From def7aa7094122147aed5d36b8f50c56496ee7ab5 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Sun, 16 Nov 2025 20:00:43 +0100 Subject: [PATCH 001/789] arch/riscv/smp: Fix race condition If the APs are much faster then the working hart, it is possible that it will enter HART_SLEEPING state before the working hart checks whether or not the APs woke up by checking the HART_AWAKE state. One can reproduce this issue by adding the following print message and testing it in QEMU. One will notice that it will get stuck. + printk(BIOS_SPEW, "waiting for hart %d\n", i); while (atomic_read(&OTHER_HLS(i)->entry.sync_a) != HART_AWAKE) Fix it by adding another sync step at the end of `smp_resume()`. Tested: QEMU RISC-V with -smp 64 parameter Signed-off-by: Maximilian Brune Change-Id: I1e0485831f71dde400d793b9f7bda88ae6519913 Reviewed-on: https://review.coreboot.org/c/coreboot/+/87299 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/arch/riscv/smp.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/arch/riscv/smp.c b/src/arch/riscv/smp.c index 67dc13b8fc..ab6e0add3a 100644 --- a/src/arch/riscv/smp.c +++ b/src/arch/riscv/smp.c @@ -4,9 +4,25 @@ #include #include #include +#include #include #include +/* + * BSP + * --------------------------------- <--- + * AP | sync_b=HART_SLEEPING | | + * ---> --------------------------------- --------------------------------- | + * | | sync_a=HART_SLEEPING | ----> | Wait for sync_a=HART_SLEEPING | | + * | --------------------------------- --------------------------------- | + * | | Wait for Interrupt | <---- | set_msip() | | + * | --------------------------------- --------------------------------- | + * | | sync_a=HART_AWAKE | ----> | Wait for sync_a=HART_AWAKE | | + * | --------------------------------- --------------------------------- | + * | | Wait for sync_b=HART_AWAKE | <---- | sync_b=HART_AWAKE | | + * ---- --------------------------------- --------------------------------- ---- + */ + // made up value to sync hart state #define HART_SLEEPING 0x1 #define HART_AWAKE 0x2 @@ -29,6 +45,11 @@ void smp_pause(int working_hartid) } while ((read_csr(mip) & MIP_MSIP) == 0); atomic_set(&HLS()->entry.sync_a, HART_AWAKE); // mark the hart as awake + + // wait for working_hart to notice that this hart is awake + while (atomic_read(&HLS()->entry.sync_b) != HART_AWAKE) + ; + HLS()->entry.fn(HLS()->entry.arg); } } @@ -47,6 +68,8 @@ void smp_resume(void (*fn)(void *), void *arg) if (CONFIG(RISCV_GET_HART_COUNT_AT_RUNTIME)) hart_count = smp_get_hart_count(); + assert(hart_count <= CONFIG_MAX_CPUS); + // check that all harts are present u32 count_awake_harts = 0; @@ -55,6 +78,8 @@ void smp_resume(void (*fn)(void *), void *arg) if (i == working_hartid) continue; + atomic_set(&OTHER_HLS(i)->entry.sync_b, HART_SLEEPING); + if (atomic_read(&OTHER_HLS(i)->entry.sync_a) != HART_SLEEPING) { /* * we assmue here that the time between smp_pause and smp_resume @@ -83,6 +108,9 @@ void smp_resume(void (*fn)(void *), void *arg) // wait for hart to publish its waking state while (atomic_read(&OTHER_HLS(i)->entry.sync_a) != HART_AWAKE) ; + + // signal to hart that we noticed it woke up + atomic_set(&OTHER_HLS(i)->entry.sync_b, HART_AWAKE); count_awake_harts++; } printk(BIOS_DEBUG, "all harts up and running...\n"); From 060d18f0704ed31f74f413f921cdbe3ffcf078e2 Mon Sep 17 00:00:00 2001 From: Payne Lin Date: Mon, 17 Nov 2025 21:02:57 +0800 Subject: [PATCH 002/789] soc/mediatek/mt8196: Add DSI dual channel Add support for DSI dual channel and dual Display Stream Compression (DSC) features. - Add DSI dual channel and dual DSC feature. - Add dsi1, mipi1, dsc0, dsc1 engine drivers. - Add configuration for dual channel feature selection. - Add 'dsi.c' for mt8196 mipi data rate calculation. - Add 'mtk_mipi_dphy.c' for mt8196 timing calculation. BUG=b:424782827 TEST=Build pass, boot ok. Verify display output on the following platforms: - 8196 Navi: eDP path. - 8189 Skywalker: eDP path. - 8189 Padme: single MIPI path (without DSC). - 8196 Sapphire: dual MIPI path (with DSC). Change-Id: I2bea829da72d23165a74b399eabfcdd55a7f28a1 Signed-off-by: Payne Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90504 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Yidi Lin --- src/soc/mediatek/common/Kconfig | 6 + src/soc/mediatek/common/dsi_common.c | 334 +++++++++++------- .../mediatek/common/include/soc/dsi_common.h | 1 + src/soc/mediatek/mt8196/Kconfig | 1 + src/soc/mediatek/mt8196/Makefile.mk | 2 + src/soc/mediatek/mt8196/ddp.c | 280 ++++++++++++++- src/soc/mediatek/mt8196/dsi.c | 88 +++++ src/soc/mediatek/mt8196/include/soc/ddp.h | 52 ++- src/soc/mediatek/mt8196/mtk_mipi_dphy.c | 29 ++ 9 files changed, 656 insertions(+), 137 deletions(-) create mode 100644 src/soc/mediatek/mt8196/dsi.c create mode 100644 src/soc/mediatek/mt8196/mtk_mipi_dphy.c diff --git a/src/soc/mediatek/common/Kconfig b/src/soc/mediatek/common/Kconfig index 30cab53df6..c52f8ed407 100644 --- a/src/soc/mediatek/common/Kconfig +++ b/src/soc/mediatek/common/Kconfig @@ -69,6 +69,12 @@ config MEDIATEK_WDT_RESET_BY_SW If the kernel disables WDT external reset (mediatek,disable-extrst), then this option must be disabled to allow WDT hardware external reset. +config MEDIATEK_DSI_DUAL_CHANNEL + bool + default n + help + The configuration to support DSI dual channel. + config MEMORY_TEST bool default y diff --git a/src/soc/mediatek/common/dsi_common.c b/src/soc/mediatek/common/dsi_common.c index 2298aa0ace..008817ade9 100644 --- a/src/soc/mediatek/common/dsi_common.c +++ b/src/soc/mediatek/common/dsi_common.c @@ -16,6 +16,25 @@ #define CPHY_SYMBOL_RATE 7 #define CPHY_SYMBOL_RATE_DIVISOR 16 +#define COMPRESSION_RATIO 3 +#define UNCOMPRESSED_RATIO 1 + +static const struct { + struct dsi_regs *const dsi_reg; + struct mipi_tx_regs *const mipi_reg; +} dsi_mipi_regs[] = { + { + .dsi_reg = dsi0, + .mipi_reg = mipi_tx0, + }, +#if CONFIG(MEDIATEK_DSI_DUAL_CHANNEL) + { + .dsi_reg = dsi1, + .mipi_reg = mipi_tx1, + }, +#endif +}; + static unsigned int mtk_dsi_get_bits_per_pixel(u32 format) { switch (format) { @@ -33,7 +52,7 @@ static unsigned int mtk_dsi_get_bits_per_pixel(u32 format) } static u32 mtk_dsi_get_data_rate(u32 bits_per_pixel, u32 lanes, - const struct edid *edid, bool is_cphy) + const struct edid *edid, u32 mode_flags) { /* data_rate = pixel_clock * bits_per_pixel * mipi_ratio / lanes * Note pixel_clock comes in kHz and returned data_rate is in bps. @@ -41,9 +60,18 @@ static u32 mtk_dsi_get_data_rate(u32 bits_per_pixel, u32 lanes, * for older platforms which do not have complete implementation in HFP. * Newer platforms should just set that to 1.0 (100 / 100). */ + u64 pixel_clock = edid->mode.pixel_clock; u32 data_rate; - u64 dividend = (u64)edid->mode.pixel_clock * bits_per_pixel * 1000 * - MTK_DSI_MIPI_RATIO_NUMERATOR; + bool is_cphy = !!(mode_flags & MIPI_DSI_MODE_CPHY); + bool is_dsi_dual_channel = !!(mode_flags & MIPI_DSI_DUAL_CHANNEL); + bool is_dsc_enabled = !!(mode_flags & MIPI_DSI_DSC_MODE); + + if (is_dsc_enabled) + pixel_clock = pixel_clock * + (DIV_ROUND_UP(edid->mode.ha, 3) + edid->mode.hbl) / + (edid->mode.ha + edid->mode.hbl); + + u64 dividend = pixel_clock * bits_per_pixel * 1000 * MTK_DSI_MIPI_RATIO_NUMERATOR; u64 divisor = (u64)lanes * MTK_DSI_MIPI_RATIO_DENOMINATOR; if (is_cphy) { @@ -51,15 +79,20 @@ static u32 mtk_dsi_get_data_rate(u32 bits_per_pixel, u32 lanes, divisor *= CPHY_SYMBOL_RATE_DIVISOR; } data_rate = DIV_ROUND_UP(dividend, divisor); - printk(BIOS_INFO, "DSI data_rate: %u bps\n", data_rate); + printk(BIOS_INFO, "pixel_clock: %lld\n", pixel_clock); + printk(BIOS_INFO, "bits_per_pixel: %d\n", bits_per_pixel); + if (is_dsi_dual_channel) + data_rate = data_rate / 2; + + printk(BIOS_INFO, "DSI final data_rate: %u bps\n", data_rate); if (data_rate < MTK_DSI_DATA_RATE_MIN_MHZ * MHz) { printk(BIOS_ERR, "data rate (%ubps) must be >= %ubps. " - "Please check the pixel clock (%u), " + "Please check the pixel clock (%llu), " "bits per pixel (%u), " "mipi_ratio (%d%%) and number of lanes (%d)\n", data_rate, MTK_DSI_DATA_RATE_MIN_MHZ * MHz, - edid->mode.pixel_clock, bits_per_pixel, + pixel_clock, bits_per_pixel, (100 * MTK_DSI_MIPI_RATIO_NUMERATOR / MTK_DSI_MIPI_RATIO_DENOMINATOR), lanes); return 0; @@ -72,7 +105,8 @@ __weak void mtk_dsi_override_phy_timing(struct mtk_phy_timing *timing) /* Do nothing. */ } -static void mtk_dsi_dphy_timing(u32 data_rate, struct mtk_phy_timing *timing) +static void mtk_dsi_dphy_timing(struct dsi_regs *dsi_reg, u32 data_rate, + struct mtk_phy_timing *timing) { u32 timcon0, timcon1, timcon2, timcon3; u32 data_rate_mhz = DIV_ROUND_UP(data_rate, MHz); @@ -91,23 +125,23 @@ static void mtk_dsi_dphy_timing(u32 data_rate, struct mtk_phy_timing *timing) timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 | timing->clk_hs_exit << 16; - write32(&dsi0->dsi_phy_timecon0, timcon0); - write32(&dsi0->dsi_phy_timecon1, timcon1); - write32(&dsi0->dsi_phy_timecon2, timcon2); - write32(&dsi0->dsi_phy_timecon3, timcon3); + write32(&dsi_reg->dsi_phy_timecon0, timcon0); + write32(&dsi_reg->dsi_phy_timecon1, timcon1); + write32(&dsi_reg->dsi_phy_timecon2, timcon2); + write32(&dsi_reg->dsi_phy_timecon3, timcon3); } -static void mtk_dsi_clk_hs_mode_enable(void) +static void mtk_dsi_clk_hs_mode_enable(struct dsi_regs *dsi_reg) { - setbits32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN); + setbits32(&dsi_reg->dsi_phy_lccon, LC_HS_TX_EN); } -static void mtk_dsi_clk_hs_mode_disable(void) +static void mtk_dsi_clk_hs_mode_disable(struct dsi_regs *dsi_reg) { - clrbits32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN); + clrbits32(&dsi_reg->dsi_phy_lccon, LC_HS_TX_EN); } -static void mtk_dsi_set_mode(u32 mode_flags) +static void mtk_dsi_set_mode(struct dsi_regs *dsi_reg, u32 mode_flags) { u32 tmp_reg1 = 0; @@ -121,10 +155,10 @@ static void mtk_dsi_set_mode(u32 mode_flags) tmp_reg1 = SYNC_PULSE_MODE; } - write32(&dsi0->dsi_mode_ctrl, tmp_reg1); + write32(&dsi_reg->dsi_mode_ctrl, tmp_reg1); } -static void mtk_dsi_rxtx_control(u32 mode_flags, u32 lanes) +static void mtk_dsi_rxtx_control(struct dsi_regs *dsi_reg, u32 mode_flags, u32 lanes) { u32 tmp_reg = 0; @@ -150,7 +184,7 @@ static void mtk_dsi_rxtx_control(u32 mode_flags, u32 lanes) if (!(mode_flags & MIPI_DSI_MODE_EOT_PACKET)) tmp_reg |= EOTP_DISABLE; - write32(&dsi0->dsi_txrx_ctrl, tmp_reg); + write32(&dsi_reg->dsi_txrx_ctrl, tmp_reg); } static void mtk_dsi_dphy_vdo_timing(const u32 mode_flags, @@ -168,6 +202,9 @@ static void mtk_dsi_dphy_vdo_timing(const u32 mode_flags, phy_timing->da_hs_zero + phy_timing->da_hs_exit + 3; u32 delta = 10; + int channels = (mode_flags & MIPI_DSI_DUAL_CHANNEL) ? 2 : 1; + int dsc_ratio = (mode_flags & MIPI_DSI_DSC_MODE) ? COMPRESSION_RATIO : + UNCOMPRESSED_RATIO; if (mode_flags & MIPI_DSI_MODE_EOT_PACKET) delta += 2; @@ -188,17 +225,44 @@ static void mtk_dsi_dphy_vdo_timing(const u32 mode_flags, hbp * bytes_per_pixel, d_phy); } - *hsync_active_byte = edid->mode.hspw * bytes_per_pixel - 10; + *hsync_active_byte = edid->mode.hspw / channels * bytes_per_pixel - 10; + if (mode_flags & MIPI_DSI_MODE_LINE_END) { *hsync_active_byte = DIV_ROUND_UP(*hsync_active_byte, lanes) * lanes - 2; *hbp_byte = DIV_ROUND_UP(*hbp_byte, lanes) * lanes - 2; *hfp_byte = DIV_ROUND_UP(*hfp_byte, lanes) * lanes - 2; - *hbp_byte -= (edid->mode.ha * bytes_per_pixel + 2) % lanes; + *hbp_byte -= (edid->mode.ha / dsc_ratio / channels * bytes_per_pixel + 2) % + lanes; } } -static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format, u32 lanes, - const struct edid *edid, +static u32 mtk_dsi_get_packet_fmt(u32 format) +{ + u32 packet_fmt; + + switch (format) { + case MIPI_DSI_FMT_RGB888: + packet_fmt = PACKED_PS_24BIT_RGB888; + break; + case MIPI_DSI_FMT_RGB666: + packet_fmt = LOOSELY_PS_18BIT_RGB666; + break; + case MIPI_DSI_FMT_RGB666_PACKED: + packet_fmt = PACKED_PS_18BIT_RGB666; + break; + case MIPI_DSI_FMT_RGB565: + packet_fmt = PACKED_PS_16BIT_RGB565; + break; + default: + packet_fmt = PACKED_PS_24BIT_RGB888; + break; + } + + return packet_fmt; +} + +static void mtk_dsi_config_vdo_timing(struct dsi_regs *const dsi_reg, u32 mode_flags, + u32 format, u32 lanes, const struct edid *edid, const struct mtk_phy_timing *phy_timing) { u32 hsync_active_byte; @@ -211,26 +275,30 @@ static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format, u32 lanes, u32 bytes_per_pixel; u32 packet_fmt; u32 hactive; + u32 hbp_offset; bool is_cphy = !!(mode_flags & MIPI_DSI_MODE_CPHY); + bool is_dsc_enabled = !!(mode_flags & MIPI_DSI_DSC_MODE); + int channels = !!(mode_flags & MIPI_DSI_DUAL_CHANNEL) ? 2 : 1; + int dsc_ratio = is_dsc_enabled ? COMPRESSION_RATIO : UNCOMPRESSED_RATIO; bytes_per_pixel = DIV_ROUND_UP(mtk_dsi_get_bits_per_pixel(format), 8); vbp_byte = edid->mode.vbl - edid->mode.vso - edid->mode.vspw - edid->mode.vborder; vfp_byte = edid->mode.vso - edid->mode.vborder; - write32(&dsi0->dsi_vsa_nl, edid->mode.vspw); - write32(&dsi0->dsi_vbp_nl, vbp_byte); - write32(&dsi0->dsi_vfp_nl, vfp_byte); - write32(&dsi0->dsi_vact_nl, edid->mode.va); + write32(&dsi_reg->dsi_vsa_nl, edid->mode.vspw); + write32(&dsi_reg->dsi_vbp_nl, vbp_byte); + write32(&dsi_reg->dsi_vfp_nl, vfp_byte); + write32(&dsi_reg->dsi_vact_nl, edid->mode.va); - hbp = edid->mode.hbl - edid->mode.hso - edid->mode.hspw - - edid->mode.hborder; - hfp = edid->mode.hso - edid->mode.hborder; + hbp = (edid->mode.hbl - edid->mode.hso - edid->mode.hspw - + edid->mode.hborder) / channels; + hfp = (edid->mode.hso - edid->mode.hborder) / channels; + + hbp_offset = (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) ? + 0 : (edid->mode.hspw / channels); + hbp_byte = (hbp + hbp_offset) * bytes_per_pixel - 10; - if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) - hbp_byte = hbp * bytes_per_pixel - 10; - else - hbp_byte = (hbp + edid->mode.hspw) * bytes_per_pixel - 10; hfp_byte = hfp * bytes_per_pixel; if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) @@ -255,49 +323,40 @@ static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format, u32 lanes, hbp_byte = MIN_HBP_BYTE; } - write32(&dsi0->dsi_hsa_wc, hsync_active_byte); - write32(&dsi0->dsi_hbp_wc, hbp_byte); - write32(&dsi0->dsi_hfp_wc, hfp_byte); + write32(&dsi_reg->dsi_hsa_wc, hsync_active_byte); + write32(&dsi_reg->dsi_hbp_wc, hbp_byte); + write32(&dsi_reg->dsi_hfp_wc, hfp_byte); - switch (format) { - case MIPI_DSI_FMT_RGB888: - packet_fmt = PACKED_PS_24BIT_RGB888; - break; - case MIPI_DSI_FMT_RGB666: - packet_fmt = LOOSELY_PS_18BIT_RGB666; - break; - case MIPI_DSI_FMT_RGB666_PACKED: - packet_fmt = PACKED_PS_18BIT_RGB666; - break; - case MIPI_DSI_FMT_RGB565: - packet_fmt = PACKED_PS_16BIT_RGB565; - break; - default: - packet_fmt = PACKED_PS_24BIT_RGB888; - break; - } + if (is_dsc_enabled) + packet_fmt = COMPRESSED_PIXEL_STREAM_V2; + else + packet_fmt = mtk_dsi_get_packet_fmt(format); - hactive = edid->mode.ha; + hactive = edid->mode.ha / dsc_ratio / channels; packet_fmt |= (hactive * bytes_per_pixel) & DSI_PS_WC; - write32(&dsi0->dsi_psctrl, + write32(&dsi_reg->dsi_psctrl, PIXEL_STREAM_CUSTOM_HEADER << DSI_PSCON_CUSTOM_HEADER_SHIFT | packet_fmt); /* Older systems like MT8173 do not support size_con. */ if (MTK_DSI_HAVE_SIZE_CON) - write32(&dsi0->dsi_size_con, + write32(&dsi_reg->dsi_size_con, edid->mode.va << DSI_SIZE_CON_HEIGHT_SHIFT | hactive << DSI_SIZE_CON_WIDTH_SHIFT); if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) - mtk_dsi_cphy_enable_cmdq_6byte(dsi0); + mtk_dsi_cphy_enable_cmdq_6byte(dsi_reg); +} + +static void mtk_dsi_dual_enable(struct dsi_regs *dsi_reg, bool enable) +{ + clrsetbits32(&dsi_reg->dsi_con_ctrl, DSI_DUAL, (enable ? DSI_DUAL : 0)); } -static void mtk_dsi_start(void) +static void mtk_dsi_start(struct dsi_regs *dsi_reg) { - write32(&dsi0->dsi_start, 0); - /* Only start master DSI */ - write32(&dsi0->dsi_start, 1); + write32(&dsi_reg->dsi_start, 0); + write32(&dsi_reg->dsi_start, 1); } static bool mtk_dsi_is_read_command(enum mipi_dsi_transaction type) @@ -313,60 +372,77 @@ static bool mtk_dsi_is_read_command(enum mipi_dsi_transaction type) } } +static void mtk_dsi_enable_and_start(bool is_dsi_dual_channel) +{ + /* + * For dual channel synchronization, + * the secondary dsi1 must be dual-enabled before starting the primary dsi0. + */ + if (is_dsi_dual_channel) + mtk_dsi_dual_enable(dsi_mipi_regs[ARRAY_SIZE(dsi_mipi_regs) - 1].dsi_reg, true); + /* + * Only start primary dsi0 for single or dual channel mode. + * The secondary dsi1 is dual-enabled in mtk_dsi_dual_enable() + * and does not require a separate start. + * Starting only the primary dsi0 ensures correct synchronization + * with secondary dsi1 if there is. + */ + mtk_dsi_start(dsi_mipi_regs[0].dsi_reg); +} + static enum cb_err mtk_dsi_cmdq(enum mipi_dsi_transaction type, const u8 *data, u8 len, void *user_data) { const u8 *tx_buf = data; u32 config; - int i, j; - - if (!wait_ms(20, !(read32(&dsi0->dsi_intsta) & DSI_BUSY))) { - printk(BIOS_ERR, "%s: cannot get DSI ready for sending commands" - " after 20ms and the panel may not work properly.\n", - __func__); - return CB_ERR; - } - write32(&dsi0->dsi_intsta, 0); - - if (mtk_dsi_is_read_command(type)) - config = BTA; - else - config = (len > 2) ? LONG_PACKET : SHORT_PACKET; - - if (len <= 2) { - uint32_t val = (type << 8) | config; - for (i = 0; i < len; i++) - val |= tx_buf[i] << (i + 2) * 8; - write32(&dsi0->dsi_cmdq[0], val); - write32(&dsi0->dsi_cmdq_size, 1); - } else { - /* TODO(hungte) Replace by buffer_to_fifo32_prefix */ - write32(&dsi0->dsi_cmdq[0], (len << 16) | (type << 8) | config); - for (i = 0; i < len; i += 4) { - uint32_t val = 0; - for (j = 0; j < MIN(len - i, 4); j++) - val |= tx_buf[i + j] << j * 8; - write32(&dsi0->dsi_cmdq[i / 4 + 1], val); + uint32_t *mode_flags = (uint32_t *)user_data; + bool is_dsi_dual_channel = (*mode_flags & MIPI_DSI_DUAL_CHANNEL); + + for (unsigned int k = 0; k < ARRAY_SIZE(dsi_mipi_regs); k++) { + struct dsi_regs *dsi = dsi_mipi_regs[k].dsi_reg; + if (!wait_ms(20, !(read32(&dsi->dsi_intsta) & DSI_BUSY))) { + printk(BIOS_ERR, "%s: cannot get DSI-%d ready for sending commands" + " after 20ms and the panel may not work properly.\n", + __func__, k); + return CB_ERR; + } + write32(&dsi->dsi_intsta, 0); + + if (mtk_dsi_is_read_command(type)) + config = BTA; + else + config = (len > 2) ? LONG_PACKET : SHORT_PACKET; + + u32 prefix = config | type << 8; + int prefsz = 2; + if (len > 2) { + prefix |= len << 16; + prefsz += 2; } - write32(&dsi0->dsi_cmdq_size, 1 + DIV_ROUND_UP(len, 4)); + buffer_to_fifo32_prefix(tx_buf, prefix, prefsz, prefsz + len, &dsi->dsi_cmdq[0], + 4, 4); + write32(&dsi->dsi_cmdq_size, DIV_ROUND_UP(prefsz + len, 4)); + setbits32(&dsi->dsi_cmdq_size, CMDQ_SIZE_SEL); } - setbits32(&dsi0->dsi_cmdq_size, CMDQ_SIZE_SEL); - mtk_dsi_start(); + mtk_dsi_enable_and_start(is_dsi_dual_channel); - if (!wait_us(400, read32(&dsi0->dsi_intsta) & CMD_DONE_INT_FLAG)) { - printk(BIOS_ERR, "%s: failed sending DSI command, " - "panel may not work.\n", __func__); - return CB_ERR; + for (unsigned int k = 0; k < ARRAY_SIZE(dsi_mipi_regs); k++) { + struct dsi_regs *dsi = dsi_mipi_regs[k].dsi_reg; + if (!wait_us(400, read32(&dsi->dsi_intsta) & CMD_DONE_INT_FLAG)) { + printk(BIOS_ERR, "%s: failed sending DSI-%d command, " + "panel may not work.\n", __func__, k); + return CB_ERR; + } } return CB_SUCCESS; } -static void mtk_dsi_reset_phy(void) +static void mtk_dsi_reset_phy(struct dsi_regs *const dsi_reg) { - setbits32(&dsi0->dsi_con_ctrl, DPHY_RESET); - clrbits32(&dsi0->dsi_con_ctrl, DPHY_RESET); + setbits32(&dsi_reg->dsi_con_ctrl, DPHY_RESET); + clrbits32(&dsi_reg->dsi_con_ctrl, DPHY_RESET); } int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, @@ -375,6 +451,8 @@ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, u32 data_rate; u32 bits_per_pixel = mtk_dsi_get_bits_per_pixel(format); bool is_cphy = !!(mode_flags & MIPI_DSI_MODE_CPHY); + bool is_dsi_dual_channel = !!(mode_flags & MIPI_DSI_DUAL_CHANNEL); + unsigned int num_dsi = is_dsi_dual_channel ? 2 : 1; if (!CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) { printk(BIOS_ERR, "%s: Board is built without C-PHY interface support. " @@ -382,27 +460,47 @@ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, return -1; } - data_rate = mtk_dsi_get_data_rate(bits_per_pixel, lanes, edid, is_cphy); + if (num_dsi > ARRAY_SIZE(dsi_mipi_regs)) { + printk(BIOS_ERR, "%s: num_dsi %d > %lu\n", __func__, + num_dsi, ARRAY_SIZE(dsi_mipi_regs)); + return -1; + } + + data_rate = mtk_dsi_get_data_rate(bits_per_pixel, lanes, edid, mode_flags); if (!data_rate) return -1; - mtk_dsi_configure_mipi_tx(mipi_tx0, data_rate, lanes, is_cphy); - mtk_dsi_reset(dsi0); - struct mtk_phy_timing phy_timing = {}; - if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) - mtk_dsi_cphy_timing(data_rate, &phy_timing); - else - mtk_dsi_dphy_timing(data_rate, &phy_timing); - mtk_dsi_rxtx_control(mode_flags, lanes); - mdelay(1); - mtk_dsi_reset_phy(); - mtk_dsi_clk_hs_mode_disable(); - mtk_dsi_config_vdo_timing(mode_flags, format, lanes, edid, &phy_timing); - mtk_dsi_clk_hs_mode_enable(); + for (unsigned int i = 0; i < num_dsi; i++) { + struct dsi_regs *dsi = dsi_mipi_regs[i].dsi_reg; + struct mipi_tx_regs *mipi = dsi_mipi_regs[i].mipi_reg; + if (!dsi || !mipi) { + printk(BIOS_ERR, "%s: Null dsi/mipi reg for DSI-%d\n", __func__, i); + return -1; + } + mtk_dsi_configure_mipi_tx(mipi, data_rate, lanes, is_cphy); + mtk_dsi_reset(dsi); + struct mtk_phy_timing phy_timing = {}; + if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) + /* Dual channel is not implemented for CPHY. */ + mtk_dsi_cphy_timing(data_rate, &phy_timing); + else + mtk_dsi_dphy_timing(dsi, data_rate, &phy_timing); + + mtk_dsi_rxtx_control(dsi, mode_flags, lanes); + mdelay(1); + mtk_dsi_reset_phy(dsi); + mtk_dsi_clk_hs_mode_disable(dsi); + mtk_dsi_config_vdo_timing(dsi, mode_flags, format, lanes, edid, &phy_timing); + mtk_dsi_clk_hs_mode_enable(dsi); + } + if (init_commands) - mipi_panel_parse_init_commands(init_commands, mtk_dsi_cmdq, NULL); - mtk_dsi_set_mode(mode_flags); - mtk_dsi_start(); + mipi_panel_parse_init_commands(init_commands, mtk_dsi_cmdq, &mode_flags); + + for (unsigned int i = 0; i < num_dsi; i++) + mtk_dsi_set_mode(dsi_mipi_regs[i].dsi_reg, mode_flags); + + mtk_dsi_enable_and_start(is_dsi_dual_channel); return 0; } diff --git a/src/soc/mediatek/common/include/soc/dsi_common.h b/src/soc/mediatek/common/include/soc/dsi_common.h index e06701f490..57961d10bb 100644 --- a/src/soc/mediatek/common/include/soc/dsi_common.h +++ b/src/soc/mediatek/common/include/soc/dsi_common.h @@ -59,6 +59,7 @@ enum { LOOSELY_PS_18BIT_RGB666 = (1 << 16), PACKED_PS_18BIT_RGB666 = (2 << 16), PACKED_PS_24BIT_RGB888 = (3 << 16), + COMPRESSED_PIXEL_STREAM_V2 = (5 << 16), DSI_PSCON_CUSTOM_HEADER_SHIFT = 26, }; diff --git a/src/soc/mediatek/mt8196/Kconfig b/src/soc/mediatek/mt8196/Kconfig index 90c85007ef..c6eedf9341 100644 --- a/src/soc/mediatek/mt8196/Kconfig +++ b/src/soc/mediatek/mt8196/Kconfig @@ -18,6 +18,7 @@ config SOC_MEDIATEK_MT8196 select ARM64_USE_ARCH_TIMER select PCI select EARLY_MMU_INIT + select MEDIATEK_DSI_DUAL_CHANNEL if SOC_MEDIATEK_MT8196 diff --git a/src/soc/mediatek/mt8196/Makefile.mk b/src/soc/mediatek/mt8196/Makefile.mk index cc7ec0ad11..47f9592bc8 100644 --- a/src/soc/mediatek/mt8196/Makefile.mk +++ b/src/soc/mediatek/mt8196/Makefile.mk @@ -64,12 +64,14 @@ ramstage-y += ../common/dp/dp_intf_v2.c ramstage-y += ../common/dp/dptx_common.c ../common/dp/dptx_v2.c dptx.c ramstage-y += ../common/dp/dptx_hal_common.c ../common/dp/dptx_hal_v2.c dptx_hal.c ramstage-y += ../common/dramc_info.c +ramstage-y += ../common/dsi_common.c dsi.c ramstage-y += ../common/early_init.c ramstage-y += ../common/emi.c ramstage-y += gpueb.c ramstage-y += l2c_ops.c ramstage-y += ../common/mcu.c mcupm.c ramstage-y += ../common/mmu_operations.c +ramstage-y += ../common/mtk_mipi_dphy.c mtk_mipi_dphy.c ramstage-$(CONFIG_PCI) += ../common/pcie.c pcie.c ramstage-$(CONFIG_COMMONLIB_STORAGE_MMC) += msdc.c ramstage-y += ../common/mt6363.c mt6363.c diff --git a/src/soc/mediatek/mt8196/ddp.c b/src/soc/mediatek/mt8196/ddp.c index 380d52f171..ba317d4e79 100644 --- a/src/soc/mediatek/mt8196/ddp.c +++ b/src/soc/mediatek/mt8196/ddp.c @@ -11,6 +11,30 @@ #define SIZE(w, h) ((u32)(h) << 16 | (w)) #define DUAL_PIPE(path) ((path) == DISP_PATH_DUAL_MIPI) +#define DSC_EN BIT(0) +#define DSC_DUAL_INOUT BIT(2) +#define DSC_IN_SRC_SEL BIT(3) +#define DSC_BYPASS BIT(4) +#define DSC_RELAY BIT(5) +#define DSC_PT_MEM_EN BIT(7) +#define DSC_EMPTY_FLAG_SEL GENMASK(15, 14) +#define DSC_EMPTY_FLAG_ALWAYS_LOW BIT(15) +#define DSC_UFOE_SEL BIT(16) +#define DSC_ZERO_FIFO_STALL_DISABLE BIT(20) + +#define DSC_INTEN_SEL GENMASK(6, 0) +#define DSC_ZERO_FIFO BIT(2) + +#define DSC_INTACK_SEL GENMASK(6, 0) +#define DSC_INTACK_BUF_UNDERFLOW BIT(6) + +#define DSC_PIC_PREPAD_HEIGHT_SEL GENMASK(15, 0) +#define DSC_PIC_PREPAD_WIDTH_SEL GENMASK(31, 16) + +#define ALIGN_PADDING(V, N) (((N) - ((V) % (N))) % (N)) +/* Provide default value for x == 0. */ +#define DEF(x, default) ((x) == 0 ? (default) : (x)) + struct disp_pipe_regs { struct disp_mdp_rsz_regs *const mdp_rsz; struct disp_tdshp_regs *const tdshp; @@ -44,6 +68,245 @@ static const struct disp_pipe_regs disp_pipe1_regs = { .dsc = disp_dsc3_reg, }; +static void dsc_configure_registers(struct disp_dsc_regs *reg, u16 w, u16 h, + const struct dsc_config *dsc_cfg) +{ + u32 init_delay_limit, init_delay_height; + u32 pic_group_width, pic_height_ext_num; + u32 slice_group_width; + u32 pad_num; + u32 slice_mode; + u32 dsc_cfg_mode = 0x22; + u32 mask; + u32 val; + u32 rgb_swap = 0; + + if (dsc_cfg->bits_per_component == 0xA) + dsc_cfg_mode = 0x828; + + assert(dsc_cfg->pic_width > 0); + assert(dsc_cfg->pic_width >= dsc_cfg->slice_width); + assert(dsc_cfg->slice_width > 0); + slice_mode = dsc_cfg->pic_width / dsc_cfg->slice_width - 1; + pic_group_width = DIV_ROUND_UP(dsc_cfg->pic_width, 3); + pic_height_ext_num = DIV_ROUND_UP(h, dsc_cfg->slice_height); + slice_group_width = DIV_ROUND_UP(dsc_cfg->slice_width, 3); + pad_num = ALIGN_PADDING(dsc_cfg->slice_chunk_size * (slice_mode + 1), 3); + init_delay_limit = DIV_ROUND_UP(dsc_cfg->initial_xmit_delay, 3); + init_delay_limit = DIV_ROUND_UP((128 + init_delay_limit) * 3, dsc_cfg->slice_width); + init_delay_height = MIN(15, init_delay_limit); + + mask = DSC_EN | DSC_DUAL_INOUT | DSC_IN_SRC_SEL | DSC_BYPASS | DSC_RELAY | + DSC_PT_MEM_EN | DSC_EMPTY_FLAG_SEL | DSC_UFOE_SEL | + DSC_ZERO_FIFO_STALL_DISABLE; + val = DSC_PT_MEM_EN | DSC_EMPTY_FLAG_ALWAYS_LOW | DSC_UFOE_SEL | + DSC_ZERO_FIFO_STALL_DISABLE; + + clrsetbits32(®->dsc_con, mask, val); + clrsetbits32(®->dsc_inten, DSC_INTEN_SEL, 0x7F); + clrsetbits32(®->dsc_intack, DSC_INTACK_SEL, DSC_INTACK_BUF_UNDERFLOW); + + write32(®->dsc_spr, 0x0); + + val = w | (pic_group_width - 1) << 16; + write32(®->pic_w, val); + + val = (h - 1) | (pic_height_ext_num * dsc_cfg->slice_height - 1) << 16; + write32(®->pic_h, val); + + val = dsc_cfg->slice_width | (slice_group_width - 1) << 16; + write32(®->dsc_slice_w, val); + + val = (dsc_cfg->slice_height - 1) | (pic_height_ext_num - 1) << 16 | + (dsc_cfg->slice_width % 3) << 30; + write32(®->dsc_slice_h, val); + + val = dsc_cfg->slice_chunk_size | + (((dsc_cfg->slice_chunk_size << slice_mode) + 2) / 3) << 16; + write32(®->chunk_size, val); + + mask = GENMASK(23, 0); + val = dsc_cfg->slice_chunk_size * dsc_cfg->slice_height; + clrsetbits32(®->dsc_buf_size, mask, val); + + mask = BIT(0) | BIT(2) | GENMASK(11, 8); + val = slice_mode | rgb_swap << 2 | init_delay_height << 8; + clrsetbits32(®->dsc_mode, mask, val); + + write32(®->dsc_cfg, dsc_cfg_mode); + + mask = GENMASK(2, 0); + val = pad_num; + clrsetbits32(®->dsc_pad, mask, val); + + val = dsc_cfg->slice_width | dsc_cfg->pic_width << 16; + write32(®->dsc_enc_width, val); + + mask = DSC_PIC_PREPAD_HEIGHT_SEL | DSC_PIC_PREPAD_WIDTH_SEL; + val = h | w << 16; + clrsetbits32(®->dsc_pic_pre_pad_size, mask, val); + + setbits32(®->dsc_dbg_con, BIT(9)); + + write32(®->dsc_obuf, 0x410); + + DEFINE_BITFIELD(LINE_BUF_DEPTH, 3, 0) + DEFINE_BITFIELD(BITS_PER_COMPONENT, 7, 4) + DEFINE_BITFIELD(BITS_PER_PIXEL, 17, 8) + DEFINE_BIT(CONVERT_RGB, 18) + DEFINE_BIT(BLOCK_PRED_ENABLE, 19) + SET32_BITFIELDS(®->dsc_pps[0], + LINE_BUF_DEPTH, DEF(dsc_cfg->line_buf_depth, 0x9), + BITS_PER_COMPONENT, DEF(dsc_cfg->bits_per_component, 0x8), + BITS_PER_PIXEL, DEF(dsc_cfg->bits_per_pixel, 0x80), + CONVERT_RGB, DEF((u8)dsc_cfg->convert_rgb, 1), + BLOCK_PRED_ENABLE, DEF((u8)dsc_cfg->block_pred_enable, 0)); + + DEFINE_BITFIELD(INITIAL_DEC_DELAY, 31, 16) + DEFINE_BITFIELD(INITIAL_XMIT_DELAY, 15, 0) + WRITE32_BITFIELDS(®->dsc_pps[1], + INITIAL_DEC_DELAY, DEF(dsc_cfg->initial_dec_delay, 0x268), + INITIAL_XMIT_DELAY, DEF(dsc_cfg->initial_xmit_delay, 0x200)); + + DEFINE_BITFIELD(INITIAL_SCALE_VALUE, 15, 0) + DEFINE_BITFIELD(SCALE_INCREMENT_INTERVAL, 31, 16) + WRITE32_BITFIELDS(®->dsc_pps[2], + INITIAL_SCALE_VALUE, DEF(dsc_cfg->initial_scale_value, 0x20), + SCALE_INCREMENT_INTERVAL, + DEF(dsc_cfg->scale_increment_interval, 0x387)); + + DEFINE_BITFIELD(FIRST_LINE_BPG_OFFSET, 31, 16) + DEFINE_BITFIELD(SCALE_DECREMENT_INTERVAL, 15, 0) + WRITE32_BITFIELDS(®->dsc_pps[3], + FIRST_LINE_BPG_OFFSET, DEF(dsc_cfg->first_line_bpg_offset, 0xc), + SCALE_DECREMENT_INTERVAL, + DEF(dsc_cfg->scale_decrement_interval, 0xa)); + + DEFINE_BITFIELD(NFL_BPG_OFFSET, 15, 0) + DEFINE_BITFIELD(SLICE_BPG_OFFSET, 31, 16) + WRITE32_BITFIELDS(®->dsc_pps[4], + NFL_BPG_OFFSET, DEF(dsc_cfg->nfl_bpg_offset, 0x319), + SLICE_BPG_OFFSET, DEF(dsc_cfg->slice_bpg_offset, 0x263)); + + DEFINE_BITFIELD(INITIAL_OFFSET, 15, 0) + DEFINE_BITFIELD(FINAL_OFFSET, 31, 16) + WRITE32_BITFIELDS(®->dsc_pps[5], + INITIAL_OFFSET, DEF(dsc_cfg->initial_offset, 0x1800), + FINAL_OFFSET, DEF(dsc_cfg->final_offset, 0x10f0)); + + DEFINE_BITFIELD(FLATNESS_MIN_QP, 4, 0) + DEFINE_BITFIELD(FLATNESS_MAX_QP, 12, 8) + DEFINE_BITFIELD(RC_MODEL_SIZE, 31, 16) + SET32_BITFIELDS(®->dsc_pps[6], + FLATNESS_MIN_QP, DEF(dsc_cfg->flatness_min_qp, 0x3), + FLATNESS_MAX_QP, DEF(dsc_cfg->flatness_max_qp, 0xc), + RC_MODEL_SIZE, DEF(dsc_cfg->rc_model_size, 0x2000)); + + DEFINE_BITFIELD(RC_TGT_OFFSET_LOW, 31, 28) + DEFINE_BITFIELD(RC_TGT_OFFSET_HIGH, 27, 24) + DEFINE_BITFIELD(RC_QUANT_INCR_LIMIT1, 20, 16) + DEFINE_BITFIELD(RC_QUANT_INCR_LIMIT0, 12, 8) + DEFINE_BITFIELD(RC_EDGE_FACTOR, 7, 0) + WRITE32_BITFIELDS(®->dsc_pps[7], + RC_TGT_OFFSET_LOW, dsc_cfg->rc_tgt_offset_low, + RC_TGT_OFFSET_HIGH, dsc_cfg->rc_tgt_offset_high, + RC_QUANT_INCR_LIMIT1, dsc_cfg->rc_quant_incr_limit1, + RC_QUANT_INCR_LIMIT0, dsc_cfg->rc_quant_incr_limit0, + RC_EDGE_FACTOR, dsc_cfg->rc_edge_factor); + + DEFINE_BITFIELD(RC_BUF_THRESH_3, 31, 24) + DEFINE_BITFIELD(RC_BUF_THRESH_2, 23, 16) + DEFINE_BITFIELD(RC_BUF_THRESH_1, 15, 8) + DEFINE_BITFIELD(RC_BUF_THRESH_0, 7, 0) + WRITE32_BITFIELDS(®->dsc_pps[8], + RC_BUF_THRESH_3, dsc_cfg->rc_buf_thresh[3], + RC_BUF_THRESH_2, dsc_cfg->rc_buf_thresh[2], + RC_BUF_THRESH_1, dsc_cfg->rc_buf_thresh[1], + RC_BUF_THRESH_0, dsc_cfg->rc_buf_thresh[0]); + + DEFINE_BITFIELD(RC_BUF_THRESH_7, 31, 24) + DEFINE_BITFIELD(RC_BUF_THRESH_6, 23, 16) + DEFINE_BITFIELD(RC_BUF_THRESH_5, 15, 8) + DEFINE_BITFIELD(RC_BUF_THRESH_4, 7, 0) + WRITE32_BITFIELDS(®->dsc_pps[9], + RC_BUF_THRESH_7, dsc_cfg->rc_buf_thresh[7], + RC_BUF_THRESH_6, dsc_cfg->rc_buf_thresh[6], + RC_BUF_THRESH_5, dsc_cfg->rc_buf_thresh[5], + RC_BUF_THRESH_4, dsc_cfg->rc_buf_thresh[4]); + + DEFINE_BITFIELD(RC_BUF_THRESH_11, 31, 24) + DEFINE_BITFIELD(RC_BUF_THRESH_10, 23, 16) + DEFINE_BITFIELD(RC_BUF_THRESH_9, 15, 8) + DEFINE_BITFIELD(RC_BUF_THRESH_8, 7, 0) + WRITE32_BITFIELDS(®->dsc_pps[10], + RC_BUF_THRESH_11, dsc_cfg->rc_buf_thresh[11], + RC_BUF_THRESH_10, dsc_cfg->rc_buf_thresh[10], + RC_BUF_THRESH_9, dsc_cfg->rc_buf_thresh[9], + RC_BUF_THRESH_8, dsc_cfg->rc_buf_thresh[8]); + + DEFINE_BITFIELD(RC_BUF_THRESH_13, 15, 8) + DEFINE_BITFIELD(RC_BUF_THRESH_12, 7, 0) + WRITE32_BITFIELDS(®->dsc_pps[11], + RC_BUF_THRESH_13, dsc_cfg->rc_buf_thresh[13], + RC_BUF_THRESH_12, dsc_cfg->rc_buf_thresh[12]); + + DEFINE_BITFIELD(RC_RANGE_BPG_OFFSET_ODD, 31, 26) + DEFINE_BITFIELD(RC_RANGE_MAX_QP_ODD, 25, 21) + DEFINE_BITFIELD(RC_RANGE_MIN_QP_ODD, 20, 16) + DEFINE_BITFIELD(RC_RANGE_BPG_OFFSET_EVEN, 15, 10) + DEFINE_BITFIELD(RC_RANGE_MAX_QP_EVEN, 9, 5) + DEFINE_BITFIELD(RC_RANGE_MIN_QP_EVEN, 4, 0) + for (int i = 0; i < 7; i++) { + WRITE32_BITFIELDS(®->dsc_pps_rc_range_params[i], + RC_RANGE_BPG_OFFSET_ODD, + dsc_cfg->rc_range_params[2 * i + 1].range_bpg_offset, + RC_RANGE_MAX_QP_ODD, + dsc_cfg->rc_range_params[2 * i + 1].range_max_qp, + RC_RANGE_MIN_QP_ODD, + dsc_cfg->rc_range_params[2 * i + 1].range_min_qp, + RC_RANGE_BPG_OFFSET_EVEN, + dsc_cfg->rc_range_params[2 * i].range_bpg_offset, + RC_RANGE_MAX_QP_EVEN, + dsc_cfg->rc_range_params[2 * i].range_max_qp, + RC_RANGE_MIN_QP_EVEN, + dsc_cfg->rc_range_params[2 * i].range_min_qp); + } + /* Special case for the last register */ + WRITE32_BITFIELDS(®->dsc_pps_rc_range_params[7], + RC_RANGE_BPG_OFFSET_EVEN, + dsc_cfg->rc_range_params[14].range_bpg_offset, + RC_RANGE_MAX_QP_EVEN, dsc_cfg->rc_range_params[14].range_max_qp, + RC_RANGE_MIN_QP_EVEN, dsc_cfg->rc_range_params[14].range_min_qp); + + if (dsc_cfg->dsc_version_minor == 1) + write32(®->dsc_shadow, 0x20); + else if (dsc_cfg->dsc_version_minor == 2) + write32(®->dsc_shadow, 0x40); + else + printk(BIOS_WARNING, "%s : wrong version minor:%d\n", __func__, + dsc_cfg->dsc_version_minor); +} + +static void dsc_config(struct disp_dsc_regs *reg, u16 w, u16 h, + const struct dsc_config *dsc_cfg) +{ + bool dsc_enable; + + dsc_enable = (dsc_cfg && dsc_cfg->dsc_version_major); + printk(BIOS_INFO, "%s: w:%d, h:%d, dsc enable:%d\n", __func__, w, h, dsc_enable); + + if (!dsc_enable) { + setbits32(®->dsc_con, DSC_RELAY); + clrsetbits32(®->chunk_size, GENMASK(31, 16), w << 16); + clrsetbits32(®->pic_w, GENMASK(15, 0), w); + clrsetbits32(®->pic_h, GENMASK(15, 0), h); + printk(BIOS_INFO, "%s: DSC_relay mode\n", __func__); + return; + } + + dsc_configure_registers(reg, w, h, dsc_cfg); +} + static void blender_config(struct blender *reg, u16 width, u16 height, enum mtk_disp_blender_layer type) { @@ -157,17 +420,9 @@ static void dither_start(struct disp_dither_regs *reg) setbits32(®->en, BIT(0)); } -static void dsc_config(struct disp_dsc_regs *reg, u16 width, u16 height) -{ - write32(®->dsc_con, BIT(5)); - write32(®->pic_w, width); - write32(®->pic_h, height); - write32(®->chunk_size, width << 16); -} - static void dsc_start(struct disp_dsc_regs *reg) { - setbits32(®->dsc_con, BIT(0)); + setbits32(®->dsc_con, DSC_EN); } static void ovlsys_path_connect(struct ovlsys_cfg *reg) @@ -325,7 +580,8 @@ static void disp_config_blender(struct blender *const blenders[], size_t size, u } } -static void main_disp_path_setup(u16 width, u16 height, u32 vrefresh, enum disp_path_sel path) +static void main_disp_path_setup(u16 width, u16 height, u32 vrefresh, enum disp_path_sel path, + const struct dsc_config *dsc_cfg) { u16 w = width; size_t num_pipe = DUAL_PIPE(path) ? 2 : 1; @@ -361,7 +617,7 @@ static void main_disp_path_setup(u16 width, u16 height, u32 vrefresh, enum disp_ postmask_start(pipes[i].postmask); dither_config(pipes[i].dither, w, height); dither_start(pipes[i].dither); - dsc_config(pipes[i].dsc, w, height); + dsc_config(pipes[i].dsc, w, height, dsc_cfg); dsc_start(pipes[i].dsc); } @@ -435,7 +691,7 @@ void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, if (width > 0x1FFF || height > 0x1FFF) printk(BIOS_WARNING, "%s: w/h: %d/%d exceed hw limit %u\n", __func__, width, height, 0x1FFF); - main_disp_path_setup(width, height, vrefresh, path); + main_disp_path_setup(width, height, vrefresh, path, dsc_config); ovlsys_layer_config(fmt, bpp, width, height, path); } diff --git a/src/soc/mediatek/mt8196/dsi.c b/src/soc/mediatek/mt8196/dsi.c new file mode 100644 index 0000000000..6d6705986b --- /dev/null +++ b/src/soc/mediatek/mt8196/dsi.c @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include +#include +#include +#include + +#define RG_DSI_PRD_REF_SEL GENMASK(5, 0) +#define RG_DSI_PRD_REF_MINI 0 +#define RG_DSI_PRD_REF_DEF 4 +#define RG_DSI_PRD_REF_MAX 7 + +void mtk_dsi_configure_mipi_tx(struct mipi_tx_regs *mipi_tx_reg, u32 data_rate, + u32 lanes, bool is_cphy) +{ + unsigned int txdiv0; + u64 pcw; + + /* Select different voltage when different data rate */ + if (data_rate < (u32)2500 * MHz) { + clrsetbits32(&mipi_tx_reg->pll_con1, RG_DSI_PRD_REF_SEL, RG_DSI_PRD_REF_MINI); + write32(&mipi_tx_reg->cdphy_preserved, 0xFFFF00F0); + } else { + clrsetbits32(&mipi_tx_reg->pll_con1, RG_DSI_PRD_REF_SEL, RG_DSI_PRD_REF_DEF); + write32(&mipi_tx_reg->cdphy_preserved, 0xFFFF0030); + } + + if (data_rate >= 2000 * MHz) { + txdiv0 = 0; + } else if (data_rate >= 1000 * MHz) { + txdiv0 = 1; + } else if (data_rate >= 500 * MHz) { + txdiv0 = 2; + } else if (data_rate > 250 * MHz) { + /* (data_rate == 250MHz) is a special case that should go to the + else-block below (txdiv0 = 4) */ + txdiv0 = 3; + } else { + /* MIN = 125 */ + assert(data_rate >= MTK_DSI_DATA_RATE_MIN_MHZ * MHz); + txdiv0 = 4; + } + + if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) + mtk_dsi_cphy_lane_sel_setting(mipi_tx_reg); + + clrbits32(&mipi_tx_reg->pll_con4, BIT(11) | BIT(10)); + setbits32(&mipi_tx_reg->pll_pwr, AD_DSI_PLL_SDM_PWR_ON); + udelay(30); + clrbits32(&mipi_tx_reg->pll_pwr, AD_DSI_PLL_SDM_ISO_EN); + + pcw = (u64)(data_rate >> 1) * (1 << txdiv0); + pcw <<= 24; + pcw /= CLK26M_HZ; + + write32(&mipi_tx_reg->pll_con0, pcw); + clrsetbits32(&mipi_tx_reg->pll_con1, RG_DSI_PLL_POSDIV, txdiv0 << 8); + udelay(30); + setbits32(&mipi_tx_reg->pll_con1, RG_DSI_PLL_EN); + + /* BG_LPF_EN / BG_CORE_EN */ + write32(&mipi_tx_reg->lane_con, 0x3FFF0180); + udelay(40); + write32(&mipi_tx_reg->lane_con, 0x3FFF00C0); + + if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) + mtk_dsi_cphy_enable(mipi_tx_reg); + + /* Switch OFF each Lane */ + clrbits32(&mipi_tx_reg->d0_sw_ctl_en, DSI_SW_CTL_EN); + clrbits32(&mipi_tx_reg->d1_sw_ctl_en, DSI_SW_CTL_EN); + clrbits32(&mipi_tx_reg->d2_sw_ctl_en, DSI_SW_CTL_EN); + clrbits32(&mipi_tx_reg->d3_sw_ctl_en, DSI_SW_CTL_EN); + clrbits32(&mipi_tx_reg->ck_sw_ctl_en, DSI_SW_CTL_EN); + + if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) + mtk_dsi_cphy_disable_ck_mode(mipi_tx_reg); + else + mtk_dsi_dphy_disable_ck_mode(mipi_tx_reg); +} + +void mtk_dsi_reset(struct dsi_regs *dsi_reg) +{ + write32(&dsi_reg->dsi_shadow_ctrl, DSI_FORCE_COMMIT_ALWAYS); + write32(&dsi_reg->dsi_con_ctrl, 1); + write32(&dsi_reg->dsi_con_ctrl, 0); +} diff --git a/src/soc/mediatek/mt8196/include/soc/ddp.h b/src/soc/mediatek/mt8196/include/soc/ddp.h index 2c91747345..5d0130842f 100644 --- a/src/soc/mediatek/mt8196/include/soc/ddp.h +++ b/src/soc/mediatek/mt8196/include/soc/ddp.h @@ -539,17 +539,55 @@ check_member(disp_postmask_regs, size, 0x30); struct disp_dsc_regs { u32 dsc_con; - u32 reserved0x4[5]; + u32 dsc_inten; + u32 dsc_intsta; + u32 dsc_intack; + u32 dsc_sta; + u32 dsc_spr; u32 pic_w; u32 pic_h; - u32 reserved0x20; - u32 reserved0x24; + u32 dsc_slice_w; + u32 dsc_slice_h; u32 chunk_size; + u32 dsc_buf_size; + u32 dsc_mode; + u32 dsc_cfg; + u32 dsc_pad; + u32 dsc_enc_width; + u32 dsc_pic_pre_pad_size; + u32 dsc_pic_pre_pad_value; + u32 reserved0[6]; + u32 dsc_dbg_con; + u32 dsc_cksm_mon0; + u32 dsc_cksm_mon1; + u32 dsc_resv; + u32 dsc_obuf; + u32 dsc_obuf_mon; + u32 dsc_mute_con; + u32 dsc_ddren; + u32 dsc_pps[12]; + u32 dsc_pps_rc_range_params[8]; + u32 reserved1[12]; + u32 dsc_dbg[21]; + u32 reserved2[3]; + u32 dsc_enc_dbg[5]; + u32 dsc_enc_cov; + u32 reserved3[34]; + u32 dsc_shadow; + u32 reserved4[7]; + u32 dsc_dummy; + u32 reserved5; + u32 shadow_ctrl; + u32 reserved6; + u32 dsc_up_inten; + u32 dsc_up_intsta; + u32 dsc_up_intack; }; -check_member(disp_dsc_regs, dsc_con, 0x0); -check_member(disp_dsc_regs, pic_w, 0x18); -check_member(disp_dsc_regs, pic_h, 0x1C); -check_member(disp_dsc_regs, chunk_size, 0x28); +check_member(disp_dsc_regs, dsc_slice_w, 0x20); +check_member(disp_dsc_regs, dsc_dbg_con, 0x60); +check_member(disp_dsc_regs, dsc_enc_cov, 0x174); +check_member(disp_dsc_regs, dsc_shadow, 0x200); +check_member(disp_dsc_regs, dsc_up_intack, 0x238); static struct disp_mdp_rsz_regs *const disp_mdp_rsz0_reg = (void *)DISP_MDP_RSZ0_BASE; static struct disp_mdp_rsz_regs *const disp_mdp_rsz1_reg = (void *)DISP_MDP_RSZ1_BASE; diff --git a/src/soc/mediatek/mt8196/mtk_mipi_dphy.c b/src/soc/mediatek/mt8196/mtk_mipi_dphy.c new file mode 100644 index 0000000000..62001ec254 --- /dev/null +++ b/src/soc/mediatek/mt8196/mtk_mipi_dphy.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include + +#define PHY_TIMING_DIV(x) (((x) / 8000) + 1) + +void mtk_dsi_dphy_timing_calculation(u32 data_rate_mhz, struct mtk_phy_timing *timing) +{ + u32 temp; + timing->lpx = ALIGN_UP(PHY_TIMING_DIV(80 * data_rate_mhz), 2); + timing->da_hs_prepare = ALIGN_UP(PHY_TIMING_DIV(59 * data_rate_mhz + 4 * 1000), 2); + timing->da_hs_zero = PHY_TIMING_DIV(163 * data_rate_mhz + 11 * 1000) - + timing->da_hs_prepare; + + temp = data_rate_mhz < 740 ? 443 : 420; + timing->da_hs_trail = PHY_TIMING_DIV(66 * data_rate_mhz + temp * 100); + timing->ta_go = 4 * timing->lpx; + timing->ta_sure = 3 * timing->lpx / 2; + timing->ta_get = 5 * timing->lpx; + timing->da_hs_exit = ALIGN_UP(PHY_TIMING_DIV(118 * data_rate_mhz), 2); + timing->da_hs_sync = 1; + + timing->clk_hs_prepare = ALIGN_UP(PHY_TIMING_DIV(57 * data_rate_mhz), 2); + timing->clk_hs_post = PHY_TIMING_DIV(65 * data_rate_mhz + 53 * 1000); + timing->clk_hs_trail = PHY_TIMING_DIV(65 * data_rate_mhz + 52 * 1000); + timing->clk_hs_zero = PHY_TIMING_DIV(330 * data_rate_mhz) - timing->clk_hs_prepare; + timing->clk_hs_exit = PHY_TIMING_DIV(118 * data_rate_mhz); +} From 65833355ca36029eff45838068f32b6db8fb5972 Mon Sep 17 00:00:00 2001 From: Felix Singer Date: Thu, 18 Dec 2025 19:18:27 +0100 Subject: [PATCH 003/789] tests: Disable gcov warnings Newer gcov/lcov versions shipped in CI container images throw a warning and thus cause the CI to fail. It's unclear how to fix this warning at the moment, but gcov isn't critical anyway. So disable this specific warning for now, so that we can roll out new CI images. Excluding file '/home/coreboot/node-root/workspace/test_coreboot/payloads/libpayload/tests/libcbfs/cbfs-lookup-test.c' lcov: WARNING: (inconsistent) /home/coreboot/node-root/workspace/test_coreboot/payloads/libpayload/libcbfs/cbfs.c:79: unexecuted block on non-branch line with non-zero hit count. Use "geninfo --rc geninfo_unexecuted_blocks=1 to set count to zero. (use "lcov --ignore-errors inconsistent,inconsistent ..." to suppress this warning) Excluding file '/home/coreboot/node-root/workspace/test_coreboot/payloads/libpayload/tests/libcbfs/cbfs-lookup-test.c' [snip] Message summary: 1 warning message: inconsistent: 1 genhtml: ERROR: (corrupt) unable to read trace file 'build/coverage/tests.info': genhtml: ERROR: (inconsistent) "/home/coreboot/node-root/workspace/test_coreboot/payloads/libpayload/libcbfs/cbfs.c":77: function 'cbfs_unmap' is not hit but line 79 is. To skip consistency checks, see the 'check_data_consistency' section in man lcovrc(5). (use "genhtml --ignore-errors inconsistent ..." to bypass this error) (use "genhtml --ignore-errors corrupt ..." to bypass this error) make[1]: *** [tests/Makefile.mk:277: coverage-report] Error 1 make: *** [util/testing/Makefile.mk:103: what-jenkins-does] Error 2 Change-Id: I2c52c53fbe856a8bca062f34c576fdfda3818f2b Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/90554 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- payloads/libpayload/tests/Makefile.mk | 2 +- tests/Makefile.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/payloads/libpayload/tests/Makefile.mk b/payloads/libpayload/tests/Makefile.mk index a6cee5f480..9ab8c3b71c 100644 --- a/payloads/libpayload/tests/Makefile.mk +++ b/payloads/libpayload/tests/Makefile.mk @@ -273,7 +273,7 @@ clean-junit.xml-unit-tests: ifeq ($(COV),1) coverage-report: - lcov -o $(testobj)/tests.info -c -d $(testobj) --exclude '$(testsrc)/*' + lcov --ignore-errors inconsistent -o $(testobj)/tests.info -c -d $(testobj) --exclude '$(testsrc)/*' genhtml -q -o $(coverage-dir) -t "coreboot unit tests" -s $(testobj)/tests.info clean-coverage-report: diff --git a/tests/Makefile.mk b/tests/Makefile.mk index f3f122dd38..08ba3dc3cb 100644 --- a/tests/Makefile.mk +++ b/tests/Makefile.mk @@ -149,7 +149,7 @@ clean-junit.xml-unit-tests: ifeq ($(COV),1) coverage-report: lcov -o $(testobj)/tests.info -c -d $(testobj) --exclude '$(testsrc)/*' - genhtml -q -o $(testobj)/$(coverage_dir) -t "coreboot unit tests" \ + genhtml --ignore-errors inconsistent,corrupt -q -o $(testobj)/$(coverage_dir) -t "coreboot unit tests" \ -s $(testobj)/tests.info clean-coverage-report: From d528561130af22a2bc73ced71cd43df2ac5faeed Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Thu, 18 Dec 2025 19:26:31 +0530 Subject: [PATCH 004/789] mb/google/bluey: Use PMIC for off-mode detection Refactor boot mode detection to use is_pon_on_ac() for identifying off-mode charging, relying on the underlying PMIC registers. Additionally, introduce is_pd_sync_required() to centralize logic for enabling Power Delivery negotiation during off-mode, low battery, or no-battery boot scenarios. BUG=b:457566143 TEST=Verify different boot modes on Google/Quenbi. Change-Id: I7bdece2fc920310f3b1c59a1a6b90cf3bd03e3d9 Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90551 Tested-by: build bot (Jenkins) Reviewed-by: Jayvik Desai Reviewed-by: Subrata Banik --- src/mainboard/google/bluey/romstage.c | 35 ++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index 3c5b307fd8..e21777b715 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -27,16 +28,7 @@ static enum boot_mode_t boot_mode = LB_BOOT_MODE_NORMAL; */ bool is_off_mode(void) { - const uint64_t manual_pwron_event_mask = - (EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON) | - EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)); - uint64_t ec_events = google_chromeec_get_events_b(); - - if (!(ec_events & manual_pwron_event_mask) && - (ec_events & EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED))) - return true; - - return false; + return is_pon_on_ac(); } static enum boot_mode_t set_boot_mode(void) @@ -53,12 +45,32 @@ static enum boot_mode_t set_boot_mode(void) return boot_mode_new; } +static bool is_pd_sync_required(void) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC)) + return false; + + const uint64_t manual_pwron_event_mask = + (EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON) | + EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)); + uint64_t ec_events = google_chromeec_get_events_b(); + + if (!(ec_events & manual_pwron_event_mask) && + (ec_events & EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED))) + return true; + + if (google_chromeec_is_below_critical_threshold() || !google_chromeec_is_battery_present()) + return true; + + return false; +} + int qclib_mainboard_override(struct qclib_cb_if_table *table) { if (!CONFIG(EC_GOOGLE_CHROMEEC)) return 0; - if ((set_boot_mode() != LB_BOOT_MODE_NORMAL) || !google_chromeec_is_battery_present()) + if (is_pd_sync_required()) table->global_attributes |= QCLIB_GA_ENABLE_PD_NEGOTIATION; else table->global_attributes &= ~QCLIB_GA_ENABLE_PD_NEGOTIATION; @@ -75,6 +87,7 @@ void platform_romstage_main(void) /* QCLib: DDR init & train */ qclib_load_and_run(); + /* Underlying PMIC registers are accessible only at this point */ set_boot_mode(); aop_fw_load_reset(); From d1e1003217c764ebf27428066cac974ba78070da Mon Sep 17 00:00:00 2001 From: Zheng Li Date: Wed, 19 Nov 2025 11:34:33 +0800 Subject: [PATCH 005/789] spd/lp5: Add SPD for MT62F2G32D4DS-031RFWT:C Add MT62F2G32D4DS-031RFWT:C in the memory_parts.json and re-generate the SPD. Micron: MT62F2G32D4DS-031RFWT:C BUG=b:447273470 TEST=util/spd_tools/bin/spd_gen spd/lp5/memory_parts.json lp5 Change-Id: I2dc0151db31ed07c61454e800d539c9b546a1ea7 Signed-off-by: Zheng Li Reviewed-on: https://review.coreboot.org/c/coreboot/+/90109 Tested-by: build bot (Jenkins) Reviewed-by: Kun Liu Reviewed-by: Eric Lai --- spd/lp5/memory_parts.json | 10 ++++++++++ spd/lp5/set-0/parts_spd_manifest.generated.txt | 1 + spd/lp5/set-1/parts_spd_manifest.generated.txt | 1 + 3 files changed, 12 insertions(+) diff --git a/spd/lp5/memory_parts.json b/spd/lp5/memory_parts.json index c012c2eb50..bb725fcb73 100644 --- a/spd/lp5/memory_parts.json +++ b/spd/lp5/memory_parts.json @@ -413,6 +413,16 @@ "ranksPerChannel": 1, "speedMbps": 6400 } + }, + { + "name": "MT62F2G32D4DS-031RF WT:C", + "attribs": { + "densityPerDieGb": 16, + "diesPerPackage": 4, + "bitWidthPerChannel": 16, + "ranksPerChannel": 2, + "speedMbps": 6400 + } } ] } diff --git a/spd/lp5/set-0/parts_spd_manifest.generated.txt b/spd/lp5/set-0/parts_spd_manifest.generated.txt index 9566fc2752..7d3c3f378a 100644 --- a/spd/lp5/set-0/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-0/parts_spd_manifest.generated.txt @@ -40,3 +40,4 @@ K3KLALA0EM-MGCU,spd-13.hex MT62F1G32D2DS-020 WT:D,spd-11.hex K3KL8L80EM-MGCV,spd-11.hex MT62F1G32D2DS-031RF WT:C,spd-3.hex +MT62F2G32D4DS-031RF WT:C,spd-6.hex diff --git a/spd/lp5/set-1/parts_spd_manifest.generated.txt b/spd/lp5/set-1/parts_spd_manifest.generated.txt index 9566fc2752..7d3c3f378a 100644 --- a/spd/lp5/set-1/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-1/parts_spd_manifest.generated.txt @@ -40,3 +40,4 @@ K3KLALA0EM-MGCU,spd-13.hex MT62F1G32D2DS-020 WT:D,spd-11.hex K3KL8L80EM-MGCV,spd-11.hex MT62F1G32D2DS-031RF WT:C,spd-3.hex +MT62F2G32D4DS-031RF WT:C,spd-6.hex From a3adf4898b32360f55689f64fead81e96c9b463e Mon Sep 17 00:00:00 2001 From: Zheng Li Date: Thu, 11 Dec 2025 10:53:46 +0800 Subject: [PATCH 006/789] mb/google/brya/var/pujjocento: Add 2 Micron modules to RAM id table Add support for the new memory Micron MT62F1G32D2DS-031RF WT:C using spd-3.hex, and MT62F2G32D4DS-031RF WT:C using spd-6.hex DRAM Part Name ID to assign K3KL6L60GM-MGCT 0 (0000) H9JCNNNBK3MLYR-N6E 1 (0001) H58G56CK8BX146 2 (0010) K3KL8L80CM-MGCT 3 (0011) MT62F1G32D2DS-031RF WT:C 4 (0100) MT62F2G32D4DS-031RF WT:C 5 (0101) BUG=b:447273470 BRANCH=firmware-trulo-15217.771.B TEST=util/spd_tools/bin/part_id_gen ADL lp5 \ src/mainboard/google/brya/variants/pujjocento/memory \ src/mainboard/google/brya/variants/pujjocento/memory/mem_parts_used.txt Change-Id: Ica96fefb3fb8b18ed693383641960c67e128e7e7 Signed-off-by: Zheng Li Reviewed-on: https://review.coreboot.org/c/coreboot/+/90454 Reviewed-by: Eric Lai Reviewed-by: Kun Liu Tested-by: build bot (Jenkins) --- .../google/brya/variants/pujjocento/memory/Makefile.mk | 2 ++ .../brya/variants/pujjocento/memory/dram_id.generated.txt | 2 ++ .../google/brya/variants/pujjocento/memory/mem_parts_used.txt | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/mainboard/google/brya/variants/pujjocento/memory/Makefile.mk b/src/mainboard/google/brya/variants/pujjocento/memory/Makefile.mk index c60f5439fe..5c2e43e1aa 100644 --- a/src/mainboard/google/brya/variants/pujjocento/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/pujjocento/memory/Makefile.mk @@ -8,3 +8,5 @@ SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 0(0b0000) Parts = K3KL6L60GM SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 1(0b0001) Parts = H9JCNNNBK3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 2(0b0010) Parts = H58G56CK8BX146 SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = K3KL8L80CM-MGCT +SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 4(0b0100) Parts = MT62F1G32D2DS-031RF WT:C +SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = MT62F2G32D4DS-031RF WT:C diff --git a/src/mainboard/google/brya/variants/pujjocento/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/pujjocento/memory/dram_id.generated.txt index 94e605c7b2..d7e389d451 100644 --- a/src/mainboard/google/brya/variants/pujjocento/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/pujjocento/memory/dram_id.generated.txt @@ -8,3 +8,5 @@ K3KL6L60GM-MGCT 0 (0000) H9JCNNNBK3MLYR-N6E 1 (0001) H58G56CK8BX146 2 (0010) K3KL8L80CM-MGCT 3 (0011) +MT62F1G32D2DS-031RF WT:C 4 (0100) +MT62F2G32D4DS-031RF WT:C 5 (0101) diff --git a/src/mainboard/google/brya/variants/pujjocento/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/pujjocento/memory/mem_parts_used.txt index e38d99697d..6d5723fdbf 100644 --- a/src/mainboard/google/brya/variants/pujjocento/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/pujjocento/memory/mem_parts_used.txt @@ -13,3 +13,5 @@ K3KL6L60GM-MGCT H9JCNNNBK3MLYR-N6E H58G56CK8BX146 K3KL8L80CM-MGCT +MT62F1G32D2DS-031RF WT:C +MT62F2G32D4DS-031RF WT:C From 76e963534602ac1a100a622e0cfc7e0ea3638839 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Tue, 2 Dec 2025 08:36:14 +0100 Subject: [PATCH 007/789] amdfwread: Parse and print directory sizes Parse the directory table size field and print along walking the PSP directory tables. Example output: Table: FW Offset Size PSPL1: Dir [0x00b10000-0x00b12000) +-->PSPL1: 0x48 0x00b30000 0x00010000 +-->PSPL2: Dir [0x00030000-0x00081000) +-->PSPL2: 0x00 0x00040000 0x00000440 Change-Id: I355c301c83af25524353a2e980066ce78b01fc37 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/90329 Tested-by: build bot (Jenkins) Reviewed-by: Alicja Michalska Reviewed-by: Matt DeVillier --- util/amdfwtool/amdfwread.c | 96 +++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 6 deletions(-) diff --git a/util/amdfwtool/amdfwread.c b/util/amdfwtool/amdfwread.c index ddd0bc3fb0..46884f1e48 100644 --- a/util/amdfwtool/amdfwread.c +++ b/util/amdfwtool/amdfwread.c @@ -113,6 +113,9 @@ static int read_psp_directory(FILE *fw, uint32_t offset, uint32_t expected_cooki return 1; } + if (!entries || !num_entries) + return 0; + /* Read the entries */ *num_entries = header->num_entries; *entries = malloc(sizeof(psp_directory_entry) * header->num_entries); @@ -148,6 +151,9 @@ static int read_bios_directory(FILE *fw, uint32_t offset, uint32_t expected_cook return 1; } + if (!entries || !num_entries) + return 0; + /* Read the entries */ *num_entries = header->num_entries; *entries = malloc(sizeof(bios_directory_entry) * header->num_entries); @@ -313,6 +319,64 @@ static int amdfw_bios_dir_walk(FILE *fw, uint32_t bios_offset, uint32_t cookie, return 0; } +/* + * Returns the size of the PSP directory. + * + * @param fw File to operate on + * @param psp_offset Relative offset to PSP directory + * @param cookie Expected table cookie + * @param size Where to write the size to + * + * @return 0 on success, or < 0 on error. + */ +static int amdfw_psp_dir_size(FILE *fw, uint32_t psp_offset, uint32_t cookie, uint32_t *size) +{ + psp_directory_header header; + + if (!fw || !size) + return -1; + + if (read_psp_directory(fw, psp_offset, cookie, &header, NULL, NULL) != 0) + return -1; + + if (header.additional_info_fields.version == 1) + *size = header.additional_info_fields_v1.dir_size; + else + *size = header.additional_info_fields.dir_size; + + *size *= TABLE_ALIGNMENT; + return 0; +} + +/* + * Returns the size of the BIOS directory. + * + * @param fw File to operate on + * @param bios_offset Relative offset to BIOS directory + * @param cookie Expected table cookie + * @param size Where to write the size to + * + * @return 0 on success, or < 0 on error. + */ +static int amdfw_bios_dir_size(FILE *fw, uint32_t bios_offset, uint32_t cookie, uint32_t *size) +{ + bios_directory_hdr header; + + if (!fw || !size) + return -1; + + if (read_bios_directory(fw, bios_offset, cookie, &header, NULL, NULL) != 0) + return -1; + + if (header.additional_info_fields.version == 1) + *size = header.additional_info_fields_v1.dir_size; + else + *size = header.additional_info_fields.dir_size; + + *size *= TABLE_ALIGNMENT; + return 0; +} + static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, uint8_t level) { psp_directory_entry *current_entries = NULL; @@ -339,7 +403,7 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui uint32_t type = current_entries[i].type; uint64_t mode = current_entries[i].address_mode; uint64_t addr = current_entries[i].addr; - + uint32_t dir_size = 0; if (dir_mode < 2) mode = dir_mode; @@ -365,6 +429,10 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui l2_dir_offset = relative_offset(psp_offset, addr, mode); printf(" %sPSPL2: Dir 0x%08x\n", indent, l2_dir_offset); + if (amdfw_psp_dir_size(fw, l2_dir_offset, PSPL2_COOKIE, &dir_size) == 0) + printf(" %sPSPL2: Dir [0x%08x-0x%08x)\n", indent, l2_dir_offset, l2_dir_offset + dir_size); + else + printf(" %sPSPL2: Dir @0x%08x\n", indent, l2_dir_offset); amdfw_psp_dir_walk(fw, l2_dir_offset, PSPL2_COOKIE, level + 2); break; @@ -384,13 +452,19 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui } l2_dir_offset = ish_dir.pl2_location; - printf(" %sPSPL2: Dir 0x%08x\n", indent, l2_dir_offset); + if (amdfw_psp_dir_size(fw, l2_dir_offset, PSPL2_COOKIE, &dir_size) == 0) + printf(" %sPSPL2: Dir [0x%08x-0x%08x)\n", indent, l2_dir_offset, l2_dir_offset + dir_size); + else + printf(" %sPSPL2: Dir @0x%08x\n", indent, l2_dir_offset); amdfw_psp_dir_walk(fw, l2_dir_offset, PSPL2_COOKIE, level + 2); break; case AMD_FW_BIOS_TABLE: bios_dir_offset = relative_offset(psp_offset, addr, mode); - printf(" %sBIOSL2: Dir 0x%08x\n", indent, bios_dir_offset); + if (amdfw_bios_dir_size(fw, bios_dir_offset, BHDL2_COOKIE, &dir_size) == 0) + printf(" %sBIOSL2: Dir [0x%08x-0x%08x)\n", indent, bios_dir_offset, bios_dir_offset + dir_size); + else + printf(" %sBIOSL2: Dir @0x%08x\n", indent, bios_dir_offset); amdfw_bios_dir_walk(fw, bios_dir_offset, BHDL2_COOKIE, level + 2); break; @@ -406,7 +480,7 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui static int list_amdfw_psp_dir(FILE *fw, const embedded_firmware *fw_header) { - uint32_t psp_offset = 0; + uint32_t psp_offset = 0, dir_size = 0; /* 0xffffffff or 0x00000000 indicates that the offset is in new_psp_directory */ if (fw_header->psp_directory != 0xffffffff && fw_header->psp_directory != 0x00000000) @@ -414,18 +488,28 @@ static int list_amdfw_psp_dir(FILE *fw, const embedded_firmware *fw_header) else psp_offset = fw_header->new_psp_directory; - printf("PSPL1: Dir 0x%08x\n", psp_offset); + if (amdfw_psp_dir_size(fw, psp_offset, PSP_COOKIE, &dir_size) == 0) + printf("PSPL1: Dir [0x%08x-0x%08x)\n", psp_offset, psp_offset + dir_size); + else + printf("PSPL1: Dir @0x%08x\n", psp_offset); + amdfw_psp_dir_walk(fw, psp_offset, PSP_COOKIE, 0); return 0; } static int list_amdfw_bios_dir(FILE *fw, const embedded_firmware *fw_header) { + uint32_t dir_size = 0; + /* 0xffffffff or 0x00000000 implies that the SoC uses recovery A/B layout. Only BIOS L2 directory is present and that too as part of PSP L2 directory. */ if (fw_header->bios3_entry != 0xffffffff && fw_header->bios3_entry != 0x00000000) { - printf("BIOSL1: Dir 0x%08x\n", fw_header->bios3_entry); + if (amdfw_psp_dir_size(fw, fw_header->bios3_entry, BHD_COOKIE, &dir_size) == 0) + printf("BIOSL1: Dir [0x%08x-0x%08x)\n", fw_header->bios3_entry, fw_header->bios3_entry + dir_size); + else + printf("BIOSL1: Dir @0x%08x\n", fw_header->bios3_entry); + amdfw_bios_dir_walk(fw, fw_header->bios3_entry, BHD_COOKIE, 0); } return 0; From 0302b2ee07782761f6efa8088af6ab930d1613a1 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 22 Nov 2025 11:47:16 +0100 Subject: [PATCH 008/789] lib/xxhash: Move to commonlib/bsd Move the xxhash lib to commonlib/bsd folder so that it can be easily included by tools. Update use of standard headers to allow compilation on POSIX compatible systems as well. Use the new xxhash lib in cbfstool over the existing duplicated xxhash lib residing in lz4/lib. Change-Id: I21041409d5b734cecf43294dcaf3bf17531dbc15 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/89682 Reviewed-by: Matt DeVillier Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) --- src/commonlib/Makefile.mk | 2 + .../bsd/include/commonlib/bsd}/xxhash.h | 3 +- src/{lib => commonlib/bsd}/xxhash.c | 3 +- src/drivers/mrc_cache/mrc_cache.c | 2 +- src/lib/Makefile.mk | 3 - src/soc/amd/common/block/apob/apob_cache.c | 2 +- util/cbfstool/cbfstool.c | 2 +- util/cbfstool/lz4/lib/lz4_xxhash.h | 13 + util/cbfstool/lz4/lib/lz4frame.c | 2 +- util/cbfstool/lz4/lib/xxhash.c | 962 ------------------ util/cbfstool/lz4/lib/xxhash.h | 192 ---- 11 files changed, 22 insertions(+), 1164 deletions(-) rename src/{include => commonlib/bsd/include/commonlib/bsd}/xxhash.h (99%) rename src/{lib => commonlib/bsd}/xxhash.c (99%) create mode 100644 util/cbfstool/lz4/lib/lz4_xxhash.h delete mode 100644 util/cbfstool/lz4/lib/xxhash.c delete mode 100644 util/cbfstool/lz4/lib/xxhash.h diff --git a/src/commonlib/Makefile.mk b/src/commonlib/Makefile.mk index 91648c5170..44f63e1ea6 100644 --- a/src/commonlib/Makefile.mk +++ b/src/commonlib/Makefile.mk @@ -73,3 +73,5 @@ all-y += bsd/ipchksum.c decompressor-y += bsd/string.c smm-y += bsd/string.c all-y += bsd/string.c + +all-y += bsd/xxhash.c diff --git a/src/include/xxhash.h b/src/commonlib/bsd/include/commonlib/bsd/xxhash.h similarity index 99% rename from src/include/xxhash.h rename to src/commonlib/bsd/include/commonlib/bsd/xxhash.h index f6340cb791..a859b67d8a 100644 --- a/src/include/xxhash.h +++ b/src/commonlib/bsd/include/commonlib/bsd/xxhash.h @@ -46,7 +46,8 @@ #ifndef XXHASH_H #define XXHASH_H -#include +#include +#include /*-**************************** * Simple Hash Functions diff --git a/src/lib/xxhash.c b/src/commonlib/bsd/xxhash.c similarity index 99% rename from src/lib/xxhash.c rename to src/commonlib/bsd/xxhash.c index c14fb96815..e6c9d2edb7 100644 --- a/src/lib/xxhash.c +++ b/src/commonlib/bsd/xxhash.c @@ -9,10 +9,9 @@ * - xxHash source repository: https://github.com/Cyan4973/xxHash */ -#include +#include #include #include -#include /*-************************************* * Macros diff --git a/src/drivers/mrc_cache/mrc_cache.c b/src/drivers/mrc_cache/mrc_cache.c index a066fa8f3a..e6b1ed20a7 100644 --- a/src/drivers/mrc_cache/mrc_cache.c +++ b/src/drivers/mrc_cache/mrc_cache.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -14,7 +15,6 @@ #include #include #include -#include #include "mrc_cache.h" diff --git a/src/lib/Makefile.mk b/src/lib/Makefile.mk index 073d9fbb68..9deefaf95b 100644 --- a/src/lib/Makefile.mk +++ b/src/lib/Makefile.mk @@ -275,9 +275,6 @@ postcar-y += crc_byte.c ramstage-y += crc_byte.c smm-y += crc_byte.c -romstage-y += xxhash.c -ramstage-y += xxhash.c - postcar-y += bootmode.c postcar-y += boot_device.c postcar-y += cbfs.c diff --git a/src/soc/amd/common/block/apob/apob_cache.c b/src/soc/amd/common/block/apob/apob_cache.c index 713826a297..d70adfc5b2 100644 --- a/src/soc/amd/common/block/apob/apob_cache.c +++ b/src/soc/amd/common/block/apob/apob_cache.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,7 +17,6 @@ #include #include #include -#include #define DEFAULT_MRC_CACHE "RW_MRC_CACHE" #define DEFAULT_MRC_CACHE_SIZE FMAP_SECTION_RW_MRC_CACHE_SIZE diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index 1b9931063e..5555b57364 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -14,7 +14,7 @@ #include "cbfs_sections.h" #include "elfparsing.h" #include "partitioned_file.h" -#include "lz4/lib/xxhash.h" +#include "lz4/lib/lz4_xxhash.h" #include #include #include diff --git a/util/cbfstool/lz4/lib/lz4_xxhash.h b/util/cbfstool/lz4/lib/lz4_xxhash.h new file mode 100644 index 0000000000..2e380e4e20 --- /dev/null +++ b/util/cbfstool/lz4/lib/lz4_xxhash.h @@ -0,0 +1,13 @@ +#include + +typedef struct xxh64_state XXH64_state_t; +#define XXH64_update xxh64_update +#define XXH64_reset xxh64_reset +#define XXH64_digest xxh64_digest +#define XXH64 xxh64 + +typedef struct xxh32_state XXH32_state_t; +#define XXH32_update xxh32_update +#define XXH32_reset xxh32_reset +#define XXH32_digest xxh32_digest +#define XXH32 xxh32 diff --git a/util/cbfstool/lz4/lib/lz4frame.c b/util/cbfstool/lz4/lib/lz4frame.c index aef508d8df..8aebc63cd3 100644 --- a/util/cbfstool/lz4/lib/lz4frame.c +++ b/util/cbfstool/lz4/lib/lz4frame.c @@ -62,7 +62,7 @@ You can contact the author at : #include "lz4frame_static.h" #include "lz4.h" #include "lz4hc.h" -#include "xxhash.h" +#include "lz4_xxhash.h" /************************************** diff --git a/util/cbfstool/lz4/lib/xxhash.c b/util/cbfstool/lz4/lib/xxhash.c deleted file mode 100644 index 0f896266f0..0000000000 --- a/util/cbfstool/lz4/lib/xxhash.c +++ /dev/null @@ -1,962 +0,0 @@ -/* -xxHash - Fast Hash algorithm -Copyright (C) 2012-2015, Yann Collet - -BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -You can contact the author at : -- xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - - -/************************************** -* Tuning parameters -**************************************/ -/* XXH_FORCE_MEMORY_ACCESS - * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. - * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. - * The below switch allow to select different access method for improved performance. - * Method 0 (default) : use `memcpy()`. Safe and portable. - * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). - * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. - * Method 2 : direct access. This method is portable but violate C standard. - * It can generate buggy code on targets which generate assembly depending on alignment. - * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) - * See http://stackoverflow.com/a/32095106/646947 for details. - * Prefer these methods in priority order (0 > 1 > 2) - */ -#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define XXH_FORCE_MEMORY_ACCESS 2 -# elif defined(__INTEL_COMPILER) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) -# define XXH_FORCE_MEMORY_ACCESS 1 -# endif -#endif - -/* XXH_ACCEPT_NULL_INPUT_POINTER : - * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. - * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. - * By default, this option is disabled. To enable it, uncomment below define : - */ -/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */ - -/* XXH_FORCE_NATIVE_FORMAT : - * By default, xxHash library provides endian-independent Hash values, based on little-endian convention. - * Results are therefore identical for little-endian and big-endian CPU. - * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. - * Should endian-independance be of no importance for your application, you may set the #define below to 1, - * to improve speed for Big-endian CPU. - * This option has no impact on Little_Endian CPU. - */ -#define XXH_FORCE_NATIVE_FORMAT 0 - -/* XXH_USELESS_ALIGN_BRANCH : - * This is a minor performance trick, only useful with lots of very small keys. - * It means : don't make a test between aligned/unaligned, because performance will be the same. - * It saves one initial branch per hash. - */ -#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_USELESS_ALIGN_BRANCH 1 -#endif - - -/************************************** -* Compiler Specific Options -***************************************/ -#ifdef _MSC_VER /* Visual Studio */ -# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ -# define FORCE_INLINE static __forceinline -#else -# if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# ifdef __GNUC__ -# define FORCE_INLINE static inline __attribute__((always_inline)) -# else -# define FORCE_INLINE static inline -# endif -# else -# define FORCE_INLINE static -# endif /* __STDC_VERSION__ */ -#endif - - -/************************************** -* Includes & Memory related functions -***************************************/ -#include "xxhash.h" -/* Modify the local functions below should you wish to use some other memory routines */ -/* for malloc(), free() */ -#include -static void* XXH_malloc(size_t s) { return malloc(s); } -static void XXH_free (void* p) { free(p); } -/* for memcpy() */ -#include -static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } - - -/************************************** -* Basic Types -***************************************/ -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# include - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef uint32_t U32; - typedef int32_t S32; - typedef uint64_t U64; -#else - typedef unsigned char BYTE; - typedef unsigned short U16; - typedef unsigned int U32; - typedef signed int S32; - typedef unsigned long long U64; -#endif - - -#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) - -/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ -static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } -static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } - -#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) - -/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ -/* currently only defined for gcc and icc */ -typedef union { U32 u32; U64 u64; } __packed unalign; - -static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } -static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } - -#else - -/* portable and safe solution. Generally efficient. - * see : http://stackoverflow.com/a/32095106/646947 - */ - -static U32 XXH_read32(const void* memPtr) -{ - U32 val; - memcpy(&val, memPtr, sizeof(val)); - return val; -} - -static U64 XXH_read64(const void* memPtr) -{ - U64 val; - memcpy(&val, memPtr, sizeof(val)); - return val; -} - -#endif // XXH_FORCE_DIRECT_MEMORY_ACCESS - - -/****************************************** -* Compiler-specific Functions and Macros -******************************************/ -#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) - -/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ -#if defined(_MSC_VER) -# define XXH_rotl32(x,r) _rotl(x,r) -# define XXH_rotl64(x,r) _rotl64(x,r) -#else -# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) -# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) -#endif - -#if defined(_MSC_VER) /* Visual Studio */ -# define XXH_swap32 _byteswap_ulong -# define XXH_swap64 _byteswap_uint64 -#elif GCC_VERSION >= 403 -# define XXH_swap32 __builtin_bswap32 -# define XXH_swap64 __builtin_bswap64 -#else -static U32 XXH_swap32 (U32 x) -{ - return ((x << 24) & 0xff000000 ) | - ((x << 8) & 0x00ff0000 ) | - ((x >> 8) & 0x0000ff00 ) | - ((x >> 24) & 0x000000ff ); -} -static U64 XXH_swap64 (U64 x) -{ - return ((x << 56) & 0xff00000000000000ULL) | - ((x << 40) & 0x00ff000000000000ULL) | - ((x << 24) & 0x0000ff0000000000ULL) | - ((x << 8) & 0x000000ff00000000ULL) | - ((x >> 8) & 0x00000000ff000000ULL) | - ((x >> 24) & 0x0000000000ff0000ULL) | - ((x >> 40) & 0x000000000000ff00ULL) | - ((x >> 56) & 0x00000000000000ffULL); -} -#endif - - -/*************************************** -* Architecture Macros -***************************************/ -typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianness; - -/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example one the compiler command line */ -#ifndef XXH_CPU_LITTLE_ENDIAN - static const int one = 1; -# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&one)) -#endif - - -/***************************** -* Memory reads -*****************************/ -typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; - -FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianness endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); - else - return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); -} - -FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianness endian) -{ - return XXH_readLE32_align(ptr, endian, XXH_unaligned); -} - -FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianness endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); - else - return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); -} - -FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianness endian) -{ - return XXH_readLE64_align(ptr, endian, XXH_unaligned); -} - - -/*************************************** -* Macros -***************************************/ -#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } /* use only *after* variable declarations */ - - -/*************************************** -* Constants -***************************************/ -#define PRIME32_1 2654435761U -#define PRIME32_2 2246822519U -#define PRIME32_3 3266489917U -#define PRIME32_4 668265263U -#define PRIME32_5 374761393U - -#define PRIME64_1 11400714785074694791ULL -#define PRIME64_2 14029467366897019727ULL -#define PRIME64_3 1609587929392839161ULL -#define PRIME64_4 9650029242287828579ULL -#define PRIME64_5 2870177450012600261ULL - - -/***************************** -* Simple Hash Functions -*****************************/ -FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianness endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U32 h32; -#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) - { - len=0; - bEnd=p=(const BYTE*)(size_t)16; - } -#endif - - if (len>=16) - { - const BYTE* const limit = bEnd - 16; - U32 v1 = seed + PRIME32_1 + PRIME32_2; - U32 v2 = seed + PRIME32_2; - U32 v3 = seed + 0; - U32 v4 = seed - PRIME32_1; - - do - { - v1 += XXH_get32bits(p) * PRIME32_2; - v1 = XXH_rotl32(v1, 13); - v1 *= PRIME32_1; - p+=4; - v2 += XXH_get32bits(p) * PRIME32_2; - v2 = XXH_rotl32(v2, 13); - v2 *= PRIME32_1; - p+=4; - v3 += XXH_get32bits(p) * PRIME32_2; - v3 = XXH_rotl32(v3, 13); - v3 *= PRIME32_1; - p+=4; - v4 += XXH_get32bits(p) * PRIME32_2; - v4 = XXH_rotl32(v4, 13); - v4 *= PRIME32_1; - p+=4; - } - while (p<=limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); - } - else - { - h32 = seed + PRIME32_5; - } - - h32 += (U32) len; - - while (p+4<=bEnd) - { - h32 += XXH_get32bits(p) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -unsigned int XXH32 (const void* input, size_t len, unsigned int seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH32_state_t state; - XXH32_reset(&state, seed); - XXH32_update(&state, input, len); - return XXH32_digest(&state); -#else - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - -# if !defined(XXH_USELESS_ALIGN_BRANCH) - if ((((size_t)input) & 3) == 0) /* Input is 4-bytes aligned, leverage the speed benefit */ - { - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } -# endif - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - -FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianness endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U64 h64; -#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) - { - len=0; - bEnd=p=(const BYTE*)(size_t)32; - } -#endif - - if (len>=32) - { - const BYTE* const limit = bEnd - 32; - U64 v1 = seed + PRIME64_1 + PRIME64_2; - U64 v2 = seed + PRIME64_2; - U64 v3 = seed + 0; - U64 v4 = seed - PRIME64_1; - - do - { - v1 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - v2 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - v3 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - v4 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - } - while (p<=limit); - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - - v1 *= PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - h64 ^= v1; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v2 *= PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - h64 ^= v2; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v3 *= PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - h64 ^= v3; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v4 *= PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - h64 ^= v4; - h64 = h64 * PRIME64_1 + PRIME64_4; - } - else - { - h64 = seed + PRIME64_5; - } - - h64 += (U64) len; - - while (p+8<=bEnd) - { - U64 k1 = XXH_get64bits(p); - k1 *= PRIME64_2; - k1 = XXH_rotl64(k1,31); - k1 *= PRIME64_1; - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) - { - h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH64_state_t state; - XXH64_reset(&state, seed); - XXH64_update(&state, input, len); - return XXH64_digest(&state); -#else - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - -# if !defined(XXH_USELESS_ALIGN_BRANCH) - if ((((size_t)input) & 7)==0) /* Input is aligned, let's leverage the speed advantage */ - { - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } -# endif - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - -/**************************************************** -* Advanced Hash Functions -****************************************************/ - -/*** Allocation ***/ -typedef struct -{ - U64 total_len; - U32 seed; - U32 v1; - U32 v2; - U32 v3; - U32 v4; - U32 mem32[4]; /* defined as U32 for alignment */ - U32 memsize; -} XXH_istate32_t; - -typedef struct -{ - U64 total_len; - U64 seed; - U64 v1; - U64 v2; - U64 v3; - U64 v4; - U64 mem64[4]; /* defined as U64 for alignment */ - U32 memsize; -} XXH_istate64_t; - - -XXH32_state_t* XXH32_createState(void) -{ - XXH_STATIC_ASSERT(sizeof(XXH32_state_t) >= sizeof(XXH_istate32_t)); /* A compilation error here means XXH32_state_t is not large enough */ - return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); -} -XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - -XXH64_state_t* XXH64_createState(void) -{ - XXH_STATIC_ASSERT(sizeof(XXH64_state_t) >= sizeof(XXH_istate64_t)); /* A compilation error here means XXH64_state_t is not large enough */ - return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); -} -XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - - -/*** Hash feed ***/ - -XXH_errorcode XXH32_reset(XXH32_state_t* state_in, unsigned int seed) -{ - XXH_istate32_t* state = (XXH_istate32_t*) state_in; - state->seed = seed; - state->v1 = seed + PRIME32_1 + PRIME32_2; - state->v2 = seed + PRIME32_2; - state->v3 = seed + 0; - state->v4 = seed - PRIME32_1; - state->total_len = 0; - state->memsize = 0; - return XXH_OK; -} - -XXH_errorcode XXH64_reset(XXH64_state_t* state_in, unsigned long long seed) -{ - XXH_istate64_t* state = (XXH_istate64_t*) state_in; - state->seed = seed; - state->v1 = seed + PRIME64_1 + PRIME64_2; - state->v2 = seed + PRIME64_2; - state->v3 = seed + 0; - state->v4 = seed - PRIME64_1; - state->total_len = 0; - state->memsize = 0; - return XXH_OK; -} - - -FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state_in, const void* input, size_t len, XXH_endianness endian) -{ - XXH_istate32_t* state = (XXH_istate32_t *) state_in; - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len += len; - - if (state->memsize + len < 16) /* fill in tmp buffer */ - { - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); - state->memsize += (U32)len; - return XXH_OK; - } - - if (state->memsize) /* some data left from previous update */ - { - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); - { - const U32* p32 = state->mem32; - state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v1 = XXH_rotl32(state->v1, 13); - state->v1 *= PRIME32_1; - p32++; - state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v2 = XXH_rotl32(state->v2, 13); - state->v2 *= PRIME32_1; - p32++; - state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v3 = XXH_rotl32(state->v3, 13); - state->v3 *= PRIME32_1; - p32++; - state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v4 = XXH_rotl32(state->v4, 13); - state->v4 *= PRIME32_1; - p32++; - } - p += 16-state->memsize; - state->memsize = 0; - } - - if (p <= bEnd-16) - { - const BYTE* const limit = bEnd - 16; - U32 v1 = state->v1; - U32 v2 = state->v2; - U32 v3 = state->v3; - U32 v4 = state->v4; - - do - { - v1 += XXH_readLE32(p, endian) * PRIME32_2; - v1 = XXH_rotl32(v1, 13); - v1 *= PRIME32_1; - p+=4; - v2 += XXH_readLE32(p, endian) * PRIME32_2; - v2 = XXH_rotl32(v2, 13); - v2 *= PRIME32_1; - p+=4; - v3 += XXH_readLE32(p, endian) * PRIME32_2; - v3 = XXH_rotl32(v3, 13); - v3 *= PRIME32_1; - p+=4; - v4 += XXH_readLE32(p, endian) * PRIME32_2; - v4 = XXH_rotl32(v4, 13); - v4 *= PRIME32_1; - p+=4; - } - while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) - { - XXH_memcpy(state->mem32, p, bEnd-p); - state->memsize = (int)(bEnd-p); - } - - return XXH_OK; -} - -XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) -{ - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH32_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state_in, XXH_endianness endian) -{ - const XXH_istate32_t* state = (const XXH_istate32_t*) state_in; - const BYTE * p = (const BYTE*)state->mem32; - const BYTE* bEnd = (const BYTE*)(state->mem32) + state->memsize; - U32 h32; - - if (state->total_len >= 16) - { - h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); - } - else - { - h32 = state->seed + PRIME32_5; - } - - h32 += (U32) state->total_len; - - while (p+4<=bEnd) - { - h32 += XXH_readLE32(p, endian) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -unsigned int XXH32_digest (const XXH32_state_t* state_in) -{ - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_digest_endian(state_in, XXH_littleEndian); - else - return XXH32_digest_endian(state_in, XXH_bigEndian); -} - - -FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state_in, const void* input, size_t len, XXH_endianness endian) -{ - XXH_istate64_t * state = (XXH_istate64_t *) state_in; - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len += len; - - if (state->memsize + len < 32) /* fill in tmp buffer */ - { - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); - state->memsize += (U32)len; - return XXH_OK; - } - - if (state->memsize) /* some data left from previous update */ - { - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); - { - const U64* p64 = state->mem64; - state->v1 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v1 = XXH_rotl64(state->v1, 31); - state->v1 *= PRIME64_1; - p64++; - state->v2 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v2 = XXH_rotl64(state->v2, 31); - state->v2 *= PRIME64_1; - p64++; - state->v3 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v3 = XXH_rotl64(state->v3, 31); - state->v3 *= PRIME64_1; - p64++; - state->v4 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v4 = XXH_rotl64(state->v4, 31); - state->v4 *= PRIME64_1; - p64++; - } - p += 32-state->memsize; - state->memsize = 0; - } - - if (p+32 <= bEnd) - { - const BYTE* const limit = bEnd - 32; - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; - - do - { - v1 += XXH_readLE64(p, endian) * PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - p+=8; - v2 += XXH_readLE64(p, endian) * PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - p+=8; - v3 += XXH_readLE64(p, endian) * PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - p+=8; - v4 += XXH_readLE64(p, endian) * PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - p+=8; - } - while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) - { - XXH_memcpy(state->mem64, p, bEnd-p); - state->memsize = (int)(bEnd-p); - } - - return XXH_OK; -} - -XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) -{ - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH64_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state_in, XXH_endianness endian) -{ - const XXH_istate64_t * state = (const XXH_istate64_t *) state_in; - const BYTE * p = (const BYTE*)state->mem64; - const BYTE* bEnd = (const BYTE*)state->mem64 + state->memsize; - U64 h64; - - if (state->total_len >= 32) - { - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - - v1 *= PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - h64 ^= v1; - h64 = h64*PRIME64_1 + PRIME64_4; - - v2 *= PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - h64 ^= v2; - h64 = h64*PRIME64_1 + PRIME64_4; - - v3 *= PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - h64 ^= v3; - h64 = h64*PRIME64_1 + PRIME64_4; - - v4 *= PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - h64 ^= v4; - h64 = h64*PRIME64_1 + PRIME64_4; - } - else - { - h64 = state->seed + PRIME64_5; - } - - h64 += (U64) state->total_len; - - while (p+8<=bEnd) - { - U64 k1 = XXH_readLE64(p, endian); - k1 *= PRIME64_2; - k1 = XXH_rotl64(k1,31); - k1 *= PRIME64_1; - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) - { - h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -unsigned long long XXH64_digest (const XXH64_state_t* state_in) -{ - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_digest_endian(state_in, XXH_littleEndian); - else - return XXH64_digest_endian(state_in, XXH_bigEndian); -} - - diff --git a/util/cbfstool/lz4/lib/xxhash.h b/util/cbfstool/lz4/lib/xxhash.h deleted file mode 100644 index c60aa61571..0000000000 --- a/util/cbfstool/lz4/lib/xxhash.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - xxHash - Extremely Fast Hash algorithm - Header File - Copyright (C) 2012-2015, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - You can contact the author at : - - xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - -/* Notice extracted from xxHash homepage : - -xxHash is an extremely fast Hash algorithm, running at RAM speed limits. -It also successfully passes all tests from the SMHasher suite. - -Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) - -Name Speed Q.Score Author -xxHash 5.4 GB/s 10 -CrapWow 3.2 GB/s 2 Andrew -MumurHash 3a 2.7 GB/s 10 Austin Appleby -SpookyHash 2.0 GB/s 10 Bob Jenkins -SBox 1.4 GB/s 9 Bret Mulvey -Lookup3 1.2 GB/s 9 Bob Jenkins -SuperFastHash 1.2 GB/s 1 Paul Hsieh -CityHash64 1.05 GB/s 10 Pike & Alakuijala -FNV 0.55 GB/s 5 Fowler, Noll, Vo -CRC32 0.43 GB/s 9 -MD5-32 0.33 GB/s 10 Ronald L. Rivest -SHA1-32 0.28 GB/s 10 - -Q.Score is a measure of quality of the hash function. -It depends on successfully passing SMHasher test set. -10 is a perfect score. - -A 64-bits version, named XXH64, is available since r35. -It offers much better speed, but for 64-bits applications only. -Name Speed on 64 bits Speed on 32 bits -XXH64 13.8 GB/s 1.9 GB/s -XXH32 6.8 GB/s 6.0 GB/s -*/ - -#pragma once - -#if defined (__cplusplus) -extern "C" { -#endif - - -/***************************** -* Definitions -*****************************/ -#include /* size_t */ -typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; - - -/***************************** -* Namespace Emulation -*****************************/ -/* Motivations : - -If you need to include xxHash into your library, -but wish to avoid xxHash symbols to be present on your library interface -in an effort to avoid potential name collision if another library also includes xxHash, - -you can use XXH_NAMESPACE, which will automatically prefix any symbol from xxHash -with the value of XXH_NAMESPACE (so avoid to keep it NULL, and avoid numeric values). - -Note that no change is required within the calling program : -it can still call xxHash functions using their regular name. -They will be automatically translated by this header. -*/ -#ifdef XXH_NAMESPACE -# define XXH_CAT(A,B) A##B -# define XXH_NAME2(A,B) XXH_CAT(A,B) -# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) -# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) -# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) -# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) -# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) -# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) -# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) -# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) -# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) -# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) -# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) -# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) -#endif - - -/***************************** -* Simple Hash Functions -*****************************/ - -unsigned int XXH32 (const void* input, size_t length, unsigned seed); -unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed); - -/* -XXH32() : - Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". - The memory between input & input+length must be valid (allocated and read-accessible). - "seed" can be used to alter the result predictably. - This function successfully passes all SMHasher tests. - Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s -XXH64() : - Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". - Faster on 64-bits systems. Slower on 32-bits systems. -*/ - - - -/***************************** -* Advanced Hash Functions -*****************************/ -typedef struct { long long ll[ 6]; } XXH32_state_t; -typedef struct { long long ll[11]; } XXH64_state_t; - -/* -These structures allow static allocation of XXH states. -States must then be initialized using XXHnn_reset() before first use. - -If you prefer dynamic allocation, please refer to functions below. -*/ - -XXH32_state_t* XXH32_createState(void); -XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); - -XXH64_state_t* XXH64_createState(void); -XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); - -/* -These functions create and release memory for XXH state. -States must then be initialized using XXHnn_reset() before first use. -*/ - - -XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned seed); -XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); -unsigned int XXH32_digest (const XXH32_state_t* statePtr); - -XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); -XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); -unsigned long long XXH64_digest (const XXH64_state_t* statePtr); - -/* -These functions calculate the xxHash of an input provided in multiple smaller packets, -as opposed to an input provided as a single block. - -XXH state space must first be allocated, using either static or dynamic method provided above. - -Start a new hash by initializing state with a seed, using XXHnn_reset(). - -Then, feed the hash state by calling XXHnn_update() as many times as necessary. -Obviously, input must be valid, meaning allocated and read accessible. -The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. - -Finally, you can produce a hash anytime, by using XXHnn_digest(). -This function returns the final nn-bits hash. -You can nonetheless continue feeding the hash state with more input, -and therefore get some new hashes, by calling again XXHnn_digest(). - -When you are done, don't forget to free XXH state space, using typically XXHnn_freeState(). -*/ - - -#if defined (__cplusplus) -} -#endif From 0421ef2cd844936660f31a8564b17deae8540a26 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 22 Nov 2022 16:17:10 +0100 Subject: [PATCH 009/789] util/cbfstool: Add zstd support This adds zstd support to cbfstool. The code is taken from zstd-1.5.7 with modifications: - renaming bits.h to zstd_bits.h to avoid conflicts with coreboot's bits.h used on riscv - renaming compiler.h to zstd_compiler.h to avoid conflicts with coreboot's compiler.h - Dropped all streaming API functions - Dropped multithreaded support, since it's now unused - Dropped local DDict support zstd offers similar compression ratios to LZMA, but a vastly fast decompress speed. Typically zstd results in slightly larger binaries than LZMA. Whether zstd should then be preferred over LZMA depends on a few things: - Caching: When loading from memory mapped boot devices, zstd will read the boot medium multiple times, while LZMA will not. If the memory mapped boot medium is not cached zstd results in much slower decompression. - Boot medium speed: Often, but not always LZMA results in smaller binaries. If the boot medium is the bottleneck, than loading smaller binaries might actually be faster. On a fast boot medium (high spi freq, using quad/dual io), the performance benefits from zstd might be more substantial - zstd decompression code has a much larger footprint than LZMA. If the stage (postcar) is loaded in uncached memory the size increase might slow things down. On QEMU Q35 postcar .text section size doubled, while heap section has growen by 50%. - zstd uses a lot of .bss (CTX is about 32KiB large). This might not be available in some environments. Orignal commit from 2022 was using zstd-1.5.2. Updated to zstd-1.5.7. Change-Id: I34508268f8767008ef25cb9e466d201345881232 Signed-off-by: Arthur Heymans Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/69753 Reviewed-by: Julius Werner Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- .../include/commonlib/bsd/cbfs_serialized.h | 1 + .../bsd/include/commonlib/bsd/compression.h | 3 + src/commonlib/bsd/zstd/common/allocations.h | 57 + src/commonlib/bsd/zstd/common/bitstream.h | 456 ++ src/commonlib/bsd/zstd/common/cpu.h | 251 + src/commonlib/bsd/zstd/common/debug.c | 32 + src/commonlib/bsd/zstd/common/debug.h | 109 + .../bsd/zstd/common/entropy_common.c | 342 + src/commonlib/bsd/zstd/common/error_private.c | 66 + src/commonlib/bsd/zstd/common/error_private.h | 160 + src/commonlib/bsd/zstd/common/fse.h | 627 ++ .../bsd/zstd/common/fse_decompress.c | 317 + src/commonlib/bsd/zstd/common/huf.h | 279 + src/commonlib/bsd/zstd/common/mem.h | 424 ++ .../bsd/zstd/common/portability_macros.h | 173 + src/commonlib/bsd/zstd/common/zstd_bits.h | 206 + src/commonlib/bsd/zstd/common/zstd_common.c | 50 + src/commonlib/bsd/zstd/common/zstd_compiler.h | 462 ++ src/commonlib/bsd/zstd/common/zstd_deps.h | 125 + src/commonlib/bsd/zstd/common/zstd_internal.h | 324 + src/commonlib/bsd/zstd/common/zstd_trace.h | 158 + src/commonlib/bsd/zstd/common/zstd_xxhash.h | 20 + src/commonlib/bsd/zstd/compress/clevels.h | 136 + .../bsd/zstd/compress/fse_compress.c | 627 ++ src/commonlib/bsd/zstd/compress/hist.c | 193 + src/commonlib/bsd/zstd/compress/hist.h | 84 + .../bsd/zstd/compress/huf_compress.c | 1466 ++++ .../bsd/zstd/compress/zstd_compress.c | 6046 +++++++++++++++++ .../zstd/compress/zstd_compress_internal.h | 1625 +++++ .../zstd/compress/zstd_compress_literals.c | 237 + .../zstd/compress/zstd_compress_literals.h | 41 + .../zstd/compress/zstd_compress_sequences.c | 444 ++ .../zstd/compress/zstd_compress_sequences.h | 57 + .../zstd/compress/zstd_compress_superblock.c | 690 ++ .../zstd/compress/zstd_compress_superblock.h | 34 + src/commonlib/bsd/zstd/compress/zstd_cwksp.h | 767 +++ .../bsd/zstd/compress/zstd_double_fast.c | 780 +++ .../bsd/zstd/compress/zstd_double_fast.h | 44 + src/commonlib/bsd/zstd/compress/zstd_fast.c | 987 +++ src/commonlib/bsd/zstd/compress/zstd_fast.h | 32 + src/commonlib/bsd/zstd/compress/zstd_lazy.c | 2201 ++++++ src/commonlib/bsd/zstd/compress/zstd_lazy.h | 195 + src/commonlib/bsd/zstd/compress/zstd_ldm.c | 747 ++ src/commonlib/bsd/zstd/compress/zstd_ldm.h | 111 + .../bsd/zstd/compress/zstd_ldm_geartab.h | 108 + src/commonlib/bsd/zstd/compress/zstd_opt.c | 1582 +++++ src/commonlib/bsd/zstd/compress/zstd_opt.h | 74 + .../bsd/zstd/compress/zstd_preSplit.c | 239 + .../bsd/zstd/compress/zstd_preSplit.h | 34 + .../bsd/zstd/decompress/huf_decompress.c | 1946 ++++++ .../bsd/zstd/decompress/zstd_ddict.c | 246 + .../bsd/zstd/decompress/zstd_ddict.h | 46 + .../bsd/zstd/decompress/zstd_decompress.c | 922 +++ .../zstd/decompress/zstd_decompress_block.c | 2188 ++++++ .../zstd/decompress/zstd_decompress_block.h | 69 + .../decompress/zstd_decompress_internal.h | 240 + src/commonlib/bsd/zstd/zdict.h | 483 ++ src/commonlib/bsd/zstd/zstd.h | 2646 ++++++++ src/commonlib/bsd/zstd/zstd_errors.h | 109 + util/cbfstool/Makefile.mk | 34 + util/cbfstool/cbfs.h | 1 + util/cbfstool/compress.c | 56 +- 62 files changed, 33208 insertions(+), 1 deletion(-) create mode 100644 src/commonlib/bsd/zstd/common/allocations.h create mode 100644 src/commonlib/bsd/zstd/common/bitstream.h create mode 100644 src/commonlib/bsd/zstd/common/cpu.h create mode 100644 src/commonlib/bsd/zstd/common/debug.c create mode 100644 src/commonlib/bsd/zstd/common/debug.h create mode 100644 src/commonlib/bsd/zstd/common/entropy_common.c create mode 100644 src/commonlib/bsd/zstd/common/error_private.c create mode 100644 src/commonlib/bsd/zstd/common/error_private.h create mode 100644 src/commonlib/bsd/zstd/common/fse.h create mode 100644 src/commonlib/bsd/zstd/common/fse_decompress.c create mode 100644 src/commonlib/bsd/zstd/common/huf.h create mode 100644 src/commonlib/bsd/zstd/common/mem.h create mode 100644 src/commonlib/bsd/zstd/common/portability_macros.h create mode 100644 src/commonlib/bsd/zstd/common/zstd_bits.h create mode 100644 src/commonlib/bsd/zstd/common/zstd_common.c create mode 100644 src/commonlib/bsd/zstd/common/zstd_compiler.h create mode 100644 src/commonlib/bsd/zstd/common/zstd_deps.h create mode 100644 src/commonlib/bsd/zstd/common/zstd_internal.h create mode 100644 src/commonlib/bsd/zstd/common/zstd_trace.h create mode 100644 src/commonlib/bsd/zstd/common/zstd_xxhash.h create mode 100644 src/commonlib/bsd/zstd/compress/clevels.h create mode 100644 src/commonlib/bsd/zstd/compress/fse_compress.c create mode 100644 src/commonlib/bsd/zstd/compress/hist.c create mode 100644 src/commonlib/bsd/zstd/compress/hist.h create mode 100644 src/commonlib/bsd/zstd/compress/huf_compress.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_compress.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_compress_internal.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_compress_literals.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_compress_literals.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_compress_sequences.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_compress_sequences.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_compress_superblock.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_compress_superblock.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_cwksp.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_double_fast.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_double_fast.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_fast.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_fast.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_lazy.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_lazy.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_ldm.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_ldm.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_ldm_geartab.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_opt.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_opt.h create mode 100644 src/commonlib/bsd/zstd/compress/zstd_preSplit.c create mode 100644 src/commonlib/bsd/zstd/compress/zstd_preSplit.h create mode 100644 src/commonlib/bsd/zstd/decompress/huf_decompress.c create mode 100644 src/commonlib/bsd/zstd/decompress/zstd_ddict.c create mode 100644 src/commonlib/bsd/zstd/decompress/zstd_ddict.h create mode 100644 src/commonlib/bsd/zstd/decompress/zstd_decompress.c create mode 100644 src/commonlib/bsd/zstd/decompress/zstd_decompress_block.c create mode 100644 src/commonlib/bsd/zstd/decompress/zstd_decompress_block.h create mode 100644 src/commonlib/bsd/zstd/decompress/zstd_decompress_internal.h create mode 100644 src/commonlib/bsd/zstd/zdict.h create mode 100644 src/commonlib/bsd/zstd/zstd.h create mode 100644 src/commonlib/bsd/zstd/zstd_errors.h diff --git a/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h b/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h index b6a7baa20e..7a0fb27755 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h +++ b/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h @@ -10,6 +10,7 @@ enum cbfs_compression { CBFS_COMPRESS_NONE = 0, CBFS_COMPRESS_LZMA = 1, CBFS_COMPRESS_LZ4 = 2, + CBFS_COMPRESS_ZSTD = 3, }; enum cbfs_type { diff --git a/src/commonlib/bsd/include/commonlib/bsd/compression.h b/src/commonlib/bsd/include/commonlib/bsd/compression.h index 873e7e4e15..1f70fa4c60 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/compression.h +++ b/src/commonlib/bsd/include/commonlib/bsd/compression.h @@ -18,4 +18,7 @@ size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn); /* Same as ulz4fn() but does not perform any bounds checks. */ size_t ulz4f(const void *src, void *dst); +/* Decompresses ZSTD image */ +size_t uzstdfn(const void *src, size_t srcn, void *dst, size_t dstn); + #endif /* _COMMONLIB_COMPRESSION_H_ */ diff --git a/src/commonlib/bsd/zstd/common/allocations.h b/src/commonlib/bsd/zstd/common/allocations.h new file mode 100644 index 0000000000..1bfa3db9e9 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/allocations.h @@ -0,0 +1,57 @@ + +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This file provides custom allocation primitives + */ + +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */ + +#include "zstd_compiler.h" /* MEM_STATIC */ +#define ZSTD_STATIC_LINKING_ONLY +#include "../zstd.h" /* ZSTD_customMem */ + +#ifndef ZSTD_ALLOCATIONS_H +#define ZSTD_ALLOCATIONS_H + +/* custom memory allocation functions */ + +MEM_STATIC void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem) +{ + if (customMem.customAlloc) + return customMem.customAlloc(customMem.opaque, size); + return ZSTD_malloc(size); +} + +MEM_STATIC void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem) +{ + if (customMem.customAlloc) { + /* calloc implemented as malloc+memset; + * not as efficient as calloc, but next best guess for custom malloc */ + void* const ptr = customMem.customAlloc(customMem.opaque, size); + ZSTD_memset(ptr, 0, size); + return ptr; + } + return ZSTD_calloc(1, size); +} + +MEM_STATIC void ZSTD_customFree(void* ptr, ZSTD_customMem customMem) +{ + if (ptr!=NULL) { + if (customMem.customFree) + customMem.customFree(customMem.opaque, ptr); + else + ZSTD_free(ptr); + } +} + +#endif /* ZSTD_ALLOCATIONS_H */ diff --git a/src/commonlib/bsd/zstd/common/bitstream.h b/src/commonlib/bsd/zstd/common/bitstream.h new file mode 100644 index 0000000000..b0d433ff6f --- /dev/null +++ b/src/commonlib/bsd/zstd/common/bitstream.h @@ -0,0 +1,456 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * bitstream + * Part of FSE library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ +#ifndef BITSTREAM_H_MODULE +#define BITSTREAM_H_MODULE + +/* +* This API consists of small unitary functions, which must be inlined for best performance. +* Since link-time-optimization is not available for all compilers, +* these functions are defined into a .h to be included. +*/ + +/*-**************************************** +* Dependencies +******************************************/ +#include "mem.h" /* unaligned access routines */ +#include "zstd_compiler.h" /* UNLIKELY() */ +#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */ +#include "error_private.h" /* error codes and messages */ +#include "zstd_bits.h" /* ZSTD_highbit32 */ + +/*========================================= +* Target specific +=========================================*/ +#ifndef ZSTD_NO_INTRINSICS +# if (defined(__BMI__) || defined(__BMI2__)) && defined(__GNUC__) +# include /* support for bextr (experimental)/bzhi */ +# elif defined(__ICCARM__) +# include +# endif +#endif + +#define STREAM_ACCUMULATOR_MIN_32 25 +#define STREAM_ACCUMULATOR_MIN_64 57 +#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64)) + + +/*-****************************************** +* bitStream encoding API (write forward) +********************************************/ +typedef size_t BitContainerType; +/* bitStream can mix input from multiple sources. + * A critical property of these streams is that they encode and decode in **reverse** direction. + * So the first bit sequence you add will be the last to be read, like a LIFO stack. + */ +typedef struct { + BitContainerType bitContainer; + unsigned bitPos; + char* startPtr; + char* ptr; + char* endPtr; +} BIT_CStream_t; + +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity); +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, BitContainerType value, unsigned nbBits); +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC); +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); + +/* Start with initCStream, providing the size of buffer to write into. +* bitStream will never write outside of this buffer. +* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code. +* +* bits are first added to a local register. +* Local register is BitContainerType, 64-bits on 64-bits systems, or 32-bits on 32-bits systems. +* Writing data into memory is an explicit operation, performed by the flushBits function. +* Hence keep track how many bits are potentially stored into local register to avoid register overflow. +* After a flushBits, a maximum of 7 bits might still be stored into local register. +* +* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers. +* +* Last operation is to close the bitStream. +* The function returns the final size of CStream in bytes. +* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable) +*/ + + +/*-******************************************** +* bitStream decoding API (read backward) +**********************************************/ +typedef struct { + BitContainerType bitContainer; + unsigned bitsConsumed; + const char* ptr; + const char* start; + const char* limitPtr; +} BIT_DStream_t; + +typedef enum { BIT_DStream_unfinished = 0, /* fully refilled */ + BIT_DStream_endOfBuffer = 1, /* still some bits left in bitstream */ + BIT_DStream_completed = 2, /* bitstream entirely consumed, bit-exact */ + BIT_DStream_overflow = 3 /* user requested more bits than present in bitstream */ + } BIT_DStream_status; /* result of BIT_reloadDStream() */ + +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); +MEM_STATIC BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD); +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); + + +/* Start by invoking BIT_initDStream(). +* A chunk of the bitStream is then stored into a local register. +* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (BitContainerType). +* You can then retrieve bitFields stored into the local register, **in reverse order**. +* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method. +* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished. +* Otherwise, it can be less than that, so proceed accordingly. +* Checking if DStream has reached its end can be performed with BIT_endOfDStream(). +*/ + + +/*-**************************************** +* unsafe API +******************************************/ +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, BitContainerType value, unsigned nbBits); +/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */ + +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC); +/* unsafe version; does not check buffer overflow */ + +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); +/* faster, but works only if nbBits >= 1 */ + +/*===== Local Constants =====*/ +static const unsigned BIT_mask[] = { + 0, 1, 3, 7, 0xF, 0x1F, + 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, + 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, + 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, + 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, + 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */ +#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0])) + +/*-************************************************************** +* bitStream encoding +****************************************************************/ +/*! BIT_initCStream() : + * `dstCapacity` must be > sizeof(size_t) + * @return : 0 if success, + * otherwise an error code (can be tested using ERR_isError()) */ +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, + void* startPtr, size_t dstCapacity) +{ + bitC->bitContainer = 0; + bitC->bitPos = 0; + bitC->startPtr = (char*)startPtr; + bitC->ptr = bitC->startPtr; + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer); + if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall); + return 0; +} + +FORCE_INLINE_TEMPLATE BitContainerType BIT_getLowerBits(BitContainerType bitContainer, U32 const nbBits) +{ +#if STATIC_BMI2 && !defined(ZSTD_NO_INTRINSICS) +# if (defined(__x86_64__) || defined(_M_X64)) && !defined(__ILP32__) + return _bzhi_u64(bitContainer, nbBits); +# else + DEBUG_STATIC_ASSERT(sizeof(bitContainer) == sizeof(U32)); + return _bzhi_u32(bitContainer, nbBits); +# endif +#else + assert(nbBits < BIT_MASK_SIZE); + return bitContainer & BIT_mask[nbBits]; +#endif +} + +/*! BIT_addBits() : + * can add up to 31 bits into `bitC`. + * Note : does not check for register overflow ! */ +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, + BitContainerType value, unsigned nbBits) +{ + DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32); + assert(nbBits < BIT_MASK_SIZE); + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); + bitC->bitContainer |= BIT_getLowerBits(value, nbBits) << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_addBitsFast() : + * works only if `value` is _clean_, + * meaning all high bits above nbBits are 0 */ +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, + BitContainerType value, unsigned nbBits) +{ + assert((value>>nbBits) == 0); + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); + bitC->bitContainer |= value << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_flushBitsFast() : + * assumption : bitContainer has not overflowed + * unsafe version; does not check buffer overflow */ +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); + assert(bitC->ptr <= bitC->endPtr); + MEM_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes*8; +} + +/*! BIT_flushBits() : + * assumption : bitContainer has not overflowed + * safe version; check for buffer overflow, and prevents it. + * note : does not signal buffer overflow. + * overflow will be revealed later on using BIT_closeCStream() */ +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); + assert(bitC->ptr <= bitC->endPtr); + MEM_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes*8; +} + +/*! BIT_closeCStream() : + * @return : size of CStream, in bytes, + * or 0 if it could not fit into dstBuffer */ +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) +{ + BIT_addBitsFast(bitC, 1, 1); /* endMark */ + BIT_flushBits(bitC); + if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ + return (size_t)(bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); +} + + +/*-******************************************************** +* bitStream decoding +**********************************************************/ +/*! BIT_initDStream() : + * Initialize a BIT_DStream_t. + * `bitD` : a pointer to an already allocated BIT_DStream_t structure. + * `srcSize` must be the *exact* size of the bitStream, in bytes. + * @return : size of stream (== srcSize), or an errorCode if a problem is detected + */ +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) +{ + if (srcSize < 1) { ZSTD_memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } + + bitD->start = (const char*)srcBuffer; + bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer); + + if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */ + bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer); + bitD->bitContainer = MEM_readLEST(bitD->ptr); + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; + bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */ + if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } + } else { + bitD->ptr = bitD->start; + bitD->bitContainer = *(const BYTE*)(bitD->start); + switch(srcSize) + { + case 7: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); + ZSTD_FALLTHROUGH; + + case 6: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); + ZSTD_FALLTHROUGH; + + case 5: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); + ZSTD_FALLTHROUGH; + + case 4: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[3]) << 24; + ZSTD_FALLTHROUGH; + + case 3: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[2]) << 16; + ZSTD_FALLTHROUGH; + + case 2: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[1]) << 8; + ZSTD_FALLTHROUGH; + + default: break; + } + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; + bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; + if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */ + } + bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; + } + + return srcSize; +} + +FORCE_INLINE_TEMPLATE BitContainerType BIT_getUpperBits(BitContainerType bitContainer, U32 const start) +{ + return bitContainer >> start; +} + +FORCE_INLINE_TEMPLATE BitContainerType BIT_getMiddleBits(BitContainerType bitContainer, U32 const start, U32 const nbBits) +{ + U32 const regMask = sizeof(bitContainer)*8 - 1; + /* if start > regMask, bitstream is corrupted, and result is undefined */ + assert(nbBits < BIT_MASK_SIZE); + /* x86 transform & ((1 << nbBits) - 1) to bzhi instruction, it is better + * than accessing memory. When bmi2 instruction is not present, we consider + * such cpus old (pre-Haswell, 2013) and their performance is not of that + * importance. + */ +#if defined(__x86_64__) || defined(_M_X64) + return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1); +#else + return (bitContainer >> (start & regMask)) & BIT_mask[nbBits]; +#endif +} + +/*! BIT_lookBits() : + * Provides next n bits from local register. + * local register is not modified. + * On 32-bits, maxNbBits==24. + * On 64-bits, maxNbBits==56. + * @return : value extracted */ +FORCE_INLINE_TEMPLATE BitContainerType BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) +{ + /* arbitrate between double-shift and shift+mask */ +#if 1 + /* if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8, + * bitstream is likely corrupted, and result is undefined */ + return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits); +#else + /* this code path is slower on my os-x laptop */ + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; + return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask); +#endif +} + +/*! BIT_lookBitsFast() : + * unsafe version; only works if nbBits >= 1 */ +MEM_STATIC BitContainerType BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) +{ + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; + assert(nbBits >= 1); + return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask); +} + +FORCE_INLINE_TEMPLATE void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) +{ + bitD->bitsConsumed += nbBits; +} + +/*! BIT_readBits() : + * Read (consume) next n bits from local register and update. + * Pay attention to not read more than nbBits contained into local register. + * @return : extracted value. */ +FORCE_INLINE_TEMPLATE BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits) +{ + BitContainerType const value = BIT_lookBits(bitD, nbBits); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_readBitsFast() : + * unsafe version; only works if nbBits >= 1 */ +MEM_STATIC BitContainerType BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits) +{ + BitContainerType const value = BIT_lookBitsFast(bitD, nbBits); + assert(nbBits >= 1); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_reloadDStream_internal() : + * Simple variant of BIT_reloadDStream(), with two conditions: + * 1. bitstream is valid : bitsConsumed <= sizeof(bitD->bitContainer)*8 + * 2. look window is valid after shifted down : bitD->ptr >= bitD->start + */ +MEM_STATIC BIT_DStream_status BIT_reloadDStream_internal(BIT_DStream_t* bitD) +{ + assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8); + bitD->ptr -= bitD->bitsConsumed >> 3; + assert(bitD->ptr >= bitD->start); + bitD->bitsConsumed &= 7; + bitD->bitContainer = MEM_readLEST(bitD->ptr); + return BIT_DStream_unfinished; +} + +/*! BIT_reloadDStreamFast() : + * Similar to BIT_reloadDStream(), but with two differences: + * 1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold! + * 2. Returns BIT_DStream_overflow when bitD->ptr < bitD->limitPtr, at this + * point you must use BIT_reloadDStream() to reload. + */ +MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD) +{ + if (UNLIKELY(bitD->ptr < bitD->limitPtr)) + return BIT_DStream_overflow; + return BIT_reloadDStream_internal(bitD); +} + +/*! BIT_reloadDStream() : + * Refill `bitD` from buffer previously set in BIT_initDStream() . + * This function is safe, it guarantees it will not never beyond src buffer. + * @return : status of `BIT_DStream_t` internal register. + * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */ +FORCE_INLINE_TEMPLATE BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) +{ + /* note : once in overflow mode, a bitstream remains in this mode until it's reset */ + if (UNLIKELY(bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))) { + static const BitContainerType zeroFilled = 0; + bitD->ptr = (const char*)&zeroFilled; /* aliasing is allowed for char */ + /* overflow detected, erroneous scenario or end of stream: no update */ + return BIT_DStream_overflow; + } + + assert(bitD->ptr >= bitD->start); + + if (bitD->ptr >= bitD->limitPtr) { + return BIT_reloadDStream_internal(bitD); + } + if (bitD->ptr == bitD->start) { + /* reached end of bitStream => no update */ + if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer; + return BIT_DStream_completed; + } + /* start < ptr < limitPtr => cautious update */ + { U32 nbBytes = bitD->bitsConsumed >> 3; + BIT_DStream_status result = BIT_DStream_unfinished; + if (bitD->ptr - nbBytes < bitD->start) { + nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ + result = BIT_DStream_endOfBuffer; + } + bitD->ptr -= nbBytes; + bitD->bitsConsumed -= nbBytes*8; + bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */ + return result; + } +} + +/*! BIT_endOfDStream() : + * @return : 1 if DStream has _exactly_ reached its end (all bits consumed). + */ +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) +{ + return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); +} + +#endif /* BITSTREAM_H_MODULE */ diff --git a/src/commonlib/bsd/zstd/common/cpu.h b/src/commonlib/bsd/zstd/common/cpu.h new file mode 100644 index 0000000000..7f841fea6c --- /dev/null +++ b/src/commonlib/bsd/zstd/common/cpu.h @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMMON_CPU_H +#define ZSTD_COMMON_CPU_H + +/** + * Implementation taken from folly/CpuId.h + * https://github.com/facebook/folly/blob/master/folly/CpuId.h + */ + +#include "mem.h" + +#ifdef _MSC_VER +#include +#endif + +typedef struct { + U32 f1c; + U32 f1d; + U32 f7b; + U32 f7c; +} ZSTD_cpuid_t; + +MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) { + U32 f1c = 0; + U32 f1d = 0; + U32 f7b = 0; + U32 f7c = 0; +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) +#if !defined(_M_X64) || !defined(__clang__) || __clang_major__ >= 16 + int reg[4]; + __cpuid((int*)reg, 0); + { + int const n = reg[0]; + if (n >= 1) { + __cpuid((int*)reg, 1); + f1c = (U32)reg[2]; + f1d = (U32)reg[3]; + } + if (n >= 7) { + __cpuidex((int*)reg, 7, 0); + f7b = (U32)reg[1]; + f7c = (U32)reg[2]; + } + } +#else + /* Clang compiler has a bug (fixed in https://reviews.llvm.org/D101338) in + * which the `__cpuid` intrinsic does not save and restore `rbx` as it needs + * to due to being a reserved register. So in that case, do the `cpuid` + * ourselves. Clang supports inline assembly anyway. + */ + U32 n; + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "popq %%rbx\n\t" + : "=a"(n) + : "a"(0) + : "rcx", "rdx"); + if (n >= 1) { + U32 f1a; + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "popq %%rbx\n\t" + : "=a"(f1a), "=c"(f1c), "=d"(f1d) + : "a"(1) + :); + } + if (n >= 7) { + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "movq %%rbx, %%rax\n\t" + "popq %%rbx" + : "=a"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "rdx"); + } +#endif +#elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__) + /* The following block like the normal cpuid branch below, but gcc + * reserves ebx for use of its pic register so we must specially + * handle the save and restore to avoid clobbering the register + */ + U32 n; + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "popl %%ebx\n\t" + : "=a"(n) + : "a"(0) + : "ecx", "edx"); + if (n >= 1) { + U32 f1a; + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "popl %%ebx\n\t" + : "=a"(f1a), "=c"(f1c), "=d"(f1d) + : "a"(1)); + } + if (n >= 7) { + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "movl %%ebx, %%eax\n\t" + "popl %%ebx" + : "=a"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "edx"); + } +#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__) + U32 n; + __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx"); + if (n >= 1) { + U32 f1a; + __asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx"); + } + if (n >= 7) { + U32 f7a; + __asm__("cpuid" + : "=a"(f7a), "=b"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "edx"); + } +#endif + { + ZSTD_cpuid_t cpuid; + cpuid.f1c = f1c; + cpuid.f1d = f1d; + cpuid.f7b = f7b; + cpuid.f7c = f7c; + return cpuid; + } +} + +#define X(name, r, bit) \ + MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \ + return ((cpuid.r) & (1U << bit)) != 0; \ + } + +/* cpuid(1): Processor Info and Feature Bits. */ +#define C(name, bit) X(name, f1c, bit) + C(sse3, 0) + C(pclmuldq, 1) + C(dtes64, 2) + C(monitor, 3) + C(dscpl, 4) + C(vmx, 5) + C(smx, 6) + C(eist, 7) + C(tm2, 8) + C(ssse3, 9) + C(cnxtid, 10) + C(fma, 12) + C(cx16, 13) + C(xtpr, 14) + C(pdcm, 15) + C(pcid, 17) + C(dca, 18) + C(sse41, 19) + C(sse42, 20) + C(x2apic, 21) + C(movbe, 22) + C(popcnt, 23) + C(tscdeadline, 24) + C(aes, 25) + C(xsave, 26) + C(osxsave, 27) + C(avx, 28) + C(f16c, 29) + C(rdrand, 30) +#undef C +#define D(name, bit) X(name, f1d, bit) + D(fpu, 0) + D(vme, 1) + D(de, 2) + D(pse, 3) + D(tsc, 4) + D(msr, 5) + D(pae, 6) + D(mce, 7) + D(cx8, 8) + D(apic, 9) + D(sep, 11) + D(mtrr, 12) + D(pge, 13) + D(mca, 14) + D(cmov, 15) + D(pat, 16) + D(pse36, 17) + D(psn, 18) + D(clfsh, 19) + D(ds, 21) + D(acpi, 22) + D(mmx, 23) + D(fxsr, 24) + D(sse, 25) + D(sse2, 26) + D(ss, 27) + D(htt, 28) + D(tm, 29) + D(pbe, 31) +#undef D + +/* cpuid(7): Extended Features. */ +#define B(name, bit) X(name, f7b, bit) + B(bmi1, 3) + B(hle, 4) + B(avx2, 5) + B(smep, 7) + B(bmi2, 8) + B(erms, 9) + B(invpcid, 10) + B(rtm, 11) + B(mpx, 14) + B(avx512f, 16) + B(avx512dq, 17) + B(rdseed, 18) + B(adx, 19) + B(smap, 20) + B(avx512ifma, 21) + B(pcommit, 22) + B(clflushopt, 23) + B(clwb, 24) + B(avx512pf, 26) + B(avx512er, 27) + B(avx512cd, 28) + B(sha, 29) + B(avx512bw, 30) + B(avx512vl, 31) +#undef B +#define C(name, bit) X(name, f7c, bit) + C(prefetchwt1, 0) + C(avx512vbmi, 1) +#undef C + +#undef X + +#endif /* ZSTD_COMMON_CPU_H */ diff --git a/src/commonlib/bsd/zstd/common/debug.c b/src/commonlib/bsd/zstd/common/debug.c new file mode 100644 index 0000000000..c42634e21d --- /dev/null +++ b/src/commonlib/bsd/zstd/common/debug.c @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * debug + * Part of FSE library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + + +/* + * This module only hosts one global variable + * which can be used to dynamically influence the verbosity of traces, + * such as DEBUGLOG and RAWLOG + */ + +#include "debug.h" + +#if !defined(ZSTD_LINUX_KERNEL) || (DEBUGLEVEL>=2) +/* We only use this when DEBUGLEVEL>=2, but we get -Werror=pedantic errors if a + * translation unit is empty. So remove this from Linux kernel builds, but + * otherwise just leave it in. + */ +int g_debuglevel = DEBUGLEVEL; +#endif diff --git a/src/commonlib/bsd/zstd/common/debug.h b/src/commonlib/bsd/zstd/common/debug.h new file mode 100644 index 0000000000..2634d9d70e --- /dev/null +++ b/src/commonlib/bsd/zstd/common/debug.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * debug + * Part of FSE library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + + +/* + * The purpose of this header is to enable debug functions. + * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time, + * and DEBUG_STATIC_ASSERT() for compile-time. + * + * By default, DEBUGLEVEL==0, which means run-time debug is disabled. + * + * Level 1 enables assert() only. + * Starting level 2, traces can be generated and pushed to stderr. + * The higher the level, the more verbose the traces. + * + * It's possible to dynamically adjust level using variable g_debug_level, + * which is only declared if DEBUGLEVEL>=2, + * and is a global variable, not multi-thread protected (use with care) + */ + +#ifndef DEBUG_H_12987983217 +#define DEBUG_H_12987983217 + + +/* static assert is triggered at compile time, leaving no runtime artefact. + * static assert only works with compile-time constants. + * Also, this variant can only be used inside a function. */ +#define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1]) + + +/* DEBUGLEVEL is expected to be defined externally, + * typically through compiler command line. + * Value must be a number. */ +#ifndef DEBUGLEVEL +# define DEBUGLEVEL 0 +#endif + + +/* recommended values for DEBUGLEVEL : + * 0 : release mode, no debug, all run-time checks disabled + * 1 : enables assert() only, no display + * 2 : reserved, for currently active debug path + * 3 : events once per object lifetime (CCtx, CDict, etc.) + * 4 : events once per frame + * 5 : events once per block + * 6 : events once per sequence (verbose) + * 7+: events at every position (*very* verbose) + * + * It's generally inconvenient to output traces > 5. + * In which case, it's possible to selectively trigger high verbosity levels + * by modifying g_debug_level. + */ + +#if (DEBUGLEVEL>=1) +# define ZSTD_DEPS_NEED_ASSERT +# include "zstd_deps.h" +#else +# ifndef assert /* assert may be already defined, due to prior #include */ +# define assert(condition) ((void)0) /* disable assert (default) */ +# endif +#endif + +#if (DEBUGLEVEL>=2) +# define ZSTD_DEPS_NEED_IO +# include "zstd_deps.h" +extern int g_debuglevel; /* the variable is only declared, + it actually lives in debug.c, + and is shared by the whole process. + It's not thread-safe. + It's useful when enabling very verbose levels + on selective conditions (such as position in src) */ + +# define RAWLOG(l, ...) \ + do { \ + if (l<=g_debuglevel) { \ + ZSTD_DEBUG_PRINT(__VA_ARGS__); \ + } \ + } while (0) + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define LINE_AS_STRING TOSTRING(__LINE__) + +# define DEBUGLOG(l, ...) \ + do { \ + if (l<=g_debuglevel) { \ + ZSTD_DEBUG_PRINT(__FILE__ ":" LINE_AS_STRING ": " __VA_ARGS__); \ + ZSTD_DEBUG_PRINT(" \n"); \ + } \ + } while (0) +#else +# define RAWLOG(l, ...) do { } while (0) /* disabled */ +# define DEBUGLOG(l, ...) do { } while (0) /* disabled */ +#endif + +#endif /* DEBUG_H_12987983217 */ diff --git a/src/commonlib/bsd/zstd/common/entropy_common.c b/src/commonlib/bsd/zstd/common/entropy_common.c new file mode 100644 index 0000000000..0b2a60a0dd --- /dev/null +++ b/src/commonlib/bsd/zstd/common/entropy_common.c @@ -0,0 +1,342 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * Common functions of New Generation Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************* +* Dependencies +***************************************/ +#include "mem.h" +#include "error_private.h" /* ERR_*, ERROR */ +#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */ +#include "fse.h" +#include "huf.h" +#include "zstd_bits.h" /* ZSDT_highbit32, ZSTD_countTrailingZeros32 */ + + +/*=== Version ===*/ +unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } + + +/*=== Error Management ===*/ +unsigned FSE_isError(size_t code) { return ERR_isError(code); } +const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } + +unsigned HUF_isError(size_t code) { return ERR_isError(code); } +const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } + + +/*-************************************************************** +* FSE NCount encoding-decoding +****************************************************************/ +FORCE_INLINE_TEMPLATE +size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + const BYTE* const istart = (const BYTE*) headerBuffer; + const BYTE* const iend = istart + hbSize; + const BYTE* ip = istart; + int nbBits; + int remaining; + int threshold; + U32 bitStream; + int bitCount; + unsigned charnum = 0; + unsigned const maxSV1 = *maxSVPtr + 1; + int previous0 = 0; + + if (hbSize < 8) { + /* This function only works when hbSize >= 8 */ + char buffer[8] = {0}; + ZSTD_memcpy(buffer, headerBuffer, hbSize); + { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr, + buffer, sizeof(buffer)); + if (FSE_isError(countSize)) return countSize; + if (countSize > hbSize) return ERROR(corruption_detected); + return countSize; + } } + assert(hbSize >= 8); + + /* init */ + ZSTD_memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */ + bitStream = MEM_readLE32(ip); + nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ + if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); + bitStream >>= 4; + bitCount = 4; + *tableLogPtr = nbBits; + remaining = (1<> 1; + while (repeats >= 12) { + charnum += 3 * 12; + if (LIKELY(ip <= iend-7)) { + ip += 3; + } else { + bitCount -= (int)(8 * (iend - 7 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1; + } + charnum += 3 * repeats; + bitStream >>= 2 * repeats; + bitCount += 2 * repeats; + + /* Add the final repeat which isn't 0b11. */ + assert((bitStream & 3) < 3); + charnum += bitStream & 3; + bitCount += 2; + + /* This is an error, but break and return an error + * at the end, because returning out of a loop makes + * it harder for the compiler to optimize. + */ + if (charnum >= maxSV1) break; + + /* We don't need to set the normalized count to 0 + * because we already memset the whole buffer to 0. + */ + + if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + assert((bitCount >> 3) <= 3); /* For first condition to work */ + ip += bitCount>>3; + bitCount &= 7; + } else { + bitCount -= (int)(8 * (iend - 4 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + } + { + int const max = (2*threshold-1) - remaining; + int count; + + if ((bitStream & (threshold-1)) < (U32)max) { + count = bitStream & (threshold-1); + bitCount += nbBits-1; + } else { + count = bitStream & (2*threshold-1); + if (count >= threshold) count -= max; + bitCount += nbBits; + } + + count--; /* extra accuracy */ + /* When it matters (small blocks), this is a + * predictable branch, because we don't use -1. + */ + if (count >= 0) { + remaining -= count; + } else { + assert(count == -1); + remaining += count; + } + normalizedCounter[charnum++] = (short)count; + previous0 = !count; + + assert(threshold > 1); + if (remaining < threshold) { + /* This branch can be folded into the + * threshold update condition because we + * know that threshold > 1. + */ + if (remaining <= 1) break; + nbBits = ZSTD_highbit32(remaining) + 1; + threshold = 1 << (nbBits - 1); + } + if (charnum >= maxSV1) break; + + if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + ip += bitCount>>3; + bitCount &= 7; + } else { + bitCount -= (int)(8 * (iend - 4 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + } } + if (remaining != 1) return ERROR(corruption_detected); + /* Only possible when there are too many zeros. */ + if (charnum > maxSV1) return ERROR(maxSymbolValue_tooSmall); + if (bitCount > 32) return ERROR(corruption_detected); + *maxSVPtr = charnum-1; + + ip += (bitCount+7)>>3; + return ip-istart; +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t FSE_readNCount_body_default( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} + +#if DYNAMIC_BMI2 +BMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} +#endif + +size_t FSE_readNCount_bmi2( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { + return FSE_readNCount_body_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); + } +#endif + (void)bmi2; + return FSE_readNCount_body_default(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} + +size_t FSE_readNCount( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize, /* bmi2 */ 0); +} + + +/*! HUF_readStats() : + Read compact Huffman tree, saved by HUF_writeCTable(). + `huffWeight` is destination buffer. + `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. + @return : size read from `src` , or an error Code . + Note : Needed by HUF_readCTable() and HUF_readDTableX?() . +*/ +size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize) +{ + U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; + return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* flags */ 0); +} + +FORCE_INLINE_TEMPLATE size_t +HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, + int bmi2) +{ + U32 weightTotal; + const BYTE* ip = (const BYTE*) src; + size_t iSize; + size_t oSize; + + if (!srcSize) return ERROR(srcSize_wrong); + iSize = ip[0]; + /* ZSTD_memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ + + if (iSize >= 128) { /* special header */ + oSize = iSize - 127; + iSize = ((oSize+1)/2); + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + if (oSize >= hwSize) return ERROR(corruption_detected); + ip += 1; + { U32 n; + for (n=0; n> 4; + huffWeight[n+1] = ip[n/2] & 15; + } } } + else { /* header compressed with FSE (normal case) */ + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + /* max (hwSize-1) values decoded, as last one is implied */ + oSize = FSE_decompress_wksp_bmi2(huffWeight, hwSize-1, ip+1, iSize, 6, workSpace, wkspSize, bmi2); + if (FSE_isError(oSize)) return oSize; + } + + /* collect weight stats */ + ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); + weightTotal = 0; + { U32 n; for (n=0; n HUF_TABLELOG_MAX) return ERROR(corruption_detected); + rankStats[huffWeight[n]]++; + weightTotal += (1 << huffWeight[n]) >> 1; + } } + if (weightTotal == 0) return ERROR(corruption_detected); + + /* get last non-null symbol weight (implied, total must be 2^n) */ + { U32 const tableLog = ZSTD_highbit32(weightTotal) + 1; + if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); + *tableLogPtr = tableLog; + /* determine last weight */ + { U32 const total = 1 << tableLog; + U32 const rest = total - weightTotal; + U32 const verif = 1 << ZSTD_highbit32(rest); + U32 const lastWeight = ZSTD_highbit32(rest) + 1; + if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ + huffWeight[oSize] = (BYTE)lastWeight; + rankStats[lastWeight]++; + } } + + /* check tree construction validity */ + if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ + + /* results */ + *nbSymbolsPtr = (U32)(oSize+1); + return iSize+1; +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize) +{ + return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 0); +} + +#if DYNAMIC_BMI2 +static BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize) +{ + return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 1); +} +#endif + +size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, + int flags) +{ +#if DYNAMIC_BMI2 + if (flags & HUF_flags_bmi2) { + return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); + } +#endif + (void)flags; + return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); +} diff --git a/src/commonlib/bsd/zstd/common/error_private.c b/src/commonlib/bsd/zstd/common/error_private.c new file mode 100644 index 0000000000..2d8e3bdd61 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/error_private.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* The purpose of this file is to have a single list of error strings embedded in binary */ + +#include "error_private.h" + +const char* ERR_getErrorString(ERR_enum code) +{ +#ifdef ZSTD_STRIP_ERROR_STRINGS + (void)code; + return "Error strings stripped"; +#else + static const char* const notErrorCode = "Unspecified error code"; + switch( code ) + { + case PREFIX(no_error): return "No error detected"; + case PREFIX(GENERIC): return "Error (generic)"; + case PREFIX(prefix_unknown): return "Unknown frame descriptor"; + case PREFIX(version_unsupported): return "Version not supported"; + case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter"; + case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding"; + case PREFIX(corruption_detected): return "Data corruption detected"; + case PREFIX(checksum_wrong): return "Restored data doesn't match checksum"; + case PREFIX(literals_headerWrong): return "Header of Literals' block doesn't respect format specification"; + case PREFIX(parameter_unsupported): return "Unsupported parameter"; + case PREFIX(parameter_combination_unsupported): return "Unsupported combination of parameters"; + case PREFIX(parameter_outOfBound): return "Parameter is out of bound"; + case PREFIX(init_missing): return "Context should be init first"; + case PREFIX(memory_allocation): return "Allocation error : not enough memory"; + case PREFIX(workSpace_tooSmall): return "workSpace buffer is not large enough"; + case PREFIX(stage_wrong): return "Operation not authorized at current processing stage"; + case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported"; + case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large"; + case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; + case PREFIX(cannotProduce_uncompressedBlock): return "This mode cannot generate an uncompressed block"; + case PREFIX(stabilityCondition_notRespected): return "pledged buffer stability condition is not respected"; + case PREFIX(dictionary_corrupted): return "Dictionary is corrupted"; + case PREFIX(dictionary_wrong): return "Dictionary mismatch"; + case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples"; + case PREFIX(dstSize_tooSmall): return "Destination buffer is too small"; + case PREFIX(srcSize_wrong): return "Src size is incorrect"; + case PREFIX(dstBuffer_null): return "Operation on NULL destination buffer"; + case PREFIX(noForwardProgress_destFull): return "Operation made no progress over multiple calls, due to output buffer being full"; + case PREFIX(noForwardProgress_inputEmpty): return "Operation made no progress over multiple calls, due to input being empty"; + /* following error codes are not stable and may be removed or changed in a future version */ + case PREFIX(frameIndex_tooLarge): return "Frame index is too large"; + case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking"; + case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong"; + case PREFIX(srcBuffer_wrong): return "Source buffer is wrong"; + case PREFIX(sequenceProducer_failed): return "Block-level external sequence producer returned an error code"; + case PREFIX(externalSequences_invalid): return "External sequences are not valid"; + case PREFIX(maxCode): + default: return notErrorCode; + } +#endif +} diff --git a/src/commonlib/bsd/zstd/common/error_private.h b/src/commonlib/bsd/zstd/common/error_private.h new file mode 100644 index 0000000000..eeee67f52e --- /dev/null +++ b/src/commonlib/bsd/zstd/common/error_private.h @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* Note : this module is expected to remain private, do not expose it */ + +#ifndef ERROR_H_MODULE +#define ERROR_H_MODULE + +/* **************************************** +* Dependencies +******************************************/ +#include "../zstd_errors.h" /* enum list */ +#include "zstd_compiler.h" +#include "debug.h" +#include "zstd_deps.h" /* size_t */ + +/* **************************************** +* Compiler-specific +******************************************/ +#if defined(__GNUC__) +# define ERR_STATIC static __attribute__((unused)) +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define ERR_STATIC static inline +#elif defined(_MSC_VER) +# define ERR_STATIC static __inline +#else +# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif + + +/*-**************************************** +* Customization (error_public.h) +******************************************/ +typedef ZSTD_ErrorCode ERR_enum; +#define PREFIX(name) ZSTD_error_##name + + +/*-**************************************** +* Error codes handling +******************************************/ +#undef ERROR /* already defined on Visual Studio */ +#define ERROR(name) ZSTD_ERROR(name) +#define ZSTD_ERROR(name) ((size_t)-PREFIX(name)) + +ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); } + +ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); } + +/* check and forward error code */ +#define CHECK_V_F(e, f) \ + size_t const e = f; \ + do { \ + if (ERR_isError(e)) \ + return e; \ + } while (0) +#define CHECK_F(f) do { CHECK_V_F(_var_err__, f); } while (0) + + +/*-**************************************** +* Error Strings +******************************************/ + +const char* ERR_getErrorString(ERR_enum code); /* error_private.c */ + +ERR_STATIC const char* ERR_getErrorName(size_t code) +{ + return ERR_getErrorString(ERR_getErrorCode(code)); +} + +/** + * Ignore: this is an internal helper. + * + * This is a helper function to help force C99-correctness during compilation. + * Under strict compilation modes, variadic macro arguments can't be empty. + * However, variadic function arguments can be. Using a function therefore lets + * us statically check that at least one (string) argument was passed, + * independent of the compilation flags. + */ +static INLINE_KEYWORD UNUSED_ATTR +void _force_has_format_string(const char *format, ...) { + (void)format; +} + +/** + * Ignore: this is an internal helper. + * + * We want to force this function invocation to be syntactically correct, but + * we don't want to force runtime evaluation of its arguments. + */ +#define _FORCE_HAS_FORMAT_STRING(...) \ + do { \ + if (0) { \ + _force_has_format_string(__VA_ARGS__); \ + } \ + } while (0) + +#define ERR_QUOTE(str) #str + +/** + * Return the specified error if the condition evaluates to true. + * + * In debug modes, prints additional information. + * In order to do that (particularly, printing the conditional that failed), + * this can't just wrap RETURN_ERROR(). + */ +#define RETURN_ERROR_IF(cond, err, ...) \ + do { \ + if (cond) { \ + RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return ERROR(err); \ + } \ + } while (0) + +/** + * Unconditionally return the specified error. + * + * In debug modes, prints additional information. + */ +#define RETURN_ERROR(err, ...) \ + do { \ + RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return ERROR(err); \ + } while(0) + +/** + * If the provided expression evaluates to an error code, returns that error code. + * + * In debug modes, prints additional information. + */ +#define FORWARD_IF_ERROR(err, ...) \ + do { \ + size_t const err_code = (err); \ + if (ERR_isError(err_code)) { \ + RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \ + __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return err_code; \ + } \ + } while(0) + +#endif /* ERROR_H_MODULE */ diff --git a/src/commonlib/bsd/zstd/common/fse.h b/src/commonlib/bsd/zstd/common/fse.h new file mode 100644 index 0000000000..2b450b9579 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/fse.h @@ -0,0 +1,627 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * FSE : Finite State Entropy codec + * Public Prototypes declaration + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ +#ifndef FSE_H +#define FSE_H + + +/*-***************************************** +* Dependencies +******************************************/ +#include "zstd_deps.h" /* size_t, ptrdiff_t */ + +/*-***************************************** +* FSE_PUBLIC_API : control library symbols visibility +******************************************/ +#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) +# define FSE_PUBLIC_API __attribute__ ((visibility ("default"))) +#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ +# define FSE_PUBLIC_API __declspec(dllexport) +#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) +# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define FSE_PUBLIC_API +#endif + +/*------ Version ------*/ +#define FSE_VERSION_MAJOR 0 +#define FSE_VERSION_MINOR 9 +#define FSE_VERSION_RELEASE 0 + +#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE +#define FSE_QUOTE(str) #str +#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str) +#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION) + +#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE) +FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */ + + +/*-***************************************** +* Tool functions +******************************************/ +FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */ + +/* Error Management */ +FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ +FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */ + + +/*-***************************************** +* FSE detailed API +******************************************/ +/*! +FSE_compress() does the following: +1. count symbol occurrence from source[] into table count[] (see hist.h) +2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog) +3. save normalized counters to memory buffer using writeNCount() +4. build encoding table 'CTable' from normalized counters +5. encode the data stream using encoding table 'CTable' + +FSE_decompress() does the following: +1. read normalized counters with readNCount() +2. build decoding table 'DTable' from normalized counters +3. decode the data stream using decoding table 'DTable' + +The following API allows targeting specific sub-functions for advanced tasks. +For example, it's possible to compress several blocks using the same 'CTable', +or to save and provide normalized distribution using external method. +*/ + +/* *** COMPRESSION *** */ + +/*! FSE_optimalTableLog(): + dynamically downsize 'tableLog' when conditions are met. + It saves CPU time, by using smaller tables, while preserving or even improving compression ratio. + @return : recommended tableLog (necessarily <= 'maxTableLog') */ +FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); + +/*! FSE_normalizeCount(): + normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) + 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). + useLowProbCount is a boolean parameter which trades off compressed size for + faster header decoding. When it is set to 1, the compressed data will be slightly + smaller. And when it is set to 0, FSE_readNCount() and FSE_buildDTable() will be + faster. If you are compressing a small amount of data (< 2 KB) then useLowProbCount=0 + is a good default, since header deserialization makes a big speed difference. + Otherwise, useLowProbCount=1 is a good default, since the speed difference is small. + @return : tableLog, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, + const unsigned* count, size_t srcSize, unsigned maxSymbolValue, unsigned useLowProbCount); + +/*! FSE_NCountWriteBound(): + Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. + Typically useful for allocation purpose. */ +FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_writeNCount(): + Compactly save 'normalizedCounter' into 'buffer'. + @return : size of the compressed table, + or an errorCode, which can be tested using FSE_isError(). */ +FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, + const short* normalizedCounter, + unsigned maxSymbolValue, unsigned tableLog); + +/*! Constructor and Destructor of FSE_CTable. + Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */ +typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */ + +/*! FSE_buildCTable(): + Builds `ct`, which must be already allocated, using FSE_createCTable(). + @return : 0, or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_compress_usingCTable(): + Compress `src` using `ct` into `dst` which must be already allocated. + @return : size of compressed data (<= `dstCapacity`), + or 0 if compressed data could not fit into `dst`, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct); + +/*! +Tutorial : +---------- +The first step is to count all symbols. FSE_count() does this job very fast. +Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells. +'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0] +maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value) +FSE_count() will return the number of occurrence of the most frequent symbol. +This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). + +The next step is to normalize the frequencies. +FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'. +It also guarantees a minimum of 1 to any Symbol with frequency >= 1. +You can use 'tableLog'==0 to mean "use default tableLog value". +If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(), +which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default"). + +The result of FSE_normalizeCount() will be saved into a table, +called 'normalizedCounter', which is a table of signed short. +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells. +The return value is tableLog if everything proceeded as expected. +It is 0 if there is a single symbol within distribution. +If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()). + +'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount(). +'buffer' must be already allocated. +For guaranteed success, buffer size must be at least FSE_headerBound(). +The result of the function is the number of bytes written into 'buffer'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small). + +'normalizedCounter' can then be used to create the compression table 'CTable'. +The space required by 'CTable' must be already allocated, using FSE_createCTable(). +You can then use FSE_buildCTable() to fill 'CTable'. +If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()). + +'CTable' can then be used to compress 'src', with FSE_compress_usingCTable(). +Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize' +The function returns the size of compressed data (without header), necessarily <= `dstCapacity`. +If it returns '0', compressed data could not fit into 'dst'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). +*/ + + +/* *** DECOMPRESSION *** */ + +/*! FSE_readNCount(): + Read compactly saved 'normalizedCounter' from 'rBuffer'. + @return : size read from 'rBuffer', + or an errorCode, which can be tested using FSE_isError(). + maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ +FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, + unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, + const void* rBuffer, size_t rBuffSize); + +/*! FSE_readNCount_bmi2(): + * Same as FSE_readNCount() but pass bmi2=1 when your CPU supports BMI2 and 0 otherwise. + */ +FSE_PUBLIC_API size_t FSE_readNCount_bmi2(short* normalizedCounter, + unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, + const void* rBuffer, size_t rBuffSize, int bmi2); + +typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ + +/*! +Tutorial : +---------- +(Note : these functions only decompress FSE-compressed blocks. + If block is uncompressed, use memcpy() instead + If block is a single repeated byte, use memset() instead ) + +The first step is to obtain the normalized frequencies of symbols. +This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount(). +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short. +In practice, that means it's necessary to know 'maxSymbolValue' beforehand, +or size the table to handle worst case situations (typically 256). +FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'. +The result of FSE_readNCount() is the number of bytes read from 'rBuffer'. +Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that. +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'. +This is performed by the function FSE_buildDTable(). +The space required by 'FSE_DTable' must be already allocated using FSE_createDTable(). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable(). +`cSrcSize` must be strictly correct, otherwise decompression will fail. +FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small) +*/ + +#endif /* FSE_H */ + + +#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY) +#define FSE_H_FSE_STATIC_LINKING_ONLY +#include "bitstream.h" + +/* ***************************************** +* Static allocation +*******************************************/ +/* FSE buffer bounds */ +#define FSE_NCOUNTBOUND 512 +#define FSE_BLOCKBOUND(size) ((size) + ((size)>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */) +#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */ +#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<((maxTableLog)-1)) + (((maxSymbolValue)+1)*2)) +#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<(maxTableLog))) + +/* or use the size to malloc() space directly. Pay attention to alignment restrictions though */ +#define FSE_CTABLE_SIZE(maxTableLog, maxSymbolValue) (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(FSE_CTable)) +#define FSE_DTABLE_SIZE(maxTableLog) (FSE_DTABLE_SIZE_U32(maxTableLog) * sizeof(FSE_DTable)) + + +/* ***************************************** + * FSE advanced API + ***************************************** */ + +unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus); +/**< same as FSE_optimalTableLog(), which used `minus==2` */ + +size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); +/**< build a fake FSE_CTable, designed to compress always the same symbolValue */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`. + * See FSE_buildCTable_wksp() for breakdown of workspace usage. + */ +#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (((maxSymbolValue + 2) + (1ull << (tableLog)))/2 + sizeof(U64)/sizeof(U32) /* additional 8 bytes for potential table overwrite */) +#define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)) +size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); + +#define FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) (sizeof(short) * (maxSymbolValue + 1) + (1ULL << maxTableLog) + 8) +#define FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ((FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) + sizeof(unsigned) - 1) / sizeof(unsigned)) +FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); +/**< Same as FSE_buildDTable(), using an externally allocated `workspace` produced with `FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxSymbolValue)` */ + +#define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + 1 + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) + (FSE_MAX_SYMBOL_VALUE + 1) / 2 + 1) +#define FSE_DECOMPRESS_WKSP_SIZE(maxTableLog, maxSymbolValue) (FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(unsigned)) +size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2); +/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DECOMPRESS_WKSP_SIZE_U32(maxLog, maxSymbolValue)`. + * Set bmi2 to 1 if your CPU supports BMI2 or 0 if it doesn't */ + +typedef enum { + FSE_repeat_none, /**< Cannot use the previous table */ + FSE_repeat_check, /**< Can use the previous table but it must be checked */ + FSE_repeat_valid /**< Can use the previous table and it is assumed to be valid */ + } FSE_repeat; + +/* ***************************************** +* FSE symbol compression API +*******************************************/ +/*! + This API consists of small unitary functions, which highly benefit from being inlined. + Hence their body are included in next section. +*/ +typedef struct { + ptrdiff_t value; + const void* stateTable; + const void* symbolTT; + unsigned stateLog; +} FSE_CState_t; + +static void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct); + +static void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* CStatePtr, unsigned symbol); + +static void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* CStatePtr); + +/**< +These functions are inner components of FSE_compress_usingCTable(). +They allow the creation of custom streams, mixing multiple tables and bit sources. + +A key property to keep in mind is that encoding and decoding are done **in reverse direction**. +So the first symbol you will encode is the last you will decode, like a LIFO stack. + +You will need a few variables to track your CStream. They are : + +FSE_CTable ct; // Provided by FSE_buildCTable() +BIT_CStream_t bitStream; // bitStream tracking structure +FSE_CState_t state; // State tracking structure (can have several) + + +The first thing to do is to init bitStream and state. + size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize); + FSE_initCState(&state, ct); + +Note that BIT_initCStream() can produce an error code, so its result should be tested, using FSE_isError(); +You can then encode your input data, byte after byte. +FSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time. +Remember decoding will be done in reverse direction. + FSE_encodeByte(&bitStream, &state, symbol); + +At any time, you can also add any bit sequence. +Note : maximum allowed nbBits is 25, for compatibility with 32-bits decoders + BIT_addBits(&bitStream, bitField, nbBits); + +The above methods don't commit data to memory, they just store it into local register, for speed. +Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). +Writing data to memory is a manual operation, performed by the flushBits function. + BIT_flushBits(&bitStream); + +Your last FSE encoding operation shall be to flush your last state value(s). + FSE_flushState(&bitStream, &state); + +Finally, you must close the bitStream. +The function returns the size of CStream in bytes. +If data couldn't fit into dstBuffer, it will return a 0 ( == not compressible) +If there is an error, it returns an errorCode (which can be tested using FSE_isError()). + size_t size = BIT_closeCStream(&bitStream); +*/ + + +/* ***************************************** +* FSE symbol decompression API +*******************************************/ +typedef struct { + size_t state; + const void* table; /* precise table may vary, depending on U16 */ +} FSE_DState_t; + + +static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt); + +static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); + +static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr); + +/**< +Let's now decompose FSE_decompress_usingDTable() into its unitary components. +You will decode FSE-encoded symbols from the bitStream, +and also any other bitFields you put in, **in reverse order**. + +You will need a few variables to track your bitStream. They are : + +BIT_DStream_t DStream; // Stream context +FSE_DState_t DState; // State context. Multiple ones are possible +FSE_DTable* DTablePtr; // Decoding table, provided by FSE_buildDTable() + +The first thing to do is to init the bitStream. + errorCode = BIT_initDStream(&DStream, srcBuffer, srcSize); + +You should then retrieve your initial state(s) +(in reverse flushing order if you have several ones) : + errorCode = FSE_initDState(&DState, &DStream, DTablePtr); + +You can then decode your data, symbol after symbol. +For information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'. +Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out). + unsigned char symbol = FSE_decodeSymbol(&DState, &DStream); + +You can retrieve any bitfield you eventually stored into the bitStream (in reverse order) +Note : maximum allowed nbBits is 25, for 32-bits compatibility + size_t bitField = BIT_readBits(&DStream, nbBits); + +All above operations only read from local register (which size depends on size_t). +Refueling the register from memory is manually performed by the reload method. + endSignal = FSE_reloadDStream(&DStream); + +BIT_reloadDStream() result tells if there is still some more data to read from DStream. +BIT_DStream_unfinished : there is still some data left into the DStream. +BIT_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled. +BIT_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed. +BIT_DStream_tooFar : Dstream went too far. Decompression result is corrupted. + +When reaching end of buffer (BIT_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop, +to properly detect the exact end of stream. +After each decoded symbol, check if DStream is fully consumed using this simple test : + BIT_reloadDStream(&DStream) >= BIT_DStream_completed + +When it's done, verify decompression is fully completed, by checking both DStream and the relevant states. +Checking if DStream has reached its end is performed by : + BIT_endOfDStream(&DStream); +Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible. + FSE_endOfDState(&DState); +*/ + + +/* ***************************************** +* FSE unsafe API +*******************************************/ +static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); +/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */ + + +/* ***************************************** +* Implementation of inlined functions +*******************************************/ +typedef struct { + int deltaFindState; + U32 deltaNbBits; +} FSE_symbolCompressionTransform; /* total 8 bytes */ + +MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct) +{ + const void* ptr = ct; + const U16* u16ptr = (const U16*) ptr; + const U32 tableLog = MEM_read16(ptr); + statePtr->value = (ptrdiff_t)1<stateTable = u16ptr+2; + statePtr->symbolTT = ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1); + statePtr->stateLog = tableLog; +} + + +/*! FSE_initCState2() : +* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read) +* uses the smallest state value possible, saving the cost of this symbol */ +MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol) +{ + FSE_initCState(statePtr, ct); + { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; + const U16* stateTable = (const U16*)(statePtr->stateTable); + U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16); + statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits; + statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; + } +} + +MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, unsigned symbol) +{ + FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; + const U16* const stateTable = (const U16*)(statePtr->stateTable); + U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); + BIT_addBits(bitC, (BitContainerType)statePtr->value, nbBitsOut); + statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; +} + +MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr) +{ + BIT_addBits(bitC, (BitContainerType)statePtr->value, statePtr->stateLog); + BIT_flushBits(bitC); +} + + +/* FSE_getMaxNbBits() : + * Approximate maximum cost of a symbol, in bits. + * Fractional get rounded up (i.e. a symbol with a normalized frequency of 3 gives the same result as a frequency of 2) + * note 1 : assume symbolValue is valid (<= maxSymbolValue) + * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ +MEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue) +{ + const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; + return (symbolTT[symbolValue].deltaNbBits + ((1<<16)-1)) >> 16; +} + +/* FSE_bitCost() : + * Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits) + * note 1 : assume symbolValue is valid (<= maxSymbolValue) + * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ +MEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog) +{ + const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; + U32 const minNbBits = symbolTT[symbolValue].deltaNbBits >> 16; + U32 const threshold = (minNbBits+1) << 16; + assert(tableLog < 16); + assert(accuracyLog < 31-tableLog); /* ensure enough room for renormalization double shift */ + { U32 const tableSize = 1 << tableLog; + U32 const deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize); + U32 const normalizedDeltaFromThreshold = (deltaFromThreshold << accuracyLog) >> tableLog; /* linear interpolation (very approximate) */ + U32 const bitMultiplier = 1 << accuracyLog; + assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold); + assert(normalizedDeltaFromThreshold <= bitMultiplier); + return (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold; + } +} + + +/* ====== Decompression ====== */ + +typedef struct { + U16 tableLog; + U16 fastMode; +} FSE_DTableHeader; /* sizeof U32 */ + +typedef struct +{ + unsigned short newState; + unsigned char symbol; + unsigned char nbBits; +} FSE_decode_t; /* size == U32 */ + +MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt) +{ + const void* ptr = dt; + const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr; + DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + return DInfo.symbol; +} + +MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + size_t const lowBits = BIT_readBits(bitD, nbBits); + DStatePtr->state = DInfo.newState + lowBits; +} + +MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBits(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +/*! FSE_decodeSymbolFast() : + unsafe, only works if no symbol has a probability > 50% */ +MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBitsFast(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) +{ + return DStatePtr->state == 0; +} + + + +#ifndef FSE_COMMONDEFS_ONLY + +/* ************************************************************** +* Tuning parameters +****************************************************************/ +/*!MEMORY_USAGE : +* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) +* Increasing memory usage improves compression ratio +* Reduced memory usage can improve speed, due to cache effect +* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ +#ifndef FSE_MAX_MEMORY_USAGE +# define FSE_MAX_MEMORY_USAGE 14 +#endif +#ifndef FSE_DEFAULT_MEMORY_USAGE +# define FSE_DEFAULT_MEMORY_USAGE 13 +#endif +#if (FSE_DEFAULT_MEMORY_USAGE > FSE_MAX_MEMORY_USAGE) +# error "FSE_DEFAULT_MEMORY_USAGE must be <= FSE_MAX_MEMORY_USAGE" +#endif + +/*!FSE_MAX_SYMBOL_VALUE : +* Maximum symbol value authorized. +* Required for proper stack allocation */ +#ifndef FSE_MAX_SYMBOL_VALUE +# define FSE_MAX_SYMBOL_VALUE 255 +#endif + +/* ************************************************************** +* template functions type & suffix +****************************************************************/ +#define FSE_FUNCTION_TYPE BYTE +#define FSE_FUNCTION_EXTENSION +#define FSE_DECODE_TYPE FSE_decode_t + + +#endif /* !FSE_COMMONDEFS_ONLY */ + + +/* *************************************************************** +* Constants +*****************************************************************/ +#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2) +#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX +# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" +#endif + +#define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3) + +#endif /* FSE_STATIC_LINKING_ONLY */ diff --git a/src/commonlib/bsd/zstd/common/fse_decompress.c b/src/commonlib/bsd/zstd/common/fse_decompress.c new file mode 100644 index 0000000000..6fbac2992a --- /dev/null +++ b/src/commonlib/bsd/zstd/common/fse_decompress.c @@ -0,0 +1,317 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * FSE : Finite State Entropy decoder + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + + +/* ************************************************************** +* Includes +****************************************************************/ +#include "debug.h" /* assert */ +#include "bitstream.h" +#include "zstd_compiler.h" +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#include "error_private.h" +#include "zstd_deps.h" /* ZSTD_memcpy */ +#include "zstd_bits.h" /* ZSTD_highbit32 */ + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_isError ERR_isError +#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ + + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + +static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) +{ + void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ + FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr); + U16* symbolNext = (U16*)workSpace; + BYTE* spread = (BYTE*)(symbolNext + maxSymbolValue + 1); + + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + U32 highThreshold = tableSize-1; + + /* Sanity Checks */ + if (FSE_BUILD_DTABLE_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(maxSymbolValue_tooLarge); + if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); + + /* Init, lay down lowprob symbols */ + { FSE_DTableHeader DTableH; + DTableH.tableLog = (U16)tableLog; + DTableH.fastMode = 1; + { S16 const largeLimit= (S16)(1 << (tableLog-1)); + U32 s; + for (s=0; s= largeLimit) DTableH.fastMode=0; + symbolNext[s] = (U16)normalizedCounter[s]; + } } } + ZSTD_memcpy(dt, &DTableH, sizeof(DTableH)); + } + + /* Spread symbols */ + if (highThreshold == tableSize - 1) { + size_t const tableMask = tableSize-1; + size_t const step = FSE_TABLESTEP(tableSize); + /* First lay down the symbols in order. + * We use a uint64_t to lay down 8 bytes at a time. This reduces branch + * misses since small blocks generally have small table logs, so nearly + * all symbols have counts <= 8. We ensure we have 8 bytes at the end of + * our buffer to handle the over-write. + */ + { U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s highThreshold) position = (position + step) & tableMask; /* lowprob area */ + } } + if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + } + + /* Build Decoding table */ + { U32 u; + for (u=0; u sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[1] = FSE_GETSYMBOL(&state2); + + if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } } + + op[2] = FSE_GETSYMBOL(&state1); + + if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[3] = FSE_GETSYMBOL(&state2); + } + + /* tail */ + /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ + while (1) { + if (op>(omax-2)) return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state1); + if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state2); + break; + } + + if (op>(omax-2)) return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state2); + if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state1); + break; + } } + + assert(op >= ostart); + return (size_t)(op-ostart); +} + +typedef struct { + short ncount[FSE_MAX_SYMBOL_VALUE + 1]; +} FSE_DecompressWksp; + + +FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body( + void* dst, size_t dstCapacity, + const void* cSrc, size_t cSrcSize, + unsigned maxLog, void* workSpace, size_t wkspSize, + int bmi2) +{ + const BYTE* const istart = (const BYTE*)cSrc; + const BYTE* ip = istart; + unsigned tableLog; + unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; + FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace; + size_t const dtablePos = sizeof(FSE_DecompressWksp) / sizeof(FSE_DTable); + FSE_DTable* const dtable = (FSE_DTable*)workSpace + dtablePos; + + FSE_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0); + if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC); + + /* correct offset to dtable depends on this property */ + FSE_STATIC_ASSERT(sizeof(FSE_DecompressWksp) % sizeof(FSE_DTable) == 0); + + /* normal FSE decoding mode */ + { size_t const NCountLength = + FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2); + if (FSE_isError(NCountLength)) return NCountLength; + if (tableLog > maxLog) return ERROR(tableLog_tooLarge); + assert(NCountLength <= cSrcSize); + ip += NCountLength; + cSrcSize -= NCountLength; + } + + if (FSE_DECOMPRESS_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(tableLog_tooLarge); + assert(sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog) <= wkspSize); + workSpace = (BYTE*)workSpace + sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog); + wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog); + + CHECK_F( FSE_buildDTable_internal(dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) ); + + { + const void* ptr = dtable; + const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; + const U32 fastMode = DTableH->fastMode; + + /* select fast mode (static) */ + if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1); + return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0); + } +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t FSE_decompress_wksp_body_default(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) +{ + return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 0); +} + +#if DYNAMIC_BMI2 +BMI2_TARGET_ATTRIBUTE static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) +{ + return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 1); +} +#endif + +size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { + return FSE_decompress_wksp_body_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize); + } +#endif + (void)bmi2; + return FSE_decompress_wksp_body_default(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize); +} + +#endif /* FSE_COMMONDEFS_ONLY */ diff --git a/src/commonlib/bsd/zstd/common/huf.h b/src/commonlib/bsd/zstd/common/huf.h new file mode 100644 index 0000000000..c7c0f3fd43 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/huf.h @@ -0,0 +1,279 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * huff0 huffman codec, + * part of Finite State Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +#ifndef HUF_H_298734234 +#define HUF_H_298734234 + +/* *** Dependencies *** */ +#include "zstd_deps.h" /* size_t */ +#include "mem.h" /* U32 */ +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" + +/* *** Tool functions *** */ +#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */ +size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ + +/* Error Management */ +unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */ +const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */ + + +#define HUF_WORKSPACE_SIZE ((8 << 10) + 512 /* sorting scratch space */) +#define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64)) + +/* *** Constants *** */ +#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_TABLELOG_ABSOLUTEMAX */ +#define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */ +#define HUF_SYMBOLVALUE_MAX 255 + +#define HUF_TABLELOG_ABSOLUTEMAX 12 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ +#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX) +# error "HUF_TABLELOG_MAX is too large !" +#endif + + +/* **************************************** +* Static allocation +******************************************/ +/* HUF buffer bounds */ +#define HUF_CTABLEBOUND 129 +#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */ +#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* static allocation of HUF's Compression Table */ +/* this is a private definition, just exposed for allocation and strict aliasing purpose. never EVER access its members directly */ +typedef size_t HUF_CElt; /* consider it an incomplete type */ +#define HUF_CTABLE_SIZE_ST(maxSymbolValue) ((maxSymbolValue)+2) /* Use tables of size_t, for proper alignment */ +#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_ST(maxSymbolValue) * sizeof(size_t)) +#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ + HUF_CElt name[HUF_CTABLE_SIZE_ST(maxSymbolValue)] /* no final ; */ + +/* static allocation of HUF's DTable */ +typedef U32 HUF_DTable; +#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog))) +#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \ + HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) } +#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ + HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) } + + +/* **************************************** +* Advanced decompression functions +******************************************/ + +/** + * Huffman flags bitset. + * For all flags, 0 is the default value. + */ +typedef enum { + /** + * If compiled with DYNAMIC_BMI2: Set flag only if the CPU supports BMI2 at runtime. + * Otherwise: Ignored. + */ + HUF_flags_bmi2 = (1 << 0), + /** + * If set: Test possible table depths to find the one that produces the smallest header + encoded size. + * If unset: Use heuristic to find the table depth. + */ + HUF_flags_optimalDepth = (1 << 1), + /** + * If set: If the previous table can encode the input, always reuse the previous table. + * If unset: If the previous table can encode the input, reuse the previous table if it results in a smaller output. + */ + HUF_flags_preferRepeat = (1 << 2), + /** + * If set: Sample the input and check if the sample is uncompressible, if it is then don't attempt to compress. + * If unset: Always histogram the entire input. + */ + HUF_flags_suspectUncompressible = (1 << 3), + /** + * If set: Don't use assembly implementations + * If unset: Allow using assembly implementations + */ + HUF_flags_disableAsm = (1 << 4), + /** + * If set: Don't use the fast decoding loop, always use the fallback decoding loop. + * If unset: Use the fast decoding loop when possible. + */ + HUF_flags_disableFast = (1 << 5) +} HUF_flags_e; + + +/* **************************************** + * HUF detailed API + * ****************************************/ +#define HUF_OPTIMAL_DEPTH_THRESHOLD ZSTD_btultra + +/*! HUF_compress() does the following: + * 1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h") + * 2. (optional) refine tableLog using HUF_optimalTableLog() + * 3. build Huffman table from count using HUF_buildCTable() + * 4. save Huffman table to memory buffer using HUF_writeCTable() + * 5. encode the data stream using HUF_compress4X_usingCTable() + * + * The following API allows targeting specific sub-functions for advanced tasks. + * For example, it's possible to compress several blocks using the same 'CTable', + * or to save and regenerate 'CTable' using external methods. + */ +unsigned HUF_minTableLog(unsigned symbolCardinality); +unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue); +unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, void* workSpace, + size_t wkspSize, HUF_CElt* table, const unsigned* count, int flags); /* table is used as scratch space for building and testing tables, not a return value */ +size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize); +size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags); +size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue); +int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue); + +typedef enum { + HUF_repeat_none, /**< Cannot use the previous table */ + HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */ + HUF_repeat_valid /**< Can use the previous table and it is assumed to be valid */ + } HUF_repeat; + +/** HUF_compress4X_repeat() : + * Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. + * If it uses hufTable it does not modify hufTable or repeat. + * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. + * If preferRepeat then the old table will always be used if valid. + * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */ +size_t HUF_compress4X_repeat(void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ + HUF_CElt* hufTable, HUF_repeat* repeat, int flags); + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE. + */ +#define HUF_CTABLE_WORKSPACE_SIZE_U32 ((4 * (HUF_SYMBOLVALUE_MAX + 1)) + 192) +#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned)) +size_t HUF_buildCTable_wksp (HUF_CElt* tree, + const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, + void* workSpace, size_t wkspSize); + +/*! HUF_readStats() : + * Read compact Huffman tree, saved by HUF_writeCTable(). + * `huffWeight` is destination buffer. + * @return : size read from `src` , or an error Code . + * Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ +size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, + U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize); + +/*! HUF_readStats_wksp() : + * Same as HUF_readStats() but takes an external workspace which must be + * 4-byte aligned and its size must be >= HUF_READ_STATS_WORKSPACE_SIZE. + * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. + */ +#define HUF_READ_STATS_WORKSPACE_SIZE_U32 FSE_DECOMPRESS_WKSP_SIZE_U32(6, HUF_TABLELOG_MAX-1) +#define HUF_READ_STATS_WORKSPACE_SIZE (HUF_READ_STATS_WORKSPACE_SIZE_U32 * sizeof(unsigned)) +size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, + U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workspace, size_t wkspSize, + int flags); + +/** HUF_readCTable() : + * Loading a CTable saved with HUF_writeCTable() */ +size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights); + +/** HUF_getNbBitsFromCTable() : + * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX + * Note 1 : If symbolValue > HUF_readCTableHeader(symbolTable).maxSymbolValue, returns 0 + * Note 2 : is not inlined, as HUF_CElt definition is private + */ +U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue); + +typedef struct { + BYTE tableLog; + BYTE maxSymbolValue; + BYTE unused[sizeof(size_t) - 2]; +} HUF_CTableHeader; + +/** HUF_readCTableHeader() : + * @returns The header from the CTable specifying the tableLog and the maxSymbolValue. + */ +HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable); + +/* + * HUF_decompress() does the following: + * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics + * 2. build Huffman table from save, using HUF_readDTableX?() + * 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable() + */ + +/** HUF_selectDecoder() : + * Tells which decoder is likely to decode faster, + * based on a set of pre-computed metrics. + * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . + * Assumption : 0 < dstSize <= 128 KB */ +U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize); + +/** + * The minimum workspace size for the `workSpace` used in + * HUF_readDTableX1_wksp() and HUF_readDTableX2_wksp(). + * + * The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when + * HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15. + * Buffer overflow errors may potentially occur if code modifications result in + * a required workspace size greater than that specified in the following + * macro. + */ +#define HUF_DECOMPRESS_WORKSPACE_SIZE ((2 << 10) + (1 << 9)) +#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) + + +/* ====================== */ +/* single stream variants */ +/* ====================== */ + +size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags); +/** HUF_compress1X_repeat() : + * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. + * If it uses hufTable it does not modify hufTable or repeat. + * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. + * If preferRepeat then the old table will always be used if valid. + * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */ +size_t HUF_compress1X_repeat(void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ + HUF_CElt* hufTable, HUF_repeat* repeat, int flags); + +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); +#ifndef HUF_FORCE_DECOMPRESS_X1 +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); /**< double-symbols decoder */ +#endif + +/* BMI2 variants. + * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. + */ +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags); +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); +#endif +size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags); +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags); +#endif +#ifndef HUF_FORCE_DECOMPRESS_X1 +size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags); +#endif + +#endif /* HUF_H_298734234 */ diff --git a/src/commonlib/bsd/zstd/common/mem.h b/src/commonlib/bsd/zstd/common/mem.h new file mode 100644 index 0000000000..4b2a4aebef --- /dev/null +++ b/src/commonlib/bsd/zstd/common/mem.h @@ -0,0 +1,424 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef MEM_H_MODULE +#define MEM_H_MODULE + +/*-**************************************** +* Dependencies +******************************************/ +#include /* size_t, ptrdiff_t */ +#include "zstd_compiler.h" /* __has_builtin */ +#include "debug.h" /* DEBUG_STATIC_ASSERT */ +#include "zstd_deps.h" /* ZSTD_memcpy */ + + +/*-**************************************** +* Compiler specifics +******************************************/ +#if defined(_MSC_VER) /* Visual Studio */ +# include /* _byteswap_ulong */ +# include /* _byteswap_* */ +#elif defined(__ICCARM__) +# include +#endif + +/*-************************************************************** +* Basic Types +*****************************************************************/ +#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# if defined(_AIX) +# include +# else +# include /* intptr_t */ +# endif + typedef uint8_t BYTE; + typedef uint8_t U8; + typedef int8_t S8; + typedef uint16_t U16; + typedef int16_t S16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; + typedef int64_t S64; +#else +# include +#if CHAR_BIT != 8 +# error "this implementation requires char to be exactly 8-bit type" +#endif + typedef unsigned char BYTE; + typedef unsigned char U8; + typedef signed char S8; +#if USHRT_MAX != 65535 +# error "this implementation requires short to be exactly 16-bit type" +#endif + typedef unsigned short U16; + typedef signed short S16; +#if UINT_MAX != 4294967295 +# error "this implementation requires int to be exactly 32-bit type" +#endif + typedef unsigned int U32; + typedef signed int S32; +/* note : there are no limits defined for long long type in C90. + * limits exist in C99, however, in such case, is preferred */ + typedef unsigned long long U64; + typedef signed long long S64; +#endif + +/*-************************************************************** +* Memory I/O API +*****************************************************************/ +/*=== Static platform detection ===*/ +MEM_STATIC unsigned MEM_32bits(void); +MEM_STATIC unsigned MEM_64bits(void); +MEM_STATIC unsigned MEM_isLittleEndian(void); + +/*=== Native unaligned read/write ===*/ +MEM_STATIC U16 MEM_read16(const void* memPtr); +MEM_STATIC U32 MEM_read32(const void* memPtr); +MEM_STATIC U64 MEM_read64(const void* memPtr); +MEM_STATIC size_t MEM_readST(const void* memPtr); + +MEM_STATIC void MEM_write16(void* memPtr, U16 value); +MEM_STATIC void MEM_write32(void* memPtr, U32 value); +MEM_STATIC void MEM_write64(void* memPtr, U64 value); + +/*=== Little endian unaligned read/write ===*/ +MEM_STATIC U16 MEM_readLE16(const void* memPtr); +MEM_STATIC U32 MEM_readLE24(const void* memPtr); +MEM_STATIC U32 MEM_readLE32(const void* memPtr); +MEM_STATIC U64 MEM_readLE64(const void* memPtr); +MEM_STATIC size_t MEM_readLEST(const void* memPtr); + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val); +MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val); +MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32); +MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64); +MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val); + +/*=== Big endian unaligned read/write ===*/ +MEM_STATIC U32 MEM_readBE32(const void* memPtr); +MEM_STATIC U64 MEM_readBE64(const void* memPtr); +MEM_STATIC size_t MEM_readBEST(const void* memPtr); + +MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32); +MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64); +MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val); + +/*=== Byteswap ===*/ +MEM_STATIC U32 MEM_swap32(U32 in); +MEM_STATIC U64 MEM_swap64(U64 in); +MEM_STATIC size_t MEM_swapST(size_t in); + + +/*-************************************************************** +* Memory I/O Implementation +*****************************************************************/ +/* MEM_FORCE_MEMORY_ACCESS : For accessing unaligned memory: + * Method 0 : always use `memcpy()`. Safe and portable. + * Method 1 : Use compiler extension to set unaligned access. + * Method 2 : direct access. This method is portable but violate C standard. + * It can generate buggy code on targets depending on alignment. + * Default : method 1 if supported, else method 0 + */ +#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# ifdef __GNUC__ +# define MEM_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; } +MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; } + +MEM_STATIC unsigned MEM_isLittleEndian(void) +{ +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + return 1; +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + return 0; +#elif defined(__clang__) && __LITTLE_ENDIAN__ + return 1; +#elif defined(__clang__) && __BIG_ENDIAN__ + return 0; +#elif defined(_MSC_VER) && (_M_X64 || _M_IX86) + return 1; +#elif defined(__DMC__) && defined(_M_IX86) + return 1; +#elif defined(__IAR_SYSTEMS_ICC__) && __LITTLE_ENDIAN__ + return 1; +#else + const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +#endif +} + +#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) + +/* violates C standard, by lying on structure alignment. +Only use if no other choice to achieve best performance on target platform */ +MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } +MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } +MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } +MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; } + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } +MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } +MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; } + +#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) + +typedef __attribute__((aligned(1))) U16 unalign16; +typedef __attribute__((aligned(1))) U32 unalign32; +typedef __attribute__((aligned(1))) U64 unalign64; +typedef __attribute__((aligned(1))) size_t unalignArch; + +MEM_STATIC U16 MEM_read16(const void* ptr) { return *(const unalign16*)ptr; } +MEM_STATIC U32 MEM_read32(const void* ptr) { return *(const unalign32*)ptr; } +MEM_STATIC U64 MEM_read64(const void* ptr) { return *(const unalign64*)ptr; } +MEM_STATIC size_t MEM_readST(const void* ptr) { return *(const unalignArch*)ptr; } + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(unalign16*)memPtr = value; } +MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(unalign32*)memPtr = value; } +MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(unalign64*)memPtr = value; } + +#else + +/* default method, safe and standard. + can sometimes prove slower */ + +MEM_STATIC U16 MEM_read16(const void* memPtr) +{ + U16 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U32 MEM_read32(const void* memPtr) +{ + U32 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U64 MEM_read64(const void* memPtr) +{ + U64 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC size_t MEM_readST(const void* memPtr) +{ + size_t val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) +{ + ZSTD_memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC void MEM_write32(void* memPtr, U32 value) +{ + ZSTD_memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC void MEM_write64(void* memPtr, U64 value) +{ + ZSTD_memcpy(memPtr, &value, sizeof(value)); +} + +#endif /* MEM_FORCE_MEMORY_ACCESS */ + +MEM_STATIC U32 MEM_swap32_fallback(U32 in) +{ + return ((in << 24) & 0xff000000 ) | + ((in << 8) & 0x00ff0000 ) | + ((in >> 8) & 0x0000ff00 ) | + ((in >> 24) & 0x000000ff ); +} + +MEM_STATIC U32 MEM_swap32(U32 in) +{ +#if defined(_MSC_VER) /* Visual Studio */ + return _byteswap_ulong(in); +#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \ + || (defined(__clang__) && __has_builtin(__builtin_bswap32)) + return __builtin_bswap32(in); +#elif defined(__ICCARM__) + return __REV(in); +#else + return MEM_swap32_fallback(in); +#endif +} + +MEM_STATIC U64 MEM_swap64_fallback(U64 in) +{ + return ((in << 56) & 0xff00000000000000ULL) | + ((in << 40) & 0x00ff000000000000ULL) | + ((in << 24) & 0x0000ff0000000000ULL) | + ((in << 8) & 0x000000ff00000000ULL) | + ((in >> 8) & 0x00000000ff000000ULL) | + ((in >> 24) & 0x0000000000ff0000ULL) | + ((in >> 40) & 0x000000000000ff00ULL) | + ((in >> 56) & 0x00000000000000ffULL); +} + +MEM_STATIC U64 MEM_swap64(U64 in) +{ +#if defined(_MSC_VER) /* Visual Studio */ + return _byteswap_uint64(in); +#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \ + || (defined(__clang__) && __has_builtin(__builtin_bswap64)) + return __builtin_bswap64(in); +#else + return MEM_swap64_fallback(in); +#endif +} + +MEM_STATIC size_t MEM_swapST(size_t in) +{ + if (MEM_32bits()) + return (size_t)MEM_swap32((U32)in); + else + return (size_t)MEM_swap64((U64)in); +} + +/*=== Little endian r/w ===*/ + +MEM_STATIC U16 MEM_readLE16(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read16(memPtr); + else { + const BYTE* p = (const BYTE*)memPtr; + return (U16)(p[0] + (p[1]<<8)); + } +} + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val) +{ + if (MEM_isLittleEndian()) { + MEM_write16(memPtr, val); + } else { + BYTE* p = (BYTE*)memPtr; + p[0] = (BYTE)val; + p[1] = (BYTE)(val>>8); + } +} + +MEM_STATIC U32 MEM_readLE24(const void* memPtr) +{ + return (U32)MEM_readLE16(memPtr) + ((U32)(((const BYTE*)memPtr)[2]) << 16); +} + +MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val) +{ + MEM_writeLE16(memPtr, (U16)val); + ((BYTE*)memPtr)[2] = (BYTE)(val>>16); +} + +MEM_STATIC U32 MEM_readLE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read32(memPtr); + else + return MEM_swap32(MEM_read32(memPtr)); +} + +MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32) +{ + if (MEM_isLittleEndian()) + MEM_write32(memPtr, val32); + else + MEM_write32(memPtr, MEM_swap32(val32)); +} + +MEM_STATIC U64 MEM_readLE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read64(memPtr); + else + return MEM_swap64(MEM_read64(memPtr)); +} + +MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64) +{ + if (MEM_isLittleEndian()) + MEM_write64(memPtr, val64); + else + MEM_write64(memPtr, MEM_swap64(val64)); +} + +MEM_STATIC size_t MEM_readLEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readLE32(memPtr); + else + return (size_t)MEM_readLE64(memPtr); +} + +MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeLE32(memPtr, (U32)val); + else + MEM_writeLE64(memPtr, (U64)val); +} + +/*=== Big endian r/w ===*/ + +MEM_STATIC U32 MEM_readBE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_swap32(MEM_read32(memPtr)); + else + return MEM_read32(memPtr); +} + +MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32) +{ + if (MEM_isLittleEndian()) + MEM_write32(memPtr, MEM_swap32(val32)); + else + MEM_write32(memPtr, val32); +} + +MEM_STATIC U64 MEM_readBE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_swap64(MEM_read64(memPtr)); + else + return MEM_read64(memPtr); +} + +MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64) +{ + if (MEM_isLittleEndian()) + MEM_write64(memPtr, MEM_swap64(val64)); + else + MEM_write64(memPtr, val64); +} + +MEM_STATIC size_t MEM_readBEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readBE32(memPtr); + else + return (size_t)MEM_readBE64(memPtr); +} + +MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeBE32(memPtr, (U32)val); + else + MEM_writeBE64(memPtr, (U64)val); +} + +/* code only tested on 32 and 64 bits systems */ +MEM_STATIC void MEM_check(void) { DEBUG_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); } + +#endif /* MEM_H_MODULE */ diff --git a/src/commonlib/bsd/zstd/common/portability_macros.h b/src/commonlib/bsd/zstd/common/portability_macros.h new file mode 100644 index 0000000000..e61f0784d3 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/portability_macros.h @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_PORTABILITY_MACROS_H +#define ZSTD_PORTABILITY_MACROS_H + +/** + * This header file contains macro definitions to support portability. + * This header is shared between C and ASM code, so it MUST only + * contain macro definitions. It MUST not contain any C code. + * + * This header ONLY defines macros to detect platforms/feature support. + * + */ + + +/* compat. with non-clang compilers */ +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +/* compat. with non-clang compilers */ +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/* compat. with non-clang compilers */ +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + +/* detects whether we are being compiled under msan */ +#ifndef ZSTD_MEMORY_SANITIZER +# if __has_feature(memory_sanitizer) +# define ZSTD_MEMORY_SANITIZER 1 +# else +# define ZSTD_MEMORY_SANITIZER 0 +# endif +#endif + +/* detects whether we are being compiled under asan */ +#ifndef ZSTD_ADDRESS_SANITIZER +# if __has_feature(address_sanitizer) +# define ZSTD_ADDRESS_SANITIZER 1 +# elif defined(__SANITIZE_ADDRESS__) +# define ZSTD_ADDRESS_SANITIZER 1 +# else +# define ZSTD_ADDRESS_SANITIZER 0 +# endif +#endif + +/* detects whether we are being compiled under dfsan */ +#ifndef ZSTD_DATAFLOW_SANITIZER +# if __has_feature(dataflow_sanitizer) +# define ZSTD_DATAFLOW_SANITIZER 1 +# else +# define ZSTD_DATAFLOW_SANITIZER 0 +# endif +#endif + +/* Mark the internal assembly functions as hidden */ +#ifdef __ELF__ +# define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func +#elif defined(__APPLE__) +# define ZSTD_HIDE_ASM_FUNCTION(func) .private_extern func +#else +# define ZSTD_HIDE_ASM_FUNCTION(func) +#endif + +/* Compile time determination of BMI2 support */ +#ifndef STATIC_BMI2 +# if defined(__BMI2__) +# define STATIC_BMI2 1 +# elif defined(_MSC_VER) && defined(__AVX2__) +# define STATIC_BMI2 1 /* MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2 */ +# endif +#endif + +#ifndef STATIC_BMI2 +# define STATIC_BMI2 0 +#endif + +/* Enable runtime BMI2 dispatch based on the CPU. + * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default. + */ +#ifndef DYNAMIC_BMI2 +# if ((defined(__clang__) && __has_attribute(__target__)) \ + || (defined(__GNUC__) \ + && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ + && (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)) \ + && !defined(__BMI2__) +# define DYNAMIC_BMI2 1 +# else +# define DYNAMIC_BMI2 0 +# endif +#endif + +/** + * Only enable assembly for GNU C compatible compilers, + * because other platforms may not support GAS assembly syntax. + * + * Only enable assembly for Linux / MacOS / Win32, other platforms may + * work, but they haven't been tested. This could likely be + * extended to BSD systems. + * + * Disable assembly when MSAN is enabled, because MSAN requires + * 100% of code to be instrumented to work. + */ +#if defined(__GNUC__) +# if defined(__linux__) || defined(__linux) || defined(__APPLE__) || defined(_WIN32) +# if ZSTD_MEMORY_SANITIZER +# define ZSTD_ASM_SUPPORTED 0 +# elif ZSTD_DATAFLOW_SANITIZER +# define ZSTD_ASM_SUPPORTED 0 +# else +# define ZSTD_ASM_SUPPORTED 1 +# endif +# else +# define ZSTD_ASM_SUPPORTED 0 +# endif +#else +# define ZSTD_ASM_SUPPORTED 0 +#endif + +/** + * Determines whether we should enable assembly for x86-64 + * with BMI2. + * + * Enable if all of the following conditions hold: + * - ASM hasn't been explicitly disabled by defining ZSTD_DISABLE_ASM + * - Assembly is supported + * - We are compiling for x86-64 and either: + * - DYNAMIC_BMI2 is enabled + * - BMI2 is supported at compile time + */ +#if !defined(ZSTD_DISABLE_ASM) && \ + ZSTD_ASM_SUPPORTED && \ + defined(__x86_64__) && \ + (DYNAMIC_BMI2 || defined(__BMI2__)) +# define ZSTD_ENABLE_ASM_X86_64_BMI2 1 +#else +# define ZSTD_ENABLE_ASM_X86_64_BMI2 0 +#endif + +/* + * For x86 ELF targets, add .note.gnu.property section for Intel CET in + * assembly sources when CET is enabled. + * + * Additionally, any function that may be called indirectly must begin + * with ZSTD_CET_ENDBRANCH. + */ +#if defined(__ELF__) && (defined(__x86_64__) || defined(__i386__)) \ + && defined(__has_include) +# if __has_include() +# include +# define ZSTD_CET_ENDBRANCH _CET_ENDBR +# endif +#endif + +#ifndef ZSTD_CET_ENDBRANCH +# define ZSTD_CET_ENDBRANCH +#endif + +#endif /* ZSTD_PORTABILITY_MACROS_H */ diff --git a/src/commonlib/bsd/zstd/common/zstd_bits.h b/src/commonlib/bsd/zstd/common/zstd_bits.h new file mode 100644 index 0000000000..5128d00ccf --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_bits.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_BITS_H +#define ZSTD_BITS_H + +#include "mem.h" + +MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val) +{ + assert(val != 0); + { + static const U32 DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3, + 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, + 26, 12, 18, 6, 11, 5, 10, 9}; + return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >> 27]; + } +} + +MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val) +{ + assert(val != 0); +#if defined(_MSC_VER) +# if STATIC_BMI2 + return (unsigned)_tzcnt_u32(val); +# else + if (val != 0) { + unsigned long r; + _BitScanForward(&r, val); + return (unsigned)r; + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) + return (unsigned)__builtin_ctz(val); +#elif defined(__ICCARM__) + return (unsigned)__builtin_ctz(val); +#else + return ZSTD_countTrailingZeros32_fallback(val); +#endif +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val) +{ + assert(val != 0); + { + static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31}; + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + val |= val >> 8; + val |= val >> 16; + return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27]; + } +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val) +{ + assert(val != 0); +#if defined(_MSC_VER) +# if STATIC_BMI2 + return (unsigned)_lzcnt_u32(val); +# else + if (val != 0) { + unsigned long r; + _BitScanReverse(&r, val); + return (unsigned)(31 - r); + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) + return (unsigned)__builtin_clz(val); +#elif defined(__ICCARM__) + return (unsigned)__builtin_clz(val); +#else + return ZSTD_countLeadingZeros32_fallback(val); +#endif +} + +MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val) +{ + assert(val != 0); +#if defined(_MSC_VER) && defined(_WIN64) +# if STATIC_BMI2 + return (unsigned)_tzcnt_u64(val); +# else + if (val != 0) { + unsigned long r; + _BitScanForward64(&r, val); + return (unsigned)r; + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__) + return (unsigned)__builtin_ctzll(val); +#elif defined(__ICCARM__) + return (unsigned)__builtin_ctzll(val); +#else + { + U32 mostSignificantWord = (U32)(val >> 32); + U32 leastSignificantWord = (U32)val; + if (leastSignificantWord == 0) { + return 32 + ZSTD_countTrailingZeros32(mostSignificantWord); + } else { + return ZSTD_countTrailingZeros32(leastSignificantWord); + } + } +#endif +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val) +{ + assert(val != 0); +#if defined(_MSC_VER) && defined(_WIN64) +# if STATIC_BMI2 + return (unsigned)_lzcnt_u64(val); +# else + if (val != 0) { + unsigned long r; + _BitScanReverse64(&r, val); + return (unsigned)(63 - r); + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) + return (unsigned)(__builtin_clzll(val)); +#elif defined(__ICCARM__) + return (unsigned)(__builtin_clzll(val)); +#else + { + U32 mostSignificantWord = (U32)(val >> 32); + U32 leastSignificantWord = (U32)val; + if (mostSignificantWord == 0) { + return 32 + ZSTD_countLeadingZeros32(leastSignificantWord); + } else { + return ZSTD_countLeadingZeros32(mostSignificantWord); + } + } +#endif +} + +MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val) +{ + if (MEM_isLittleEndian()) { + if (MEM_64bits()) { + return ZSTD_countTrailingZeros64((U64)val) >> 3; + } else { + return ZSTD_countTrailingZeros32((U32)val) >> 3; + } + } else { /* Big Endian CPU */ + if (MEM_64bits()) { + return ZSTD_countLeadingZeros64((U64)val) >> 3; + } else { + return ZSTD_countLeadingZeros32((U32)val) >> 3; + } + } +} + +MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */ +{ + assert(val != 0); + return 31 - ZSTD_countLeadingZeros32(val); +} + +/* ZSTD_rotateRight_*(): + * Rotates a bitfield to the right by "count" bits. + * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts + */ +MEM_STATIC +U64 ZSTD_rotateRight_U64(U64 const value, U32 count) { + assert(count < 64); + count &= 0x3F; /* for fickle pattern recognition */ + return (value >> count) | (U64)(value << ((0U - count) & 0x3F)); +} + +MEM_STATIC +U32 ZSTD_rotateRight_U32(U32 const value, U32 count) { + assert(count < 32); + count &= 0x1F; /* for fickle pattern recognition */ + return (value >> count) | (U32)(value << ((0U - count) & 0x1F)); +} + +MEM_STATIC +U16 ZSTD_rotateRight_U16(U16 const value, U32 count) { + assert(count < 16); + count &= 0x0F; /* for fickle pattern recognition */ + return (value >> count) | (U16)(value << ((0U - count) & 0x0F)); +} + +#endif /* ZSTD_BITS_H */ diff --git a/src/commonlib/bsd/zstd/common/zstd_common.c b/src/commonlib/bsd/zstd/common/zstd_common.c new file mode 100644 index 0000000000..9b551ec867 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_common.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + + +/*-************************************* +* Dependencies +***************************************/ +#define ZSTD_DEPS_NEED_MALLOC +#include "error_private.h" +#include "zstd_internal.h" + + +/*-**************************************** +* Version +******************************************/ +unsigned ZSTD_versionNumber(void) { return ZSTD_VERSION_NUMBER; } + +const char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; } + + +/*-**************************************** +* ZSTD Error Management +******************************************/ +#undef ZSTD_isError /* defined within zstd_internal.h */ +/*! ZSTD_isError() : + * tells if a return value is an error code + * symbol is required for external callers */ +unsigned ZSTD_isError(size_t code) { return ERR_isError(code); } + +/*! ZSTD_getErrorName() : + * provides error code string from function result (useful for debugging) */ +const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); } + +/*! ZSTD_getError() : + * convert a `size_t` function result into a proper ZSTD_errorCode enum */ +ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); } + +/*! ZSTD_getErrorString() : + * provides error code string from enum */ +const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); } diff --git a/src/commonlib/bsd/zstd/common/zstd_compiler.h b/src/commonlib/bsd/zstd/common/zstd_compiler.h new file mode 100644 index 0000000000..80df87162e --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_compiler.h @@ -0,0 +1,462 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPILER_H +#define ZSTD_COMPILER_H + +#include + +#include "portability_macros.h" + +/*-******************************************************* +* Compiler specifics +*********************************************************/ +/* force inlining */ + +#if !defined(ZSTD_NO_INLINE) +#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# define INLINE_KEYWORD inline +#else +# define INLINE_KEYWORD +#endif + +#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define FORCE_INLINE_ATTR __attribute__((always_inline)) +#elif defined(_MSC_VER) +# define FORCE_INLINE_ATTR __forceinline +#else +# define FORCE_INLINE_ATTR +#endif + +#else + +#define INLINE_KEYWORD +#define FORCE_INLINE_ATTR + +#endif + +/** + On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC). + This explicitly marks such functions as __cdecl so that the code will still compile + if a CC other than __cdecl has been made the default. +*/ +#if defined(_MSC_VER) +# define WIN_CDECL __cdecl +#else +# define WIN_CDECL +#endif + +/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */ +#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define UNUSED_ATTR __attribute__((unused)) +#else +# define UNUSED_ATTR +#endif + +/** + * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant + * parameters. They must be inlined for the compiler to eliminate the constant + * branches. + */ +#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR UNUSED_ATTR +/** + * HINT_INLINE is used to help the compiler generate better code. It is *not* + * used for "templates", so it can be tweaked based on the compilers + * performance. + * + * gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the + * always_inline attribute. + * + * clang up to 5.0.0 (trunk) benefit tremendously from the always_inline + * attribute. + */ +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5 +# define HINT_INLINE static INLINE_KEYWORD +#else +# define HINT_INLINE FORCE_INLINE_TEMPLATE +#endif + +/* "soft" inline : + * The compiler is free to select if it's a good idea to inline or not. + * The main objective is to silence compiler warnings + * when a defined function in included but not used. + * + * Note : this macro is prefixed `MEM_` because it used to be provided by `mem.h` unit. + * Updating the prefix is probably preferable, but requires a fairly large codemod, + * since this name is used everywhere. + */ +#ifndef MEM_STATIC /* already defined in Linux Kernel mem.h */ +#if defined(__GNUC__) +# define MEM_STATIC static __inline UNUSED_ATTR +#elif defined(__IAR_SYSTEMS_ICC__) +# define MEM_STATIC static inline UNUSED_ATTR +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define MEM_STATIC static inline +#elif defined(_MSC_VER) +# define MEM_STATIC static __inline +#else +# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif +#endif + +/* force no inlining */ +#ifdef _MSC_VER +# define FORCE_NOINLINE static __declspec(noinline) +#else +# if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define FORCE_NOINLINE static __attribute__((__noinline__)) +# else +# define FORCE_NOINLINE static +# endif +#endif + + +/* target attribute */ +#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) +#else +# define TARGET_ATTRIBUTE(target) +#endif + +/* Target attribute for BMI2 dynamic dispatch. + * Enable lzcnt, bmi, and bmi2. + * We test for bmi1 & bmi2. lzcnt is included in bmi1. + */ +#define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2") + +/* prefetch + * can be disabled, by declaring NO_PREFETCH build macro */ +#if defined(NO_PREFETCH) +# define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */ +# define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */ +#else +# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) && !defined(_M_ARM64EC) /* _mm_prefetch() is not defined outside of x86/x64 */ +# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) +# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1) +# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) +# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) +# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */) +# elif defined(__aarch64__) +# define PREFETCH_L1(ptr) do { __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))); } while (0) +# define PREFETCH_L2(ptr) do { __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))); } while (0) +# else +# define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */ +# define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */ +# endif +#endif /* NO_PREFETCH */ + +#define CACHELINE_SIZE 64 + +#define PREFETCH_AREA(p, s) \ + do { \ + const char* const _ptr = (const char*)(p); \ + size_t const _size = (size_t)(s); \ + size_t _pos; \ + for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \ + PREFETCH_L2(_ptr + _pos); \ + } \ + } while (0) + +/* vectorization + * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax, + * and some compilers, like Intel ICC and MCST LCC, do not support it at all. */ +#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5) +# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize"))) +# else +# define DONT_VECTORIZE _Pragma("GCC optimize(\"no-tree-vectorize\")") +# endif +#else +# define DONT_VECTORIZE +#endif + +/* Tell the compiler that a branch is likely or unlikely. + * Only use these macros if it causes the compiler to generate better code. + * If you can remove a LIKELY/UNLIKELY annotation without speed changes in gcc + * and clang, please do. + */ +#if defined(__GNUC__) +#define LIKELY(x) (__builtin_expect((x), 1)) +#define UNLIKELY(x) (__builtin_expect((x), 0)) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#endif + +#if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))) +# define ZSTD_UNREACHABLE do { assert(0), __builtin_unreachable(); } while (0) +#else +# define ZSTD_UNREACHABLE do { assert(0); } while (0) +#endif + +/* disable warnings */ +#ifdef _MSC_VER /* Visual Studio */ +# include /* For Visual 2005 */ +# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */ +# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */ +# pragma warning(disable : 4324) /* disable: C4324: padded structure */ +#endif + +/* compile time determination of SIMD support */ +#if !defined(ZSTD_NO_INTRINSICS) +# if defined(__AVX2__) +# define ZSTD_ARCH_X86_AVX2 +# endif +# if defined(__SSE2__) || defined(_M_X64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) +# define ZSTD_ARCH_X86_SSE2 +# endif +# +# if defined(ZSTD_ARCH_X86_AVX2) +# include +# endif +# if defined(ZSTD_ARCH_X86_SSE2) +# include +# elif defined(ZSTD_ARCH_ARM_NEON) +# include +# endif +#endif + +/* C-language Attributes are added in C23. */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute) +# define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x) +#else +# define ZSTD_HAS_C_ATTRIBUTE(x) 0 +#endif + +/* Only use C++ attributes in C++. Some compilers report support for C++ + * attributes when compiling with C. + */ +#if defined(__cplusplus) && defined(__has_cpp_attribute) +# define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define ZSTD_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +/* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute. + * - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough + * - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough + * - Else: __attribute__((__fallthrough__)) + */ +#ifndef ZSTD_FALLTHROUGH +# if ZSTD_HAS_C_ATTRIBUTE(fallthrough) +# define ZSTD_FALLTHROUGH [[fallthrough]] +# elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough) +# define ZSTD_FALLTHROUGH [[fallthrough]] +# elif __has_attribute(__fallthrough__) +/* Leading semicolon is to satisfy gcc-11 with -pedantic. Without the semicolon + * gcc complains about: a label can only be part of a statement and a declaration is not a statement. + */ +# define ZSTD_FALLTHROUGH ; __attribute__((__fallthrough__)) +# else +# define ZSTD_FALLTHROUGH +# endif +#endif + +/*-************************************************************** +* Alignment +*****************************************************************/ + +/* @return 1 if @u is a 2^n value, 0 otherwise + * useful to check a value is valid for alignment restrictions */ +MEM_STATIC int ZSTD_isPower2(size_t u) { + return (u & (u-1)) == 0; +} + +/* this test was initially positioned in mem.h, + * but this file is removed (or replaced) for linux kernel + * so it's now hosted in compiler.h, + * which remains valid for both user & kernel spaces. + */ + +#ifndef ZSTD_ALIGNOF +# if defined(__GNUC__) || defined(_MSC_VER) +/* covers gcc, clang & MSVC */ +/* note : this section must come first, before C11, + * due to a limitation in the kernel source generator */ +# define ZSTD_ALIGNOF(T) __alignof(T) + +# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +/* C11 support */ +# include +# define ZSTD_ALIGNOF(T) alignof(T) + +# else +/* No known support for alignof() - imperfect backup */ +# define ZSTD_ALIGNOF(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T)) + +# endif +#endif /* ZSTD_ALIGNOF */ + +#ifndef ZSTD_ALIGNED +/* C90-compatible alignment macro (GCC/Clang). Adjust for other compilers if needed. */ +# if defined(__GNUC__) || defined(__clang__) +# define ZSTD_ALIGNED(a) __attribute__((aligned(a))) +# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ +# define ZSTD_ALIGNED(a) _Alignas(a) +#elif defined(_MSC_VER) +# define ZSTD_ALIGNED(n) __declspec(align(n)) +# else + /* this compiler will require its own alignment instruction */ +# define ZSTD_ALIGNED(...) +# endif +#endif /* ZSTD_ALIGNED */ + + +/*-************************************************************** +* Sanitizer +*****************************************************************/ + +/** + * Zstd relies on pointer overflow in its decompressor. + * We add this attribute to functions that rely on pointer overflow. + */ +#ifndef ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +# if __has_attribute(no_sanitize) +# if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8 + /* gcc < 8 only has signed-integer-overlow which triggers on pointer overflow */ +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("signed-integer-overflow"))) +# else + /* older versions of clang [3.7, 5.0) will warn that pointer-overflow is ignored. */ +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("pointer-overflow"))) +# endif +# else +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +# endif +#endif + +/** + * Helper function to perform a wrapped pointer difference without triggering + * UBSAN. + * + * @returns lhs - rhs with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +ptrdiff_t ZSTD_wrappedPtrDiff(unsigned char const* lhs, unsigned char const* rhs) +{ + return lhs - rhs; +} + +/** + * Helper function to perform a wrapped pointer add without triggering UBSAN. + * + * @return ptr + add with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add) +{ + return ptr + add; +} + +/** + * Helper function to perform a wrapped pointer subtraction without triggering + * UBSAN. + * + * @return ptr - sub with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* ptr, ptrdiff_t sub) +{ + return ptr - sub; +} + +/** + * Helper function to add to a pointer that works around C's undefined behavior + * of adding 0 to NULL. + * + * @returns `ptr + add` except it defines `NULL + 0 == NULL`. + */ +MEM_STATIC +unsigned char* ZSTD_maybeNullPtrAdd(unsigned char* ptr, ptrdiff_t add) +{ + return add > 0 ? ptr + add : ptr; +} + +/* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an + * abundance of caution, disable our custom poisoning on mingw. */ +#ifdef __MINGW32__ +#ifndef ZSTD_ASAN_DONT_POISON_WORKSPACE +#define ZSTD_ASAN_DONT_POISON_WORKSPACE 1 +#endif +#ifndef ZSTD_MSAN_DONT_POISON_WORKSPACE +#define ZSTD_MSAN_DONT_POISON_WORKSPACE 1 +#endif +#endif + +#if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE) +/* Not all platforms that support msan provide sanitizers/msan_interface.h. + * We therefore declare the functions we need ourselves, rather than trying to + * include the header file... */ +#include /* size_t */ +#define ZSTD_DEPS_NEED_STDINT +#include "zstd_deps.h" /* intptr_t */ + +/* Make memory region fully initialized (without changing its contents). */ +void __msan_unpoison(const volatile void *a, size_t size); + +/* Make memory region fully uninitialized (without changing its contents). + This is a legacy interface that does not update origin information. Use + __msan_allocated_memory() instead. */ +void __msan_poison(const volatile void *a, size_t size); + +/* Returns the offset of the first (at least partially) poisoned byte in the + memory range, or -1 if the whole range is good. */ +intptr_t __msan_test_shadow(const volatile void *x, size_t size); + +/* Print shadow and origin for the memory range to stderr in a human-readable + format. */ +void __msan_print_shadow(const volatile void *x, size_t size); +#endif + +#if ZSTD_ADDRESS_SANITIZER && !defined(ZSTD_ASAN_DONT_POISON_WORKSPACE) +/* Not all platforms that support asan provide sanitizers/asan_interface.h. + * We therefore declare the functions we need ourselves, rather than trying to + * include the header file... */ +#include /* size_t */ + +/** + * Marks a memory region ([addr, addr+size)) as unaddressable. + * + * This memory must be previously allocated by your program. Instrumented + * code is forbidden from accessing addresses in this region until it is + * unpoisoned. This function is not guaranteed to poison the entire region - + * it could poison only a subregion of [addr, addr+size) due to ASan + * alignment restrictions. + * + * \note This function is not thread-safe because no two threads can poison or + * unpoison memory in the same memory region simultaneously. + * + * \param addr Start of memory region. + * \param size Size of memory region. */ +void __asan_poison_memory_region(void const volatile *addr, size_t size); + +/** + * Marks a memory region ([addr, addr+size)) as addressable. + * + * This memory must be previously allocated by your program. Accessing + * addresses in this region is allowed until this region is poisoned again. + * This function could unpoison a super-region of [addr, addr+size) due + * to ASan alignment restrictions. + * + * \note This function is not thread-safe because no two threads can + * poison or unpoison memory in the same memory region simultaneously. + * + * \param addr Start of memory region. + * \param size Size of memory region. */ +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +#endif + +#endif /* ZSTD_COMPILER_H */ diff --git a/src/commonlib/bsd/zstd/common/zstd_deps.h b/src/commonlib/bsd/zstd/common/zstd_deps.h new file mode 100644 index 0000000000..7ad8df1a21 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_deps.h @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This file provides common libc dependencies that zstd requires. + * The purpose is to allow replacing this file with a custom implementation + * to compile zstd without libc support. + */ + +/* Need: + * NULL + * INT_MAX + * UINT_MAX + * ZSTD_memcpy() + * ZSTD_memset() + * ZSTD_memmove() + */ +#ifndef ZSTD_DEPS_COMMON +#define ZSTD_DEPS_COMMON + +/* Even though we use qsort_r only for the dictionary builder, the macro + * _GNU_SOURCE has to be declared *before* the inclusion of any standard + * header and the script 'combine.sh' combines the whole zstd source code + * in a single file. + */ +#if defined(__linux) || defined(__linux__) || defined(linux) || defined(__gnu_linux__) || \ + defined(__CYGWIN__) || defined(__MSYS__) +#if !defined(_GNU_SOURCE) && !defined(__ANDROID__) /* NDK doesn't ship qsort_r(). */ +#define _GNU_SOURCE +#endif +#endif + +#include +#include +#include + +#if defined(__GNUC__) && __GNUC__ >= 4 +# define ZSTD_memcpy(d,s,l) __builtin_memcpy((d),(s),(l)) +# define ZSTD_memmove(d,s,l) __builtin_memmove((d),(s),(l)) +# define ZSTD_memset(p,v,l) __builtin_memset((p),(v),(l)) +#else +# define ZSTD_memcpy(d,s,l) memcpy((d),(s),(l)) +# define ZSTD_memmove(d,s,l) memmove((d),(s),(l)) +# define ZSTD_memset(p,v,l) memset((p),(v),(l)) +#endif + +#endif /* ZSTD_DEPS_COMMON */ + +/* Need: + * ZSTD_malloc() + * ZSTD_free() + * ZSTD_calloc() + */ +#ifdef ZSTD_DEPS_NEED_MALLOC +#ifndef ZSTD_DEPS_MALLOC +#define ZSTD_DEPS_MALLOC + +#include + +#define ZSTD_malloc(s) malloc(s) +#define ZSTD_calloc(n,s) calloc((n), (s)) +#define ZSTD_free(p) free((p)) + +#endif /* ZSTD_DEPS_MALLOC */ +#endif /* ZSTD_DEPS_NEED_MALLOC */ + +/* + * Provides 64-bit math support. + * Need: + * U64 ZSTD_div64(U64 dividend, U32 divisor) + */ +#ifdef ZSTD_DEPS_NEED_MATH64 +#ifndef ZSTD_DEPS_MATH64 +#define ZSTD_DEPS_MATH64 + +#define ZSTD_div64(dividend, divisor) ((dividend) / (divisor)) + +#endif /* ZSTD_DEPS_MATH64 */ +#endif /* ZSTD_DEPS_NEED_MATH64 */ + +/* Need: + * assert() + */ +#ifdef ZSTD_DEPS_NEED_ASSERT +#ifndef ZSTD_DEPS_ASSERT +#define ZSTD_DEPS_ASSERT + +#include + +#endif /* ZSTD_DEPS_ASSERT */ +#endif /* ZSTD_DEPS_NEED_ASSERT */ + +/* Need: + * ZSTD_DEBUG_PRINT() + */ +#ifdef ZSTD_DEPS_NEED_IO +#ifndef ZSTD_DEPS_IO +#define ZSTD_DEPS_IO + +#include +#define ZSTD_DEBUG_PRINT(...) fprintf(stderr, __VA_ARGS__) + +#endif /* ZSTD_DEPS_IO */ +#endif /* ZSTD_DEPS_NEED_IO */ + +/* Only requested when is known to be present. + * Need: + * intptr_t + */ +#ifdef ZSTD_DEPS_NEED_STDINT +#ifndef ZSTD_DEPS_STDINT +#define ZSTD_DEPS_STDINT + +#include + +#endif /* ZSTD_DEPS_STDINT */ +#endif /* ZSTD_DEPS_NEED_STDINT */ diff --git a/src/commonlib/bsd/zstd/common/zstd_internal.h b/src/commonlib/bsd/zstd/common/zstd_internal.h new file mode 100644 index 0000000000..eef669f9d8 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_internal.h @@ -0,0 +1,324 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CCOMMON_H_MODULE +#define ZSTD_CCOMMON_H_MODULE + +/* this module contains definitions which must be identical + * across compression, decompression and dictBuilder. + * It also contains a few functions useful to at least 2 of them + * and which benefit from being inlined */ + +/*-************************************* +* Dependencies +***************************************/ +#include "zstd_compiler.h" +#include "cpu.h" +#include "mem.h" +#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */ +#include "error_private.h" +#define ZSTD_STATIC_LINKING_ONLY +#include "../zstd.h" +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#include "huf.h" +#include "zstd_xxhash.h" + +#ifndef ZSTD_NO_TRACE +# include "zstd_trace.h" +#else +# define ZSTD_TRACE 0 +#endif + +/* ---- static assert (debug) --- */ +#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) +#define ZSTD_isError ERR_isError /* for inlining */ +#define FSE_isError ERR_isError +#define HUF_isError ERR_isError + + +/*-************************************* +* shared macros +***************************************/ +#undef MIN +#undef MAX +#define MIN(a,b) ((a)<(b) ? (a) : (b)) +#define MAX(a,b) ((a)>(b) ? (a) : (b)) +#define BOUNDED(min,val,max) (MAX(min,MIN(val,max))) + + +/*-************************************* +* Common constants +***************************************/ +#define ZSTD_OPT_NUM (1<<12) + +#define ZSTD_REP_NUM 3 /* number of repcodes */ +static UNUSED_ATTR const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 }; + +#define KB *(1 <<10) +#define MB *(1 <<20) +#define GB *(1U<<30) + +#define BIT7 128 +#define BIT6 64 +#define BIT5 32 +#define BIT4 16 +#define BIT1 2 +#define BIT0 1 + +#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10 +static UNUSED_ATTR const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 }; +static UNUSED_ATTR const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 }; + +#define ZSTD_FRAMEIDSIZE 4 /* magic number size */ + +#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */ +static UNUSED_ATTR const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE; +typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; + +#define ZSTD_FRAMECHECKSUMSIZE 4 + +#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */ +#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */) /* for a non-null block */ +#define MIN_LITERALS_FOR_4_STREAMS 6 + +typedef enum { set_basic, set_rle, set_compressed, set_repeat } SymbolEncodingType_e; + +#define LONGNBSEQ 0x7F00 + +#define MINMATCH 3 + +#define Litbits 8 +#define LitHufLog 11 +#define MaxLit ((1<= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN); + /* Separate out the first COPY16() call because the copy length is + * almost certain to be short, so the branches have different + * probabilities. Since it is almost certain to be short, only do + * one COPY16() in the first call. Then, do two calls per loop since + * at that point it is more likely to have a high trip count. + */ + ZSTD_copy16(op, ip); + if (16 >= length) return; + op += 16; + ip += 16; + do { + COPY16(op, ip); + COPY16(op, ip); + } + while (op < oend); + } +} + +MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + size_t const length = MIN(dstCapacity, srcSize); + if (length > 0) { + ZSTD_memcpy(dst, src, length); + } + return length; +} + +/* define "workspace is too large" as this number of times larger than needed */ +#define ZSTD_WORKSPACETOOLARGE_FACTOR 3 + +/* when workspace is continuously too large + * during at least this number of times, + * context's memory usage is considered wasteful, + * because it's sized to handle a worst case scenario which rarely happens. + * In which case, resize it down to free some memory */ +#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128 + +/* Controls whether the input/output buffer is buffered or stable. */ +typedef enum { + ZSTD_bm_buffered = 0, /* Buffer the input/output */ + ZSTD_bm_stable = 1 /* ZSTD_inBuffer/ZSTD_outBuffer is stable */ +} ZSTD_bufferMode_e; + + +/*-******************************************* +* Private declarations +*********************************************/ + +/** + * Contains the compressed frame size and an upper-bound for the decompressed frame size. + * Note: before using `compressedSize`, check for errors using ZSTD_isError(). + * similarly, before using `decompressedBound`, check for errors using: + * `decompressedBound != ZSTD_CONTENTSIZE_ERROR` + */ +typedef struct { + size_t nbBlocks; + size_t compressedSize; + unsigned long long decompressedBound; +} ZSTD_frameSizeInfo; /* decompress & legacy */ + +/* ZSTD_invalidateRepCodes() : + * ensures next compression will not use repcodes from previous block. + * Note : only works with regular variant; + * do not use with extDict variant ! */ +void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */ + + +typedef struct { + blockType_e blockType; + U32 lastBlock; + U32 origSize; +} blockProperties_t; /* declared here for decompress and fullbench */ + +/*! ZSTD_getcBlockSize() : + * Provides the size of compressed block from block header `src` */ +/* Used by: decompress, fullbench */ +size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, + blockProperties_t* bpPtr); + +/*! ZSTD_decodeSeqHeaders() : + * decode sequence header from src */ +/* Used by: zstd_decompress_block, fullbench */ +size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, + const void* src, size_t srcSize); + +/** + * @returns true iff the CPU supports dynamic BMI2 dispatch. + */ +MEM_STATIC int ZSTD_cpuSupportsBmi2(void) +{ + ZSTD_cpuid_t cpuid = ZSTD_cpuid(); + return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid); +} + +#endif /* ZSTD_CCOMMON_H_MODULE */ diff --git a/src/commonlib/bsd/zstd/common/zstd_trace.h b/src/commonlib/bsd/zstd/common/zstd_trace.h new file mode 100644 index 0000000000..dc08bd4cb6 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_trace.h @@ -0,0 +1,158 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_TRACE_H +#define ZSTD_TRACE_H + +#include + +/* weak symbol support + * For now, enable conservatively: + * - Only GNUC + * - Only ELF + * - Only x86-64, i386, aarch64 and risc-v. + * Also, explicitly disable on platforms known not to work so they aren't + * forgotten in the future. + */ +#if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && \ + defined(__GNUC__) && defined(__ELF__) && \ + (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ + defined(_M_IX86) || defined(__aarch64__) || defined(__riscv)) && \ + !defined(__APPLE__) && !defined(_WIN32) && !defined(__MINGW32__) && \ + !defined(__CYGWIN__) && !defined(_AIX) +# define ZSTD_HAVE_WEAK_SYMBOLS 1 +#else +# define ZSTD_HAVE_WEAK_SYMBOLS 0 +#endif +#if ZSTD_HAVE_WEAK_SYMBOLS +# define ZSTD_WEAK_ATTR __attribute__((__weak__)) +#else +# define ZSTD_WEAK_ATTR +#endif + +/* Only enable tracing when weak symbols are available. */ +#ifndef ZSTD_TRACE +# define ZSTD_TRACE ZSTD_HAVE_WEAK_SYMBOLS +#endif + +#if ZSTD_TRACE + +struct ZSTD_CCtx_s; +struct ZSTD_DCtx_s; +struct ZSTD_CCtx_params_s; + +typedef struct { + /** + * ZSTD_VERSION_NUMBER + * + * This is guaranteed to be the first member of ZSTD_trace. + * Otherwise, this struct is not stable between versions. If + * the version number does not match your expectation, you + * should not interpret the rest of the struct. + */ + unsigned version; + /** + * Non-zero if streaming (de)compression is used. + */ + int streaming; + /** + * The dictionary ID. + */ + unsigned dictionaryID; + /** + * Is the dictionary cold? + * Only set on decompression. + */ + int dictionaryIsCold; + /** + * The dictionary size or zero if no dictionary. + */ + size_t dictionarySize; + /** + * The uncompressed size of the data. + */ + size_t uncompressedSize; + /** + * The compressed size of the data. + */ + size_t compressedSize; + /** + * The fully resolved CCtx parameters (NULL on decompression). + */ + struct ZSTD_CCtx_params_s const* params; + /** + * The ZSTD_CCtx pointer (NULL on decompression). + */ + struct ZSTD_CCtx_s const* cctx; + /** + * The ZSTD_DCtx pointer (NULL on compression). + */ + struct ZSTD_DCtx_s const* dctx; +} ZSTD_Trace; + +/** + * A tracing context. It must be 0 when tracing is disabled. + * Otherwise, any non-zero value returned by a tracing begin() + * function is presented to any subsequent calls to end(). + * + * Any non-zero value is treated as tracing is enabled and not + * interpreted by the library. + * + * Two possible uses are: + * * A timestamp for when the begin() function was called. + * * A unique key identifying the (de)compression, like the + * address of the [dc]ctx pointer if you need to track + * more information than just a timestamp. + */ +typedef unsigned long long ZSTD_TraceCtx; + +/** + * Trace the beginning of a compression call. + * @param cctx The dctx pointer for the compression. + * It can be used as a key to map begin() to end(). + * @returns Non-zero if tracing is enabled. The return value is + * passed to ZSTD_trace_compress_end(). + */ +ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_compress_begin( + struct ZSTD_CCtx_s const* cctx); + +/** + * Trace the end of a compression call. + * @param ctx The return value of ZSTD_trace_compress_begin(). + * @param trace The zstd tracing info. + */ +ZSTD_WEAK_ATTR void ZSTD_trace_compress_end( + ZSTD_TraceCtx ctx, + ZSTD_Trace const* trace); + +/** + * Trace the beginning of a decompression call. + * @param dctx The dctx pointer for the decompression. + * It can be used as a key to map begin() to end(). + * @returns Non-zero if tracing is enabled. The return value is + * passed to ZSTD_trace_compress_end(). + */ +ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_decompress_begin( + struct ZSTD_DCtx_s const* dctx); + +/** + * Trace the end of a decompression call. + * @param ctx The return value of ZSTD_trace_decompress_begin(). + * @param trace The zstd tracing info. + */ +ZSTD_WEAK_ATTR void ZSTD_trace_decompress_end( + ZSTD_TraceCtx ctx, + ZSTD_Trace const* trace); + +#endif /* ZSTD_TRACE */ + +#endif /* ZSTD_TRACE_H */ diff --git a/src/commonlib/bsd/zstd/common/zstd_xxhash.h b/src/commonlib/bsd/zstd/common/zstd_xxhash.h new file mode 100644 index 0000000000..4e3f2480d9 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_xxhash.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#ifndef ZSTD_XXHASH_COMMON +#define ZSTD_XXHASH_COMMON + +#include + +typedef struct xxh64_state XXH64_state_t; +#define XXH64_update xxh64_update +#define XXH64_reset xxh64_reset +#define XXH64_digest xxh64_digest +#define XXH64 xxh64 + +typedef struct xxh32_state XXH32_state_t; +#define XXH32_update xxh32_update +#define XXH32_reset xxh32_reset +#define XXH32_digest xxh32_digest +#define XXH32 xxh32 + +#endif /* ZSTD_XXHASH_COMMON */ diff --git a/src/commonlib/bsd/zstd/compress/clevels.h b/src/commonlib/bsd/zstd/compress/clevels.h new file mode 100644 index 0000000000..8ebf1be282 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/clevels.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CLEVELS_H +#define ZSTD_CLEVELS_H + +#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */ +#include "../zstd.h" + +/*-===== Pre-defined compression levels =====-*/ + +#define ZSTD_MAX_CLEVEL 22 + +#ifdef __GNUC__ +__attribute__((__unused__)) +#endif + +static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = { +{ /* "default" - for any srcSize > 256 KB */ + /* W, C, H, S, L, TL, strat */ + { 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */ + { 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */ + { 20, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */ + { 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */ + { 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */ + { 21, 18, 19, 3, 5, 2, ZSTD_greedy }, /* level 5 */ + { 21, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6 */ + { 21, 19, 20, 4, 5, 8, ZSTD_lazy }, /* level 7 */ + { 21, 19, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 8 */ + { 22, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ + { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 10 */ + { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 11 */ + { 22, 22, 23, 6, 5, 32, ZSTD_lazy2 }, /* level 12 */ + { 22, 22, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */ + { 22, 22, 23, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */ + { 22, 23, 23, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */ + { 22, 22, 22, 5, 5, 48, ZSTD_btopt }, /* level 16 */ + { 23, 23, 22, 5, 4, 64, ZSTD_btopt }, /* level 17 */ + { 23, 23, 22, 6, 3, 64, ZSTD_btultra }, /* level 18 */ + { 23, 24, 22, 7, 3,256, ZSTD_btultra2}, /* level 19 */ + { 25, 25, 23, 7, 3,256, ZSTD_btultra2}, /* level 20 */ + { 26, 26, 24, 7, 3,512, ZSTD_btultra2}, /* level 21 */ + { 27, 27, 25, 9, 3,999, ZSTD_btultra2}, /* level 22 */ +}, +{ /* for srcSize <= 256 KB */ + /* W, C, H, S, L, T, strat */ + { 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */ + { 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */ + { 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */ + { 18, 16, 17, 3, 5, 2, ZSTD_greedy }, /* level 4.*/ + { 18, 17, 18, 5, 5, 2, ZSTD_greedy }, /* level 5.*/ + { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/ + { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */ + { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ + { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 18, 18, 19, 5, 4, 12, ZSTD_btlazy2 }, /* level 11.*/ + { 18, 19, 19, 7, 4, 12, ZSTD_btlazy2 }, /* level 12.*/ + { 18, 18, 19, 4, 4, 16, ZSTD_btopt }, /* level 13 */ + { 18, 18, 19, 4, 3, 32, ZSTD_btopt }, /* level 14.*/ + { 18, 18, 19, 6, 3,128, ZSTD_btopt }, /* level 15.*/ + { 18, 19, 19, 6, 3,128, ZSTD_btultra }, /* level 16.*/ + { 18, 19, 19, 8, 3,256, ZSTD_btultra }, /* level 17.*/ + { 18, 19, 19, 6, 3,128, ZSTD_btultra2}, /* level 18.*/ + { 18, 19, 19, 8, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 18, 19, 19, 10, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 18, 19, 19, 12, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 18, 19, 19, 13, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +{ /* for srcSize <= 128 KB */ + /* W, C, H, S, L, T, strat */ + { 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */ + { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */ + { 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */ + { 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */ + { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */ + { 17, 16, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */ + { 17, 16, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */ + { 17, 16, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ + { 17, 16, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 17, 16, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 17, 17, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 11 */ + { 17, 18, 17, 7, 4, 12, ZSTD_btlazy2 }, /* level 12 */ + { 17, 18, 17, 3, 4, 12, ZSTD_btopt }, /* level 13.*/ + { 17, 18, 17, 4, 3, 32, ZSTD_btopt }, /* level 14.*/ + { 17, 18, 17, 6, 3,256, ZSTD_btopt }, /* level 15.*/ + { 17, 18, 17, 6, 3,128, ZSTD_btultra }, /* level 16.*/ + { 17, 18, 17, 8, 3,256, ZSTD_btultra }, /* level 17.*/ + { 17, 18, 17, 10, 3,512, ZSTD_btultra }, /* level 18.*/ + { 17, 18, 17, 5, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 17, 18, 17, 7, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 17, 18, 17, 9, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 17, 18, 17, 11, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +{ /* for srcSize <= 16 KB */ + /* W, C, H, S, L, T, strat */ + { 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */ + { 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */ + { 14, 14, 15, 2, 4, 0, ZSTD_dfast }, /* level 3 */ + { 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4 */ + { 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/ + { 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */ + { 14, 14, 14, 6, 4, 8, ZSTD_lazy2 }, /* level 7 */ + { 14, 14, 14, 8, 4, 8, ZSTD_lazy2 }, /* level 8.*/ + { 14, 15, 14, 5, 4, 8, ZSTD_btlazy2 }, /* level 9.*/ + { 14, 15, 14, 9, 4, 8, ZSTD_btlazy2 }, /* level 10.*/ + { 14, 15, 14, 3, 4, 12, ZSTD_btopt }, /* level 11.*/ + { 14, 15, 14, 4, 3, 24, ZSTD_btopt }, /* level 12.*/ + { 14, 15, 14, 5, 3, 32, ZSTD_btultra }, /* level 13.*/ + { 14, 15, 15, 6, 3, 64, ZSTD_btultra }, /* level 14.*/ + { 14, 15, 15, 7, 3,256, ZSTD_btultra }, /* level 15.*/ + { 14, 15, 15, 5, 3, 48, ZSTD_btultra2}, /* level 16.*/ + { 14, 15, 15, 6, 3,128, ZSTD_btultra2}, /* level 17.*/ + { 14, 15, 15, 7, 3,256, ZSTD_btultra2}, /* level 18.*/ + { 14, 15, 15, 8, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 14, 15, 15, 8, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 14, 15, 15, 9, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 14, 15, 15, 10, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +}; + + + +#endif /* ZSTD_CLEVELS_H */ diff --git a/src/commonlib/bsd/zstd/compress/fse_compress.c b/src/commonlib/bsd/zstd/compress/fse_compress.c new file mode 100644 index 0000000000..7ef32108ef --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/fse_compress.c @@ -0,0 +1,627 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * FSE : Finite State Entropy encoder + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************************************** +* Includes +****************************************************************/ +#include "../common/zstd_compiler.h" +#include "../common/mem.h" /* U32, U16, etc. */ +#include "../common/debug.h" /* assert, DEBUGLOG */ +#include "hist.h" /* HIST_count_wksp */ +#include "../common/bitstream.h" +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/error_private.h" +#define ZSTD_DEPS_NEED_MALLOC +#define ZSTD_DEPS_NEED_MATH64 +#include "../common/zstd_deps.h" /* ZSTD_memset */ +#include "../common/zstd_bits.h" /* ZSTD_highbit32 */ + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_isError ERR_isError + + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + + +/* Function templates */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * wkspSize should be sized to handle worst case situation, which is `1<>1 : 1) ; + FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); + U32 const step = FSE_TABLESTEP(tableSize); + U32 const maxSV1 = maxSymbolValue+1; + + U16* cumul = (U16*)workSpace; /* size = maxSV1 */ + FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSV1+1)); /* size = tableSize */ + + U32 highThreshold = tableSize-1; + + assert(((size_t)workSpace & 1) == 0); /* Must be 2 bytes-aligned */ + if (FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) > wkspSize) return ERROR(tableLog_tooLarge); + /* CTable header */ + tableU16[-2] = (U16) tableLog; + tableU16[-1] = (U16) maxSymbolValue; + assert(tableLog < 16); /* required for threshold strategy to work */ + + /* For explanations on how to distribute symbol values over the table : + * https://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */ + + #ifdef __clang_analyzer__ + ZSTD_memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */ + #endif + + /* symbol start positions */ + { U32 u; + cumul[0] = 0; + for (u=1; u <= maxSV1; u++) { + if (normalizedCounter[u-1]==-1) { /* Low proba symbol */ + cumul[u] = cumul[u-1] + 1; + tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1); + } else { + assert(normalizedCounter[u-1] >= 0); + cumul[u] = cumul[u-1] + (U16)normalizedCounter[u-1]; + assert(cumul[u] >= cumul[u-1]); /* no overflow */ + } } + cumul[maxSV1] = (U16)(tableSize+1); + } + + /* Spread symbols */ + if (highThreshold == tableSize - 1) { + /* Case for no low prob count symbols. Lay down 8 bytes at a time + * to reduce branch misses since we are operating on a small block + */ + BYTE* const spread = tableSymbol + tableSize; /* size = tableSize + 8 (may write beyond tableSize) */ + { U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s=0); + pos += (size_t)n; + } + } + /* Spread symbols across the table. Lack of lowprob symbols means that + * we don't need variable sized inner loop, so we can unroll the loop and + * reduce branch misses. + */ + { size_t position = 0; + size_t s; + size_t const unroll = 2; /* Experimentally determined optimal unroll */ + assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */ + for (s = 0; s < (size_t)tableSize; s += unroll) { + size_t u; + for (u = 0; u < unroll; ++u) { + size_t const uPosition = (position + (u * step)) & tableMask; + tableSymbol[uPosition] = spread[s + u]; + } + position = (position + (unroll * step)) & tableMask; + } + assert(position == 0); /* Must have initialized all positions */ + } + } else { + U32 position = 0; + U32 symbol; + for (symbol=0; symbol highThreshold) + position = (position + step) & tableMask; /* Low proba area */ + } } + assert(position==0); /* Must have initialized all positions */ + } + + /* Build table */ + { U32 u; for (u=0; u 1); + { U32 const maxBitsOut = tableLog - ZSTD_highbit32 ((U32)normalizedCounter[s]-1); + U32 const minStatePlus = (U32)normalizedCounter[s] << maxBitsOut; + symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus; + symbolTT[s].deltaFindState = (int)(total - (unsigned)normalizedCounter[s]); + total += (unsigned)normalizedCounter[s]; + } } } } + +#if 0 /* debug : symbol costs */ + DEBUGLOG(5, "\n --- table statistics : "); + { U32 symbol; + for (symbol=0; symbol<=maxSymbolValue; symbol++) { + DEBUGLOG(5, "%3u: w=%3i, maxBits=%u, fracBits=%.2f", + symbol, normalizedCounter[symbol], + FSE_getMaxNbBits(symbolTT, symbol), + (double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256); + } } +#endif + + return 0; +} + + + +#ifndef FSE_COMMONDEFS_ONLY + +/*-************************************************************** +* FSE NCount encoding +****************************************************************/ +size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog) +{ + size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog + + 4 /* bitCount initialized at 4 */ + + 2 /* first two symbols may use one additional bit each */) / 8) + + 1 /* round up to whole nb bytes */ + + 2 /* additional two bytes for bitstream flush */; + return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ +} + +static size_t +FSE_writeNCount_generic (void* header, size_t headerBufferSize, + const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, + unsigned writeIsSafe) +{ + BYTE* const ostart = (BYTE*) header; + BYTE* out = ostart; + BYTE* const oend = ostart + headerBufferSize; + int nbBits; + const int tableSize = 1 << tableLog; + int remaining; + int threshold; + U32 bitStream = 0; + int bitCount = 0; + unsigned symbol = 0; + unsigned const alphabetSize = maxSymbolValue + 1; + int previousIs0 = 0; + + /* Table Size */ + bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount; + bitCount += 4; + + /* Init */ + remaining = tableSize+1; /* +1 for extra accuracy */ + threshold = tableSize; + nbBits = (int)tableLog+1; + + while ((symbol < alphabetSize) && (remaining>1)) { /* stops at 1 */ + if (previousIs0) { + unsigned start = symbol; + while ((symbol < alphabetSize) && !normalizedCounter[symbol]) symbol++; + if (symbol == alphabetSize) break; /* incorrect distribution */ + while (symbol >= start+24) { + start+=24; + bitStream += 0xFFFFU << bitCount; + if ((!writeIsSafe) && (out > oend-2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE) bitStream; + out[1] = (BYTE)(bitStream>>8); + out+=2; + bitStream>>=16; + } + while (symbol >= start+3) { + start+=3; + bitStream += 3U << bitCount; + bitCount += 2; + } + bitStream += (symbol-start) << bitCount; + bitCount += 2; + if (bitCount>16) { + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out += 2; + bitStream >>= 16; + bitCount -= 16; + } } + { int count = normalizedCounter[symbol++]; + int const max = (2*threshold-1) - remaining; + remaining -= count < 0 ? -count : count; + count++; /* +1 for extra accuracy */ + if (count>=threshold) + count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */ + bitStream += (U32)count << bitCount; + bitCount += nbBits; + bitCount -= (count>=1; } + } + if (bitCount>16) { + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out += 2; + bitStream >>= 16; + bitCount -= 16; + } } + + if (remaining != 1) + return ERROR(GENERIC); /* incorrect normalized distribution */ + assert(symbol <= alphabetSize); + + /* flush remaining bitStream */ + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out+= (bitCount+7) /8; + + assert(out >= ostart); + return (size_t)(out-ostart); +} + + +size_t FSE_writeNCount (void* buffer, size_t bufferSize, + const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +{ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */ + if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */ + + if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog)) + return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0); + + return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1 /* write in buffer is safe */); +} + + +/*-************************************************************** +* FSE Compression Code +****************************************************************/ + +/* provides the minimum logSize to safely represent a distribution */ +static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue) +{ + U32 minBitsSrc = ZSTD_highbit32((U32)(srcSize)) + 1; + U32 minBitsSymbols = ZSTD_highbit32(maxSymbolValue) + 2; + U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols; + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + return minBits; +} + +unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus) +{ + U32 maxBitsSrc = ZSTD_highbit32((U32)(srcSize - 1)) - minus; + U32 tableLog = maxTableLog; + U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue); + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; + if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */ + if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */ + if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG; + if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG; + return tableLog; +} + +unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue) +{ + return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2); +} + +/* Secondary normalization method. + To be used when primary method fails. */ + +static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue, short lowProbCount) +{ + short const NOT_YET_ASSIGNED = -2; + U32 s; + U32 distributed = 0; + U32 ToDistribute; + + /* Init */ + U32 const lowThreshold = (U32)(total >> tableLog); + U32 lowOne = (U32)((total * 3) >> (tableLog + 1)); + + for (s=0; s<=maxSymbolValue; s++) { + if (count[s] == 0) { + norm[s]=0; + continue; + } + if (count[s] <= lowThreshold) { + norm[s] = lowProbCount; + distributed++; + total -= count[s]; + continue; + } + if (count[s] <= lowOne) { + norm[s] = 1; + distributed++; + total -= count[s]; + continue; + } + + norm[s]=NOT_YET_ASSIGNED; + } + ToDistribute = (1 << tableLog) - distributed; + + if (ToDistribute == 0) + return 0; + + if ((total / ToDistribute) > lowOne) { + /* risk of rounding to zero */ + lowOne = (U32)((total * 3) / (ToDistribute * 2)); + for (s=0; s<=maxSymbolValue; s++) { + if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) { + norm[s] = 1; + distributed++; + total -= count[s]; + continue; + } } + ToDistribute = (1 << tableLog) - distributed; + } + + if (distributed == maxSymbolValue+1) { + /* all values are pretty poor; + probably incompressible data (should have already been detected); + find max, then give all remaining points to max */ + U32 maxV = 0, maxC = 0; + for (s=0; s<=maxSymbolValue; s++) + if (count[s] > maxC) { maxV=s; maxC=count[s]; } + norm[maxV] += (short)ToDistribute; + return 0; + } + + if (total == 0) { + /* all of the symbols were low enough for the lowOne or lowThreshold */ + for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1)) + if (norm[s] > 0) { ToDistribute--; norm[s]++; } + return 0; + } + + { U64 const vStepLog = 62 - tableLog; + U64 const mid = (1ULL << (vStepLog-1)) - 1; + U64 const rStep = ZSTD_div64((((U64)1<> vStepLog); + U32 const sEnd = (U32)(end >> vStepLog); + U32 const weight = sEnd - sStart; + if (weight < 1) + return ERROR(GENERIC); + norm[s] = (short)weight; + tmpTotal = end; + } } } + + return 0; +} + +size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, + const unsigned* count, size_t total, + unsigned maxSymbolValue, unsigned useLowProbCount) +{ + /* Sanity checks */ + if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; + if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported size */ + if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */ + + { static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 }; + short const lowProbCount = useLowProbCount ? -1 : 1; + U64 const scale = 62 - tableLog; + U64 const step = ZSTD_div64((U64)1<<62, (U32)total); /* <== here, one division ! */ + U64 const vStep = 1ULL<<(scale-20); + int stillToDistribute = 1<> tableLog); + + for (s=0; s<=maxSymbolValue; s++) { + if (count[s] == total) return 0; /* rle special case */ + if (count[s] == 0) { normalizedCounter[s]=0; continue; } + if (count[s] <= lowThreshold) { + normalizedCounter[s] = lowProbCount; + stillToDistribute--; + } else { + short proba = (short)((count[s]*step) >> scale); + if (proba<8) { + U64 restToBeat = vStep * rtbTable[proba]; + proba += (count[s]*step) - ((U64)proba< restToBeat; + } + if (proba > largestP) { largestP=proba; largest=s; } + normalizedCounter[s] = proba; + stillToDistribute -= proba; + } } + if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) { + /* corner case, need another normalization method */ + size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue, lowProbCount); + if (FSE_isError(errorCode)) return errorCode; + } + else normalizedCounter[largest] += (short)stillToDistribute; + } + +#if 0 + { /* Print Table (debug) */ + U32 s; + U32 nTotal = 0; + for (s=0; s<=maxSymbolValue; s++) + RAWLOG(2, "%3i: %4i \n", s, normalizedCounter[s]); + for (s=0; s<=maxSymbolValue; s++) + nTotal += abs(normalizedCounter[s]); + if (nTotal != (1U< FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) { /* test bit 2 */ + FSE_encodeSymbol(&bitC, &CState2, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + FSE_FLUSHBITS(&bitC); + } + + /* 2 or 4 encoding per loop */ + while ( ip>istart ) { + + FSE_encodeSymbol(&bitC, &CState2, *--ip); + + if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */ + FSE_FLUSHBITS(&bitC); + + FSE_encodeSymbol(&bitC, &CState1, *--ip); + + if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) { /* this test must be static */ + FSE_encodeSymbol(&bitC, &CState2, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + } + + FSE_FLUSHBITS(&bitC); + } + + FSE_flushCState(&bitC, &CState2); + FSE_flushCState(&bitC, &CState1); + return BIT_closeCStream(&bitC); +} + +size_t FSE_compress_usingCTable (void* dst, size_t dstSize, + const void* src, size_t srcSize, + const FSE_CTable* ct) +{ + unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize)); + + if (fast) + return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1); + else + return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0); +} + + +size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } + +#endif /* FSE_COMMONDEFS_ONLY */ diff --git a/src/commonlib/bsd/zstd/compress/hist.c b/src/commonlib/bsd/zstd/compress/hist.c new file mode 100644 index 0000000000..f5c6ecbc5c --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/hist.c @@ -0,0 +1,193 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * hist : Histogram functions + * part of Finite State Entropy project + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* --- dependencies --- */ +#include "../common/mem.h" /* U32, BYTE, etc. */ +#include "../common/debug.h" /* assert, DEBUGLOG */ +#include "../common/error_private.h" /* ERROR */ +#include "hist.h" + + +/* --- Error management --- */ +unsigned HIST_isError(size_t code) { return ERR_isError(code); } + +/*-************************************************************** + * Histogram functions + ****************************************************************/ +void HIST_add(unsigned* count, const void* src, size_t srcSize) +{ + const BYTE* ip = (const BYTE*)src; + const BYTE* const end = ip + srcSize; + + while (ip largestCount) largestCount = count[s]; + } + + return largestCount; +} + +typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e; + +/* HIST_count_parallel_wksp() : + * store histogram into 4 intermediate tables, recombined at the end. + * this design makes better use of OoO cpus, + * and is noticeably faster when some values are heavily repeated. + * But it needs some additional workspace for intermediate tables. + * `workSpace` must be a U32 table of size >= HIST_WKSP_SIZE_U32. + * @return : largest histogram frequency, + * or an error code (notably when histogram's alphabet is larger than *maxSymbolValuePtr) */ +static size_t HIST_count_parallel_wksp( + unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + HIST_checkInput_e check, + U32* const workSpace) +{ + const BYTE* ip = (const BYTE*)source; + const BYTE* const iend = ip+sourceSize; + size_t const countSize = (*maxSymbolValuePtr + 1) * sizeof(*count); + unsigned max=0; + U32* const Counting1 = workSpace; + U32* const Counting2 = Counting1 + 256; + U32* const Counting3 = Counting2 + 256; + U32* const Counting4 = Counting3 + 256; + + /* safety checks */ + assert(*maxSymbolValuePtr <= 255); + if (!sourceSize) { + ZSTD_memset(count, 0, countSize); + *maxSymbolValuePtr = 0; + return 0; + } + ZSTD_memset(workSpace, 0, 4*256*sizeof(unsigned)); + + /* by stripes of 16 bytes */ + { U32 cached = MEM_read32(ip); ip += 4; + while (ip < iend-15) { + U32 c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + } + ip-=4; + } + + /* finish last symbols */ + while (ip max) max = Counting1[s]; + } } + + { unsigned maxSymbolValue = 255; + while (!Counting1[maxSymbolValue]) maxSymbolValue--; + if (check && maxSymbolValue > *maxSymbolValuePtr) return ERROR(maxSymbolValue_tooSmall); + *maxSymbolValuePtr = maxSymbolValue; + ZSTD_memmove(count, Counting1, countSize); /* in case count & Counting1 are overlapping */ + } + return (size_t)max; +} + +/* HIST_countFast_wksp() : + * Same as HIST_countFast(), but using an externally provided scratch buffer. + * `workSpace` is a writable buffer which must be 4-bytes aligned, + * `workSpaceSize` must be >= HIST_WKSP_SIZE + */ +size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + void* workSpace, size_t workSpaceSize) +{ + if (sourceSize < 1500) /* heuristic threshold */ + return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize); + if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ + if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall); + return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace); +} + +/* HIST_count_wksp() : + * Same as HIST_count(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */ +size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + void* workSpace, size_t workSpaceSize) +{ + if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ + if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall); + if (*maxSymbolValuePtr < 255) + return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, (U32*)workSpace); + *maxSymbolValuePtr = 255; + return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize); +} + +#ifndef ZSTD_NO_UNUSED_FUNCTIONS +/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */ +size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize) +{ + unsigned tmpCounters[HIST_WKSP_SIZE_U32]; + return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters)); +} + +size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize) +{ + unsigned tmpCounters[HIST_WKSP_SIZE_U32]; + return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters)); +} +#endif diff --git a/src/commonlib/bsd/zstd/compress/hist.h b/src/commonlib/bsd/zstd/compress/hist.h new file mode 100644 index 0000000000..acb2aec6d5 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/hist.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * hist : Histogram functions + * part of Finite State Entropy project + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* --- dependencies --- */ +#include "../common/zstd_deps.h" /* size_t */ + + +/* --- simple histogram functions --- */ + +/*! HIST_count(): + * Provides the precise count of each byte within a table 'count'. + * 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1). + * Updates *maxSymbolValuePtr with actual largest symbol value detected. + * @return : count of the most frequent symbol (which isn't identified). + * or an error code, which can be tested using HIST_isError(). + * note : if return == srcSize, there is only one symbol. + */ +size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +unsigned HIST_isError(size_t code); /**< tells if a return value is an error code */ + + +/* --- advanced histogram functions --- */ + +#define HIST_WKSP_SIZE_U32 1024 +#define HIST_WKSP_SIZE (HIST_WKSP_SIZE_U32 * sizeof(unsigned)) +/** HIST_count_wksp() : + * Same as HIST_count(), but using an externally provided scratch buffer. + * Benefit is this function will use very little stack space. + * `workSpace` is a writable buffer which must be 4-bytes aligned, + * `workSpaceSize` must be >= HIST_WKSP_SIZE + */ +size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize, + void* workSpace, size_t workSpaceSize); + +/** HIST_countFast() : + * same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr. + * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` + */ +size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +/** HIST_countFast_wksp() : + * Same as HIST_countFast(), but using an externally provided scratch buffer. + * `workSpace` is a writable buffer which must be 4-bytes aligned, + * `workSpaceSize` must be >= HIST_WKSP_SIZE + */ +size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize, + void* workSpace, size_t workSpaceSize); + +/*! HIST_count_simple() : + * Same as HIST_countFast(), this function is unsafe, + * and will segfault if any value within `src` is `> *maxSymbolValuePtr`. + * It is also a bit slower for large inputs. + * However, it does not need any additional memory (not even on stack). + * @return : count of the most frequent symbol. + * Note this function doesn't produce any error (i.e. it must succeed). + */ +unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +/*! HIST_add() : + * Lowest level: just add nb of occurrences of characters from @src into @count. + * @count is not reset. @count array is presumed large enough (i.e. 1 KB). + @ This function does not need any additional stack memory. + */ +void HIST_add(unsigned* count, const void* src, size_t srcSize); diff --git a/src/commonlib/bsd/zstd/compress/huf_compress.c b/src/commonlib/bsd/zstd/compress/huf_compress.c new file mode 100644 index 0000000000..add0c589fd --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/huf_compress.c @@ -0,0 +1,1466 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * Huffman encoder, part of New Generation Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************************************** +* Compiler specifics +****************************************************************/ +#ifdef _MSC_VER /* Visual Studio */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +#endif + + +/* ************************************************************** +* Includes +****************************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */ +#include "../common/zstd_compiler.h" +#include "../common/bitstream.h" +#include "hist.h" +#define FSE_STATIC_LINKING_ONLY /* FSE_optimalTableLog_internal */ +#include "../common/fse.h" /* header compression */ +#include "../common/huf.h" +#include "../common/error_private.h" +#include "../common/zstd_bits.h" /* ZSTD_highbit32 */ + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define HUF_isError ERR_isError +#define HUF_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ + + +/* ************************************************************** +* Required declarations +****************************************************************/ +typedef struct nodeElt_s { + U32 count; + U16 parent; + BYTE byte; + BYTE nbBits; +} nodeElt; + + +/* ************************************************************** +* Debug Traces +****************************************************************/ + +#if DEBUGLEVEL >= 2 + +static size_t showU32(const U32* arr, size_t size) +{ + size_t u; + for (u=0; u= add) { + assert(add < align); + assert(((size_t)aligned & mask) == 0); + *workspaceSizePtr -= add; + return aligned; + } else { + *workspaceSizePtr = 0; + return NULL; + } +} + + +/* HUF_compressWeights() : + * Same as FSE_compress(), but dedicated to huff0's weights compression. + * The use case needs much less stack memory. + * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX. + */ +#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6 + +typedef struct { + FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)]; + U32 scratchBuffer[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER)]; + unsigned count[HUF_TABLELOG_MAX+1]; + S16 norm[HUF_TABLELOG_MAX+1]; +} HUF_CompressWeightsWksp; + +static size_t +HUF_compressWeights(void* dst, size_t dstSize, + const void* weightTable, size_t wtSize, + void* workspace, size_t workspaceSize) +{ + BYTE* const ostart = (BYTE*) dst; + BYTE* op = ostart; + BYTE* const oend = ostart + dstSize; + + unsigned maxSymbolValue = HUF_TABLELOG_MAX; + U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER; + HUF_CompressWeightsWksp* wksp = (HUF_CompressWeightsWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32)); + + if (workspaceSize < sizeof(HUF_CompressWeightsWksp)) return ERROR(GENERIC); + + /* init conditions */ + if (wtSize <= 1) return 0; /* Not compressible */ + + /* Scan input and build symbol stats */ + { unsigned const maxCount = HIST_count_simple(wksp->count, &maxSymbolValue, weightTable, wtSize); /* never fails */ + if (maxCount == wtSize) return 1; /* only a single symbol in src : rle */ + if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */ + } + + tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue); + CHECK_F( FSE_normalizeCount(wksp->norm, tableLog, wksp->count, wtSize, maxSymbolValue, /* useLowProbCount */ 0) ); + + /* Write table description header */ + { CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), wksp->norm, maxSymbolValue, tableLog) ); + op += hSize; + } + + /* Compress */ + CHECK_F( FSE_buildCTable_wksp(wksp->CTable, wksp->norm, maxSymbolValue, tableLog, wksp->scratchBuffer, sizeof(wksp->scratchBuffer)) ); + { CHECK_V_F(cSize, FSE_compress_usingCTable(op, (size_t)(oend - op), weightTable, wtSize, wksp->CTable) ); + if (cSize == 0) return 0; /* not enough space for compressed data */ + op += cSize; + } + + return (size_t)(op-ostart); +} + +static size_t HUF_getNbBits(HUF_CElt elt) +{ + return elt & 0xFF; +} + +static size_t HUF_getNbBitsFast(HUF_CElt elt) +{ + return elt; +} + +static size_t HUF_getValue(HUF_CElt elt) +{ + return elt & ~(size_t)0xFF; +} + +static size_t HUF_getValueFast(HUF_CElt elt) +{ + return elt; +} + +static void HUF_setNbBits(HUF_CElt* elt, size_t nbBits) +{ + assert(nbBits <= HUF_TABLELOG_ABSOLUTEMAX); + *elt = nbBits; +} + +static void HUF_setValue(HUF_CElt* elt, size_t value) +{ + size_t const nbBits = HUF_getNbBits(*elt); + if (nbBits > 0) { + assert((value >> nbBits) == 0); + *elt |= value << (sizeof(HUF_CElt) * 8 - nbBits); + } +} + +HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable) +{ + HUF_CTableHeader header; + ZSTD_memcpy(&header, ctable, sizeof(header)); + return header; +} + +static void HUF_writeCTableHeader(HUF_CElt* ctable, U32 tableLog, U32 maxSymbolValue) +{ + HUF_CTableHeader header; + HUF_STATIC_ASSERT(sizeof(ctable[0]) == sizeof(header)); + ZSTD_memset(&header, 0, sizeof(header)); + assert(tableLog < 256); + header.tableLog = (BYTE)tableLog; + assert(maxSymbolValue < 256); + header.maxSymbolValue = (BYTE)maxSymbolValue; + ZSTD_memcpy(ctable, &header, sizeof(header)); +} + +typedef struct { + HUF_CompressWeightsWksp wksp; + BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */ + BYTE huffWeight[HUF_SYMBOLVALUE_MAX]; +} HUF_WriteCTableWksp; + +size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, + const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, + void* workspace, size_t workspaceSize) +{ + HUF_CElt const* const ct = CTable + 1; + BYTE* op = (BYTE*)dst; + U32 n; + HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32)); + + HUF_STATIC_ASSERT(HUF_CTABLE_WORKSPACE_SIZE >= sizeof(HUF_WriteCTableWksp)); + + assert(HUF_readCTableHeader(CTable).maxSymbolValue == maxSymbolValue); + assert(HUF_readCTableHeader(CTable).tableLog == huffLog); + + /* check conditions */ + if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC); + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge); + + /* convert to weight */ + wksp->bitsToWeight[0] = 0; + for (n=1; nbitsToWeight[n] = (BYTE)(huffLog + 1 - n); + for (n=0; nhuffWeight[n] = wksp->bitsToWeight[HUF_getNbBits(ct[n])]; + + /* attempt weights compression by FSE */ + if (maxDstSize < 1) return ERROR(dstSize_tooSmall); + { CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, wksp->huffWeight, maxSymbolValue, &wksp->wksp, sizeof(wksp->wksp)) ); + if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */ + op[0] = (BYTE)hSize; + return hSize+1; + } } + + /* write raw values as 4-bits (max : 15) */ + if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */ + if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */ + op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1)); + wksp->huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */ + for (n=0; nhuffWeight[n] << 4) + wksp->huffWeight[n+1]); + return ((maxSymbolValue+1)/2) + 1; +} + + +size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* hasZeroWeights) +{ + BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some static analyzer may complain */ + U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */ + U32 tableLog = 0; + U32 nbSymbols = 0; + HUF_CElt* const ct = CTable + 1; + + /* get symbol weights */ + CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize)); + *hasZeroWeights = (rankVal[0] > 0); + + /* check result */ + if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); + if (nbSymbols > *maxSymbolValuePtr+1) return ERROR(maxSymbolValue_tooSmall); + + *maxSymbolValuePtr = nbSymbols - 1; + + HUF_writeCTableHeader(CTable, tableLog, *maxSymbolValuePtr); + + /* Prepare base value per rank */ + { U32 n, nextRankStart = 0; + for (n=1; n<=tableLog; n++) { + U32 curr = nextRankStart; + nextRankStart += (rankVal[n] << (n-1)); + rankVal[n] = curr; + } } + + /* fill nbBits */ + { U32 n; for (n=0; nn=tableLog+1 */ + U16 valPerRank[HUF_TABLELOG_MAX+2] = {0}; + { U32 n; for (n=0; n0; n--) { /* start at n=tablelog <-> w=1 */ + valPerRank[n] = min; /* get starting value within each rank */ + min += nbPerRank[n]; + min >>= 1; + } } + /* assign value within rank, symbol order */ + { U32 n; for (n=0; n HUF_readCTableHeader(CTable).maxSymbolValue) + return 0; + return (U32)HUF_getNbBits(ct[symbolValue]); +} + + +/** + * HUF_setMaxHeight(): + * Try to enforce @targetNbBits on the Huffman tree described in @huffNode. + * + * It attempts to convert all nodes with nbBits > @targetNbBits + * to employ @targetNbBits instead. Then it adjusts the tree + * so that it remains a valid canonical Huffman tree. + * + * @pre The sum of the ranks of each symbol == 2^largestBits, + * where largestBits == huffNode[lastNonNull].nbBits. + * @post The sum of the ranks of each symbol == 2^largestBits, + * where largestBits is the return value (expected <= targetNbBits). + * + * @param huffNode The Huffman tree modified in place to enforce targetNbBits. + * It's presumed sorted, from most frequent to rarest symbol. + * @param lastNonNull The symbol with the lowest count in the Huffman tree. + * @param targetNbBits The allowed number of bits, which the Huffman tree + * may not respect. After this function the Huffman tree will + * respect targetNbBits. + * @return The maximum number of bits of the Huffman tree after adjustment. + */ +static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 targetNbBits) +{ + const U32 largestBits = huffNode[lastNonNull].nbBits; + /* early exit : no elt > targetNbBits, so the tree is already valid. */ + if (largestBits <= targetNbBits) return largestBits; + + DEBUGLOG(5, "HUF_setMaxHeight (targetNbBits = %u)", targetNbBits); + + /* there are several too large elements (at least >= 2) */ + { int totalCost = 0; + const U32 baseCost = 1 << (largestBits - targetNbBits); + int n = (int)lastNonNull; + + /* Adjust any ranks > targetNbBits to targetNbBits. + * Compute totalCost, which is how far the sum of the ranks is + * we are over 2^largestBits after adjust the offending ranks. + */ + while (huffNode[n].nbBits > targetNbBits) { + totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits)); + huffNode[n].nbBits = (BYTE)targetNbBits; + n--; + } + /* n stops at huffNode[n].nbBits <= targetNbBits */ + assert(huffNode[n].nbBits <= targetNbBits); + /* n end at index of smallest symbol using < targetNbBits */ + while (huffNode[n].nbBits == targetNbBits) --n; + + /* renorm totalCost from 2^largestBits to 2^targetNbBits + * note : totalCost is necessarily a multiple of baseCost */ + assert(((U32)totalCost & (baseCost - 1)) == 0); + totalCost >>= (largestBits - targetNbBits); + assert(totalCost > 0); + + /* repay normalized cost */ + { U32 const noSymbol = 0xF0F0F0F0; + U32 rankLast[HUF_TABLELOG_MAX+2]; + + /* Get pos of last (smallest = lowest cum. count) symbol per rank */ + ZSTD_memset(rankLast, 0xF0, sizeof(rankLast)); + { U32 currentNbBits = targetNbBits; + int pos; + for (pos=n ; pos >= 0; pos--) { + if (huffNode[pos].nbBits >= currentNbBits) continue; + currentNbBits = huffNode[pos].nbBits; /* < targetNbBits */ + rankLast[targetNbBits-currentNbBits] = (U32)pos; + } } + + while (totalCost > 0) { + /* Try to reduce the next power of 2 above totalCost because we + * gain back half the rank. + */ + U32 nBitsToDecrease = ZSTD_highbit32((U32)totalCost) + 1; + for ( ; nBitsToDecrease > 1; nBitsToDecrease--) { + U32 const highPos = rankLast[nBitsToDecrease]; + U32 const lowPos = rankLast[nBitsToDecrease-1]; + if (highPos == noSymbol) continue; + /* Decrease highPos if no symbols of lowPos or if it is + * not cheaper to remove 2 lowPos than highPos. + */ + if (lowPos == noSymbol) break; + { U32 const highTotal = huffNode[highPos].count; + U32 const lowTotal = 2 * huffNode[lowPos].count; + if (highTotal <= lowTotal) break; + } } + /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */ + assert(rankLast[nBitsToDecrease] != noSymbol || nBitsToDecrease == 1); + /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */ + while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol)) + nBitsToDecrease++; + assert(rankLast[nBitsToDecrease] != noSymbol); + /* Increase the number of bits to gain back half the rank cost. */ + totalCost -= 1 << (nBitsToDecrease-1); + huffNode[rankLast[nBitsToDecrease]].nbBits++; + + /* Fix up the new rank. + * If the new rank was empty, this symbol is now its smallest. + * Otherwise, this symbol will be the largest in the new rank so no adjustment. + */ + if (rankLast[nBitsToDecrease-1] == noSymbol) + rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; + /* Fix up the old rank. + * If the symbol was at position 0, meaning it was the highest weight symbol in the tree, + * it must be the only symbol in its rank, so the old rank now has no symbols. + * Otherwise, since the Huffman nodes are sorted by count, the previous position is now + * the smallest node in the rank. If the previous position belongs to a different rank, + * then the rank is now empty. + */ + if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */ + rankLast[nBitsToDecrease] = noSymbol; + else { + rankLast[nBitsToDecrease]--; + if (huffNode[rankLast[nBitsToDecrease]].nbBits != targetNbBits-nBitsToDecrease) + rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */ + } + } /* while (totalCost > 0) */ + + /* If we've removed too much weight, then we have to add it back. + * To avoid overshooting again, we only adjust the smallest rank. + * We take the largest nodes from the lowest rank 0 and move them + * to rank 1. There's guaranteed to be enough rank 0 symbols because + * TODO. + */ + while (totalCost < 0) { /* Sometimes, cost correction overshoot */ + /* special case : no rank 1 symbol (using targetNbBits-1); + * let's create one from largest rank 0 (using targetNbBits). + */ + if (rankLast[1] == noSymbol) { + while (huffNode[n].nbBits == targetNbBits) n--; + huffNode[n+1].nbBits--; + assert(n >= 0); + rankLast[1] = (U32)(n+1); + totalCost++; + continue; + } + huffNode[ rankLast[1] + 1 ].nbBits--; + rankLast[1]++; + totalCost ++; + } + } /* repay normalized cost */ + } /* there are several too large elements (at least >= 2) */ + + return targetNbBits; +} + +typedef struct { + U16 base; + U16 curr; +} rankPos; + +typedef nodeElt huffNodeTable[2 * (HUF_SYMBOLVALUE_MAX + 1)]; + +/* Number of buckets available for HUF_sort() */ +#define RANK_POSITION_TABLE_SIZE 192 + +typedef struct { + huffNodeTable huffNodeTbl; + rankPos rankPosition[RANK_POSITION_TABLE_SIZE]; +} HUF_buildCTable_wksp_tables; + +/* RANK_POSITION_DISTINCT_COUNT_CUTOFF == Cutoff point in HUF_sort() buckets for which we use log2 bucketing. + * Strategy is to use as many buckets as possible for representing distinct + * counts while using the remainder to represent all "large" counts. + * + * To satisfy this requirement for 192 buckets, we can do the following: + * Let buckets 0-166 represent distinct counts of [0, 166] + * Let buckets 166 to 192 represent all remaining counts up to RANK_POSITION_MAX_COUNT_LOG using log2 bucketing. + */ +#define RANK_POSITION_MAX_COUNT_LOG 32 +#define RANK_POSITION_LOG_BUCKETS_BEGIN ((RANK_POSITION_TABLE_SIZE - 1) - RANK_POSITION_MAX_COUNT_LOG - 1 /* == 158 */) +#define RANK_POSITION_DISTINCT_COUNT_CUTOFF (RANK_POSITION_LOG_BUCKETS_BEGIN + ZSTD_highbit32(RANK_POSITION_LOG_BUCKETS_BEGIN) /* == 166 */) + +/* Return the appropriate bucket index for a given count. See definition of + * RANK_POSITION_DISTINCT_COUNT_CUTOFF for explanation of bucketing strategy. + */ +static U32 HUF_getIndex(U32 const count) { + return (count < RANK_POSITION_DISTINCT_COUNT_CUTOFF) + ? count + : ZSTD_highbit32(count) + RANK_POSITION_LOG_BUCKETS_BEGIN; +} + +/* Helper swap function for HUF_quickSortPartition() */ +static void HUF_swapNodes(nodeElt* a, nodeElt* b) { + nodeElt tmp = *a; + *a = *b; + *b = tmp; +} + +/* Returns 0 if the huffNode array is not sorted by descending count */ +MEM_STATIC int HUF_isSorted(nodeElt huffNode[], U32 const maxSymbolValue1) { + U32 i; + for (i = 1; i < maxSymbolValue1; ++i) { + if (huffNode[i].count > huffNode[i-1].count) { + return 0; + } + } + return 1; +} + +/* Insertion sort by descending order */ +HINT_INLINE void HUF_insertionSort(nodeElt huffNode[], int const low, int const high) { + int i; + int const size = high-low+1; + huffNode += low; + for (i = 1; i < size; ++i) { + nodeElt const key = huffNode[i]; + int j = i - 1; + while (j >= 0 && huffNode[j].count < key.count) { + huffNode[j + 1] = huffNode[j]; + j--; + } + huffNode[j + 1] = key; + } +} + +/* Pivot helper function for quicksort. */ +static int HUF_quickSortPartition(nodeElt arr[], int const low, int const high) { + /* Simply select rightmost element as pivot. "Better" selectors like + * median-of-three don't experimentally appear to have any benefit. + */ + U32 const pivot = arr[high].count; + int i = low - 1; + int j = low; + for ( ; j < high; j++) { + if (arr[j].count > pivot) { + i++; + HUF_swapNodes(&arr[i], &arr[j]); + } + } + HUF_swapNodes(&arr[i + 1], &arr[high]); + return i + 1; +} + +/* Classic quicksort by descending with partially iterative calls + * to reduce worst case callstack size. + */ +static void HUF_simpleQuickSort(nodeElt arr[], int low, int high) { + int const kInsertionSortThreshold = 8; + if (high - low < kInsertionSortThreshold) { + HUF_insertionSort(arr, low, high); + return; + } + while (low < high) { + int const idx = HUF_quickSortPartition(arr, low, high); + if (idx - low < high - idx) { + HUF_simpleQuickSort(arr, low, idx - 1); + low = idx + 1; + } else { + HUF_simpleQuickSort(arr, idx + 1, high); + high = idx - 1; + } + } +} + +/** + * HUF_sort(): + * Sorts the symbols [0, maxSymbolValue] by count[symbol] in decreasing order. + * This is a typical bucket sorting strategy that uses either quicksort or insertion sort to sort each bucket. + * + * @param[out] huffNode Sorted symbols by decreasing count. Only members `.count` and `.byte` are filled. + * Must have (maxSymbolValue + 1) entries. + * @param[in] count Histogram of the symbols. + * @param[in] maxSymbolValue Maximum symbol value. + * @param rankPosition This is a scratch workspace. Must have RANK_POSITION_TABLE_SIZE entries. + */ +static void HUF_sort(nodeElt huffNode[], const unsigned count[], U32 const maxSymbolValue, rankPos rankPosition[]) { + U32 n; + U32 const maxSymbolValue1 = maxSymbolValue+1; + + /* Compute base and set curr to base. + * For symbol s let lowerRank = HUF_getIndex(count[n]) and rank = lowerRank + 1. + * See HUF_getIndex to see bucketing strategy. + * We attribute each symbol to lowerRank's base value, because we want to know where + * each rank begins in the output, so for rank R we want to count ranks R+1 and above. + */ + ZSTD_memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE); + for (n = 0; n < maxSymbolValue1; ++n) { + U32 lowerRank = HUF_getIndex(count[n]); + assert(lowerRank < RANK_POSITION_TABLE_SIZE - 1); + rankPosition[lowerRank].base++; + } + + assert(rankPosition[RANK_POSITION_TABLE_SIZE - 1].base == 0); + /* Set up the rankPosition table */ + for (n = RANK_POSITION_TABLE_SIZE - 1; n > 0; --n) { + rankPosition[n-1].base += rankPosition[n].base; + rankPosition[n-1].curr = rankPosition[n-1].base; + } + + /* Insert each symbol into their appropriate bucket, setting up rankPosition table. */ + for (n = 0; n < maxSymbolValue1; ++n) { + U32 const c = count[n]; + U32 const r = HUF_getIndex(c) + 1; + U32 const pos = rankPosition[r].curr++; + assert(pos < maxSymbolValue1); + huffNode[pos].count = c; + huffNode[pos].byte = (BYTE)n; + } + + /* Sort each bucket. */ + for (n = RANK_POSITION_DISTINCT_COUNT_CUTOFF; n < RANK_POSITION_TABLE_SIZE - 1; ++n) { + int const bucketSize = rankPosition[n].curr - rankPosition[n].base; + U32 const bucketStartIdx = rankPosition[n].base; + if (bucketSize > 1) { + assert(bucketStartIdx < maxSymbolValue1); + HUF_simpleQuickSort(huffNode + bucketStartIdx, 0, bucketSize-1); + } + } + + assert(HUF_isSorted(huffNode, maxSymbolValue1)); +} + + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as sizeof(HUF_buildCTable_wksp_tables). + */ +#define STARTNODE (HUF_SYMBOLVALUE_MAX+1) + +/* HUF_buildTree(): + * Takes the huffNode array sorted by HUF_sort() and builds an unlimited-depth Huffman tree. + * + * @param huffNode The array sorted by HUF_sort(). Builds the Huffman tree in this array. + * @param maxSymbolValue The maximum symbol value. + * @return The smallest node in the Huffman tree (by count). + */ +static int HUF_buildTree(nodeElt* huffNode, U32 maxSymbolValue) +{ + nodeElt* const huffNode0 = huffNode - 1; + int nonNullRank; + int lowS, lowN; + int nodeNb = STARTNODE; + int n, nodeRoot; + DEBUGLOG(5, "HUF_buildTree (alphabet size = %u)", maxSymbolValue + 1); + /* init for parents */ + nonNullRank = (int)maxSymbolValue; + while(huffNode[nonNullRank].count == 0) nonNullRank--; + lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb; + huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count; + huffNode[lowS].parent = huffNode[lowS-1].parent = (U16)nodeNb; + nodeNb++; lowS-=2; + for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30); + huffNode0[0].count = (U32)(1U<<31); /* fake entry, strong barrier */ + + /* create parents */ + while (nodeNb <= nodeRoot) { + int const n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++; + int const n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++; + huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count; + huffNode[n1].parent = huffNode[n2].parent = (U16)nodeNb; + nodeNb++; + } + + /* distribute weights (unlimited tree height) */ + huffNode[nodeRoot].nbBits = 0; + for (n=nodeRoot-1; n>=STARTNODE; n--) + huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1; + for (n=0; n<=nonNullRank; n++) + huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1; + + DEBUGLOG(6, "Initial distribution of bits completed (%zu sorted symbols)", showHNodeBits(huffNode, maxSymbolValue+1)); + + return nonNullRank; +} + +/** + * HUF_buildCTableFromTree(): + * Build the CTable given the Huffman tree in huffNode. + * + * @param[out] CTable The output Huffman CTable. + * @param huffNode The Huffman tree. + * @param nonNullRank The last and smallest node in the Huffman tree. + * @param maxSymbolValue The maximum symbol value. + * @param maxNbBits The exact maximum number of bits used in the Huffman tree. + */ +static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, int nonNullRank, U32 maxSymbolValue, U32 maxNbBits) +{ + HUF_CElt* const ct = CTable + 1; + /* fill result into ctable (val, nbBits) */ + int n; + U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0}; + U16 valPerRank[HUF_TABLELOG_MAX+1] = {0}; + int const alphabetSize = (int)(maxSymbolValue + 1); + for (n=0; n<=nonNullRank; n++) + nbPerRank[huffNode[n].nbBits]++; + /* determine starting value per rank */ + { U16 min = 0; + for (n=(int)maxNbBits; n>0; n--) { + valPerRank[n] = min; /* get starting value within each rank */ + min += nbPerRank[n]; + min >>= 1; + } } + for (n=0; nhuffNodeTbl; + nodeElt* const huffNode = huffNode0+1; + int nonNullRank; + + HUF_STATIC_ASSERT(HUF_CTABLE_WORKSPACE_SIZE == sizeof(HUF_buildCTable_wksp_tables)); + + DEBUGLOG(5, "HUF_buildCTable_wksp (alphabet size = %u)", maxSymbolValue+1); + + /* safety checks */ + if (wkspSize < sizeof(HUF_buildCTable_wksp_tables)) + return ERROR(workSpace_tooSmall); + if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT; + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) + return ERROR(maxSymbolValue_tooLarge); + ZSTD_memset(huffNode0, 0, sizeof(huffNodeTable)); + + /* sort, decreasing order */ + HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition); + DEBUGLOG(6, "sorted symbols completed (%zu symbols)", showHNodeSymbols(huffNode, maxSymbolValue+1)); + + /* build tree */ + nonNullRank = HUF_buildTree(huffNode, maxSymbolValue); + + /* determine and enforce maxTableLog */ + maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits); + if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */ + + HUF_buildCTableFromTree(CTable, huffNode, nonNullRank, maxSymbolValue, maxNbBits); + + return maxNbBits; +} + +size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) +{ + HUF_CElt const* ct = CTable + 1; + size_t nbBits = 0; + int s; + for (s = 0; s <= (int)maxSymbolValue; ++s) { + nbBits += HUF_getNbBits(ct[s]) * count[s]; + } + return nbBits >> 3; +} + +int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) { + HUF_CTableHeader header = HUF_readCTableHeader(CTable); + HUF_CElt const* ct = CTable + 1; + int bad = 0; + int s; + + assert(header.tableLog <= HUF_TABLELOG_ABSOLUTEMAX); + + if (header.maxSymbolValue < maxSymbolValue) + return 0; + + for (s = 0; s <= (int)maxSymbolValue; ++s) { + bad |= (count[s] != 0) & (HUF_getNbBits(ct[s]) == 0); + } + return !bad; +} + +size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); } + +/** HUF_CStream_t: + * Huffman uses its own BIT_CStream_t implementation. + * There are three major differences from BIT_CStream_t: + * 1. HUF_addBits() takes a HUF_CElt (size_t) which is + * the pair (nbBits, value) in the format: + * format: + * - Bits [0, 4) = nbBits + * - Bits [4, 64 - nbBits) = 0 + * - Bits [64 - nbBits, 64) = value + * 2. The bitContainer is built from the upper bits and + * right shifted. E.g. to add a new value of N bits + * you right shift the bitContainer by N, then or in + * the new value into the N upper bits. + * 3. The bitstream has two bit containers. You can add + * bits to the second container and merge them into + * the first container. + */ + +#define HUF_BITS_IN_CONTAINER (sizeof(size_t) * 8) + +typedef struct { + size_t bitContainer[2]; + size_t bitPos[2]; + + BYTE* startPtr; + BYTE* ptr; + BYTE* endPtr; +} HUF_CStream_t; + +/**! HUF_initCStream(): + * Initializes the bitstream. + * @returns 0 or an error code. + */ +static size_t HUF_initCStream(HUF_CStream_t* bitC, + void* startPtr, size_t dstCapacity) +{ + ZSTD_memset(bitC, 0, sizeof(*bitC)); + bitC->startPtr = (BYTE*)startPtr; + bitC->ptr = bitC->startPtr; + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer[0]); + if (dstCapacity <= sizeof(bitC->bitContainer[0])) return ERROR(dstSize_tooSmall); + return 0; +} + +/*! HUF_addBits(): + * Adds the symbol stored in HUF_CElt elt to the bitstream. + * + * @param elt The element we're adding. This is a (nbBits, value) pair. + * See the HUF_CStream_t docs for the format. + * @param idx Insert into the bitstream at this idx. + * @param kFast This is a template parameter. If the bitstream is guaranteed + * to have at least 4 unused bits after this call it may be 1, + * otherwise it must be 0. HUF_addBits() is faster when fast is set. + */ +FORCE_INLINE_TEMPLATE void HUF_addBits(HUF_CStream_t* bitC, HUF_CElt elt, int idx, int kFast) +{ + assert(idx <= 1); + assert(HUF_getNbBits(elt) <= HUF_TABLELOG_ABSOLUTEMAX); + /* This is efficient on x86-64 with BMI2 because shrx + * only reads the low 6 bits of the register. The compiler + * knows this and elides the mask. When fast is set, + * every operation can use the same value loaded from elt. + */ + bitC->bitContainer[idx] >>= HUF_getNbBits(elt); + bitC->bitContainer[idx] |= kFast ? HUF_getValueFast(elt) : HUF_getValue(elt); + /* We only read the low 8 bits of bitC->bitPos[idx] so it + * doesn't matter that the high bits have noise from the value. + */ + bitC->bitPos[idx] += HUF_getNbBitsFast(elt); + assert((bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER); + /* The last 4-bits of elt are dirty if fast is set, + * so we must not be overwriting bits that have already been + * inserted into the bit container. + */ +#if DEBUGLEVEL >= 1 + { + size_t const nbBits = HUF_getNbBits(elt); + size_t const dirtyBits = nbBits == 0 ? 0 : ZSTD_highbit32((U32)nbBits) + 1; + (void)dirtyBits; + /* Middle bits are 0. */ + assert(((elt >> dirtyBits) << (dirtyBits + nbBits)) == 0); + /* We didn't overwrite any bits in the bit container. */ + assert(!kFast || (bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER); + (void)dirtyBits; + } +#endif +} + +FORCE_INLINE_TEMPLATE void HUF_zeroIndex1(HUF_CStream_t* bitC) +{ + bitC->bitContainer[1] = 0; + bitC->bitPos[1] = 0; +} + +/*! HUF_mergeIndex1() : + * Merges the bit container @ index 1 into the bit container @ index 0 + * and zeros the bit container @ index 1. + */ +FORCE_INLINE_TEMPLATE void HUF_mergeIndex1(HUF_CStream_t* bitC) +{ + assert((bitC->bitPos[1] & 0xFF) < HUF_BITS_IN_CONTAINER); + bitC->bitContainer[0] >>= (bitC->bitPos[1] & 0xFF); + bitC->bitContainer[0] |= bitC->bitContainer[1]; + bitC->bitPos[0] += bitC->bitPos[1]; + assert((bitC->bitPos[0] & 0xFF) <= HUF_BITS_IN_CONTAINER); +} + +/*! HUF_flushBits() : +* Flushes the bits in the bit container @ index 0. +* +* @post bitPos will be < 8. +* @param kFast If kFast is set then we must know a-priori that +* the bit container will not overflow. +*/ +FORCE_INLINE_TEMPLATE void HUF_flushBits(HUF_CStream_t* bitC, int kFast) +{ + /* The upper bits of bitPos are noisy, so we must mask by 0xFF. */ + size_t const nbBits = bitC->bitPos[0] & 0xFF; + size_t const nbBytes = nbBits >> 3; + /* The top nbBits bits of bitContainer are the ones we need. */ + size_t const bitContainer = bitC->bitContainer[0] >> (HUF_BITS_IN_CONTAINER - nbBits); + /* Mask bitPos to account for the bytes we consumed. */ + bitC->bitPos[0] &= 7; + assert(nbBits > 0); + assert(nbBits <= sizeof(bitC->bitContainer[0]) * 8); + assert(bitC->ptr <= bitC->endPtr); + MEM_writeLEST(bitC->ptr, bitContainer); + bitC->ptr += nbBytes; + assert(!kFast || bitC->ptr <= bitC->endPtr); + if (!kFast && bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; + /* bitContainer doesn't need to be modified because the leftover + * bits are already the top bitPos bits. And we don't care about + * noise in the lower values. + */ +} + +/*! HUF_endMark() + * @returns The Huffman stream end mark: A 1-bit value = 1. + */ +static HUF_CElt HUF_endMark(void) +{ + HUF_CElt endMark; + HUF_setNbBits(&endMark, 1); + HUF_setValue(&endMark, 1); + return endMark; +} + +/*! HUF_closeCStream() : + * @return Size of CStream, in bytes, + * or 0 if it could not fit into dstBuffer */ +static size_t HUF_closeCStream(HUF_CStream_t* bitC) +{ + HUF_addBits(bitC, HUF_endMark(), /* idx */ 0, /* kFast */ 0); + HUF_flushBits(bitC, /* kFast */ 0); + { + size_t const nbBits = bitC->bitPos[0] & 0xFF; + if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ + return (size_t)(bitC->ptr - bitC->startPtr) + (nbBits > 0); + } +} + +FORCE_INLINE_TEMPLATE void +HUF_encodeSymbol(HUF_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable, int idx, int fast) +{ + HUF_addBits(bitCPtr, CTable[symbol], idx, fast); +} + +FORCE_INLINE_TEMPLATE void +HUF_compress1X_usingCTable_internal_body_loop(HUF_CStream_t* bitC, + const BYTE* ip, size_t srcSize, + const HUF_CElt* ct, + int kUnroll, int kFastFlush, int kLastFast) +{ + /* Join to kUnroll */ + int n = (int)srcSize; + int rem = n % kUnroll; + if (rem > 0) { + for (; rem > 0; --rem) { + HUF_encodeSymbol(bitC, ip[--n], ct, 0, /* fast */ 0); + } + HUF_flushBits(bitC, kFastFlush); + } + assert(n % kUnroll == 0); + + /* Join to 2 * kUnroll */ + if (n % (2 * kUnroll)) { + int u; + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - u], ct, 0, 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, 0, kLastFast); + HUF_flushBits(bitC, kFastFlush); + n -= kUnroll; + } + assert(n % (2 * kUnroll) == 0); + + for (; n>0; n-= 2 * kUnroll) { + /* Encode kUnroll symbols into the bitstream @ index 0. */ + int u; + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - u], ct, /* idx */ 0, /* fast */ 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, /* idx */ 0, /* fast */ kLastFast); + HUF_flushBits(bitC, kFastFlush); + /* Encode kUnroll symbols into the bitstream @ index 1. + * This allows us to start filling the bit container + * without any data dependencies. + */ + HUF_zeroIndex1(bitC); + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - kUnroll - u], ct, /* idx */ 1, /* fast */ 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll - kUnroll], ct, /* idx */ 1, /* fast */ kLastFast); + /* Merge bitstream @ index 1 into the bitstream @ index 0 */ + HUF_mergeIndex1(bitC); + HUF_flushBits(bitC, kFastFlush); + } + assert(n == 0); + +} + +/** + * Returns a tight upper bound on the output space needed by Huffman + * with 8 bytes buffer to handle over-writes. If the output is at least + * this large we don't need to do bounds checks during Huffman encoding. + */ +static size_t HUF_tightCompressBound(size_t srcSize, size_t tableLog) +{ + return ((srcSize * tableLog) >> 3) + 8; +} + + +FORCE_INLINE_TEMPLATE size_t +HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable) +{ + U32 const tableLog = HUF_readCTableHeader(CTable).tableLog; + HUF_CElt const* ct = CTable + 1; + const BYTE* ip = (const BYTE*) src; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstSize; + HUF_CStream_t bitC; + + /* init */ + if (dstSize < 8) return 0; /* not enough space to compress */ + { BYTE* op = ostart; + size_t const initErr = HUF_initCStream(&bitC, op, (size_t)(oend-op)); + if (HUF_isError(initErr)) return 0; } + + if (dstSize < HUF_tightCompressBound(srcSize, (size_t)tableLog) || tableLog > 11) + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ MEM_32bits() ? 2 : 4, /* kFast */ 0, /* kLastFast */ 0); + else { + if (MEM_32bits()) { + switch (tableLog) { + case 11: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 10: ZSTD_FALLTHROUGH; + case 9: ZSTD_FALLTHROUGH; + case 8: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + case 7: ZSTD_FALLTHROUGH; + default: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 3, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + } + } else { + switch (tableLog) { + case 11: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 10: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + case 9: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 6, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 8: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 7, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 7: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 8, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 6: ZSTD_FALLTHROUGH; + default: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 9, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + } + } + } + assert(bitC.ptr <= bitC.endPtr); + + return HUF_closeCStream(&bitC); +} + +#if DYNAMIC_BMI2 + +static BMI2_TARGET_ATTRIBUTE size_t +HUF_compress1X_usingCTable_internal_bmi2(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable) +{ + return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable); +} + +static size_t +HUF_compress1X_usingCTable_internal_default(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable) +{ + return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable); +} + +static size_t +HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable, const int flags) +{ + if (flags & HUF_flags_bmi2) { + return HUF_compress1X_usingCTable_internal_bmi2(dst, dstSize, src, srcSize, CTable); + } + return HUF_compress1X_usingCTable_internal_default(dst, dstSize, src, srcSize, CTable); +} + +#else + +static size_t +HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable, const int flags) +{ + (void)flags; + return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable); +} + +#endif + +size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags) +{ + return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags); +} + +static size_t +HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable, int flags) +{ + size_t const segmentSize = (srcSize+3)/4; /* first 3 segments */ + const BYTE* ip = (const BYTE*) src; + const BYTE* const iend = ip + srcSize; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + BYTE* op = ostart; + + if (dstSize < 6 + 1 + 1 + 1 + 8) return 0; /* minimum space to compress successfully */ + if (srcSize < 12) return 0; /* no saving possible : too small input */ + op += 6; /* jumpTable */ + + assert(op <= oend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + MEM_writeLE16(ostart, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + assert(op <= oend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + MEM_writeLE16(ostart+2, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + assert(op <= oend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + MEM_writeLE16(ostart+4, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + assert(op <= oend); + assert(ip <= iend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + op += cSize; + } + + return (size_t)(op-ostart); +} + +size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags) +{ + return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags); +} + +typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e; + +static size_t HUF_compressCTable_internal( + BYTE* const ostart, BYTE* op, BYTE* const oend, + const void* src, size_t srcSize, + HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int flags) +{ + size_t const cSize = (nbStreams==HUF_singleStream) ? + HUF_compress1X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, flags) : + HUF_compress4X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, flags); + if (HUF_isError(cSize)) { return cSize; } + if (cSize==0) { return 0; } /* uncompressible */ + op += cSize; + /* check compressibility */ + assert(op >= ostart); + if ((size_t)(op-ostart) >= srcSize-1) { return 0; } + return (size_t)(op-ostart); +} + +typedef struct { + unsigned count[HUF_SYMBOLVALUE_MAX + 1]; + HUF_CElt CTable[HUF_CTABLE_SIZE_ST(HUF_SYMBOLVALUE_MAX)]; + union { + HUF_buildCTable_wksp_tables buildCTable_wksp; + HUF_WriteCTableWksp writeCTable_wksp; + U32 hist_wksp[HIST_WKSP_SIZE_U32]; + } wksps; +} HUF_compress_tables_t; + +#define SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE 4096 +#define SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO 10 /* Must be >= 2 */ + +unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue) +{ + unsigned cardinality = 0; + unsigned i; + + for (i = 0; i < maxSymbolValue + 1; i++) { + if (count[i] != 0) cardinality += 1; + } + + return cardinality; +} + +unsigned HUF_minTableLog(unsigned symbolCardinality) +{ + U32 minBitsSymbols = ZSTD_highbit32(symbolCardinality) + 1; + return minBitsSymbols; +} + +unsigned HUF_optimalTableLog( + unsigned maxTableLog, + size_t srcSize, + unsigned maxSymbolValue, + void* workSpace, size_t wkspSize, + HUF_CElt* table, + const unsigned* count, + int flags) +{ + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + assert(wkspSize >= sizeof(HUF_buildCTable_wksp_tables)); + + if (!(flags & HUF_flags_optimalDepth)) { + /* cheap evaluation, based on FSE */ + return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1); + } + + { BYTE* dst = (BYTE*)workSpace + sizeof(HUF_WriteCTableWksp); + size_t dstSize = wkspSize - sizeof(HUF_WriteCTableWksp); + size_t hSize, newSize; + const unsigned symbolCardinality = HUF_cardinality(count, maxSymbolValue); + const unsigned minTableLog = HUF_minTableLog(symbolCardinality); + size_t optSize = ((size_t) ~0) - 1; + unsigned optLog = maxTableLog, optLogGuess; + + DEBUGLOG(6, "HUF_optimalTableLog: probing huf depth (srcSize=%zu)", srcSize); + + /* Search until size increases */ + for (optLogGuess = minTableLog; optLogGuess <= maxTableLog; optLogGuess++) { + DEBUGLOG(7, "checking for huffLog=%u", optLogGuess); + + { size_t maxBits = HUF_buildCTable_wksp(table, count, maxSymbolValue, optLogGuess, workSpace, wkspSize); + if (ERR_isError(maxBits)) continue; + + if (maxBits < optLogGuess && optLogGuess > minTableLog) break; + + hSize = HUF_writeCTable_wksp(dst, dstSize, table, maxSymbolValue, (U32)maxBits, workSpace, wkspSize); + } + + if (ERR_isError(hSize)) continue; + + newSize = HUF_estimateCompressedSize(table, count, maxSymbolValue) + hSize; + + if (newSize > optSize + 1) { + break; + } + + if (newSize < optSize) { + optSize = newSize; + optLog = optLogGuess; + } + } + assert(optLog <= HUF_TABLELOG_MAX); + return optLog; + } +} + +/* HUF_compress_internal() : + * `workSpace_align4` must be aligned on 4-bytes boundaries, + * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U64 unsigned */ +static size_t +HUF_compress_internal (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, + HUF_nbStreams_e nbStreams, + void* workSpace, size_t wkspSize, + HUF_CElt* oldHufTable, HUF_repeat* repeat, int flags) +{ + HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(size_t)); + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstSize; + BYTE* op = ostart; + + DEBUGLOG(5, "HUF_compress_internal (srcSize=%zu)", srcSize); + HUF_STATIC_ASSERT(sizeof(*table) + HUF_WORKSPACE_MAX_ALIGNMENT <= HUF_WORKSPACE_SIZE); + + /* checks & inits */ + if (wkspSize < sizeof(*table)) return ERROR(workSpace_tooSmall); + if (!srcSize) return 0; /* Uncompressed */ + if (!dstSize) return 0; /* cannot fit anything within dst budget */ + if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */ + if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge); + if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX; + if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT; + + /* Heuristic : If old table is valid, use it for small inputs */ + if ((flags & HUF_flags_preferRepeat) && repeat && *repeat == HUF_repeat_valid) { + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, oldHufTable, flags); + } + + /* If uncompressible data is suspected, do a smaller sampling first */ + DEBUG_STATIC_ASSERT(SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO >= 2); + if ((flags & HUF_flags_suspectUncompressible) && srcSize >= (SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE * SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO)) { + size_t largestTotal = 0; + DEBUGLOG(5, "input suspected incompressible : sampling to check"); + { unsigned maxSymbolValueBegin = maxSymbolValue; + CHECK_V_F(largestBegin, HIST_count_simple (table->count, &maxSymbolValueBegin, (const BYTE*)src, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) ); + largestTotal += largestBegin; + } + { unsigned maxSymbolValueEnd = maxSymbolValue; + CHECK_V_F(largestEnd, HIST_count_simple (table->count, &maxSymbolValueEnd, (const BYTE*)src + srcSize - SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) ); + largestTotal += largestEnd; + } + if (largestTotal <= ((2 * SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) >> 7)+4) return 0; /* heuristic : probably not compressible enough */ + } + + /* Scan input and build symbol stats */ + { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, table->wksps.hist_wksp, sizeof(table->wksps.hist_wksp)) ); + if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */ + if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */ + } + DEBUGLOG(6, "histogram detail completed (%zu symbols)", showU32(table->count, maxSymbolValue+1)); + + /* Check validity of previous table */ + if ( repeat + && *repeat == HUF_repeat_check + && !HUF_validateCTable(oldHufTable, table->count, maxSymbolValue)) { + *repeat = HUF_repeat_none; + } + /* Heuristic : use existing table for small inputs */ + if ((flags & HUF_flags_preferRepeat) && repeat && *repeat != HUF_repeat_none) { + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, oldHufTable, flags); + } + + /* Build Huffman Tree */ + huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, &table->wksps, sizeof(table->wksps), table->CTable, table->count, flags); + { size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count, + maxSymbolValue, huffLog, + &table->wksps.buildCTable_wksp, sizeof(table->wksps.buildCTable_wksp)); + CHECK_F(maxBits); + huffLog = (U32)maxBits; + DEBUGLOG(6, "bit distribution completed (%zu symbols)", showCTableBits(table->CTable + 1, maxSymbolValue+1)); + } + + /* Write table description header */ + { CHECK_V_F(hSize, HUF_writeCTable_wksp(op, dstSize, table->CTable, maxSymbolValue, huffLog, + &table->wksps.writeCTable_wksp, sizeof(table->wksps.writeCTable_wksp)) ); + /* Check if using previous huffman table is beneficial */ + if (repeat && *repeat != HUF_repeat_none) { + size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, table->count, maxSymbolValue); + size_t const newSize = HUF_estimateCompressedSize(table->CTable, table->count, maxSymbolValue); + if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) { + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, oldHufTable, flags); + } } + + /* Use the new huffman table */ + if (hSize + 12ul >= srcSize) { return 0; } + op += hSize; + if (repeat) { *repeat = HUF_repeat_none; } + if (oldHufTable) + ZSTD_memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */ + } + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, table->CTable, flags); +} + +size_t HUF_compress1X_repeat (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, + void* workSpace, size_t wkspSize, + HUF_CElt* hufTable, HUF_repeat* repeat, int flags) +{ + DEBUGLOG(5, "HUF_compress1X_repeat (srcSize = %zu)", srcSize); + return HUF_compress_internal(dst, dstSize, src, srcSize, + maxSymbolValue, huffLog, HUF_singleStream, + workSpace, wkspSize, hufTable, + repeat, flags); +} + +/* HUF_compress4X_repeat(): + * compress input using 4 streams. + * consider skipping quickly + * reuse an existing huffman compression table */ +size_t HUF_compress4X_repeat (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, + void* workSpace, size_t wkspSize, + HUF_CElt* hufTable, HUF_repeat* repeat, int flags) +{ + DEBUGLOG(5, "HUF_compress4X_repeat (srcSize = %zu)", srcSize); + return HUF_compress_internal(dst, dstSize, src, srcSize, + maxSymbolValue, huffLog, HUF_fourStreams, + workSpace, wkspSize, + hufTable, repeat, flags); +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress.c b/src/commonlib/bsd/zstd/compress/zstd_compress.c new file mode 100644 index 0000000000..7cf21cc5cb --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress.c @@ -0,0 +1,6046 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/*-************************************* +* Dependencies +***************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */ +#include "../common/zstd_deps.h" /* INT_MAX, ZSTD_memset, ZSTD_memcpy */ +#include "../common/mem.h" +#include "../common/error_private.h" +#include "hist.h" /* HIST_countFast_wksp */ +#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */ +#include "../common/fse.h" +#include "../common/huf.h" +#include "zstd_compress_internal.h" +#include "zstd_compress_sequences.h" +#include "zstd_compress_literals.h" +#include "zstd_fast.h" +#include "zstd_double_fast.h" +#include "zstd_lazy.h" +#include "zstd_opt.h" +#include "zstd_ldm.h" +#include "zstd_compress_superblock.h" +#include "../common/zstd_bits.h" /* ZSTD_highbit32, ZSTD_rotateRight_U64 */ + +/* *************************************************************** +* Tuning parameters +*****************************************************************/ +/*! + * COMPRESS_HEAPMODE : + * Select how default decompression function ZSTD_compress() allocates its context, + * on stack (0, default), or into heap (1). + * Note that functions with explicit context such as ZSTD_compressCCtx() are unaffected. + */ +#ifndef ZSTD_COMPRESS_HEAPMODE +# define ZSTD_COMPRESS_HEAPMODE 0 +#endif + +/*! + * ZSTD_HASHLOG3_MAX : + * Maximum size of the hash table dedicated to find 3-bytes matches, + * in log format, aka 17 => 1 << 17 == 128Ki positions. + * This structure is only used in zstd_opt. + * Since allocation is centralized for all strategies, it has to be known here. + * The actual (selected) size of the hash table is then stored in ZSTD_MatchState_t.hashLog3, + * so that zstd_opt.c doesn't need to know about this constant. + */ +#ifndef ZSTD_HASHLOG3_MAX +# define ZSTD_HASHLOG3_MAX 17 +#endif + +/*-************************************* +* Helper functions +***************************************/ +/* ZSTD_compressBound() + * Note that the result from this function is only valid for + * the one-pass compression functions. + * When employing the streaming mode, + * if flushes are frequently altering the size of blocks, + * the overhead from block headers can make the compressed data larger + * than the return value of ZSTD_compressBound(). + */ +size_t ZSTD_compressBound(size_t srcSize) { + size_t const r = ZSTD_COMPRESSBOUND(srcSize); + if (r==0) return ERROR(srcSize_wrong); + return r; +} + + +/*-************************************* +* Context memory management +***************************************/ +struct ZSTD_CDict_s { + const void* dictContent; + size_t dictContentSize; + ZSTD_dictContentType_e dictContentType; /* The dictContentType the CDict was created with */ + U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */ + ZSTD_cwksp workspace; + ZSTD_MatchState_t matchState; + ZSTD_compressedBlockState_t cBlockState; + ZSTD_customMem customMem; + U32 dictID; + int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */ + ZSTD_ParamSwitch_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use + * row-based matchfinder. Unless the cdict is reloaded, we will use + * the same greedy/lazy matchfinder at compression time. + */ +}; /* typedef'd to ZSTD_CDict within "zstd.h" */ + +ZSTD_CCtx* ZSTD_createCCtx(void) +{ + return ZSTD_createCCtx_advanced(ZSTD_defaultCMem); +} + +static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager) +{ + assert(cctx != NULL); + ZSTD_memset(cctx, 0, sizeof(*cctx)); + cctx->customMem = memManager; + cctx->bmi2 = ZSTD_cpuSupportsBmi2(); + { size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters); + assert(!ZSTD_isError(err)); + (void)err; + } +} + +ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) +{ + ZSTD_STATIC_ASSERT(zcss_init==0); + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1)); + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_customMalloc(sizeof(ZSTD_CCtx), customMem); + if (!cctx) return NULL; + ZSTD_initCCtx(cctx, customMem); + return cctx; + } +} + +ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize) +{ + ZSTD_cwksp ws; + ZSTD_CCtx* cctx; + if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL; /* minimum size */ + if ((size_t)workspace & 7) return NULL; /* must be 8-aligned */ + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc); + + cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx)); + if (cctx == NULL) return NULL; + + ZSTD_memset(cctx, 0, sizeof(ZSTD_CCtx)); + ZSTD_cwksp_move(&cctx->workspace, &ws); + cctx->staticSize = workspaceSize; + + /* statically sized space. tmpWorkspace never moves (but prev/next block swap places) */ + if (!ZSTD_cwksp_check_available(&cctx->workspace, TMP_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL; + cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t)); + cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t)); + cctx->tmpWorkspace = ZSTD_cwksp_reserve_object(&cctx->workspace, TMP_WORKSPACE_SIZE); + cctx->tmpWkspSize = TMP_WORKSPACE_SIZE; + cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); + return cctx; +} + +/** + * Clears and frees all of the dictionaries in the CCtx. + */ +static void ZSTD_clearAllDicts(ZSTD_CCtx* cctx) +{ + ZSTD_customFree(cctx->localDict.dictBuffer, cctx->customMem); + ZSTD_freeCDict(cctx->localDict.cdict); + ZSTD_memset(&cctx->localDict, 0, sizeof(cctx->localDict)); + ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); + cctx->cdict = NULL; +} + +static size_t ZSTD_sizeof_localDict(ZSTD_localDict dict) +{ + size_t const bufferSize = dict.dictBuffer != NULL ? dict.dictSize : 0; + size_t const cdictSize = ZSTD_sizeof_CDict(dict.cdict); + return bufferSize + cdictSize; +} + +static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx) +{ + assert(cctx != NULL); + assert(cctx->staticSize == 0); + ZSTD_clearAllDicts(cctx); +#ifdef ZSTD_MULTITHREAD + ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL; +#endif + ZSTD_cwksp_free(&cctx->workspace, cctx->customMem); +} + +size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) +{ + DEBUGLOG(3, "ZSTD_freeCCtx (address: %p)", (void*)cctx); + if (cctx==NULL) return 0; /* support free on NULL */ + RETURN_ERROR_IF(cctx->staticSize, memory_allocation, + "not compatible with static CCtx"); + { int cctxInWorkspace = ZSTD_cwksp_owns_buffer(&cctx->workspace, cctx); + ZSTD_freeCCtxContent(cctx); + if (!cctxInWorkspace) ZSTD_customFree(cctx, cctx->customMem); + } + return 0; +} + + +static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx) +{ +#ifdef ZSTD_MULTITHREAD + return ZSTDMT_sizeof_CCtx(cctx->mtctx); +#else + (void)cctx; + return 0; +#endif +} + + +size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx) +{ + if (cctx==NULL) return 0; /* support sizeof on NULL */ + /* cctx may be in the workspace */ + return (cctx->workspace.workspace == cctx ? 0 : sizeof(*cctx)) + + ZSTD_cwksp_sizeof(&cctx->workspace) + + ZSTD_sizeof_localDict(cctx->localDict) + + ZSTD_sizeof_mtctx(cctx); +} + +/* private API call, for dictBuilder only */ +const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); } + +/* Returns true if the strategy supports using a row based matchfinder */ +static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) { + return (strategy >= ZSTD_greedy && strategy <= ZSTD_lazy2); +} + +/* Returns true if the strategy and useRowMatchFinder mode indicate that we will use the row based matchfinder + * for this compression. + */ +static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_ParamSwitch_e mode) { + assert(mode != ZSTD_ps_auto); + return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_ps_enable); +} + +/* Returns row matchfinder usage given an initial mode and cParams */ +static ZSTD_ParamSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_ParamSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */ + mode = ZSTD_ps_disable; + if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode; + if (cParams->windowLog > 14) mode = ZSTD_ps_enable; + return mode; +} + +/* Returns block splitter usage (generally speaking, when using slower/stronger compression modes) */ +static ZSTD_ParamSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_ParamSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; + return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17) ? ZSTD_ps_enable : ZSTD_ps_disable; +} + +/* Returns 1 if the arguments indicate that we should allocate a chainTable, 0 otherwise */ +static int ZSTD_allocateChainTable(const ZSTD_strategy strategy, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const U32 forDDSDict) { + assert(useRowMatchFinder != ZSTD_ps_auto); + /* We always should allocate a chaintable if we are allocating a matchstate for a DDS dictionary matchstate. + * We do not allocate a chaintable if we are using ZSTD_fast, or are using the row-based matchfinder. + */ + return forDDSDict || ((strategy != ZSTD_fast) && !ZSTD_rowMatchFinderUsed(strategy, useRowMatchFinder)); +} + +/* Returns ZSTD_ps_enable if compression parameters are such that we should + * enable long distance matching (wlog >= 27, strategy >= btopt). + * Returns ZSTD_ps_disable otherwise. + */ +static ZSTD_ParamSwitch_e ZSTD_resolveEnableLdm(ZSTD_ParamSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; + return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable; +} + +static int ZSTD_resolveExternalSequenceValidation(int mode) { + return mode; +} + +/* Resolves maxBlockSize to the default if no value is present. */ +static size_t ZSTD_resolveMaxBlockSize(size_t maxBlockSize) { + if (maxBlockSize == 0) { + return ZSTD_BLOCKSIZE_MAX; + } else { + return maxBlockSize; + } +} + +static ZSTD_ParamSwitch_e ZSTD_resolveExternalRepcodeSearch(ZSTD_ParamSwitch_e value, int cLevel) { + if (value != ZSTD_ps_auto) return value; + if (cLevel < 10) { + return ZSTD_ps_disable; + } else { + return ZSTD_ps_enable; + } +} + +/* Returns 1 if compression parameters are such that CDict hashtable and chaintable indices are tagged. + * If so, the tags need to be removed in ZSTD_resetCCtx_byCopyingCDict. */ +static int ZSTD_CDictIndicesAreTagged(const ZSTD_compressionParameters* const cParams) { + return cParams->strategy == ZSTD_fast || cParams->strategy == ZSTD_dfast; +} + +static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( + ZSTD_compressionParameters cParams) +{ + ZSTD_CCtx_params cctxParams; + /* should not matter, as all cParams are presumed properly defined */ + ZSTD_CCtxParams_init(&cctxParams, ZSTD_CLEVEL_DEFAULT); + cctxParams.cParams = cParams; + + /* Adjust advanced params according to cParams */ + cctxParams.ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams.ldmParams.enableLdm, &cParams); + if (cctxParams.ldmParams.enableLdm == ZSTD_ps_enable) { + ZSTD_ldm_adjustParameters(&cctxParams.ldmParams, &cParams); + assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog); + assert(cctxParams.ldmParams.hashRateLog < 32); + } + cctxParams.postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.postBlockSplitter, &cParams); + cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams); + cctxParams.validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams.validateSequences); + cctxParams.maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams.maxBlockSize); + cctxParams.searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams.searchForExternalRepcodes, + cctxParams.compressionLevel); + assert(!ZSTD_checkCParams(cParams)); + return cctxParams; +} + +static ZSTD_CCtx_params* ZSTD_createCCtxParams_advanced( + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params* params; + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + params = (ZSTD_CCtx_params*)ZSTD_customCalloc( + sizeof(ZSTD_CCtx_params), customMem); + if (!params) { return NULL; } + ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT); + params->customMem = customMem; + return params; +} + +ZSTD_CCtx_params* ZSTD_createCCtxParams(void) +{ + return ZSTD_createCCtxParams_advanced(ZSTD_defaultCMem); +} + +size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params) +{ + if (params == NULL) { return 0; } + ZSTD_customFree(params, params->customMem); + return 0; +} + +size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params) +{ + return ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT); +} + +size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) { + RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!"); + ZSTD_memset(cctxParams, 0, sizeof(*cctxParams)); + cctxParams->compressionLevel = compressionLevel; + cctxParams->fParams.contentSizeFlag = 1; + return 0; +} + +#define ZSTD_NO_CLEVEL 0 + +/** + * Initializes `cctxParams` from `params` and `compressionLevel`. + * @param compressionLevel If params are derived from a compression level then that compression level, otherwise ZSTD_NO_CLEVEL. + */ +static void +ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, + const ZSTD_parameters* params, + int compressionLevel) +{ + assert(!ZSTD_checkCParams(params->cParams)); + ZSTD_memset(cctxParams, 0, sizeof(*cctxParams)); + cctxParams->cParams = params->cParams; + cctxParams->fParams = params->fParams; + /* Should not matter, as all cParams are presumed properly defined. + * But, set it for tracing anyway. + */ + cctxParams->compressionLevel = compressionLevel; + cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, ¶ms->cParams); + cctxParams->postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->postBlockSplitter, ¶ms->cParams); + cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, ¶ms->cParams); + cctxParams->validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams->validateSequences); + cctxParams->maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams->maxBlockSize); + cctxParams->searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams->searchForExternalRepcodes, compressionLevel); + DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d", + cctxParams->useRowMatchFinder, cctxParams->postBlockSplitter, cctxParams->ldmParams.enableLdm); +} + +size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params) +{ + RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!"); + FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , ""); + ZSTD_CCtxParams_init_internal(cctxParams, ¶ms, ZSTD_NO_CLEVEL); + return 0; +} + +ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) +{ + ZSTD_bounds bounds = { 0, 0, 0 }; + + switch(param) + { + case ZSTD_c_compressionLevel: + bounds.lowerBound = ZSTD_minCLevel(); + bounds.upperBound = ZSTD_maxCLevel(); + return bounds; + + case ZSTD_c_windowLog: + bounds.lowerBound = ZSTD_WINDOWLOG_MIN; + bounds.upperBound = ZSTD_WINDOWLOG_MAX; + return bounds; + + case ZSTD_c_hashLog: + bounds.lowerBound = ZSTD_HASHLOG_MIN; + bounds.upperBound = ZSTD_HASHLOG_MAX; + return bounds; + + case ZSTD_c_chainLog: + bounds.lowerBound = ZSTD_CHAINLOG_MIN; + bounds.upperBound = ZSTD_CHAINLOG_MAX; + return bounds; + + case ZSTD_c_searchLog: + bounds.lowerBound = ZSTD_SEARCHLOG_MIN; + bounds.upperBound = ZSTD_SEARCHLOG_MAX; + return bounds; + + case ZSTD_c_minMatch: + bounds.lowerBound = ZSTD_MINMATCH_MIN; + bounds.upperBound = ZSTD_MINMATCH_MAX; + return bounds; + + case ZSTD_c_targetLength: + bounds.lowerBound = ZSTD_TARGETLENGTH_MIN; + bounds.upperBound = ZSTD_TARGETLENGTH_MAX; + return bounds; + + case ZSTD_c_strategy: + bounds.lowerBound = ZSTD_STRATEGY_MIN; + bounds.upperBound = ZSTD_STRATEGY_MAX; + return bounds; + + case ZSTD_c_contentSizeFlag: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_checksumFlag: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_dictIDFlag: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_nbWorkers: + bounds.lowerBound = 0; +#ifdef ZSTD_MULTITHREAD + bounds.upperBound = ZSTDMT_NBWORKERS_MAX; +#else + bounds.upperBound = 0; +#endif + return bounds; + + case ZSTD_c_jobSize: + bounds.lowerBound = 0; +#ifdef ZSTD_MULTITHREAD + bounds.upperBound = ZSTDMT_JOBSIZE_MAX; +#else + bounds.upperBound = 0; +#endif + return bounds; + + case ZSTD_c_overlapLog: +#ifdef ZSTD_MULTITHREAD + bounds.lowerBound = ZSTD_OVERLAPLOG_MIN; + bounds.upperBound = ZSTD_OVERLAPLOG_MAX; +#else + bounds.lowerBound = 0; + bounds.upperBound = 0; +#endif + return bounds; + + case ZSTD_c_enableDedicatedDictSearch: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_enableLongDistanceMatching: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_ldmHashLog: + bounds.lowerBound = ZSTD_LDM_HASHLOG_MIN; + bounds.upperBound = ZSTD_LDM_HASHLOG_MAX; + return bounds; + + case ZSTD_c_ldmMinMatch: + bounds.lowerBound = ZSTD_LDM_MINMATCH_MIN; + bounds.upperBound = ZSTD_LDM_MINMATCH_MAX; + return bounds; + + case ZSTD_c_ldmBucketSizeLog: + bounds.lowerBound = ZSTD_LDM_BUCKETSIZELOG_MIN; + bounds.upperBound = ZSTD_LDM_BUCKETSIZELOG_MAX; + return bounds; + + case ZSTD_c_ldmHashRateLog: + bounds.lowerBound = ZSTD_LDM_HASHRATELOG_MIN; + bounds.upperBound = ZSTD_LDM_HASHRATELOG_MAX; + return bounds; + + /* experimental parameters */ + case ZSTD_c_rsyncable: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_forceMaxWindow : + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_format: + ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless); + bounds.lowerBound = ZSTD_f_zstd1; + bounds.upperBound = ZSTD_f_zstd1_magicless; /* note : how to ensure at compile time that this is the highest value enum ? */ + return bounds; + + case ZSTD_c_forceAttachDict: + ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceLoad); + bounds.lowerBound = ZSTD_dictDefaultAttach; + bounds.upperBound = ZSTD_dictForceLoad; /* note : how to ensure at compile time that this is the highest value enum ? */ + return bounds; + + case ZSTD_c_literalCompressionMode: + ZSTD_STATIC_ASSERT(ZSTD_ps_auto < ZSTD_ps_enable && ZSTD_ps_enable < ZSTD_ps_disable); + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_targetCBlockSize: + bounds.lowerBound = ZSTD_TARGETCBLOCKSIZE_MIN; + bounds.upperBound = ZSTD_TARGETCBLOCKSIZE_MAX; + return bounds; + + case ZSTD_c_srcSizeHint: + bounds.lowerBound = ZSTD_SRCSIZEHINT_MIN; + bounds.upperBound = ZSTD_SRCSIZEHINT_MAX; + return bounds; + + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + bounds.lowerBound = (int)ZSTD_bm_buffered; + bounds.upperBound = (int)ZSTD_bm_stable; + return bounds; + + case ZSTD_c_blockDelimiters: + bounds.lowerBound = (int)ZSTD_sf_noBlockDelimiters; + bounds.upperBound = (int)ZSTD_sf_explicitBlockDelimiters; + return bounds; + + case ZSTD_c_validateSequences: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_splitAfterSequences: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_blockSplitterLevel: + bounds.lowerBound = 0; + bounds.upperBound = ZSTD_BLOCKSPLITTER_LEVEL_MAX; + return bounds; + + case ZSTD_c_useRowMatchFinder: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_deterministicRefPrefix: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_prefetchCDictTables: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_enableSeqProducerFallback: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_maxBlockSize: + bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN; + bounds.upperBound = ZSTD_BLOCKSIZE_MAX; + return bounds; + + case ZSTD_c_repcodeResolution: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + default: + bounds.error = ERROR(parameter_unsupported); + return bounds; + } +} + +/* ZSTD_cParam_clampBounds: + * Clamps the value into the bounded range. + */ +static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value) +{ + ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); + if (ZSTD_isError(bounds.error)) return bounds.error; + if (*value < bounds.lowerBound) *value = bounds.lowerBound; + if (*value > bounds.upperBound) *value = bounds.upperBound; + return 0; +} + +#define BOUNDCHECK(cParam, val) \ + do { \ + RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \ + parameter_outOfBound, "Param out of bounds"); \ + } while (0) + + +static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) +{ + switch(param) + { + case ZSTD_c_compressionLevel: + case ZSTD_c_hashLog: + case ZSTD_c_chainLog: + case ZSTD_c_searchLog: + case ZSTD_c_minMatch: + case ZSTD_c_targetLength: + case ZSTD_c_strategy: + case ZSTD_c_blockSplitterLevel: + return 1; + + case ZSTD_c_format: + case ZSTD_c_windowLog: + case ZSTD_c_contentSizeFlag: + case ZSTD_c_checksumFlag: + case ZSTD_c_dictIDFlag: + case ZSTD_c_forceMaxWindow : + case ZSTD_c_nbWorkers: + case ZSTD_c_jobSize: + case ZSTD_c_overlapLog: + case ZSTD_c_rsyncable: + case ZSTD_c_enableDedicatedDictSearch: + case ZSTD_c_enableLongDistanceMatching: + case ZSTD_c_ldmHashLog: + case ZSTD_c_ldmMinMatch: + case ZSTD_c_ldmBucketSizeLog: + case ZSTD_c_ldmHashRateLog: + case ZSTD_c_forceAttachDict: + case ZSTD_c_literalCompressionMode: + case ZSTD_c_targetCBlockSize: + case ZSTD_c_srcSizeHint: + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + case ZSTD_c_blockDelimiters: + case ZSTD_c_validateSequences: + case ZSTD_c_splitAfterSequences: + case ZSTD_c_useRowMatchFinder: + case ZSTD_c_deterministicRefPrefix: + case ZSTD_c_prefetchCDictTables: + case ZSTD_c_enableSeqProducerFallback: + case ZSTD_c_maxBlockSize: + case ZSTD_c_repcodeResolution: + default: + return 0; + } +} + +size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value) +{ + DEBUGLOG(4, "ZSTD_CCtx_setParameter (%i, %i)", (int)param, value); + if (cctx->streamStage != zcss_init) { + if (ZSTD_isUpdateAuthorized(param)) { + cctx->cParamsChanged = 1; + } else { + RETURN_ERROR(stage_wrong, "can only set params in cctx init stage"); + } } + + switch(param) + { + case ZSTD_c_nbWorkers: + RETURN_ERROR_IF((value!=0) && cctx->staticSize, parameter_unsupported, + "MT not compatible with static alloc"); + break; + + case ZSTD_c_compressionLevel: + case ZSTD_c_windowLog: + case ZSTD_c_hashLog: + case ZSTD_c_chainLog: + case ZSTD_c_searchLog: + case ZSTD_c_minMatch: + case ZSTD_c_targetLength: + case ZSTD_c_strategy: + case ZSTD_c_ldmHashRateLog: + case ZSTD_c_format: + case ZSTD_c_contentSizeFlag: + case ZSTD_c_checksumFlag: + case ZSTD_c_dictIDFlag: + case ZSTD_c_forceMaxWindow: + case ZSTD_c_forceAttachDict: + case ZSTD_c_literalCompressionMode: + case ZSTD_c_jobSize: + case ZSTD_c_overlapLog: + case ZSTD_c_rsyncable: + case ZSTD_c_enableDedicatedDictSearch: + case ZSTD_c_enableLongDistanceMatching: + case ZSTD_c_ldmHashLog: + case ZSTD_c_ldmMinMatch: + case ZSTD_c_ldmBucketSizeLog: + case ZSTD_c_targetCBlockSize: + case ZSTD_c_srcSizeHint: + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + case ZSTD_c_blockDelimiters: + case ZSTD_c_validateSequences: + case ZSTD_c_splitAfterSequences: + case ZSTD_c_blockSplitterLevel: + case ZSTD_c_useRowMatchFinder: + case ZSTD_c_deterministicRefPrefix: + case ZSTD_c_prefetchCDictTables: + case ZSTD_c_enableSeqProducerFallback: + case ZSTD_c_maxBlockSize: + case ZSTD_c_repcodeResolution: + break; + + default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); + } + return ZSTD_CCtxParams_setParameter(&cctx->requestedParams, param, value); +} + +size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, + ZSTD_cParameter param, int value) +{ + DEBUGLOG(4, "ZSTD_CCtxParams_setParameter (%i, %i)", (int)param, value); + switch(param) + { + case ZSTD_c_format : + BOUNDCHECK(ZSTD_c_format, value); + CCtxParams->format = (ZSTD_format_e)value; + return (size_t)CCtxParams->format; + + case ZSTD_c_compressionLevel : { + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); + if (value == 0) + CCtxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default */ + else + CCtxParams->compressionLevel = value; + if (CCtxParams->compressionLevel >= 0) return (size_t)CCtxParams->compressionLevel; + return 0; /* return type (size_t) cannot represent negative values */ + } + + case ZSTD_c_windowLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_windowLog, value); + CCtxParams->cParams.windowLog = (U32)value; + return CCtxParams->cParams.windowLog; + + case ZSTD_c_hashLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_hashLog, value); + CCtxParams->cParams.hashLog = (U32)value; + return CCtxParams->cParams.hashLog; + + case ZSTD_c_chainLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_chainLog, value); + CCtxParams->cParams.chainLog = (U32)value; + return CCtxParams->cParams.chainLog; + + case ZSTD_c_searchLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_searchLog, value); + CCtxParams->cParams.searchLog = (U32)value; + return (size_t)value; + + case ZSTD_c_minMatch : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_minMatch, value); + CCtxParams->cParams.minMatch = (U32)value; + return CCtxParams->cParams.minMatch; + + case ZSTD_c_targetLength : + BOUNDCHECK(ZSTD_c_targetLength, value); + CCtxParams->cParams.targetLength = (U32)value; + return CCtxParams->cParams.targetLength; + + case ZSTD_c_strategy : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_strategy, value); + CCtxParams->cParams.strategy = (ZSTD_strategy)value; + return (size_t)CCtxParams->cParams.strategy; + + case ZSTD_c_contentSizeFlag : + /* Content size written in frame header _when known_ (default:1) */ + DEBUGLOG(4, "set content size flag = %u", (value!=0)); + CCtxParams->fParams.contentSizeFlag = value != 0; + return (size_t)CCtxParams->fParams.contentSizeFlag; + + case ZSTD_c_checksumFlag : + /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */ + CCtxParams->fParams.checksumFlag = value != 0; + return (size_t)CCtxParams->fParams.checksumFlag; + + case ZSTD_c_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */ + DEBUGLOG(4, "set dictIDFlag = %u", (value!=0)); + CCtxParams->fParams.noDictIDFlag = !value; + return !CCtxParams->fParams.noDictIDFlag; + + case ZSTD_c_forceMaxWindow : + CCtxParams->forceWindow = (value != 0); + return (size_t)CCtxParams->forceWindow; + + case ZSTD_c_forceAttachDict : { + const ZSTD_dictAttachPref_e pref = (ZSTD_dictAttachPref_e)value; + BOUNDCHECK(ZSTD_c_forceAttachDict, (int)pref); + CCtxParams->attachDictPref = pref; + return CCtxParams->attachDictPref; + } + + case ZSTD_c_literalCompressionMode : { + const ZSTD_ParamSwitch_e lcm = (ZSTD_ParamSwitch_e)value; + BOUNDCHECK(ZSTD_c_literalCompressionMode, (int)lcm); + CCtxParams->literalCompressionMode = lcm; + return CCtxParams->literalCompressionMode; + } + + case ZSTD_c_nbWorkers : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); + CCtxParams->nbWorkers = value; + return (size_t)(CCtxParams->nbWorkers); +#endif + + case ZSTD_c_jobSize : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + /* Adjust to the minimum non-default value. */ + if (value != 0 && value < ZSTDMT_JOBSIZE_MIN) + value = ZSTDMT_JOBSIZE_MIN; + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); + assert(value >= 0); + CCtxParams->jobSize = (size_t)value; + return CCtxParams->jobSize; +#endif + + case ZSTD_c_overlapLog : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), ""); + CCtxParams->overlapLog = value; + return (size_t)CCtxParams->overlapLog; +#endif + + case ZSTD_c_rsyncable : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), ""); + CCtxParams->rsyncable = value; + return (size_t)CCtxParams->rsyncable; +#endif + + case ZSTD_c_enableDedicatedDictSearch : + CCtxParams->enableDedicatedDictSearch = (value!=0); + return (size_t)CCtxParams->enableDedicatedDictSearch; + + case ZSTD_c_enableLongDistanceMatching : + BOUNDCHECK(ZSTD_c_enableLongDistanceMatching, value); + CCtxParams->ldmParams.enableLdm = (ZSTD_ParamSwitch_e)value; + return CCtxParams->ldmParams.enableLdm; + + case ZSTD_c_ldmHashLog : + if (value!=0) /* 0 ==> auto */ + BOUNDCHECK(ZSTD_c_ldmHashLog, value); + CCtxParams->ldmParams.hashLog = (U32)value; + return CCtxParams->ldmParams.hashLog; + + case ZSTD_c_ldmMinMatch : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_ldmMinMatch, value); + CCtxParams->ldmParams.minMatchLength = (U32)value; + return CCtxParams->ldmParams.minMatchLength; + + case ZSTD_c_ldmBucketSizeLog : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_ldmBucketSizeLog, value); + CCtxParams->ldmParams.bucketSizeLog = (U32)value; + return CCtxParams->ldmParams.bucketSizeLog; + + case ZSTD_c_ldmHashRateLog : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_ldmHashRateLog, value); + CCtxParams->ldmParams.hashRateLog = (U32)value; + return CCtxParams->ldmParams.hashRateLog; + + case ZSTD_c_targetCBlockSize : + if (value!=0) { /* 0 ==> default */ + value = MAX(value, ZSTD_TARGETCBLOCKSIZE_MIN); + BOUNDCHECK(ZSTD_c_targetCBlockSize, value); + } + CCtxParams->targetCBlockSize = (U32)value; + return CCtxParams->targetCBlockSize; + + case ZSTD_c_srcSizeHint : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_srcSizeHint, value); + CCtxParams->srcSizeHint = value; + return (size_t)CCtxParams->srcSizeHint; + + case ZSTD_c_stableInBuffer: + BOUNDCHECK(ZSTD_c_stableInBuffer, value); + CCtxParams->inBufferMode = (ZSTD_bufferMode_e)value; + return CCtxParams->inBufferMode; + + case ZSTD_c_stableOutBuffer: + BOUNDCHECK(ZSTD_c_stableOutBuffer, value); + CCtxParams->outBufferMode = (ZSTD_bufferMode_e)value; + return CCtxParams->outBufferMode; + + case ZSTD_c_blockDelimiters: + BOUNDCHECK(ZSTD_c_blockDelimiters, value); + CCtxParams->blockDelimiters = (ZSTD_SequenceFormat_e)value; + return CCtxParams->blockDelimiters; + + case ZSTD_c_validateSequences: + BOUNDCHECK(ZSTD_c_validateSequences, value); + CCtxParams->validateSequences = value; + return (size_t)CCtxParams->validateSequences; + + case ZSTD_c_splitAfterSequences: + BOUNDCHECK(ZSTD_c_splitAfterSequences, value); + CCtxParams->postBlockSplitter = (ZSTD_ParamSwitch_e)value; + return CCtxParams->postBlockSplitter; + + case ZSTD_c_blockSplitterLevel: + BOUNDCHECK(ZSTD_c_blockSplitterLevel, value); + CCtxParams->preBlockSplitter_level = value; + return (size_t)CCtxParams->preBlockSplitter_level; + + case ZSTD_c_useRowMatchFinder: + BOUNDCHECK(ZSTD_c_useRowMatchFinder, value); + CCtxParams->useRowMatchFinder = (ZSTD_ParamSwitch_e)value; + return CCtxParams->useRowMatchFinder; + + case ZSTD_c_deterministicRefPrefix: + BOUNDCHECK(ZSTD_c_deterministicRefPrefix, value); + CCtxParams->deterministicRefPrefix = !!value; + return (size_t)CCtxParams->deterministicRefPrefix; + + case ZSTD_c_prefetchCDictTables: + BOUNDCHECK(ZSTD_c_prefetchCDictTables, value); + CCtxParams->prefetchCDictTables = (ZSTD_ParamSwitch_e)value; + return CCtxParams->prefetchCDictTables; + + case ZSTD_c_enableSeqProducerFallback: + BOUNDCHECK(ZSTD_c_enableSeqProducerFallback, value); + CCtxParams->enableMatchFinderFallback = value; + return (size_t)CCtxParams->enableMatchFinderFallback; + + case ZSTD_c_maxBlockSize: + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_maxBlockSize, value); + assert(value>=0); + CCtxParams->maxBlockSize = (size_t)value; + return CCtxParams->maxBlockSize; + + case ZSTD_c_repcodeResolution: + BOUNDCHECK(ZSTD_c_repcodeResolution, value); + CCtxParams->searchForExternalRepcodes = (ZSTD_ParamSwitch_e)value; + return CCtxParams->searchForExternalRepcodes; + + default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); + } +} + +size_t ZSTD_CCtx_getParameter(ZSTD_CCtx const* cctx, ZSTD_cParameter param, int* value) +{ + return ZSTD_CCtxParams_getParameter(&cctx->requestedParams, param, value); +} + +size_t ZSTD_CCtxParams_getParameter( + ZSTD_CCtx_params const* CCtxParams, ZSTD_cParameter param, int* value) +{ + switch(param) + { + case ZSTD_c_format : + *value = (int)CCtxParams->format; + break; + case ZSTD_c_compressionLevel : + *value = CCtxParams->compressionLevel; + break; + case ZSTD_c_windowLog : + *value = (int)CCtxParams->cParams.windowLog; + break; + case ZSTD_c_hashLog : + *value = (int)CCtxParams->cParams.hashLog; + break; + case ZSTD_c_chainLog : + *value = (int)CCtxParams->cParams.chainLog; + break; + case ZSTD_c_searchLog : + *value = (int)CCtxParams->cParams.searchLog; + break; + case ZSTD_c_minMatch : + *value = (int)CCtxParams->cParams.minMatch; + break; + case ZSTD_c_targetLength : + *value = (int)CCtxParams->cParams.targetLength; + break; + case ZSTD_c_strategy : + *value = (int)CCtxParams->cParams.strategy; + break; + case ZSTD_c_contentSizeFlag : + *value = CCtxParams->fParams.contentSizeFlag; + break; + case ZSTD_c_checksumFlag : + *value = CCtxParams->fParams.checksumFlag; + break; + case ZSTD_c_dictIDFlag : + *value = !CCtxParams->fParams.noDictIDFlag; + break; + case ZSTD_c_forceMaxWindow : + *value = CCtxParams->forceWindow; + break; + case ZSTD_c_forceAttachDict : + *value = (int)CCtxParams->attachDictPref; + break; + case ZSTD_c_literalCompressionMode : + *value = (int)CCtxParams->literalCompressionMode; + break; + case ZSTD_c_nbWorkers : +#ifndef ZSTD_MULTITHREAD + assert(CCtxParams->nbWorkers == 0); +#endif + *value = CCtxParams->nbWorkers; + break; + case ZSTD_c_jobSize : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR(parameter_unsupported, "not compiled with multithreading"); +#else + assert(CCtxParams->jobSize <= INT_MAX); + *value = (int)CCtxParams->jobSize; + break; +#endif + case ZSTD_c_overlapLog : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR(parameter_unsupported, "not compiled with multithreading"); +#else + *value = CCtxParams->overlapLog; + break; +#endif + case ZSTD_c_rsyncable : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR(parameter_unsupported, "not compiled with multithreading"); +#else + *value = CCtxParams->rsyncable; + break; +#endif + case ZSTD_c_enableDedicatedDictSearch : + *value = CCtxParams->enableDedicatedDictSearch; + break; + case ZSTD_c_enableLongDistanceMatching : + *value = (int)CCtxParams->ldmParams.enableLdm; + break; + case ZSTD_c_ldmHashLog : + *value = (int)CCtxParams->ldmParams.hashLog; + break; + case ZSTD_c_ldmMinMatch : + *value = (int)CCtxParams->ldmParams.minMatchLength; + break; + case ZSTD_c_ldmBucketSizeLog : + *value = (int)CCtxParams->ldmParams.bucketSizeLog; + break; + case ZSTD_c_ldmHashRateLog : + *value = (int)CCtxParams->ldmParams.hashRateLog; + break; + case ZSTD_c_targetCBlockSize : + *value = (int)CCtxParams->targetCBlockSize; + break; + case ZSTD_c_srcSizeHint : + *value = (int)CCtxParams->srcSizeHint; + break; + case ZSTD_c_stableInBuffer : + *value = (int)CCtxParams->inBufferMode; + break; + case ZSTD_c_stableOutBuffer : + *value = (int)CCtxParams->outBufferMode; + break; + case ZSTD_c_blockDelimiters : + *value = (int)CCtxParams->blockDelimiters; + break; + case ZSTD_c_validateSequences : + *value = (int)CCtxParams->validateSequences; + break; + case ZSTD_c_splitAfterSequences : + *value = (int)CCtxParams->postBlockSplitter; + break; + case ZSTD_c_blockSplitterLevel : + *value = CCtxParams->preBlockSplitter_level; + break; + case ZSTD_c_useRowMatchFinder : + *value = (int)CCtxParams->useRowMatchFinder; + break; + case ZSTD_c_deterministicRefPrefix: + *value = (int)CCtxParams->deterministicRefPrefix; + break; + case ZSTD_c_prefetchCDictTables: + *value = (int)CCtxParams->prefetchCDictTables; + break; + case ZSTD_c_enableSeqProducerFallback: + *value = CCtxParams->enableMatchFinderFallback; + break; + case ZSTD_c_maxBlockSize: + *value = (int)CCtxParams->maxBlockSize; + break; + case ZSTD_c_repcodeResolution: + *value = (int)CCtxParams->searchForExternalRepcodes; + break; + default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); + } + return 0; +} + +/** ZSTD_CCtx_setParametersUsingCCtxParams() : + * just applies `params` into `cctx` + * no action is performed, parameters are merely stored. + * If ZSTDMT is enabled, parameters are pushed to cctx->mtctx. + * This is possible even if a compression is ongoing. + * In which case, new parameters will be applied on the fly, starting with next compression job. + */ +size_t ZSTD_CCtx_setParametersUsingCCtxParams( + ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params) +{ + DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams"); + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "The context is in the wrong stage!"); + RETURN_ERROR_IF(cctx->cdict, stage_wrong, + "Can't override parameters with cdict attached (some must " + "be inherited from the cdict)."); + + cctx->requestedParams = *params; + return 0; +} + +size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams) +{ + ZSTD_STATIC_ASSERT(sizeof(cparams) == 7 * 4 /* all params are listed below */); + DEBUGLOG(4, "ZSTD_CCtx_setCParams"); + /* only update if all parameters are valid */ + FORWARD_IF_ERROR(ZSTD_checkCParams(cparams), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, (int)cparams.windowLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, (int)cparams.chainLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, (int)cparams.hashLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, (int)cparams.searchLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, (int)cparams.minMatch), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, (int)cparams.targetLength), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, (int)cparams.strategy), ""); + return 0; +} + +size_t ZSTD_CCtx_setFParams(ZSTD_CCtx* cctx, ZSTD_frameParameters fparams) +{ + ZSTD_STATIC_ASSERT(sizeof(fparams) == 3 * 4 /* all params are listed below */); + DEBUGLOG(4, "ZSTD_CCtx_setFParams"); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, fparams.contentSizeFlag != 0), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, fparams.checksumFlag != 0), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, fparams.noDictIDFlag == 0), ""); + return 0; +} + +size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params) +{ + DEBUGLOG(4, "ZSTD_CCtx_setParams"); + /* First check cParams, because we want to update all or none. */ + FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); + /* Next set fParams, because this could fail if the cctx isn't in init stage. */ + FORWARD_IF_ERROR(ZSTD_CCtx_setFParams(cctx, params.fParams), ""); + /* Finally set cParams, which should succeed. */ + FORWARD_IF_ERROR(ZSTD_CCtx_setCParams(cctx, params.cParams), ""); + return 0; +} + +size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize) +{ + DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %llu bytes", pledgedSrcSize); + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't set pledgedSrcSize when not in init stage."); + cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1; + return 0; +} + +static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams( + int const compressionLevel, + size_t const dictSize); +static int ZSTD_dedicatedDictSearch_isSupported( + const ZSTD_compressionParameters* cParams); +static void ZSTD_dedicatedDictSearch_revertCParams( + ZSTD_compressionParameters* cParams); + +size_t ZSTD_CCtx_loadDictionary_advanced( + ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize); + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't load a dictionary when cctx is not in init stage."); + ZSTD_clearAllDicts(cctx); /* erase any previously set dictionary */ + if (dict == NULL || dictSize == 0) /* no dictionary */ + return 0; + if (dictLoadMethod == ZSTD_dlm_byRef) { + cctx->localDict.dict = dict; + } else { + /* copy dictionary content inside CCtx to own its lifetime */ + void* dictBuffer; + RETURN_ERROR_IF(cctx->staticSize, memory_allocation, + "static CCtx can't allocate for an internal copy of dictionary"); + dictBuffer = ZSTD_customMalloc(dictSize, cctx->customMem); + RETURN_ERROR_IF(dictBuffer==NULL, memory_allocation, + "allocation failed for dictionary content"); + ZSTD_memcpy(dictBuffer, dict, dictSize); + cctx->localDict.dictBuffer = dictBuffer; /* owned ptr to free */ + cctx->localDict.dict = dictBuffer; /* read-only reference */ + } + cctx->localDict.dictSize = dictSize; + cctx->localDict.dictContentType = dictContentType; + return 0; +} + +size_t ZSTD_CCtx_loadDictionary_byReference( + ZSTD_CCtx* cctx, const void* dict, size_t dictSize) +{ + return ZSTD_CCtx_loadDictionary_advanced( + cctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto); +} + +size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize) +{ + return ZSTD_CCtx_loadDictionary_advanced( + cctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto); +} + +size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't ref a dict when ctx not in init stage."); + /* Free the existing local cdict (if any) to save memory. */ + ZSTD_clearAllDicts(cctx); + cctx->cdict = cdict; + return 0; +} + +size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool) +{ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't ref a pool when ctx not in init stage."); + cctx->pool = pool; + return 0; +} + +size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize) +{ + return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, ZSTD_dct_rawContent); +} + +size_t ZSTD_CCtx_refPrefix_advanced( + ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType) +{ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't ref a prefix when ctx not in init stage."); + ZSTD_clearAllDicts(cctx); + if (prefix != NULL && prefixSize > 0) { + cctx->prefixDict.dict = prefix; + cctx->prefixDict.dictSize = prefixSize; + cctx->prefixDict.dictContentType = dictContentType; + } + return 0; +} + +/*! ZSTD_CCtx_reset() : + * Also dumps dictionary */ +size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset) +{ + if ( (reset == ZSTD_reset_session_only) + || (reset == ZSTD_reset_session_and_parameters) ) { + cctx->streamStage = zcss_init; + cctx->pledgedSrcSizePlusOne = 0; + } + if ( (reset == ZSTD_reset_parameters) + || (reset == ZSTD_reset_session_and_parameters) ) { + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Reset parameters is only possible during init stage."); + ZSTD_clearAllDicts(cctx); + return ZSTD_CCtxParams_reset(&cctx->requestedParams); + } + return 0; +} + + +/** ZSTD_checkCParams() : + control CParam values remain within authorized range. + @return : 0, or an error code if one value is beyond authorized range */ +size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) +{ + BOUNDCHECK(ZSTD_c_windowLog, (int)cParams.windowLog); + BOUNDCHECK(ZSTD_c_chainLog, (int)cParams.chainLog); + BOUNDCHECK(ZSTD_c_hashLog, (int)cParams.hashLog); + BOUNDCHECK(ZSTD_c_searchLog, (int)cParams.searchLog); + BOUNDCHECK(ZSTD_c_minMatch, (int)cParams.minMatch); + BOUNDCHECK(ZSTD_c_targetLength,(int)cParams.targetLength); + BOUNDCHECK(ZSTD_c_strategy, (int)cParams.strategy); + return 0; +} + +/** ZSTD_clampCParams() : + * make CParam values within valid range. + * @return : valid CParams */ +static ZSTD_compressionParameters +ZSTD_clampCParams(ZSTD_compressionParameters cParams) +{ +# define CLAMP_TYPE(cParam, val, type) \ + do { \ + ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); \ + if ((int)valbounds.upperBound) val=(type)bounds.upperBound; \ + } while (0) +# define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, unsigned) + CLAMP(ZSTD_c_windowLog, cParams.windowLog); + CLAMP(ZSTD_c_chainLog, cParams.chainLog); + CLAMP(ZSTD_c_hashLog, cParams.hashLog); + CLAMP(ZSTD_c_searchLog, cParams.searchLog); + CLAMP(ZSTD_c_minMatch, cParams.minMatch); + CLAMP(ZSTD_c_targetLength,cParams.targetLength); + CLAMP_TYPE(ZSTD_c_strategy,cParams.strategy, ZSTD_strategy); + return cParams; +} + +/** ZSTD_cycleLog() : + * condition for correct operation : hashLog > 1 */ +U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) +{ + U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2); + return hashLog - btScale; +} + +/** ZSTD_dictAndWindowLog() : + * Returns an adjusted window log that is large enough to fit the source and the dictionary. + * The zstd format says that the entire dictionary is valid if one byte of the dictionary + * is within the window. So the hashLog and chainLog should be large enough to reference both + * the dictionary and the window. So we must use this adjusted dictAndWindowLog when downsizing + * the hashLog and windowLog. + * NOTE: srcSize must not be ZSTD_CONTENTSIZE_UNKNOWN. + */ +static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize) +{ + const U64 maxWindowSize = 1ULL << ZSTD_WINDOWLOG_MAX; + /* No dictionary ==> No change */ + if (dictSize == 0) { + return windowLog; + } + assert(windowLog <= ZSTD_WINDOWLOG_MAX); + assert(srcSize != ZSTD_CONTENTSIZE_UNKNOWN); /* Handled in ZSTD_adjustCParams_internal() */ + { + U64 const windowSize = 1ULL << windowLog; + U64 const dictAndWindowSize = dictSize + windowSize; + /* If the window size is already large enough to fit both the source and the dictionary + * then just use the window size. Otherwise adjust so that it fits the dictionary and + * the window. + */ + if (windowSize >= dictSize + srcSize) { + return windowLog; /* Window size large enough already */ + } else if (dictAndWindowSize >= maxWindowSize) { + return ZSTD_WINDOWLOG_MAX; /* Larger than max window log */ + } else { + return ZSTD_highbit32((U32)dictAndWindowSize - 1) + 1; + } + } +} + +/** ZSTD_adjustCParams_internal() : + * optimize `cPar` for a specified input (`srcSize` and `dictSize`). + * mostly downsize to reduce memory consumption and initialization latency. + * `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known. + * `mode` is the mode for parameter adjustment. See docs for `ZSTD_CParamMode_e`. + * note : `srcSize==0` means 0! + * condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */ +static ZSTD_compressionParameters +ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, + unsigned long long srcSize, + size_t dictSize, + ZSTD_CParamMode_e mode, + ZSTD_ParamSwitch_e useRowMatchFinder) +{ + const U64 minSrcSize = 513; /* (1<<9) + 1 */ + const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1); + assert(ZSTD_checkCParams(cPar)==0); + + /* Cascade the selected strategy down to the next-highest one built into + * this binary. */ +#ifdef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btultra2) { + cPar.strategy = ZSTD_btultra; + } + if (cPar.strategy == ZSTD_btultra) { + cPar.strategy = ZSTD_btopt; + } +#endif +#ifdef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btopt) { + cPar.strategy = ZSTD_btlazy2; + } +#endif +#ifdef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btlazy2) { + cPar.strategy = ZSTD_lazy2; + } +#endif +#ifdef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_lazy2) { + cPar.strategy = ZSTD_lazy; + } +#endif +#ifdef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_lazy) { + cPar.strategy = ZSTD_greedy; + } +#endif +#ifdef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_greedy) { + cPar.strategy = ZSTD_dfast; + } +#endif +#ifdef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_dfast) { + cPar.strategy = ZSTD_fast; + cPar.targetLength = 0; + } +#endif + + switch (mode) { + case ZSTD_cpm_unknown: + case ZSTD_cpm_noAttachDict: + /* If we don't know the source size, don't make any + * assumptions about it. We will already have selected + * smaller parameters if a dictionary is in use. + */ + break; + case ZSTD_cpm_createCDict: + /* Assume a small source size when creating a dictionary + * with an unknown source size. + */ + if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN) + srcSize = minSrcSize; + break; + case ZSTD_cpm_attachDict: + /* Dictionary has its own dedicated parameters which have + * already been selected. We are selecting parameters + * for only the source. + */ + dictSize = 0; + break; + default: + assert(0); + break; + } + + /* resize windowLog if input is small enough, to use less memory */ + if ( (srcSize <= maxWindowResize) + && (dictSize <= maxWindowResize) ) { + U32 const tSize = (U32)(srcSize + dictSize); + static U32 const hashSizeMin = 1 << ZSTD_HASHLOG_MIN; + U32 const srcLog = (tSize < hashSizeMin) ? ZSTD_HASHLOG_MIN : + ZSTD_highbit32(tSize-1) + 1; + if (cPar.windowLog > srcLog) cPar.windowLog = srcLog; + } + if (srcSize != ZSTD_CONTENTSIZE_UNKNOWN) { + U32 const dictAndWindowLog = ZSTD_dictAndWindowLog(cPar.windowLog, (U64)srcSize, (U64)dictSize); + U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy); + if (cPar.hashLog > dictAndWindowLog+1) cPar.hashLog = dictAndWindowLog+1; + if (cycleLog > dictAndWindowLog) + cPar.chainLog -= (cycleLog - dictAndWindowLog); + } + + if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) + cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* minimum wlog required for valid frame header */ + + /* We can't use more than 32 bits of hash in total, so that means that we require: + * (hashLog + 8) <= 32 && (chainLog + 8) <= 32 + */ + if (mode == ZSTD_cpm_createCDict && ZSTD_CDictIndicesAreTagged(&cPar)) { + U32 const maxShortCacheHashLog = 32 - ZSTD_SHORT_CACHE_TAG_BITS; + if (cPar.hashLog > maxShortCacheHashLog) { + cPar.hashLog = maxShortCacheHashLog; + } + if (cPar.chainLog > maxShortCacheHashLog) { + cPar.chainLog = maxShortCacheHashLog; + } + } + + + /* At this point, we aren't 100% sure if we are using the row match finder. + * Unless it is explicitly disabled, conservatively assume that it is enabled. + * In this case it will only be disabled for small sources, so shrinking the + * hash log a little bit shouldn't result in any ratio loss. + */ + if (useRowMatchFinder == ZSTD_ps_auto) + useRowMatchFinder = ZSTD_ps_enable; + + /* We can't hash more than 32-bits in total. So that means that we require: + * (hashLog - rowLog + 8) <= 32 + */ + if (ZSTD_rowMatchFinderUsed(cPar.strategy, useRowMatchFinder)) { + /* Switch to 32-entry rows if searchLog is 5 (or more) */ + U32 const rowLog = BOUNDED(4, cPar.searchLog, 6); + U32 const maxRowHashLog = 32 - ZSTD_ROW_HASH_TAG_BITS; + U32 const maxHashLog = maxRowHashLog + rowLog; + assert(cPar.hashLog >= rowLog); + if (cPar.hashLog > maxHashLog) { + cPar.hashLog = maxHashLog; + } + } + + return cPar; +} + +ZSTD_compressionParameters +ZSTD_adjustCParams(ZSTD_compressionParameters cPar, + unsigned long long srcSize, + size_t dictSize) +{ + cPar = ZSTD_clampCParams(cPar); /* resulting cPar is necessarily valid (all parameters within range) */ + if (srcSize == 0) srcSize = ZSTD_CONTENTSIZE_UNKNOWN; + return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize, ZSTD_cpm_unknown, ZSTD_ps_auto); +} + +static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); +static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); + +static void ZSTD_overrideCParams( + ZSTD_compressionParameters* cParams, + const ZSTD_compressionParameters* overrides) +{ + if (overrides->windowLog) cParams->windowLog = overrides->windowLog; + if (overrides->hashLog) cParams->hashLog = overrides->hashLog; + if (overrides->chainLog) cParams->chainLog = overrides->chainLog; + if (overrides->searchLog) cParams->searchLog = overrides->searchLog; + if (overrides->minMatch) cParams->minMatch = overrides->minMatch; + if (overrides->targetLength) cParams->targetLength = overrides->targetLength; + if (overrides->strategy) cParams->strategy = overrides->strategy; +} + +ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( + const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + ZSTD_compressionParameters cParams; + if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) { + assert(CCtxParams->srcSizeHint>=0); + srcSizeHint = (U64)CCtxParams->srcSizeHint; + } + cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode); + if (CCtxParams->ldmParams.enableLdm == ZSTD_ps_enable) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG; + ZSTD_overrideCParams(&cParams, &CCtxParams->cParams); + assert(!ZSTD_checkCParams(cParams)); + /* srcSizeHint == 0 means 0 */ + return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize, mode, CCtxParams->useRowMatchFinder); +} + +static size_t +ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const int enableDedicatedDictSearch, + const U32 forCCtx) +{ + /* chain table size should be 0 for fast or row-hash strategies */ + size_t const chainSize = ZSTD_allocateChainTable(cParams->strategy, useRowMatchFinder, enableDedicatedDictSearch && !forCCtx) + ? ((size_t)1 << cParams->chainLog) + : 0; + size_t const hSize = ((size_t)1) << cParams->hashLog; + U32 const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; + size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0; + /* We don't use ZSTD_cwksp_alloc_size() here because the tables aren't + * surrounded by redzones in ASAN. */ + size_t const tableSpace = chainSize * sizeof(U32) + + hSize * sizeof(U32) + + h3Size * sizeof(U32); + size_t const optPotentialSpace = + ZSTD_cwksp_aligned64_alloc_size((MaxML+1) * sizeof(U32)) + + ZSTD_cwksp_aligned64_alloc_size((MaxLL+1) * sizeof(U32)) + + ZSTD_cwksp_aligned64_alloc_size((MaxOff+1) * sizeof(U32)) + + ZSTD_cwksp_aligned64_alloc_size((1<strategy, useRowMatchFinder) + ? ZSTD_cwksp_aligned64_alloc_size(hSize) + : 0; + size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt)) + ? optPotentialSpace + : 0; + size_t const slackSpace = ZSTD_cwksp_slack_space_required(); + + /* tables are guaranteed to be sized in multiples of 64 bytes (or 16 uint32_t) */ + ZSTD_STATIC_ASSERT(ZSTD_HASHLOG_MIN >= 4 && ZSTD_WINDOWLOG_MIN >= 4 && ZSTD_CHAINLOG_MIN >= 4); + assert(useRowMatchFinder != ZSTD_ps_auto); + + DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u", + (U32)chainSize, (U32)hSize, (U32)h3Size); + return tableSpace + optSpace + slackSpace + lazyAdditionalSpace; +} + +/* Helper function for calculating memory requirements. + * Gives a tighter bound than ZSTD_sequenceBound() by taking minMatch into account. */ +static size_t ZSTD_maxNbSeq(size_t blockSize, unsigned minMatch, int useSequenceProducer) { + U32 const divider = (minMatch==3 || useSequenceProducer) ? 3 : 4; + return blockSize / divider; +} + +static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( + const ZSTD_compressionParameters* cParams, + const ldmParams_t* ldmParams, + const int isStatic, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const size_t buffInSize, + const size_t buffOutSize, + const U64 pledgedSrcSize, + int useSequenceProducer, + size_t maxBlockSize) +{ + size_t const windowSize = (size_t) BOUNDED(1ULL, 1ULL << cParams->windowLog, pledgedSrcSize); + size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(maxBlockSize), windowSize); + size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, cParams->minMatch, useSequenceProducer); + size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize) + + ZSTD_cwksp_aligned64_alloc_size(maxNbSeq * sizeof(SeqDef)) + + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE)); + size_t const tmpWorkSpace = ZSTD_cwksp_alloc_size(TMP_WORKSPACE_SIZE); + size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t)); + size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 0, /* forCCtx */ 1); + + size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams); + size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize); + size_t const ldmSeqSpace = ldmParams->enableLdm == ZSTD_ps_enable ? + ZSTD_cwksp_aligned64_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0; + + + size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize) + + ZSTD_cwksp_alloc_size(buffOutSize); + + size_t const cctxSpace = isStatic ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0; + + size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize); + size_t const externalSeqSpace = useSequenceProducer + ? ZSTD_cwksp_aligned64_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence)) + : 0; + + size_t const neededSpace = + cctxSpace + + tmpWorkSpace + + blockStateSpace + + ldmSpace + + ldmSeqSpace + + matchStateSize + + tokenSpace + + bufferSpace + + externalSeqSpace; + + DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace); + return neededSpace; +} + +size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params) +{ + ZSTD_compressionParameters const cParams = + ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); + ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, + &cParams); + + RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only."); + /* estimateCCtxSize is for one-shot compression. So no buffers should + * be needed. However, we still allocate two 0-sized buffers, which can + * take space under ASAN. */ + return ZSTD_estimateCCtxSize_usingCCtxParams_internal( + &cParams, ¶ms->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize); +} + +size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams) +{ + ZSTD_CCtx_params initialParams = ZSTD_makeCCtxParamsFromCParams(cParams); + if (ZSTD_rowMatchFinderSupported(cParams.strategy)) { + /* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */ + size_t noRowCCtxSize; + size_t rowCCtxSize; + initialParams.useRowMatchFinder = ZSTD_ps_disable; + noRowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); + initialParams.useRowMatchFinder = ZSTD_ps_enable; + rowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); + return MAX(noRowCCtxSize, rowCCtxSize); + } else { + return ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); + } +} + +static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel) +{ + int tier = 0; + size_t largestSize = 0; + static const unsigned long long srcSizeTiers[4] = {16 KB, 128 KB, 256 KB, ZSTD_CONTENTSIZE_UNKNOWN}; + for (; tier < 4; ++tier) { + /* Choose the set of cParams for a given level across all srcSizes that give the largest cctxSize */ + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeTiers[tier], 0, ZSTD_cpm_noAttachDict); + largestSize = MAX(ZSTD_estimateCCtxSize_usingCParams(cParams), largestSize); + } + return largestSize; +} + +size_t ZSTD_estimateCCtxSize(int compressionLevel) +{ + int level; + size_t memBudget = 0; + for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) { + /* Ensure monotonically increasing memory usage as compression level increases */ + size_t const newMB = ZSTD_estimateCCtxSize_internal(level); + if (newMB > memBudget) memBudget = newMB; + } + return memBudget; +} + +static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1, + ZSTD_compressionParameters cParams2) +{ + (void)cParams1; + (void)cParams2; + assert(cParams1.windowLog == cParams2.windowLog); + assert(cParams1.chainLog == cParams2.chainLog); + assert(cParams1.hashLog == cParams2.hashLog); + assert(cParams1.searchLog == cParams2.searchLog); + assert(cParams1.minMatch == cParams2.minMatch); + assert(cParams1.targetLength == cParams2.targetLength); + assert(cParams1.strategy == cParams2.strategy); +} + +void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs) +{ + int i; + for (i = 0; i < ZSTD_REP_NUM; ++i) + bs->rep[i] = repStartValue[i]; + bs->entropy.huf.repeatMode = HUF_repeat_none; + bs->entropy.fse.offcode_repeatMode = FSE_repeat_none; + bs->entropy.fse.matchlength_repeatMode = FSE_repeat_none; + bs->entropy.fse.litlength_repeatMode = FSE_repeat_none; +} + +/*! ZSTD_invalidateMatchState() + * Invalidate all the matches in the match finder tables. + * Requires nextSrc and base to be set (can be NULL). + */ +static void ZSTD_invalidateMatchState(ZSTD_MatchState_t* ms) +{ + ZSTD_window_clear(&ms->window); + + ms->nextToUpdate = ms->window.dictLimit; + ms->loadedDictEnd = 0; + ms->opt.litLengthSum = 0; /* force reset of btopt stats */ + ms->dictMatchState = NULL; +} + +/** + * Controls, for this matchState reset, whether the tables need to be cleared / + * prepared for the coming compression (ZSTDcrp_makeClean), or whether the + * tables can be left unclean (ZSTDcrp_leaveDirty), because we know that a + * subsequent operation will overwrite the table space anyways (e.g., copying + * the matchState contents in from a CDict). + */ +typedef enum { + ZSTDcrp_makeClean, + ZSTDcrp_leaveDirty +} ZSTD_compResetPolicy_e; + +/** + * Controls, for this matchState reset, whether indexing can continue where it + * left off (ZSTDirp_continue), or whether it needs to be restarted from zero + * (ZSTDirp_reset). + */ +typedef enum { + ZSTDirp_continue, + ZSTDirp_reset +} ZSTD_indexResetPolicy_e; + +typedef enum { + ZSTD_resetTarget_CDict, + ZSTD_resetTarget_CCtx +} ZSTD_resetTarget_e; + +/* Mixes bits in a 64 bits in a value, based on XXH3_rrmxmx */ +static U64 ZSTD_bitmix(U64 val, U64 len) { + val ^= ZSTD_rotateRight_U64(val, 49) ^ ZSTD_rotateRight_U64(val, 24); + val *= 0x9FB21C651E98DF25ULL; + val ^= (val >> 35) + len ; + val *= 0x9FB21C651E98DF25ULL; + return val ^ (val >> 28); +} + +/* Mixes in the hashSalt and hashSaltEntropy to create a new hashSalt */ +static void ZSTD_advanceHashSalt(ZSTD_MatchState_t* ms) { + ms->hashSalt = ZSTD_bitmix(ms->hashSalt, 8) ^ ZSTD_bitmix((U64) ms->hashSaltEntropy, 4); +} + +static size_t +ZSTD_reset_matchState(ZSTD_MatchState_t* ms, + ZSTD_cwksp* ws, + const ZSTD_compressionParameters* cParams, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const ZSTD_compResetPolicy_e crp, + const ZSTD_indexResetPolicy_e forceResetIndex, + const ZSTD_resetTarget_e forWho) +{ + /* disable chain table allocation for fast or row-based strategies */ + size_t const chainSize = ZSTD_allocateChainTable(cParams->strategy, useRowMatchFinder, + ms->dedicatedDictSearch && (forWho == ZSTD_resetTarget_CDict)) + ? ((size_t)1 << cParams->chainLog) + : 0; + size_t const hSize = ((size_t)1) << cParams->hashLog; + U32 const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; + size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0; + + DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset); + assert(useRowMatchFinder != ZSTD_ps_auto); + if (forceResetIndex == ZSTDirp_reset) { + ZSTD_window_init(&ms->window); + ZSTD_cwksp_mark_tables_dirty(ws); + } + + ms->hashLog3 = hashLog3; + ms->lazySkipping = 0; + + ZSTD_invalidateMatchState(ms); + + assert(!ZSTD_cwksp_reserve_failed(ws)); /* check that allocation hasn't already failed */ + + ZSTD_cwksp_clear_tables(ws); + + DEBUGLOG(5, "reserving table space"); + /* table Space */ + ms->hashTable = (U32*)ZSTD_cwksp_reserve_table(ws, hSize * sizeof(U32)); + ms->chainTable = (U32*)ZSTD_cwksp_reserve_table(ws, chainSize * sizeof(U32)); + ms->hashTable3 = (U32*)ZSTD_cwksp_reserve_table(ws, h3Size * sizeof(U32)); + RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation, + "failed a workspace allocation in ZSTD_reset_matchState"); + + DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_leaveDirty); + if (crp!=ZSTDcrp_leaveDirty) { + /* reset tables only */ + ZSTD_cwksp_clean_tables(ws); + } + + if (ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)) { + /* Row match finder needs an additional table of hashes ("tags") */ + size_t const tagTableSize = hSize; + /* We want to generate a new salt in case we reset a Cctx, but we always want to use + * 0 when we reset a Cdict */ + if(forWho == ZSTD_resetTarget_CCtx) { + ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned_init_once(ws, tagTableSize); + ZSTD_advanceHashSalt(ms); + } else { + /* When we are not salting we want to always memset the memory */ + ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned64(ws, tagTableSize); + ZSTD_memset(ms->tagTable, 0, tagTableSize); + ms->hashSalt = 0; + } + { /* Switch to 32-entry rows if searchLog is 5 (or more) */ + U32 const rowLog = BOUNDED(4, cParams->searchLog, 6); + assert(cParams->hashLog >= rowLog); + ms->rowHashLog = cParams->hashLog - rowLog; + } + } + + /* opt parser space */ + if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) { + DEBUGLOG(4, "reserving optimal parser space"); + ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (1<opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxLL+1) * sizeof(unsigned)); + ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxML+1) * sizeof(unsigned)); + ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxOff+1) * sizeof(unsigned)); + ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_match_t)); + ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t)); + } + + ms->cParams = *cParams; + + RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation, + "failed a workspace allocation in ZSTD_reset_matchState"); + return 0; +} + +/* ZSTD_indexTooCloseToMax() : + * minor optimization : prefer memset() rather than reduceIndex() + * which is measurably slow in some circumstances (reported for Visual Studio). + * Works when re-using a context for a lot of smallish inputs : + * if all inputs are smaller than ZSTD_INDEXOVERFLOW_MARGIN, + * memset() will be triggered before reduceIndex(). + */ +#define ZSTD_INDEXOVERFLOW_MARGIN (16 MB) +static int ZSTD_indexTooCloseToMax(ZSTD_window_t w) +{ + return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN); +} + +/** ZSTD_dictTooBig(): + * When dictionaries are larger than ZSTD_CHUNKSIZE_MAX they can't be loaded in + * one go generically. So we ensure that in that case we reset the tables to zero, + * so that we can load as much of the dictionary as possible. + */ +static int ZSTD_dictTooBig(size_t const loadedDictSize) +{ + return loadedDictSize > ZSTD_CHUNKSIZE_MAX; +} + +/*! ZSTD_resetCCtx_internal() : + * @param loadedDictSize The size of the dictionary to be loaded + * into the context, if any. If no dictionary is used, or the + * dictionary is being attached / copied, then pass 0. + * note : `params` are assumed fully validated at this stage. + */ +static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, + ZSTD_CCtx_params const* params, + U64 const pledgedSrcSize, + size_t const loadedDictSize, + ZSTD_compResetPolicy_e const crp, + ZSTD_buffered_policy_e const zbuff) +{ + ZSTD_cwksp* const ws = &zc->workspace; + DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d useBlockSplitter=%d", + (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->postBlockSplitter); + assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams))); + + zc->isFirstBlock = 1; + + /* Set applied params early so we can modify them for LDM, + * and point params at the applied params. + */ + zc->appliedParams = *params; + params = &zc->appliedParams; + + assert(params->useRowMatchFinder != ZSTD_ps_auto); + assert(params->postBlockSplitter != ZSTD_ps_auto); + assert(params->ldmParams.enableLdm != ZSTD_ps_auto); + assert(params->maxBlockSize != 0); + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* Adjust long distance matching parameters */ + ZSTD_ldm_adjustParameters(&zc->appliedParams.ldmParams, ¶ms->cParams); + assert(params->ldmParams.hashLog >= params->ldmParams.bucketSizeLog); + assert(params->ldmParams.hashRateLog < 32); + } + + { size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params->cParams.windowLog), pledgedSrcSize)); + size_t const blockSize = MIN(params->maxBlockSize, windowSize); + size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, params->cParams.minMatch, ZSTD_hasExtSeqProd(params)); + size_t const buffOutSize = (zbuff == ZSTDb_buffered && params->outBufferMode == ZSTD_bm_buffered) + ? ZSTD_compressBound(blockSize) + 1 + : 0; + size_t const buffInSize = (zbuff == ZSTDb_buffered && params->inBufferMode == ZSTD_bm_buffered) + ? windowSize + blockSize + : 0; + size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize); + + int const indexTooClose = ZSTD_indexTooCloseToMax(zc->blockState.matchState.window); + int const dictTooBig = ZSTD_dictTooBig(loadedDictSize); + ZSTD_indexResetPolicy_e needsIndexReset = + (indexTooClose || dictTooBig || !zc->initialized) ? ZSTDirp_reset : ZSTDirp_continue; + + size_t const neededSpace = + ZSTD_estimateCCtxSize_usingCCtxParams_internal( + ¶ms->cParams, ¶ms->ldmParams, zc->staticSize != 0, params->useRowMatchFinder, + buffInSize, buffOutSize, pledgedSrcSize, ZSTD_hasExtSeqProd(params), params->maxBlockSize); + + FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!"); + + if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0); + + { /* Check if workspace is large enough, alloc a new one if needed */ + int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace; + int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace); + int resizeWorkspace = workspaceTooSmall || workspaceWasteful; + DEBUGLOG(4, "Need %zu B workspace", neededSpace); + DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize); + + if (resizeWorkspace) { + DEBUGLOG(4, "Resize workspaceSize from %zuKB to %zuKB", + ZSTD_cwksp_sizeof(ws) >> 10, + neededSpace >> 10); + + RETURN_ERROR_IF(zc->staticSize, memory_allocation, "static cctx : no resize"); + + needsIndexReset = ZSTDirp_reset; + + ZSTD_cwksp_free(ws, zc->customMem); + FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem), ""); + + DEBUGLOG(5, "reserving object space"); + /* Statically sized space. + * tmpWorkspace never moves, + * though prev/next block swap places */ + assert(ZSTD_cwksp_check_available(ws, 2 * sizeof(ZSTD_compressedBlockState_t))); + zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t)); + RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock"); + zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t)); + RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock"); + zc->tmpWorkspace = ZSTD_cwksp_reserve_object(ws, TMP_WORKSPACE_SIZE); + RETURN_ERROR_IF(zc->tmpWorkspace == NULL, memory_allocation, "couldn't allocate tmpWorkspace"); + zc->tmpWkspSize = TMP_WORKSPACE_SIZE; + } } + + ZSTD_cwksp_clear(ws); + + /* init params */ + zc->blockState.matchState.cParams = params->cParams; + zc->blockState.matchState.prefetchCDictTables = params->prefetchCDictTables == ZSTD_ps_enable; + zc->pledgedSrcSizePlusOne = pledgedSrcSize+1; + zc->consumedSrcSize = 0; + zc->producedCSize = 0; + if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN) + zc->appliedParams.fParams.contentSizeFlag = 0; + DEBUGLOG(4, "pledged content size : %u ; flag : %u", + (unsigned)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag); + zc->blockSizeMax = blockSize; + + XXH64_reset(&zc->xxhState, 0); + zc->stage = ZSTDcs_init; + zc->dictID = 0; + zc->dictContentSize = 0; + + ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock); + + FORWARD_IF_ERROR(ZSTD_reset_matchState( + &zc->blockState.matchState, + ws, + ¶ms->cParams, + params->useRowMatchFinder, + crp, + needsIndexReset, + ZSTD_resetTarget_CCtx), ""); + + zc->seqStore.sequencesStart = (SeqDef*)ZSTD_cwksp_reserve_aligned64(ws, maxNbSeq * sizeof(SeqDef)); + + /* ldm hash table */ + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* TODO: avoid memset? */ + size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog; + zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned64(ws, ldmHSize * sizeof(ldmEntry_t)); + ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t)); + zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned64(ws, maxNbLdmSeq * sizeof(rawSeq)); + zc->maxNbLdmSequences = maxNbLdmSeq; + + ZSTD_window_init(&zc->ldmState.window); + zc->ldmState.loadedDictEnd = 0; + } + + /* reserve space for block-level external sequences */ + if (ZSTD_hasExtSeqProd(params)) { + size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize); + zc->extSeqBufCapacity = maxNbExternalSeq; + zc->extSeqBuf = + (ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned64(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence)); + } + + /* buffers */ + + /* ZSTD_wildcopy() is used to copy into the literals buffer, + * so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes. + */ + zc->seqStore.litStart = ZSTD_cwksp_reserve_buffer(ws, blockSize + WILDCOPY_OVERLENGTH); + zc->seqStore.maxNbLit = blockSize; + + zc->bufferedPolicy = zbuff; + zc->inBuffSize = buffInSize; + zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize); + zc->outBuffSize = buffOutSize; + zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize); + + /* ldm bucketOffsets table */ + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* TODO: avoid memset? */ + size_t const numBuckets = + ((size_t)1) << (params->ldmParams.hashLog - + params->ldmParams.bucketSizeLog); + zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, numBuckets); + ZSTD_memset(zc->ldmState.bucketOffsets, 0, numBuckets); + } + + /* sequences storage */ + ZSTD_referenceExternalSequences(zc, NULL, 0); + zc->seqStore.maxNbSeq = maxNbSeq; + zc->seqStore.llCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); + zc->seqStore.mlCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); + zc->seqStore.ofCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); + + DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws)); + assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace)); + + zc->initialized = 1; + + return 0; + } +} + +/* ZSTD_invalidateRepCodes() : + * ensures next compression will not use repcodes from previous block. + * Note : only works with regular variant; + * do not use with extDict variant ! */ +void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) { + int i; + for (i=0; iblockState.prevCBlock->rep[i] = 0; + assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window)); +} + +/* These are the approximate sizes for each strategy past which copying the + * dictionary tables into the working context is faster than using them + * in-place. + */ +static const size_t attachDictSizeCutoffs[ZSTD_STRATEGY_MAX+1] = { + 8 KB, /* unused */ + 8 KB, /* ZSTD_fast */ + 16 KB, /* ZSTD_dfast */ + 32 KB, /* ZSTD_greedy */ + 32 KB, /* ZSTD_lazy */ + 32 KB, /* ZSTD_lazy2 */ + 32 KB, /* ZSTD_btlazy2 */ + 32 KB, /* ZSTD_btopt */ + 8 KB, /* ZSTD_btultra */ + 8 KB /* ZSTD_btultra2 */ +}; + +static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + U64 pledgedSrcSize) +{ + size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy]; + int const dedicatedDictSearch = cdict->matchState.dedicatedDictSearch; + return dedicatedDictSearch + || ( ( pledgedSrcSize <= cutoff + || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN + || params->attachDictPref == ZSTD_dictForceAttach ) + && params->attachDictPref != ZSTD_dictForceCopy + && !params->forceWindow ); /* dictMatchState isn't correctly + * handled in _enforceMaxDist */ +} + +static size_t +ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx, + const ZSTD_CDict* cdict, + ZSTD_CCtx_params params, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + DEBUGLOG(4, "ZSTD_resetCCtx_byAttachingCDict() pledgedSrcSize=%llu", + (unsigned long long)pledgedSrcSize); + { + ZSTD_compressionParameters adjusted_cdict_cParams = cdict->matchState.cParams; + unsigned const windowLog = params.cParams.windowLog; + assert(windowLog != 0); + /* Resize working context table params for input only, since the dict + * has its own tables. */ + /* pledgedSrcSize == 0 means 0! */ + + if (cdict->matchState.dedicatedDictSearch) { + ZSTD_dedicatedDictSearch_revertCParams(&adjusted_cdict_cParams); + } + + params.cParams = ZSTD_adjustCParams_internal(adjusted_cdict_cParams, pledgedSrcSize, + cdict->dictContentSize, ZSTD_cpm_attachDict, + params.useRowMatchFinder); + params.cParams.windowLog = windowLog; + params.useRowMatchFinder = cdict->useRowMatchFinder; /* cdict overrides */ + FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, ¶ms, pledgedSrcSize, + /* loadedDictSize */ 0, + ZSTDcrp_makeClean, zbuff), ""); + assert(cctx->appliedParams.cParams.strategy == adjusted_cdict_cParams.strategy); + } + + { const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc + - cdict->matchState.window.base); + const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit; + if (cdictLen == 0) { + /* don't even attach dictionaries with no contents */ + DEBUGLOG(4, "skipping attaching empty dictionary"); + } else { + DEBUGLOG(4, "attaching dictionary into context"); + cctx->blockState.matchState.dictMatchState = &cdict->matchState; + + /* prep working match state so dict matches never have negative indices + * when they are translated to the working context's index space. */ + if (cctx->blockState.matchState.window.dictLimit < cdictEnd) { + cctx->blockState.matchState.window.nextSrc = + cctx->blockState.matchState.window.base + cdictEnd; + ZSTD_window_clear(&cctx->blockState.matchState.window); + } + /* loadedDictEnd is expressed within the referential of the active context */ + cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit; + } } + + cctx->dictID = cdict->dictID; + cctx->dictContentSize = cdict->dictContentSize; + + /* copy block state */ + ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); + + return 0; +} + +static void ZSTD_copyCDictTableIntoCCtx(U32* dst, U32 const* src, size_t tableSize, + ZSTD_compressionParameters const* cParams) { + if (ZSTD_CDictIndicesAreTagged(cParams)){ + /* Remove tags from the CDict table if they are present. + * See docs on "short cache" in zstd_compress_internal.h for context. */ + size_t i; + for (i = 0; i < tableSize; i++) { + U32 const taggedIndex = src[i]; + U32 const index = taggedIndex >> ZSTD_SHORT_CACHE_TAG_BITS; + dst[i] = index; + } + } else { + ZSTD_memcpy(dst, src, tableSize * sizeof(U32)); + } +} + +static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, + const ZSTD_CDict* cdict, + ZSTD_CCtx_params params, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams; + + assert(!cdict->matchState.dedicatedDictSearch); + DEBUGLOG(4, "ZSTD_resetCCtx_byCopyingCDict() pledgedSrcSize=%llu", + (unsigned long long)pledgedSrcSize); + + { unsigned const windowLog = params.cParams.windowLog; + assert(windowLog != 0); + /* Copy only compression parameters related to tables. */ + params.cParams = *cdict_cParams; + params.cParams.windowLog = windowLog; + params.useRowMatchFinder = cdict->useRowMatchFinder; + FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, ¶ms, pledgedSrcSize, + /* loadedDictSize */ 0, + ZSTDcrp_leaveDirty, zbuff), ""); + assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy); + assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog); + assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog); + } + + ZSTD_cwksp_mark_tables_dirty(&cctx->workspace); + assert(params.useRowMatchFinder != ZSTD_ps_auto); + + /* copy tables */ + { size_t const chainSize = ZSTD_allocateChainTable(cdict_cParams->strategy, cdict->useRowMatchFinder, 0 /* DDS guaranteed disabled */) + ? ((size_t)1 << cdict_cParams->chainLog) + : 0; + size_t const hSize = (size_t)1 << cdict_cParams->hashLog; + + ZSTD_copyCDictTableIntoCCtx(cctx->blockState.matchState.hashTable, + cdict->matchState.hashTable, + hSize, cdict_cParams); + + /* Do not copy cdict's chainTable if cctx has parameters such that it would not use chainTable */ + if (ZSTD_allocateChainTable(cctx->appliedParams.cParams.strategy, cctx->appliedParams.useRowMatchFinder, 0 /* forDDSDict */)) { + ZSTD_copyCDictTableIntoCCtx(cctx->blockState.matchState.chainTable, + cdict->matchState.chainTable, + chainSize, cdict_cParams); + } + /* copy tag table */ + if (ZSTD_rowMatchFinderUsed(cdict_cParams->strategy, cdict->useRowMatchFinder)) { + size_t const tagTableSize = hSize; + ZSTD_memcpy(cctx->blockState.matchState.tagTable, + cdict->matchState.tagTable, + tagTableSize); + cctx->blockState.matchState.hashSalt = cdict->matchState.hashSalt; + } + } + + /* Zero the hashTable3, since the cdict never fills it */ + assert(cctx->blockState.matchState.hashLog3 <= 31); + { U32 const h3log = cctx->blockState.matchState.hashLog3; + size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0; + assert(cdict->matchState.hashLog3 == 0); + ZSTD_memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32)); + } + + ZSTD_cwksp_mark_tables_clean(&cctx->workspace); + + /* copy dictionary offsets */ + { ZSTD_MatchState_t const* srcMatchState = &cdict->matchState; + ZSTD_MatchState_t* dstMatchState = &cctx->blockState.matchState; + dstMatchState->window = srcMatchState->window; + dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; + dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; + } + + cctx->dictID = cdict->dictID; + cctx->dictContentSize = cdict->dictContentSize; + + /* copy block state */ + ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); + + return 0; +} + +/* We have a choice between copying the dictionary context into the working + * context, or referencing the dictionary context from the working context + * in-place. We decide here which strategy to use. */ +static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + + DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)", + (unsigned)pledgedSrcSize); + + if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) { + return ZSTD_resetCCtx_byAttachingCDict( + cctx, cdict, *params, pledgedSrcSize, zbuff); + } else { + return ZSTD_resetCCtx_byCopyingCDict( + cctx, cdict, *params, pledgedSrcSize, zbuff); + } +} + +/*! ZSTD_copyCCtx_internal() : + * Duplicate an existing context `srcCCtx` into another one `dstCCtx`. + * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()). + * The "context", in this case, refers to the hash and chain tables, + * entropy tables, and dictionary references. + * `windowLog` value is enforced if != 0, otherwise value is copied from srcCCtx. + * @return : 0, or an error code */ +static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, + const ZSTD_CCtx* srcCCtx, + ZSTD_frameParameters fParams, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong, + "Can't copy a ctx that's not in init stage."); + DEBUGLOG(5, "ZSTD_copyCCtx_internal"); + ZSTD_memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); + { ZSTD_CCtx_params params = dstCCtx->requestedParams; + /* Copy only compression parameters related to tables. */ + params.cParams = srcCCtx->appliedParams.cParams; + assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_ps_auto); + assert(srcCCtx->appliedParams.postBlockSplitter != ZSTD_ps_auto); + assert(srcCCtx->appliedParams.ldmParams.enableLdm != ZSTD_ps_auto); + params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder; + params.postBlockSplitter = srcCCtx->appliedParams.postBlockSplitter; + params.ldmParams = srcCCtx->appliedParams.ldmParams; + params.fParams = fParams; + params.maxBlockSize = srcCCtx->appliedParams.maxBlockSize; + ZSTD_resetCCtx_internal(dstCCtx, ¶ms, pledgedSrcSize, + /* loadedDictSize */ 0, + ZSTDcrp_leaveDirty, zbuff); + assert(dstCCtx->appliedParams.cParams.windowLog == srcCCtx->appliedParams.cParams.windowLog); + assert(dstCCtx->appliedParams.cParams.strategy == srcCCtx->appliedParams.cParams.strategy); + assert(dstCCtx->appliedParams.cParams.hashLog == srcCCtx->appliedParams.cParams.hashLog); + assert(dstCCtx->appliedParams.cParams.chainLog == srcCCtx->appliedParams.cParams.chainLog); + assert(dstCCtx->blockState.matchState.hashLog3 == srcCCtx->blockState.matchState.hashLog3); + } + + ZSTD_cwksp_mark_tables_dirty(&dstCCtx->workspace); + + /* copy tables */ + { size_t const chainSize = ZSTD_allocateChainTable(srcCCtx->appliedParams.cParams.strategy, + srcCCtx->appliedParams.useRowMatchFinder, + 0 /* forDDSDict */) + ? ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog) + : 0; + size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog; + U32 const h3log = srcCCtx->blockState.matchState.hashLog3; + size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0; + + ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable, + srcCCtx->blockState.matchState.hashTable, + hSize * sizeof(U32)); + ZSTD_memcpy(dstCCtx->blockState.matchState.chainTable, + srcCCtx->blockState.matchState.chainTable, + chainSize * sizeof(U32)); + ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable3, + srcCCtx->blockState.matchState.hashTable3, + h3Size * sizeof(U32)); + } + + ZSTD_cwksp_mark_tables_clean(&dstCCtx->workspace); + + /* copy dictionary offsets */ + { + const ZSTD_MatchState_t* srcMatchState = &srcCCtx->blockState.matchState; + ZSTD_MatchState_t* dstMatchState = &dstCCtx->blockState.matchState; + dstMatchState->window = srcMatchState->window; + dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; + dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; + } + dstCCtx->dictID = srcCCtx->dictID; + dstCCtx->dictContentSize = srcCCtx->dictContentSize; + + /* copy block state */ + ZSTD_memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock)); + + return 0; +} + +/*! ZSTD_copyCCtx() : + * Duplicate an existing context `srcCCtx` into another one `dstCCtx`. + * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()). + * pledgedSrcSize==0 means "unknown". +* @return : 0, or an error code */ +size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize) +{ + ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; + ZSTD_buffered_policy_e const zbuff = srcCCtx->bufferedPolicy; + ZSTD_STATIC_ASSERT((U32)ZSTDb_buffered==1); + if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; + fParams.contentSizeFlag = (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN); + + return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx, + fParams, pledgedSrcSize, + zbuff); +} + + +#define ZSTD_ROWSIZE 16 +/*! ZSTD_reduceTable() : + * reduce table indexes by `reducerValue`, or squash to zero. + * PreserveMark preserves "unsorted mark" for btlazy2 strategy. + * It must be set to a clear 0/1 value, to remove branch during inlining. + * Presume table size is a multiple of ZSTD_ROWSIZE + * to help auto-vectorization */ +FORCE_INLINE_TEMPLATE void +ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerValue, int const preserveMark) +{ + int const nbRows = (int)size / ZSTD_ROWSIZE; + int cellNb = 0; + int rowNb; + /* Protect special index values < ZSTD_WINDOW_START_INDEX. */ + U32 const reducerThreshold = reducerValue + ZSTD_WINDOW_START_INDEX; + assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */ + assert(size < (1U<<31)); /* can be cast to int */ + +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) + /* To validate that the table reuse logic is sound, and that we don't + * access table space that we haven't cleaned, we re-"poison" the table + * space every time we mark it dirty. + * + * This function however is intended to operate on those dirty tables and + * re-clean them. So when this function is used correctly, we can unpoison + * the memory it operated on. This introduces a blind spot though, since + * if we now try to operate on __actually__ poisoned memory, we will not + * detect that. */ + __msan_unpoison(table, size * sizeof(U32)); +#endif + + for (rowNb=0 ; rowNb < nbRows ; rowNb++) { + int column; + for (column=0; columncParams.hashLog; + ZSTD_reduceTable(ms->hashTable, hSize, reducerValue); + } + + if (ZSTD_allocateChainTable(params->cParams.strategy, params->useRowMatchFinder, (U32)ms->dedicatedDictSearch)) { + U32 const chainSize = (U32)1 << params->cParams.chainLog; + if (params->cParams.strategy == ZSTD_btlazy2) + ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue); + else + ZSTD_reduceTable(ms->chainTable, chainSize, reducerValue); + } + + if (ms->hashLog3) { + U32 const h3Size = (U32)1 << ms->hashLog3; + ZSTD_reduceTable(ms->hashTable3, h3Size, reducerValue); + } +} + + +/*-******************************************************* +* Block entropic compression +*********************************************************/ + +/* See doc/zstd_compression_format.md for detailed format description */ + +int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr) +{ + const SeqDef* const sequences = seqStorePtr->sequencesStart; + BYTE* const llCodeTable = seqStorePtr->llCode; + BYTE* const ofCodeTable = seqStorePtr->ofCode; + BYTE* const mlCodeTable = seqStorePtr->mlCode; + U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + U32 u; + int longOffsets = 0; + assert(nbSeq <= seqStorePtr->maxNbSeq); + for (u=0; u= STREAM_ACCUMULATOR_MIN)); + if (MEM_32bits() && ofCode >= STREAM_ACCUMULATOR_MIN) + longOffsets = 1; + } + if (seqStorePtr->longLengthType==ZSTD_llt_literalLength) + llCodeTable[seqStorePtr->longLengthPos] = MaxLL; + if (seqStorePtr->longLengthType==ZSTD_llt_matchLength) + mlCodeTable[seqStorePtr->longLengthPos] = MaxML; + return longOffsets; +} + +/* ZSTD_useTargetCBlockSize(): + * Returns if target compressed block size param is being used. + * If used, compression will do best effort to make a compressed block size to be around targetCBlockSize. + * Returns 1 if true, 0 otherwise. */ +static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams) +{ + DEBUGLOG(5, "ZSTD_useTargetCBlockSize (targetCBlockSize=%zu)", cctxParams->targetCBlockSize); + return (cctxParams->targetCBlockSize != 0); +} + +/* ZSTD_blockSplitterEnabled(): + * Returns if block splitting param is being used + * If used, compression will do best effort to split a block in order to improve compression ratio. + * At the time this function is called, the parameter must be finalized. + * Returns 1 if true, 0 otherwise. */ +static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams) +{ + DEBUGLOG(5, "ZSTD_blockSplitterEnabled (postBlockSplitter=%d)", cctxParams->postBlockSplitter); + assert(cctxParams->postBlockSplitter != ZSTD_ps_auto); + return (cctxParams->postBlockSplitter == ZSTD_ps_enable); +} + +/* Type returned by ZSTD_buildSequencesStatistics containing finalized symbol encoding types + * and size of the sequences statistics + */ +typedef struct { + U32 LLtype; + U32 Offtype; + U32 MLtype; + size_t size; + size_t lastCountSize; /* Accounts for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */ + int longOffsets; +} ZSTD_symbolEncodingTypeStats_t; + +/* ZSTD_buildSequencesStatistics(): + * Returns a ZSTD_symbolEncodingTypeStats_t, or a zstd error code in the `size` field. + * Modifies `nextEntropy` to have the appropriate values as a side effect. + * nbSeq must be greater than 0. + * + * entropyWkspSize must be of size at least ENTROPY_WORKSPACE_SIZE - (MaxSeq + 1)*sizeof(U32) + */ +static ZSTD_symbolEncodingTypeStats_t +ZSTD_buildSequencesStatistics( + const SeqStore_t* seqStorePtr, size_t nbSeq, + const ZSTD_fseCTables_t* prevEntropy, ZSTD_fseCTables_t* nextEntropy, + BYTE* dst, const BYTE* const dstEnd, + ZSTD_strategy strategy, unsigned* countWorkspace, + void* entropyWorkspace, size_t entropyWkspSize) +{ + BYTE* const ostart = dst; + const BYTE* const oend = dstEnd; + BYTE* op = ostart; + FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable; + FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable; + FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable; + const BYTE* const ofCodeTable = seqStorePtr->ofCode; + const BYTE* const llCodeTable = seqStorePtr->llCode; + const BYTE* const mlCodeTable = seqStorePtr->mlCode; + ZSTD_symbolEncodingTypeStats_t stats; + + stats.lastCountSize = 0; + /* convert length/distances into codes */ + stats.longOffsets = ZSTD_seqToCodes(seqStorePtr); + assert(op <= oend); + assert(nbSeq != 0); /* ZSTD_selectEncodingType() divides by nbSeq */ + /* build CTable for Literal Lengths */ + { unsigned max = MaxLL; + size_t const mostFrequent = HIST_countFast_wksp(countWorkspace, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */ + DEBUGLOG(5, "Building LL table"); + nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode; + stats.LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode, + countWorkspace, max, mostFrequent, nbSeq, + LLFSELog, prevEntropy->litlengthCTable, + LL_defaultNorm, LL_defaultNormLog, + ZSTD_defaultAllowed, strategy); + assert(set_basic < set_compressed && set_rle < set_compressed); + assert(!(stats.LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */ + { size_t const countSize = ZSTD_buildCTable( + op, (size_t)(oend - op), + CTable_LitLength, LLFSELog, (SymbolEncodingType_e)stats.LLtype, + countWorkspace, max, llCodeTable, nbSeq, + LL_defaultNorm, LL_defaultNormLog, MaxLL, + prevEntropy->litlengthCTable, + sizeof(prevEntropy->litlengthCTable), + entropyWorkspace, entropyWkspSize); + if (ZSTD_isError(countSize)) { + DEBUGLOG(3, "ZSTD_buildCTable for LitLens failed"); + stats.size = countSize; + return stats; + } + if (stats.LLtype == set_compressed) + stats.lastCountSize = countSize; + op += countSize; + assert(op <= oend); + } } + /* build CTable for Offsets */ + { unsigned max = MaxOff; + size_t const mostFrequent = HIST_countFast_wksp( + countWorkspace, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */ + /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */ + ZSTD_DefaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed; + DEBUGLOG(5, "Building OF table"); + nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode; + stats.Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode, + countWorkspace, max, mostFrequent, nbSeq, + OffFSELog, prevEntropy->offcodeCTable, + OF_defaultNorm, OF_defaultNormLog, + defaultPolicy, strategy); + assert(!(stats.Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */ + { size_t const countSize = ZSTD_buildCTable( + op, (size_t)(oend - op), + CTable_OffsetBits, OffFSELog, (SymbolEncodingType_e)stats.Offtype, + countWorkspace, max, ofCodeTable, nbSeq, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, + prevEntropy->offcodeCTable, + sizeof(prevEntropy->offcodeCTable), + entropyWorkspace, entropyWkspSize); + if (ZSTD_isError(countSize)) { + DEBUGLOG(3, "ZSTD_buildCTable for Offsets failed"); + stats.size = countSize; + return stats; + } + if (stats.Offtype == set_compressed) + stats.lastCountSize = countSize; + op += countSize; + assert(op <= oend); + } } + /* build CTable for MatchLengths */ + { unsigned max = MaxML; + size_t const mostFrequent = HIST_countFast_wksp( + countWorkspace, &max, mlCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */ + DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op)); + nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode; + stats.MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode, + countWorkspace, max, mostFrequent, nbSeq, + MLFSELog, prevEntropy->matchlengthCTable, + ML_defaultNorm, ML_defaultNormLog, + ZSTD_defaultAllowed, strategy); + assert(!(stats.MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */ + { size_t const countSize = ZSTD_buildCTable( + op, (size_t)(oend - op), + CTable_MatchLength, MLFSELog, (SymbolEncodingType_e)stats.MLtype, + countWorkspace, max, mlCodeTable, nbSeq, + ML_defaultNorm, ML_defaultNormLog, MaxML, + prevEntropy->matchlengthCTable, + sizeof(prevEntropy->matchlengthCTable), + entropyWorkspace, entropyWkspSize); + if (ZSTD_isError(countSize)) { + DEBUGLOG(3, "ZSTD_buildCTable for MatchLengths failed"); + stats.size = countSize; + return stats; + } + if (stats.MLtype == set_compressed) + stats.lastCountSize = countSize; + op += countSize; + assert(op <= oend); + } } + stats.size = (size_t)(op-ostart); + return stats; +} + +/* ZSTD_entropyCompressSeqStore_internal(): + * compresses both literals and sequences + * Returns compressed size of block, or a zstd error. + */ +#define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20 +MEM_STATIC size_t +ZSTD_entropyCompressSeqStore_internal( + void* dst, size_t dstCapacity, + const void* literals, size_t litSize, + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + void* entropyWorkspace, size_t entropyWkspSize, + const int bmi2) +{ + ZSTD_strategy const strategy = cctxParams->cParams.strategy; + unsigned* count = (unsigned*)entropyWorkspace; + FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable; + FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable; + FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable; + const SeqDef* const sequences = seqStorePtr->sequencesStart; + const size_t nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + const BYTE* const ofCodeTable = seqStorePtr->ofCode; + const BYTE* const llCodeTable = seqStorePtr->llCode; + const BYTE* const mlCodeTable = seqStorePtr->mlCode; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart; + size_t lastCountSize; + int longOffsets = 0; + + entropyWorkspace = count + (MaxSeq + 1); + entropyWkspSize -= (MaxSeq + 1) * sizeof(*count); + + DEBUGLOG(5, "ZSTD_entropyCompressSeqStore_internal (nbSeq=%zu, dstCapacity=%zu)", nbSeq, dstCapacity); + ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<= HUF_WORKSPACE_SIZE); + + /* Compress literals */ + { size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + /* Base suspicion of uncompressibility on ratio of literals to sequences */ + int const suspectUncompressible = (numSequences == 0) || (litSize / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO); + + size_t const cSize = ZSTD_compressLiterals( + op, dstCapacity, + literals, litSize, + entropyWorkspace, entropyWkspSize, + &prevEntropy->huf, &nextEntropy->huf, + cctxParams->cParams.strategy, + ZSTD_literalsCompressionIsDisabled(cctxParams), + suspectUncompressible, bmi2); + FORWARD_IF_ERROR(cSize, "ZSTD_compressLiterals failed"); + assert(cSize <= dstCapacity); + op += cSize; + } + + /* Sequences Header */ + RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/, + dstSize_tooSmall, "Can't fit seq hdr in output buf!"); + if (nbSeq < 128) { + *op++ = (BYTE)nbSeq; + } else if (nbSeq < LONGNBSEQ) { + op[0] = (BYTE)((nbSeq>>8) + 0x80); + op[1] = (BYTE)nbSeq; + op+=2; + } else { + op[0]=0xFF; + MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)); + op+=3; + } + assert(op <= oend); + if (nbSeq==0) { + /* Copy the old tables over as if we repeated them */ + ZSTD_memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse)); + return (size_t)(op - ostart); + } + { BYTE* const seqHead = op++; + /* build stats for sequences */ + const ZSTD_symbolEncodingTypeStats_t stats = + ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq, + &prevEntropy->fse, &nextEntropy->fse, + op, oend, + strategy, count, + entropyWorkspace, entropyWkspSize); + FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!"); + *seqHead = (BYTE)((stats.LLtype<<6) + (stats.Offtype<<4) + (stats.MLtype<<2)); + lastCountSize = stats.lastCountSize; + op += stats.size; + longOffsets = stats.longOffsets; + } + + { size_t const bitstreamSize = ZSTD_encodeSequences( + op, (size_t)(oend - op), + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, + longOffsets, bmi2); + FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed"); + op += bitstreamSize; + assert(op <= oend); + /* zstd versions <= 1.3.4 mistakenly report corruption when + * FSE_readNCount() receives a buffer < 4 bytes. + * Fixed by https://github.com/facebook/zstd/pull/1146. + * This can happen when the last set_compressed table present is 2 + * bytes and the bitstream is only one byte. + * In this exceedingly rare case, we will simply emit an uncompressed + * block, since it isn't worth optimizing. + */ + if (lastCountSize && (lastCountSize + bitstreamSize) < 4) { + /* lastCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */ + assert(lastCountSize + bitstreamSize == 3); + DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by " + "emitting an uncompressed block."); + return 0; + } + } + + DEBUGLOG(5, "compressed block size : %u", (unsigned)(op - ostart)); + return (size_t)(op - ostart); +} + +static size_t +ZSTD_entropyCompressSeqStore_wExtLitBuffer( + void* dst, size_t dstCapacity, + const void* literals, size_t litSize, + size_t blockSize, + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + void* entropyWorkspace, size_t entropyWkspSize, + int bmi2) +{ + size_t const cSize = ZSTD_entropyCompressSeqStore_internal( + dst, dstCapacity, + literals, litSize, + seqStorePtr, prevEntropy, nextEntropy, cctxParams, + entropyWorkspace, entropyWkspSize, bmi2); + if (cSize == 0) return 0; + /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block. + * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block. + */ + if ((cSize == ERROR(dstSize_tooSmall)) & (blockSize <= dstCapacity)) { + DEBUGLOG(4, "not enough dstCapacity (%zu) for ZSTD_entropyCompressSeqStore_internal()=> do not compress block", dstCapacity); + return 0; /* block not compressed */ + } + FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSeqStore_internal failed"); + + /* Check compressibility */ + { size_t const maxCSize = blockSize - ZSTD_minGain(blockSize, cctxParams->cParams.strategy); + if (cSize >= maxCSize) return 0; /* block not compressed */ + } + DEBUGLOG(5, "ZSTD_entropyCompressSeqStore() cSize: %zu", cSize); + /* libzstd decoder before > v1.5.4 is not compatible with compressed blocks of size ZSTD_BLOCKSIZE_MAX exactly. + * This restriction is indirectly already fulfilled by respecting ZSTD_minGain() condition above. + */ + assert(cSize < ZSTD_BLOCKSIZE_MAX); + return cSize; +} + +static size_t +ZSTD_entropyCompressSeqStore( + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + size_t srcSize, + void* entropyWorkspace, size_t entropyWkspSize, + int bmi2) +{ + return ZSTD_entropyCompressSeqStore_wExtLitBuffer( + dst, dstCapacity, + seqStorePtr->litStart, (size_t)(seqStorePtr->lit - seqStorePtr->litStart), + srcSize, + seqStorePtr, + prevEntropy, nextEntropy, + cctxParams, + entropyWorkspace, entropyWkspSize, + bmi2); +} + +/* ZSTD_selectBlockCompressor() : + * Not static, but internal use only (used by long distance matcher) + * assumption : strat is a valid strategy */ +ZSTD_BlockCompressor_f ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_ParamSwitch_e useRowMatchFinder, ZSTD_dictMode_e dictMode) +{ + static const ZSTD_BlockCompressor_f blockCompressor[4][ZSTD_STRATEGY_MAX+1] = { + { ZSTD_compressBlock_fast /* default for 0 */, + ZSTD_compressBlock_fast, + ZSTD_COMPRESSBLOCK_DOUBLEFAST, + ZSTD_COMPRESSBLOCK_GREEDY, + ZSTD_COMPRESSBLOCK_LAZY, + ZSTD_COMPRESSBLOCK_LAZY2, + ZSTD_COMPRESSBLOCK_BTLAZY2, + ZSTD_COMPRESSBLOCK_BTOPT, + ZSTD_COMPRESSBLOCK_BTULTRA, + ZSTD_COMPRESSBLOCK_BTULTRA2 + }, + { ZSTD_compressBlock_fast_extDict /* default for 0 */, + ZSTD_compressBlock_fast_extDict, + ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT, + ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT, + ZSTD_COMPRESSBLOCK_LAZY_EXTDICT, + ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT, + ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT, + ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT, + ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT, + ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT + }, + { ZSTD_compressBlock_fast_dictMatchState /* default for 0 */, + ZSTD_compressBlock_fast_dictMatchState, + ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE + }, + { NULL /* default for 0 */, + NULL, + NULL, + ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH, + ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH, + ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH, + NULL, + NULL, + NULL, + NULL } + }; + ZSTD_BlockCompressor_f selectedCompressor; + ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1); + + assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat)); + DEBUGLOG(5, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder); + if (ZSTD_rowMatchFinderUsed(strat, useRowMatchFinder)) { + static const ZSTD_BlockCompressor_f rowBasedBlockCompressors[4][3] = { + { + ZSTD_COMPRESSBLOCK_GREEDY_ROW, + ZSTD_COMPRESSBLOCK_LAZY_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW, + ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW, + ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW, + ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW + } + }; + DEBUGLOG(5, "Selecting a row-based matchfinder"); + assert(useRowMatchFinder != ZSTD_ps_auto); + selectedCompressor = rowBasedBlockCompressors[(int)dictMode][(int)strat - (int)ZSTD_greedy]; + } else { + selectedCompressor = blockCompressor[(int)dictMode][(int)strat]; + } + assert(selectedCompressor != NULL); + return selectedCompressor; +} + +static void ZSTD_storeLastLiterals(SeqStore_t* seqStorePtr, + const BYTE* anchor, size_t lastLLSize) +{ + ZSTD_memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; +} + +void ZSTD_resetSeqStore(SeqStore_t* ssPtr) +{ + ssPtr->lit = ssPtr->litStart; + ssPtr->sequences = ssPtr->sequencesStart; + ssPtr->longLengthType = ZSTD_llt_none; +} + +/* ZSTD_postProcessSequenceProducerResult() : + * Validates and post-processes sequences obtained through the external matchfinder API: + * - Checks whether nbExternalSeqs represents an error condition. + * - Appends a block delimiter to outSeqs if one is not already present. + * See zstd.h for context regarding block delimiters. + * Returns the number of sequences after post-processing, or an error code. */ +static size_t ZSTD_postProcessSequenceProducerResult( + ZSTD_Sequence* outSeqs, size_t nbExternalSeqs, size_t outSeqsCapacity, size_t srcSize +) { + RETURN_ERROR_IF( + nbExternalSeqs > outSeqsCapacity, + sequenceProducer_failed, + "External sequence producer returned error code %lu", + (unsigned long)nbExternalSeqs + ); + + RETURN_ERROR_IF( + nbExternalSeqs == 0 && srcSize > 0, + sequenceProducer_failed, + "Got zero sequences from external sequence producer for a non-empty src buffer!" + ); + + if (srcSize == 0) { + ZSTD_memset(&outSeqs[0], 0, sizeof(ZSTD_Sequence)); + return 1; + } + + { + ZSTD_Sequence const lastSeq = outSeqs[nbExternalSeqs - 1]; + + /* We can return early if lastSeq is already a block delimiter. */ + if (lastSeq.offset == 0 && lastSeq.matchLength == 0) { + return nbExternalSeqs; + } + + /* This error condition is only possible if the external matchfinder + * produced an invalid parse, by definition of ZSTD_sequenceBound(). */ + RETURN_ERROR_IF( + nbExternalSeqs == outSeqsCapacity, + sequenceProducer_failed, + "nbExternalSeqs == outSeqsCapacity but lastSeq is not a block delimiter!" + ); + + /* lastSeq is not a block delimiter, so we need to append one. */ + ZSTD_memset(&outSeqs[nbExternalSeqs], 0, sizeof(ZSTD_Sequence)); + return nbExternalSeqs + 1; + } +} + +/* ZSTD_fastSequenceLengthSum() : + * Returns sum(litLen) + sum(matchLen) + lastLits for *seqBuf*. + * Similar to another function in zstd_compress.c (determine_blockSize), + * except it doesn't check for a block delimiter to end summation. + * Removing the early exit allows the compiler to auto-vectorize (https://godbolt.org/z/cY1cajz9P). + * This function can be deleted and replaced by determine_blockSize after we resolve issue #3456. */ +static size_t ZSTD_fastSequenceLengthSum(ZSTD_Sequence const* seqBuf, size_t seqBufSize) { + size_t matchLenSum, litLenSum, i; + matchLenSum = 0; + litLenSum = 0; + for (i = 0; i < seqBufSize; i++) { + litLenSum += seqBuf[i].litLength; + matchLenSum += seqBuf[i].matchLength; + } + return litLenSum + matchLenSum; +} + +/** + * Function to validate sequences produced by a block compressor. + */ +static void ZSTD_validateSeqStore(const SeqStore_t* seqStore, const ZSTD_compressionParameters* cParams) +{ +#if DEBUGLEVEL >= 1 + const SeqDef* seq = seqStore->sequencesStart; + const SeqDef* const seqEnd = seqStore->sequences; + size_t const matchLenLowerBound = cParams->minMatch == 3 ? 3 : 4; + for (; seq < seqEnd; ++seq) { + const ZSTD_SequenceLength seqLength = ZSTD_getSequenceLength(seqStore, seq); + assert(seqLength.matchLength >= matchLenLowerBound); + (void)seqLength; + (void)matchLenLowerBound; + } +#else + (void)seqStore; + (void)cParams; +#endif +} + +static size_t +ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx, + ZSTD_SequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize, + ZSTD_ParamSwitch_e externalRepSearch); + +typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_BuildSeqStore_e; + +static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) +{ + ZSTD_MatchState_t* const ms = &zc->blockState.matchState; + DEBUGLOG(5, "ZSTD_buildSeqStore (srcSize=%zu)", srcSize); + assert(srcSize <= ZSTD_BLOCKSIZE_MAX); + /* Assert that we have correctly flushed the ctx params into the ms's copy */ + ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams); + /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding + * additional 1. We need to revisit and change this logic to be more consistent */ + if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1+1) { + if (zc->appliedParams.cParams.strategy >= ZSTD_btopt) { + ZSTD_ldm_skipRawSeqStoreBytes(&zc->externSeqStore, srcSize); + } else { + ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch); + } + return ZSTDbss_noCompress; /* don't even attempt compression below a certain srcSize */ + } + ZSTD_resetSeqStore(&(zc->seqStore)); + /* required for optimal parser to read stats from dictionary */ + ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy; + /* tell the optimal parser how we expect to compress literals */ + ms->opt.literalCompressionMode = zc->appliedParams.literalCompressionMode; + /* a gap between an attached dict and the current window is not safe, + * they must remain adjacent, + * and when that stops being the case, the dict must be unset */ + assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit); + + /* limited update after a very long match */ + { const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const U32 curr = (U32)(istart-base); + if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1)); /* ensure no overflow */ + if (curr > ms->nextToUpdate + 384) + ms->nextToUpdate = curr - MIN(192, (U32)(curr - ms->nextToUpdate - 384)); + } + + /* select and store sequences */ + { ZSTD_dictMode_e const dictMode = ZSTD_matchState_dictMode(ms); + size_t lastLLSize; + { int i; + for (i = 0; i < ZSTD_REP_NUM; ++i) + zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i]; + } + if (zc->externSeqStore.pos < zc->externSeqStore.size) { + assert(zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_disable); + + /* External matchfinder + LDM is technically possible, just not implemented yet. + * We need to revisit soon and implement it. */ + RETURN_ERROR_IF( + ZSTD_hasExtSeqProd(&zc->appliedParams), + parameter_combination_unsupported, + "Long-distance matching with external sequence producer enabled is not currently supported." + ); + + /* Updates ldmSeqStore.pos */ + lastLLSize = + ZSTD_ldm_blockCompress(&zc->externSeqStore, + ms, &zc->seqStore, + zc->blockState.nextCBlock->rep, + zc->appliedParams.useRowMatchFinder, + src, srcSize); + assert(zc->externSeqStore.pos <= zc->externSeqStore.size); + } else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) { + RawSeqStore_t ldmSeqStore = kNullRawSeqStore; + + /* External matchfinder + LDM is technically possible, just not implemented yet. + * We need to revisit soon and implement it. */ + RETURN_ERROR_IF( + ZSTD_hasExtSeqProd(&zc->appliedParams), + parameter_combination_unsupported, + "Long-distance matching with external sequence producer enabled is not currently supported." + ); + + ldmSeqStore.seq = zc->ldmSequences; + ldmSeqStore.capacity = zc->maxNbLdmSequences; + /* Updates ldmSeqStore.size */ + FORWARD_IF_ERROR(ZSTD_ldm_generateSequences(&zc->ldmState, &ldmSeqStore, + &zc->appliedParams.ldmParams, + src, srcSize), ""); + /* Updates ldmSeqStore.pos */ + lastLLSize = + ZSTD_ldm_blockCompress(&ldmSeqStore, + ms, &zc->seqStore, + zc->blockState.nextCBlock->rep, + zc->appliedParams.useRowMatchFinder, + src, srcSize); + assert(ldmSeqStore.pos == ldmSeqStore.size); + } else if (ZSTD_hasExtSeqProd(&zc->appliedParams)) { + assert( + zc->extSeqBufCapacity >= ZSTD_sequenceBound(srcSize) + ); + assert(zc->appliedParams.extSeqProdFunc != NULL); + + { U32 const windowSize = (U32)1 << zc->appliedParams.cParams.windowLog; + + size_t const nbExternalSeqs = (zc->appliedParams.extSeqProdFunc)( + zc->appliedParams.extSeqProdState, + zc->extSeqBuf, + zc->extSeqBufCapacity, + src, srcSize, + NULL, 0, /* dict and dictSize, currently not supported */ + zc->appliedParams.compressionLevel, + windowSize + ); + + size_t const nbPostProcessedSeqs = ZSTD_postProcessSequenceProducerResult( + zc->extSeqBuf, + nbExternalSeqs, + zc->extSeqBufCapacity, + srcSize + ); + + /* Return early if there is no error, since we don't need to worry about last literals */ + if (!ZSTD_isError(nbPostProcessedSeqs)) { + ZSTD_SequencePosition seqPos = {0,0,0}; + size_t const seqLenSum = ZSTD_fastSequenceLengthSum(zc->extSeqBuf, nbPostProcessedSeqs); + RETURN_ERROR_IF(seqLenSum > srcSize, externalSequences_invalid, "External sequences imply too large a block!"); + FORWARD_IF_ERROR( + ZSTD_transferSequences_wBlockDelim( + zc, &seqPos, + zc->extSeqBuf, nbPostProcessedSeqs, + src, srcSize, + zc->appliedParams.searchForExternalRepcodes + ), + "Failed to copy external sequences to seqStore!" + ); + ms->ldmSeqStore = NULL; + DEBUGLOG(5, "Copied %lu sequences from external sequence producer to internal seqStore.", (unsigned long)nbExternalSeqs); + return ZSTDbss_compress; + } + + /* Propagate the error if fallback is disabled */ + if (!zc->appliedParams.enableMatchFinderFallback) { + return nbPostProcessedSeqs; + } + + /* Fallback to software matchfinder */ + { ZSTD_BlockCompressor_f const blockCompressor = + ZSTD_selectBlockCompressor( + zc->appliedParams.cParams.strategy, + zc->appliedParams.useRowMatchFinder, + dictMode); + ms->ldmSeqStore = NULL; + DEBUGLOG( + 5, + "External sequence producer returned error code %lu. Falling back to internal parser.", + (unsigned long)nbExternalSeqs + ); + lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); + } } + } else { /* not long range mode and no external matchfinder */ + ZSTD_BlockCompressor_f const blockCompressor = ZSTD_selectBlockCompressor( + zc->appliedParams.cParams.strategy, + zc->appliedParams.useRowMatchFinder, + dictMode); + ms->ldmSeqStore = NULL; + lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); + } + { const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize; + ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize); + } } + ZSTD_validateSeqStore(&zc->seqStore, &zc->appliedParams.cParams); + return ZSTDbss_compress; +} + +static size_t ZSTD_copyBlockSequences(SeqCollector* seqCollector, const SeqStore_t* seqStore, const U32 prevRepcodes[ZSTD_REP_NUM]) +{ + const SeqDef* inSeqs = seqStore->sequencesStart; + const size_t nbInSequences = (size_t)(seqStore->sequences - inSeqs); + const size_t nbInLiterals = (size_t)(seqStore->lit - seqStore->litStart); + + ZSTD_Sequence* outSeqs = seqCollector->seqIndex == 0 ? seqCollector->seqStart : seqCollector->seqStart + seqCollector->seqIndex; + const size_t nbOutSequences = nbInSequences + 1; + size_t nbOutLiterals = 0; + Repcodes_t repcodes; + size_t i; + + /* Bounds check that we have enough space for every input sequence + * and the block delimiter + */ + assert(seqCollector->seqIndex <= seqCollector->maxSequences); + RETURN_ERROR_IF( + nbOutSequences > (size_t)(seqCollector->maxSequences - seqCollector->seqIndex), + dstSize_tooSmall, + "Not enough space to copy sequences"); + + ZSTD_memcpy(&repcodes, prevRepcodes, sizeof(repcodes)); + for (i = 0; i < nbInSequences; ++i) { + U32 rawOffset; + outSeqs[i].litLength = inSeqs[i].litLength; + outSeqs[i].matchLength = inSeqs[i].mlBase + MINMATCH; + outSeqs[i].rep = 0; + + /* Handle the possible single length >= 64K + * There can only be one because we add MINMATCH to every match length, + * and blocks are at most 128K. + */ + if (i == seqStore->longLengthPos) { + if (seqStore->longLengthType == ZSTD_llt_literalLength) { + outSeqs[i].litLength += 0x10000; + } else if (seqStore->longLengthType == ZSTD_llt_matchLength) { + outSeqs[i].matchLength += 0x10000; + } + } + + /* Determine the raw offset given the offBase, which may be a repcode. */ + if (OFFBASE_IS_REPCODE(inSeqs[i].offBase)) { + const U32 repcode = OFFBASE_TO_REPCODE(inSeqs[i].offBase); + assert(repcode > 0); + outSeqs[i].rep = repcode; + if (outSeqs[i].litLength != 0) { + rawOffset = repcodes.rep[repcode - 1]; + } else { + if (repcode == 3) { + assert(repcodes.rep[0] > 1); + rawOffset = repcodes.rep[0] - 1; + } else { + rawOffset = repcodes.rep[repcode]; + } + } + } else { + rawOffset = OFFBASE_TO_OFFSET(inSeqs[i].offBase); + } + outSeqs[i].offset = rawOffset; + + /* Update repcode history for the sequence */ + ZSTD_updateRep(repcodes.rep, + inSeqs[i].offBase, + inSeqs[i].litLength == 0); + + nbOutLiterals += outSeqs[i].litLength; + } + /* Insert last literals (if any exist) in the block as a sequence with ml == off == 0. + * If there are no last literals, then we'll emit (of: 0, ml: 0, ll: 0), which is a marker + * for the block boundary, according to the API. + */ + assert(nbInLiterals >= nbOutLiterals); + { + const size_t lastLLSize = nbInLiterals - nbOutLiterals; + outSeqs[nbInSequences].litLength = (U32)lastLLSize; + outSeqs[nbInSequences].matchLength = 0; + outSeqs[nbInSequences].offset = 0; + assert(nbOutSequences == nbInSequences + 1); + } + seqCollector->seqIndex += nbOutSequences; + assert(seqCollector->seqIndex <= seqCollector->maxSequences); + + return 0; +} + +size_t ZSTD_sequenceBound(size_t srcSize) { + const size_t maxNbSeq = (srcSize / ZSTD_MINMATCH_MIN) + 1; + const size_t maxNbDelims = (srcSize / ZSTD_BLOCKSIZE_MAX_MIN) + 1; + return maxNbSeq + maxNbDelims; +} + +size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize) { + size_t in = 0; + size_t out = 0; + for (; in < seqsSize; ++in) { + if (sequences[in].offset == 0 && sequences[in].matchLength == 0) { + if (in != seqsSize - 1) { + sequences[in+1].litLength += sequences[in].litLength; + } + } else { + sequences[out] = sequences[in]; + ++out; + } + } + return out; +} + +/* Unrolled loop to read four size_ts of input at a time. Returns 1 if is RLE, 0 if not. */ +static int ZSTD_isRLE(const BYTE* src, size_t length) { + const BYTE* ip = src; + const BYTE value = ip[0]; + const size_t valueST = (size_t)((U64)value * 0x0101010101010101ULL); + const size_t unrollSize = sizeof(size_t) * 4; + const size_t unrollMask = unrollSize - 1; + const size_t prefixLength = length & unrollMask; + size_t i; + if (length == 1) return 1; + /* Check if prefix is RLE first before using unrolled loop */ + if (prefixLength && ZSTD_count(ip+1, ip, ip+prefixLength) != prefixLength-1) { + return 0; + } + for (i = prefixLength; i != length; i += unrollSize) { + size_t u; + for (u = 0; u < unrollSize; u += sizeof(size_t)) { + if (MEM_readST(ip + i + u) != valueST) { + return 0; + } } } + return 1; +} + +/* Returns true if the given block may be RLE. + * This is just a heuristic based on the compressibility. + * It may return both false positives and false negatives. + */ +static int ZSTD_maybeRLE(SeqStore_t const* seqStore) +{ + size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart); + size_t const nbLits = (size_t)(seqStore->lit - seqStore->litStart); + + return nbSeqs < 4 && nbLits < 10; +} + +static void +ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t* const bs) +{ + ZSTD_compressedBlockState_t* const tmp = bs->prevCBlock; + bs->prevCBlock = bs->nextCBlock; + bs->nextCBlock = tmp; +} + +/* Writes the block header */ +static void +writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock) +{ + U32 const cBlockHeader = cSize == 1 ? + lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) : + lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); + MEM_writeLE24(op, cBlockHeader); + DEBUGLOG(5, "writeBlockHeader: cSize: %zu blockSize: %zu lastBlock: %u", cSize, blockSize, lastBlock); +} + +/** ZSTD_buildBlockEntropyStats_literals() : + * Builds entropy for the literals. + * Stores literals block type (raw, rle, compressed, repeat) and + * huffman description table to hufMetadata. + * Requires ENTROPY_WORKSPACE_SIZE workspace + * @return : size of huffman description table, or an error code + */ +static size_t +ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSize, + const ZSTD_hufCTables_t* prevHuf, + ZSTD_hufCTables_t* nextHuf, + ZSTD_hufCTablesMetadata_t* hufMetadata, + const int literalsCompressionIsDisabled, + void* workspace, size_t wkspSize, + int hufFlags) +{ + BYTE* const wkspStart = (BYTE*)workspace; + BYTE* const wkspEnd = wkspStart + wkspSize; + BYTE* const countWkspStart = wkspStart; + unsigned* const countWksp = (unsigned*)workspace; + const size_t countWkspSize = (HUF_SYMBOLVALUE_MAX + 1) * sizeof(unsigned); + BYTE* const nodeWksp = countWkspStart + countWkspSize; + const size_t nodeWkspSize = (size_t)(wkspEnd - nodeWksp); + unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX; + unsigned huffLog = LitHufLog; + HUF_repeat repeat = prevHuf->repeatMode; + DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_literals (srcSize=%zu)", srcSize); + + /* Prepare nextEntropy assuming reusing the existing table */ + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + + if (literalsCompressionIsDisabled) { + DEBUGLOG(5, "set_basic - disabled"); + hufMetadata->hType = set_basic; + return 0; + } + + /* small ? don't even attempt compression (speed opt) */ +#ifndef COMPRESS_LITERALS_SIZE_MIN +# define COMPRESS_LITERALS_SIZE_MIN 63 /* heuristic */ +#endif + { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN; + if (srcSize <= minLitSize) { + DEBUGLOG(5, "set_basic - too small"); + hufMetadata->hType = set_basic; + return 0; + } } + + /* Scan input and build symbol stats */ + { size_t const largest = + HIST_count_wksp (countWksp, &maxSymbolValue, + (const BYTE*)src, srcSize, + workspace, wkspSize); + FORWARD_IF_ERROR(largest, "HIST_count_wksp failed"); + if (largest == srcSize) { + /* only one literal symbol */ + DEBUGLOG(5, "set_rle"); + hufMetadata->hType = set_rle; + return 0; + } + if (largest <= (srcSize >> 7)+4) { + /* heuristic: likely not compressible */ + DEBUGLOG(5, "set_basic - no gain"); + hufMetadata->hType = set_basic; + return 0; + } } + + /* Validate the previous Huffman table */ + if (repeat == HUF_repeat_check + && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) { + repeat = HUF_repeat_none; + } + + /* Build Huffman Tree */ + ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable)); + huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, nodeWksp, nodeWkspSize, nextHuf->CTable, countWksp, hufFlags); + assert(huffLog <= LitHufLog); + { size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp, + maxSymbolValue, huffLog, + nodeWksp, nodeWkspSize); + FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp"); + huffLog = (U32)maxBits; + } + { /* Build and write the CTable */ + size_t const newCSize = HUF_estimateCompressedSize( + (HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue); + size_t const hSize = HUF_writeCTable_wksp( + hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer), + (HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog, + nodeWksp, nodeWkspSize); + /* Check against repeating the previous CTable */ + if (repeat != HUF_repeat_none) { + size_t const oldCSize = HUF_estimateCompressedSize( + (HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue); + if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) { + DEBUGLOG(5, "set_repeat - smaller"); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + hufMetadata->hType = set_repeat; + return 0; + } } + if (newCSize + hSize >= srcSize) { + DEBUGLOG(5, "set_basic - no gains"); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + hufMetadata->hType = set_basic; + return 0; + } + DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize); + hufMetadata->hType = set_compressed; + nextHuf->repeatMode = HUF_repeat_check; + return hSize; + } +} + + +/* ZSTD_buildDummySequencesStatistics(): + * Returns a ZSTD_symbolEncodingTypeStats_t with all encoding types as set_basic, + * and updates nextEntropy to the appropriate repeatMode. + */ +static ZSTD_symbolEncodingTypeStats_t +ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy) +{ + ZSTD_symbolEncodingTypeStats_t stats = {set_basic, set_basic, set_basic, 0, 0, 0}; + nextEntropy->litlength_repeatMode = FSE_repeat_none; + nextEntropy->offcode_repeatMode = FSE_repeat_none; + nextEntropy->matchlength_repeatMode = FSE_repeat_none; + return stats; +} + +/** ZSTD_buildBlockEntropyStats_sequences() : + * Builds entropy for the sequences. + * Stores symbol compression modes and fse table to fseMetadata. + * Requires ENTROPY_WORKSPACE_SIZE wksp. + * @return : size of fse tables or error code */ +static size_t +ZSTD_buildBlockEntropyStats_sequences( + const SeqStore_t* seqStorePtr, + const ZSTD_fseCTables_t* prevEntropy, + ZSTD_fseCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + ZSTD_fseCTablesMetadata_t* fseMetadata, + void* workspace, size_t wkspSize) +{ + ZSTD_strategy const strategy = cctxParams->cParams.strategy; + size_t const nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + BYTE* const ostart = fseMetadata->fseTablesBuffer; + BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer); + BYTE* op = ostart; + unsigned* countWorkspace = (unsigned*)workspace; + unsigned* entropyWorkspace = countWorkspace + (MaxSeq + 1); + size_t entropyWorkspaceSize = wkspSize - (MaxSeq + 1) * sizeof(*countWorkspace); + ZSTD_symbolEncodingTypeStats_t stats; + + DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_sequences (nbSeq=%zu)", nbSeq); + stats = nbSeq != 0 ? ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq, + prevEntropy, nextEntropy, op, oend, + strategy, countWorkspace, + entropyWorkspace, entropyWorkspaceSize) + : ZSTD_buildDummySequencesStatistics(nextEntropy); + FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!"); + fseMetadata->llType = (SymbolEncodingType_e) stats.LLtype; + fseMetadata->ofType = (SymbolEncodingType_e) stats.Offtype; + fseMetadata->mlType = (SymbolEncodingType_e) stats.MLtype; + fseMetadata->lastCountSize = stats.lastCountSize; + return stats.size; +} + + +/** ZSTD_buildBlockEntropyStats() : + * Builds entropy for the block. + * Requires workspace size ENTROPY_WORKSPACE_SIZE + * @return : 0 on success, or an error code + * Note : also employed in superblock + */ +size_t ZSTD_buildBlockEntropyStats( + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize) +{ + size_t const litSize = (size_t)(seqStorePtr->lit - seqStorePtr->litStart); + int const huf_useOptDepth = (cctxParams->cParams.strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD); + int const hufFlags = huf_useOptDepth ? HUF_flags_optimalDepth : 0; + + entropyMetadata->hufMetadata.hufDesSize = + ZSTD_buildBlockEntropyStats_literals(seqStorePtr->litStart, litSize, + &prevEntropy->huf, &nextEntropy->huf, + &entropyMetadata->hufMetadata, + ZSTD_literalsCompressionIsDisabled(cctxParams), + workspace, wkspSize, hufFlags); + + FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildBlockEntropyStats_literals failed"); + entropyMetadata->fseMetadata.fseTablesSize = + ZSTD_buildBlockEntropyStats_sequences(seqStorePtr, + &prevEntropy->fse, &nextEntropy->fse, + cctxParams, + &entropyMetadata->fseMetadata, + workspace, wkspSize); + FORWARD_IF_ERROR(entropyMetadata->fseMetadata.fseTablesSize, "ZSTD_buildBlockEntropyStats_sequences failed"); + return 0; +} + +/* Returns the size estimate for the literals section (header + content) of a block */ +static size_t +ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSize, + const ZSTD_hufCTables_t* huf, + const ZSTD_hufCTablesMetadata_t* hufMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + unsigned* const countWksp = (unsigned*)workspace; + unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX; + size_t literalSectionHeaderSize = 3 + (litSize >= 1 KB) + (litSize >= 16 KB); + U32 singleStream = litSize < 256; + + if (hufMetadata->hType == set_basic) return litSize; + else if (hufMetadata->hType == set_rle) return 1; + else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) { + size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize); + if (ZSTD_isError(largest)) return litSize; + { size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue); + if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize; + if (!singleStream) cLitSizeEstimate += 6; /* multi-stream huffman uses 6-byte jump table */ + return cLitSizeEstimate + literalSectionHeaderSize; + } } + assert(0); /* impossible */ + return 0; +} + +/* Returns the size estimate for the FSE-compressed symbols (of, ml, ll) of a block */ +static size_t +ZSTD_estimateBlockSize_symbolType(SymbolEncodingType_e type, + const BYTE* codeTable, size_t nbSeq, unsigned maxCode, + const FSE_CTable* fseCTable, + const U8* additionalBits, + short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, + void* workspace, size_t wkspSize) +{ + unsigned* const countWksp = (unsigned*)workspace; + const BYTE* ctp = codeTable; + const BYTE* const ctStart = ctp; + const BYTE* const ctEnd = ctStart + nbSeq; + size_t cSymbolTypeSizeEstimateInBits = 0; + unsigned max = maxCode; + + HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */ + if (type == set_basic) { + /* We selected this encoding type, so it must be valid. */ + assert(max <= defaultMax); + (void)defaultMax; + cSymbolTypeSizeEstimateInBits = ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max); + } else if (type == set_rle) { + cSymbolTypeSizeEstimateInBits = 0; + } else if (type == set_compressed || type == set_repeat) { + cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max); + } + if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) { + return nbSeq * 10; + } + while (ctp < ctEnd) { + if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp]; + else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */ + ctp++; + } + return cSymbolTypeSizeEstimateInBits >> 3; +} + +/* Returns the size estimate for the sequences section (header + content) of a block */ +static size_t +ZSTD_estimateBlockSize_sequences(const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_fseCTables_t* fseTables, + const ZSTD_fseCTablesMetadata_t* fseMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + size_t sequencesSectionHeaderSize = 1 /* seqHead */ + 1 /* min seqSize size */ + (nbSeq >= 128) + (nbSeq >= LONGNBSEQ); + size_t cSeqSizeEstimate = 0; + cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, nbSeq, MaxOff, + fseTables->offcodeCTable, NULL, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->llType, llCodeTable, nbSeq, MaxLL, + fseTables->litlengthCTable, LL_bits, + LL_defaultNorm, LL_defaultNormLog, MaxLL, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, nbSeq, MaxML, + fseTables->matchlengthCTable, ML_bits, + ML_defaultNorm, ML_defaultNormLog, MaxML, + workspace, wkspSize); + if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize; + return cSeqSizeEstimate + sequencesSectionHeaderSize; +} + +/* Returns the size estimate for a given stream of literals, of, ll, ml */ +static size_t +ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize, + const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_entropyCTables_t* entropy, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize, + int writeLitEntropy, int writeSeqEntropy) +{ + size_t const literalsSize = ZSTD_estimateBlockSize_literal(literals, litSize, + &entropy->huf, &entropyMetadata->hufMetadata, + workspace, wkspSize, writeLitEntropy); + size_t const seqSize = ZSTD_estimateBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable, + nbSeq, &entropy->fse, &entropyMetadata->fseMetadata, + workspace, wkspSize, writeSeqEntropy); + return seqSize + literalsSize + ZSTD_blockHeaderSize; +} + +/* Builds entropy statistics and uses them for blocksize estimation. + * + * @return: estimated compressed size of the seqStore, or a zstd error. + */ +static size_t +ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(SeqStore_t* seqStore, ZSTD_CCtx* zc) +{ + ZSTD_entropyCTablesMetadata_t* const entropyMetadata = &zc->blockSplitCtx.entropyMetadata; + DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()"); + FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(seqStore, + &zc->blockState.prevCBlock->entropy, + &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + entropyMetadata, + zc->tmpWorkspace, zc->tmpWkspSize), ""); + return ZSTD_estimateBlockSize( + seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart), + seqStore->ofCode, seqStore->llCode, seqStore->mlCode, + (size_t)(seqStore->sequences - seqStore->sequencesStart), + &zc->blockState.nextCBlock->entropy, + entropyMetadata, + zc->tmpWorkspace, zc->tmpWkspSize, + (int)(entropyMetadata->hufMetadata.hType == set_compressed), 1); +} + +/* Returns literals bytes represented in a seqStore */ +static size_t ZSTD_countSeqStoreLiteralsBytes(const SeqStore_t* const seqStore) +{ + size_t literalsBytes = 0; + size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart); + size_t i; + for (i = 0; i < nbSeqs; ++i) { + SeqDef const seq = seqStore->sequencesStart[i]; + literalsBytes += seq.litLength; + if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_literalLength) { + literalsBytes += 0x10000; + } } + return literalsBytes; +} + +/* Returns match bytes represented in a seqStore */ +static size_t ZSTD_countSeqStoreMatchBytes(const SeqStore_t* const seqStore) +{ + size_t matchBytes = 0; + size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart); + size_t i; + for (i = 0; i < nbSeqs; ++i) { + SeqDef seq = seqStore->sequencesStart[i]; + matchBytes += seq.mlBase + MINMATCH; + if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) { + matchBytes += 0x10000; + } } + return matchBytes; +} + +/* Derives the seqStore that is a chunk of the originalSeqStore from [startIdx, endIdx). + * Stores the result in resultSeqStore. + */ +static void ZSTD_deriveSeqStoreChunk(SeqStore_t* resultSeqStore, + const SeqStore_t* originalSeqStore, + size_t startIdx, size_t endIdx) +{ + *resultSeqStore = *originalSeqStore; + if (startIdx > 0) { + resultSeqStore->sequences = originalSeqStore->sequencesStart + startIdx; + resultSeqStore->litStart += ZSTD_countSeqStoreLiteralsBytes(resultSeqStore); + } + + /* Move longLengthPos into the correct position if necessary */ + if (originalSeqStore->longLengthType != ZSTD_llt_none) { + if (originalSeqStore->longLengthPos < startIdx || originalSeqStore->longLengthPos > endIdx) { + resultSeqStore->longLengthType = ZSTD_llt_none; + } else { + resultSeqStore->longLengthPos -= (U32)startIdx; + } + } + resultSeqStore->sequencesStart = originalSeqStore->sequencesStart + startIdx; + resultSeqStore->sequences = originalSeqStore->sequencesStart + endIdx; + if (endIdx == (size_t)(originalSeqStore->sequences - originalSeqStore->sequencesStart)) { + /* This accounts for possible last literals if the derived chunk reaches the end of the block */ + assert(resultSeqStore->lit == originalSeqStore->lit); + } else { + size_t const literalsBytes = ZSTD_countSeqStoreLiteralsBytes(resultSeqStore); + resultSeqStore->lit = resultSeqStore->litStart + literalsBytes; + } + resultSeqStore->llCode += startIdx; + resultSeqStore->mlCode += startIdx; + resultSeqStore->ofCode += startIdx; +} + +/** + * Returns the raw offset represented by the combination of offBase, ll0, and repcode history. + * offBase must represent a repcode in the numeric representation of ZSTD_storeSeq(). + */ +static U32 +ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offBase, const U32 ll0) +{ + U32 const adjustedRepCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0; /* [ 0 - 3 ] */ + assert(OFFBASE_IS_REPCODE(offBase)); + if (adjustedRepCode == ZSTD_REP_NUM) { + assert(ll0); + /* litlength == 0 and offCode == 2 implies selection of first repcode - 1 + * This is only valid if it results in a valid offset value, aka > 0. + * Note : it may happen that `rep[0]==1` in exceptional circumstances. + * In which case this function will return 0, which is an invalid offset. + * It's not an issue though, since this value will be + * compared and discarded within ZSTD_seqStore_resolveOffCodes(). + */ + return rep[0] - 1; + } + return rep[adjustedRepCode]; +} + +/** + * ZSTD_seqStore_resolveOffCodes() reconciles any possible divergences in offset history that may arise + * due to emission of RLE/raw blocks that disturb the offset history, + * and replaces any repcodes within the seqStore that may be invalid. + * + * dRepcodes are updated as would be on the decompression side. + * cRepcodes are updated exactly in accordance with the seqStore. + * + * Note : this function assumes seq->offBase respects the following numbering scheme : + * 0 : invalid + * 1-3 : repcode 1-3 + * 4+ : real_offset+3 + */ +static void +ZSTD_seqStore_resolveOffCodes(Repcodes_t* const dRepcodes, Repcodes_t* const cRepcodes, + const SeqStore_t* const seqStore, U32 const nbSeq) +{ + U32 idx = 0; + U32 const longLitLenIdx = seqStore->longLengthType == ZSTD_llt_literalLength ? seqStore->longLengthPos : nbSeq; + for (; idx < nbSeq; ++idx) { + SeqDef* const seq = seqStore->sequencesStart + idx; + U32 const ll0 = (seq->litLength == 0) && (idx != longLitLenIdx); + U32 const offBase = seq->offBase; + assert(offBase > 0); + if (OFFBASE_IS_REPCODE(offBase)) { + U32 const dRawOffset = ZSTD_resolveRepcodeToRawOffset(dRepcodes->rep, offBase, ll0); + U32 const cRawOffset = ZSTD_resolveRepcodeToRawOffset(cRepcodes->rep, offBase, ll0); + /* Adjust simulated decompression repcode history if we come across a mismatch. Replace + * the repcode with the offset it actually references, determined by the compression + * repcode history. + */ + if (dRawOffset != cRawOffset) { + seq->offBase = OFFSET_TO_OFFBASE(cRawOffset); + } + } + /* Compression repcode history is always updated with values directly from the unmodified seqStore. + * Decompression repcode history may use modified seq->offset value taken from compression repcode history. + */ + ZSTD_updateRep(dRepcodes->rep, seq->offBase, ll0); + ZSTD_updateRep(cRepcodes->rep, offBase, ll0); + } +} + +/* ZSTD_compressSeqStore_singleBlock(): + * Compresses a seqStore into a block with a block header, into the buffer dst. + * + * Returns the total size of that block (including header) or a ZSTD error code. + */ +static size_t +ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, + const SeqStore_t* const seqStore, + Repcodes_t* const dRep, Repcodes_t* const cRep, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 lastBlock, U32 isPartition) +{ + const U32 rleMaxLength = 25; + BYTE* op = (BYTE*)dst; + const BYTE* ip = (const BYTE*)src; + size_t cSize; + size_t cSeqsSize; + + /* In case of an RLE or raw block, the simulated decompression repcode history must be reset */ + Repcodes_t const dRepOriginal = *dRep; + DEBUGLOG(5, "ZSTD_compressSeqStore_singleBlock"); + if (isPartition) + ZSTD_seqStore_resolveOffCodes(dRep, cRep, seqStore, (U32)(seqStore->sequences - seqStore->sequencesStart)); + + RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "Block header doesn't fit"); + cSeqsSize = ZSTD_entropyCompressSeqStore(seqStore, + &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + op + ZSTD_blockHeaderSize, dstCapacity - ZSTD_blockHeaderSize, + srcSize, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */, + zc->bmi2); + FORWARD_IF_ERROR(cSeqsSize, "ZSTD_entropyCompressSeqStore failed!"); + + if (!zc->isFirstBlock && + cSeqsSize < rleMaxLength && + ZSTD_isRLE((BYTE const*)src, srcSize)) { + /* We don't want to emit our first block as a RLE even if it qualifies because + * doing so will cause the decoder (cli only) to throw a "should consume all input error." + * This is only an issue for zstd <= v1.4.3 + */ + cSeqsSize = 1; + } + + /* Sequence collection not supported when block splitting */ + if (zc->seqCollector.collectSequences) { + FORWARD_IF_ERROR(ZSTD_copyBlockSequences(&zc->seqCollector, seqStore, dRepOriginal.rep), "copyBlockSequences failed"); + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + return 0; + } + + if (cSeqsSize == 0) { + cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock); + FORWARD_IF_ERROR(cSize, "Nocompress block failed"); + DEBUGLOG(5, "Writing out nocompress block, size: %zu", cSize); + *dRep = dRepOriginal; /* reset simulated decompression repcode history */ + } else if (cSeqsSize == 1) { + cSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, srcSize, lastBlock); + FORWARD_IF_ERROR(cSize, "RLE compress block failed"); + DEBUGLOG(5, "Writing out RLE block, size: %zu", cSize); + *dRep = dRepOriginal; /* reset simulated decompression repcode history */ + } else { + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + writeBlockHeader(op, cSeqsSize, srcSize, lastBlock); + cSize = ZSTD_blockHeaderSize + cSeqsSize; + DEBUGLOG(5, "Writing out compressed block, size: %zu", cSize); + } + + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + return cSize; +} + +/* Struct to keep track of where we are in our recursive calls. */ +typedef struct { + U32* splitLocations; /* Array of split indices */ + size_t idx; /* The current index within splitLocations being worked on */ +} seqStoreSplits; + +#define MIN_SEQUENCES_BLOCK_SPLITTING 300 + +/* Helper function to perform the recursive search for block splits. + * Estimates the cost of seqStore prior to split, and estimates the cost of splitting the sequences in half. + * If advantageous to split, then we recurse down the two sub-blocks. + * If not, or if an error occurred in estimation, then we do not recurse. + * + * Note: The recursion depth is capped by a heuristic minimum number of sequences, + * defined by MIN_SEQUENCES_BLOCK_SPLITTING. + * In theory, this means the absolute largest recursion depth is 10 == log2(maxNbSeqInBlock/MIN_SEQUENCES_BLOCK_SPLITTING). + * In practice, recursion depth usually doesn't go beyond 4. + * + * Furthermore, the number of splits is capped by ZSTD_MAX_NB_BLOCK_SPLITS. + * At ZSTD_MAX_NB_BLOCK_SPLITS == 196 with the current existing blockSize + * maximum of 128 KB, this value is actually impossible to reach. + */ +static void +ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx, + ZSTD_CCtx* zc, const SeqStore_t* origSeqStore) +{ + SeqStore_t* const fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk; + SeqStore_t* const firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore; + SeqStore_t* const secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore; + size_t estimatedOriginalSize; + size_t estimatedFirstHalfSize; + size_t estimatedSecondHalfSize; + size_t midIdx = (startIdx + endIdx)/2; + + DEBUGLOG(5, "ZSTD_deriveBlockSplitsHelper: startIdx=%zu endIdx=%zu", startIdx, endIdx); + assert(endIdx >= startIdx); + if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= ZSTD_MAX_NB_BLOCK_SPLITS) { + DEBUGLOG(6, "ZSTD_deriveBlockSplitsHelper: Too few sequences (%zu)", endIdx - startIdx); + return; + } + ZSTD_deriveSeqStoreChunk(fullSeqStoreChunk, origSeqStore, startIdx, endIdx); + ZSTD_deriveSeqStoreChunk(firstHalfSeqStore, origSeqStore, startIdx, midIdx); + ZSTD_deriveSeqStoreChunk(secondHalfSeqStore, origSeqStore, midIdx, endIdx); + estimatedOriginalSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(fullSeqStoreChunk, zc); + estimatedFirstHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(firstHalfSeqStore, zc); + estimatedSecondHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(secondHalfSeqStore, zc); + DEBUGLOG(5, "Estimated original block size: %zu -- First half split: %zu -- Second half split: %zu", + estimatedOriginalSize, estimatedFirstHalfSize, estimatedSecondHalfSize); + if (ZSTD_isError(estimatedOriginalSize) || ZSTD_isError(estimatedFirstHalfSize) || ZSTD_isError(estimatedSecondHalfSize)) { + return; + } + if (estimatedFirstHalfSize + estimatedSecondHalfSize < estimatedOriginalSize) { + DEBUGLOG(5, "split decided at seqNb:%zu", midIdx); + ZSTD_deriveBlockSplitsHelper(splits, startIdx, midIdx, zc, origSeqStore); + splits->splitLocations[splits->idx] = (U32)midIdx; + splits->idx++; + ZSTD_deriveBlockSplitsHelper(splits, midIdx, endIdx, zc, origSeqStore); + } +} + +/* Base recursive function. + * Populates a table with intra-block partition indices that can improve compression ratio. + * + * @return: number of splits made (which equals the size of the partition table - 1). + */ +static size_t ZSTD_deriveBlockSplits(ZSTD_CCtx* zc, U32 partitions[], U32 nbSeq) +{ + seqStoreSplits splits; + splits.splitLocations = partitions; + splits.idx = 0; + if (nbSeq <= 4) { + DEBUGLOG(5, "ZSTD_deriveBlockSplits: Too few sequences to split (%u <= 4)", nbSeq); + /* Refuse to try and split anything with less than 4 sequences */ + return 0; + } + ZSTD_deriveBlockSplitsHelper(&splits, 0, nbSeq, zc, &zc->seqStore); + splits.splitLocations[splits.idx] = nbSeq; + DEBUGLOG(5, "ZSTD_deriveBlockSplits: final nb partitions: %zu", splits.idx+1); + return splits.idx; +} + +/* ZSTD_compressBlock_splitBlock(): + * Attempts to split a given block into multiple blocks to improve compression ratio. + * + * Returns combined size of all blocks (which includes headers), or a ZSTD error code. + */ +static size_t +ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t blockSize, + U32 lastBlock, U32 nbSeq) +{ + size_t cSize = 0; + const BYTE* ip = (const BYTE*)src; + BYTE* op = (BYTE*)dst; + size_t i = 0; + size_t srcBytesTotal = 0; + U32* const partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */ + SeqStore_t* const nextSeqStore = &zc->blockSplitCtx.nextSeqStore; + SeqStore_t* const currSeqStore = &zc->blockSplitCtx.currSeqStore; + size_t const numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq); + + /* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history + * may become invalid. In order to reconcile potentially invalid repcodes, we keep track of two + * separate repcode histories that simulate repcode history on compression and decompression side, + * and use the histories to determine whether we must replace a particular repcode with its raw offset. + * + * 1) cRep gets updated for each partition, regardless of whether the block was emitted as uncompressed + * or RLE. This allows us to retrieve the offset value that an invalid repcode references within + * a nocompress/RLE block. + * 2) dRep gets updated only for compressed partitions, and when a repcode gets replaced, will use + * the replacement offset value rather than the original repcode to update the repcode history. + * dRep also will be the final repcode history sent to the next block. + * + * See ZSTD_seqStore_resolveOffCodes() for more details. + */ + Repcodes_t dRep; + Repcodes_t cRep; + ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + ZSTD_memset(nextSeqStore, 0, sizeof(SeqStore_t)); + + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", + (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, + (unsigned)zc->blockState.matchState.nextToUpdate); + + if (numSplits == 0) { + size_t cSizeSingleBlock = + ZSTD_compressSeqStore_singleBlock(zc, &zc->seqStore, + &dRep, &cRep, + op, dstCapacity, + ip, blockSize, + lastBlock, 0 /* isPartition */); + FORWARD_IF_ERROR(cSizeSingleBlock, "Compressing single block from splitBlock_internal() failed!"); + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: No splits"); + assert(zc->blockSizeMax <= ZSTD_BLOCKSIZE_MAX); + assert(cSizeSingleBlock <= zc->blockSizeMax + ZSTD_blockHeaderSize); + return cSizeSingleBlock; + } + + ZSTD_deriveSeqStoreChunk(currSeqStore, &zc->seqStore, 0, partitions[0]); + for (i = 0; i <= numSplits; ++i) { + size_t cSizeChunk; + U32 const lastPartition = (i == numSplits); + U32 lastBlockEntireSrc = 0; + + size_t srcBytes = ZSTD_countSeqStoreLiteralsBytes(currSeqStore) + ZSTD_countSeqStoreMatchBytes(currSeqStore); + srcBytesTotal += srcBytes; + if (lastPartition) { + /* This is the final partition, need to account for possible last literals */ + srcBytes += blockSize - srcBytesTotal; + lastBlockEntireSrc = lastBlock; + } else { + ZSTD_deriveSeqStoreChunk(nextSeqStore, &zc->seqStore, partitions[i], partitions[i+1]); + } + + cSizeChunk = ZSTD_compressSeqStore_singleBlock(zc, currSeqStore, + &dRep, &cRep, + op, dstCapacity, + ip, srcBytes, + lastBlockEntireSrc, 1 /* isPartition */); + DEBUGLOG(5, "Estimated size: %zu vs %zu : actual size", + ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(currSeqStore, zc), cSizeChunk); + FORWARD_IF_ERROR(cSizeChunk, "Compressing chunk failed!"); + + ip += srcBytes; + op += cSizeChunk; + dstCapacity -= cSizeChunk; + cSize += cSizeChunk; + *currSeqStore = *nextSeqStore; + assert(cSizeChunk <= zc->blockSizeMax + ZSTD_blockHeaderSize); + } + /* cRep and dRep may have diverged during the compression. + * If so, we use the dRep repcodes for the next block. + */ + ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(Repcodes_t)); + return cSize; +} + +static size_t +ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, U32 lastBlock) +{ + U32 nbSeq; + size_t cSize; + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock"); + assert(zc->appliedParams.postBlockSplitter == ZSTD_ps_enable); + + { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); + FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); + if (bss == ZSTDbss_noCompress) { + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block"); + cSize = ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock: Nocompress block"); + return cSize; + } + nbSeq = (U32)(zc->seqStore.sequences - zc->seqStore.sequencesStart); + } + + cSize = ZSTD_compressBlock_splitBlock_internal(zc, dst, dstCapacity, src, srcSize, lastBlock, nbSeq); + FORWARD_IF_ERROR(cSize, "Splitting blocks failed!"); + return cSize; +} + +static size_t +ZSTD_compressBlock_internal(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, U32 frame) +{ + /* This is an estimated upper bound for the length of an rle block. + * This isn't the actual upper bound. + * Finding the real threshold needs further investigation. + */ + const U32 rleMaxLength = 25; + size_t cSize; + const BYTE* ip = (const BYTE*)src; + BYTE* op = (BYTE*)dst; + DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", + (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, + (unsigned)zc->blockState.matchState.nextToUpdate); + + { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); + FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); + if (bss == ZSTDbss_noCompress) { + RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block"); + cSize = 0; + goto out; + } + } + + if (zc->seqCollector.collectSequences) { + FORWARD_IF_ERROR(ZSTD_copyBlockSequences(&zc->seqCollector, ZSTD_getSeqStore(zc), zc->blockState.prevCBlock->rep), "copyBlockSequences failed"); + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + return 0; + } + + /* encode sequences and literals */ + cSize = ZSTD_entropyCompressSeqStore(&zc->seqStore, + &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + dst, dstCapacity, + srcSize, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */, + zc->bmi2); + + if (frame && + /* We don't want to emit our first block as a RLE even if it qualifies because + * doing so will cause the decoder (cli only) to throw a "should consume all input error." + * This is only an issue for zstd <= v1.4.3 + */ + !zc->isFirstBlock && + cSize < rleMaxLength && + ZSTD_isRLE(ip, srcSize)) + { + cSize = 1; + op[0] = ip[0]; + } + +out: + if (!ZSTD_isError(cSize) && cSize > 1) { + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + } + /* We check that dictionaries have offset codes available for the first + * block. After the first block, the offcode table might not have large + * enough codes to represent the offsets in the data. + */ + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + return cSize; +} + +static size_t ZSTD_compressBlock_targetCBlockSize_body(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const size_t bss, U32 lastBlock) +{ + DEBUGLOG(6, "Attempting ZSTD_compressSuperBlock()"); + if (bss == ZSTDbss_compress) { + if (/* We don't want to emit our first block as a RLE even if it qualifies because + * doing so will cause the decoder (cli only) to throw a "should consume all input error." + * This is only an issue for zstd <= v1.4.3 + */ + !zc->isFirstBlock && + ZSTD_maybeRLE(&zc->seqStore) && + ZSTD_isRLE((BYTE const*)src, srcSize)) + { + return ZSTD_rleCompressBlock(dst, dstCapacity, *(BYTE const*)src, srcSize, lastBlock); + } + /* Attempt superblock compression. + * + * Note that compressed size of ZSTD_compressSuperBlock() is not bound by the + * standard ZSTD_compressBound(). This is a problem, because even if we have + * space now, taking an extra byte now could cause us to run out of space later + * and violate ZSTD_compressBound(). + * + * Define blockBound(blockSize) = blockSize + ZSTD_blockHeaderSize. + * + * In order to respect ZSTD_compressBound() we must attempt to emit a raw + * uncompressed block in these cases: + * * cSize == 0: Return code for an uncompressed block. + * * cSize == dstSize_tooSmall: We may have expanded beyond blockBound(srcSize). + * ZSTD_noCompressBlock() will return dstSize_tooSmall if we are really out of + * output space. + * * cSize >= blockBound(srcSize): We have expanded the block too much so + * emit an uncompressed block. + */ + { size_t const cSize = + ZSTD_compressSuperBlock(zc, dst, dstCapacity, src, srcSize, lastBlock); + if (cSize != ERROR(dstSize_tooSmall)) { + size_t const maxCSize = + srcSize - ZSTD_minGain(srcSize, zc->appliedParams.cParams.strategy); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSuperBlock failed"); + if (cSize != 0 && cSize < maxCSize + ZSTD_blockHeaderSize) { + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + return cSize; + } + } + } + } /* if (bss == ZSTDbss_compress)*/ + + DEBUGLOG(6, "Resorting to ZSTD_noCompressBlock()"); + /* Superblock compression failed, attempt to emit a single no compress block. + * The decoder will be able to stream this block since it is uncompressed. + */ + return ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock); +} + +static size_t ZSTD_compressBlock_targetCBlockSize(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 lastBlock) +{ + size_t cSize = 0; + const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); + DEBUGLOG(5, "ZSTD_compressBlock_targetCBlockSize (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u, srcSize=%zu)", + (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, (unsigned)zc->blockState.matchState.nextToUpdate, srcSize); + FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); + + cSize = ZSTD_compressBlock_targetCBlockSize_body(zc, dst, dstCapacity, src, srcSize, bss, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize_body failed"); + + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + return cSize; +} + +static void ZSTD_overflowCorrectIfNeeded(ZSTD_MatchState_t* ms, + ZSTD_cwksp* ws, + ZSTD_CCtx_params const* params, + void const* ip, + void const* iend) +{ + U32 const cycleLog = ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy); + U32 const maxDist = (U32)1 << params->cParams.windowLog; + if (ZSTD_window_needOverflowCorrection(ms->window, cycleLog, maxDist, ms->loadedDictEnd, ip, iend)) { + U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip); + ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30); + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30); + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31); + ZSTD_cwksp_mark_tables_dirty(ws); + ZSTD_reduceIndex(ms, params, correction); + ZSTD_cwksp_mark_tables_clean(ws); + if (ms->nextToUpdate < correction) ms->nextToUpdate = 0; + else ms->nextToUpdate -= correction; + /* invalidate dictionaries on overflow correction */ + ms->loadedDictEnd = 0; + ms->dictMatchState = NULL; + } +} + +#include "zstd_preSplit.h" + +static size_t ZSTD_optimalBlockSize(ZSTD_CCtx* cctx, const void* src, size_t srcSize, size_t blockSizeMax, int splitLevel, ZSTD_strategy strat, S64 savings) +{ + /* split level based on compression strategy, from `fast` to `btultra2` */ + static const int splitLevels[] = { 0, 0, 1, 2, 2, 3, 3, 4, 4, 4 }; + /* note: conservatively only split full blocks (128 KB) currently. + * While it's possible to go lower, let's keep it simple for a first implementation. + * Besides, benefits of splitting are reduced when blocks are already small. + */ + if (srcSize < 128 KB || blockSizeMax < 128 KB) + return MIN(srcSize, blockSizeMax); + /* do not split incompressible data though: + * require verified savings to allow pre-splitting. + * Note: as a consequence, the first full block is not split. + */ + if (savings < 3) { + DEBUGLOG(6, "don't attempt splitting: savings (%i) too low", (int)savings); + return 128 KB; + } + /* apply @splitLevel, or use default value (which depends on @strat). + * note that splitting heuristic is still conditioned by @savings >= 3, + * so the first block will not reach this code path */ + if (splitLevel == 1) return 128 KB; + if (splitLevel == 0) { + assert(ZSTD_fast <= strat && strat <= ZSTD_btultra2); + splitLevel = splitLevels[strat]; + } else { + assert(2 <= splitLevel && splitLevel <= 6); + splitLevel -= 2; + } + return ZSTD_splitBlock(src, blockSizeMax, splitLevel, cctx->tmpWorkspace, cctx->tmpWkspSize); +} + +/*! ZSTD_compress_frameChunk() : +* Compress a chunk of data into one or multiple blocks. +* All blocks will be terminated, all input will be consumed. +* Function will issue an error if there is not enough `dstCapacity` to hold the compressed content. +* Frame is supposed already started (header already produced) +* @return : compressed size, or an error code +*/ +static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 lastFrameChunk) +{ + size_t blockSizeMax = cctx->blockSizeMax; + size_t remaining = srcSize; + const BYTE* ip = (const BYTE*)src; + BYTE* const ostart = (BYTE*)dst; + BYTE* op = ostart; + U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog; + S64 savings = (S64)cctx->consumedSrcSize - (S64)cctx->producedCSize; + + assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX); + + DEBUGLOG(5, "ZSTD_compress_frameChunk (srcSize=%u, blockSizeMax=%u)", (unsigned)srcSize, (unsigned)blockSizeMax); + if (cctx->appliedParams.fParams.checksumFlag && srcSize) + XXH64_update(&cctx->xxhState, src, srcSize); + + while (remaining) { + ZSTD_MatchState_t* const ms = &cctx->blockState.matchState; + size_t const blockSize = ZSTD_optimalBlockSize(cctx, + ip, remaining, + blockSizeMax, + cctx->appliedParams.preBlockSplitter_level, + cctx->appliedParams.cParams.strategy, + savings); + U32 const lastBlock = lastFrameChunk & (blockSize == remaining); + assert(blockSize <= remaining); + + /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding + * additional 1. We need to revisit and change this logic to be more consistent */ + RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE + 1, + dstSize_tooSmall, + "not enough space to store compressed block"); + + ZSTD_overflowCorrectIfNeeded( + ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize); + ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState); + ZSTD_window_enforceMaxDist(&ms->window, ip, maxDist, &ms->loadedDictEnd, &ms->dictMatchState); + + /* Ensure hash/chain table insertion resumes no sooner than lowlimit */ + if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit; + + { size_t cSize; + if (ZSTD_useTargetCBlockSize(&cctx->appliedParams)) { + cSize = ZSTD_compressBlock_targetCBlockSize(cctx, op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize failed"); + assert(cSize > 0); + assert(cSize <= blockSize + ZSTD_blockHeaderSize); + } else if (ZSTD_blockSplitterEnabled(&cctx->appliedParams)) { + cSize = ZSTD_compressBlock_splitBlock(cctx, op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_splitBlock failed"); + assert(cSize > 0 || cctx->seqCollector.collectSequences == 1); + } else { + cSize = ZSTD_compressBlock_internal(cctx, + op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, + ip, blockSize, 1 /* frame */); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_internal failed"); + + if (cSize == 0) { /* block is not compressible */ + cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); + } else { + U32 const cBlockHeader = cSize == 1 ? + lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) : + lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); + MEM_writeLE24(op, cBlockHeader); + cSize += ZSTD_blockHeaderSize; + } + } /* if (ZSTD_useTargetCBlockSize(&cctx->appliedParams))*/ + + /* @savings is employed to ensure that splitting doesn't worsen expansion of incompressible data. + * Without splitting, the maximum expansion is 3 bytes per full block. + * An adversarial input could attempt to fudge the split detector, + * and make it split incompressible data, resulting in more block headers. + * Note that, since ZSTD_COMPRESSBOUND() assumes a worst case scenario of 1KB per block, + * and the splitter never creates blocks that small (current lower limit is 8 KB), + * there is already no risk to expand beyond ZSTD_COMPRESSBOUND() limit. + * But if the goal is to not expand by more than 3-bytes per 128 KB full block, + * then yes, it becomes possible to make the block splitter oversplit incompressible data. + * Using @savings, we enforce an even more conservative condition, + * requiring the presence of enough savings (at least 3 bytes) to authorize splitting, + * otherwise only full blocks are used. + * But being conservative is fine, + * since splitting barely compressible blocks is not fruitful anyway */ + savings += (S64)blockSize - (S64)cSize; + + ip += blockSize; + assert(remaining >= blockSize); + remaining -= blockSize; + op += cSize; + assert(dstCapacity >= cSize); + dstCapacity -= cSize; + cctx->isFirstBlock = 0; + DEBUGLOG(5, "ZSTD_compress_frameChunk: adding a block of size %u", + (unsigned)cSize); + } } + + if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending; + return (size_t)(op-ostart); +} + + +static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity, + const ZSTD_CCtx_params* params, + U64 pledgedSrcSize, U32 dictID) +{ + BYTE* const op = (BYTE*)dst; + U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */ + U32 const dictIDSizeCode = params->fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */ + U32 const checksumFlag = params->fParams.checksumFlag>0; + U32 const windowSize = (U32)1 << params->cParams.windowLog; + U32 const singleSegment = params->fParams.contentSizeFlag && (windowSize >= pledgedSrcSize); + BYTE const windowLogByte = (BYTE)((params->cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3); + U32 const fcsCode = params->fParams.contentSizeFlag ? + (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0; /* 0-3 */ + BYTE const frameHeaderDescriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) ); + size_t pos=0; + + assert(!(params->fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)); + RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall, + "dst buf is too small to fit worst-case frame header size."); + DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u", + !params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode); + if (params->format == ZSTD_f_zstd1) { + MEM_writeLE32(dst, ZSTD_MAGICNUMBER); + pos = 4; + } + op[pos++] = frameHeaderDescriptionByte; + if (!singleSegment) op[pos++] = windowLogByte; + switch(dictIDSizeCode) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : break; + case 1 : op[pos] = (BYTE)(dictID); pos++; break; + case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break; + case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break; + } + switch(fcsCode) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break; + case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break; + case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break; + case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break; + } + return pos; +} + +/* ZSTD_writeSkippableFrame_advanced() : + * Writes out a skippable frame with the specified magic number variant (16 are supported), + * from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15, and the desired source data. + * + * Returns the total number of bytes written, or a ZSTD error code. + */ +size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity, + const void* src, size_t srcSize, unsigned magicVariant) { + BYTE* op = (BYTE*)dst; + RETURN_ERROR_IF(dstCapacity < srcSize + ZSTD_SKIPPABLEHEADERSIZE /* Skippable frame overhead */, + dstSize_tooSmall, "Not enough room for skippable frame"); + RETURN_ERROR_IF(srcSize > (unsigned)0xFFFFFFFF, srcSize_wrong, "Src size too large for skippable frame"); + RETURN_ERROR_IF(magicVariant > 15, parameter_outOfBound, "Skippable frame magic number variant not supported"); + + MEM_writeLE32(op, (U32)(ZSTD_MAGIC_SKIPPABLE_START + magicVariant)); + MEM_writeLE32(op+4, (U32)srcSize); + ZSTD_memcpy(op+8, src, srcSize); + return srcSize + ZSTD_SKIPPABLEHEADERSIZE; +} + +/* ZSTD_writeLastEmptyBlock() : + * output an empty Block with end-of-frame mark to complete a frame + * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h)) + * or an error code if `dstCapacity` is too small (stage == ZSTDcs_init); + assert(nbSeq == 0 || cctx->appliedParams.ldmParams.enableLdm != ZSTD_ps_enable); + cctx->externSeqStore.seq = seq; + cctx->externSeqStore.size = nbSeq; + cctx->externSeqStore.capacity = nbSeq; + cctx->externSeqStore.pos = 0; + cctx->externSeqStore.posInSequence = 0; +} + + +static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 frame, U32 lastFrameChunk) +{ + ZSTD_MatchState_t* const ms = &cctx->blockState.matchState; + size_t fhSize = 0; + + DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u", + cctx->stage, (unsigned)srcSize); + RETURN_ERROR_IF(cctx->stage==ZSTDcs_created, stage_wrong, + "missing init (ZSTD_compressBegin)"); + + if (frame && (cctx->stage==ZSTDcs_init)) { + fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, + cctx->pledgedSrcSizePlusOne-1, cctx->dictID); + FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed"); + assert(fhSize <= dstCapacity); + dstCapacity -= fhSize; + dst = (char*)dst + fhSize; + cctx->stage = ZSTDcs_ongoing; + } + + if (!srcSize) return fhSize; /* do not generate an empty block if no input */ + + if (!ZSTD_window_update(&ms->window, src, srcSize, ms->forceNonContiguous)) { + ms->forceNonContiguous = 0; + ms->nextToUpdate = ms->window.dictLimit; + } + if (cctx->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) { + ZSTD_window_update(&cctx->ldmState.window, src, srcSize, /* forceNonContiguous */ 0); + } + + if (!frame) { + /* overflow check and correction for block mode */ + ZSTD_overflowCorrectIfNeeded( + ms, &cctx->workspace, &cctx->appliedParams, + src, (BYTE const*)src + srcSize); + } + + DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSizeMax); + { size_t const cSize = frame ? + ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) : + ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */); + FORWARD_IF_ERROR(cSize, "%s", frame ? "ZSTD_compress_frameChunk failed" : "ZSTD_compressBlock_internal failed"); + cctx->consumedSrcSize += srcSize; + cctx->producedCSize += (cSize + fhSize); + assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0)); + if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */ + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1); + RETURN_ERROR_IF( + cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne, + srcSize_wrong, + "error : pledgedSrcSize = %u, while realSrcSize >= %u", + (unsigned)cctx->pledgedSrcSizePlusOne-1, + (unsigned)cctx->consumedSrcSize); + } + return cSize + fhSize; + } +} + +size_t ZSTD_compressContinue_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressContinue (srcSize=%u)", (unsigned)srcSize); + return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */); +} + +/* NOTE: Must just wrap ZSTD_compressContinue_public() */ +size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + return ZSTD_compressContinue_public(cctx, dst, dstCapacity, src, srcSize); +} + +static size_t ZSTD_getBlockSize_deprecated(const ZSTD_CCtx* cctx) +{ + ZSTD_compressionParameters const cParams = cctx->appliedParams.cParams; + assert(!ZSTD_checkCParams(cParams)); + return MIN(cctx->appliedParams.maxBlockSize, (size_t)1 << cParams.windowLog); +} + +/* NOTE: Must just wrap ZSTD_getBlockSize_deprecated() */ +size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx) +{ + return ZSTD_getBlockSize_deprecated(cctx); +} + +/* NOTE: Must just wrap ZSTD_compressBlock_deprecated() */ +size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressBlock: srcSize = %u", (unsigned)srcSize); + { size_t const blockSizeMax = ZSTD_getBlockSize_deprecated(cctx); + RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong, "input is larger than a block"); } + + return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */); +} + +/* NOTE: Must just wrap ZSTD_compressBlock_deprecated() */ +size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_deprecated(cctx, dst, dstCapacity, src, srcSize); +} + +/*! ZSTD_loadDictionaryContent() : + * @return : 0, or an error code + */ +static size_t +ZSTD_loadDictionaryContent(ZSTD_MatchState_t* ms, + ldmState_t* ls, + ZSTD_cwksp* ws, + ZSTD_CCtx_params const* params, + const void* src, size_t srcSize, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp) +{ + const BYTE* ip = (const BYTE*) src; + const BYTE* const iend = ip + srcSize; + int const loadLdmDict = params->ldmParams.enableLdm == ZSTD_ps_enable && ls != NULL; + + /* Assert that the ms params match the params we're being given */ + ZSTD_assertEqualCParams(params->cParams, ms->cParams); + + { /* Ensure large dictionaries can't cause index overflow */ + + /* Allow the dictionary to set indices up to exactly ZSTD_CURRENT_MAX. + * Dictionaries right at the edge will immediately trigger overflow + * correction, but I don't want to insert extra constraints here. + */ + U32 maxDictSize = ZSTD_CURRENT_MAX - ZSTD_WINDOW_START_INDEX; + + int const CDictTaggedIndices = ZSTD_CDictIndicesAreTagged(¶ms->cParams); + if (CDictTaggedIndices && tfp == ZSTD_tfp_forCDict) { + /* Some dictionary matchfinders in zstd use "short cache", + * which treats the lower ZSTD_SHORT_CACHE_TAG_BITS of each + * CDict hashtable entry as a tag rather than as part of an index. + * When short cache is used, we need to truncate the dictionary + * so that its indices don't overlap with the tag. */ + U32 const shortCacheMaxDictSize = (1u << (32 - ZSTD_SHORT_CACHE_TAG_BITS)) - ZSTD_WINDOW_START_INDEX; + maxDictSize = MIN(maxDictSize, shortCacheMaxDictSize); + assert(!loadLdmDict); + } + + /* If the dictionary is too large, only load the suffix of the dictionary. */ + if (srcSize > maxDictSize) { + ip = iend - maxDictSize; + src = ip; + srcSize = maxDictSize; + } + } + + if (srcSize > ZSTD_CHUNKSIZE_MAX) { + /* We must have cleared our windows when our source is this large. */ + assert(ZSTD_window_isEmpty(ms->window)); + if (loadLdmDict) assert(ZSTD_window_isEmpty(ls->window)); + } + ZSTD_window_update(&ms->window, src, srcSize, /* forceNonContiguous */ 0); + + DEBUGLOG(4, "ZSTD_loadDictionaryContent: useRowMatchFinder=%d", (int)params->useRowMatchFinder); + + if (loadLdmDict) { /* Load the entire dict into LDM matchfinders. */ + DEBUGLOG(4, "ZSTD_loadDictionaryContent: Trigger loadLdmDict"); + ZSTD_window_update(&ls->window, src, srcSize, /* forceNonContiguous */ 0); + ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base); + ZSTD_ldm_fillHashTable(ls, ip, iend, ¶ms->ldmParams); + DEBUGLOG(4, "ZSTD_loadDictionaryContent: ZSTD_ldm_fillHashTable completes"); + } + + /* If the dict is larger than we can reasonably index in our tables, only load the suffix. */ + { U32 maxDictSize = 1U << MIN(MAX(params->cParams.hashLog + 3, params->cParams.chainLog + 1), 31); + if (srcSize > maxDictSize) { + ip = iend - maxDictSize; + src = ip; + srcSize = maxDictSize; + } + } + + ms->nextToUpdate = (U32)(ip - ms->window.base); + ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base); + ms->forceNonContiguous = params->deterministicRefPrefix; + + if (srcSize <= HASH_READ_SIZE) return 0; + + ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, iend); + + switch(params->cParams.strategy) + { + case ZSTD_fast: + ZSTD_fillHashTable(ms, iend, dtlm, tfp); + break; + case ZSTD_dfast: +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + ZSTD_fillDoubleHashTable(ms, iend, dtlm, tfp); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) + assert(srcSize >= HASH_READ_SIZE); + if (ms->dedicatedDictSearch) { + assert(ms->chainTable != NULL); + ZSTD_dedicatedDictSearch_lazy_loadDictionary(ms, iend-HASH_READ_SIZE); + } else { + assert(params->useRowMatchFinder != ZSTD_ps_auto); + if (params->useRowMatchFinder == ZSTD_ps_enable) { + size_t const tagTableSize = ((size_t)1 << params->cParams.hashLog); + ZSTD_memset(ms->tagTable, 0, tagTableSize); + ZSTD_row_update(ms, iend-HASH_READ_SIZE); + DEBUGLOG(4, "Using row-based hash table for lazy dict"); + } else { + ZSTD_insertAndFindFirstIndex(ms, iend-HASH_READ_SIZE); + DEBUGLOG(4, "Using chain-based hash table for lazy dict"); + } + } +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + case ZSTD_btlazy2: /* we want the dictionary table fully sorted */ + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) + assert(srcSize >= HASH_READ_SIZE); + DEBUGLOG(4, "Fill %u bytes into the Binary Tree", (unsigned)srcSize); + ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + default: + assert(0); /* not possible : not a valid strategy id */ + } + + ms->nextToUpdate = (U32)(iend - ms->window.base); + return 0; +} + + +/* Dictionaries that assign zero probability to symbols that show up causes problems + * when FSE encoding. Mark dictionaries with zero probability symbols as FSE_repeat_check + * and only dictionaries with 100% valid symbols can be assumed valid. + */ +static FSE_repeat ZSTD_dictNCountRepeat(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) +{ + U32 s; + if (dictMaxSymbolValue < maxSymbolValue) { + return FSE_repeat_check; + } + for (s = 0; s <= maxSymbolValue; ++s) { + if (normalizedCounter[s] == 0) { + return FSE_repeat_check; + } + } + return FSE_repeat_valid; +} + +size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, + const void* const dict, size_t dictSize) +{ + short offcodeNCount[MaxOff+1]; + unsigned offcodeMaxValue = MaxOff; + const BYTE* dictPtr = (const BYTE*)dict; /* skip magic num and dict ID */ + const BYTE* const dictEnd = dictPtr + dictSize; + dictPtr += 8; + bs->entropy.huf.repeatMode = HUF_repeat_check; + + { unsigned maxSymbolValue = 255; + unsigned hasZeroWeights = 1; + size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, + (size_t)(dictEnd-dictPtr), &hasZeroWeights); + + /* We only set the loaded table as valid if it contains all non-zero + * weights. Otherwise, we set it to check */ + if (!hasZeroWeights && maxSymbolValue == 255) + bs->entropy.huf.repeatMode = HUF_repeat_valid; + + RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted, ""); + dictPtr += hufHeaderSize; + } + + { unsigned offcodeLog; + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, ""); + /* fill all offset symbols to avoid garbage at end of table */ + RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( + bs->entropy.fse.offcodeCTable, + offcodeNCount, MaxOff, offcodeLog, + workspace, HUF_WORKSPACE_SIZE)), + dictionary_corrupted, ""); + /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ + dictPtr += offcodeHeaderSize; + } + + { short matchlengthNCount[MaxML+1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog; + size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, ""); + RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( + bs->entropy.fse.matchlengthCTable, + matchlengthNCount, matchlengthMaxValue, matchlengthLog, + workspace, HUF_WORKSPACE_SIZE)), + dictionary_corrupted, ""); + bs->entropy.fse.matchlength_repeatMode = ZSTD_dictNCountRepeat(matchlengthNCount, matchlengthMaxValue, MaxML); + dictPtr += matchlengthHeaderSize; + } + + { short litlengthNCount[MaxLL+1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog; + size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, ""); + RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( + bs->entropy.fse.litlengthCTable, + litlengthNCount, litlengthMaxValue, litlengthLog, + workspace, HUF_WORKSPACE_SIZE)), + dictionary_corrupted, ""); + bs->entropy.fse.litlength_repeatMode = ZSTD_dictNCountRepeat(litlengthNCount, litlengthMaxValue, MaxLL); + dictPtr += litlengthHeaderSize; + } + + RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, ""); + bs->rep[0] = MEM_readLE32(dictPtr+0); + bs->rep[1] = MEM_readLE32(dictPtr+4); + bs->rep[2] = MEM_readLE32(dictPtr+8); + dictPtr += 12; + + { size_t const dictContentSize = (size_t)(dictEnd - dictPtr); + U32 offcodeMax = MaxOff; + if (dictContentSize <= ((U32)-1) - 128 KB) { + U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */ + offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */ + } + /* All offset values <= dictContentSize + 128 KB must be representable for a valid table */ + bs->entropy.fse.offcode_repeatMode = ZSTD_dictNCountRepeat(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)); + + /* All repCodes must be <= dictContentSize and != 0 */ + { U32 u; + for (u=0; u<3; u++) { + RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, ""); + RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, ""); + } } } + + return (size_t)(dictPtr - (const BYTE*)dict); +} + +/* Dictionary format : + * See : + * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#dictionary-format + */ +/*! ZSTD_loadZstdDictionary() : + * @return : dictID, or an error code + * assumptions : magic number supposed already checked + * dictSize supposed >= 8 + */ +static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, + ZSTD_MatchState_t* ms, + ZSTD_cwksp* ws, + ZSTD_CCtx_params const* params, + const void* dict, size_t dictSize, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp, + void* workspace) +{ + const BYTE* dictPtr = (const BYTE*)dict; + const BYTE* const dictEnd = dictPtr + dictSize; + size_t dictID; + size_t eSize; + ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<= 8); + assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY); + + dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr + 4 /* skip magic number */ ); + eSize = ZSTD_loadCEntropy(bs, workspace, dict, dictSize); + FORWARD_IF_ERROR(eSize, "ZSTD_loadCEntropy failed"); + dictPtr += eSize; + + { + size_t const dictContentSize = (size_t)(dictEnd - dictPtr); + FORWARD_IF_ERROR(ZSTD_loadDictionaryContent( + ms, NULL, ws, params, dictPtr, dictContentSize, dtlm, tfp), ""); + } + return dictID; +} + +/** ZSTD_compress_insertDictionary() : +* @return : dictID, or an error code */ +static size_t +ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, + ZSTD_MatchState_t* ms, + ldmState_t* ls, + ZSTD_cwksp* ws, + const ZSTD_CCtx_params* params, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp, + void* workspace) +{ + DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize); + if ((dict==NULL) || (dictSize<8)) { + RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, ""); + return 0; + } + + ZSTD_reset_compressedBlockState(bs); + + /* dict restricted modes */ + if (dictContentType == ZSTD_dct_rawContent) + return ZSTD_loadDictionaryContent(ms, ls, ws, params, dict, dictSize, dtlm, tfp); + + if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) { + if (dictContentType == ZSTD_dct_auto) { + DEBUGLOG(4, "raw content dictionary detected"); + return ZSTD_loadDictionaryContent( + ms, ls, ws, params, dict, dictSize, dtlm, tfp); + } + RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, ""); + assert(0); /* impossible */ + } + + /* dict as full zstd dictionary */ + return ZSTD_loadZstdDictionary( + bs, ms, ws, params, dict, dictSize, dtlm, tfp, workspace); +} + +#define ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF (128 KB) +#define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6ULL) + +/*! ZSTD_compressBegin_internal() : + * Assumption : either @dict OR @cdict (or none) is non-NULL, never both + * @return : 0, or an error code */ +static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + size_t const dictContentSize = cdict ? cdict->dictContentSize : dictSize; +#if ZSTD_TRACE + cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0; +#endif + DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params->cParams.windowLog); + /* params are supposed to be fully validated at this point */ + assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams))); + assert(!((dict) && (cdict))); /* either dict or cdict, not both */ + if ( (cdict) + && (cdict->dictContentSize > 0) + && ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF + || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER + || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN + || cdict->compressionLevel == 0) + && (params->attachDictPref != ZSTD_dictForceLoad) ) { + return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff); + } + + FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, + dictContentSize, + ZSTDcrp_makeClean, zbuff) , ""); + { size_t const dictID = cdict ? + ZSTD_compress_insertDictionary( + cctx->blockState.prevCBlock, &cctx->blockState.matchState, + &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent, + cdict->dictContentSize, cdict->dictContentType, dtlm, + ZSTD_tfp_forCCtx, cctx->tmpWorkspace) + : ZSTD_compress_insertDictionary( + cctx->blockState.prevCBlock, &cctx->blockState.matchState, + &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, dict, dictSize, + dictContentType, dtlm, ZSTD_tfp_forCCtx, cctx->tmpWorkspace); + FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed"); + assert(dictID <= UINT_MAX); + cctx->dictID = (U32)dictID; + cctx->dictContentSize = dictContentSize; + } + return 0; +} + +size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + unsigned long long pledgedSrcSize) +{ + DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params->cParams.windowLog); + /* compression parameters verification and optimization */ + FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) , ""); + return ZSTD_compressBegin_internal(cctx, + dict, dictSize, dictContentType, dtlm, + cdict, + params, pledgedSrcSize, + ZSTDb_not_buffered); +} + +/*! ZSTD_compressBegin_advanced() : +* @return : 0, or an error code */ +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_parameters params, unsigned long long pledgedSrcSize) +{ + ZSTD_CCtx_params cctxParams; + ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, ZSTD_NO_CLEVEL); + return ZSTD_compressBegin_advanced_internal(cctx, + dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, + NULL /*cdict*/, + &cctxParams, pledgedSrcSize); +} + +static size_t +ZSTD_compressBegin_usingDict_deprecated(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) +{ + ZSTD_CCtx_params cctxParams; + { ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_noAttachDict); + ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel); + } + DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize); + return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL, + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered); +} + +size_t +ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) +{ + return ZSTD_compressBegin_usingDict_deprecated(cctx, dict, dictSize, compressionLevel); +} + +size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel) +{ + return ZSTD_compressBegin_usingDict_deprecated(cctx, NULL, 0, compressionLevel); +} + + +/*! ZSTD_writeEpilogue() : +* Ends a frame. +* @return : nb of bytes written into dst (or an error code) */ +static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity) +{ + BYTE* const ostart = (BYTE*)dst; + BYTE* op = ostart; + + DEBUGLOG(4, "ZSTD_writeEpilogue"); + RETURN_ERROR_IF(cctx->stage == ZSTDcs_created, stage_wrong, "init missing"); + + /* special case : empty frame */ + if (cctx->stage == ZSTDcs_init) { + size_t fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0); + FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed"); + dstCapacity -= fhSize; + op += fhSize; + cctx->stage = ZSTDcs_ongoing; + } + + if (cctx->stage != ZSTDcs_ending) { + /* write one last empty block, make it the "last" block */ + U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0; + ZSTD_STATIC_ASSERT(ZSTD_BLOCKHEADERSIZE == 3); + RETURN_ERROR_IF(dstCapacity<3, dstSize_tooSmall, "no room for epilogue"); + MEM_writeLE24(op, cBlockHeader24); + op += ZSTD_blockHeaderSize; + dstCapacity -= ZSTD_blockHeaderSize; + } + + if (cctx->appliedParams.fParams.checksumFlag) { + U32 const checksum = (U32) XXH64_digest(&cctx->xxhState); + RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum"); + DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", (unsigned)checksum); + MEM_writeLE32(op, checksum); + op += 4; + } + + cctx->stage = ZSTDcs_created; /* return to "created but no init" status */ + return (size_t)(op-ostart); +} + +void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize) +{ +#if ZSTD_TRACE + if (cctx->traceCtx && ZSTD_trace_compress_end != NULL) { + int const streaming = cctx->inBuffSize > 0 || cctx->outBuffSize > 0 || cctx->appliedParams.nbWorkers > 0; + ZSTD_Trace trace; + ZSTD_memset(&trace, 0, sizeof(trace)); + trace.version = ZSTD_VERSION_NUMBER; + trace.streaming = streaming; + trace.dictionaryID = cctx->dictID; + trace.dictionarySize = cctx->dictContentSize; + trace.uncompressedSize = cctx->consumedSrcSize; + trace.compressedSize = cctx->producedCSize + extraCSize; + trace.params = &cctx->appliedParams; + trace.cctx = cctx; + ZSTD_trace_compress_end(cctx->traceCtx, &trace); + } + cctx->traceCtx = 0; +#else + (void)cctx; + (void)extraCSize; +#endif +} + +size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + size_t endResult; + size_t const cSize = ZSTD_compressContinue_internal(cctx, + dst, dstCapacity, src, srcSize, + 1 /* frame mode */, 1 /* last chunk */); + FORWARD_IF_ERROR(cSize, "ZSTD_compressContinue_internal failed"); + endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize); + FORWARD_IF_ERROR(endResult, "ZSTD_writeEpilogue failed"); + assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0)); + if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */ + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1); + DEBUGLOG(4, "end of frame : controlling src size"); + RETURN_ERROR_IF( + cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1, + srcSize_wrong, + "error : pledgedSrcSize = %u, while realSrcSize = %u", + (unsigned)cctx->pledgedSrcSizePlusOne-1, + (unsigned)cctx->consumedSrcSize); + } + ZSTD_CCtx_trace(cctx, endResult); + return cSize + endResult; +} + +/* NOTE: Must just wrap ZSTD_compressEnd_public() */ +size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); +} + +size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + ZSTD_parameters params) +{ + DEBUGLOG(4, "ZSTD_compress_advanced"); + FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); + ZSTD_CCtxParams_init_internal(&cctx->simpleApiParams, ¶ms, ZSTD_NO_CLEVEL); + return ZSTD_compress_advanced_internal(cctx, + dst, dstCapacity, + src, srcSize, + dict, dictSize, + &cctx->simpleApiParams); +} + +/* Internal */ +size_t ZSTD_compress_advanced_internal( + ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + const ZSTD_CCtx_params* params) +{ + DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize); + FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx, + dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL, + params, srcSize, ZSTDb_not_buffered) , ""); + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); +} + +size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + int compressionLevel) +{ + { + ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict); + assert(params.fParams.contentSizeFlag == 1); + ZSTD_CCtxParams_init_internal(&cctx->simpleApiParams, ¶ms, (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT: compressionLevel); + } + DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize); + return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctx->simpleApiParams); +} + +size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel) +{ + DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (unsigned)srcSize); + assert(cctx != NULL); + return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel); +} + +size_t ZSTD_compress(void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel) +{ + size_t result; +#if ZSTD_COMPRESS_HEAPMODE + ZSTD_CCtx* cctx = ZSTD_createCCtx(); + RETURN_ERROR_IF(!cctx, memory_allocation, "ZSTD_createCCtx failed"); + result = ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel); + ZSTD_freeCCtx(cctx); +#else + ZSTD_CCtx ctxBody; + ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem); + result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel); + ZSTD_freeCCtxContent(&ctxBody); /* can't free ctxBody itself, as it's on stack; free only heap content */ +#endif + return result; +} + + +/* ===== Dictionary API ===== */ + +/*! ZSTD_estimateCDictSize_advanced() : + * Estimate amount of memory that will be needed to create a dictionary with following arguments */ +size_t ZSTD_estimateCDictSize_advanced( + size_t dictSize, ZSTD_compressionParameters cParams, + ZSTD_dictLoadMethod_e dictLoadMethod) +{ + DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (unsigned)sizeof(ZSTD_CDict)); + return ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + /* enableDedicatedDictSearch == 1 ensures that CDict estimation will not be too small + * in case we are using DDS with row-hash. */ + + ZSTD_sizeof_matchState(&cParams, ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams), + /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 + : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void *)))); +} + +size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel) +{ + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy); +} + +size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict) +{ + if (cdict==NULL) return 0; /* support sizeof on NULL */ + DEBUGLOG(5, "sizeof(*cdict) : %u", (unsigned)sizeof(*cdict)); + /* cdict may be in the workspace */ + return (cdict->workspace.workspace == cdict ? 0 : sizeof(*cdict)) + + ZSTD_cwksp_sizeof(&cdict->workspace); +} + +static size_t ZSTD_initCDict_internal( + ZSTD_CDict* cdict, + const void* dictBuffer, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_CCtx_params params) +{ + DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (unsigned)dictContentType); + assert(!ZSTD_checkCParams(params.cParams)); + cdict->matchState.cParams = params.cParams; + cdict->matchState.dedicatedDictSearch = params.enableDedicatedDictSearch; + if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) { + cdict->dictContent = dictBuffer; + } else { + void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*))); + RETURN_ERROR_IF(!internalBuffer, memory_allocation, "NULL pointer!"); + cdict->dictContent = internalBuffer; + ZSTD_memcpy(internalBuffer, dictBuffer, dictSize); + } + cdict->dictContentSize = dictSize; + cdict->dictContentType = dictContentType; + + cdict->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cdict->workspace, HUF_WORKSPACE_SIZE); + + + /* Reset the state to no dictionary */ + ZSTD_reset_compressedBlockState(&cdict->cBlockState); + FORWARD_IF_ERROR(ZSTD_reset_matchState( + &cdict->matchState, + &cdict->workspace, + ¶ms.cParams, + params.useRowMatchFinder, + ZSTDcrp_makeClean, + ZSTDirp_reset, + ZSTD_resetTarget_CDict), ""); + /* (Maybe) load the dictionary + * Skips loading the dictionary if it is < 8 bytes. + */ + { params.compressionLevel = ZSTD_CLEVEL_DEFAULT; + params.fParams.contentSizeFlag = 1; + { size_t const dictID = ZSTD_compress_insertDictionary( + &cdict->cBlockState, &cdict->matchState, NULL, &cdict->workspace, + ¶ms, cdict->dictContent, cdict->dictContentSize, + dictContentType, ZSTD_dtlm_full, ZSTD_tfp_forCDict, cdict->entropyWorkspace); + FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed"); + assert(dictID <= (size_t)(U32)-1); + cdict->dictID = (U32)dictID; + } + } + + return 0; +} + +static ZSTD_CDict* +ZSTD_createCDict_advanced_internal(size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_compressionParameters cParams, + ZSTD_ParamSwitch_e useRowMatchFinder, + int enableDedicatedDictSearch, + ZSTD_customMem customMem) +{ + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + DEBUGLOG(3, "ZSTD_createCDict_advanced_internal (dictSize=%u)", (unsigned)dictSize); + + { size_t const workspaceSize = + ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + + ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, enableDedicatedDictSearch, /* forCCtx */ 0) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 + : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*)))); + void* const workspace = ZSTD_customMalloc(workspaceSize, customMem); + ZSTD_cwksp ws; + ZSTD_CDict* cdict; + + if (!workspace) { + ZSTD_customFree(workspace, customMem); + return NULL; + } + + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_dynamic_alloc); + + cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict)); + assert(cdict != NULL); + ZSTD_cwksp_move(&cdict->workspace, &ws); + cdict->customMem = customMem; + cdict->compressionLevel = ZSTD_NO_CLEVEL; /* signals advanced API usage */ + cdict->useRowMatchFinder = useRowMatchFinder; + return cdict; + } +} + +ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams, + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params cctxParams; + ZSTD_memset(&cctxParams, 0, sizeof(cctxParams)); + DEBUGLOG(3, "ZSTD_createCDict_advanced, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType); + ZSTD_CCtxParams_init(&cctxParams, 0); + cctxParams.cParams = cParams; + cctxParams.customMem = customMem; + return ZSTD_createCDict_advanced2( + dictBuffer, dictSize, + dictLoadMethod, dictContentType, + &cctxParams, customMem); +} + +ZSTD_CDict* ZSTD_createCDict_advanced2( + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + const ZSTD_CCtx_params* originalCctxParams, + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params cctxParams = *originalCctxParams; + ZSTD_compressionParameters cParams; + ZSTD_CDict* cdict; + + DEBUGLOG(3, "ZSTD_createCDict_advanced2, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType); + if (!customMem.customAlloc ^ !customMem.customFree) return NULL; + + if (cctxParams.enableDedicatedDictSearch) { + cParams = ZSTD_dedicatedDictSearch_getCParams( + cctxParams.compressionLevel, dictSize); + ZSTD_overrideCParams(&cParams, &cctxParams.cParams); + } else { + cParams = ZSTD_getCParamsFromCCtxParams( + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + } + + if (!ZSTD_dedicatedDictSearch_isSupported(&cParams)) { + /* Fall back to non-DDSS params */ + cctxParams.enableDedicatedDictSearch = 0; + cParams = ZSTD_getCParamsFromCCtxParams( + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + } + + DEBUGLOG(3, "ZSTD_createCDict_advanced2: DedicatedDictSearch=%u", cctxParams.enableDedicatedDictSearch); + cctxParams.cParams = cParams; + cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams); + + cdict = ZSTD_createCDict_advanced_internal(dictSize, + dictLoadMethod, cctxParams.cParams, + cctxParams.useRowMatchFinder, cctxParams.enableDedicatedDictSearch, + customMem); + + if (!cdict || ZSTD_isError( ZSTD_initCDict_internal(cdict, + dict, dictSize, + dictLoadMethod, dictContentType, + cctxParams) )) { + ZSTD_freeCDict(cdict); + return NULL; + } + + return cdict; +} + +ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel) +{ + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize, + ZSTD_dlm_byCopy, ZSTD_dct_auto, + cParams, ZSTD_defaultCMem); + if (cdict) + cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel; + return cdict; +} + +ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel) +{ + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize, + ZSTD_dlm_byRef, ZSTD_dct_auto, + cParams, ZSTD_defaultCMem); + if (cdict) + cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel; + return cdict; +} + +size_t ZSTD_freeCDict(ZSTD_CDict* cdict) +{ + if (cdict==NULL) return 0; /* support free on NULL */ + { ZSTD_customMem const cMem = cdict->customMem; + int cdictInWorkspace = ZSTD_cwksp_owns_buffer(&cdict->workspace, cdict); + ZSTD_cwksp_free(&cdict->workspace, cMem); + if (!cdictInWorkspace) { + ZSTD_customFree(cdict, cMem); + } + return 0; + } +} + +/*! ZSTD_initStaticCDict_advanced() : + * Generate a digested dictionary in provided memory area. + * workspace: The memory area to emplace the dictionary into. + * Provided pointer must 8-bytes aligned. + * It must outlive dictionary usage. + * workspaceSize: Use ZSTD_estimateCDictSize() + * to determine how large workspace must be. + * cParams : use ZSTD_getCParams() to transform a compression level + * into its relevant cParams. + * @return : pointer to ZSTD_CDict*, or NULL if error (size too small) + * Note : there is no corresponding "free" function. + * Since workspace was allocated externally, it must be freed externally. + */ +const ZSTD_CDict* ZSTD_initStaticCDict( + void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams) +{ + ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams); + /* enableDedicatedDictSearch == 1 ensures matchstate is not too small in case this CDict will be used for DDS + row hash */ + size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0); + size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 + : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*)))) + + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + + matchStateSize; + ZSTD_CDict* cdict; + ZSTD_CCtx_params params; + + DEBUGLOG(4, "ZSTD_initStaticCDict (dictSize==%u)", (unsigned)dictSize); + if ((size_t)workspace & 7) return NULL; /* 8-aligned */ + + { + ZSTD_cwksp ws; + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc); + cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict)); + if (cdict == NULL) return NULL; + ZSTD_cwksp_move(&cdict->workspace, &ws); + } + + if (workspaceSize < neededSize) return NULL; + + ZSTD_CCtxParams_init(¶ms, 0); + params.cParams = cParams; + params.useRowMatchFinder = useRowMatchFinder; + cdict->useRowMatchFinder = useRowMatchFinder; + cdict->compressionLevel = ZSTD_NO_CLEVEL; + + if (ZSTD_isError( ZSTD_initCDict_internal(cdict, + dict, dictSize, + dictLoadMethod, dictContentType, + params) )) + return NULL; + + return cdict; +} + +ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict) +{ + assert(cdict != NULL); + return cdict->matchState.cParams; +} + +/*! ZSTD_getDictID_fromCDict() : + * Provides the dictID of the dictionary loaded into `cdict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict) +{ + if (cdict==NULL) return 0; + return cdict->dictID; +} + +/* ZSTD_compressBegin_usingCDict_internal() : + * Implementation of various ZSTD_compressBegin_usingCDict* functions. + */ +static size_t ZSTD_compressBegin_usingCDict_internal( + ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, + ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize) +{ + ZSTD_CCtx_params cctxParams; + DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_internal"); + RETURN_ERROR_IF(cdict==NULL, dictionary_wrong, "NULL pointer!"); + /* Initialize the cctxParams from the cdict */ + { + ZSTD_parameters params; + params.fParams = fParams; + params.cParams = ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF + || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER + || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN + || cdict->compressionLevel == 0 ) ? + ZSTD_getCParamsFromCDict(cdict) + : ZSTD_getCParams(cdict->compressionLevel, + pledgedSrcSize, + cdict->dictContentSize); + ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, cdict->compressionLevel); + } + /* Increase window log to fit the entire dictionary and source if the + * source size is known. Limit the increase to 19, which is the + * window log for compression level 1 with the largest source size. + */ + if (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN) { + U32 const limitedSrcSize = (U32)MIN(pledgedSrcSize, 1U << 19); + U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1; + cctxParams.cParams.windowLog = MAX(cctxParams.cParams.windowLog, limitedSrcLog); + } + return ZSTD_compressBegin_internal(cctx, + NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, + cdict, + &cctxParams, pledgedSrcSize, + ZSTDb_not_buffered); +} + + +/* ZSTD_compressBegin_usingCDict_advanced() : + * This function is DEPRECATED. + * cdict must be != NULL */ +size_t ZSTD_compressBegin_usingCDict_advanced( + ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, + ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize) +{ + return ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, pledgedSrcSize); +} + +/* ZSTD_compressBegin_usingCDict() : + * cdict must be != NULL */ +size_t ZSTD_compressBegin_usingCDict_deprecated(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; + return ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN); +} + +size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + return ZSTD_compressBegin_usingCDict_deprecated(cctx, cdict); +} + +/*! ZSTD_compress_usingCDict_internal(): + * Implementation of various ZSTD_compress_usingCDict* functions. + */ +static size_t ZSTD_compress_usingCDict_internal(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict, ZSTD_frameParameters fParams) +{ + FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, srcSize), ""); /* will check if cdict != NULL */ + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); +} + +/*! ZSTD_compress_usingCDict_advanced(): + * This function is DEPRECATED. + */ +size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict, ZSTD_frameParameters fParams) +{ + return ZSTD_compress_usingCDict_internal(cctx, dst, dstCapacity, src, srcSize, cdict, fParams); +} + +/*! ZSTD_compress_usingCDict() : + * Compression using a digested Dictionary. + * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. + * Note that compression parameters are decided at CDict creation time + * while frame parameters are hardcoded */ +size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict) +{ + ZSTD_frameParameters const fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; + return ZSTD_compress_usingCDict_internal(cctx, dst, dstCapacity, src, srcSize, cdict, fParams); +} + +/*====== Compression ======*/ + +/* ZSTD_validateSequence() : + * @offBase : must use the format required by ZSTD_storeSeq() + * @returns a ZSTD error code if sequence is not valid + */ +static size_t +ZSTD_validateSequence(U32 offBase, U32 matchLength, U32 minMatch, + size_t posInSrc, U32 windowLog, size_t dictSize, int useSequenceProducer) +{ + U32 const windowSize = 1u << windowLog; + /* posInSrc represents the amount of data the decoder would decode up to this point. + * As long as the amount of data decoded is less than or equal to window size, offsets may be + * larger than the total length of output decoded in order to reference the dict, even larger than + * window size. After output surpasses windowSize, we're limited to windowSize offsets again. + */ + size_t const offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize; + size_t const matchLenLowerBound = (minMatch == 3 || useSequenceProducer) ? 3 : 4; + RETURN_ERROR_IF(offBase > OFFSET_TO_OFFBASE(offsetBound), externalSequences_invalid, "Offset too large!"); + /* Validate maxNbSeq is large enough for the given matchLength and minMatch */ + RETURN_ERROR_IF(matchLength < matchLenLowerBound, externalSequences_invalid, "Matchlength too small for the minMatch"); + return 0; +} + +/* Returns an offset code, given a sequence's raw offset, the ongoing repcode array, and whether litLength == 0 */ +static U32 ZSTD_finalizeOffBase(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 ll0) +{ + U32 offBase = OFFSET_TO_OFFBASE(rawOffset); + + if (!ll0 && rawOffset == rep[0]) { + offBase = REPCODE1_TO_OFFBASE; + } else if (rawOffset == rep[1]) { + offBase = REPCODE_TO_OFFBASE(2 - ll0); + } else if (rawOffset == rep[2]) { + offBase = REPCODE_TO_OFFBASE(3 - ll0); + } else if (ll0 && rawOffset == rep[0] - 1) { + offBase = REPCODE3_TO_OFFBASE; + } + return offBase; +} + +/* This function scans through an array of ZSTD_Sequence, + * storing the sequences it reads, until it reaches a block delimiter. + * Note that the block delimiter includes the last literals of the block. + * @blockSize must be == sum(sequence_lengths). + * @returns @blockSize on success, and a ZSTD_error otherwise. + */ +static size_t +ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx, + ZSTD_SequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize, + ZSTD_ParamSwitch_e externalRepSearch) +{ + U32 idx = seqPos->idx; + U32 const startIdx = idx; + BYTE const* ip = (BYTE const*)(src); + const BYTE* const iend = ip + blockSize; + Repcodes_t updatedRepcodes; + U32 dictSize; + + DEBUGLOG(5, "ZSTD_transferSequences_wBlockDelim (blockSize = %zu)", blockSize); + + if (cctx->cdict) { + dictSize = (U32)cctx->cdict->dictContentSize; + } else if (cctx->prefixDict.dict) { + dictSize = (U32)cctx->prefixDict.dictSize; + } else { + dictSize = 0; + } + ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + for (; idx < inSeqsSize && (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0); ++idx) { + U32 const litLength = inSeqs[idx].litLength; + U32 const matchLength = inSeqs[idx].matchLength; + U32 offBase; + + if (externalRepSearch == ZSTD_ps_disable) { + offBase = OFFSET_TO_OFFBASE(inSeqs[idx].offset); + } else { + U32 const ll0 = (litLength == 0); + offBase = ZSTD_finalizeOffBase(inSeqs[idx].offset, updatedRepcodes.rep, ll0); + ZSTD_updateRep(updatedRepcodes.rep, offBase, ll0); + } + + DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength); + if (cctx->appliedParams.validateSequences) { + seqPos->posInSrc += litLength + matchLength; + FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch, + seqPos->posInSrc, + cctx->appliedParams.cParams.windowLog, dictSize, + ZSTD_hasExtSeqProd(&cctx->appliedParams)), + "Sequence validation failed"); + } + RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, externalSequences_invalid, + "Not enough memory allocated. Try adjusting ZSTD_c_minMatch."); + ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength); + ip += matchLength + litLength; + } + RETURN_ERROR_IF(idx == inSeqsSize, externalSequences_invalid, "Block delimiter not found."); + + /* If we skipped repcode search while parsing, we need to update repcodes now */ + assert(externalRepSearch != ZSTD_ps_auto); + assert(idx >= startIdx); + if (externalRepSearch == ZSTD_ps_disable && idx != startIdx) { + U32* const rep = updatedRepcodes.rep; + U32 lastSeqIdx = idx - 1; /* index of last non-block-delimiter sequence */ + + if (lastSeqIdx >= startIdx + 2) { + rep[2] = inSeqs[lastSeqIdx - 2].offset; + rep[1] = inSeqs[lastSeqIdx - 1].offset; + rep[0] = inSeqs[lastSeqIdx].offset; + } else if (lastSeqIdx == startIdx + 1) { + rep[2] = rep[0]; + rep[1] = inSeqs[lastSeqIdx - 1].offset; + rep[0] = inSeqs[lastSeqIdx].offset; + } else { + assert(lastSeqIdx == startIdx); + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = inSeqs[lastSeqIdx].offset; + } + } + + ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t)); + + if (inSeqs[idx].litLength) { + DEBUGLOG(6, "Storing last literals of size: %u", inSeqs[idx].litLength); + ZSTD_storeLastLiterals(&cctx->seqStore, ip, inSeqs[idx].litLength); + ip += inSeqs[idx].litLength; + seqPos->posInSrc += inSeqs[idx].litLength; + } + RETURN_ERROR_IF(ip != iend, externalSequences_invalid, "Blocksize doesn't agree with block delimiter!"); + seqPos->idx = idx+1; + return blockSize; +} + +/*-===== Pre-defined compression levels =====-*/ +#include "clevels.h" + +int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } +int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; } +int ZSTD_defaultCLevel(void) { return ZSTD_CLEVEL_DEFAULT; } + +static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const compressionLevel, size_t const dictSize) +{ + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, 0, dictSize, ZSTD_cpm_createCDict); + switch (cParams.strategy) { + case ZSTD_fast: + case ZSTD_dfast: + break; + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + cParams.hashLog += ZSTD_LAZY_DDSS_BUCKET_LOG; + break; + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + } + return cParams; +} + +static int ZSTD_dedicatedDictSearch_isSupported( + ZSTD_compressionParameters const* cParams) +{ + return (cParams->strategy >= ZSTD_greedy) + && (cParams->strategy <= ZSTD_lazy2) + && (cParams->hashLog > cParams->chainLog) + && (cParams->chainLog <= 24); +} + +/** + * Reverses the adjustment applied to cparams when enabling dedicated dict + * search. This is used to recover the params set to be used in the working + * context. (Otherwise, those tables would also grow.) + */ +static void ZSTD_dedicatedDictSearch_revertCParams( + ZSTD_compressionParameters* cParams) { + switch (cParams->strategy) { + case ZSTD_fast: + case ZSTD_dfast: + break; + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG; + if (cParams->hashLog < ZSTD_HASHLOG_MIN) { + cParams->hashLog = ZSTD_HASHLOG_MIN; + } + break; + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + } +} + +static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + switch (mode) { + case ZSTD_cpm_unknown: + case ZSTD_cpm_noAttachDict: + case ZSTD_cpm_createCDict: + break; + case ZSTD_cpm_attachDict: + dictSize = 0; + break; + default: + assert(0); + break; + } + { int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN; + size_t const addedSize = unknown && dictSize > 0 ? 500 : 0; + return unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize; + } +} + +/*! ZSTD_getCParams_internal() : + * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize. + * Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown. + * Use dictSize == 0 for unknown or unused. + * Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_CParamMode_e`. */ +static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + U64 const rSize = ZSTD_getCParamRowSize(srcSizeHint, dictSize, mode); + U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); + int row; + DEBUGLOG(5, "ZSTD_getCParams_internal (cLevel=%i)", compressionLevel); + + /* row */ + if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT; /* 0 == default */ + else if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */ + else if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL; + else row = compressionLevel; + + { ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row]; + DEBUGLOG(5, "ZSTD_getCParams_internal selected tableID: %u row: %u strat: %u", tableID, row, (U32)cp.strategy); + /* acceleration factor */ + if (compressionLevel < 0) { + int const clampedCompressionLevel = MAX(ZSTD_minCLevel(), compressionLevel); + cp.targetLength = (unsigned)(-clampedCompressionLevel); + } + /* refine parameters based on srcSize & dictSize */ + return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize, mode, ZSTD_ps_auto); + } +} + +/*! ZSTD_getCParams() : + * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize. + * Size values are optional, provide 0 if not known or unused */ +ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) +{ + if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN; + return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown); +} + +/*! ZSTD_getParams() : + * same idea as ZSTD_getCParams() + * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`). + * Fields of `ZSTD_frameParameters` are set to default values */ +static ZSTD_parameters +ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + ZSTD_parameters params; + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode); + DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel); + ZSTD_memset(¶ms, 0, sizeof(params)); + params.cParams = cParams; + params.fParams.contentSizeFlag = 1; + return params; +} + +/*! ZSTD_getParams() : + * same idea as ZSTD_getCParams() + * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`). + * Fields of `ZSTD_frameParameters` are set to default values */ +ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) +{ + if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN; + return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown); +} + +void ZSTD_registerSequenceProducer( + ZSTD_CCtx* zc, + void* extSeqProdState, + ZSTD_sequenceProducer_F extSeqProdFunc) +{ + assert(zc != NULL); + ZSTD_CCtxParams_registerSequenceProducer( + &zc->requestedParams, extSeqProdState, extSeqProdFunc + ); +} + +void ZSTD_CCtxParams_registerSequenceProducer( + ZSTD_CCtx_params* params, + void* extSeqProdState, + ZSTD_sequenceProducer_F extSeqProdFunc) +{ + assert(params != NULL); + if (extSeqProdFunc != NULL) { + params->extSeqProdFunc = extSeqProdFunc; + params->extSeqProdState = extSeqProdState; + } else { + params->extSeqProdFunc = NULL; + params->extSeqProdState = NULL; + } +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_internal.h b/src/commonlib/bsd/zstd/compress/zstd_compress_internal.h new file mode 100644 index 0000000000..1d26c60867 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_internal.h @@ -0,0 +1,1625 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This header contains definitions + * that shall **only** be used by modules within lib/compress. + */ + +#ifndef ZSTD_COMPRESS_H +#define ZSTD_COMPRESS_H + +/*-************************************* +* Dependencies +***************************************/ +#include "../common/zstd_internal.h" +#include "zstd_cwksp.h" +#include "../common/zstd_bits.h" /* ZSTD_highbit32, ZSTD_NbCommonBytes */ +#include "zstd_preSplit.h" /* ZSTD_SLIPBLOCK_WORKSPACESIZE */ + +/*-************************************* +* Constants +***************************************/ +#define kSearchStrength 8 +#define HASH_READ_SIZE 8 +#define ZSTD_DUBT_UNSORTED_MARK 1 /* For btlazy2 strategy, index ZSTD_DUBT_UNSORTED_MARK==1 means "unsorted". + It could be confused for a real successor at index "1", if sorted as larger than its predecessor. + It's not a big deal though : candidate will just be sorted again. + Additionally, candidate position 1 will be lost. + But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss. + The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table reuse with a different strategy. + This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */ + + +/*-************************************* +* Context memory management +***************************************/ +typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e; +typedef enum { zcss_init=0, zcss_load, zcss_flush } ZSTD_cStreamStage; + +typedef struct ZSTD_prefixDict_s { + const void* dict; + size_t dictSize; + ZSTD_dictContentType_e dictContentType; +} ZSTD_prefixDict; + +typedef struct { + void* dictBuffer; + void const* dict; + size_t dictSize; + ZSTD_dictContentType_e dictContentType; + ZSTD_CDict* cdict; +} ZSTD_localDict; + +typedef struct { + HUF_CElt CTable[HUF_CTABLE_SIZE_ST(255)]; + HUF_repeat repeatMode; +} ZSTD_hufCTables_t; + +typedef struct { + FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)]; + FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)]; + FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)]; + FSE_repeat offcode_repeatMode; + FSE_repeat matchlength_repeatMode; + FSE_repeat litlength_repeatMode; +} ZSTD_fseCTables_t; + +typedef struct { + ZSTD_hufCTables_t huf; + ZSTD_fseCTables_t fse; +} ZSTD_entropyCTables_t; + +/*********************************************** +* Sequences * +***********************************************/ +typedef struct SeqDef_s { + U32 offBase; /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */ + U16 litLength; + U16 mlBase; /* mlBase == matchLength - MINMATCH */ +} SeqDef; + +/* Controls whether seqStore has a single "long" litLength or matchLength. See SeqStore_t. */ +typedef enum { + ZSTD_llt_none = 0, /* no longLengthType */ + ZSTD_llt_literalLength = 1, /* represents a long literal */ + ZSTD_llt_matchLength = 2 /* represents a long match */ +} ZSTD_longLengthType_e; + +typedef struct { + SeqDef* sequencesStart; + SeqDef* sequences; /* ptr to end of sequences */ + BYTE* litStart; + BYTE* lit; /* ptr to end of literals */ + BYTE* llCode; + BYTE* mlCode; + BYTE* ofCode; + size_t maxNbSeq; + size_t maxNbLit; + + /* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength + * in the seqStore that has a value larger than U16 (if it exists). To do so, we increment + * the existing value of the litLength or matchLength by 0x10000. + */ + ZSTD_longLengthType_e longLengthType; + U32 longLengthPos; /* Index of the sequence to apply long length modification to */ +} SeqStore_t; + +typedef struct { + U32 litLength; + U32 matchLength; +} ZSTD_SequenceLength; + +/** + * Returns the ZSTD_SequenceLength for the given sequences. It handles the decoding of long sequences + * indicated by longLengthPos and longLengthType, and adds MINMATCH back to matchLength. + */ +MEM_STATIC ZSTD_SequenceLength ZSTD_getSequenceLength(SeqStore_t const* seqStore, SeqDef const* seq) +{ + ZSTD_SequenceLength seqLen; + seqLen.litLength = seq->litLength; + seqLen.matchLength = seq->mlBase + MINMATCH; + if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) { + if (seqStore->longLengthType == ZSTD_llt_literalLength) { + seqLen.litLength += 0x10000; + } + if (seqStore->longLengthType == ZSTD_llt_matchLength) { + seqLen.matchLength += 0x10000; + } + } + return seqLen; +} + +const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */ +int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */ + + +/*********************************************** +* Entropy buffer statistics structs and funcs * +***********************************************/ +/** ZSTD_hufCTablesMetadata_t : + * Stores Literals Block Type for a super-block in hType, and + * huffman tree description in hufDesBuffer. + * hufDesSize refers to the size of huffman tree description in bytes. + * This metadata is populated in ZSTD_buildBlockEntropyStats_literals() */ +typedef struct { + SymbolEncodingType_e hType; + BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE]; + size_t hufDesSize; +} ZSTD_hufCTablesMetadata_t; + +/** ZSTD_fseCTablesMetadata_t : + * Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and + * fse tables in fseTablesBuffer. + * fseTablesSize refers to the size of fse tables in bytes. + * This metadata is populated in ZSTD_buildBlockEntropyStats_sequences() */ +typedef struct { + SymbolEncodingType_e llType; + SymbolEncodingType_e ofType; + SymbolEncodingType_e mlType; + BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE]; + size_t fseTablesSize; + size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */ +} ZSTD_fseCTablesMetadata_t; + +typedef struct { + ZSTD_hufCTablesMetadata_t hufMetadata; + ZSTD_fseCTablesMetadata_t fseMetadata; +} ZSTD_entropyCTablesMetadata_t; + +/** ZSTD_buildBlockEntropyStats() : + * Builds entropy for the block. + * @return : 0 on success or error code */ +size_t ZSTD_buildBlockEntropyStats( + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize); + +/********************************* +* Compression internals structs * +*********************************/ + +typedef struct { + U32 off; /* Offset sumtype code for the match, using ZSTD_storeSeq() format */ + U32 len; /* Raw length of match */ +} ZSTD_match_t; + +typedef struct { + U32 offset; /* Offset of sequence */ + U32 litLength; /* Length of literals prior to match */ + U32 matchLength; /* Raw length of match */ +} rawSeq; + +typedef struct { + rawSeq* seq; /* The start of the sequences */ + size_t pos; /* The index in seq where reading stopped. pos <= size. */ + size_t posInSequence; /* The position within the sequence at seq[pos] where reading + stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */ + size_t size; /* The number of sequences. <= capacity. */ + size_t capacity; /* The capacity starting from `seq` pointer */ +} RawSeqStore_t; + +UNUSED_ATTR static const RawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0}; + +typedef struct { + int price; /* price from beginning of segment to this position */ + U32 off; /* offset of previous match */ + U32 mlen; /* length of previous match */ + U32 litlen; /* nb of literals since previous match */ + U32 rep[ZSTD_REP_NUM]; /* offset history after previous match */ +} ZSTD_optimal_t; + +typedef enum { zop_dynamic=0, zop_predef } ZSTD_OptPrice_e; + +#define ZSTD_OPT_SIZE (ZSTD_OPT_NUM+3) +typedef struct { + /* All tables are allocated inside cctx->workspace by ZSTD_resetCCtx_internal() */ + unsigned* litFreq; /* table of literals statistics, of size 256 */ + unsigned* litLengthFreq; /* table of litLength statistics, of size (MaxLL+1) */ + unsigned* matchLengthFreq; /* table of matchLength statistics, of size (MaxML+1) */ + unsigned* offCodeFreq; /* table of offCode statistics, of size (MaxOff+1) */ + ZSTD_match_t* matchTable; /* list of found matches, of size ZSTD_OPT_SIZE */ + ZSTD_optimal_t* priceTable; /* All positions tracked by optimal parser, of size ZSTD_OPT_SIZE */ + + U32 litSum; /* nb of literals */ + U32 litLengthSum; /* nb of litLength codes */ + U32 matchLengthSum; /* nb of matchLength codes */ + U32 offCodeSum; /* nb of offset codes */ + U32 litSumBasePrice; /* to compare to log2(litfreq) */ + U32 litLengthSumBasePrice; /* to compare to log2(llfreq) */ + U32 matchLengthSumBasePrice;/* to compare to log2(mlfreq) */ + U32 offCodeSumBasePrice; /* to compare to log2(offreq) */ + ZSTD_OptPrice_e priceType; /* prices can be determined dynamically, or follow a pre-defined cost structure */ + const ZSTD_entropyCTables_t* symbolCosts; /* pre-calculated dictionary statistics */ + ZSTD_ParamSwitch_e literalCompressionMode; +} optState_t; + +typedef struct { + ZSTD_entropyCTables_t entropy; + U32 rep[ZSTD_REP_NUM]; +} ZSTD_compressedBlockState_t; + +typedef struct { + BYTE const* nextSrc; /* next block here to continue on current prefix */ + BYTE const* base; /* All regular indexes relative to this position */ + BYTE const* dictBase; /* extDict indexes relative to this position */ + U32 dictLimit; /* below that point, need extDict */ + U32 lowLimit; /* below that point, no more valid data */ + U32 nbOverflowCorrections; /* Number of times overflow correction has run since + * ZSTD_window_init(). Useful for debugging coredumps + * and for ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY. + */ +} ZSTD_window_t; + +#define ZSTD_WINDOW_START_INDEX 2 + +typedef struct ZSTD_MatchState_t ZSTD_MatchState_t; + +#define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */ + +struct ZSTD_MatchState_t { + ZSTD_window_t window; /* State for window round buffer management */ + U32 loadedDictEnd; /* index of end of dictionary, within context's referential. + * When loadedDictEnd != 0, a dictionary is in use, and still valid. + * This relies on a mechanism to set loadedDictEnd=0 when dictionary is no longer within distance. + * Such mechanism is provided within ZSTD_window_enforceMaxDist() and ZSTD_checkDictValidity(). + * When dict referential is copied into active context (i.e. not attached), + * loadedDictEnd == dictSize, since referential starts from zero. + */ + U32 nextToUpdate; /* index from which to continue table update */ + U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */ + + U32 rowHashLog; /* For row-based matchfinder: Hashlog based on nb of rows in the hashTable.*/ + BYTE* tagTable; /* For row-based matchFinder: A row-based table containing the hashes and head index. */ + U32 hashCache[ZSTD_ROW_HASH_CACHE_SIZE]; /* For row-based matchFinder: a cache of hashes to improve speed */ + U64 hashSalt; /* For row-based matchFinder: salts the hash for reuse of tag table */ + U32 hashSaltEntropy; /* For row-based matchFinder: collects entropy for salt generation */ + + U32* hashTable; + U32* hashTable3; + U32* chainTable; + + int forceNonContiguous; /* Non-zero if we should force non-contiguous load for the next window update. */ + + int dedicatedDictSearch; /* Indicates whether this matchState is using the + * dedicated dictionary search structure. + */ + optState_t opt; /* optimal parser state */ + const ZSTD_MatchState_t* dictMatchState; + ZSTD_compressionParameters cParams; + const RawSeqStore_t* ldmSeqStore; + + /* Controls prefetching in some dictMatchState matchfinders. + * This behavior is controlled from the cctx ms. + * This parameter has no effect in the cdict ms. */ + int prefetchCDictTables; + + /* When == 0, lazy match finders insert every position. + * When != 0, lazy match finders only insert positions they search. + * This allows them to skip much faster over incompressible data, + * at a small cost to compression ratio. + */ + int lazySkipping; +}; + +typedef struct { + ZSTD_compressedBlockState_t* prevCBlock; + ZSTD_compressedBlockState_t* nextCBlock; + ZSTD_MatchState_t matchState; +} ZSTD_blockState_t; + +typedef struct { + U32 offset; + U32 checksum; +} ldmEntry_t; + +typedef struct { + BYTE const* split; + U32 hash; + U32 checksum; + ldmEntry_t* bucket; +} ldmMatchCandidate_t; + +#define LDM_BATCH_SIZE 64 + +typedef struct { + ZSTD_window_t window; /* State for the window round buffer management */ + ldmEntry_t* hashTable; + U32 loadedDictEnd; + BYTE* bucketOffsets; /* Next position in bucket to insert entry */ + size_t splitIndices[LDM_BATCH_SIZE]; + ldmMatchCandidate_t matchCandidates[LDM_BATCH_SIZE]; +} ldmState_t; + +typedef struct { + ZSTD_ParamSwitch_e enableLdm; /* ZSTD_ps_enable to enable LDM. ZSTD_ps_auto by default */ + U32 hashLog; /* Log size of hashTable */ + U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */ + U32 minMatchLength; /* Minimum match length */ + U32 hashRateLog; /* Log number of entries to skip */ + U32 windowLog; /* Window log for the LDM */ +} ldmParams_t; + +typedef struct { + int collectSequences; + ZSTD_Sequence* seqStart; + size_t seqIndex; + size_t maxSequences; +} SeqCollector; + +struct ZSTD_CCtx_params_s { + ZSTD_format_e format; + ZSTD_compressionParameters cParams; + ZSTD_frameParameters fParams; + + int compressionLevel; + int forceWindow; /* force back-references to respect limit of + * 1< 63) ? ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength]; +} + +/* ZSTD_MLcode() : + * note : mlBase = matchLength - MINMATCH; + * because it's the format it's stored in seqStore->sequences */ +MEM_STATIC U32 ZSTD_MLcode(U32 mlBase) +{ + static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, + 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 }; + static const U32 ML_deltaCode = 36; + return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase]; +} + +/* ZSTD_cParam_withinBounds: + * @return 1 if value is within cParam bounds, + * 0 otherwise */ +MEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value) +{ + ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); + if (ZSTD_isError(bounds.error)) return 0; + if (value < bounds.lowerBound) return 0; + if (value > bounds.upperBound) return 0; + return 1; +} + +/* ZSTD_selectAddr: + * @return index >= lowLimit ? candidate : backup, + * tries to force branchless codegen. */ +MEM_STATIC const BYTE* +ZSTD_selectAddr(U32 index, U32 lowLimit, const BYTE* candidate, const BYTE* backup) +{ +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ( + "cmp %1, %2\n" + "cmova %3, %0\n" + : "+r"(candidate) + : "r"(index), "r"(lowLimit), "r"(backup) + ); + return candidate; +#else + return index >= lowLimit ? candidate : backup; +#endif +} + +/* ZSTD_noCompressBlock() : + * Writes uncompressed block to dst buffer from given src. + * Returns the size of the block */ +MEM_STATIC size_t +ZSTD_noCompressBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock) +{ + U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3); + DEBUGLOG(5, "ZSTD_noCompressBlock (srcSize=%zu, dstCapacity=%zu)", srcSize, dstCapacity); + RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity, + dstSize_tooSmall, "dst buf too small for uncompressed block"); + MEM_writeLE24(dst, cBlockHeader24); + ZSTD_memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize); + return ZSTD_blockHeaderSize + srcSize; +} + +MEM_STATIC size_t +ZSTD_rleCompressBlock(void* dst, size_t dstCapacity, BYTE src, size_t srcSize, U32 lastBlock) +{ + BYTE* const op = (BYTE*)dst; + U32 const cBlockHeader = lastBlock + (((U32)bt_rle)<<1) + (U32)(srcSize << 3); + RETURN_ERROR_IF(dstCapacity < 4, dstSize_tooSmall, ""); + MEM_writeLE24(op, cBlockHeader); + op[3] = src; + return 4; +} + + +/* ZSTD_minGain() : + * minimum compression required + * to generate a compress block or a compressed literals section. + * note : use same formula for both situations */ +MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat) +{ + U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6; + ZSTD_STATIC_ASSERT(ZSTD_btultra == 8); + assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat)); + return (srcSize >> minlog) + 2; +} + +MEM_STATIC int ZSTD_literalsCompressionIsDisabled(const ZSTD_CCtx_params* cctxParams) +{ + switch (cctxParams->literalCompressionMode) { + case ZSTD_ps_enable: + return 0; + case ZSTD_ps_disable: + return 1; + default: + assert(0 /* impossible: pre-validated */); + ZSTD_FALLTHROUGH; + case ZSTD_ps_auto: + return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0); + } +} + +/*! ZSTD_safecopyLiterals() : + * memcpy() function that won't read beyond more than WILDCOPY_OVERLENGTH bytes past ilimit_w. + * Only called when the sequence ends past ilimit_w, so it only needs to be optimized for single + * large copies. + */ +static void +ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE const* ilimit_w) +{ + assert(iend > ilimit_w); + if (ip <= ilimit_w) { + ZSTD_wildcopy(op, ip, ilimit_w - ip, ZSTD_no_overlap); + op += ilimit_w - ip; + ip = ilimit_w; + } + while (ip < iend) *op++ = *ip++; +} + + +#define REPCODE1_TO_OFFBASE REPCODE_TO_OFFBASE(1) +#define REPCODE2_TO_OFFBASE REPCODE_TO_OFFBASE(2) +#define REPCODE3_TO_OFFBASE REPCODE_TO_OFFBASE(3) +#define REPCODE_TO_OFFBASE(r) (assert((r)>=1), assert((r)<=ZSTD_REP_NUM), (r)) /* accepts IDs 1,2,3 */ +#define OFFSET_TO_OFFBASE(o) (assert((o)>0), o + ZSTD_REP_NUM) +#define OFFBASE_IS_OFFSET(o) ((o) > ZSTD_REP_NUM) +#define OFFBASE_IS_REPCODE(o) ( 1 <= (o) && (o) <= ZSTD_REP_NUM) +#define OFFBASE_TO_OFFSET(o) (assert(OFFBASE_IS_OFFSET(o)), (o) - ZSTD_REP_NUM) +#define OFFBASE_TO_REPCODE(o) (assert(OFFBASE_IS_REPCODE(o)), (o)) /* returns ID 1,2,3 */ + +/*! ZSTD_storeSeqOnly() : + * Store a sequence (litlen, litPtr, offBase and matchLength) into SeqStore_t. + * Literals themselves are not copied, but @litPtr is updated. + * @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE(). + * @matchLength : must be >= MINMATCH +*/ +HINT_INLINE UNUSED_ATTR void +ZSTD_storeSeqOnly(SeqStore_t* seqStorePtr, + size_t litLength, + U32 offBase, + size_t matchLength) +{ + assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq); + + /* literal Length */ + assert(litLength <= ZSTD_BLOCKSIZE_MAX); + if (UNLIKELY(litLength>0xFFFF)) { + assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */ + seqStorePtr->longLengthType = ZSTD_llt_literalLength; + seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + } + seqStorePtr->sequences[0].litLength = (U16)litLength; + + /* match offset */ + seqStorePtr->sequences[0].offBase = offBase; + + /* match Length */ + assert(matchLength <= ZSTD_BLOCKSIZE_MAX); + assert(matchLength >= MINMATCH); + { size_t const mlBase = matchLength - MINMATCH; + if (UNLIKELY(mlBase>0xFFFF)) { + assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */ + seqStorePtr->longLengthType = ZSTD_llt_matchLength; + seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + } + seqStorePtr->sequences[0].mlBase = (U16)mlBase; + } + + seqStorePtr->sequences++; +} + +/*! ZSTD_storeSeq() : + * Store a sequence (litlen, litPtr, offBase and matchLength) into SeqStore_t. + * @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE(). + * @matchLength : must be >= MINMATCH + * Allowed to over-read literals up to litLimit. +*/ +HINT_INLINE UNUSED_ATTR void +ZSTD_storeSeq(SeqStore_t* seqStorePtr, + size_t litLength, const BYTE* literals, const BYTE* litLimit, + U32 offBase, + size_t matchLength) +{ + BYTE const* const litLimit_w = litLimit - WILDCOPY_OVERLENGTH; + BYTE const* const litEnd = literals + litLength; +#if defined(DEBUGLEVEL) && (DEBUGLEVEL >= 6) + static const BYTE* g_start = NULL; + if (g_start==NULL) g_start = (const BYTE*)literals; /* note : index only works for compression within a single segment */ + { U32 const pos = (U32)((const BYTE*)literals - g_start); + DEBUGLOG(6, "Cpos%7u :%3u literals, match%4u bytes at offBase%7u", + pos, (U32)litLength, (U32)matchLength, (U32)offBase); + } +#endif + assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq); + /* copy Literals */ + assert(seqStorePtr->maxNbLit <= 128 KB); + assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit); + assert(literals + litLength <= litLimit); + if (litEnd <= litLimit_w) { + /* Common case we can use wildcopy. + * First copy 16 bytes, because literals are likely short. + */ + ZSTD_STATIC_ASSERT(WILDCOPY_OVERLENGTH >= 16); + ZSTD_copy16(seqStorePtr->lit, literals); + if (litLength > 16) { + ZSTD_wildcopy(seqStorePtr->lit+16, literals+16, (ptrdiff_t)litLength-16, ZSTD_no_overlap); + } + } else { + ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w); + } + seqStorePtr->lit += litLength; + + ZSTD_storeSeqOnly(seqStorePtr, litLength, offBase, matchLength); +} + +/* ZSTD_updateRep() : + * updates in-place @rep (array of repeat offsets) + * @offBase : sum-type, using numeric representation of ZSTD_storeSeq() + */ +MEM_STATIC void +ZSTD_updateRep(U32 rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0) +{ + if (OFFBASE_IS_OFFSET(offBase)) { /* full offset */ + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = OFFBASE_TO_OFFSET(offBase); + } else { /* repcode */ + U32 const repCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0; + if (repCode > 0) { /* note : if repCode==0, no change */ + U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode]; + rep[2] = (repCode >= 2) ? rep[1] : rep[2]; + rep[1] = rep[0]; + rep[0] = currentOffset; + } else { /* repCode == 0 */ + /* nothing to do */ + } + } +} + +typedef struct repcodes_s { + U32 rep[3]; +} Repcodes_t; + +MEM_STATIC Repcodes_t +ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0) +{ + Repcodes_t newReps; + ZSTD_memcpy(&newReps, rep, sizeof(newReps)); + ZSTD_updateRep(newReps.rep, offBase, ll0); + return newReps; +} + + +/*-************************************* +* Match length counter +***************************************/ +MEM_STATIC size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit) +{ + const BYTE* const pStart = pIn; + const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1); + + if (pIn < pInLoopLimit) { + { size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn); + if (diff) return ZSTD_NbCommonBytes(diff); } + pIn+=sizeof(size_t); pMatch+=sizeof(size_t); + while (pIn < pInLoopLimit) { + size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn); + if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; } + pIn += ZSTD_NbCommonBytes(diff); + return (size_t)(pIn - pStart); + } } + if (MEM_64bits() && (pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; } + if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; } + if ((pIn> (32-h) ; } +MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h, 0); } /* only in zstd_opt.h */ +MEM_STATIC size_t ZSTD_hash3PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash3(MEM_readLE32(ptr), h, s); } + +static const U32 prime4bytes = 2654435761U; +static U32 ZSTD_hash4(U32 u, U32 h, U32 s) { assert(h <= 32); return ((u * prime4bytes) ^ s) >> (32-h) ; } +static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_readLE32(ptr), h, 0); } +static size_t ZSTD_hash4PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash4(MEM_readLE32(ptr), h, s); } + +static const U64 prime5bytes = 889523592379ULL; +static size_t ZSTD_hash5(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-40)) * prime5bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash5PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash5(MEM_readLE64(p), h, s); } + +static const U64 prime6bytes = 227718039650203ULL; +static size_t ZSTD_hash6(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-48)) * prime6bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash6PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash6(MEM_readLE64(p), h, s); } + +static const U64 prime7bytes = 58295818150454627ULL; +static size_t ZSTD_hash7(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-56)) * prime7bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash7PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash7(MEM_readLE64(p), h, s); } + +static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL; +static size_t ZSTD_hash8(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u) * prime8bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash8PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash8(MEM_readLE64(p), h, s); } + + +MEM_STATIC FORCE_INLINE_ATTR +size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls) +{ + /* Although some of these hashes do support hBits up to 64, some do not. + * To be on the safe side, always avoid hBits > 32. */ + assert(hBits <= 32); + + switch(mls) + { + default: + case 4: return ZSTD_hash4Ptr(p, hBits); + case 5: return ZSTD_hash5Ptr(p, hBits); + case 6: return ZSTD_hash6Ptr(p, hBits); + case 7: return ZSTD_hash7Ptr(p, hBits); + case 8: return ZSTD_hash8Ptr(p, hBits); + } +} + +MEM_STATIC FORCE_INLINE_ATTR +size_t ZSTD_hashPtrSalted(const void* p, U32 hBits, U32 mls, const U64 hashSalt) { + /* Although some of these hashes do support hBits up to 64, some do not. + * To be on the safe side, always avoid hBits > 32. */ + assert(hBits <= 32); + + switch(mls) + { + default: + case 4: return ZSTD_hash4PtrS(p, hBits, (U32)hashSalt); + case 5: return ZSTD_hash5PtrS(p, hBits, hashSalt); + case 6: return ZSTD_hash6PtrS(p, hBits, hashSalt); + case 7: return ZSTD_hash7PtrS(p, hBits, hashSalt); + case 8: return ZSTD_hash8PtrS(p, hBits, hashSalt); + } +} + + +/** ZSTD_ipow() : + * Return base^exponent. + */ +static U64 ZSTD_ipow(U64 base, U64 exponent) +{ + U64 power = 1; + while (exponent) { + if (exponent & 1) power *= base; + exponent >>= 1; + base *= base; + } + return power; +} + +#define ZSTD_ROLL_HASH_CHAR_OFFSET 10 + +/** ZSTD_rollingHash_append() : + * Add the buffer to the hash value. + */ +static U64 ZSTD_rollingHash_append(U64 hash, void const* buf, size_t size) +{ + BYTE const* istart = (BYTE const*)buf; + size_t pos; + for (pos = 0; pos < size; ++pos) { + hash *= prime8bytes; + hash += istart[pos] + ZSTD_ROLL_HASH_CHAR_OFFSET; + } + return hash; +} + +/** ZSTD_rollingHash_compute() : + * Compute the rolling hash value of the buffer. + */ +MEM_STATIC U64 ZSTD_rollingHash_compute(void const* buf, size_t size) +{ + return ZSTD_rollingHash_append(0, buf, size); +} + +/** ZSTD_rollingHash_primePower() : + * Compute the primePower to be passed to ZSTD_rollingHash_rotate() for a hash + * over a window of length bytes. + */ +MEM_STATIC U64 ZSTD_rollingHash_primePower(U32 length) +{ + return ZSTD_ipow(prime8bytes, length - 1); +} + +/** ZSTD_rollingHash_rotate() : + * Rotate the rolling hash by one byte. + */ +MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64 primePower) +{ + hash -= (toRemove + ZSTD_ROLL_HASH_CHAR_OFFSET) * primePower; + hash *= prime8bytes; + hash += toAdd + ZSTD_ROLL_HASH_CHAR_OFFSET; + return hash; +} + +/*-************************************* +* Round buffer management +***************************************/ +/* Max @current value allowed: + * In 32-bit mode: we want to avoid crossing the 2 GB limit, + * reducing risks of side effects in case of signed operations on indexes. + * In 64-bit mode: we want to ensure that adding the maximum job size (512 MB) + * doesn't overflow U32 index capacity (4 GB) */ +#define ZSTD_CURRENT_MAX (MEM_64bits() ? 3500U MB : 2000U MB) +/* Maximum chunk size before overflow correction needs to be called again */ +#define ZSTD_CHUNKSIZE_MAX \ + ( ((U32)-1) /* Maximum ending current index */ \ + - ZSTD_CURRENT_MAX) /* Maximum beginning lowLimit */ + +/** + * ZSTD_window_clear(): + * Clears the window containing the history by simply setting it to empty. + */ +MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window) +{ + size_t const endT = (size_t)(window->nextSrc - window->base); + U32 const end = (U32)endT; + + window->lowLimit = end; + window->dictLimit = end; +} + +MEM_STATIC U32 ZSTD_window_isEmpty(ZSTD_window_t const window) +{ + return window.dictLimit == ZSTD_WINDOW_START_INDEX && + window.lowLimit == ZSTD_WINDOW_START_INDEX && + (window.nextSrc - window.base) == ZSTD_WINDOW_START_INDEX; +} + +/** + * ZSTD_window_hasExtDict(): + * Returns non-zero if the window has a non-empty extDict. + */ +MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window) +{ + return window.lowLimit < window.dictLimit; +} + +/** + * ZSTD_matchState_dictMode(): + * Inspects the provided matchState and figures out what dictMode should be + * passed to the compressor. + */ +MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_MatchState_t *ms) +{ + return ZSTD_window_hasExtDict(ms->window) ? + ZSTD_extDict : + ms->dictMatchState != NULL ? + (ms->dictMatchState->dedicatedDictSearch ? ZSTD_dedicatedDictSearch : ZSTD_dictMatchState) : + ZSTD_noDict; +} + +/* Defining this macro to non-zero tells zstd to run the overflow correction + * code much more frequently. This is very inefficient, and should only be + * used for tests and fuzzers. + */ +#ifndef ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY +# ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +# define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 1 +# else +# define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 0 +# endif +#endif + +/** + * ZSTD_window_canOverflowCorrect(): + * Returns non-zero if the indices are large enough for overflow correction + * to work correctly without impacting compression ratio. + */ +MEM_STATIC U32 ZSTD_window_canOverflowCorrect(ZSTD_window_t const window, + U32 cycleLog, + U32 maxDist, + U32 loadedDictEnd, + void const* src) +{ + U32 const cycleSize = 1u << cycleLog; + U32 const curr = (U32)((BYTE const*)src - window.base); + U32 const minIndexToOverflowCorrect = cycleSize + + MAX(maxDist, cycleSize) + + ZSTD_WINDOW_START_INDEX; + + /* Adjust the min index to backoff the overflow correction frequency, + * so we don't waste too much CPU in overflow correction. If this + * computation overflows we don't really care, we just need to make + * sure it is at least minIndexToOverflowCorrect. + */ + U32 const adjustment = window.nbOverflowCorrections + 1; + U32 const adjustedIndex = MAX(minIndexToOverflowCorrect * adjustment, + minIndexToOverflowCorrect); + U32 const indexLargeEnough = curr > adjustedIndex; + + /* Only overflow correct early if the dictionary is invalidated already, + * so we don't hurt compression ratio. + */ + U32 const dictionaryInvalidated = curr > maxDist + loadedDictEnd; + + return indexLargeEnough && dictionaryInvalidated; +} + +/** + * ZSTD_window_needOverflowCorrection(): + * Returns non-zero if the indices are getting too large and need overflow + * protection. + */ +MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window, + U32 cycleLog, + U32 maxDist, + U32 loadedDictEnd, + void const* src, + void const* srcEnd) +{ + U32 const curr = (U32)((BYTE const*)srcEnd - window.base); + if (ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) { + if (ZSTD_window_canOverflowCorrect(window, cycleLog, maxDist, loadedDictEnd, src)) { + return 1; + } + } + return curr > ZSTD_CURRENT_MAX; +} + +/** + * ZSTD_window_correctOverflow(): + * Reduces the indices to protect from index overflow. + * Returns the correction made to the indices, which must be applied to every + * stored index. + * + * The least significant cycleLog bits of the indices must remain the same, + * which may be 0. Every index up to maxDist in the past must be valid. + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, + U32 maxDist, void const* src) +{ + /* preemptive overflow correction: + * 1. correction is large enough: + * lowLimit > (3<<29) ==> current > 3<<29 + 1< (3<<29 + 1< (3<<29) - (1< (3<<29) - (1<<30) (NOTE: chainLog <= 30) + * > 1<<29 + * + * 2. (ip+ZSTD_CHUNKSIZE_MAX - cctx->base) doesn't overflow: + * After correction, current is less than (1<base < 1<<32. + * 3. (cctx->lowLimit + 1< 3<<29 + 1<base); + U32 const currentCycle = curr & cycleMask; + /* Ensure newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX. */ + U32 const currentCycleCorrection = currentCycle < ZSTD_WINDOW_START_INDEX + ? MAX(cycleSize, ZSTD_WINDOW_START_INDEX) + : 0; + U32 const newCurrent = currentCycle + + currentCycleCorrection + + MAX(maxDist, cycleSize); + U32 const correction = curr - newCurrent; + /* maxDist must be a power of two so that: + * (newCurrent & cycleMask) == (curr & cycleMask) + * This is required to not corrupt the chains / binary tree. + */ + assert((maxDist & (maxDist - 1)) == 0); + assert((curr & cycleMask) == (newCurrent & cycleMask)); + assert(curr > newCurrent); + if (!ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) { + /* Loose bound, should be around 1<<29 (see above) */ + assert(correction > 1<<28); + } + + window->base += correction; + window->dictBase += correction; + if (window->lowLimit < correction + ZSTD_WINDOW_START_INDEX) { + window->lowLimit = ZSTD_WINDOW_START_INDEX; + } else { + window->lowLimit -= correction; + } + if (window->dictLimit < correction + ZSTD_WINDOW_START_INDEX) { + window->dictLimit = ZSTD_WINDOW_START_INDEX; + } else { + window->dictLimit -= correction; + } + + /* Ensure we can still reference the full window. */ + assert(newCurrent >= maxDist); + assert(newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX); + /* Ensure that lowLimit and dictLimit didn't underflow. */ + assert(window->lowLimit <= newCurrent); + assert(window->dictLimit <= newCurrent); + + ++window->nbOverflowCorrections; + + DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction, + window->lowLimit); + return correction; +} + +/** + * ZSTD_window_enforceMaxDist(): + * Updates lowLimit so that: + * (srcEnd - base) - lowLimit == maxDist + loadedDictEnd + * + * It ensures index is valid as long as index >= lowLimit. + * This must be called before a block compression call. + * + * loadedDictEnd is only defined if a dictionary is in use for current compression. + * As the name implies, loadedDictEnd represents the index at end of dictionary. + * The value lies within context's referential, it can be directly compared to blockEndIdx. + * + * If loadedDictEndPtr is NULL, no dictionary is in use, and we use loadedDictEnd == 0. + * If loadedDictEndPtr is not NULL, we set it to zero after updating lowLimit. + * This is because dictionaries are allowed to be referenced fully + * as long as the last byte of the dictionary is in the window. + * Once input has progressed beyond window size, dictionary cannot be referenced anymore. + * + * In normal dict mode, the dictionary lies between lowLimit and dictLimit. + * In dictMatchState mode, lowLimit and dictLimit are the same, + * and the dictionary is below them. + * forceWindow and dictMatchState are therefore incompatible. + */ +MEM_STATIC void +ZSTD_window_enforceMaxDist(ZSTD_window_t* window, + const void* blockEnd, + U32 maxDist, + U32* loadedDictEndPtr, + const ZSTD_MatchState_t** dictMatchStatePtr) +{ + U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base); + U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0; + DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u", + (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd); + + /* - When there is no dictionary : loadedDictEnd == 0. + In which case, the test (blockEndIdx > maxDist) is merely to avoid + overflowing next operation `newLowLimit = blockEndIdx - maxDist`. + - When there is a standard dictionary : + Index referential is copied from the dictionary, + which means it starts from 0. + In which case, loadedDictEnd == dictSize, + and it makes sense to compare `blockEndIdx > maxDist + dictSize` + since `blockEndIdx` also starts from zero. + - When there is an attached dictionary : + loadedDictEnd is expressed within the referential of the context, + so it can be directly compared against blockEndIdx. + */ + if (blockEndIdx > maxDist + loadedDictEnd) { + U32 const newLowLimit = blockEndIdx - maxDist; + if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit; + if (window->dictLimit < window->lowLimit) { + DEBUGLOG(5, "Update dictLimit to match lowLimit, from %u to %u", + (unsigned)window->dictLimit, (unsigned)window->lowLimit); + window->dictLimit = window->lowLimit; + } + /* On reaching window size, dictionaries are invalidated */ + if (loadedDictEndPtr) *loadedDictEndPtr = 0; + if (dictMatchStatePtr) *dictMatchStatePtr = NULL; + } +} + +/* Similar to ZSTD_window_enforceMaxDist(), + * but only invalidates dictionary + * when input progresses beyond window size. + * assumption : loadedDictEndPtr and dictMatchStatePtr are valid (non NULL) + * loadedDictEnd uses same referential as window->base + * maxDist is the window size */ +MEM_STATIC void +ZSTD_checkDictValidity(const ZSTD_window_t* window, + const void* blockEnd, + U32 maxDist, + U32* loadedDictEndPtr, + const ZSTD_MatchState_t** dictMatchStatePtr) +{ + assert(loadedDictEndPtr != NULL); + assert(dictMatchStatePtr != NULL); + { U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base); + U32 const loadedDictEnd = *loadedDictEndPtr; + DEBUGLOG(5, "ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u", + (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd); + assert(blockEndIdx >= loadedDictEnd); + + if (blockEndIdx > loadedDictEnd + maxDist || loadedDictEnd != window->dictLimit) { + /* On reaching window size, dictionaries are invalidated. + * For simplification, if window size is reached anywhere within next block, + * the dictionary is invalidated for the full block. + * + * We also have to invalidate the dictionary if ZSTD_window_update() has detected + * non-contiguous segments, which means that loadedDictEnd != window->dictLimit. + * loadedDictEnd may be 0, if forceWindow is true, but in that case we never use + * dictMatchState, so setting it to NULL is not a problem. + */ + DEBUGLOG(6, "invalidating dictionary for current block (distance > windowSize)"); + *loadedDictEndPtr = 0; + *dictMatchStatePtr = NULL; + } else { + if (*loadedDictEndPtr != 0) { + DEBUGLOG(6, "dictionary considered valid for current block"); + } } } +} + +MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) { + ZSTD_memset(window, 0, sizeof(*window)); + window->base = (BYTE const*)" "; + window->dictBase = (BYTE const*)" "; + ZSTD_STATIC_ASSERT(ZSTD_DUBT_UNSORTED_MARK < ZSTD_WINDOW_START_INDEX); /* Start above ZSTD_DUBT_UNSORTED_MARK */ + window->dictLimit = ZSTD_WINDOW_START_INDEX; /* start from >0, so that 1st position is valid */ + window->lowLimit = ZSTD_WINDOW_START_INDEX; /* it ensures first and later CCtx usages compress the same */ + window->nextSrc = window->base + ZSTD_WINDOW_START_INDEX; /* see issue #1241 */ + window->nbOverflowCorrections = 0; +} + +/** + * ZSTD_window_update(): + * Updates the window by appending [src, src + srcSize) to the window. + * If it is not contiguous, the current prefix becomes the extDict, and we + * forget about the extDict. Handles overlap of the prefix and extDict. + * Returns non-zero if the segment is contiguous. + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_window_update(ZSTD_window_t* window, + const void* src, size_t srcSize, + int forceNonContiguous) +{ + BYTE const* const ip = (BYTE const*)src; + U32 contiguous = 1; + DEBUGLOG(5, "ZSTD_window_update"); + if (srcSize == 0) + return contiguous; + assert(window->base != NULL); + assert(window->dictBase != NULL); + /* Check if blocks follow each other */ + if (src != window->nextSrc || forceNonContiguous) { + /* not contiguous */ + size_t const distanceFromBase = (size_t)(window->nextSrc - window->base); + DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", window->dictLimit); + window->lowLimit = window->dictLimit; + assert(distanceFromBase == (size_t)(U32)distanceFromBase); /* should never overflow */ + window->dictLimit = (U32)distanceFromBase; + window->dictBase = window->base; + window->base = ip - distanceFromBase; + /* ms->nextToUpdate = window->dictLimit; */ + if (window->dictLimit - window->lowLimit < HASH_READ_SIZE) window->lowLimit = window->dictLimit; /* too small extDict */ + contiguous = 0; + } + window->nextSrc = ip + srcSize; + /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */ + if ( (ip+srcSize > window->dictBase + window->lowLimit) + & (ip < window->dictBase + window->dictLimit)) { + size_t const highInputIdx = (size_t)((ip + srcSize) - window->dictBase); + U32 const lowLimitMax = (highInputIdx > (size_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx; + assert(highInputIdx < UINT_MAX); + window->lowLimit = lowLimitMax; + DEBUGLOG(5, "Overlapping extDict and input : new lowLimit = %u", window->lowLimit); + } + return contiguous; +} + +/** + * Returns the lowest allowed match index. It may either be in the ext-dict or the prefix. + */ +MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_MatchState_t* ms, U32 curr, unsigned windowLog) +{ + U32 const maxDistance = 1U << windowLog; + U32 const lowestValid = ms->window.lowLimit; + U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + U32 const isDictionary = (ms->loadedDictEnd != 0); + /* When using a dictionary the entire dictionary is valid if a single byte of the dictionary + * is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't + * valid for the entire block. So this check is sufficient to find the lowest valid match index. + */ + U32 const matchLowest = isDictionary ? lowestValid : withinWindow; + return matchLowest; +} + +/** + * Returns the lowest allowed match index in the prefix. + */ +MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_MatchState_t* ms, U32 curr, unsigned windowLog) +{ + U32 const maxDistance = 1U << windowLog; + U32 const lowestValid = ms->window.dictLimit; + U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + U32 const isDictionary = (ms->loadedDictEnd != 0); + /* When computing the lowest prefix index we need to take the dictionary into account to handle + * the edge case where the dictionary and the source are contiguous in memory. + */ + U32 const matchLowest = isDictionary ? lowestValid : withinWindow; + return matchLowest; +} + +/* index_safety_check: + * intentional underflow : ensure repIndex isn't overlapping dict + prefix + * @return 1 if values are not overlapping, + * 0 otherwise */ +MEM_STATIC int ZSTD_index_overlap_check(const U32 prefixLowestIndex, const U32 repIndex) { + return ((U32)((prefixLowestIndex-1) - repIndex) >= 3); +} + + +/* debug functions */ +#if (DEBUGLEVEL>=2) + +MEM_STATIC double ZSTD_fWeight(U32 rawStat) +{ + U32 const fp_accuracy = 8; + U32 const fp_multiplier = (1 << fp_accuracy); + U32 const newStat = rawStat + 1; + U32 const hb = ZSTD_highbit32(newStat); + U32 const BWeight = hb * fp_multiplier; + U32 const FWeight = (newStat << fp_accuracy) >> hb; + U32 const weight = BWeight + FWeight; + assert(hb + fp_accuracy < 31); + return (double)weight / fp_multiplier; +} + +/* display a table content, + * listing each element, its frequency, and its predicted bit cost */ +MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max) +{ + unsigned u, sum; + for (u=0, sum=0; u<=max; u++) sum += table[u]; + DEBUGLOG(2, "total nb elts: %u", sum); + for (u=0; u<=max; u++) { + DEBUGLOG(2, "%2u: %5u (%.2f)", + u, table[u], ZSTD_fWeight(sum) - ZSTD_fWeight(table[u]) ); + } +} + +#endif + +/* Short Cache */ + +/* Normally, zstd matchfinders follow this flow: + * 1. Compute hash at ip + * 2. Load index from hashTable[hash] + * 3. Check if *ip == *(base + index) + * In dictionary compression, loading *(base + index) is often an L2 or even L3 miss. + * + * Short cache is an optimization which allows us to avoid step 3 most of the time + * when the data doesn't actually match. With short cache, the flow becomes: + * 1. Compute (hash, currentTag) at ip. currentTag is an 8-bit independent hash at ip. + * 2. Load (index, matchTag) from hashTable[hash]. See ZSTD_writeTaggedIndex to understand how this works. + * 3. Only if currentTag == matchTag, check *ip == *(base + index). Otherwise, continue. + * + * Currently, short cache is only implemented in CDict hashtables. Thus, its use is limited to + * dictMatchState matchfinders. + */ +#define ZSTD_SHORT_CACHE_TAG_BITS 8 +#define ZSTD_SHORT_CACHE_TAG_MASK ((1u << ZSTD_SHORT_CACHE_TAG_BITS) - 1) + +/* Helper function for ZSTD_fillHashTable and ZSTD_fillDoubleHashTable. + * Unpacks hashAndTag into (hash, tag), then packs (index, tag) into hashTable[hash]. */ +MEM_STATIC void ZSTD_writeTaggedIndex(U32* const hashTable, size_t hashAndTag, U32 index) { + size_t const hash = hashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS; + U32 const tag = (U32)(hashAndTag & ZSTD_SHORT_CACHE_TAG_MASK); + assert(index >> (32 - ZSTD_SHORT_CACHE_TAG_BITS) == 0); + hashTable[hash] = (index << ZSTD_SHORT_CACHE_TAG_BITS) | tag; +} + +/* Helper function for short cache matchfinders. + * Unpacks tag1 and tag2 from lower bits of packedTag1 and packedTag2, then checks if the tags match. */ +MEM_STATIC int ZSTD_comparePackedTags(size_t packedTag1, size_t packedTag2) { + U32 const tag1 = packedTag1 & ZSTD_SHORT_CACHE_TAG_MASK; + U32 const tag2 = packedTag2 & ZSTD_SHORT_CACHE_TAG_MASK; + return tag1 == tag2; +} + +/* =============================================================== + * Shared internal declarations + * These prototypes may be called from sources not in lib/compress + * =============================================================== */ + +/* ZSTD_loadCEntropy() : + * dict : must point at beginning of a valid zstd dictionary. + * return : size of dictionary header (size of magic number + dict ID + entropy tables) + * assumptions : magic number supposed already checked + * and dictSize >= 8 */ +size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, + const void* const dict, size_t dictSize); + +void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs); + +typedef struct { + U32 idx; /* Index in array of ZSTD_Sequence */ + U32 posInSequence; /* Position within sequence at idx */ + size_t posInSrc; /* Number of bytes given by sequences provided so far */ +} ZSTD_SequencePosition; + +/* for benchmark */ +size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx, + const ZSTD_Sequence* const inSeqs, size_t nbSequences, + int const repcodeResolution); + +typedef struct { + size_t nbSequences; + size_t blockSize; + size_t litSize; +} BlockSummary; + +BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs); + +/* ============================================================== + * Private declarations + * These prototypes shall only be called from within lib/compress + * ============================================================== */ + +/* ZSTD_getCParamsFromCCtxParams() : + * cParams are built depending on compressionLevel, src size hints, + * LDM and manually set compression parameters. + * Note: srcSizeHint == 0 means 0! + */ +ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( + const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); + +void ZSTD_resetSeqStore(SeqStore_t* ssPtr); + +/*! ZSTD_getCParamsFromCDict() : + * as the name implies */ +ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict); + +/* ZSTD_compressBegin_advanced_internal() : + * Private use only. To be called from zstdmt_compress.c. */ +size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + unsigned long long pledgedSrcSize); + +/* ZSTD_compress_advanced_internal() : + * Private use only. To be called from zstdmt_compress.c. */ +size_t ZSTD_compress_advanced_internal(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + const ZSTD_CCtx_params* params); + + +/* ZSTD_writeLastEmptyBlock() : + * output an empty Block with end-of-frame mark to complete a frame + * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h)) + * or an error code if `dstCapacity` is too small ( 1 */ +U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat); + +/** ZSTD_CCtx_trace() : + * Trace the end of a compression call. + */ +void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize); + +/* Returns 1 if an external sequence producer is registered, otherwise returns 0. */ +MEM_STATIC int ZSTD_hasExtSeqProd(const ZSTD_CCtx_params* params) { + return params->extSeqProdFunc != NULL; +} + +/* =============================================================== + * Deprecated definitions that are still used internally to avoid + * deprecation warnings. These functions are exactly equivalent to + * their public variants, but avoid the deprecation warnings. + * =============================================================== */ + +size_t ZSTD_compressBegin_usingCDict_deprecated(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); + +size_t ZSTD_compressContinue_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); + + +#endif /* ZSTD_COMPRESS_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_literals.c b/src/commonlib/bsd/zstd/compress/zstd_compress_literals.c new file mode 100644 index 0000000000..7c4960e6d6 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_literals.c @@ -0,0 +1,237 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + /*-************************************* + * Dependencies + ***************************************/ +#include "zstd_compress_literals.h" + + +/* ************************************************************** +* Debug Traces +****************************************************************/ +#if DEBUGLEVEL >= 2 + +static size_t showHexa(const void* src, size_t srcSize) +{ + const BYTE* const ip = (const BYTE*)src; + size_t u; + for (u=0; u31) + (srcSize>4095); + + DEBUGLOG(5, "ZSTD_noCompressLiterals: srcSize=%zu, dstCapacity=%zu", srcSize, dstCapacity); + + RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall, ""); + + switch(flSize) + { + case 1: /* 2 - 1 - 5 */ + ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3)); + break; + case 2: /* 2 - 2 - 12 */ + MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4))); + break; + case 3: /* 2 - 2 - 20 */ + MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4))); + break; + default: /* not necessary : flSize is {1,2,3} */ + assert(0); + } + + ZSTD_memcpy(ostart + flSize, src, srcSize); + DEBUGLOG(5, "Raw (uncompressed) literals: %u -> %u", (U32)srcSize, (U32)(srcSize + flSize)); + return srcSize + flSize; +} + +static int allBytesIdentical(const void* src, size_t srcSize) +{ + assert(srcSize >= 1); + assert(src != NULL); + { const BYTE b = ((const BYTE*)src)[0]; + size_t p; + for (p=1; p31) + (srcSize>4095); + + assert(dstCapacity >= 4); (void)dstCapacity; + assert(allBytesIdentical(src, srcSize)); + + switch(flSize) + { + case 1: /* 2 - 1 - 5 */ + ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3)); + break; + case 2: /* 2 - 2 - 12 */ + MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4))); + break; + case 3: /* 2 - 2 - 20 */ + MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4))); + break; + default: /* not necessary : flSize is {1,2,3} */ + assert(0); + } + + ostart[flSize] = *(const BYTE*)src; + DEBUGLOG(5, "RLE : Repeated Literal (%02X: %u times) -> %u bytes encoded", ((const BYTE*)src)[0], (U32)srcSize, (U32)flSize + 1); + return flSize+1; +} + +/* ZSTD_minLiteralsToCompress() : + * returns minimal amount of literals + * for literal compression to even be attempted. + * Minimum is made tighter as compression strategy increases. + */ +static size_t +ZSTD_minLiteralsToCompress(ZSTD_strategy strategy, HUF_repeat huf_repeat) +{ + assert((int)strategy >= 0); + assert((int)strategy <= 9); + /* btultra2 : min 8 bytes; + * then 2x larger for each successive compression strategy + * max threshold 64 bytes */ + { int const shift = MIN(9-(int)strategy, 3); + size_t const mintc = (huf_repeat == HUF_repeat_valid) ? 6 : (size_t)8 << shift; + DEBUGLOG(7, "minLiteralsToCompress = %zu", mintc); + return mintc; + } +} + +size_t ZSTD_compressLiterals ( + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + void* entropyWorkspace, size_t entropyWorkspaceSize, + const ZSTD_hufCTables_t* prevHuf, + ZSTD_hufCTables_t* nextHuf, + ZSTD_strategy strategy, + int disableLiteralCompression, + int suspectUncompressible, + int bmi2) +{ + size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB); + BYTE* const ostart = (BYTE*)dst; + U32 singleStream = srcSize < 256; + SymbolEncodingType_e hType = set_compressed; + size_t cLitSize; + + DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i, srcSize=%u, dstCapacity=%zu)", + disableLiteralCompression, (U32)srcSize, dstCapacity); + + DEBUGLOG(6, "Completed literals listing (%zu bytes)", showHexa(src, srcSize)); + + /* Prepare nextEntropy assuming reusing the existing table */ + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + + if (disableLiteralCompression) + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + + /* if too small, don't even attempt compression (speed opt) */ + if (srcSize < ZSTD_minLiteralsToCompress(strategy, prevHuf->repeatMode)) + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + + RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, "not enough space for compression"); + { HUF_repeat repeat = prevHuf->repeatMode; + int const flags = 0 + | (bmi2 ? HUF_flags_bmi2 : 0) + | (strategy < ZSTD_lazy && srcSize <= 1024 ? HUF_flags_preferRepeat : 0) + | (strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD ? HUF_flags_optimalDepth : 0) + | (suspectUncompressible ? HUF_flags_suspectUncompressible : 0); + + typedef size_t (*huf_compress_f)(void*, size_t, const void*, size_t, unsigned, unsigned, void*, size_t, HUF_CElt*, HUF_repeat*, int); + huf_compress_f huf_compress; + if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1; + huf_compress = singleStream ? HUF_compress1X_repeat : HUF_compress4X_repeat; + cLitSize = huf_compress(ostart+lhSize, dstCapacity-lhSize, + src, srcSize, + HUF_SYMBOLVALUE_MAX, LitHufLog, + entropyWorkspace, entropyWorkspaceSize, + (HUF_CElt*)nextHuf->CTable, + &repeat, flags); + DEBUGLOG(5, "%zu literals compressed into %zu bytes (before header)", srcSize, cLitSize); + if (repeat != HUF_repeat_none) { + /* reused the existing table */ + DEBUGLOG(5, "reusing statistics from previous huffman block"); + hType = set_repeat; + } + } + + { size_t const minGain = ZSTD_minGain(srcSize, strategy); + if ((cLitSize==0) || (cLitSize >= srcSize - minGain) || ERR_isError(cLitSize)) { + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + } } + if (cLitSize==1) { + /* A return value of 1 signals that the alphabet consists of a single symbol. + * However, in some rare circumstances, it could be the compressed size (a single byte). + * For that outcome to have a chance to happen, it's necessary that `srcSize < 8`. + * (it's also necessary to not generate statistics). + * Therefore, in such a case, actively check that all bytes are identical. */ + if ((srcSize >= 8) || allBytesIdentical(src, srcSize)) { + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize); + } } + + if (hType == set_compressed) { + /* using a newly constructed table */ + nextHuf->repeatMode = HUF_repeat_check; + } + + /* Build header */ + switch(lhSize) + { + case 3: /* 2 - 2 - 10 - 10 */ + if (!singleStream) assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS); + { U32 const lhc = hType + ((U32)(!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14); + MEM_writeLE24(ostart, lhc); + break; + } + case 4: /* 2 - 2 - 14 - 14 */ + assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS); + { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18); + MEM_writeLE32(ostart, lhc); + break; + } + case 5: /* 2 - 2 - 18 - 18 */ + assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS); + { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22); + MEM_writeLE32(ostart, lhc); + ostart[4] = (BYTE)(cLitSize >> 10); + break; + } + default: /* not possible : lhSize is {3,4,5} */ + assert(0); + } + DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)srcSize, (U32)(lhSize+cLitSize)); + return lhSize+cLitSize; +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_literals.h b/src/commonlib/bsd/zstd/compress/zstd_compress_literals.h new file mode 100644 index 0000000000..994ca02e4d --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_literals.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPRESS_LITERALS_H +#define ZSTD_COMPRESS_LITERALS_H + +#include "zstd_compress_internal.h" /* ZSTD_hufCTables_t, ZSTD_minGain() */ + + +size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* ZSTD_compressRleLiteralsBlock() : + * Conditions : + * - All bytes in @src are identical + * - dstCapacity >= 4 */ +size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* ZSTD_compressLiterals(): + * @entropyWorkspace: must be aligned on 4-bytes boundaries + * @entropyWorkspaceSize : must be >= HUF_WORKSPACE_SIZE + * @suspectUncompressible: sampling checks, to potentially skip huffman coding + */ +size_t ZSTD_compressLiterals (void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + void* entropyWorkspace, size_t entropyWorkspaceSize, + const ZSTD_hufCTables_t* prevHuf, + ZSTD_hufCTables_t* nextHuf, + ZSTD_strategy strategy, int disableLiteralCompression, + int suspectUncompressible, + int bmi2); + +#endif /* ZSTD_COMPRESS_LITERALS_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.c b/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.c new file mode 100644 index 0000000000..46b43b5bc9 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.c @@ -0,0 +1,444 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + /*-************************************* + * Dependencies + ***************************************/ +#include "zstd_compress_sequences.h" + +/** + * -log2(x / 256) lookup table for x in [0, 256). + * If x == 0: Return 0 + * Else: Return floor(-log2(x / 256) * 256) + */ +static unsigned const kInverseProbabilityLog256[256] = { + 0, 2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162, + 1130, 1100, 1073, 1047, 1024, 1001, 980, 960, 941, 923, 906, 889, + 874, 859, 844, 830, 817, 804, 791, 779, 768, 756, 745, 734, + 724, 714, 704, 694, 685, 676, 667, 658, 650, 642, 633, 626, + 618, 610, 603, 595, 588, 581, 574, 567, 561, 554, 548, 542, + 535, 529, 523, 517, 512, 506, 500, 495, 489, 484, 478, 473, + 468, 463, 458, 453, 448, 443, 438, 434, 429, 424, 420, 415, + 411, 407, 402, 398, 394, 390, 386, 382, 377, 373, 370, 366, + 362, 358, 354, 350, 347, 343, 339, 336, 332, 329, 325, 322, + 318, 315, 311, 308, 305, 302, 298, 295, 292, 289, 286, 282, + 279, 276, 273, 270, 267, 264, 261, 258, 256, 253, 250, 247, + 244, 241, 239, 236, 233, 230, 228, 225, 222, 220, 217, 215, + 212, 209, 207, 204, 202, 199, 197, 194, 192, 190, 187, 185, + 182, 180, 178, 175, 173, 171, 168, 166, 164, 162, 159, 157, + 155, 153, 151, 149, 146, 144, 142, 140, 138, 136, 134, 132, + 130, 128, 126, 123, 121, 119, 117, 115, 114, 112, 110, 108, + 106, 104, 102, 100, 98, 96, 94, 93, 91, 89, 87, 85, + 83, 82, 80, 78, 76, 74, 73, 71, 69, 67, 66, 64, + 62, 61, 59, 57, 55, 54, 52, 50, 49, 47, 46, 44, + 42, 41, 39, 37, 36, 34, 33, 31, 30, 28, 26, 25, + 23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7, + 5, 4, 2, 1, +}; + +static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) { + void const* ptr = ctable; + U16 const* u16ptr = (U16 const*)ptr; + U32 const maxSymbolValue = MEM_read16(u16ptr + 1); + return maxSymbolValue; +} + +/** + * Returns true if we should use ncount=-1 else we should + * use ncount=1 for low probability symbols instead. + */ +static unsigned ZSTD_useLowProbCount(size_t const nbSeq) +{ + /* Heuristic: This should cover most blocks <= 16K and + * start to fade out after 16K to about 32K depending on + * compressibility. + */ + return nbSeq >= 2048; +} + +/** + * Returns the cost in bytes of encoding the normalized count header. + * Returns an error if any of the helper functions return an error. + */ +static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max, + size_t const nbSeq, unsigned const FSELog) +{ + BYTE wksp[FSE_NCOUNTBOUND]; + S16 norm[MaxSeq + 1]; + const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max); + FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max, ZSTD_useLowProbCount(nbSeq)), ""); + return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog); +} + +/** + * Returns the cost in bits of encoding the distribution described by count + * using the entropy bound. + */ +static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total) +{ + unsigned cost = 0; + unsigned s; + + assert(total > 0); + for (s = 0; s <= max; ++s) { + unsigned norm = (unsigned)((256 * count[s]) / total); + if (count[s] != 0 && norm == 0) + norm = 1; + assert(count[s] < total); + cost += count[s] * kInverseProbabilityLog256[norm]; + } + return cost >> 8; +} + +/** + * Returns the cost in bits of encoding the distribution in count using ctable. + * Returns an error if ctable cannot represent all the symbols in count. + */ +size_t ZSTD_fseBitCost( + FSE_CTable const* ctable, + unsigned const* count, + unsigned const max) +{ + unsigned const kAccuracyLog = 8; + size_t cost = 0; + unsigned s; + FSE_CState_t cstate; + FSE_initCState(&cstate, ctable); + if (ZSTD_getFSEMaxSymbolValue(ctable) < max) { + DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u", + ZSTD_getFSEMaxSymbolValue(ctable), max); + return ERROR(GENERIC); + } + for (s = 0; s <= max; ++s) { + unsigned const tableLog = cstate.stateLog; + unsigned const badCost = (tableLog + 1) << kAccuracyLog; + unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog); + if (count[s] == 0) + continue; + if (bitCost >= badCost) { + DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s); + return ERROR(GENERIC); + } + cost += (size_t)count[s] * bitCost; + } + return cost >> kAccuracyLog; +} + +/** + * Returns the cost in bits of encoding the distribution in count using the + * table described by norm. The max symbol support by norm is assumed >= max. + * norm must be valid for every symbol with non-zero probability in count. + */ +size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog, + unsigned const* count, unsigned const max) +{ + unsigned const shift = 8 - accuracyLog; + size_t cost = 0; + unsigned s; + assert(accuracyLog <= 8); + for (s = 0; s <= max; ++s) { + unsigned const normAcc = (norm[s] != -1) ? (unsigned)norm[s] : 1; + unsigned const norm256 = normAcc << shift; + assert(norm256 > 0); + assert(norm256 < 256); + cost += count[s] * kInverseProbabilityLog256[norm256]; + } + return cost >> 8; +} + +SymbolEncodingType_e +ZSTD_selectEncodingType( + FSE_repeat* repeatMode, unsigned const* count, unsigned const max, + size_t const mostFrequent, size_t nbSeq, unsigned const FSELog, + FSE_CTable const* prevCTable, + short const* defaultNorm, U32 defaultNormLog, + ZSTD_DefaultPolicy_e const isDefaultAllowed, + ZSTD_strategy const strategy) +{ + ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0); + if (mostFrequent == nbSeq) { + *repeatMode = FSE_repeat_none; + if (isDefaultAllowed && nbSeq <= 2) { + /* Prefer set_basic over set_rle when there are 2 or fewer symbols, + * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol. + * If basic encoding isn't possible, always choose RLE. + */ + DEBUGLOG(5, "Selected set_basic"); + return set_basic; + } + DEBUGLOG(5, "Selected set_rle"); + return set_rle; + } + if (strategy < ZSTD_lazy) { + if (isDefaultAllowed) { + size_t const staticFse_nbSeq_max = 1000; + size_t const mult = 10 - strategy; + size_t const baseLog = 3; + size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog; /* 28-36 for offset, 56-72 for lengths */ + assert(defaultNormLog >= 5 && defaultNormLog <= 6); /* xx_DEFAULTNORMLOG */ + assert(mult <= 9 && mult >= 7); + if ( (*repeatMode == FSE_repeat_valid) + && (nbSeq < staticFse_nbSeq_max) ) { + DEBUGLOG(5, "Selected set_repeat"); + return set_repeat; + } + if ( (nbSeq < dynamicFse_nbSeq_min) + || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) { + DEBUGLOG(5, "Selected set_basic"); + /* The format allows default tables to be repeated, but it isn't useful. + * When using simple heuristics to select encoding type, we don't want + * to confuse these tables with dictionaries. When running more careful + * analysis, we don't need to waste time checking both repeating tables + * and default tables. + */ + *repeatMode = FSE_repeat_none; + return set_basic; + } + } + } else { + size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC); + size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC); + size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog); + size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq); + + if (isDefaultAllowed) { + assert(!ZSTD_isError(basicCost)); + assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost))); + } + assert(!ZSTD_isError(NCountCost)); + assert(compressedCost < ERROR(maxCode)); + DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u", + (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost); + if (basicCost <= repeatCost && basicCost <= compressedCost) { + DEBUGLOG(5, "Selected set_basic"); + assert(isDefaultAllowed); + *repeatMode = FSE_repeat_none; + return set_basic; + } + if (repeatCost <= compressedCost) { + DEBUGLOG(5, "Selected set_repeat"); + assert(!ZSTD_isError(repeatCost)); + return set_repeat; + } + assert(compressedCost < basicCost && compressedCost < repeatCost); + } + DEBUGLOG(5, "Selected set_compressed"); + *repeatMode = FSE_repeat_check; + return set_compressed; +} + +typedef struct { + S16 norm[MaxSeq + 1]; + U32 wksp[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(MaxSeq, MaxFSELog)]; +} ZSTD_BuildCTableWksp; + +size_t +ZSTD_buildCTable(void* dst, size_t dstCapacity, + FSE_CTable* nextCTable, U32 FSELog, SymbolEncodingType_e type, + unsigned* count, U32 max, + const BYTE* codeTable, size_t nbSeq, + const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax, + const FSE_CTable* prevCTable, size_t prevCTableSize, + void* entropyWorkspace, size_t entropyWorkspaceSize) +{ + BYTE* op = (BYTE*)dst; + const BYTE* const oend = op + dstCapacity; + DEBUGLOG(6, "ZSTD_buildCTable (dstCapacity=%u)", (unsigned)dstCapacity); + + switch (type) { + case set_rle: + FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max), ""); + RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall, "not enough space"); + *op = codeTable[0]; + return 1; + case set_repeat: + ZSTD_memcpy(nextCTable, prevCTable, prevCTableSize); + return 0; + case set_basic: + FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */ + return 0; + case set_compressed: { + ZSTD_BuildCTableWksp* wksp = (ZSTD_BuildCTableWksp*)entropyWorkspace; + size_t nbSeq_1 = nbSeq; + const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max); + if (count[codeTable[nbSeq-1]] > 1) { + count[codeTable[nbSeq-1]]--; + nbSeq_1--; + } + assert(nbSeq_1 > 1); + assert(entropyWorkspaceSize >= sizeof(ZSTD_BuildCTableWksp)); + (void)entropyWorkspaceSize; + FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "FSE_normalizeCount failed"); + assert(oend >= op); + { size_t const NCountSize = FSE_writeNCount(op, (size_t)(oend - op), wksp->norm, max, tableLog); /* overflow protected */ + FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed"); + FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), "FSE_buildCTable_wksp failed"); + return NCountSize; + } + } + default: assert(0); RETURN_ERROR(GENERIC, "impossible to reach"); + } +} + +FORCE_INLINE_TEMPLATE size_t +ZSTD_encodeSequences_body( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets) +{ + BIT_CStream_t blockStream; + FSE_CState_t stateMatchLength; + FSE_CState_t stateOffsetBits; + FSE_CState_t stateLitLength; + + RETURN_ERROR_IF( + ERR_isError(BIT_initCStream(&blockStream, dst, dstCapacity)), + dstSize_tooSmall, "not enough space remaining"); + DEBUGLOG(6, "available space for bitstream : %i (dstCapacity=%u)", + (int)(blockStream.endPtr - blockStream.startPtr), + (unsigned)dstCapacity); + + /* first symbols */ + FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]); + FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]); + FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]); + BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]); + if (MEM_32bits()) BIT_flushBits(&blockStream); + BIT_addBits(&blockStream, sequences[nbSeq-1].mlBase, ML_bits[mlCodeTable[nbSeq-1]]); + if (MEM_32bits()) BIT_flushBits(&blockStream); + if (longOffsets) { + U32 const ofBits = ofCodeTable[nbSeq-1]; + unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1); + if (extraBits) { + BIT_addBits(&blockStream, sequences[nbSeq-1].offBase, extraBits); + BIT_flushBits(&blockStream); + } + BIT_addBits(&blockStream, sequences[nbSeq-1].offBase >> extraBits, + ofBits - extraBits); + } else { + BIT_addBits(&blockStream, sequences[nbSeq-1].offBase, ofCodeTable[nbSeq-1]); + } + BIT_flushBits(&blockStream); + + { size_t n; + for (n=nbSeq-2 ; n= 64-7-(LLFSELog+MLFSELog+OffFSELog))) + BIT_flushBits(&blockStream); /* (7)*/ + BIT_addBits(&blockStream, sequences[n].litLength, llBits); + if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream); + BIT_addBits(&blockStream, sequences[n].mlBase, mlBits); + if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream); + if (longOffsets) { + unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1); + if (extraBits) { + BIT_addBits(&blockStream, sequences[n].offBase, extraBits); + BIT_flushBits(&blockStream); /* (7)*/ + } + BIT_addBits(&blockStream, sequences[n].offBase >> extraBits, + ofBits - extraBits); /* 31 */ + } else { + BIT_addBits(&blockStream, sequences[n].offBase, ofBits); /* 31 */ + } + BIT_flushBits(&blockStream); /* (7)*/ + DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr)); + } } + + DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog); + FSE_flushCState(&blockStream, &stateMatchLength); + DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog); + FSE_flushCState(&blockStream, &stateOffsetBits); + DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog); + FSE_flushCState(&blockStream, &stateLitLength); + + { size_t const streamSize = BIT_closeCStream(&blockStream); + RETURN_ERROR_IF(streamSize==0, dstSize_tooSmall, "not enough space"); + return streamSize; + } +} + +static size_t +ZSTD_encodeSequences_default( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets) +{ + return ZSTD_encodeSequences_body(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); +} + + +#if DYNAMIC_BMI2 + +static BMI2_TARGET_ATTRIBUTE size_t +ZSTD_encodeSequences_bmi2( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets) +{ + return ZSTD_encodeSequences_body(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); +} + +#endif + +size_t ZSTD_encodeSequences( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2) +{ + DEBUGLOG(5, "ZSTD_encodeSequences: dstCapacity = %u", (unsigned)dstCapacity); +#if DYNAMIC_BMI2 + if (bmi2) { + return ZSTD_encodeSequences_bmi2(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); + } +#endif + (void)bmi2; + return ZSTD_encodeSequences_default(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.h b/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.h new file mode 100644 index 0000000000..bcc1da97e3 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPRESS_SEQUENCES_H +#define ZSTD_COMPRESS_SEQUENCES_H + +#include "zstd_compress_internal.h" /* SeqDef */ +#include "../common/fse.h" /* FSE_repeat, FSE_CTable */ +#include "../common/zstd_internal.h" /* SymbolEncodingType_e, ZSTD_strategy */ + +typedef enum { + ZSTD_defaultDisallowed = 0, + ZSTD_defaultAllowed = 1 +} ZSTD_DefaultPolicy_e; + +SymbolEncodingType_e +ZSTD_selectEncodingType( + FSE_repeat* repeatMode, unsigned const* count, unsigned const max, + size_t const mostFrequent, size_t nbSeq, unsigned const FSELog, + FSE_CTable const* prevCTable, + short const* defaultNorm, U32 defaultNormLog, + ZSTD_DefaultPolicy_e const isDefaultAllowed, + ZSTD_strategy const strategy); + +size_t +ZSTD_buildCTable(void* dst, size_t dstCapacity, + FSE_CTable* nextCTable, U32 FSELog, SymbolEncodingType_e type, + unsigned* count, U32 max, + const BYTE* codeTable, size_t nbSeq, + const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax, + const FSE_CTable* prevCTable, size_t prevCTableSize, + void* entropyWorkspace, size_t entropyWorkspaceSize); + +size_t ZSTD_encodeSequences( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2); + +size_t ZSTD_fseBitCost( + FSE_CTable const* ctable, + unsigned const* count, + unsigned const max); + +size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog, + unsigned const* count, unsigned const max); +#endif /* ZSTD_COMPRESS_SEQUENCES_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.c b/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.c new file mode 100644 index 0000000000..85a2f1c231 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.c @@ -0,0 +1,690 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + /*-************************************* + * Dependencies + ***************************************/ +#include "zstd_compress_superblock.h" + +#include "../common/zstd_internal.h" /* ZSTD_getSequenceLength */ +#include "hist.h" /* HIST_countFast_wksp */ +#include "zstd_compress_internal.h" /* ZSTD_[huf|fse|entropy]CTablesMetadata_t */ +#include "zstd_compress_sequences.h" +#include "zstd_compress_literals.h" + +/** ZSTD_compressSubBlock_literal() : + * Compresses literals section for a sub-block. + * When we have to write the Huffman table we will sometimes choose a header + * size larger than necessary. This is because we have to pick the header size + * before we know the table size + compressed size, so we have a bound on the + * table size. If we guessed incorrectly, we fall back to uncompressed literals. + * + * We write the header when writeEntropy=1 and set entropyWritten=1 when we succeeded + * in writing the header, otherwise it is set to 0. + * + * hufMetadata->hType has literals block type info. + * If it is set_basic, all sub-blocks literals section will be Raw_Literals_Block. + * If it is set_rle, all sub-blocks literals section will be RLE_Literals_Block. + * If it is set_compressed, first sub-block's literals section will be Compressed_Literals_Block + * If it is set_compressed, first sub-block's literals section will be Treeless_Literals_Block + * and the following sub-blocks' literals sections will be Treeless_Literals_Block. + * @return : compressed size of literals section of a sub-block + * Or 0 if unable to compress. + * Or error code */ +static size_t +ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable, + const ZSTD_hufCTablesMetadata_t* hufMetadata, + const BYTE* literals, size_t litSize, + void* dst, size_t dstSize, + const int bmi2, int writeEntropy, int* entropyWritten) +{ + size_t const header = writeEntropy ? 200 : 0; + size_t const lhSize = 3 + (litSize >= (1 KB - header)) + (litSize >= (16 KB - header)); + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstSize; + BYTE* op = ostart + lhSize; + U32 const singleStream = lhSize == 3; + SymbolEncodingType_e hType = writeEntropy ? hufMetadata->hType : set_repeat; + size_t cLitSize = 0; + + DEBUGLOG(5, "ZSTD_compressSubBlock_literal (litSize=%zu, lhSize=%zu, writeEntropy=%d)", litSize, lhSize, writeEntropy); + + *entropyWritten = 0; + if (litSize == 0 || hufMetadata->hType == set_basic) { + DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal"); + return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize); + } else if (hufMetadata->hType == set_rle) { + DEBUGLOG(5, "ZSTD_compressSubBlock_literal using rle literal"); + return ZSTD_compressRleLiteralsBlock(dst, dstSize, literals, litSize); + } + + assert(litSize > 0); + assert(hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat); + + if (writeEntropy && hufMetadata->hType == set_compressed) { + ZSTD_memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize); + op += hufMetadata->hufDesSize; + cLitSize += hufMetadata->hufDesSize; + DEBUGLOG(5, "ZSTD_compressSubBlock_literal (hSize=%zu)", hufMetadata->hufDesSize); + } + + { int const flags = bmi2 ? HUF_flags_bmi2 : 0; + const size_t cSize = singleStream ? HUF_compress1X_usingCTable(op, (size_t)(oend-op), literals, litSize, hufTable, flags) + : HUF_compress4X_usingCTable(op, (size_t)(oend-op), literals, litSize, hufTable, flags); + op += cSize; + cLitSize += cSize; + if (cSize == 0 || ERR_isError(cSize)) { + DEBUGLOG(5, "Failed to write entropy tables %s", ZSTD_getErrorName(cSize)); + return 0; + } + /* If we expand and we aren't writing a header then emit uncompressed */ + if (!writeEntropy && cLitSize >= litSize) { + DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal because uncompressible"); + return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize); + } + /* If we are writing headers then allow expansion that doesn't change our header size. */ + if (lhSize < (size_t)(3 + (cLitSize >= 1 KB) + (cLitSize >= 16 KB))) { + assert(cLitSize > litSize); + DEBUGLOG(5, "Literals expanded beyond allowed header size"); + return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize); + } + DEBUGLOG(5, "ZSTD_compressSubBlock_literal (cSize=%zu)", cSize); + } + + /* Build header */ + switch(lhSize) + { + case 3: /* 2 - 2 - 10 - 10 */ + { U32 const lhc = hType + ((U32)(!singleStream) << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<14); + MEM_writeLE24(ostart, lhc); + break; + } + case 4: /* 2 - 2 - 14 - 14 */ + { U32 const lhc = hType + (2 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<18); + MEM_writeLE32(ostart, lhc); + break; + } + case 5: /* 2 - 2 - 18 - 18 */ + { U32 const lhc = hType + (3 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<22); + MEM_writeLE32(ostart, lhc); + ostart[4] = (BYTE)(cLitSize >> 10); + break; + } + default: /* not possible : lhSize is {3,4,5} */ + assert(0); + } + *entropyWritten = 1; + DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)litSize, (U32)(op-ostart)); + return (size_t)(op-ostart); +} + +static size_t +ZSTD_seqDecompressedSize(SeqStore_t const* seqStore, + const SeqDef* sequences, size_t nbSeqs, + size_t litSize, int lastSubBlock) +{ + size_t matchLengthSum = 0; + size_t litLengthSum = 0; + size_t n; + for (n=0; nllType, fseMetadata->ofType, and fseMetadata->mlType have + * symbol compression modes for the super-block. + * The first successfully compressed block will have these in its header. + * We set entropyWritten=1 when we succeed in compressing the sequences. + * The following sub-blocks will always have repeat mode. + * @return : compressed size of sequences section of a sub-block + * Or 0 if it is unable to compress + * Or error code. */ +static size_t +ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables, + const ZSTD_fseCTablesMetadata_t* fseMetadata, + const SeqDef* sequences, size_t nbSeq, + const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + const int bmi2, int writeEntropy, int* entropyWritten) +{ + const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart; + BYTE* seqHead; + + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (nbSeq=%zu, writeEntropy=%d, longOffsets=%d)", nbSeq, writeEntropy, longOffsets); + + *entropyWritten = 0; + /* Sequences Header */ + RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/, + dstSize_tooSmall, ""); + if (nbSeq < 128) + *op++ = (BYTE)nbSeq; + else if (nbSeq < LONGNBSEQ) + op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2; + else + op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3; + if (nbSeq==0) { + return (size_t)(op - ostart); + } + + /* seqHead : flags for FSE encoding type */ + seqHead = op++; + + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (seqHeadSize=%u)", (unsigned)(op-ostart)); + + if (writeEntropy) { + const U32 LLtype = fseMetadata->llType; + const U32 Offtype = fseMetadata->ofType; + const U32 MLtype = fseMetadata->mlType; + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (fseTablesSize=%zu)", fseMetadata->fseTablesSize); + *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2)); + ZSTD_memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize); + op += fseMetadata->fseTablesSize; + } else { + const U32 repeat = set_repeat; + *seqHead = (BYTE)((repeat<<6) + (repeat<<4) + (repeat<<2)); + } + + { size_t const bitstreamSize = ZSTD_encodeSequences( + op, (size_t)(oend - op), + fseTables->matchlengthCTable, mlCode, + fseTables->offcodeCTable, ofCode, + fseTables->litlengthCTable, llCode, + sequences, nbSeq, + longOffsets, bmi2); + FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed"); + op += bitstreamSize; + /* zstd versions <= 1.3.4 mistakenly report corruption when + * FSE_readNCount() receives a buffer < 4 bytes. + * Fixed by https://github.com/facebook/zstd/pull/1146. + * This can happen when the last set_compressed table present is 2 + * bytes and the bitstream is only one byte. + * In this exceedingly rare case, we will simply emit an uncompressed + * block, since it isn't worth optimizing. + */ +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (writeEntropy && fseMetadata->lastCountSize && fseMetadata->lastCountSize + bitstreamSize < 4) { + /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */ + assert(fseMetadata->lastCountSize + bitstreamSize == 3); + DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by " + "emitting an uncompressed block."); + return 0; + } +#endif + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (bitstreamSize=%zu)", bitstreamSize); + } + + /* zstd versions <= 1.4.0 mistakenly report error when + * sequences section body size is less than 3 bytes. + * Fixed by https://github.com/facebook/zstd/pull/1664. + * This can happen when the previous sequences section block is compressed + * with rle mode and the current block's sequences section is compressed + * with repeat mode where sequences section body size can be 1 byte. + */ +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (op-seqHead < 4) { + DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.4.0 by emitting " + "an uncompressed block when sequences are < 4 bytes"); + return 0; + } +#endif + + *entropyWritten = 1; + return (size_t)(op - ostart); +} + +/** ZSTD_compressSubBlock() : + * Compresses a single sub-block. + * @return : compressed size of the sub-block + * Or 0 if it failed to compress. */ +static size_t ZSTD_compressSubBlock(const ZSTD_entropyCTables_t* entropy, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + const SeqDef* sequences, size_t nbSeq, + const BYTE* literals, size_t litSize, + const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + const int bmi2, + int writeLitEntropy, int writeSeqEntropy, + int* litEntropyWritten, int* seqEntropyWritten, + U32 lastBlock) +{ + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart + ZSTD_blockHeaderSize; + DEBUGLOG(5, "ZSTD_compressSubBlock (litSize=%zu, nbSeq=%zu, writeLitEntropy=%d, writeSeqEntropy=%d, lastBlock=%d)", + litSize, nbSeq, writeLitEntropy, writeSeqEntropy, lastBlock); + { size_t cLitSize = ZSTD_compressSubBlock_literal((const HUF_CElt*)entropy->huf.CTable, + &entropyMetadata->hufMetadata, literals, litSize, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, litEntropyWritten); + FORWARD_IF_ERROR(cLitSize, "ZSTD_compressSubBlock_literal failed"); + if (cLitSize == 0) return 0; + op += cLitSize; + } + { size_t cSeqSize = ZSTD_compressSubBlock_sequences(&entropy->fse, + &entropyMetadata->fseMetadata, + sequences, nbSeq, + llCode, mlCode, ofCode, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeSeqEntropy, seqEntropyWritten); + FORWARD_IF_ERROR(cSeqSize, "ZSTD_compressSubBlock_sequences failed"); + if (cSeqSize == 0) return 0; + op += cSeqSize; + } + /* Write block header */ + { size_t cSize = (size_t)(op-ostart) - ZSTD_blockHeaderSize; + U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); + MEM_writeLE24(ostart, cBlockHeader24); + } + return (size_t)(op-ostart); +} + +static size_t ZSTD_estimateSubBlockSize_literal(const BYTE* literals, size_t litSize, + const ZSTD_hufCTables_t* huf, + const ZSTD_hufCTablesMetadata_t* hufMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + unsigned* const countWksp = (unsigned*)workspace; + unsigned maxSymbolValue = 255; + size_t literalSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */ + + if (hufMetadata->hType == set_basic) return litSize; + else if (hufMetadata->hType == set_rle) return 1; + else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) { + size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize); + if (ZSTD_isError(largest)) return litSize; + { size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue); + if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize; + return cLitSizeEstimate + literalSectionHeaderSize; + } } + assert(0); /* impossible */ + return 0; +} + +static size_t ZSTD_estimateSubBlockSize_symbolType(SymbolEncodingType_e type, + const BYTE* codeTable, unsigned maxCode, + size_t nbSeq, const FSE_CTable* fseCTable, + const U8* additionalBits, + short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, + void* workspace, size_t wkspSize) +{ + unsigned* const countWksp = (unsigned*)workspace; + const BYTE* ctp = codeTable; + const BYTE* const ctStart = ctp; + const BYTE* const ctEnd = ctStart + nbSeq; + size_t cSymbolTypeSizeEstimateInBits = 0; + unsigned max = maxCode; + + HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */ + if (type == set_basic) { + /* We selected this encoding type, so it must be valid. */ + assert(max <= defaultMax); + cSymbolTypeSizeEstimateInBits = max <= defaultMax + ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max) + : ERROR(GENERIC); + } else if (type == set_rle) { + cSymbolTypeSizeEstimateInBits = 0; + } else if (type == set_compressed || type == set_repeat) { + cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max); + } + if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) return nbSeq * 10; + while (ctp < ctEnd) { + if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp]; + else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */ + ctp++; + } + return cSymbolTypeSizeEstimateInBits / 8; +} + +static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_fseCTables_t* fseTables, + const ZSTD_fseCTablesMetadata_t* fseMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + size_t const sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */ + size_t cSeqSizeEstimate = 0; + if (nbSeq == 0) return sequencesSectionHeaderSize; + cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff, + nbSeq, fseTables->offcodeCTable, NULL, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL, + nbSeq, fseTables->litlengthCTable, LL_bits, + LL_defaultNorm, LL_defaultNormLog, MaxLL, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML, + nbSeq, fseTables->matchlengthCTable, ML_bits, + ML_defaultNorm, ML_defaultNormLog, MaxML, + workspace, wkspSize); + if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize; + return cSeqSizeEstimate + sequencesSectionHeaderSize; +} + +typedef struct { + size_t estLitSize; + size_t estBlockSize; +} EstimatedBlockSize; +static EstimatedBlockSize ZSTD_estimateSubBlockSize(const BYTE* literals, size_t litSize, + const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_entropyCTables_t* entropy, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize, + int writeLitEntropy, int writeSeqEntropy) +{ + EstimatedBlockSize ebs; + ebs.estLitSize = ZSTD_estimateSubBlockSize_literal(literals, litSize, + &entropy->huf, &entropyMetadata->hufMetadata, + workspace, wkspSize, writeLitEntropy); + ebs.estBlockSize = ZSTD_estimateSubBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable, + nbSeq, &entropy->fse, &entropyMetadata->fseMetadata, + workspace, wkspSize, writeSeqEntropy); + ebs.estBlockSize += ebs.estLitSize + ZSTD_blockHeaderSize; + return ebs; +} + +static int ZSTD_needSequenceEntropyTables(ZSTD_fseCTablesMetadata_t const* fseMetadata) +{ + if (fseMetadata->llType == set_compressed || fseMetadata->llType == set_rle) + return 1; + if (fseMetadata->mlType == set_compressed || fseMetadata->mlType == set_rle) + return 1; + if (fseMetadata->ofType == set_compressed || fseMetadata->ofType == set_rle) + return 1; + return 0; +} + +static size_t countLiterals(SeqStore_t const* seqStore, const SeqDef* sp, size_t seqCount) +{ + size_t n, total = 0; + assert(sp != NULL); + for (n=0; n %zu bytes", seqCount, (const void*)sp, total); + return total; +} + +#define BYTESCALE 256 + +static size_t sizeBlockSequences(const SeqDef* sp, size_t nbSeqs, + size_t targetBudget, size_t avgLitCost, size_t avgSeqCost, + int firstSubBlock) +{ + size_t n, budget = 0, inSize=0; + /* entropy headers */ + size_t const headerSize = (size_t)firstSubBlock * 120 * BYTESCALE; /* generous estimate */ + assert(firstSubBlock==0 || firstSubBlock==1); + budget += headerSize; + + /* first sequence => at least one sequence*/ + budget += sp[0].litLength * avgLitCost + avgSeqCost; + if (budget > targetBudget) return 1; + inSize = sp[0].litLength + (sp[0].mlBase+MINMATCH); + + /* loop over sequences */ + for (n=1; n targetBudget) + /* though continue to expand until the sub-block is deemed compressible */ + && (budget < inSize * BYTESCALE) ) + break; + } + + return n; +} + +/** ZSTD_compressSubBlock_multi() : + * Breaks super-block into multiple sub-blocks and compresses them. + * Entropy will be written into the first block. + * The following blocks use repeat_mode to compress. + * Sub-blocks are all compressed, except the last one when beneficial. + * @return : compressed size of the super block (which features multiple ZSTD blocks) + * or 0 if it failed to compress. */ +static size_t ZSTD_compressSubBlock_multi(const SeqStore_t* seqStorePtr, + const ZSTD_compressedBlockState_t* prevCBlock, + ZSTD_compressedBlockState_t* nextCBlock, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const int bmi2, U32 lastBlock, + void* workspace, size_t wkspSize) +{ + const SeqDef* const sstart = seqStorePtr->sequencesStart; + const SeqDef* const send = seqStorePtr->sequences; + const SeqDef* sp = sstart; /* tracks progresses within seqStorePtr->sequences */ + size_t const nbSeqs = (size_t)(send - sstart); + const BYTE* const lstart = seqStorePtr->litStart; + const BYTE* const lend = seqStorePtr->lit; + const BYTE* lp = lstart; + size_t const nbLiterals = (size_t)(lend - lstart); + BYTE const* ip = (BYTE const*)src; + BYTE const* const iend = ip + srcSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart; + const BYTE* llCodePtr = seqStorePtr->llCode; + const BYTE* mlCodePtr = seqStorePtr->mlCode; + const BYTE* ofCodePtr = seqStorePtr->ofCode; + size_t const minTarget = ZSTD_TARGETCBLOCKSIZE_MIN; /* enforce minimum size, to reduce undesirable side effects */ + size_t const targetCBlockSize = MAX(minTarget, cctxParams->targetCBlockSize); + int writeLitEntropy = (entropyMetadata->hufMetadata.hType == set_compressed); + int writeSeqEntropy = 1; + + DEBUGLOG(5, "ZSTD_compressSubBlock_multi (srcSize=%u, litSize=%u, nbSeq=%u)", + (unsigned)srcSize, (unsigned)(lend-lstart), (unsigned)(send-sstart)); + + /* let's start by a general estimation for the full block */ + if (nbSeqs > 0) { + EstimatedBlockSize const ebs = + ZSTD_estimateSubBlockSize(lp, nbLiterals, + ofCodePtr, llCodePtr, mlCodePtr, nbSeqs, + &nextCBlock->entropy, entropyMetadata, + workspace, wkspSize, + writeLitEntropy, writeSeqEntropy); + /* quick estimation */ + size_t const avgLitCost = nbLiterals ? (ebs.estLitSize * BYTESCALE) / nbLiterals : BYTESCALE; + size_t const avgSeqCost = ((ebs.estBlockSize - ebs.estLitSize) * BYTESCALE) / nbSeqs; + const size_t nbSubBlocks = MAX((ebs.estBlockSize + (targetCBlockSize/2)) / targetCBlockSize, 1); + size_t n, avgBlockBudget, blockBudgetSupp=0; + avgBlockBudget = (ebs.estBlockSize * BYTESCALE) / nbSubBlocks; + DEBUGLOG(5, "estimated fullblock size=%u bytes ; avgLitCost=%.2f ; avgSeqCost=%.2f ; targetCBlockSize=%u, nbSubBlocks=%u ; avgBlockBudget=%.0f bytes", + (unsigned)ebs.estBlockSize, (double)avgLitCost/BYTESCALE, (double)avgSeqCost/BYTESCALE, + (unsigned)targetCBlockSize, (unsigned)nbSubBlocks, (double)avgBlockBudget/BYTESCALE); + /* simplification: if estimates states that the full superblock doesn't compress, just bail out immediately + * this will result in the production of a single uncompressed block covering @srcSize.*/ + if (ebs.estBlockSize > srcSize) return 0; + + /* compress and write sub-blocks */ + assert(nbSubBlocks>0); + for (n=0; n < nbSubBlocks-1; n++) { + /* determine nb of sequences for current sub-block + nbLiterals from next sequence */ + size_t const seqCount = sizeBlockSequences(sp, (size_t)(send-sp), + avgBlockBudget + blockBudgetSupp, avgLitCost, avgSeqCost, n==0); + /* if reached last sequence : break to last sub-block (simplification) */ + assert(seqCount <= (size_t)(send-sp)); + if (sp + seqCount == send) break; + assert(seqCount > 0); + /* compress sub-block */ + { int litEntropyWritten = 0; + int seqEntropyWritten = 0; + size_t litSize = countLiterals(seqStorePtr, sp, seqCount); + const size_t decompressedSize = + ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, 0); + size_t const cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, + sp, seqCount, + lp, litSize, + llCodePtr, mlCodePtr, ofCodePtr, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, writeSeqEntropy, + &litEntropyWritten, &seqEntropyWritten, + 0); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed"); + + /* check compressibility, update state components */ + if (cSize > 0 && cSize < decompressedSize) { + DEBUGLOG(5, "Committed sub-block compressing %u bytes => %u bytes", + (unsigned)decompressedSize, (unsigned)cSize); + assert(ip + decompressedSize <= iend); + ip += decompressedSize; + lp += litSize; + op += cSize; + llCodePtr += seqCount; + mlCodePtr += seqCount; + ofCodePtr += seqCount; + /* Entropy only needs to be written once */ + if (litEntropyWritten) { + writeLitEntropy = 0; + } + if (seqEntropyWritten) { + writeSeqEntropy = 0; + } + sp += seqCount; + blockBudgetSupp = 0; + } } + /* otherwise : do not compress yet, coalesce current sub-block with following one */ + } + } /* if (nbSeqs > 0) */ + + /* write last block */ + DEBUGLOG(5, "Generate last sub-block: %u sequences remaining", (unsigned)(send - sp)); + { int litEntropyWritten = 0; + int seqEntropyWritten = 0; + size_t litSize = (size_t)(lend - lp); + size_t seqCount = (size_t)(send - sp); + const size_t decompressedSize = + ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, 1); + size_t const cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, + sp, seqCount, + lp, litSize, + llCodePtr, mlCodePtr, ofCodePtr, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, writeSeqEntropy, + &litEntropyWritten, &seqEntropyWritten, + lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed"); + + /* update pointers, the nb of literals borrowed from next sequence must be preserved */ + if (cSize > 0 && cSize < decompressedSize) { + DEBUGLOG(5, "Last sub-block compressed %u bytes => %u bytes", + (unsigned)decompressedSize, (unsigned)cSize); + assert(ip + decompressedSize <= iend); + ip += decompressedSize; + lp += litSize; + op += cSize; + llCodePtr += seqCount; + mlCodePtr += seqCount; + ofCodePtr += seqCount; + /* Entropy only needs to be written once */ + if (litEntropyWritten) { + writeLitEntropy = 0; + } + if (seqEntropyWritten) { + writeSeqEntropy = 0; + } + sp += seqCount; + } + } + + + if (writeLitEntropy) { + DEBUGLOG(5, "Literal entropy tables were never written"); + ZSTD_memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf)); + } + if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) { + /* If we haven't written our entropy tables, then we've violated our contract and + * must emit an uncompressed block. + */ + DEBUGLOG(5, "Sequence entropy tables were never written => cancel, emit an uncompressed block"); + return 0; + } + + if (ip < iend) { + /* some data left : last part of the block sent uncompressed */ + size_t const rSize = (size_t)((iend - ip)); + size_t const cSize = ZSTD_noCompressBlock(op, (size_t)(oend - op), ip, rSize, lastBlock); + DEBUGLOG(5, "Generate last uncompressed sub-block of %u bytes", (unsigned)(rSize)); + FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); + assert(cSize != 0); + op += cSize; + /* We have to regenerate the repcodes because we've skipped some sequences */ + if (sp < send) { + const SeqDef* seq; + Repcodes_t rep; + ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep)); + for (seq = sstart; seq < sp; ++seq) { + ZSTD_updateRep(rep.rep, seq->offBase, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0); + } + ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep)); + } + } + + DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed all subBlocks: total compressed size = %u", + (unsigned)(op-ostart)); + return (size_t)(op-ostart); +} + +size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + unsigned lastBlock) +{ + ZSTD_entropyCTablesMetadata_t entropyMetadata; + + FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(&zc->seqStore, + &zc->blockState.prevCBlock->entropy, + &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + &entropyMetadata, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */), ""); + + return ZSTD_compressSubBlock_multi(&zc->seqStore, + zc->blockState.prevCBlock, + zc->blockState.nextCBlock, + &entropyMetadata, + &zc->appliedParams, + dst, dstCapacity, + src, srcSize, + zc->bmi2, lastBlock, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */); +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.h b/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.h new file mode 100644 index 0000000000..a8765694d9 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPRESS_ADVANCED_H +#define ZSTD_COMPRESS_ADVANCED_H + +/*-************************************* +* Dependencies +***************************************/ + +#include "../zstd.h" /* ZSTD_CCtx */ + +/*-************************************* +* Target Compressed Block Size +***************************************/ + +/* ZSTD_compressSuperBlock() : + * Used to compress a super block when targetCBlockSize is being used. + * The given block will be compressed into multiple sub blocks that are around targetCBlockSize. */ +size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + void const* src, size_t srcSize, + unsigned lastBlock); + +#endif /* ZSTD_COMPRESS_ADVANCED_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_cwksp.h b/src/commonlib/bsd/zstd/compress/zstd_cwksp.h new file mode 100644 index 0000000000..bb5d283a22 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_cwksp.h @@ -0,0 +1,767 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CWKSP_H +#define ZSTD_CWKSP_H + +/*-************************************* +* Dependencies +***************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customFree */ +#include "../common/zstd_internal.h" +#include "../common/portability_macros.h" +#include "../common/zstd_compiler.h" /* ZS2_isPower2 */ + +/*-************************************* +* Constants +***************************************/ + +/* Since the workspace is effectively its own little malloc implementation / + * arena, when we run under ASAN, we should similarly insert redzones between + * each internal element of the workspace, so ASAN will catch overruns that + * reach outside an object but that stay inside the workspace. + * + * This defines the size of that redzone. + */ +#ifndef ZSTD_CWKSP_ASAN_REDZONE_SIZE +#define ZSTD_CWKSP_ASAN_REDZONE_SIZE 128 +#endif + + +/* Set our tables and aligneds to align by 64 bytes */ +#define ZSTD_CWKSP_ALIGNMENT_BYTES 64 + +/*-************************************* +* Structures +***************************************/ +typedef enum { + ZSTD_cwksp_alloc_objects, + ZSTD_cwksp_alloc_aligned_init_once, + ZSTD_cwksp_alloc_aligned, + ZSTD_cwksp_alloc_buffers +} ZSTD_cwksp_alloc_phase_e; + +/** + * Used to describe whether the workspace is statically allocated (and will not + * necessarily ever be freed), or if it's dynamically allocated and we can + * expect a well-formed caller to free this. + */ +typedef enum { + ZSTD_cwksp_dynamic_alloc, + ZSTD_cwksp_static_alloc +} ZSTD_cwksp_static_alloc_e; + +/** + * Zstd fits all its internal datastructures into a single continuous buffer, + * so that it only needs to perform a single OS allocation (or so that a buffer + * can be provided to it and it can perform no allocations at all). This buffer + * is called the workspace. + * + * Several optimizations complicate that process of allocating memory ranges + * from this workspace for each internal datastructure: + * + * - These different internal datastructures have different setup requirements: + * + * - The static objects need to be cleared once and can then be trivially + * reused for each compression. + * + * - Various buffers don't need to be initialized at all--they are always + * written into before they're read. + * + * - The matchstate tables have a unique requirement that they don't need + * their memory to be totally cleared, but they do need the memory to have + * some bound, i.e., a guarantee that all values in the memory they've been + * allocated is less than some maximum value (which is the starting value + * for the indices that they will then use for compression). When this + * guarantee is provided to them, they can use the memory without any setup + * work. When it can't, they have to clear the area. + * + * - These buffers also have different alignment requirements. + * + * - We would like to reuse the objects in the workspace for multiple + * compressions without having to perform any expensive reallocation or + * reinitialization work. + * + * - We would like to be able to efficiently reuse the workspace across + * multiple compressions **even when the compression parameters change** and + * we need to resize some of the objects (where possible). + * + * To attempt to manage this buffer, given these constraints, the ZSTD_cwksp + * abstraction was created. It works as follows: + * + * Workspace Layout: + * + * [ ... workspace ... ] + * [objects][tables ->] free space [<- buffers][<- aligned][<- init once] + * + * The various objects that live in the workspace are divided into the + * following categories, and are allocated separately: + * + * - Static objects: this is optionally the enclosing ZSTD_CCtx or ZSTD_CDict, + * so that literally everything fits in a single buffer. Note: if present, + * this must be the first object in the workspace, since ZSTD_customFree{CCtx, + * CDict}() rely on a pointer comparison to see whether one or two frees are + * required. + * + * - Fixed size objects: these are fixed-size, fixed-count objects that are + * nonetheless "dynamically" allocated in the workspace so that we can + * control how they're initialized separately from the broader ZSTD_CCtx. + * Examples: + * - Entropy Workspace + * - 2 x ZSTD_compressedBlockState_t + * - CDict dictionary contents + * + * - Tables: these are any of several different datastructures (hash tables, + * chain tables, binary trees) that all respect a common format: they are + * uint32_t arrays, all of whose values are between 0 and (nextSrc - base). + * Their sizes depend on the cparams. These tables are 64-byte aligned. + * + * - Init once: these buffers require to be initialized at least once before + * use. They should be used when we want to skip memory initialization + * while not triggering memory checkers (like Valgrind) when reading from + * from this memory without writing to it first. + * These buffers should be used carefully as they might contain data + * from previous compressions. + * Buffers are aligned to 64 bytes. + * + * - Aligned: these buffers don't require any initialization before they're + * used. The user of the buffer should make sure they write into a buffer + * location before reading from it. + * Buffers are aligned to 64 bytes. + * + * - Buffers: these buffers are used for various purposes that don't require + * any alignment or initialization before they're used. This means they can + * be moved around at no cost for a new compression. + * + * Allocating Memory: + * + * The various types of objects must be allocated in order, so they can be + * correctly packed into the workspace buffer. That order is: + * + * 1. Objects + * 2. Init once / Tables + * 3. Aligned / Tables + * 4. Buffers / Tables + * + * Attempts to reserve objects of different types out of order will fail. + */ +typedef struct { + void* workspace; + void* workspaceEnd; + + void* objectEnd; + void* tableEnd; + void* tableValidEnd; + void* allocStart; + void* initOnceStart; + + BYTE allocFailed; + int workspaceOversizedDuration; + ZSTD_cwksp_alloc_phase_e phase; + ZSTD_cwksp_static_alloc_e isStatic; +} ZSTD_cwksp; + +/*-************************************* +* Functions +***************************************/ + +MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws); +MEM_STATIC void* ZSTD_cwksp_initialAllocStart(ZSTD_cwksp* ws); + +MEM_STATIC void ZSTD_cwksp_assert_internal_consistency(ZSTD_cwksp* ws) { + (void)ws; + assert(ws->workspace <= ws->objectEnd); + assert(ws->objectEnd <= ws->tableEnd); + assert(ws->objectEnd <= ws->tableValidEnd); + assert(ws->tableEnd <= ws->allocStart); + assert(ws->tableValidEnd <= ws->allocStart); + assert(ws->allocStart <= ws->workspaceEnd); + assert(ws->initOnceStart <= ZSTD_cwksp_initialAllocStart(ws)); + assert(ws->workspace <= ws->initOnceStart); +#if ZSTD_MEMORY_SANITIZER + { + intptr_t const offset = __msan_test_shadow(ws->initOnceStart, + (U8*)ZSTD_cwksp_initialAllocStart(ws) - (U8*)ws->initOnceStart); + (void)offset; +#if defined(ZSTD_MSAN_PRINT) + if(offset!=-1) { + __msan_print_shadow((U8*)ws->initOnceStart + offset - 8, 32); + } +#endif + assert(offset==-1); + }; +#endif +} + +/** + * Align must be a power of 2. + */ +MEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t align) { + size_t const mask = align - 1; + assert(ZSTD_isPower2(align)); + return (size + mask) & ~mask; +} + +/** + * Use this to determine how much space in the workspace we will consume to + * allocate this object. (Normally it should be exactly the size of the object, + * but under special conditions, like ASAN, where we pad each object, it might + * be larger.) + * + * Since tables aren't currently redzoned, you don't need to call through this + * to figure out how much space you need for the matchState tables. Everything + * else is though. + * + * Do not use for sizing aligned buffers. Instead, use ZSTD_cwksp_aligned64_alloc_size(). + */ +MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) { + if (size == 0) + return 0; +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + return size + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; +#else + return size; +#endif +} + +MEM_STATIC size_t ZSTD_cwksp_aligned_alloc_size(size_t size, size_t alignment) { + return ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(size, alignment)); +} + +/** + * Returns an adjusted alloc size that is the nearest larger multiple of 64 bytes. + * Used to determine the number of bytes required for a given "aligned". + */ +MEM_STATIC size_t ZSTD_cwksp_aligned64_alloc_size(size_t size) { + return ZSTD_cwksp_aligned_alloc_size(size, ZSTD_CWKSP_ALIGNMENT_BYTES); +} + +/** + * Returns the amount of additional space the cwksp must allocate + * for internal purposes (currently only alignment). + */ +MEM_STATIC size_t ZSTD_cwksp_slack_space_required(void) { + /* For alignment, the wksp will always allocate an additional 2*ZSTD_CWKSP_ALIGNMENT_BYTES + * bytes to align the beginning of tables section and end of buffers; + */ + size_t const slackSpace = ZSTD_CWKSP_ALIGNMENT_BYTES * 2; + return slackSpace; +} + + +/** + * Return the number of additional bytes required to align a pointer to the given number of bytes. + * alignBytes must be a power of two. + */ +MEM_STATIC size_t ZSTD_cwksp_bytes_to_align_ptr(void* ptr, const size_t alignBytes) { + size_t const alignBytesMask = alignBytes - 1; + size_t const bytes = (alignBytes - ((size_t)ptr & (alignBytesMask))) & alignBytesMask; + assert(ZSTD_isPower2(alignBytes)); + assert(bytes < alignBytes); + return bytes; +} + +/** + * Returns the initial value for allocStart which is used to determine the position from + * which we can allocate from the end of the workspace. + */ +MEM_STATIC void* ZSTD_cwksp_initialAllocStart(ZSTD_cwksp* ws) +{ + char* endPtr = (char*)ws->workspaceEnd; + assert(ZSTD_isPower2(ZSTD_CWKSP_ALIGNMENT_BYTES)); + endPtr = endPtr - ((size_t)endPtr % ZSTD_CWKSP_ALIGNMENT_BYTES); + return (void*)endPtr; +} + +/** + * Internal function. Do not use directly. + * Reserves the given number of bytes within the aligned/buffer segment of the wksp, + * which counts from the end of the wksp (as opposed to the object/table segment). + * + * Returns a pointer to the beginning of that space. + */ +MEM_STATIC void* +ZSTD_cwksp_reserve_internal_buffer_space(ZSTD_cwksp* ws, size_t const bytes) +{ + void* const alloc = (BYTE*)ws->allocStart - bytes; + void* const bottom = ws->tableEnd; + DEBUGLOG(5, "cwksp: reserving [0x%p]:%zd bytes; %zd bytes remaining", + alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes); + ZSTD_cwksp_assert_internal_consistency(ws); + assert(alloc >= bottom); + if (alloc < bottom) { + DEBUGLOG(4, "cwksp: alloc failed!"); + ws->allocFailed = 1; + return NULL; + } + /* the area is reserved from the end of wksp. + * If it overlaps with tableValidEnd, it voids guarantees on values' range */ + if (alloc < ws->tableValidEnd) { + ws->tableValidEnd = alloc; + } + ws->allocStart = alloc; + return alloc; +} + +/** + * Moves the cwksp to the next phase, and does any necessary allocations. + * cwksp initialization must necessarily go through each phase in order. + * Returns a 0 on success, or zstd error + */ +MEM_STATIC size_t +ZSTD_cwksp_internal_advance_phase(ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase) +{ + assert(phase >= ws->phase); + if (phase > ws->phase) { + /* Going from allocating objects to allocating initOnce / tables */ + if (ws->phase < ZSTD_cwksp_alloc_aligned_init_once && + phase >= ZSTD_cwksp_alloc_aligned_init_once) { + ws->tableValidEnd = ws->objectEnd; + ws->initOnceStart = ZSTD_cwksp_initialAllocStart(ws); + + { /* Align the start of the tables to 64 bytes. Use [0, 63] bytes */ + void *const alloc = ws->objectEnd; + size_t const bytesToAlign = ZSTD_cwksp_bytes_to_align_ptr(alloc, ZSTD_CWKSP_ALIGNMENT_BYTES); + void *const objectEnd = (BYTE *) alloc + bytesToAlign; + DEBUGLOG(5, "reserving table alignment addtl space: %zu", bytesToAlign); + RETURN_ERROR_IF(objectEnd > ws->workspaceEnd, memory_allocation, + "table phase - alignment initial allocation failed!"); + ws->objectEnd = objectEnd; + ws->tableEnd = objectEnd; /* table area starts being empty */ + if (ws->tableValidEnd < ws->tableEnd) { + ws->tableValidEnd = ws->tableEnd; + } + } + } + ws->phase = phase; + ZSTD_cwksp_assert_internal_consistency(ws); + } + return 0; +} + +/** + * Returns whether this object/buffer/etc was allocated in this workspace. + */ +MEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp* ws, const void* ptr) +{ + return (ptr != NULL) && (ws->workspace <= ptr) && (ptr < ws->workspaceEnd); +} + +/** + * Internal function. Do not use directly. + */ +MEM_STATIC void* +ZSTD_cwksp_reserve_internal(ZSTD_cwksp* ws, size_t bytes, ZSTD_cwksp_alloc_phase_e phase) +{ + void* alloc; + if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase)) || bytes == 0) { + return NULL; + } + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* over-reserve space */ + bytes += 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; +#endif + + alloc = ZSTD_cwksp_reserve_internal_buffer_space(ws, bytes); + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on + * either size. */ + if (alloc) { + alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE; + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + /* We need to keep the redzone poisoned while unpoisoning the bytes that + * are actually allocated. */ + __asan_unpoison_memory_region(alloc, bytes - 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE); + } + } +#endif + + return alloc; +} + +/** + * Reserves and returns unaligned memory. + */ +MEM_STATIC BYTE* ZSTD_cwksp_reserve_buffer(ZSTD_cwksp* ws, size_t bytes) +{ + return (BYTE*)ZSTD_cwksp_reserve_internal(ws, bytes, ZSTD_cwksp_alloc_buffers); +} + +/** + * Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes). + * This memory has been initialized at least once in the past. + * This doesn't mean it has been initialized this time, and it might contain data from previous + * operations. + * The main usage is for algorithms that might need read access into uninitialized memory. + * The algorithm must maintain safety under these conditions and must make sure it doesn't + * leak any of the past data (directly or in side channels). + */ +MEM_STATIC void* ZSTD_cwksp_reserve_aligned_init_once(ZSTD_cwksp* ws, size_t bytes) +{ + size_t const alignedBytes = ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES); + void* ptr = ZSTD_cwksp_reserve_internal(ws, alignedBytes, ZSTD_cwksp_alloc_aligned_init_once); + assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + if(ptr && ptr < ws->initOnceStart) { + /* We assume the memory following the current allocation is either: + * 1. Not usable as initOnce memory (end of workspace) + * 2. Another initOnce buffer that has been allocated before (and so was previously memset) + * 3. An ASAN redzone, in which case we don't want to write on it + * For these reasons it should be fine to not explicitly zero every byte up to ws->initOnceStart. + * Note that we assume here that MSAN and ASAN cannot run in the same time. */ + ZSTD_memset(ptr, 0, MIN((size_t)((U8*)ws->initOnceStart - (U8*)ptr), alignedBytes)); + ws->initOnceStart = ptr; + } +#if ZSTD_MEMORY_SANITIZER + assert(__msan_test_shadow(ptr, bytes) == -1); +#endif + return ptr; +} + +/** + * Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes). + */ +MEM_STATIC void* ZSTD_cwksp_reserve_aligned64(ZSTD_cwksp* ws, size_t bytes) +{ + void* const ptr = ZSTD_cwksp_reserve_internal(ws, + ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES), + ZSTD_cwksp_alloc_aligned); + assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + return ptr; +} + +/** + * Aligned on 64 bytes. These buffers have the special property that + * their values remain constrained, allowing us to reuse them without + * memset()-ing them. + */ +MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) +{ + const ZSTD_cwksp_alloc_phase_e phase = ZSTD_cwksp_alloc_aligned_init_once; + void* alloc; + void* end; + void* top; + + /* We can only start allocating tables after we are done reserving space for objects at the + * start of the workspace */ + if(ws->phase < phase) { + if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase))) { + return NULL; + } + } + alloc = ws->tableEnd; + end = (BYTE *)alloc + bytes; + top = ws->allocStart; + + DEBUGLOG(5, "cwksp: reserving %p table %zd bytes, %zd bytes remaining", + alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes); + assert((bytes & (sizeof(U32)-1)) == 0); + ZSTD_cwksp_assert_internal_consistency(ws); + assert(end <= top); + if (end > top) { + DEBUGLOG(4, "cwksp: table alloc failed!"); + ws->allocFailed = 1; + return NULL; + } + ws->tableEnd = end; + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + __asan_unpoison_memory_region(alloc, bytes); + } +#endif + + assert((bytes & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + assert(((size_t)alloc & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + return alloc; +} + +/** + * Aligned on sizeof(void*). + * Note : should happen only once, at workspace first initialization + */ +MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) +{ + size_t const roundedBytes = ZSTD_cwksp_align(bytes, sizeof(void*)); + void* alloc = ws->objectEnd; + void* end = (BYTE*)alloc + roundedBytes; + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* over-reserve space */ + end = (BYTE *)end + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; +#endif + + DEBUGLOG(4, + "cwksp: reserving %p object %zd bytes (rounded to %zd), %zd bytes remaining", + alloc, bytes, roundedBytes, ZSTD_cwksp_available_space(ws) - roundedBytes); + assert((size_t)alloc % ZSTD_ALIGNOF(void*) == 0); + assert(bytes % ZSTD_ALIGNOF(void*) == 0); + ZSTD_cwksp_assert_internal_consistency(ws); + /* we must be in the first phase, no advance is possible */ + if (ws->phase != ZSTD_cwksp_alloc_objects || end > ws->workspaceEnd) { + DEBUGLOG(3, "cwksp: object alloc failed!"); + ws->allocFailed = 1; + return NULL; + } + ws->objectEnd = end; + ws->tableEnd = end; + ws->tableValidEnd = end; + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on + * either size. */ + alloc = (BYTE*)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE; + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + __asan_unpoison_memory_region(alloc, bytes); + } +#endif + + return alloc; +} +/** + * with alignment control + * Note : should happen only once, at workspace first initialization + */ +MEM_STATIC void* ZSTD_cwksp_reserve_object_aligned(ZSTD_cwksp* ws, size_t byteSize, size_t alignment) +{ + size_t const mask = alignment - 1; + size_t const surplus = (alignment > sizeof(void*)) ? alignment - sizeof(void*) : 0; + void* const start = ZSTD_cwksp_reserve_object(ws, byteSize + surplus); + if (start == NULL) return NULL; + if (surplus == 0) return start; + assert(ZSTD_isPower2(alignment)); + return (void*)(((size_t)start + surplus) & ~mask); +} + +MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws) +{ + DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_dirty"); + +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) + /* To validate that the table reuse logic is sound, and that we don't + * access table space that we haven't cleaned, we re-"poison" the table + * space every time we mark it dirty. + * Since tableValidEnd space and initOnce space may overlap we don't poison + * the initOnce portion as it break its promise. This means that this poisoning + * check isn't always applied fully. */ + { + size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd; + assert(__msan_test_shadow(ws->objectEnd, size) == -1); + if((BYTE*)ws->tableValidEnd < (BYTE*)ws->initOnceStart) { + __msan_poison(ws->objectEnd, size); + } else { + assert(ws->initOnceStart >= ws->objectEnd); + __msan_poison(ws->objectEnd, (BYTE*)ws->initOnceStart - (BYTE*)ws->objectEnd); + } + } +#endif + + assert(ws->tableValidEnd >= ws->objectEnd); + assert(ws->tableValidEnd <= ws->allocStart); + ws->tableValidEnd = ws->objectEnd; + ZSTD_cwksp_assert_internal_consistency(ws); +} + +MEM_STATIC void ZSTD_cwksp_mark_tables_clean(ZSTD_cwksp* ws) { + DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_clean"); + assert(ws->tableValidEnd >= ws->objectEnd); + assert(ws->tableValidEnd <= ws->allocStart); + if (ws->tableValidEnd < ws->tableEnd) { + ws->tableValidEnd = ws->tableEnd; + } + ZSTD_cwksp_assert_internal_consistency(ws); +} + +/** + * Zero the part of the allocated tables not already marked clean. + */ +MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) { + DEBUGLOG(4, "cwksp: ZSTD_cwksp_clean_tables"); + assert(ws->tableValidEnd >= ws->objectEnd); + assert(ws->tableValidEnd <= ws->allocStart); + if (ws->tableValidEnd < ws->tableEnd) { + ZSTD_memset(ws->tableValidEnd, 0, (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd)); + } + ZSTD_cwksp_mark_tables_clean(ws); +} + +/** + * Invalidates table allocations. + * All other allocations remain valid. + */ +MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) +{ + DEBUGLOG(4, "cwksp: clearing tables!"); + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* We don't do this when the workspace is statically allocated, because + * when that is the case, we have no capability to hook into the end of the + * workspace's lifecycle to unpoison the memory. + */ + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd; + __asan_poison_memory_region(ws->objectEnd, size); + } +#endif + + ws->tableEnd = ws->objectEnd; + ZSTD_cwksp_assert_internal_consistency(ws); +} + +/** + * Invalidates all buffer, aligned, and table allocations. + * Object allocations remain valid. + */ +MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) { + DEBUGLOG(4, "cwksp: clearing!"); + +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) + /* To validate that the context reuse logic is sound, and that we don't + * access stuff that this compression hasn't initialized, we re-"poison" + * the workspace except for the areas in which we expect memory reuse + * without initialization (objects, valid tables area and init once + * memory). */ + { + if((BYTE*)ws->tableValidEnd < (BYTE*)ws->initOnceStart) { + size_t size = (BYTE*)ws->initOnceStart - (BYTE*)ws->tableValidEnd; + __msan_poison(ws->tableValidEnd, size); + } + } +#endif + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* We don't do this when the workspace is statically allocated, because + * when that is the case, we have no capability to hook into the end of the + * workspace's lifecycle to unpoison the memory. + */ + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->objectEnd; + __asan_poison_memory_region(ws->objectEnd, size); + } +#endif + + ws->tableEnd = ws->objectEnd; + ws->allocStart = ZSTD_cwksp_initialAllocStart(ws); + ws->allocFailed = 0; + if (ws->phase > ZSTD_cwksp_alloc_aligned_init_once) { + ws->phase = ZSTD_cwksp_alloc_aligned_init_once; + } + ZSTD_cwksp_assert_internal_consistency(ws); +} + +MEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace); +} + +MEM_STATIC size_t ZSTD_cwksp_used(const ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->workspace) + + (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->allocStart); +} + +/** + * The provided workspace takes ownership of the buffer [start, start+size). + * Any existing values in the workspace are ignored (the previously managed + * buffer, if present, must be separately freed). + */ +MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size, ZSTD_cwksp_static_alloc_e isStatic) { + DEBUGLOG(4, "cwksp: init'ing workspace with %zd bytes", size); + assert(((size_t)start & (sizeof(void*)-1)) == 0); /* ensure correct alignment */ + ws->workspace = start; + ws->workspaceEnd = (BYTE*)start + size; + ws->objectEnd = ws->workspace; + ws->tableValidEnd = ws->objectEnd; + ws->initOnceStart = ZSTD_cwksp_initialAllocStart(ws); + ws->phase = ZSTD_cwksp_alloc_objects; + ws->isStatic = isStatic; + ZSTD_cwksp_clear(ws); + ws->workspaceOversizedDuration = 0; + ZSTD_cwksp_assert_internal_consistency(ws); +} + +MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem customMem) { + void* workspace = ZSTD_customMalloc(size, customMem); + DEBUGLOG(4, "cwksp: creating new workspace with %zd bytes", size); + RETURN_ERROR_IF(workspace == NULL, memory_allocation, "NULL pointer!"); + ZSTD_cwksp_init(ws, workspace, size, ZSTD_cwksp_dynamic_alloc); + return 0; +} + +MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) { + void *ptr = ws->workspace; + DEBUGLOG(4, "cwksp: freeing workspace"); +#if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE) + if (ptr != NULL && customMem.customFree != NULL) { + __msan_unpoison(ptr, ZSTD_cwksp_sizeof(ws)); + } +#endif + ZSTD_memset(ws, 0, sizeof(ZSTD_cwksp)); + ZSTD_customFree(ptr, customMem); +} + +/** + * Moves the management of a workspace from one cwksp to another. The src cwksp + * is left in an invalid state (src must be re-init()'ed before it's used again). + */ +MEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp* dst, ZSTD_cwksp* src) { + *dst = *src; + ZSTD_memset(src, 0, sizeof(ZSTD_cwksp)); +} + +MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) { + return ws->allocFailed; +} + +/*-************************************* +* Functions Checking Free Space +***************************************/ + +/* ZSTD_alignmentSpaceWithinBounds() : + * Returns if the estimated space needed for a wksp is within an acceptable limit of the + * actual amount of space used. + */ +MEM_STATIC int ZSTD_cwksp_estimated_space_within_bounds(const ZSTD_cwksp *const ws, size_t const estimatedSpace) { + /* We have an alignment space between objects and tables between tables and buffers, so we can have up to twice + * the alignment bytes difference between estimation and actual usage */ + return (estimatedSpace - ZSTD_cwksp_slack_space_required()) <= ZSTD_cwksp_used(ws) && + ZSTD_cwksp_used(ws) <= estimatedSpace; +} + + +MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->allocStart - (BYTE*)ws->tableEnd); +} + +MEM_STATIC int ZSTD_cwksp_check_available(ZSTD_cwksp* ws, size_t additionalNeededSpace) { + return ZSTD_cwksp_available_space(ws) >= additionalNeededSpace; +} + +MEM_STATIC int ZSTD_cwksp_check_too_large(ZSTD_cwksp* ws, size_t additionalNeededSpace) { + return ZSTD_cwksp_check_available( + ws, additionalNeededSpace * ZSTD_WORKSPACETOOLARGE_FACTOR); +} + +MEM_STATIC int ZSTD_cwksp_check_wasteful(ZSTD_cwksp* ws, size_t additionalNeededSpace) { + return ZSTD_cwksp_check_too_large(ws, additionalNeededSpace) + && ws->workspaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION; +} + +MEM_STATIC void ZSTD_cwksp_bump_oversized_duration( + ZSTD_cwksp* ws, size_t additionalNeededSpace) { + if (ZSTD_cwksp_check_too_large(ws, additionalNeededSpace)) { + ws->workspaceOversizedDuration++; + } else { + ws->workspaceOversizedDuration = 0; + } +} + +#endif /* ZSTD_CWKSP_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_double_fast.c b/src/commonlib/bsd/zstd/compress/zstd_double_fast.c new file mode 100644 index 0000000000..7a2a56b823 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_double_fast.c @@ -0,0 +1,780 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" +#include "zstd_double_fast.h" + +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillDoubleHashTableForCDict(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashLarge = ms->hashTable; + U32 const hBitsL = cParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + U32 const mls = cParams->minMatch; + U32* const hashSmall = ms->chainTable; + U32 const hBitsS = cParams->chainLog + ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Always insert every fastHashFillStep position into the hash tables. + * Insert the other positions into the large hash table if their entry + * is empty. + */ + for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + U32 i; + for (i = 0; i < fastHashFillStep; ++i) { + size_t const smHashAndTag = ZSTD_hashPtr(ip + i, hBitsS, mls); + size_t const lgHashAndTag = ZSTD_hashPtr(ip + i, hBitsL, 8); + if (i == 0) { + ZSTD_writeTaggedIndex(hashSmall, smHashAndTag, curr + i); + } + if (i == 0 || hashLarge[lgHashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS] == 0) { + ZSTD_writeTaggedIndex(hashLarge, lgHashAndTag, curr + i); + } + /* Only load extra positions for ZSTD_dtlm_full */ + if (dtlm == ZSTD_dtlm_fast) + break; + } } +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillDoubleHashTableForCCtx(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashLarge = ms->hashTable; + U32 const hBitsL = cParams->hashLog; + U32 const mls = cParams->minMatch; + U32* const hashSmall = ms->chainTable; + U32 const hBitsS = cParams->chainLog; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Always insert every fastHashFillStep position into the hash tables. + * Insert the other positions into the large hash table if their entry + * is empty. + */ + for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + U32 i; + for (i = 0; i < fastHashFillStep; ++i) { + size_t const smHash = ZSTD_hashPtr(ip + i, hBitsS, mls); + size_t const lgHash = ZSTD_hashPtr(ip + i, hBitsL, 8); + if (i == 0) + hashSmall[smHash] = curr + i; + if (i == 0 || hashLarge[lgHash] == 0) + hashLarge[lgHash] = curr + i; + /* Only load extra positions for ZSTD_dtlm_full */ + if (dtlm == ZSTD_dtlm_fast) + break; + } } +} + +void ZSTD_fillDoubleHashTable(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp) +{ + if (tfp == ZSTD_tfp_forCDict) { + ZSTD_fillDoubleHashTableForCDict(ms, end, dtlm); + } else { + ZSTD_fillDoubleHashTableForCCtx(ms, end, dtlm); + } +} + + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_doubleFast_noDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, U32 const mls /* template */) +{ + ZSTD_compressionParameters const* cParams = &ms->cParams; + U32* const hashLong = ms->hashTable; + const U32 hBitsL = cParams->hashLog; + U32* const hashSmall = ms->chainTable; + const U32 hBitsS = cParams->chainLog; + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const BYTE* anchor = istart; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + /* presumes that, if there is a dictionary, it must be using Attach mode */ + const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixLowest = base + prefixLowestIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + U32 offset_1=rep[0], offset_2=rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + size_t mLength; + U32 offset; + U32 curr; + + /* how many positions to search before increasing step size */ + const size_t kStepIncr = 1 << kSearchStrength; + /* the position at which to increment the step size if no match is found */ + const BYTE* nextStep; + size_t step; /* the current step size */ + + size_t hl0; /* the long hash at ip */ + size_t hl1; /* the long hash at ip1 */ + + U32 idxl0; /* the long match index for ip */ + U32 idxl1; /* the long match index for ip1 */ + + const BYTE* matchl0; /* the long match for ip */ + const BYTE* matchs0; /* the short match for ip */ + const BYTE* matchl1; /* the long match for ip1 */ + const BYTE* matchs0_safe; /* matchs0 or safe address */ + + const BYTE* ip = istart; /* the current position */ + const BYTE* ip1; /* the next position */ + /* Array of ~random data, should have low probability of matching data + * we load from here instead of from tables, if matchl0/matchl1 are + * invalid indices. Used to avoid unpredictable branches. */ + const BYTE dummy[] = {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0xe2,0xb4}; + + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_noDict_generic"); + + /* init */ + ip += ((ip - prefixLowest) == 0); + { + U32 const current = (U32)(ip - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog); + U32 const maxRep = current - windowLow; + if (offset_2 > maxRep) offsetSaved2 = offset_2, offset_2 = 0; + if (offset_1 > maxRep) offsetSaved1 = offset_1, offset_1 = 0; + } + + /* Outer Loop: one iteration per match found and stored */ + while (1) { + step = 1; + nextStep = ip + kStepIncr; + ip1 = ip + step; + + if (ip1 > ilimit) { + goto _cleanup; + } + + hl0 = ZSTD_hashPtr(ip, hBitsL, 8); + idxl0 = hashLong[hl0]; + matchl0 = base + idxl0; + + /* Inner Loop: one iteration per search / position */ + do { + const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls); + const U32 idxs0 = hashSmall[hs0]; + curr = (U32)(ip-base); + matchs0 = base + idxs0; + + hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */ + + /* check noDict repcode */ + if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { + mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + goto _match_stored; + } + + hl1 = ZSTD_hashPtr(ip1, hBitsL, 8); + + /* idxl0 > prefixLowestIndex is a (somewhat) unpredictable branch. + * However expression below complies into conditional move. Since + * match is unlikely and we only *branch* on idxl0 > prefixLowestIndex + * if there is a match, all branches become predictable. */ + { const BYTE* const matchl0_safe = ZSTD_selectAddr(idxl0, prefixLowestIndex, matchl0, &dummy[0]); + + /* check prefix long match */ + if (MEM_read64(matchl0_safe) == MEM_read64(ip) && matchl0_safe == matchl0) { + mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8; + offset = (U32)(ip-matchl0); + while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */ + goto _match_found; + } } + + idxl1 = hashLong[hl1]; + matchl1 = base + idxl1; + + /* Same optimization as matchl0 above */ + matchs0_safe = ZSTD_selectAddr(idxs0, prefixLowestIndex, matchs0, &dummy[0]); + + /* check prefix short match */ + if(MEM_read32(matchs0_safe) == MEM_read32(ip) && matchs0_safe == matchs0) { + goto _search_next_long; + } + + if (ip1 >= nextStep) { + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + step++; + nextStep += kStepIncr; + } + ip = ip1; + ip1 += step; + + hl0 = hl1; + idxl0 = idxl1; + matchl0 = matchl1; + #if defined(__aarch64__) + PREFETCH_L1(ip+256); + #endif + } while (ip1 <= ilimit); + +_cleanup: + /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0), + * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */ + offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved1; + rep[1] = offset_2 ? offset_2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_search_next_long: + + /* short match found: let's check for a longer one */ + mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4; + offset = (U32)(ip - matchs0); + + /* check long match at +1 position */ + if ((idxl1 > prefixLowestIndex) && (MEM_read64(matchl1) == MEM_read64(ip1))) { + size_t const l1len = ZSTD_count(ip1+8, matchl1+8, iend) + 8; + if (l1len > mLength) { + /* use the long match instead */ + ip = ip1; + mLength = l1len; + offset = (U32)(ip-matchl1); + matchs0 = matchl1; + } + } + + while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* complete backward */ + + /* fall-through */ + +_match_found: /* requires ip, offset, mLength */ + offset_2 = offset_1; + offset_1 = offset; + + if (step < 4) { + /* It is unsafe to write this value back to the hashtable when ip1 is + * greater than or equal to the new ip we will have after we're done + * processing this match. Rather than perform that test directly + * (ip1 >= ip + mLength), which costs speed in practice, we do a simpler + * more predictable test. The minmatch even if we take a short match is + * 4 bytes, so as long as step, the distance between ip and ip1 + * (initially) is less than 4, we know ip1 < new ip. */ + hashLong[hl1] = (U32)(ip1 - base); + } + + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + +_match_stored: + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while ( (ip <= ilimit) + && ( (offset_2>0) + & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; + U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base); + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base); + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, rLength); + ip += rLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + } + } +} + + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_doubleFast_dictMatchState_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls /* template */) +{ + ZSTD_compressionParameters const* cParams = &ms->cParams; + U32* const hashLong = ms->hashTable; + const U32 hBitsL = cParams->hashLog; + U32* const hashSmall = ms->chainTable; + const U32 hBitsS = cParams->chainLog; + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + /* presumes that, if there is a dictionary, it must be using Attach mode */ + const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixLowest = base + prefixLowestIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + U32 offset_1=rep[0], offset_2=rep[1]; + + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const ZSTD_compressionParameters* const dictCParams = &dms->cParams; + const U32* const dictHashLong = dms->hashTable; + const U32* const dictHashSmall = dms->chainTable; + const U32 dictStartIndex = dms->window.dictLimit; + const BYTE* const dictBase = dms->window.base; + const BYTE* const dictStart = dictBase + dictStartIndex; + const BYTE* const dictEnd = dms->window.nextSrc; + const U32 dictIndexDelta = prefixLowestIndex - (U32)(dictEnd - dictBase); + const U32 dictHBitsL = dictCParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + const U32 dictHBitsS = dictCParams->chainLog + ZSTD_SHORT_CACHE_TAG_BITS; + const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictStart)); + + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_dictMatchState_generic"); + + /* if a dictionary is attached, it must be within window range */ + assert(ms->window.dictLimit + (1U << cParams->windowLog) >= endIndex); + + if (ms->prefetchCDictTables) { + size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32); + size_t const chainTableBytes = (((size_t)1) << dictCParams->chainLog) * sizeof(U32); + PREFETCH_AREA(dictHashLong, hashTableBytes); + PREFETCH_AREA(dictHashSmall, chainTableBytes); + } + + /* init */ + ip += (dictAndPrefixLength == 0); + + /* dictMatchState repCode checks don't currently handle repCode == 0 + * disabling. */ + assert(offset_1 <= dictAndPrefixLength); + assert(offset_2 <= dictAndPrefixLength); + + /* Main Search Loop */ + while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ + size_t mLength; + U32 offset; + size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8); + size_t const h = ZSTD_hashPtr(ip, hBitsS, mls); + size_t const dictHashAndTagL = ZSTD_hashPtr(ip, dictHBitsL, 8); + size_t const dictHashAndTagS = ZSTD_hashPtr(ip, dictHBitsS, mls); + U32 const dictMatchIndexAndTagL = dictHashLong[dictHashAndTagL >> ZSTD_SHORT_CACHE_TAG_BITS]; + U32 const dictMatchIndexAndTagS = dictHashSmall[dictHashAndTagS >> ZSTD_SHORT_CACHE_TAG_BITS]; + int const dictTagsMatchL = ZSTD_comparePackedTags(dictMatchIndexAndTagL, dictHashAndTagL); + int const dictTagsMatchS = ZSTD_comparePackedTags(dictMatchIndexAndTagS, dictHashAndTagS); + U32 const curr = (U32)(ip-base); + U32 const matchIndexL = hashLong[h2]; + U32 matchIndexS = hashSmall[h]; + const BYTE* matchLong = base + matchIndexL; + const BYTE* match = base + matchIndexS; + const U32 repIndex = curr + 1 - offset_1; + const BYTE* repMatch = (repIndex < prefixLowestIndex) ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + hashLong[h2] = hashSmall[h] = curr; /* update hash tables */ + + /* check repcode */ + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + goto _match_stored; + } + + if ((matchIndexL >= prefixLowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) { + /* check prefix long match */ + mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8; + offset = (U32)(ip-matchLong); + while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ + goto _match_found; + } else if (dictTagsMatchL) { + /* check dictMatchState long match */ + U32 const dictMatchIndexL = dictMatchIndexAndTagL >> ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* dictMatchL = dictBase + dictMatchIndexL; + assert(dictMatchL < dictEnd); + + if (dictMatchL > dictStart && MEM_read64(dictMatchL) == MEM_read64(ip)) { + mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8; + offset = (U32)(curr - dictMatchIndexL - dictIndexDelta); + while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */ + goto _match_found; + } } + + if (matchIndexS > prefixLowestIndex) { + /* short match candidate */ + if (MEM_read32(match) == MEM_read32(ip)) { + goto _search_next_long; + } + } else if (dictTagsMatchS) { + /* check dictMatchState short match */ + U32 const dictMatchIndexS = dictMatchIndexAndTagS >> ZSTD_SHORT_CACHE_TAG_BITS; + match = dictBase + dictMatchIndexS; + matchIndexS = dictMatchIndexS + dictIndexDelta; + + if (match > dictStart && MEM_read32(match) == MEM_read32(ip)) { + goto _search_next_long; + } } + + ip += ((ip-anchor) >> kSearchStrength) + 1; +#if defined(__aarch64__) + PREFETCH_L1(ip+256); +#endif + continue; + +_search_next_long: + { size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8); + size_t const dictHashAndTagL3 = ZSTD_hashPtr(ip+1, dictHBitsL, 8); + U32 const matchIndexL3 = hashLong[hl3]; + U32 const dictMatchIndexAndTagL3 = dictHashLong[dictHashAndTagL3 >> ZSTD_SHORT_CACHE_TAG_BITS]; + int const dictTagsMatchL3 = ZSTD_comparePackedTags(dictMatchIndexAndTagL3, dictHashAndTagL3); + const BYTE* matchL3 = base + matchIndexL3; + hashLong[hl3] = curr + 1; + + /* check prefix long +1 match */ + if ((matchIndexL3 >= prefixLowestIndex) && (MEM_read64(matchL3) == MEM_read64(ip+1))) { + mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8; + ip++; + offset = (U32)(ip-matchL3); + while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */ + goto _match_found; + } else if (dictTagsMatchL3) { + /* check dict long +1 match */ + U32 const dictMatchIndexL3 = dictMatchIndexAndTagL3 >> ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3; + assert(dictMatchL3 < dictEnd); + if (dictMatchL3 > dictStart && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) { + mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8; + ip++; + offset = (U32)(curr + 1 - dictMatchIndexL3 - dictIndexDelta); + while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */ + goto _match_found; + } } } + + /* if no long +1 match, explore the short match we found */ + if (matchIndexS < prefixLowestIndex) { + mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4; + offset = (U32)(curr - matchIndexS); + while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } else { + mLength = ZSTD_count(ip+4, match+4, iend) + 4; + offset = (U32)(ip - match); + while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } + +_match_found: + offset_2 = offset_1; + offset_1 = offset; + + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + +_match_stored: + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while (ip <= ilimit) { + U32 const current2 = (U32)(ip-base); + U32 const repIndex2 = current2 - offset_2; + const BYTE* repMatch2 = repIndex2 < prefixLowestIndex ? + dictBase + repIndex2 - dictIndexDelta : + base + repIndex2; + if ( (ZSTD_index_overlap_check(prefixLowestIndex, repIndex2)) + && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { + const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4; + U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2; + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2; + ip += repLength2; + anchor = ip; + continue; + } + break; + } + } + } /* while (ip < ilimit) */ + + /* save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} + +#define ZSTD_GEN_DFAST_FN(dictMode, mls) \ + static size_t ZSTD_compressBlock_doubleFast_##dictMode##_##mls( \ + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \ + void const* src, size_t srcSize) \ + { \ + return ZSTD_compressBlock_doubleFast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls); \ + } + +ZSTD_GEN_DFAST_FN(noDict, 4) +ZSTD_GEN_DFAST_FN(noDict, 5) +ZSTD_GEN_DFAST_FN(noDict, 6) +ZSTD_GEN_DFAST_FN(noDict, 7) + +ZSTD_GEN_DFAST_FN(dictMatchState, 4) +ZSTD_GEN_DFAST_FN(dictMatchState, 5) +ZSTD_GEN_DFAST_FN(dictMatchState, 6) +ZSTD_GEN_DFAST_FN(dictMatchState, 7) + + +size_t ZSTD_compressBlock_doubleFast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + const U32 mls = ms->cParams.minMatch; + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_doubleFast_noDict_4(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_doubleFast_noDict_5(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_doubleFast_noDict_6(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_doubleFast_noDict_7(ms, seqStore, rep, src, srcSize); + } +} + + +size_t ZSTD_compressBlock_doubleFast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + const U32 mls = ms->cParams.minMatch; + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_doubleFast_dictMatchState_4(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_doubleFast_dictMatchState_5(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_doubleFast_dictMatchState_6(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_doubleFast_dictMatchState_7(ms, seqStore, rep, src, srcSize); + } +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_doubleFast_extDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls /* template */) +{ + ZSTD_compressionParameters const* cParams = &ms->cParams; + U32* const hashLong = ms->hashTable; + U32 const hBitsL = cParams->hashLog; + U32* const hashSmall = ms->chainTable; + U32 const hBitsS = cParams->chainLog; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + const BYTE* const base = ms->window.base; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog); + const U32 dictStartIndex = lowLimit; + const U32 dictLimit = ms->window.dictLimit; + const U32 prefixStartIndex = (dictLimit > lowLimit) ? dictLimit : lowLimit; + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const dictBase = ms->window.dictBase; + const BYTE* const dictStart = dictBase + dictStartIndex; + const BYTE* const dictEnd = dictBase + prefixStartIndex; + U32 offset_1=rep[0], offset_2=rep[1]; + + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_extDict_generic (srcSize=%zu)", srcSize); + + /* if extDict is invalidated due to maxDistance, switch to "regular" variant */ + if (prefixStartIndex == dictStartIndex) + return ZSTD_compressBlock_doubleFast(ms, seqStore, rep, src, srcSize); + + /* Search Loop */ + while (ip < ilimit) { /* < instead of <=, because (ip+1) */ + const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls); + const U32 matchIndex = hashSmall[hSmall]; + const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base; + const BYTE* match = matchBase + matchIndex; + + const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8); + const U32 matchLongIndex = hashLong[hLong]; + const BYTE* const matchLongBase = matchLongIndex < prefixStartIndex ? dictBase : base; + const BYTE* matchLong = matchLongBase + matchLongIndex; + + const U32 curr = (U32)(ip-base); + const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */ + const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base; + const BYTE* const repMatch = repBase + repIndex; + size_t mLength; + hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */ + + if (((ZSTD_index_overlap_check(prefixStartIndex, repIndex)) + & (offset_1 <= curr+1 - dictStartIndex)) /* note: we are searching at curr+1 */ + && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { + const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + } else { + if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) { + const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend; + const BYTE* const lowMatchPtr = matchLongIndex < prefixStartIndex ? dictStart : prefixStart; + U32 offset; + mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, prefixStart) + 8; + offset = curr - matchLongIndex; + while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + + } else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) { + size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8); + U32 const matchIndex3 = hashLong[h3]; + const BYTE* const match3Base = matchIndex3 < prefixStartIndex ? dictBase : base; + const BYTE* match3 = match3Base + matchIndex3; + U32 offset; + hashLong[h3] = curr + 1; + if ( (matchIndex3 > dictStartIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) { + const BYTE* const matchEnd = matchIndex3 < prefixStartIndex ? dictEnd : iend; + const BYTE* const lowMatchPtr = matchIndex3 < prefixStartIndex ? dictStart : prefixStart; + mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, prefixStart) + 8; + ip++; + offset = curr+1 - matchIndex3; + while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */ + } else { + const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend; + const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart; + mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4; + offset = curr - matchIndex; + while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + + } else { + ip += ((ip-anchor) >> kSearchStrength) + 1; + continue; + } } + + /* move to next sequence start */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while (ip <= ilimit) { + U32 const current2 = (U32)(ip-base); + U32 const repIndex2 = current2 - offset_2; + const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2; + if ( ((ZSTD_index_overlap_check(prefixStartIndex, repIndex2)) + & (offset_2 <= current2 - dictStartIndex)) + && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { + const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; + U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2; + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2; + ip += repLength2; + anchor = ip; + continue; + } + break; + } } } + + /* save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} + +ZSTD_GEN_DFAST_FN(extDict, 4) +ZSTD_GEN_DFAST_FN(extDict, 5) +ZSTD_GEN_DFAST_FN(extDict, 6) +ZSTD_GEN_DFAST_FN(extDict, 7) + +size_t ZSTD_compressBlock_doubleFast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mls = ms->cParams.minMatch; + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_doubleFast_extDict_4(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_doubleFast_extDict_5(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_doubleFast_extDict_6(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_doubleFast_extDict_7(ms, seqStore, rep, src, srcSize); + } +} + +#endif /* ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_double_fast.h b/src/commonlib/bsd/zstd/compress/zstd_double_fast.h new file mode 100644 index 0000000000..73c5e710c8 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_double_fast.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_DOUBLE_FAST_H +#define ZSTD_DOUBLE_FAST_H + +#include "../common/mem.h" /* U32 */ +#include "zstd_compress_internal.h" /* ZSTD_CCtx, size_t */ + +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + +void ZSTD_fillDoubleHashTable(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp); + +size_t ZSTD_compressBlock_doubleFast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_doubleFast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_doubleFast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST ZSTD_compressBlock_doubleFast +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE ZSTD_compressBlock_doubleFast_dictMatchState +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT ZSTD_compressBlock_doubleFast_extDict +#else +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST NULL +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT NULL +#endif /* ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR */ + +#endif /* ZSTD_DOUBLE_FAST_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_fast.c b/src/commonlib/bsd/zstd/compress/zstd_fast.c new file mode 100644 index 0000000000..1cc9de5dbd --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_fast.c @@ -0,0 +1,987 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" /* ZSTD_hashPtr, ZSTD_count, ZSTD_storeSeq */ +#include "zstd_fast.h" + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillHashTableForCDict(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hBits = cParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + U32 const mls = cParams->minMatch; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Currently, we always use ZSTD_dtlm_full for filling CDict tables. + * Feel free to remove this assert if there's a good reason! */ + assert(dtlm == ZSTD_dtlm_full); + + /* Always insert every fastHashFillStep position into the hash table. + * Insert the other positions if their hash entry is empty. + */ + for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + { size_t const hashAndTag = ZSTD_hashPtr(ip, hBits, mls); + ZSTD_writeTaggedIndex(hashTable, hashAndTag, curr); } + + if (dtlm == ZSTD_dtlm_fast) continue; + /* Only load extra positions for ZSTD_dtlm_full */ + { U32 p; + for (p = 1; p < fastHashFillStep; ++p) { + size_t const hashAndTag = ZSTD_hashPtr(ip + p, hBits, mls); + if (hashTable[hashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS] == 0) { /* not yet filled */ + ZSTD_writeTaggedIndex(hashTable, hashAndTag, curr + p); + } } } } +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillHashTableForCCtx(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hBits = cParams->hashLog; + U32 const mls = cParams->minMatch; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Currently, we always use ZSTD_dtlm_fast for filling CCtx tables. + * Feel free to remove this assert if there's a good reason! */ + assert(dtlm == ZSTD_dtlm_fast); + + /* Always insert every fastHashFillStep position into the hash table. + * Insert the other positions if their hash entry is empty. + */ + for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + size_t const hash0 = ZSTD_hashPtr(ip, hBits, mls); + hashTable[hash0] = curr; + if (dtlm == ZSTD_dtlm_fast) continue; + /* Only load extra positions for ZSTD_dtlm_full */ + { U32 p; + for (p = 1; p < fastHashFillStep; ++p) { + size_t const hash = ZSTD_hashPtr(ip + p, hBits, mls); + if (hashTable[hash] == 0) { /* not yet filled */ + hashTable[hash] = curr + p; + } } } } +} + +void ZSTD_fillHashTable(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp) +{ + if (tfp == ZSTD_tfp_forCDict) { + ZSTD_fillHashTableForCDict(ms, end, dtlm); + } else { + ZSTD_fillHashTableForCCtx(ms, end, dtlm); + } +} + + +typedef int (*ZSTD_match4Found) (const BYTE* currentPtr, const BYTE* matchAddress, U32 matchIdx, U32 idxLowLimit); + +static int +ZSTD_match4Found_cmov(const BYTE* currentPtr, const BYTE* matchAddress, U32 matchIdx, U32 idxLowLimit) +{ + /* Array of ~random data, should have low probability of matching data. + * Load from here if the index is invalid. + * Used to avoid unpredictable branches. */ + static const BYTE dummy[] = {0x12,0x34,0x56,0x78}; + + /* currentIdx >= lowLimit is a (somewhat) unpredictable branch. + * However expression below compiles into conditional move. + */ + const BYTE* mvalAddr = ZSTD_selectAddr(matchIdx, idxLowLimit, matchAddress, dummy); + /* Note: this used to be written as : return test1 && test2; + * Unfortunately, once inlined, these tests become branches, + * in which case it becomes critical that they are executed in the right order (test1 then test2). + * So we have to write these tests in a specific manner to ensure their ordering. + */ + if (MEM_read32(currentPtr) != MEM_read32(mvalAddr)) return 0; + /* force ordering of these tests, which matters once the function is inlined, as they become branches */ +#if defined(__GNUC__) + __asm__(""); +#endif + return matchIdx >= idxLowLimit; +} + +static int +ZSTD_match4Found_branch(const BYTE* currentPtr, const BYTE* matchAddress, U32 matchIdx, U32 idxLowLimit) +{ + /* using a branch instead of a cmov, + * because it's faster in scenarios where matchIdx >= idxLowLimit is generally true, + * aka almost all candidates are within range */ + U32 mval; + if (matchIdx >= idxLowLimit) { + mval = MEM_read32(matchAddress); + } else { + mval = MEM_read32(currentPtr) ^ 1; /* guaranteed to not match. */ + } + + return (MEM_read32(currentPtr) == mval); +} + + +/** + * If you squint hard enough (and ignore repcodes), the search operation at any + * given position is broken into 4 stages: + * + * 1. Hash (map position to hash value via input read) + * 2. Lookup (map hash val to index via hashtable read) + * 3. Load (map index to value at that position via input read) + * 4. Compare + * + * Each of these steps involves a memory read at an address which is computed + * from the previous step. This means these steps must be sequenced and their + * latencies are cumulative. + * + * Rather than do 1->2->3->4 sequentially for a single position before moving + * onto the next, this implementation interleaves these operations across the + * next few positions: + * + * R = Repcode Read & Compare + * H = Hash + * T = Table Lookup + * M = Match Read & Compare + * + * Pos | Time --> + * ----+------------------- + * N | ... M + * N+1 | ... TM + * N+2 | R H T M + * N+3 | H TM + * N+4 | R H T M + * N+5 | H ... + * N+6 | R ... + * + * This is very much analogous to the pipelining of execution in a CPU. And just + * like a CPU, we have to dump the pipeline when we find a match (i.e., take a + * branch). + * + * When this happens, we throw away our current state, and do the following prep + * to re-enter the loop: + * + * Pos | Time --> + * ----+------------------- + * N | H T + * N+1 | H + * + * This is also the work we do at the beginning to enter the loop initially. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_noDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls, int useCmov) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hlog = cParams->hashLog; + size_t const stepSize = cParams->targetLength + !(cParams->targetLength) + 1; /* min 2 */ + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + const U32 prefixStartIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + + const BYTE* anchor = istart; + const BYTE* ip0 = istart; + const BYTE* ip1; + const BYTE* ip2; + const BYTE* ip3; + U32 current0; + + U32 rep_offset1 = rep[0]; + U32 rep_offset2 = rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + size_t hash0; /* hash for ip0 */ + size_t hash1; /* hash for ip1 */ + U32 matchIdx; /* match idx for ip0 */ + + U32 offcode; + const BYTE* match0; + size_t mLength; + + /* ip0 and ip1 are always adjacent. The targetLength skipping and + * uncompressibility acceleration is applied to every other position, + * matching the behavior of #1562. step therefore represents the gap + * between pairs of positions, from ip0 to ip2 or ip1 to ip3. */ + size_t step; + const BYTE* nextStep; + const size_t kStepIncr = (1 << (kSearchStrength - 1)); + const ZSTD_match4Found matchFound = useCmov ? ZSTD_match4Found_cmov : ZSTD_match4Found_branch; + + DEBUGLOG(5, "ZSTD_compressBlock_fast_generic"); + ip0 += (ip0 == prefixStart); + { U32 const curr = (U32)(ip0 - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); + U32 const maxRep = curr - windowLow; + if (rep_offset2 > maxRep) offsetSaved2 = rep_offset2, rep_offset2 = 0; + if (rep_offset1 > maxRep) offsetSaved1 = rep_offset1, rep_offset1 = 0; + } + + /* start each op */ +_start: /* Requires: ip0 */ + + step = stepSize; + nextStep = ip0 + kStepIncr; + + /* calculate positions, ip0 - anchor == 0, so we skip step calc */ + ip1 = ip0 + 1; + ip2 = ip0 + step; + ip3 = ip2 + 1; + + if (ip3 >= ilimit) { + goto _cleanup; + } + + hash0 = ZSTD_hashPtr(ip0, hlog, mls); + hash1 = ZSTD_hashPtr(ip1, hlog, mls); + + matchIdx = hashTable[hash0]; + + do { + /* load repcode match for ip[2]*/ + const U32 rval = MEM_read32(ip2 - rep_offset1); + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + /* check repcode at ip[2] */ + if ((MEM_read32(ip2) == rval) & (rep_offset1 > 0)) { + ip0 = ip2; + match0 = ip0 - rep_offset1; + mLength = ip0[-1] == match0[-1]; + ip0 -= mLength; + match0 -= mLength; + offcode = REPCODE1_TO_OFFBASE; + mLength += 4; + + /* Write next hash table entry: it's already calculated. + * This write is known to be safe because ip1 is before the + * repcode (ip2). */ + hashTable[hash1] = (U32)(ip1 - base); + + goto _match; + } + + if (matchFound(ip0, base + matchIdx, matchIdx, prefixStartIndex)) { + /* Write next hash table entry (it's already calculated). + * This write is known to be safe because the ip1 == ip0 + 1, + * so searching will resume after ip1 */ + hashTable[hash1] = (U32)(ip1 - base); + + goto _offset; + } + + /* lookup ip[1] */ + matchIdx = hashTable[hash1]; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip3; + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + if (matchFound(ip0, base + matchIdx, matchIdx, prefixStartIndex)) { + /* Write next hash table entry, since it's already calculated */ + if (step <= 4) { + /* Avoid writing an index if it's >= position where search will resume. + * The minimum possible match has length 4, so search can resume at ip0 + 4. + */ + hashTable[hash1] = (U32)(ip1 - base); + } + goto _offset; + } + + /* lookup ip[1] */ + matchIdx = hashTable[hash1]; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip0 + step; + ip3 = ip1 + step; + + /* calculate step */ + if (ip2 >= nextStep) { + step++; + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + nextStep += kStepIncr; + } + } while (ip3 < ilimit); + +_cleanup: + /* Note that there are probably still a couple positions one could search. + * However, it seems to be a meaningful performance hit to try to search + * them. So let's not. */ + + /* When the repcodes are outside of the prefix, we set them to zero before the loop. + * When the offsets are still zero, we need to restore them after the block to have a correct + * repcode history. If only one offset was invalid, it is easy. The tricky case is when both + * offsets were invalid. We need to figure out which offset to refill with. + * - If both offsets are zero they are in the same order. + * - If both offsets are non-zero, we won't restore the offsets from `offsetSaved[12]`. + * - If only one is zero, we need to decide which offset to restore. + * - If rep_offset1 is non-zero, then rep_offset2 must be offsetSaved1. + * - It is impossible for rep_offset2 to be non-zero. + * + * So if rep_offset1 started invalid (offsetSaved1 != 0) and became valid (rep_offset1 != 0), then + * set rep[0] = rep_offset1 and rep[1] = offsetSaved1. + */ + offsetSaved2 = ((offsetSaved1 != 0) && (rep_offset1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = rep_offset1 ? rep_offset1 : offsetSaved1; + rep[1] = rep_offset2 ? rep_offset2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_offset: /* Requires: ip0, idx */ + + /* Compute the offset code. */ + match0 = base + matchIdx; + rep_offset2 = rep_offset1; + rep_offset1 = (U32)(ip0-match0); + offcode = OFFSET_TO_OFFBASE(rep_offset1); + mLength = 4; + + /* Count the backwards match length. */ + while (((ip0>anchor) & (match0>prefixStart)) && (ip0[-1] == match0[-1])) { + ip0--; + match0--; + mLength++; + } + +_match: /* Requires: ip0, match0, offcode */ + + /* Count the forward length. */ + mLength += ZSTD_count(ip0 + mLength, match0 + mLength, iend); + + ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength); + + ip0 += mLength; + anchor = ip0; + + /* Fill table and check for immediate repcode. */ + if (ip0 <= ilimit) { + /* Fill Table */ + assert(base+current0+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); + + if (rep_offset2 > 0) { /* rep_offset2==0 means rep_offset2 is invalidated */ + while ( (ip0 <= ilimit) && (MEM_read32(ip0) == MEM_read32(ip0 - rep_offset2)) ) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip0+4, ip0+4-rep_offset2, iend) + 4; + { U32 const tmpOff = rep_offset2; rep_offset2 = rep_offset1; rep_offset1 = tmpOff; } /* swap rep_offset2 <=> rep_offset1 */ + hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base); + ip0 += rLength; + ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, REPCODE1_TO_OFFBASE, rLength); + anchor = ip0; + continue; /* faster when present (confirmed on gcc-8) ... (?) */ + } } } + + goto _start; +} + +#define ZSTD_GEN_FAST_FN(dictMode, mml, cmov) \ + static size_t ZSTD_compressBlock_fast_##dictMode##_##mml##_##cmov( \ + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \ + void const* src, size_t srcSize) \ + { \ + return ZSTD_compressBlock_fast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mml, cmov); \ + } + +ZSTD_GEN_FAST_FN(noDict, 4, 1) +ZSTD_GEN_FAST_FN(noDict, 5, 1) +ZSTD_GEN_FAST_FN(noDict, 6, 1) +ZSTD_GEN_FAST_FN(noDict, 7, 1) + +ZSTD_GEN_FAST_FN(noDict, 4, 0) +ZSTD_GEN_FAST_FN(noDict, 5, 0) +ZSTD_GEN_FAST_FN(noDict, 6, 0) +ZSTD_GEN_FAST_FN(noDict, 7, 0) + +size_t ZSTD_compressBlock_fast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mml = ms->cParams.minMatch; + /* use cmov when "candidate in range" branch is likely unpredictable */ + int const useCmov = ms->cParams.windowLog < 19; + assert(ms->dictMatchState == NULL); + if (useCmov) { + switch(mml) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_noDict_4_1(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_noDict_5_1(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_noDict_6_1(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_noDict_7_1(ms, seqStore, rep, src, srcSize); + } + } else { + /* use a branch instead */ + switch(mml) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_noDict_4_0(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_noDict_5_0(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_noDict_6_0(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_noDict_7_0(ms, seqStore, rep, src, srcSize); + } + } +} + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_dictMatchState_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, U32 const mls, U32 const hasStep) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hlog = cParams->hashLog; + /* support stepSize of 0 */ + U32 const stepSize = cParams->targetLength + !(cParams->targetLength); + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip0 = istart; + const BYTE* ip1 = ip0 + stepSize; /* we assert below that stepSize >= 1 */ + const BYTE* anchor = istart; + const U32 prefixStartIndex = ms->window.dictLimit; + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + U32 offset_1=rep[0], offset_2=rep[1]; + + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const ZSTD_compressionParameters* const dictCParams = &dms->cParams ; + const U32* const dictHashTable = dms->hashTable; + const U32 dictStartIndex = dms->window.dictLimit; + const BYTE* const dictBase = dms->window.base; + const BYTE* const dictStart = dictBase + dictStartIndex; + const BYTE* const dictEnd = dms->window.nextSrc; + const U32 dictIndexDelta = prefixStartIndex - (U32)(dictEnd - dictBase); + const U32 dictAndPrefixLength = (U32)(istart - prefixStart + dictEnd - dictStart); + const U32 dictHBits = dictCParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + + /* if a dictionary is still attached, it necessarily means that + * it is within window size. So we just check it. */ + const U32 maxDistance = 1U << cParams->windowLog; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + assert(endIndex - prefixStartIndex <= maxDistance); + (void)maxDistance; (void)endIndex; /* these variables are not used when assert() is disabled */ + + (void)hasStep; /* not currently specialized on whether it's accelerated */ + + /* ensure there will be no underflow + * when translating a dict index into a local index */ + assert(prefixStartIndex >= (U32)(dictEnd - dictBase)); + + if (ms->prefetchCDictTables) { + size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32); + PREFETCH_AREA(dictHashTable, hashTableBytes); + } + + /* init */ + DEBUGLOG(5, "ZSTD_compressBlock_fast_dictMatchState_generic"); + ip0 += (dictAndPrefixLength == 0); + /* dictMatchState repCode checks don't currently handle repCode == 0 + * disabling. */ + assert(offset_1 <= dictAndPrefixLength); + assert(offset_2 <= dictAndPrefixLength); + + /* Outer search loop */ + assert(stepSize >= 1); + while (ip1 <= ilimit) { /* repcode check at (ip0 + 1) is safe because ip0 < ip1 */ + size_t mLength; + size_t hash0 = ZSTD_hashPtr(ip0, hlog, mls); + + size_t const dictHashAndTag0 = ZSTD_hashPtr(ip0, dictHBits, mls); + U32 dictMatchIndexAndTag = dictHashTable[dictHashAndTag0 >> ZSTD_SHORT_CACHE_TAG_BITS]; + int dictTagsMatch = ZSTD_comparePackedTags(dictMatchIndexAndTag, dictHashAndTag0); + + U32 matchIndex = hashTable[hash0]; + U32 curr = (U32)(ip0 - base); + size_t step = stepSize; + const size_t kStepIncr = 1 << kSearchStrength; + const BYTE* nextStep = ip0 + kStepIncr; + + /* Inner search loop */ + while (1) { + const BYTE* match = base + matchIndex; + const U32 repIndex = curr + 1 - offset_1; + const BYTE* repMatch = (repIndex < prefixStartIndex) ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + const size_t hash1 = ZSTD_hashPtr(ip1, hlog, mls); + size_t const dictHashAndTag1 = ZSTD_hashPtr(ip1, dictHBits, mls); + hashTable[hash0] = curr; /* update hash table */ + + if ((ZSTD_index_overlap_check(prefixStartIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip0 + 1))) { + const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip0 + 1 + 4, repMatch + 4, iend, repMatchEnd, prefixStart) + 4; + ip0++; + ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + break; + } + + if (dictTagsMatch) { + /* Found a possible dict match */ + const U32 dictMatchIndex = dictMatchIndexAndTag >> ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* dictMatch = dictBase + dictMatchIndex; + if (dictMatchIndex > dictStartIndex && + MEM_read32(dictMatch) == MEM_read32(ip0)) { + /* To replicate extDict parse behavior, we only use dict matches when the normal matchIndex is invalid */ + if (matchIndex <= prefixStartIndex) { + U32 const offset = (U32) (curr - dictMatchIndex - dictIndexDelta); + mLength = ZSTD_count_2segments(ip0 + 4, dictMatch + 4, iend, dictEnd, prefixStart) + 4; + while (((ip0 > anchor) & (dictMatch > dictStart)) + && (ip0[-1] == dictMatch[-1])) { + ip0--; + dictMatch--; + mLength++; + } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + break; + } + } + } + + if (ZSTD_match4Found_cmov(ip0, match, matchIndex, prefixStartIndex)) { + /* found a regular match of size >= 4 */ + U32 const offset = (U32) (ip0 - match); + mLength = ZSTD_count(ip0 + 4, match + 4, iend) + 4; + while (((ip0 > anchor) & (match > prefixStart)) + && (ip0[-1] == match[-1])) { + ip0--; + match--; + mLength++; + } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + break; + } + + /* Prepare for next iteration */ + dictMatchIndexAndTag = dictHashTable[dictHashAndTag1 >> ZSTD_SHORT_CACHE_TAG_BITS]; + dictTagsMatch = ZSTD_comparePackedTags(dictMatchIndexAndTag, dictHashAndTag1); + matchIndex = hashTable[hash1]; + + if (ip1 >= nextStep) { + step++; + nextStep += kStepIncr; + } + ip0 = ip1; + ip1 = ip1 + step; + if (ip1 > ilimit) goto _cleanup; + + curr = (U32)(ip0 - base); + hash0 = hash1; + } /* end inner search loop */ + + /* match found */ + assert(mLength); + ip0 += mLength; + anchor = ip0; + + if (ip0 <= ilimit) { + /* Fill Table */ + assert(base+curr+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2; /* here because curr+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); + + /* check immediate repcode */ + while (ip0 <= ilimit) { + U32 const current2 = (U32)(ip0-base); + U32 const repIndex2 = current2 - offset_2; + const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? + dictBase - dictIndexDelta + repIndex2 : + base + repIndex2; + if ( (ZSTD_index_overlap_check(prefixStartIndex, repIndex2)) + && (MEM_read32(repMatch2) == MEM_read32(ip0))) { + const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip0+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; + U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = current2; + ip0 += repLength2; + anchor = ip0; + continue; + } + break; + } + } + + /* Prepare for next iteration */ + assert(ip0 == anchor); + ip1 = ip0 + stepSize; + } + +_cleanup: + /* save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} + + +ZSTD_GEN_FAST_FN(dictMatchState, 4, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 5, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 6, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 7, 0) + +size_t ZSTD_compressBlock_fast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mls = ms->cParams.minMatch; + assert(ms->dictMatchState != NULL); + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_dictMatchState_4_0(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_dictMatchState_5_0(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_dictMatchState_6_0(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_dictMatchState_7_0(ms, seqStore, rep, src, srcSize); + } +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_extDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, U32 const mls, U32 const hasStep) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hlog = cParams->hashLog; + /* support stepSize of 0 */ + size_t const stepSize = cParams->targetLength + !(cParams->targetLength) + 1; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const BYTE* const istart = (const BYTE*)src; + const BYTE* anchor = istart; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog); + const U32 dictStartIndex = lowLimit; + const BYTE* const dictStart = dictBase + dictStartIndex; + const U32 dictLimit = ms->window.dictLimit; + const U32 prefixStartIndex = dictLimit < lowLimit ? lowLimit : dictLimit; + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const dictEnd = dictBase + prefixStartIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + U32 offset_1=rep[0], offset_2=rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + const BYTE* ip0 = istart; + const BYTE* ip1; + const BYTE* ip2; + const BYTE* ip3; + U32 current0; + + + size_t hash0; /* hash for ip0 */ + size_t hash1; /* hash for ip1 */ + U32 idx; /* match idx for ip0 */ + const BYTE* idxBase; /* base pointer for idx */ + + U32 offcode; + const BYTE* match0; + size_t mLength; + const BYTE* matchEnd = 0; /* initialize to avoid warning, assert != 0 later */ + + size_t step; + const BYTE* nextStep; + const size_t kStepIncr = (1 << (kSearchStrength - 1)); + + (void)hasStep; /* not currently specialized on whether it's accelerated */ + + DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic (offset_1=%u)", offset_1); + + /* switch to "regular" variant if extDict is invalidated due to maxDistance */ + if (prefixStartIndex == dictStartIndex) + return ZSTD_compressBlock_fast(ms, seqStore, rep, src, srcSize); + + { U32 const curr = (U32)(ip0 - base); + U32 const maxRep = curr - dictStartIndex; + if (offset_2 >= maxRep) offsetSaved2 = offset_2, offset_2 = 0; + if (offset_1 >= maxRep) offsetSaved1 = offset_1, offset_1 = 0; + } + + /* start each op */ +_start: /* Requires: ip0 */ + + step = stepSize; + nextStep = ip0 + kStepIncr; + + /* calculate positions, ip0 - anchor == 0, so we skip step calc */ + ip1 = ip0 + 1; + ip2 = ip0 + step; + ip3 = ip2 + 1; + + if (ip3 >= ilimit) { + goto _cleanup; + } + + hash0 = ZSTD_hashPtr(ip0, hlog, mls); + hash1 = ZSTD_hashPtr(ip1, hlog, mls); + + idx = hashTable[hash0]; + idxBase = idx < prefixStartIndex ? dictBase : base; + + do { + { /* load repcode match for ip[2] */ + U32 const current2 = (U32)(ip2 - base); + U32 const repIndex = current2 - offset_1; + const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base; + U32 rval; + if ( ((U32)(prefixStartIndex - repIndex) >= 4) /* intentional underflow */ + & (offset_1 > 0) ) { + rval = MEM_read32(repBase + repIndex); + } else { + rval = MEM_read32(ip2) ^ 1; /* guaranteed to not match. */ + } + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + /* check repcode at ip[2] */ + if (MEM_read32(ip2) == rval) { + ip0 = ip2; + match0 = repBase + repIndex; + matchEnd = repIndex < prefixStartIndex ? dictEnd : iend; + assert((match0 != prefixStart) & (match0 != dictStart)); + mLength = ip0[-1] == match0[-1]; + ip0 -= mLength; + match0 -= mLength; + offcode = REPCODE1_TO_OFFBASE; + mLength += 4; + goto _match; + } } + + { /* load match for ip[0] */ + U32 const mval = idx >= dictStartIndex ? + MEM_read32(idxBase + idx) : + MEM_read32(ip0) ^ 1; /* guaranteed not to match */ + + /* check match at ip[0] */ + if (MEM_read32(ip0) == mval) { + /* found a match! */ + goto _offset; + } } + + /* lookup ip[1] */ + idx = hashTable[hash1]; + idxBase = idx < prefixStartIndex ? dictBase : base; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip3; + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + { /* load match for ip[0] */ + U32 const mval = idx >= dictStartIndex ? + MEM_read32(idxBase + idx) : + MEM_read32(ip0) ^ 1; /* guaranteed not to match */ + + /* check match at ip[0] */ + if (MEM_read32(ip0) == mval) { + /* found a match! */ + goto _offset; + } } + + /* lookup ip[1] */ + idx = hashTable[hash1]; + idxBase = idx < prefixStartIndex ? dictBase : base; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip0 + step; + ip3 = ip1 + step; + + /* calculate step */ + if (ip2 >= nextStep) { + step++; + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + nextStep += kStepIncr; + } + } while (ip3 < ilimit); + +_cleanup: + /* Note that there are probably still a couple positions we could search. + * However, it seems to be a meaningful performance hit to try to search + * them. So let's not. */ + + /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0), + * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */ + offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved1; + rep[1] = offset_2 ? offset_2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_offset: /* Requires: ip0, idx, idxBase */ + + /* Compute the offset code. */ + { U32 const offset = current0 - idx; + const BYTE* const lowMatchPtr = idx < prefixStartIndex ? dictStart : prefixStart; + matchEnd = idx < prefixStartIndex ? dictEnd : iend; + match0 = idxBase + idx; + offset_2 = offset_1; + offset_1 = offset; + offcode = OFFSET_TO_OFFBASE(offset); + mLength = 4; + + /* Count the backwards match length. */ + while (((ip0>anchor) & (match0>lowMatchPtr)) && (ip0[-1] == match0[-1])) { + ip0--; + match0--; + mLength++; + } } + +_match: /* Requires: ip0, match0, offcode, matchEnd */ + + /* Count the forward length. */ + assert(matchEnd != 0); + mLength += ZSTD_count_2segments(ip0 + mLength, match0 + mLength, iend, matchEnd, prefixStart); + + ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength); + + ip0 += mLength; + anchor = ip0; + + /* write next hash table entry */ + if (ip1 < ip0) { + hashTable[hash1] = (U32)(ip1 - base); + } + + /* Fill table and check for immediate repcode. */ + if (ip0 <= ilimit) { + /* Fill Table */ + assert(base+current0+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); + + while (ip0 <= ilimit) { + U32 const repIndex2 = (U32)(ip0-base) - offset_2; + const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2; + if ( ((ZSTD_index_overlap_check(prefixStartIndex, repIndex2)) & (offset_2 > 0)) + && (MEM_read32(repMatch2) == MEM_read32(ip0)) ) { + const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip0+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; + { U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; } /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0 /*litlen*/, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base); + ip0 += repLength2; + anchor = ip0; + continue; + } + break; + } } + + goto _start; +} + +ZSTD_GEN_FAST_FN(extDict, 4, 0) +ZSTD_GEN_FAST_FN(extDict, 5, 0) +ZSTD_GEN_FAST_FN(extDict, 6, 0) +ZSTD_GEN_FAST_FN(extDict, 7, 0) + +size_t ZSTD_compressBlock_fast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mls = ms->cParams.minMatch; + assert(ms->dictMatchState == NULL); + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_extDict_4_0(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_extDict_5_0(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_extDict_6_0(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_extDict_7_0(ms, seqStore, rep, src, srcSize); + } +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_fast.h b/src/commonlib/bsd/zstd/compress/zstd_fast.h new file mode 100644 index 0000000000..4ba4217f87 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_fast.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_FAST_H +#define ZSTD_FAST_H + +#include "../common/mem.h" /* U32 */ +#include "zstd_compress_internal.h" + +void ZSTD_fillHashTable(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp); +size_t ZSTD_compressBlock_fast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_fast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_fast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#endif /* ZSTD_FAST_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_lazy.c b/src/commonlib/bsd/zstd/compress/zstd_lazy.c new file mode 100644 index 0000000000..ef1f2fe015 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_lazy.c @@ -0,0 +1,2201 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" +#include "zstd_lazy.h" +#include "../common/zstd_bits.h" /* ZSTD_countTrailingZeros64 */ + +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) + +#define kLazySkippingStep 8 + + +/*-************************************* +* Binary Tree search +***************************************/ + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_updateDUBT(ZSTD_MatchState_t* ms, + const BYTE* ip, const BYTE* iend, + U32 mls) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hashLog = cParams->hashLog; + + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + + const BYTE* const base = ms->window.base; + U32 const target = (U32)(ip - base); + U32 idx = ms->nextToUpdate; + + if (idx != target) + DEBUGLOG(7, "ZSTD_updateDUBT, from %u to %u (dictLimit:%u)", + idx, target, ms->window.dictLimit); + assert(ip + 8 <= iend); /* condition for ZSTD_hashPtr */ + (void)iend; + + assert(idx >= ms->window.dictLimit); /* condition for valid base+idx */ + for ( ; idx < target ; idx++) { + size_t const h = ZSTD_hashPtr(base + idx, hashLog, mls); /* assumption : ip + 8 <= iend */ + U32 const matchIndex = hashTable[h]; + + U32* const nextCandidatePtr = bt + 2*(idx&btMask); + U32* const sortMarkPtr = nextCandidatePtr + 1; + + DEBUGLOG(8, "ZSTD_updateDUBT: insert %u", idx); + hashTable[h] = idx; /* Update Hash Table */ + *nextCandidatePtr = matchIndex; /* update BT like a chain */ + *sortMarkPtr = ZSTD_DUBT_UNSORTED_MARK; + } + ms->nextToUpdate = target; +} + + +/** ZSTD_insertDUBT1() : + * sort one already inserted but unsorted position + * assumption : curr >= btlow == (curr - btmask) + * doesn't fail */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_insertDUBT1(const ZSTD_MatchState_t* ms, + U32 curr, const BYTE* inputEnd, + U32 nbCompares, U32 btLow, + const ZSTD_dictMode_e dictMode) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + size_t commonLengthSmaller=0, commonLengthLarger=0; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const ip = (curr>=dictLimit) ? base + curr : dictBase + curr; + const BYTE* const iend = (curr>=dictLimit) ? inputEnd : dictBase + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* match; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = smallerPtr + 1; + U32 matchIndex = *smallerPtr; /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */ + U32 dummy32; /* to be nullified at the end */ + U32 const windowValid = ms->window.lowLimit; + U32 const maxDistance = 1U << cParams->windowLog; + U32 const windowLow = (curr - windowValid > maxDistance) ? curr - maxDistance : windowValid; + + + DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)", + curr, dictLimit, windowLow); + assert(curr >= btLow); + assert(ip < iend); /* condition for ZSTD_count */ + + for (; nbCompares && (matchIndex > windowLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + assert(matchIndex < curr); + /* note : all candidates are now supposed sorted, + * but it's still possible to have nextPtr[1] == ZSTD_DUBT_UNSORTED_MARK + * when a real index has the same value as ZSTD_DUBT_UNSORTED_MARK */ + + if ( (dictMode != ZSTD_extDict) + || (matchIndex+matchLength >= dictLimit) /* both in current segment*/ + || (curr < dictLimit) /* both in extDict */) { + const BYTE* const mBase = ( (dictMode != ZSTD_extDict) + || (matchIndex+matchLength >= dictLimit)) ? + base : dictBase; + assert( (matchIndex+matchLength >= dictLimit) /* might be wrong if extDict is incorrectly set to 0 */ + || (curr < dictLimit) ); + match = mBase + matchIndex; + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* preparation for next read of match[matchLength] */ + } + + DEBUGLOG(8, "ZSTD_insertDUBT1: comparing %u with %u : found %u common bytes ", + curr, matchIndex, (U32)matchLength); + + if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ + break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */ + } + + if (match[matchLength] < ip[matchLength]) { /* necessarily within buffer */ + /* match is smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + DEBUGLOG(8, "ZSTD_insertDUBT1: %u (>btLow=%u) is smaller : next => %u", + matchIndex, btLow, nextPtr[1]); + smallerPtr = nextPtr+1; /* new "candidate" => larger than match, which was smaller than target */ + matchIndex = nextPtr[1]; /* new matchIndex, larger than previous and closer to current */ + } else { + /* match is larger than current */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + DEBUGLOG(8, "ZSTD_insertDUBT1: %u (>btLow=%u) is larger => %u", + matchIndex, btLow, nextPtr[0]); + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_DUBT_findBetterDictMatch ( + const ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + size_t* offsetPtr, + size_t bestLength, + U32 nbCompares, + U32 const mls, + const ZSTD_dictMode_e dictMode) +{ + const ZSTD_MatchState_t * const dms = ms->dictMatchState; + const ZSTD_compressionParameters* const dmsCParams = &dms->cParams; + const U32 * const dictHashTable = dms->hashTable; + U32 const hashLog = dmsCParams->hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 dictMatchIndex = dictHashTable[h]; + + const BYTE* const base = ms->window.base; + const BYTE* const prefixStart = base + ms->window.dictLimit; + U32 const curr = (U32)(ip-base); + const BYTE* const dictBase = dms->window.base; + const BYTE* const dictEnd = dms->window.nextSrc; + U32 const dictHighLimit = (U32)(dms->window.nextSrc - dms->window.base); + U32 const dictLowLimit = dms->window.lowLimit; + U32 const dictIndexDelta = ms->window.lowLimit - dictHighLimit; + + U32* const dictBt = dms->chainTable; + U32 const btLog = dmsCParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 const btLow = (btMask >= dictHighLimit - dictLowLimit) ? dictLowLimit : dictHighLimit - btMask; + + size_t commonLengthSmaller=0, commonLengthLarger=0; + + (void)dictMode; + assert(dictMode == ZSTD_dictMatchState); + + for (; nbCompares && (dictMatchIndex > dictLowLimit); --nbCompares) { + U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE* match = dictBase + dictMatchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (dictMatchIndex+matchLength >= dictHighLimit) + match = base + dictMatchIndex + dictIndexDelta; /* to prepare for next usage of match[matchLength] */ + + if (matchLength > bestLength) { + U32 matchIndex = dictMatchIndex + dictIndexDelta; + if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) { + DEBUGLOG(9, "ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)", + curr, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, OFFSET_TO_OFFBASE(curr - matchIndex), dictMatchIndex, matchIndex); + bestLength = matchLength, *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex); + } + if (ip+matchLength == iend) { /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */ + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } + } + + if (match[matchLength] < ip[matchLength]) { + if (dictMatchIndex <= btLow) { break; } /* beyond tree size, stop the search */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + dictMatchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + } else { + /* match is larger than current */ + if (dictMatchIndex <= btLow) { break; } /* beyond tree size, stop the search */ + commonLengthLarger = matchLength; + dictMatchIndex = nextPtr[0]; + } + } + + if (bestLength >= MINMATCH) { + U32 const mIndex = curr - (U32)OFFBASE_TO_OFFSET(*offsetPtr); (void)mIndex; + DEBUGLOG(8, "ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)", + curr, (U32)bestLength, (U32)*offsetPtr, mIndex); + } + return bestLength; + +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_DUBT_findBestMatch(ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + size_t* offBasePtr, + U32 const mls, + const ZSTD_dictMode_e dictMode) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hashLog = cParams->hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 matchIndex = hashTable[h]; + + const BYTE* const base = ms->window.base; + U32 const curr = (U32)(ip-base); + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog); + + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 const btLow = (btMask >= curr) ? 0 : curr - btMask; + U32 const unsortLimit = MAX(btLow, windowLow); + + U32* nextCandidate = bt + 2*(matchIndex&btMask); + U32* unsortedMark = bt + 2*(matchIndex&btMask) + 1; + U32 nbCompares = 1U << cParams->searchLog; + U32 nbCandidates = nbCompares; + U32 previousCandidate = 0; + + DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", curr); + assert(ip <= iend-8); /* required for h calculation */ + assert(dictMode != ZSTD_dedicatedDictSearch); + + /* reach end of unsorted candidates list */ + while ( (matchIndex > unsortLimit) + && (*unsortedMark == ZSTD_DUBT_UNSORTED_MARK) + && (nbCandidates > 1) ) { + DEBUGLOG(8, "ZSTD_DUBT_findBestMatch: candidate %u is unsorted", + matchIndex); + *unsortedMark = previousCandidate; /* the unsortedMark becomes a reversed chain, to move up back to original position */ + previousCandidate = matchIndex; + matchIndex = *nextCandidate; + nextCandidate = bt + 2*(matchIndex&btMask); + unsortedMark = bt + 2*(matchIndex&btMask) + 1; + nbCandidates --; + } + + /* nullify last candidate if it's still unsorted + * simplification, detrimental to compression ratio, beneficial for speed */ + if ( (matchIndex > unsortLimit) + && (*unsortedMark==ZSTD_DUBT_UNSORTED_MARK) ) { + DEBUGLOG(7, "ZSTD_DUBT_findBestMatch: nullify last unsorted candidate %u", + matchIndex); + *nextCandidate = *unsortedMark = 0; + } + + /* batch sort stacked candidates */ + matchIndex = previousCandidate; + while (matchIndex) { /* will end on matchIndex == 0 */ + U32* const nextCandidateIdxPtr = bt + 2*(matchIndex&btMask) + 1; + U32 const nextCandidateIdx = *nextCandidateIdxPtr; + ZSTD_insertDUBT1(ms, matchIndex, iend, + nbCandidates, unsortLimit, dictMode); + matchIndex = nextCandidateIdx; + nbCandidates++; + } + + /* find longest match */ + { size_t commonLengthSmaller = 0, commonLengthLarger = 0; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = bt + 2*(curr&btMask) + 1; + U32 matchEndIdx = curr + 8 + 1; + U32 dummy32; /* to be nullified at the end */ + size_t bestLength = 0; + + matchIndex = hashTable[h]; + hashTable[h] = curr; /* Update Hash Table */ + + for (; nbCompares && (matchIndex > windowLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE* match; + + if ((dictMode != ZSTD_extDict) || (matchIndex+matchLength >= dictLimit)) { + match = base + matchIndex; + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + } + + if (matchLength > bestLength) { + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr - matchIndex + 1) - ZSTD_highbit32((U32)*offBasePtr)) ) + bestLength = matchLength, *offBasePtr = OFFSET_TO_OFFBASE(curr - matchIndex); + if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ + if (dictMode == ZSTD_dictMatchState) { + nbCompares = 0; /* in addition to avoiding checking any + * further in this loop, make sure we + * skip checking in the dictionary. */ + } + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } + } + + if (match[matchLength] < ip[matchLength]) { + /* match is smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + } else { + /* match is larger than current */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; + + assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dictMatchState && nbCompares) { + bestLength = ZSTD_DUBT_findBetterDictMatch( + ms, ip, iend, + offBasePtr, bestLength, nbCompares, + mls, dictMode); + } + + assert(matchEndIdx > curr+8); /* ensure nextToUpdate is increased */ + ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */ + if (bestLength >= MINMATCH) { + U32 const mIndex = curr - (U32)OFFBASE_TO_OFFSET(*offBasePtr); (void)mIndex; + DEBUGLOG(8, "ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)", + curr, (U32)bestLength, (U32)*offBasePtr, mIndex); + } + return bestLength; + } +} + + +/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_BtFindBestMatch( ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iLimit, + size_t* offBasePtr, + const U32 mls /* template */, + const ZSTD_dictMode_e dictMode) +{ + DEBUGLOG(7, "ZSTD_BtFindBestMatch"); + if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */ + ZSTD_updateDUBT(ms, ip, iLimit, mls); + return ZSTD_DUBT_findBestMatch(ms, ip, iLimit, offBasePtr, mls, dictMode); +} + +/*********************************** +* Dedicated dict search +***********************************/ + +void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_MatchState_t* ms, const BYTE* const ip) +{ + const BYTE* const base = ms->window.base; + U32 const target = (U32)(ip - base); + U32* const hashTable = ms->hashTable; + U32* const chainTable = ms->chainTable; + U32 const chainSize = 1 << ms->cParams.chainLog; + U32 idx = ms->nextToUpdate; + U32 const minChain = chainSize < target - idx ? target - chainSize : idx; + U32 const bucketSize = 1 << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 const cacheSize = bucketSize - 1; + U32 const chainAttempts = (1 << ms->cParams.searchLog) - cacheSize; + U32 const chainLimit = chainAttempts > 255 ? 255 : chainAttempts; + + /* We know the hashtable is oversized by a factor of `bucketSize`. + * We are going to temporarily pretend `bucketSize == 1`, keeping only a + * single entry. We will use the rest of the space to construct a temporary + * chaintable. + */ + U32 const hashLog = ms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG; + U32* const tmpHashTable = hashTable; + U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog); + U32 const tmpChainSize = (U32)((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog; + U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx; + U32 hashIdx; + + assert(ms->cParams.chainLog <= 24); + assert(ms->cParams.hashLog > ms->cParams.chainLog); + assert(idx != 0); + assert(tmpMinChain <= minChain); + + /* fill conventional hash table and conventional chain table */ + for ( ; idx < target; idx++) { + U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch); + if (idx >= tmpMinChain) { + tmpChainTable[idx - tmpMinChain] = hashTable[h]; + } + tmpHashTable[h] = idx; + } + + /* sort chains into ddss chain table */ + { + U32 chainPos = 0; + for (hashIdx = 0; hashIdx < (1U << hashLog); hashIdx++) { + U32 count; + U32 countBeyondMinChain = 0; + U32 i = tmpHashTable[hashIdx]; + for (count = 0; i >= tmpMinChain && count < cacheSize; count++) { + /* skip through the chain to the first position that won't be + * in the hash cache bucket */ + if (i < minChain) { + countBeyondMinChain++; + } + i = tmpChainTable[i - tmpMinChain]; + } + if (count == cacheSize) { + for (count = 0; count < chainLimit;) { + if (i < minChain) { + if (!i || ++countBeyondMinChain > cacheSize) { + /* only allow pulling `cacheSize` number of entries + * into the cache or chainTable beyond `minChain`, + * to replace the entries pulled out of the + * chainTable into the cache. This lets us reach + * back further without increasing the total number + * of entries in the chainTable, guaranteeing the + * DDSS chain table will fit into the space + * allocated for the regular one. */ + break; + } + } + chainTable[chainPos++] = i; + count++; + if (i < tmpMinChain) { + break; + } + i = tmpChainTable[i - tmpMinChain]; + } + } else { + count = 0; + } + if (count) { + tmpHashTable[hashIdx] = ((chainPos - count) << 8) + count; + } else { + tmpHashTable[hashIdx] = 0; + } + } + assert(chainPos <= chainSize); /* I believe this is guaranteed... */ + } + + /* move chain pointers into the last entry of each hash bucket */ + for (hashIdx = (1 << hashLog); hashIdx; ) { + U32 const bucketIdx = --hashIdx << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 const chainPackedPointer = tmpHashTable[hashIdx]; + U32 i; + for (i = 0; i < cacheSize; i++) { + hashTable[bucketIdx + i] = 0; + } + hashTable[bucketIdx + bucketSize - 1] = chainPackedPointer; + } + + /* fill the buckets of the hash table */ + for (idx = ms->nextToUpdate; idx < target; idx++) { + U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch) + << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 i; + /* Shift hash cache down 1. */ + for (i = cacheSize - 1; i; i--) + hashTable[h + i] = hashTable[h + i - 1]; + hashTable[h] = idx; + } + + ms->nextToUpdate = target; +} + +/* Returns the longest match length found in the dedicated dict search structure. + * If none are longer than the argument ml, then ml will be returned. + */ +FORCE_INLINE_TEMPLATE +size_t ZSTD_dedicatedDictSearch_lazy_search(size_t* offsetPtr, size_t ml, U32 nbAttempts, + const ZSTD_MatchState_t* const dms, + const BYTE* const ip, const BYTE* const iLimit, + const BYTE* const prefixStart, const U32 curr, + const U32 dictLimit, const size_t ddsIdx) { + const U32 ddsLowestIndex = dms->window.dictLimit; + const BYTE* const ddsBase = dms->window.base; + const BYTE* const ddsEnd = dms->window.nextSrc; + const U32 ddsSize = (U32)(ddsEnd - ddsBase); + const U32 ddsIndexDelta = dictLimit - ddsSize; + const U32 bucketSize = (1 << ZSTD_LAZY_DDSS_BUCKET_LOG); + const U32 bucketLimit = nbAttempts < bucketSize - 1 ? nbAttempts : bucketSize - 1; + U32 ddsAttempt; + U32 matchIndex; + + for (ddsAttempt = 0; ddsAttempt < bucketSize - 1; ddsAttempt++) { + PREFETCH_L1(ddsBase + dms->hashTable[ddsIdx + ddsAttempt]); + } + + { + U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1]; + U32 const chainIndex = chainPackedPointer >> 8; + + PREFETCH_L1(&dms->chainTable[chainIndex]); + } + + for (ddsAttempt = 0; ddsAttempt < bucketLimit; ddsAttempt++) { + size_t currentMl=0; + const BYTE* match; + matchIndex = dms->hashTable[ddsIdx + ddsAttempt]; + match = ddsBase + matchIndex; + + if (!matchIndex) { + return ml; + } + + /* guaranteed by table construction */ + (void)ddsLowestIndex; + assert(matchIndex >= ddsLowestIndex); + assert(match+4 <= ddsEnd); + if (MEM_read32(match) == MEM_read32(ip)) { + /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + ddsIndexDelta)); + if (ip+currentMl == iLimit) { + /* best possible, avoids read overflow on next attempt */ + return ml; + } + } + } + + { + U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1]; + U32 chainIndex = chainPackedPointer >> 8; + U32 const chainLength = chainPackedPointer & 0xFF; + U32 const chainAttempts = nbAttempts - ddsAttempt; + U32 const chainLimit = chainAttempts > chainLength ? chainLength : chainAttempts; + U32 chainAttempt; + + for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++) { + PREFETCH_L1(ddsBase + dms->chainTable[chainIndex + chainAttempt]); + } + + for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++, chainIndex++) { + size_t currentMl=0; + const BYTE* match; + matchIndex = dms->chainTable[chainIndex]; + match = ddsBase + matchIndex; + + /* guaranteed by table construction */ + assert(matchIndex >= ddsLowestIndex); + assert(match+4 <= ddsEnd); + if (MEM_read32(match) == MEM_read32(ip)) { + /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + ddsIndexDelta)); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + } + } + return ml; +} + + +/* ********************************* +* Hash Chain +***********************************/ +#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & (mask)] + +/* Update chains up to ip (excluded) + Assumption : always within prefix (i.e. not within extDict) */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertAndFindFirstIndex_internal( + ZSTD_MatchState_t* ms, + const ZSTD_compressionParameters* const cParams, + const BYTE* ip, U32 const mls, U32 const lazySkipping) +{ + U32* const hashTable = ms->hashTable; + const U32 hashLog = cParams->hashLog; + U32* const chainTable = ms->chainTable; + const U32 chainMask = (1 << cParams->chainLog) - 1; + const BYTE* const base = ms->window.base; + const U32 target = (U32)(ip - base); + U32 idx = ms->nextToUpdate; + + while(idx < target) { /* catch up */ + size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls); + NEXT_IN_CHAIN(idx, chainMask) = hashTable[h]; + hashTable[h] = idx; + idx++; + /* Stop inserting every position when in the lazy skipping mode. */ + if (lazySkipping) + break; + } + + ms->nextToUpdate = target; + return hashTable[ZSTD_hashPtr(ip, hashLog, mls)]; +} + +U32 ZSTD_insertAndFindFirstIndex(ZSTD_MatchState_t* ms, const BYTE* ip) { + const ZSTD_compressionParameters* const cParams = &ms->cParams; + return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch, /* lazySkipping*/ 0); +} + +/* inlining is important to hardwire a hot branch (template emulation) */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_HcFindBestMatch( + ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iLimit, + size_t* offsetPtr, + const U32 mls, const ZSTD_dictMode_e dictMode) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const chainTable = ms->chainTable; + const U32 chainSize = (1 << cParams->chainLog); + const U32 chainMask = chainSize-1; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const U32 curr = (U32)(ip-base); + const U32 maxDistance = 1U << cParams->windowLog; + const U32 lowestValid = ms->window.lowLimit; + const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + const U32 isDictionary = (ms->loadedDictEnd != 0); + const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance; + const U32 minChain = curr > chainSize ? curr - chainSize : 0; + U32 nbAttempts = 1U << cParams->searchLog; + size_t ml=4-1; + + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const U32 ddsHashLog = dictMode == ZSTD_dedicatedDictSearch + ? dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG : 0; + const size_t ddsIdx = dictMode == ZSTD_dedicatedDictSearch + ? ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG : 0; + + U32 matchIndex; + + if (dictMode == ZSTD_dedicatedDictSearch) { + const U32* entry = &dms->hashTable[ddsIdx]; + PREFETCH_L1(entry); + } + + /* HC4 match finder */ + matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls, ms->lazySkipping); + + for ( ; (matchIndex>=lowLimit) & (nbAttempts>0) ; nbAttempts--) { + size_t currentMl=0; + if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) { + const BYTE* const match = base + matchIndex; + assert(matchIndex >= dictLimit); /* ensures this is true if dictMode != ZSTD_extDict */ + /* read 4B starting from (match + ml + 1 - sizeof(U32)) */ + if (MEM_read32(match + ml - 3) == MEM_read32(ip + ml - 3)) /* potentially better */ + currentMl = ZSTD_count(ip, match, iLimit); + } else { + const BYTE* const match = dictBase + matchIndex; + assert(match+4 <= dictEnd); + if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + + if (matchIndex <= minChain) break; + matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); + } + + assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dedicatedDictSearch) { + ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts, dms, + ip, iLimit, prefixStart, curr, dictLimit, ddsIdx); + } else if (dictMode == ZSTD_dictMatchState) { + const U32* const dmsChainTable = dms->chainTable; + const U32 dmsChainSize = (1 << dms->cParams.chainLog); + const U32 dmsChainMask = dmsChainSize - 1; + const U32 dmsLowestIndex = dms->window.dictLimit; + const BYTE* const dmsBase = dms->window.base; + const BYTE* const dmsEnd = dms->window.nextSrc; + const U32 dmsSize = (U32)(dmsEnd - dmsBase); + const U32 dmsIndexDelta = dictLimit - dmsSize; + const U32 dmsMinChain = dmsSize > dmsChainSize ? dmsSize - dmsChainSize : 0; + + matchIndex = dms->hashTable[ZSTD_hashPtr(ip, dms->cParams.hashLog, mls)]; + + for ( ; (matchIndex>=dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) { + size_t currentMl=0; + const BYTE* const match = dmsBase + matchIndex; + assert(match+4 <= dmsEnd); + if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4; + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + assert(curr > matchIndex + dmsIndexDelta); + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + dmsIndexDelta)); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + + if (matchIndex <= dmsMinChain) break; + + matchIndex = dmsChainTable[matchIndex & dmsChainMask]; + } + } + + return ml; +} + +/* ********************************* +* (SIMD) Row-based matchfinder +***********************************/ +/* Constants for row-based hash */ +#define ZSTD_ROW_HASH_TAG_MASK ((1u << ZSTD_ROW_HASH_TAG_BITS) - 1) +#define ZSTD_ROW_HASH_MAX_ENTRIES 64 /* absolute maximum number of entries per row, for all configurations */ + +#define ZSTD_ROW_HASH_CACHE_MASK (ZSTD_ROW_HASH_CACHE_SIZE - 1) + +typedef U64 ZSTD_VecMask; /* Clarifies when we are interacting with a U64 representing a mask of matches */ + +/* ZSTD_VecMask_next(): + * Starting from the LSB, returns the idx of the next non-zero bit. + * Basically counting the nb of trailing zeroes. + */ +MEM_STATIC U32 ZSTD_VecMask_next(ZSTD_VecMask val) { + return ZSTD_countTrailingZeros64(val); +} + +/* ZSTD_row_nextIndex(): + * Returns the next index to insert at within a tagTable row, and updates the "head" + * value to reflect the update. Essentially cycles backwards from [1, {entries per row}) + */ +FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextIndex(BYTE* const tagRow, U32 const rowMask) { + U32 next = (*tagRow-1) & rowMask; + next += (next == 0) ? rowMask : 0; /* skip first position */ + *tagRow = (BYTE)next; + return next; +} + +/* ZSTD_isAligned(): + * Checks that a pointer is aligned to "align" bytes which must be a power of 2. + */ +MEM_STATIC int ZSTD_isAligned(void const* ptr, size_t align) { + assert((align & (align - 1)) == 0); + return (((size_t)ptr) & (align - 1)) == 0; +} + +/* ZSTD_row_prefetch(): + * Performs prefetching for the hashTable and tagTable at a given row. + */ +FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, BYTE const* tagTable, U32 const relRow, U32 const rowLog) { + PREFETCH_L1(hashTable + relRow); + if (rowLog >= 5) { + PREFETCH_L1(hashTable + relRow + 16); + /* Note: prefetching more of the hash table does not appear to be beneficial for 128-entry rows */ + } + PREFETCH_L1(tagTable + relRow); + if (rowLog == 6) { + PREFETCH_L1(tagTable + relRow + 32); + } + assert(rowLog == 4 || rowLog == 5 || rowLog == 6); + assert(ZSTD_isAligned(hashTable + relRow, 64)); /* prefetched hash row always 64-byte aligned */ + assert(ZSTD_isAligned(tagTable + relRow, (size_t)1 << rowLog)); /* prefetched tagRow sits on correct multiple of bytes (32,64,128) */ +} + +/* ZSTD_row_fillHashCache(): + * Fill up the hash cache starting at idx, prefetching up to ZSTD_ROW_HASH_CACHE_SIZE entries, + * but not beyond iLimit. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_fillHashCache(ZSTD_MatchState_t* ms, const BYTE* base, + U32 const rowLog, U32 const mls, + U32 idx, const BYTE* const iLimit) +{ + U32 const* const hashTable = ms->hashTable; + BYTE const* const tagTable = ms->tagTable; + U32 const hashLog = ms->rowHashLog; + U32 const maxElemsToPrefetch = (base + idx) > iLimit ? 0 : (U32)(iLimit - (base + idx) + 1); + U32 const lim = idx + MIN(ZSTD_ROW_HASH_CACHE_SIZE, maxElemsToPrefetch); + + for (; idx < lim; ++idx) { + U32 const hash = (U32)ZSTD_hashPtrSalted(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt); + U32 const row = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + ZSTD_row_prefetch(hashTable, tagTable, row, rowLog); + ms->hashCache[idx & ZSTD_ROW_HASH_CACHE_MASK] = hash; + } + + DEBUGLOG(6, "ZSTD_row_fillHashCache(): [%u %u %u %u %u %u %u %u]", ms->hashCache[0], ms->hashCache[1], + ms->hashCache[2], ms->hashCache[3], ms->hashCache[4], + ms->hashCache[5], ms->hashCache[6], ms->hashCache[7]); +} + +/* ZSTD_row_nextCachedHash(): + * Returns the hash of base + idx, and replaces the hash in the hash cache with the byte at + * base + idx + ZSTD_ROW_HASH_CACHE_SIZE. Also prefetches the appropriate rows from hashTable and tagTable. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_row_nextCachedHash(U32* cache, U32 const* hashTable, + BYTE const* tagTable, BYTE const* base, + U32 idx, U32 const hashLog, + U32 const rowLog, U32 const mls, + U64 const hashSalt) +{ + U32 const newHash = (U32)ZSTD_hashPtrSalted(base+idx+ZSTD_ROW_HASH_CACHE_SIZE, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, hashSalt); + U32 const row = (newHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + ZSTD_row_prefetch(hashTable, tagTable, row, rowLog); + { U32 const hash = cache[idx & ZSTD_ROW_HASH_CACHE_MASK]; + cache[idx & ZSTD_ROW_HASH_CACHE_MASK] = newHash; + return hash; + } +} + +/* ZSTD_row_update_internalImpl(): + * Updates the hash table with positions starting from updateStartIdx until updateEndIdx. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_update_internalImpl(ZSTD_MatchState_t* ms, + U32 updateStartIdx, U32 const updateEndIdx, + U32 const mls, U32 const rowLog, + U32 const rowMask, U32 const useCache) +{ + U32* const hashTable = ms->hashTable; + BYTE* const tagTable = ms->tagTable; + U32 const hashLog = ms->rowHashLog; + const BYTE* const base = ms->window.base; + + DEBUGLOG(6, "ZSTD_row_update_internalImpl(): updateStartIdx=%u, updateEndIdx=%u", updateStartIdx, updateEndIdx); + for (; updateStartIdx < updateEndIdx; ++updateStartIdx) { + U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, updateStartIdx, hashLog, rowLog, mls, ms->hashSalt) + : (U32)ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt); + U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + U32* const row = hashTable + relRow; + BYTE* tagRow = tagTable + relRow; + U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); + + assert(hash == ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt)); + tagRow[pos] = hash & ZSTD_ROW_HASH_TAG_MASK; + row[pos] = updateStartIdx; + } +} + +/* ZSTD_row_update_internal(): + * Inserts the byte at ip into the appropriate position in the hash table, and updates ms->nextToUpdate. + * Skips sections of long matches as is necessary. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_update_internal(ZSTD_MatchState_t* ms, const BYTE* ip, + U32 const mls, U32 const rowLog, + U32 const rowMask, U32 const useCache) +{ + U32 idx = ms->nextToUpdate; + const BYTE* const base = ms->window.base; + const U32 target = (U32)(ip - base); + const U32 kSkipThreshold = 384; + const U32 kMaxMatchStartPositionsToUpdate = 96; + const U32 kMaxMatchEndPositionsToUpdate = 32; + + if (useCache) { + /* Only skip positions when using hash cache, i.e. + * if we are loading a dict, don't skip anything. + * If we decide to skip, then we only update a set number + * of positions at the beginning and end of the match. + */ + if (UNLIKELY(target - idx > kSkipThreshold)) { + U32 const bound = idx + kMaxMatchStartPositionsToUpdate; + ZSTD_row_update_internalImpl(ms, idx, bound, mls, rowLog, rowMask, useCache); + idx = target - kMaxMatchEndPositionsToUpdate; + ZSTD_row_fillHashCache(ms, base, rowLog, mls, idx, ip+1); + } + } + assert(target >= idx); + ZSTD_row_update_internalImpl(ms, idx, target, mls, rowLog, rowMask, useCache); + ms->nextToUpdate = target; +} + +/* ZSTD_row_update(): + * External wrapper for ZSTD_row_update_internal(). Used for filling the hashtable during dictionary + * processing. + */ +void ZSTD_row_update(ZSTD_MatchState_t* const ms, const BYTE* ip) { + const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6); + const U32 rowMask = (1u << rowLog) - 1; + const U32 mls = MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */); + + DEBUGLOG(5, "ZSTD_row_update(), rowLog=%u", rowLog); + ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 0 /* don't use cache */); +} + +/* Returns the mask width of bits group of which will be set to 1. Given not all + * architectures have easy movemask instruction, this helps to iterate over + * groups of bits easier and faster. + */ +FORCE_INLINE_TEMPLATE U32 +ZSTD_row_matchMaskGroupWidth(const U32 rowEntries) +{ + assert((rowEntries == 16) || (rowEntries == 32) || rowEntries == 64); + assert(rowEntries <= ZSTD_ROW_HASH_MAX_ENTRIES); + (void)rowEntries; +#if defined(ZSTD_ARCH_ARM_NEON) + /* NEON path only works for little endian */ + if (!MEM_isLittleEndian()) { + return 1; + } + if (rowEntries == 16) { + return 4; + } + if (rowEntries == 32) { + return 2; + } + if (rowEntries == 64) { + return 1; + } +#endif + return 1; +} + +#if defined(ZSTD_ARCH_X86_SSE2) +FORCE_INLINE_TEMPLATE ZSTD_VecMask +ZSTD_row_getSSEMask(int nbChunks, const BYTE* const src, const BYTE tag, const U32 head) +{ + const __m128i comparisonMask = _mm_set1_epi8((char)tag); + int matches[4] = {0}; + int i; + assert(nbChunks == 1 || nbChunks == 2 || nbChunks == 4); + for (i=0; i> chunkSize; + do { + size_t chunk = MEM_readST(&src[i]); + chunk ^= splatChar; + chunk = (((chunk | x80) - x01) | chunk) & x80; + matches <<= chunkSize; + matches |= (chunk * extractMagic) >> shiftAmount; + i -= chunkSize; + } while (i >= 0); + } else { /* big endian: reverse bits during extraction */ + const size_t msb = xFF ^ (xFF >> 1); + const size_t extractMagic = (msb / 0x1FF) | msb; + do { + size_t chunk = MEM_readST(&src[i]); + chunk ^= splatChar; + chunk = (((chunk | x80) - x01) | chunk) & x80; + matches <<= chunkSize; + matches |= ((chunk >> 7) * extractMagic) >> shiftAmount; + i -= chunkSize; + } while (i >= 0); + } + matches = ~matches; + if (rowEntries == 16) { + return ZSTD_rotateRight_U16((U16)matches, headGrouped); + } else if (rowEntries == 32) { + return ZSTD_rotateRight_U32((U32)matches, headGrouped); + } else { + return ZSTD_rotateRight_U64((U64)matches, headGrouped); + } + } +#endif +} + +/* The high-level approach of the SIMD row based match finder is as follows: + * - Figure out where to insert the new entry: + * - Generate a hash for current input position and split it into a one byte of tag and `rowHashLog` bits of index. + * - The hash is salted by a value that changes on every context reset, so when the same table is used + * we will avoid collisions that would otherwise slow us down by introducing phantom matches. + * - The hashTable is effectively split into groups or "rows" of 15 or 31 entries of U32, and the index determines + * which row to insert into. + * - Determine the correct position within the row to insert the entry into. Each row of 15 or 31 can + * be considered as a circular buffer with a "head" index that resides in the tagTable (overall 16 or 32 bytes + * per row). + * - Use SIMD to efficiently compare the tags in the tagTable to the 1-byte tag calculated for the position and + * generate a bitfield that we can cycle through to check the collisions in the hash table. + * - Pick the longest match. + * - Insert the tag into the equivalent row and position in the tagTable. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_RowFindBestMatch( + ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iLimit, + size_t* offsetPtr, + const U32 mls, const ZSTD_dictMode_e dictMode, + const U32 rowLog) +{ + U32* const hashTable = ms->hashTable; + BYTE* const tagTable = ms->tagTable; + U32* const hashCache = ms->hashCache; + const U32 hashLog = ms->rowHashLog; + const ZSTD_compressionParameters* const cParams = &ms->cParams; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const U32 curr = (U32)(ip-base); + const U32 maxDistance = 1U << cParams->windowLog; + const U32 lowestValid = ms->window.lowLimit; + const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + const U32 isDictionary = (ms->loadedDictEnd != 0); + const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance; + const U32 rowEntries = (1U << rowLog); + const U32 rowMask = rowEntries - 1; + const U32 cappedSearchLog = MIN(cParams->searchLog, rowLog); /* nb of searches is capped at nb entries per row */ + const U32 groupWidth = ZSTD_row_matchMaskGroupWidth(rowEntries); + const U64 hashSalt = ms->hashSalt; + U32 nbAttempts = 1U << cappedSearchLog; + size_t ml=4-1; + U32 hash; + + /* DMS/DDS variables that may be referenced laster */ + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + + /* Initialize the following variables to satisfy static analyzer */ + size_t ddsIdx = 0; + U32 ddsExtraAttempts = 0; /* cctx hash tables are limited in searches, but allow extra searches into DDS */ + U32 dmsTag = 0; + U32* dmsRow = NULL; + BYTE* dmsTagRow = NULL; + + if (dictMode == ZSTD_dedicatedDictSearch) { + const U32 ddsHashLog = dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG; + { /* Prefetch DDS hashtable entry */ + ddsIdx = ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG; + PREFETCH_L1(&dms->hashTable[ddsIdx]); + } + ddsExtraAttempts = cParams->searchLog > rowLog ? 1U << (cParams->searchLog - rowLog) : 0; + } + + if (dictMode == ZSTD_dictMatchState) { + /* Prefetch DMS rows */ + U32* const dmsHashTable = dms->hashTable; + BYTE* const dmsTagTable = dms->tagTable; + U32 const dmsHash = (U32)ZSTD_hashPtr(ip, dms->rowHashLog + ZSTD_ROW_HASH_TAG_BITS, mls); + U32 const dmsRelRow = (dmsHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + dmsTag = dmsHash & ZSTD_ROW_HASH_TAG_MASK; + dmsTagRow = (BYTE*)(dmsTagTable + dmsRelRow); + dmsRow = dmsHashTable + dmsRelRow; + ZSTD_row_prefetch(dmsHashTable, dmsTagTable, dmsRelRow, rowLog); + } + + /* Update the hashTable and tagTable up to (but not including) ip */ + if (!ms->lazySkipping) { + ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 1 /* useCache */); + hash = ZSTD_row_nextCachedHash(hashCache, hashTable, tagTable, base, curr, hashLog, rowLog, mls, hashSalt); + } else { + /* Stop inserting every position when in the lazy skipping mode. + * The hash cache is also not kept up to date in this mode. + */ + hash = (U32)ZSTD_hashPtrSalted(ip, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, hashSalt); + ms->nextToUpdate = curr; + } + ms->hashSaltEntropy += hash; /* collect salt entropy */ + + { /* Get the hash for ip, compute the appropriate row */ + U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + U32 const tag = hash & ZSTD_ROW_HASH_TAG_MASK; + U32* const row = hashTable + relRow; + BYTE* tagRow = (BYTE*)(tagTable + relRow); + U32 const headGrouped = (*tagRow & rowMask) * groupWidth; + U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES]; + size_t numMatches = 0; + size_t currMatch = 0; + ZSTD_VecMask matches = ZSTD_row_getMatchMask(tagRow, (BYTE)tag, headGrouped, rowEntries); + + /* Cycle through the matches and prefetch */ + for (; (matches > 0) && (nbAttempts > 0); matches &= (matches - 1)) { + U32 const matchPos = ((headGrouped + ZSTD_VecMask_next(matches)) / groupWidth) & rowMask; + U32 const matchIndex = row[matchPos]; + if(matchPos == 0) continue; + assert(numMatches < rowEntries); + if (matchIndex < lowLimit) + break; + if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) { + PREFETCH_L1(base + matchIndex); + } else { + PREFETCH_L1(dictBase + matchIndex); + } + matchBuffer[numMatches++] = matchIndex; + --nbAttempts; + } + + /* Speed opt: insert current byte into hashtable too. This allows us to avoid one iteration of the loop + in ZSTD_row_update_internal() at the next search. */ + { + U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); + tagRow[pos] = (BYTE)tag; + row[pos] = ms->nextToUpdate++; + } + + /* Return the longest match */ + for (; currMatch < numMatches; ++currMatch) { + U32 const matchIndex = matchBuffer[currMatch]; + size_t currentMl=0; + assert(matchIndex < curr); + assert(matchIndex >= lowLimit); + + if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) { + const BYTE* const match = base + matchIndex; + assert(matchIndex >= dictLimit); /* ensures this is true if dictMode != ZSTD_extDict */ + /* read 4B starting from (match + ml + 1 - sizeof(U32)) */ + if (MEM_read32(match + ml - 3) == MEM_read32(ip + ml - 3)) /* potentially better */ + currentMl = ZSTD_count(ip, match, iLimit); + } else { + const BYTE* const match = dictBase + matchIndex; + assert(match+4 <= dictEnd); + if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4; + } + + /* Save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + } + } + + assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dedicatedDictSearch) { + ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts + ddsExtraAttempts, dms, + ip, iLimit, prefixStart, curr, dictLimit, ddsIdx); + } else if (dictMode == ZSTD_dictMatchState) { + /* TODO: Measure and potentially add prefetching to DMS */ + const U32 dmsLowestIndex = dms->window.dictLimit; + const BYTE* const dmsBase = dms->window.base; + const BYTE* const dmsEnd = dms->window.nextSrc; + const U32 dmsSize = (U32)(dmsEnd - dmsBase); + const U32 dmsIndexDelta = dictLimit - dmsSize; + + { U32 const headGrouped = (*dmsTagRow & rowMask) * groupWidth; + U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES]; + size_t numMatches = 0; + size_t currMatch = 0; + ZSTD_VecMask matches = ZSTD_row_getMatchMask(dmsTagRow, (BYTE)dmsTag, headGrouped, rowEntries); + + for (; (matches > 0) && (nbAttempts > 0); matches &= (matches - 1)) { + U32 const matchPos = ((headGrouped + ZSTD_VecMask_next(matches)) / groupWidth) & rowMask; + U32 const matchIndex = dmsRow[matchPos]; + if(matchPos == 0) continue; + if (matchIndex < dmsLowestIndex) + break; + PREFETCH_L1(dmsBase + matchIndex); + matchBuffer[numMatches++] = matchIndex; + --nbAttempts; + } + + /* Return the longest match */ + for (; currMatch < numMatches; ++currMatch) { + U32 const matchIndex = matchBuffer[currMatch]; + size_t currentMl=0; + assert(matchIndex >= dmsLowestIndex); + assert(matchIndex < curr); + + { const BYTE* const match = dmsBase + matchIndex; + assert(match+4 <= dmsEnd); + if (MEM_read32(match) == MEM_read32(ip)) + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4; + } + + if (currentMl > ml) { + ml = currentMl; + assert(curr > matchIndex + dmsIndexDelta); + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + dmsIndexDelta)); + if (ip+currentMl == iLimit) break; + } + } + } + } + return ml; +} + + +/** + * Generate search functions templated on (dictMode, mls, rowLog). + * These functions are outlined for code size & compilation time. + * ZSTD_searchMax() dispatches to the correct implementation function. + * + * TODO: The start of the search function involves loading and calculating a + * bunch of constants from the ZSTD_MatchState_t. These computations could be + * done in an initialization function, and saved somewhere in the match state. + * Then we could pass a pointer to the saved state instead of the match state, + * and avoid duplicate computations. + * + * TODO: Move the match re-winding into searchMax. This improves compression + * ratio, and unlocks further simplifications with the next TODO. + * + * TODO: Try moving the repcode search into searchMax. After the re-winding + * and repcode search are in searchMax, there is no more logic in the match + * finder loop that requires knowledge about the dictMode. So we should be + * able to avoid force inlining it, and we can join the extDict loop with + * the single segment loop. It should go in searchMax instead of its own + * function to avoid having multiple virtual function calls per search. + */ + +#define ZSTD_BT_SEARCH_FN(dictMode, mls) ZSTD_BtFindBestMatch_##dictMode##_##mls +#define ZSTD_HC_SEARCH_FN(dictMode, mls) ZSTD_HcFindBestMatch_##dictMode##_##mls +#define ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog) ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog + +#define ZSTD_SEARCH_FN_ATTRS FORCE_NOINLINE + +#define GEN_ZSTD_BT_SEARCH_FN(dictMode, mls) \ + ZSTD_SEARCH_FN_ATTRS size_t ZSTD_BT_SEARCH_FN(dictMode, mls)( \ + ZSTD_MatchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offBasePtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + return ZSTD_BtFindBestMatch(ms, ip, iLimit, offBasePtr, mls, ZSTD_##dictMode); \ + } \ + +#define GEN_ZSTD_HC_SEARCH_FN(dictMode, mls) \ + ZSTD_SEARCH_FN_ATTRS size_t ZSTD_HC_SEARCH_FN(dictMode, mls)( \ + ZSTD_MatchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offsetPtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + return ZSTD_HcFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \ + } \ + +#define GEN_ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog) \ + ZSTD_SEARCH_FN_ATTRS size_t ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)( \ + ZSTD_MatchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offsetPtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + assert(MAX(4, MIN(6, ms->cParams.searchLog)) == rowLog); \ + return ZSTD_RowFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode, rowLog); \ + } \ + +#define ZSTD_FOR_EACH_ROWLOG(X, dictMode, mls) \ + X(dictMode, mls, 4) \ + X(dictMode, mls, 5) \ + X(dictMode, mls, 6) + +#define ZSTD_FOR_EACH_MLS_ROWLOG(X, dictMode) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 4) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 5) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 6) + +#define ZSTD_FOR_EACH_MLS(X, dictMode) \ + X(dictMode, 4) \ + X(dictMode, 5) \ + X(dictMode, 6) + +#define ZSTD_FOR_EACH_DICT_MODE(X, ...) \ + X(__VA_ARGS__, noDict) \ + X(__VA_ARGS__, extDict) \ + X(__VA_ARGS__, dictMatchState) \ + X(__VA_ARGS__, dedicatedDictSearch) + +/* Generate row search fns for each combination of (dictMode, mls, rowLog) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS_ROWLOG, GEN_ZSTD_ROW_SEARCH_FN) +/* Generate binary Tree search fns for each combination of (dictMode, mls) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_BT_SEARCH_FN) +/* Generate hash chain search fns for each combination of (dictMode, mls) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_HC_SEARCH_FN) + +typedef enum { search_hashChain=0, search_binaryTree=1, search_rowHash=2 } searchMethod_e; + +#define GEN_ZSTD_CALL_BT_SEARCH_FN(dictMode, mls) \ + case mls: \ + return ZSTD_BT_SEARCH_FN(dictMode, mls)(ms, ip, iend, offsetPtr); +#define GEN_ZSTD_CALL_HC_SEARCH_FN(dictMode, mls) \ + case mls: \ + return ZSTD_HC_SEARCH_FN(dictMode, mls)(ms, ip, iend, offsetPtr); +#define GEN_ZSTD_CALL_ROW_SEARCH_FN(dictMode, mls, rowLog) \ + case rowLog: \ + return ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)(ms, ip, iend, offsetPtr); + +#define ZSTD_SWITCH_MLS(X, dictMode) \ + switch (mls) { \ + ZSTD_FOR_EACH_MLS(X, dictMode) \ + } + +#define ZSTD_SWITCH_ROWLOG(dictMode, mls) \ + case mls: \ + switch (rowLog) { \ + ZSTD_FOR_EACH_ROWLOG(GEN_ZSTD_CALL_ROW_SEARCH_FN, dictMode, mls) \ + } \ + ZSTD_UNREACHABLE; \ + break; + +#define ZSTD_SWITCH_SEARCH_METHOD(dictMode) \ + switch (searchMethod) { \ + case search_hashChain: \ + ZSTD_SWITCH_MLS(GEN_ZSTD_CALL_HC_SEARCH_FN, dictMode) \ + break; \ + case search_binaryTree: \ + ZSTD_SWITCH_MLS(GEN_ZSTD_CALL_BT_SEARCH_FN, dictMode) \ + break; \ + case search_rowHash: \ + ZSTD_SWITCH_MLS(ZSTD_SWITCH_ROWLOG, dictMode) \ + break; \ + } \ + ZSTD_UNREACHABLE; + +/** + * Searches for the longest match at @p ip. + * Dispatches to the correct implementation function based on the + * (searchMethod, dictMode, mls, rowLog). We use switch statements + * here instead of using an indirect function call through a function + * pointer because after Spectre and Meltdown mitigations, indirect + * function calls can be very costly, especially in the kernel. + * + * NOTE: dictMode and searchMethod should be templated, so those switch + * statements should be optimized out. Only the mls & rowLog switches + * should be left. + * + * @param ms The match state. + * @param ip The position to search at. + * @param iend The end of the input data. + * @param[out] offsetPtr Stores the match offset into this pointer. + * @param mls The minimum search length, in the range [4, 6]. + * @param rowLog The row log (if applicable), in the range [4, 6]. + * @param searchMethod The search method to use (templated). + * @param dictMode The dictMode (templated). + * + * @returns The length of the longest match found, or < mls if no match is found. + * If a match is found its offset is stored in @p offsetPtr. + */ +FORCE_INLINE_TEMPLATE size_t ZSTD_searchMax( + ZSTD_MatchState_t* ms, + const BYTE* ip, + const BYTE* iend, + size_t* offsetPtr, + U32 const mls, + U32 const rowLog, + searchMethod_e const searchMethod, + ZSTD_dictMode_e const dictMode) +{ + if (dictMode == ZSTD_noDict) { + ZSTD_SWITCH_SEARCH_METHOD(noDict) + } else if (dictMode == ZSTD_extDict) { + ZSTD_SWITCH_SEARCH_METHOD(extDict) + } else if (dictMode == ZSTD_dictMatchState) { + ZSTD_SWITCH_SEARCH_METHOD(dictMatchState) + } else if (dictMode == ZSTD_dedicatedDictSearch) { + ZSTD_SWITCH_SEARCH_METHOD(dedicatedDictSearch) + } + ZSTD_UNREACHABLE; + return 0; +} + +/* ******************************* +* Common parser - lazy strategy +*********************************/ + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_lazy_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, + const searchMethod_e searchMethod, const U32 depth, + ZSTD_dictMode_e const dictMode) +{ + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = (searchMethod == search_rowHash) ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8; + const BYTE* const base = ms->window.base; + const U32 prefixLowestIndex = ms->window.dictLimit; + const BYTE* const prefixLowest = base + prefixLowestIndex; + const U32 mls = BOUNDED(4, ms->cParams.minMatch, 6); + const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6); + + U32 offset_1 = rep[0], offset_2 = rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + const int isDMS = dictMode == ZSTD_dictMatchState; + const int isDDS = dictMode == ZSTD_dedicatedDictSearch; + const int isDxS = isDMS || isDDS; + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const U32 dictLowestIndex = isDxS ? dms->window.dictLimit : 0; + const BYTE* const dictBase = isDxS ? dms->window.base : NULL; + const BYTE* const dictLowest = isDxS ? dictBase + dictLowestIndex : NULL; + const BYTE* const dictEnd = isDxS ? dms->window.nextSrc : NULL; + const U32 dictIndexDelta = isDxS ? + prefixLowestIndex - (U32)(dictEnd - dictBase) : + 0; + const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest)); + + DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u) (searchFunc=%u)", (U32)dictMode, (U32)searchMethod); + ip += (dictAndPrefixLength == 0); + if (dictMode == ZSTD_noDict) { + U32 const curr = (U32)(ip - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, ms->cParams.windowLog); + U32 const maxRep = curr - windowLow; + if (offset_2 > maxRep) offsetSaved2 = offset_2, offset_2 = 0; + if (offset_1 > maxRep) offsetSaved1 = offset_1, offset_1 = 0; + } + if (isDxS) { + /* dictMatchState repCode checks don't currently handle repCode == 0 + * disabling. */ + assert(offset_1 <= dictAndPrefixLength); + assert(offset_2 <= dictAndPrefixLength); + } + + /* Reset the lazy skipping state */ + ms->lazySkipping = 0; + + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + + /* Match Loop */ +#if defined(__GNUC__) && defined(__x86_64__) + /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the + * code alignment is perturbed. To fix the instability align the loop on 32-bytes. + */ + __asm__(".p2align 5"); +#endif + while (ip < ilimit) { + size_t matchLength=0; + size_t offBase = REPCODE1_TO_OFFBASE; + const BYTE* start=ip+1; + DEBUGLOG(7, "search baseline (depth 0)"); + + /* check repCode */ + if (isDxS) { + const U32 repIndex = (U32)(ip - base) + 1 - offset_1; + const BYTE* repMatch = ((dictMode == ZSTD_dictMatchState || dictMode == ZSTD_dedicatedDictSearch) + && repIndex < prefixLowestIndex) ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + if (depth==0) goto _storeSequence; + } + } + if ( dictMode == ZSTD_noDict + && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) { + matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; + if (depth==0) goto _storeSequence; + } + + /* first search (depth 0) */ + { size_t offbaseFound = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &offbaseFound, mls, rowLog, searchMethod, dictMode); + if (ml2 > matchLength) + matchLength = ml2, start = ip, offBase = offbaseFound; + } + + if (matchLength < 4) { + size_t const step = ((size_t)(ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */; + ip += step; + /* Enter the lazy skipping mode once we are skipping more than 8 bytes at a time. + * In this mode we stop inserting every position into our tables, and only insert + * positions that we search, which is one in step positions. + * The exact cutoff is flexible, I've just chosen a number that is reasonably high, + * so we minimize the compression ratio loss in "normal" scenarios. This mode gets + * triggered once we've gone 2KB without finding any matches. + */ + ms->lazySkipping = step > kLazySkippingStep; + continue; + } + + /* let's try to find a better solution */ + if (depth>=1) + while (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) { + size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4; + int const gain2 = (int)(mlRep * 3); + int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + if (isDxS) { + const U32 repIndex = (U32)(ip - base) - offset_1; + const BYTE* repMatch = repIndex < prefixLowestIndex ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + int const gain2 = (int)(mlRep * 3); + int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + } + { size_t ofbCandidate=999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, dictMode); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 4); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; /* search a better one */ + } } + + /* let's find an even better one */ + if ((depth==2) && (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) { + size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4; + int const gain2 = (int)(mlRep * 4); + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + if (isDxS) { + const U32 repIndex = (U32)(ip - base) - offset_1; + const BYTE* repMatch = repIndex < prefixLowestIndex ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + int const gain2 = (int)(mlRep * 4); + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + } + { size_t ofbCandidate=999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, dictMode); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 7); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; + } } } + break; /* nothing found : store previous solution */ + } + + /* NOTE: + * Pay attention that `start[-value]` can lead to strange undefined behavior + * notably if `value` is unsigned, resulting in a large positive `-value`. + */ + /* catch up */ + if (OFFBASE_IS_OFFSET(offBase)) { + if (dictMode == ZSTD_noDict) { + while ( ((start > anchor) & (start - OFFBASE_TO_OFFSET(offBase) > prefixLowest)) + && (start[-1] == (start-OFFBASE_TO_OFFSET(offBase))[-1]) ) /* only search for offset within prefix */ + { start--; matchLength++; } + } + if (isDxS) { + U32 const matchIndex = (U32)((size_t)(start-base) - OFFBASE_TO_OFFSET(offBase)); + const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex; + const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest; + while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ + } + offset_2 = offset_1; offset_1 = (U32)OFFBASE_TO_OFFSET(offBase); + } + /* store sequence */ +_storeSequence: + { size_t const litLength = (size_t)(start - anchor); + ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offBase, matchLength); + anchor = ip = start + matchLength; + } + if (ms->lazySkipping) { + /* We've found a match, disable lazy skipping mode, and refill the hash cache. */ + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + ms->lazySkipping = 0; + } + + /* check immediate repcode */ + if (isDxS) { + while (ip <= ilimit) { + U32 const current2 = (U32)(ip-base); + U32 const repIndex = current2 - offset_2; + const BYTE* repMatch = repIndex < prefixLowestIndex ? + dictBase - dictIndexDelta + repIndex : + base + repIndex; + if ( (ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip)) ) { + const BYTE* const repEnd2 = repIndex < prefixLowestIndex ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd2, prefixLowest) + 4; + offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength); + ip += matchLength; + anchor = ip; + continue; + } + break; + } + } + + if (dictMode == ZSTD_noDict) { + while ( ((ip <= ilimit) & (offset_2>0)) + && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { + /* store sequence */ + matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; + offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap repcodes */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength); + ip += matchLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } } } + + /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0), + * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */ + offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved1; + rep[1] = offset_2 ? offset_2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} +#endif /* build exclusions */ + + +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_greedy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_greedy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_greedy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_greedy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_lazy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_lazy2_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy2_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_btlazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_dictMatchState); +} +#endif + +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_lazy_extDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, + const searchMethod_e searchMethod, const U32 depth) +{ + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = searchMethod == search_rowHash ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8; + const BYTE* const base = ms->window.base; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictBase = ms->window.dictBase; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const dictStart = dictBase + ms->window.lowLimit; + const U32 windowLog = ms->cParams.windowLog; + const U32 mls = BOUNDED(4, ms->cParams.minMatch, 6); + const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6); + + U32 offset_1 = rep[0], offset_2 = rep[1]; + + DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic (searchFunc=%u)", (U32)searchMethod); + + /* Reset the lazy skipping state */ + ms->lazySkipping = 0; + + /* init */ + ip += (ip == prefixStart); + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + + /* Match Loop */ +#if defined(__GNUC__) && defined(__x86_64__) + /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the + * code alignment is perturbed. To fix the instability align the loop on 32-bytes. + */ + __asm__(".p2align 5"); +#endif + while (ip < ilimit) { + size_t matchLength=0; + size_t offBase = REPCODE1_TO_OFFBASE; + const BYTE* start=ip+1; + U32 curr = (U32)(ip-base); + + /* check repCode */ + { const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr+1, windowLog); + const U32 repIndex = (U32)(curr+1 - offset_1); + const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE* const repMatch = repBase + repIndex; + if ( (ZSTD_index_overlap_check(dictLimit, repIndex)) + & (offset_1 <= curr+1 - windowLow) ) /* note: we are searching at curr+1 */ + if (MEM_read32(ip+1) == MEM_read32(repMatch)) { + /* repcode detected we should take it */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repEnd, prefixStart) + 4; + if (depth==0) goto _storeSequence; + } } + + /* first search (depth 0) */ + { size_t ofbCandidate = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict); + if (ml2 > matchLength) + matchLength = ml2, start = ip, offBase = ofbCandidate; + } + + if (matchLength < 4) { + size_t const step = ((size_t)(ip-anchor) >> kSearchStrength); + ip += step + 1; /* jump faster over incompressible sections */ + /* Enter the lazy skipping mode once we are skipping more than 8 bytes at a time. + * In this mode we stop inserting every position into our tables, and only insert + * positions that we search, which is one in step positions. + * The exact cutoff is flexible, I've just chosen a number that is reasonably high, + * so we minimize the compression ratio loss in "normal" scenarios. This mode gets + * triggered once we've gone 2KB without finding any matches. + */ + ms->lazySkipping = step > kLazySkippingStep; + continue; + } + + /* let's try to find a better solution */ + if (depth>=1) + while (ip repIndex >= windowLow` */ + if (MEM_read32(ip) == MEM_read32(repMatch)) { + /* repcode detected */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4; + int const gain2 = (int)(repLength * 3); + int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1); + if ((repLength >= 4) && (gain2 > gain1)) + matchLength = repLength, offBase = REPCODE1_TO_OFFBASE, start = ip; + } } + + /* search match, depth 1 */ + { size_t ofbCandidate = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 4); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; /* search a better one */ + } } + + /* let's find an even better one */ + if ((depth==2) && (ip repIndex >= windowLow` */ + if (MEM_read32(ip) == MEM_read32(repMatch)) { + /* repcode detected */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4; + int const gain2 = (int)(repLength * 4); + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1); + if ((repLength >= 4) && (gain2 > gain1)) + matchLength = repLength, offBase = REPCODE1_TO_OFFBASE, start = ip; + } } + + /* search match, depth 2 */ + { size_t ofbCandidate = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 7); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; + } } } + break; /* nothing found : store previous solution */ + } + + /* catch up */ + if (OFFBASE_IS_OFFSET(offBase)) { + U32 const matchIndex = (U32)((size_t)(start-base) - OFFBASE_TO_OFFSET(offBase)); + const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; + const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; + while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ + offset_2 = offset_1; offset_1 = (U32)OFFBASE_TO_OFFSET(offBase); + } + + /* store sequence */ +_storeSequence: + { size_t const litLength = (size_t)(start - anchor); + ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offBase, matchLength); + anchor = ip = start + matchLength; + } + if (ms->lazySkipping) { + /* We've found a match, disable lazy skipping mode, and refill the hash cache. */ + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + ms->lazySkipping = 0; + } + + /* check immediate repcode */ + while (ip <= ilimit) { + const U32 repCurrent = (U32)(ip-base); + const U32 windowLow = ZSTD_getLowestMatchIndex(ms, repCurrent, windowLog); + const U32 repIndex = repCurrent - offset_2; + const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE* const repMatch = repBase + repIndex; + if ( (ZSTD_index_overlap_check(dictLimit, repIndex)) + & (offset_2 <= repCurrent - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */ + if (MEM_read32(ip) == MEM_read32(repMatch)) { + /* repcode detected we should take it */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4; + offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap offset history */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength); + ip += matchLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + break; + } } + + /* Save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} +#endif /* build exclusions */ + +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_greedy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0); +} + +size_t ZSTD_compressBlock_greedy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1); +} + +size_t ZSTD_compressBlock_lazy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2); +} + +size_t ZSTD_compressBlock_lazy2_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2); +} +#endif diff --git a/src/commonlib/bsd/zstd/compress/zstd_lazy.h b/src/commonlib/bsd/zstd/compress/zstd_lazy.h new file mode 100644 index 0000000000..f959a855f6 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_lazy.h @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_LAZY_H +#define ZSTD_LAZY_H + +#include "zstd_compress_internal.h" + +/** + * Dedicated Dictionary Search Structure bucket log. In the + * ZSTD_dedicatedDictSearch mode, the hashTable has + * 2 ** ZSTD_LAZY_DDSS_BUCKET_LOG entries in each bucket, rather than just + * one. + */ +#define ZSTD_LAZY_DDSS_BUCKET_LOG 2 + +#define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */ + +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) +U32 ZSTD_insertAndFindFirstIndex(ZSTD_MatchState_t* ms, const BYTE* ip); +void ZSTD_row_update(ZSTD_MatchState_t* const ms, const BYTE* ip); + +void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_MatchState_t* ms, const BYTE* const ip); + +void ZSTD_preserveUnsortedMark (U32* const table, U32 const size, U32 const reducerValue); /*! used in ZSTD_reduceIndex(). preemptively increase value of ZSTD_DUBT_UNSORTED_MARK */ +#endif + +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_greedy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_GREEDY ZSTD_compressBlock_greedy +#define ZSTD_COMPRESSBLOCK_GREEDY_ROW ZSTD_compressBlock_greedy_row +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE ZSTD_compressBlock_greedy_dictMatchState +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW ZSTD_compressBlock_greedy_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH ZSTD_compressBlock_greedy_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_greedy_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT ZSTD_compressBlock_greedy_extDict +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW ZSTD_compressBlock_greedy_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_GREEDY NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_LAZY ZSTD_compressBlock_lazy +#define ZSTD_COMPRESSBLOCK_LAZY_ROW ZSTD_compressBlock_lazy_row +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE ZSTD_compressBlock_lazy_dictMatchState +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW ZSTD_compressBlock_lazy_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH ZSTD_compressBlock_lazy_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_lazy_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT ZSTD_compressBlock_lazy_extDict +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW ZSTD_compressBlock_lazy_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_LAZY NULL +#define ZSTD_COMPRESSBLOCK_LAZY_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_LAZY2 ZSTD_compressBlock_lazy2 +#define ZSTD_COMPRESSBLOCK_LAZY2_ROW ZSTD_compressBlock_lazy2_row +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE ZSTD_compressBlock_lazy2_dictMatchState +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW ZSTD_compressBlock_lazy2_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH ZSTD_compressBlock_lazy2_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_lazy2_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT ZSTD_compressBlock_lazy2_extDict +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW ZSTD_compressBlock_lazy2_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_LAZY2 NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btlazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btlazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_BTLAZY2 ZSTD_compressBlock_btlazy2 +#define ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE ZSTD_compressBlock_btlazy2_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT ZSTD_compressBlock_btlazy2_extDict +#else +#define ZSTD_COMPRESSBLOCK_BTLAZY2 NULL +#define ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT NULL +#endif + +#endif /* ZSTD_LAZY_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_ldm.c b/src/commonlib/bsd/zstd/compress/zstd_ldm.c new file mode 100644 index 0000000000..969b73152f --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_ldm.c @@ -0,0 +1,747 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_ldm.h" + +#include "../common/debug.h" +#include +#include "zstd_fast.h" /* ZSTD_fillHashTable() */ +#include "zstd_double_fast.h" /* ZSTD_fillDoubleHashTable() */ +#include "zstd_ldm_geartab.h" + +#define LDM_BUCKET_SIZE_LOG 4 +#define LDM_MIN_MATCH_LENGTH 64 +#define LDM_HASH_RLOG 7 + +typedef struct { + U64 rolling; + U64 stopMask; +} ldmRollingHashState_t; + +/** ZSTD_ldm_gear_init(): + * + * Initializes the rolling hash state such that it will honor the + * settings in params. */ +static void ZSTD_ldm_gear_init(ldmRollingHashState_t* state, ldmParams_t const* params) +{ + unsigned maxBitsInMask = MIN(params->minMatchLength, 64); + unsigned hashRateLog = params->hashRateLog; + + state->rolling = ~(U32)0; + + /* The choice of the splitting criterion is subject to two conditions: + * 1. it has to trigger on average every 2^(hashRateLog) bytes; + * 2. ideally, it has to depend on a window of minMatchLength bytes. + * + * In the gear hash algorithm, bit n depends on the last n bytes; + * so in order to obtain a good quality splitting criterion it is + * preferable to use bits with high weight. + * + * To match condition 1 we use a mask with hashRateLog bits set + * and, because of the previous remark, we make sure these bits + * have the highest possible weight while still respecting + * condition 2. + */ + if (hashRateLog > 0 && hashRateLog <= maxBitsInMask) { + state->stopMask = (((U64)1 << hashRateLog) - 1) << (maxBitsInMask - hashRateLog); + } else { + /* In this degenerate case we simply honor the hash rate. */ + state->stopMask = ((U64)1 << hashRateLog) - 1; + } +} + +/** ZSTD_ldm_gear_reset() + * Feeds [data, data + minMatchLength) into the hash without registering any + * splits. This effectively resets the hash state. This is used when skipping + * over data, either at the beginning of a block, or skipping sections. + */ +static void ZSTD_ldm_gear_reset(ldmRollingHashState_t* state, + BYTE const* data, size_t minMatchLength) +{ + U64 hash = state->rolling; + size_t n = 0; + +#define GEAR_ITER_ONCE() do { \ + hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \ + n += 1; \ + } while (0) + while (n + 3 < minMatchLength) { + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + } + while (n < minMatchLength) { + GEAR_ITER_ONCE(); + } +#undef GEAR_ITER_ONCE +} + +/** ZSTD_ldm_gear_feed(): + * + * Registers in the splits array all the split points found in the first + * size bytes following the data pointer. This function terminates when + * either all the data has been processed or LDM_BATCH_SIZE splits are + * present in the splits array. + * + * Precondition: The splits array must not be full. + * Returns: The number of bytes processed. */ +static size_t ZSTD_ldm_gear_feed(ldmRollingHashState_t* state, + BYTE const* data, size_t size, + size_t* splits, unsigned* numSplits) +{ + size_t n; + U64 hash, mask; + + hash = state->rolling; + mask = state->stopMask; + n = 0; + +#define GEAR_ITER_ONCE() do { \ + hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \ + n += 1; \ + if (UNLIKELY((hash & mask) == 0)) { \ + splits[*numSplits] = n; \ + *numSplits += 1; \ + if (*numSplits == LDM_BATCH_SIZE) \ + goto done; \ + } \ + } while (0) + + while (n + 3 < size) { + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + } + while (n < size) { + GEAR_ITER_ONCE(); + } + +#undef GEAR_ITER_ONCE + +done: + state->rolling = hash; + return n; +} + +void ZSTD_ldm_adjustParameters(ldmParams_t* params, + const ZSTD_compressionParameters* cParams) +{ + params->windowLog = cParams->windowLog; + ZSTD_STATIC_ASSERT(LDM_BUCKET_SIZE_LOG <= ZSTD_LDM_BUCKETSIZELOG_MAX); + DEBUGLOG(4, "ZSTD_ldm_adjustParameters"); + if (params->hashRateLog == 0) { + if (params->hashLog > 0) { + /* if params->hashLog is set, derive hashRateLog from it */ + assert(params->hashLog <= ZSTD_HASHLOG_MAX); + if (params->windowLog > params->hashLog) { + params->hashRateLog = params->windowLog - params->hashLog; + } + } else { + assert(1 <= (int)cParams->strategy && (int)cParams->strategy <= 9); + /* mapping from [fast, rate7] to [btultra2, rate4] */ + params->hashRateLog = 7 - (cParams->strategy/3); + } + } + if (params->hashLog == 0) { + params->hashLog = BOUNDED(ZSTD_HASHLOG_MIN, params->windowLog - params->hashRateLog, ZSTD_HASHLOG_MAX); + } + if (params->minMatchLength == 0) { + params->minMatchLength = LDM_MIN_MATCH_LENGTH; + if (cParams->strategy >= ZSTD_btultra) + params->minMatchLength /= 2; + } + if (params->bucketSizeLog==0) { + assert(1 <= (int)cParams->strategy && (int)cParams->strategy <= 9); + params->bucketSizeLog = BOUNDED(LDM_BUCKET_SIZE_LOG, (U32)cParams->strategy, ZSTD_LDM_BUCKETSIZELOG_MAX); + } + params->bucketSizeLog = MIN(params->bucketSizeLog, params->hashLog); +} + +size_t ZSTD_ldm_getTableSize(ldmParams_t params) +{ + size_t const ldmHSize = ((size_t)1) << params.hashLog; + size_t const ldmBucketSizeLog = MIN(params.bucketSizeLog, params.hashLog); + size_t const ldmBucketSize = ((size_t)1) << (params.hashLog - ldmBucketSizeLog); + size_t const totalSize = ZSTD_cwksp_alloc_size(ldmBucketSize) + + ZSTD_cwksp_alloc_size(ldmHSize * sizeof(ldmEntry_t)); + return params.enableLdm == ZSTD_ps_enable ? totalSize : 0; +} + +size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize) +{ + return params.enableLdm == ZSTD_ps_enable ? (maxChunkSize / params.minMatchLength) : 0; +} + +/** ZSTD_ldm_getBucket() : + * Returns a pointer to the start of the bucket associated with hash. */ +static ldmEntry_t* ZSTD_ldm_getBucket( + const ldmState_t* ldmState, size_t hash, U32 const bucketSizeLog) +{ + return ldmState->hashTable + (hash << bucketSizeLog); +} + +/** ZSTD_ldm_insertEntry() : + * Insert the entry with corresponding hash into the hash table */ +static void ZSTD_ldm_insertEntry(ldmState_t* ldmState, + size_t const hash, const ldmEntry_t entry, + U32 const bucketSizeLog) +{ + BYTE* const pOffset = ldmState->bucketOffsets + hash; + unsigned const offset = *pOffset; + + *(ZSTD_ldm_getBucket(ldmState, hash, bucketSizeLog) + offset) = entry; + *pOffset = (BYTE)((offset + 1) & ((1u << bucketSizeLog) - 1)); + +} + +/** ZSTD_ldm_countBackwardsMatch() : + * Returns the number of bytes that match backwards before pIn and pMatch. + * + * We count only bytes where pMatch >= pBase and pIn >= pAnchor. */ +static size_t ZSTD_ldm_countBackwardsMatch( + const BYTE* pIn, const BYTE* pAnchor, + const BYTE* pMatch, const BYTE* pMatchBase) +{ + size_t matchLength = 0; + while (pIn > pAnchor && pMatch > pMatchBase && pIn[-1] == pMatch[-1]) { + pIn--; + pMatch--; + matchLength++; + } + return matchLength; +} + +/** ZSTD_ldm_countBackwardsMatch_2segments() : + * Returns the number of bytes that match backwards from pMatch, + * even with the backwards match spanning 2 different segments. + * + * On reaching `pMatchBase`, start counting from mEnd */ +static size_t ZSTD_ldm_countBackwardsMatch_2segments( + const BYTE* pIn, const BYTE* pAnchor, + const BYTE* pMatch, const BYTE* pMatchBase, + const BYTE* pExtDictStart, const BYTE* pExtDictEnd) +{ + size_t matchLength = ZSTD_ldm_countBackwardsMatch(pIn, pAnchor, pMatch, pMatchBase); + if (pMatch - matchLength != pMatchBase || pMatchBase == pExtDictStart) { + /* If backwards match is entirely in the extDict or prefix, immediately return */ + return matchLength; + } + DEBUGLOG(7, "ZSTD_ldm_countBackwardsMatch_2segments: found 2-parts backwards match (length in prefix==%zu)", matchLength); + matchLength += ZSTD_ldm_countBackwardsMatch(pIn - matchLength, pAnchor, pExtDictEnd, pExtDictStart); + DEBUGLOG(7, "final backwards match length = %zu", matchLength); + return matchLength; +} + +/** ZSTD_ldm_fillFastTables() : + * + * Fills the relevant tables for the ZSTD_fast and ZSTD_dfast strategies. + * This is similar to ZSTD_loadDictionaryContent. + * + * The tables for the other strategies are filled within their + * block compressors. */ +static size_t ZSTD_ldm_fillFastTables(ZSTD_MatchState_t* ms, + void const* end) +{ + const BYTE* const iend = (const BYTE*)end; + + switch(ms->cParams.strategy) + { + case ZSTD_fast: + ZSTD_fillHashTable(ms, iend, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx); + break; + + case ZSTD_dfast: +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + ZSTD_fillDoubleHashTable(ms, iend, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + default: + assert(0); /* not possible : not a valid strategy id */ + } + + return 0; +} + +void ZSTD_ldm_fillHashTable( + ldmState_t* ldmState, const BYTE* ip, + const BYTE* iend, ldmParams_t const* params) +{ + U32 const minMatchLength = params->minMatchLength; + U32 const bucketSizeLog = params->bucketSizeLog; + U32 const hBits = params->hashLog - bucketSizeLog; + BYTE const* const base = ldmState->window.base; + BYTE const* const istart = ip; + ldmRollingHashState_t hashState; + size_t* const splits = ldmState->splitIndices; + unsigned numSplits; + + DEBUGLOG(5, "ZSTD_ldm_fillHashTable"); + + ZSTD_ldm_gear_init(&hashState, params); + while (ip < iend) { + size_t hashed; + unsigned n; + + numSplits = 0; + hashed = ZSTD_ldm_gear_feed(&hashState, ip, (size_t)(iend - ip), splits, &numSplits); + + for (n = 0; n < numSplits; n++) { + if (ip + splits[n] >= istart + minMatchLength) { + BYTE const* const split = ip + splits[n] - minMatchLength; + U64 const xxhash = XXH64(split, minMatchLength, 0); + U32 const hash = (U32)(xxhash & (((U32)1 << hBits) - 1)); + ldmEntry_t entry; + + entry.offset = (U32)(split - base); + entry.checksum = (U32)(xxhash >> 32); + ZSTD_ldm_insertEntry(ldmState, hash, entry, params->bucketSizeLog); + } + } + + ip += hashed; + } +} + + +/** ZSTD_ldm_limitTableUpdate() : + * + * Sets cctx->nextToUpdate to a position corresponding closer to anchor + * if it is far way + * (after a long match, only update tables a limited amount). */ +static void ZSTD_ldm_limitTableUpdate(ZSTD_MatchState_t* ms, const BYTE* anchor) +{ + U32 const curr = (U32)(anchor - ms->window.base); + if (curr > ms->nextToUpdate + 1024) { + ms->nextToUpdate = + curr - MIN(512, curr - ms->nextToUpdate - 1024); + } +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_ldm_generateSequences_internal( + ldmState_t* ldmState, RawSeqStore_t* rawSeqStore, + ldmParams_t const* params, void const* src, size_t srcSize) +{ + /* LDM parameters */ + int const extDict = ZSTD_window_hasExtDict(ldmState->window); + U32 const minMatchLength = params->minMatchLength; + U32 const entsPerBucket = 1U << params->bucketSizeLog; + U32 const hBits = params->hashLog - params->bucketSizeLog; + /* Prefix and extDict parameters */ + U32 const dictLimit = ldmState->window.dictLimit; + U32 const lowestIndex = extDict ? ldmState->window.lowLimit : dictLimit; + BYTE const* const base = ldmState->window.base; + BYTE const* const dictBase = extDict ? ldmState->window.dictBase : NULL; + BYTE const* const dictStart = extDict ? dictBase + lowestIndex : NULL; + BYTE const* const dictEnd = extDict ? dictBase + dictLimit : NULL; + BYTE const* const lowPrefixPtr = base + dictLimit; + /* Input bounds */ + BYTE const* const istart = (BYTE const*)src; + BYTE const* const iend = istart + srcSize; + BYTE const* const ilimit = iend - HASH_READ_SIZE; + /* Input positions */ + BYTE const* anchor = istart; + BYTE const* ip = istart; + /* Rolling hash state */ + ldmRollingHashState_t hashState; + /* Arrays for staged-processing */ + size_t* const splits = ldmState->splitIndices; + ldmMatchCandidate_t* const candidates = ldmState->matchCandidates; + unsigned numSplits; + + if (srcSize < minMatchLength) + return iend - anchor; + + /* Initialize the rolling hash state with the first minMatchLength bytes */ + ZSTD_ldm_gear_init(&hashState, params); + ZSTD_ldm_gear_reset(&hashState, ip, minMatchLength); + ip += minMatchLength; + + while (ip < ilimit) { + size_t hashed; + unsigned n; + + numSplits = 0; + hashed = ZSTD_ldm_gear_feed(&hashState, ip, ilimit - ip, + splits, &numSplits); + + for (n = 0; n < numSplits; n++) { + BYTE const* const split = ip + splits[n] - minMatchLength; + U64 const xxhash = XXH64(split, minMatchLength, 0); + U32 const hash = (U32)(xxhash & (((U32)1 << hBits) - 1)); + + candidates[n].split = split; + candidates[n].hash = hash; + candidates[n].checksum = (U32)(xxhash >> 32); + candidates[n].bucket = ZSTD_ldm_getBucket(ldmState, hash, params->bucketSizeLog); + PREFETCH_L1(candidates[n].bucket); + } + + for (n = 0; n < numSplits; n++) { + size_t forwardMatchLength = 0, backwardMatchLength = 0, + bestMatchLength = 0, mLength; + U32 offset; + BYTE const* const split = candidates[n].split; + U32 const checksum = candidates[n].checksum; + U32 const hash = candidates[n].hash; + ldmEntry_t* const bucket = candidates[n].bucket; + ldmEntry_t const* cur; + ldmEntry_t const* bestEntry = NULL; + ldmEntry_t newEntry; + + newEntry.offset = (U32)(split - base); + newEntry.checksum = checksum; + + /* If a split point would generate a sequence overlapping with + * the previous one, we merely register it in the hash table and + * move on */ + if (split < anchor) { + ZSTD_ldm_insertEntry(ldmState, hash, newEntry, params->bucketSizeLog); + continue; + } + + for (cur = bucket; cur < bucket + entsPerBucket; cur++) { + size_t curForwardMatchLength, curBackwardMatchLength, + curTotalMatchLength; + if (cur->checksum != checksum || cur->offset <= lowestIndex) { + continue; + } + if (extDict) { + BYTE const* const curMatchBase = + cur->offset < dictLimit ? dictBase : base; + BYTE const* const pMatch = curMatchBase + cur->offset; + BYTE const* const matchEnd = + cur->offset < dictLimit ? dictEnd : iend; + BYTE const* const lowMatchPtr = + cur->offset < dictLimit ? dictStart : lowPrefixPtr; + curForwardMatchLength = + ZSTD_count_2segments(split, pMatch, iend, matchEnd, lowPrefixPtr); + if (curForwardMatchLength < minMatchLength) { + continue; + } + curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch_2segments( + split, anchor, pMatch, lowMatchPtr, dictStart, dictEnd); + } else { /* !extDict */ + BYTE const* const pMatch = base + cur->offset; + curForwardMatchLength = ZSTD_count(split, pMatch, iend); + if (curForwardMatchLength < minMatchLength) { + continue; + } + curBackwardMatchLength = + ZSTD_ldm_countBackwardsMatch(split, anchor, pMatch, lowPrefixPtr); + } + curTotalMatchLength = curForwardMatchLength + curBackwardMatchLength; + + if (curTotalMatchLength > bestMatchLength) { + bestMatchLength = curTotalMatchLength; + forwardMatchLength = curForwardMatchLength; + backwardMatchLength = curBackwardMatchLength; + bestEntry = cur; + } + } + + /* No match found -- insert an entry into the hash table + * and process the next candidate match */ + if (bestEntry == NULL) { + ZSTD_ldm_insertEntry(ldmState, hash, newEntry, params->bucketSizeLog); + continue; + } + + /* Match found */ + offset = (U32)(split - base) - bestEntry->offset; + mLength = forwardMatchLength + backwardMatchLength; + { + rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size; + + /* Out of sequence storage */ + if (rawSeqStore->size == rawSeqStore->capacity) + return ERROR(dstSize_tooSmall); + seq->litLength = (U32)(split - backwardMatchLength - anchor); + seq->matchLength = (U32)mLength; + seq->offset = offset; + rawSeqStore->size++; + } + + /* Insert the current entry into the hash table --- it must be + * done after the previous block to avoid clobbering bestEntry */ + ZSTD_ldm_insertEntry(ldmState, hash, newEntry, params->bucketSizeLog); + + anchor = split + forwardMatchLength; + + /* If we find a match that ends after the data that we've hashed + * then we have a repeating, overlapping, pattern. E.g. all zeros. + * If one repetition of the pattern matches our `stopMask` then all + * repetitions will. We don't need to insert them all into out table, + * only the first one. So skip over overlapping matches. + * This is a major speed boost (20x) for compressing a single byte + * repeated, when that byte ends up in the table. + */ + if (anchor > ip + hashed) { + ZSTD_ldm_gear_reset(&hashState, anchor - minMatchLength, minMatchLength); + /* Continue the outer loop at anchor (ip + hashed == anchor). */ + ip = anchor - hashed; + break; + } + } + + ip += hashed; + } + + return iend - anchor; +} + +/*! ZSTD_ldm_reduceTable() : + * reduce table indexes by `reducerValue` */ +static void ZSTD_ldm_reduceTable(ldmEntry_t* const table, U32 const size, + U32 const reducerValue) +{ + U32 u; + for (u = 0; u < size; u++) { + if (table[u].offset < reducerValue) table[u].offset = 0; + else table[u].offset -= reducerValue; + } +} + +size_t ZSTD_ldm_generateSequences( + ldmState_t* ldmState, RawSeqStore_t* sequences, + ldmParams_t const* params, void const* src, size_t srcSize) +{ + U32 const maxDist = 1U << params->windowLog; + BYTE const* const istart = (BYTE const*)src; + BYTE const* const iend = istart + srcSize; + size_t const kMaxChunkSize = 1 << 20; + size_t const nbChunks = (srcSize / kMaxChunkSize) + ((srcSize % kMaxChunkSize) != 0); + size_t chunk; + size_t leftoverSize = 0; + + assert(ZSTD_CHUNKSIZE_MAX >= kMaxChunkSize); + /* Check that ZSTD_window_update() has been called for this chunk prior + * to passing it to this function. + */ + assert(ldmState->window.nextSrc >= (BYTE const*)src + srcSize); + /* The input could be very large (in zstdmt), so it must be broken up into + * chunks to enforce the maximum distance and handle overflow correction. + */ + assert(sequences->pos <= sequences->size); + assert(sequences->size <= sequences->capacity); + for (chunk = 0; chunk < nbChunks && sequences->size < sequences->capacity; ++chunk) { + BYTE const* const chunkStart = istart + chunk * kMaxChunkSize; + size_t const remaining = (size_t)(iend - chunkStart); + BYTE const *const chunkEnd = + (remaining < kMaxChunkSize) ? iend : chunkStart + kMaxChunkSize; + size_t const chunkSize = chunkEnd - chunkStart; + size_t newLeftoverSize; + size_t const prevSize = sequences->size; + + assert(chunkStart < iend); + /* 1. Perform overflow correction if necessary. */ + if (ZSTD_window_needOverflowCorrection(ldmState->window, 0, maxDist, ldmState->loadedDictEnd, chunkStart, chunkEnd)) { + U32 const ldmHSize = 1U << params->hashLog; + U32 const correction = ZSTD_window_correctOverflow( + &ldmState->window, /* cycleLog */ 0, maxDist, chunkStart); + ZSTD_ldm_reduceTable(ldmState->hashTable, ldmHSize, correction); + /* invalidate dictionaries on overflow correction */ + ldmState->loadedDictEnd = 0; + } + /* 2. We enforce the maximum offset allowed. + * + * kMaxChunkSize should be small enough that we don't lose too much of + * the window through early invalidation. + * TODO: * Test the chunk size. + * * Try invalidation after the sequence generation and test the + * offset against maxDist directly. + * + * NOTE: Because of dictionaries + sequence splitting we MUST make sure + * that any offset used is valid at the END of the sequence, since it may + * be split into two sequences. This condition holds when using + * ZSTD_window_enforceMaxDist(), but if we move to checking offsets + * against maxDist directly, we'll have to carefully handle that case. + */ + ZSTD_window_enforceMaxDist(&ldmState->window, chunkEnd, maxDist, &ldmState->loadedDictEnd, NULL); + /* 3. Generate the sequences for the chunk, and get newLeftoverSize. */ + newLeftoverSize = ZSTD_ldm_generateSequences_internal( + ldmState, sequences, params, chunkStart, chunkSize); + if (ZSTD_isError(newLeftoverSize)) + return newLeftoverSize; + /* 4. We add the leftover literals from previous iterations to the first + * newly generated sequence, or add the `newLeftoverSize` if none are + * generated. + */ + /* Prepend the leftover literals from the last call */ + if (prevSize < sequences->size) { + sequences->seq[prevSize].litLength += (U32)leftoverSize; + leftoverSize = newLeftoverSize; + } else { + assert(newLeftoverSize == chunkSize); + leftoverSize += chunkSize; + } + } + return 0; +} + +void +ZSTD_ldm_skipSequences(RawSeqStore_t* rawSeqStore, size_t srcSize, U32 const minMatch) +{ + while (srcSize > 0 && rawSeqStore->pos < rawSeqStore->size) { + rawSeq* seq = rawSeqStore->seq + rawSeqStore->pos; + if (srcSize <= seq->litLength) { + /* Skip past srcSize literals */ + seq->litLength -= (U32)srcSize; + return; + } + srcSize -= seq->litLength; + seq->litLength = 0; + if (srcSize < seq->matchLength) { + /* Skip past the first srcSize of the match */ + seq->matchLength -= (U32)srcSize; + if (seq->matchLength < minMatch) { + /* The match is too short, omit it */ + if (rawSeqStore->pos + 1 < rawSeqStore->size) { + seq[1].litLength += seq[0].matchLength; + } + rawSeqStore->pos++; + } + return; + } + srcSize -= seq->matchLength; + seq->matchLength = 0; + rawSeqStore->pos++; + } +} + +/** + * If the sequence length is longer than remaining then the sequence is split + * between this block and the next. + * + * Returns the current sequence to handle, or if the rest of the block should + * be literals, it returns a sequence with offset == 0. + */ +static rawSeq maybeSplitSequence(RawSeqStore_t* rawSeqStore, + U32 const remaining, U32 const minMatch) +{ + rawSeq sequence = rawSeqStore->seq[rawSeqStore->pos]; + assert(sequence.offset > 0); + /* Likely: No partial sequence */ + if (remaining >= sequence.litLength + sequence.matchLength) { + rawSeqStore->pos++; + return sequence; + } + /* Cut the sequence short (offset == 0 ==> rest is literals). */ + if (remaining <= sequence.litLength) { + sequence.offset = 0; + } else if (remaining < sequence.litLength + sequence.matchLength) { + sequence.matchLength = remaining - sequence.litLength; + if (sequence.matchLength < minMatch) { + sequence.offset = 0; + } + } + /* Skip past `remaining` bytes for the future sequences. */ + ZSTD_ldm_skipSequences(rawSeqStore, remaining, minMatch); + return sequence; +} + +void ZSTD_ldm_skipRawSeqStoreBytes(RawSeqStore_t* rawSeqStore, size_t nbBytes) { + U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes); + while (currPos && rawSeqStore->pos < rawSeqStore->size) { + rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos]; + if (currPos >= currSeq.litLength + currSeq.matchLength) { + currPos -= currSeq.litLength + currSeq.matchLength; + rawSeqStore->pos++; + } else { + rawSeqStore->posInSequence = currPos; + break; + } + } + if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) { + rawSeqStore->posInSequence = 0; + } +} + +size_t ZSTD_ldm_blockCompress(RawSeqStore_t* rawSeqStore, + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + ZSTD_ParamSwitch_e useRowMatchFinder, + void const* src, size_t srcSize) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + unsigned const minMatch = cParams->minMatch; + ZSTD_BlockCompressor_f const blockCompressor = + ZSTD_selectBlockCompressor(cParams->strategy, useRowMatchFinder, ZSTD_matchState_dictMode(ms)); + /* Input bounds */ + BYTE const* const istart = (BYTE const*)src; + BYTE const* const iend = istart + srcSize; + /* Input positions */ + BYTE const* ip = istart; + + DEBUGLOG(5, "ZSTD_ldm_blockCompress: srcSize=%zu", srcSize); + /* If using opt parser, use LDMs only as candidates rather than always accepting them */ + if (cParams->strategy >= ZSTD_btopt) { + size_t lastLLSize; + ms->ldmSeqStore = rawSeqStore; + lastLLSize = blockCompressor(ms, seqStore, rep, src, srcSize); + ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize); + return lastLLSize; + } + + assert(rawSeqStore->pos <= rawSeqStore->size); + assert(rawSeqStore->size <= rawSeqStore->capacity); + /* Loop through each sequence and apply the block compressor to the literals */ + while (rawSeqStore->pos < rawSeqStore->size && ip < iend) { + /* maybeSplitSequence updates rawSeqStore->pos */ + rawSeq const sequence = maybeSplitSequence(rawSeqStore, + (U32)(iend - ip), minMatch); + /* End signal */ + if (sequence.offset == 0) + break; + + assert(ip + sequence.litLength + sequence.matchLength <= iend); + + /* Fill tables for block compressor */ + ZSTD_ldm_limitTableUpdate(ms, ip); + ZSTD_ldm_fillFastTables(ms, ip); + /* Run the block compressor */ + DEBUGLOG(5, "pos %u : calling block compressor on segment of size %u", (unsigned)(ip-istart), sequence.litLength); + { + int i; + size_t const newLitLength = + blockCompressor(ms, seqStore, rep, ip, sequence.litLength); + ip += sequence.litLength; + /* Update the repcodes */ + for (i = ZSTD_REP_NUM - 1; i > 0; i--) + rep[i] = rep[i-1]; + rep[0] = sequence.offset; + /* Store the sequence */ + ZSTD_storeSeq(seqStore, newLitLength, ip - newLitLength, iend, + OFFSET_TO_OFFBASE(sequence.offset), + sequence.matchLength); + ip += sequence.matchLength; + } + } + /* Fill the tables for the block compressor */ + ZSTD_ldm_limitTableUpdate(ms, ip); + ZSTD_ldm_fillFastTables(ms, ip); + /* Compress the last literals */ + return blockCompressor(ms, seqStore, rep, ip, iend - ip); +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_ldm.h b/src/commonlib/bsd/zstd/compress/zstd_ldm.h new file mode 100644 index 0000000000..d69c3648ce --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_ldm.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_LDM_H +#define ZSTD_LDM_H + +#include "zstd_compress_internal.h" /* ldmParams_t, U32 */ +#include "../zstd.h" /* ZSTD_CCtx, size_t */ + +/*-************************************* +* Long distance matching +***************************************/ + +#define ZSTD_LDM_DEFAULT_WINDOW_LOG ZSTD_WINDOWLOG_LIMIT_DEFAULT + +void ZSTD_ldm_fillHashTable( + ldmState_t* state, const BYTE* ip, + const BYTE* iend, ldmParams_t const* params); + +/** + * ZSTD_ldm_generateSequences(): + * + * Generates the sequences using the long distance match finder. + * Generates long range matching sequences in `sequences`, which parse a prefix + * of the source. `sequences` must be large enough to store every sequence, + * which can be checked with `ZSTD_ldm_getMaxNbSeq()`. + * @returns 0 or an error code. + * + * NOTE: The user must have called ZSTD_window_update() for all of the input + * they have, even if they pass it to ZSTD_ldm_generateSequences() in chunks. + * NOTE: This function returns an error if it runs out of space to store + * sequences. + */ +size_t ZSTD_ldm_generateSequences( + ldmState_t* ldms, RawSeqStore_t* sequences, + ldmParams_t const* params, void const* src, size_t srcSize); + +/** + * ZSTD_ldm_blockCompress(): + * + * Compresses a block using the predefined sequences, along with a secondary + * block compressor. The literals section of every sequence is passed to the + * secondary block compressor, and those sequences are interspersed with the + * predefined sequences. Returns the length of the last literals. + * Updates `rawSeqStore.pos` to indicate how many sequences have been consumed. + * `rawSeqStore.seq` may also be updated to split the last sequence between two + * blocks. + * @return The length of the last literals. + * + * NOTE: The source must be at most the maximum block size, but the predefined + * sequences can be any size, and may be longer than the block. In the case that + * they are longer than the block, the last sequences may need to be split into + * two. We handle that case correctly, and update `rawSeqStore` appropriately. + * NOTE: This function does not return any errors. + */ +size_t ZSTD_ldm_blockCompress(RawSeqStore_t* rawSeqStore, + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + ZSTD_ParamSwitch_e useRowMatchFinder, + void const* src, size_t srcSize); + +/** + * ZSTD_ldm_skipSequences(): + * + * Skip past `srcSize` bytes worth of sequences in `rawSeqStore`. + * Avoids emitting matches less than `minMatch` bytes. + * Must be called for data that is not passed to ZSTD_ldm_blockCompress(). + */ +void ZSTD_ldm_skipSequences(RawSeqStore_t* rawSeqStore, size_t srcSize, + U32 const minMatch); + +/* ZSTD_ldm_skipRawSeqStoreBytes(): + * Moves forward in rawSeqStore by nbBytes, updating fields 'pos' and 'posInSequence'. + * Not to be used in conjunction with ZSTD_ldm_skipSequences(). + * Must be called for data with is not passed to ZSTD_ldm_blockCompress(). + */ +void ZSTD_ldm_skipRawSeqStoreBytes(RawSeqStore_t* rawSeqStore, size_t nbBytes); + +/** ZSTD_ldm_getTableSize() : + * Estimate the space needed for long distance matching tables or 0 if LDM is + * disabled. + */ +size_t ZSTD_ldm_getTableSize(ldmParams_t params); + +/** ZSTD_ldm_getSeqSpace() : + * Return an upper bound on the number of sequences that can be produced by + * the long distance matcher, or 0 if LDM is disabled. + */ +size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize); + +/** ZSTD_ldm_adjustParameters() : + * If the params->hashRateLog is not set, set it to its default value based on + * windowLog and params->hashLog. + * + * Ensures that params->bucketSizeLog is <= params->hashLog (setting it to + * params->hashLog if it is not). + * + * Ensures that the minMatchLength >= targetLength during optimal parsing. + */ +void ZSTD_ldm_adjustParameters(ldmParams_t* params, + ZSTD_compressionParameters const* cParams); + +#endif /* ZSTD_FAST_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_ldm_geartab.h b/src/commonlib/bsd/zstd/compress/zstd_ldm_geartab.h new file mode 100644 index 0000000000..be292bb256 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_ldm_geartab.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_LDM_GEARTAB_H +#define ZSTD_LDM_GEARTAB_H + +#include "../common/zstd_compiler.h" /* UNUSED_ATTR */ +#include "../common/mem.h" /* U64 */ + +static UNUSED_ATTR const U64 ZSTD_ldm_gearTab[256] = { + 0xf5b8f72c5f77775c, 0x84935f266b7ac412, 0xb647ada9ca730ccc, + 0xb065bb4b114fb1de, 0x34584e7e8c3a9fd0, 0x4e97e17c6ae26b05, + 0x3a03d743bc99a604, 0xcecd042422c4044f, 0x76de76c58524259e, + 0x9c8528f65badeaca, 0x86563706e2097529, 0x2902475fa375d889, + 0xafb32a9739a5ebe6, 0xce2714da3883e639, 0x21eaf821722e69e, + 0x37b628620b628, 0x49a8d455d88caf5, 0x8556d711e6958140, + 0x4f7ae74fc605c1f, 0x829f0c3468bd3a20, 0x4ffdc885c625179e, + 0x8473de048a3daf1b, 0x51008822b05646b2, 0x69d75d12b2d1cc5f, + 0x8c9d4a19159154bc, 0xc3cc10f4abbd4003, 0xd06ddc1cecb97391, + 0xbe48e6e7ed80302e, 0x3481db31cee03547, 0xacc3f67cdaa1d210, + 0x65cb771d8c7f96cc, 0x8eb27177055723dd, 0xc789950d44cd94be, + 0x934feadc3700b12b, 0x5e485f11edbdf182, 0x1e2e2a46fd64767a, + 0x2969ca71d82efa7c, 0x9d46e9935ebbba2e, 0xe056b67e05e6822b, + 0x94d73f55739d03a0, 0xcd7010bdb69b5a03, 0x455ef9fcd79b82f4, + 0x869cb54a8749c161, 0x38d1a4fa6185d225, 0xb475166f94bbe9bb, + 0xa4143548720959f1, 0x7aed4780ba6b26ba, 0xd0ce264439e02312, + 0x84366d746078d508, 0xa8ce973c72ed17be, 0x21c323a29a430b01, + 0x9962d617e3af80ee, 0xab0ce91d9c8cf75b, 0x530e8ee6d19a4dbc, + 0x2ef68c0cf53f5d72, 0xc03a681640a85506, 0x496e4e9f9c310967, + 0x78580472b59b14a0, 0x273824c23b388577, 0x66bf923ad45cb553, + 0x47ae1a5a2492ba86, 0x35e304569e229659, 0x4765182a46870b6f, + 0x6cbab625e9099412, 0xddac9a2e598522c1, 0x7172086e666624f2, + 0xdf5003ca503b7837, 0x88c0c1db78563d09, 0x58d51865acfc289d, + 0x177671aec65224f1, 0xfb79d8a241e967d7, 0x2be1e101cad9a49a, + 0x6625682f6e29186b, 0x399553457ac06e50, 0x35dffb4c23abb74, + 0x429db2591f54aade, 0xc52802a8037d1009, 0x6acb27381f0b25f3, + 0xf45e2551ee4f823b, 0x8b0ea2d99580c2f7, 0x3bed519cbcb4e1e1, + 0xff452823dbb010a, 0x9d42ed614f3dd267, 0x5b9313c06257c57b, + 0xa114b8008b5e1442, 0xc1fe311c11c13d4b, 0x66e8763ea34c5568, + 0x8b982af1c262f05d, 0xee8876faaa75fbb7, 0x8a62a4d0d172bb2a, + 0xc13d94a3b7449a97, 0x6dbbba9dc15d037c, 0xc786101f1d92e0f1, + 0xd78681a907a0b79b, 0xf61aaf2962c9abb9, 0x2cfd16fcd3cb7ad9, + 0x868c5b6744624d21, 0x25e650899c74ddd7, 0xba042af4a7c37463, + 0x4eb1a539465a3eca, 0xbe09dbf03b05d5ca, 0x774e5a362b5472ba, + 0x47a1221229d183cd, 0x504b0ca18ef5a2df, 0xdffbdfbde2456eb9, + 0x46cd2b2fbee34634, 0xf2aef8fe819d98c3, 0x357f5276d4599d61, + 0x24a5483879c453e3, 0x88026889192b4b9, 0x28da96671782dbec, + 0x4ef37c40588e9aaa, 0x8837b90651bc9fb3, 0xc164f741d3f0e5d6, + 0xbc135a0a704b70ba, 0x69cd868f7622ada, 0xbc37ba89e0b9c0ab, + 0x47c14a01323552f6, 0x4f00794bacee98bb, 0x7107de7d637a69d5, + 0x88af793bb6f2255e, 0xf3c6466b8799b598, 0xc288c616aa7f3b59, + 0x81ca63cf42fca3fd, 0x88d85ace36a2674b, 0xd056bd3792389e7, + 0xe55c396c4e9dd32d, 0xbefb504571e6c0a6, 0x96ab32115e91e8cc, + 0xbf8acb18de8f38d1, 0x66dae58801672606, 0x833b6017872317fb, + 0xb87c16f2d1c92864, 0xdb766a74e58b669c, 0x89659f85c61417be, + 0xc8daad856011ea0c, 0x76a4b565b6fe7eae, 0xa469d085f6237312, + 0xaaf0365683a3e96c, 0x4dbb746f8424f7b8, 0x638755af4e4acc1, + 0x3d7807f5bde64486, 0x17be6d8f5bbb7639, 0x903f0cd44dc35dc, + 0x67b672eafdf1196c, 0xa676ff93ed4c82f1, 0x521d1004c5053d9d, + 0x37ba9ad09ccc9202, 0x84e54d297aacfb51, 0xa0b4b776a143445, + 0x820d471e20b348e, 0x1874383cb83d46dc, 0x97edeec7a1efe11c, + 0xb330e50b1bdc42aa, 0x1dd91955ce70e032, 0xa514cdb88f2939d5, + 0x2791233fd90db9d3, 0x7b670a4cc50f7a9b, 0x77c07d2a05c6dfa5, + 0xe3778b6646d0a6fa, 0xb39c8eda47b56749, 0x933ed448addbef28, + 0xaf846af6ab7d0bf4, 0xe5af208eb666e49, 0x5e6622f73534cd6a, + 0x297daeca42ef5b6e, 0x862daef3d35539a6, 0xe68722498f8e1ea9, + 0x981c53093dc0d572, 0xfa09b0bfbf86fbf5, 0x30b1e96166219f15, + 0x70e7d466bdc4fb83, 0x5a66736e35f2a8e9, 0xcddb59d2b7c1baef, + 0xd6c7d247d26d8996, 0xea4e39eac8de1ba3, 0x539c8bb19fa3aff2, + 0x9f90e4c5fd508d8, 0xa34e5956fbaf3385, 0x2e2f8e151d3ef375, + 0x173691e9b83faec1, 0xb85a8d56bf016379, 0x8382381267408ae3, + 0xb90f901bbdc0096d, 0x7c6ad32933bcec65, 0x76bb5e2f2c8ad595, + 0x390f851a6cf46d28, 0xc3e6064da1c2da72, 0xc52a0c101cfa5389, + 0xd78eaf84a3fbc530, 0x3781b9e2288b997e, 0x73c2f6dea83d05c4, + 0x4228e364c5b5ed7, 0x9d7a3edf0da43911, 0x8edcfeda24686756, + 0x5e7667a7b7a9b3a1, 0x4c4f389fa143791d, 0xb08bc1023da7cddc, + 0x7ab4be3ae529b1cc, 0x754e6132dbe74ff9, 0x71635442a839df45, + 0x2f6fb1643fbe52de, 0x961e0a42cf7a8177, 0xf3b45d83d89ef2ea, + 0xee3de4cf4a6e3e9b, 0xcd6848542c3295e7, 0xe4cee1664c78662f, + 0x9947548b474c68c4, 0x25d73777a5ed8b0b, 0xc915b1d636b7fc, + 0x21c2ba75d9b0d2da, 0x5f6b5dcf608a64a1, 0xdcf333255ff9570c, + 0x633b922418ced4ee, 0xc136dde0b004b34a, 0x58cc83b05d4b2f5a, + 0x5eb424dda28e42d2, 0x62df47369739cd98, 0xb4e0b42485e4ce17, + 0x16e1f0c1f9a8d1e7, 0x8ec3916707560ebf, 0x62ba6e2df2cc9db3, + 0xcbf9f4ff77d83a16, 0x78d9d7d07d2bbcc4, 0xef554ce1e02c41f4, + 0x8d7581127eccf94d, 0xa9b53336cb3c8a05, 0x38c42c0bf45c4f91, + 0x640893cdf4488863, 0x80ec34bc575ea568, 0x39f324f5b48eaa40, + 0xe9d9ed1f8eff527f, 0x9224fc058cc5a214, 0xbaba00b04cfe7741, + 0x309a9f120fcf52af, 0xa558f3ec65626212, 0x424bec8b7adabe2f, + 0x41622513a6aea433, 0xb88da2d5324ca798, 0xd287733b245528a4, + 0x9a44697e6d68aec3, 0x7b1093be2f49bb28, 0x50bbec632e3d8aad, + 0x6cd90723e1ea8283, 0x897b9e7431b02bf3, 0x219efdcb338a7047, + 0x3b0311f0a27c0656, 0xdb17bf91c0db96e7, 0x8cd4fd6b4e85a5b2, + 0xfab071054ba6409d, 0x40d6fe831fa9dfd9, 0xaf358debad7d791e, + 0xeb8d0e25a65e3e58, 0xbbcbd3df14e08580, 0xcf751f27ecdab2b, + 0x2b4da14f2613d8f4 +}; + +#endif /* ZSTD_LDM_GEARTAB_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_opt.c b/src/commonlib/bsd/zstd/compress/zstd_opt.c new file mode 100644 index 0000000000..519091b82d --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_opt.c @@ -0,0 +1,1582 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" +#include "hist.h" +#include "zstd_opt.h" + +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) + +#define ZSTD_LITFREQ_ADD 2 /* scaling factor for litFreq, so that frequencies adapt faster to new stats */ +#define ZSTD_MAX_PRICE (1<<30) + +#define ZSTD_PREDEF_THRESHOLD 8 /* if srcSize < ZSTD_PREDEF_THRESHOLD, symbols' cost is assumed static, directly determined by pre-defined distributions */ + + +/*-************************************* +* Price functions for optimal parser +***************************************/ + +#if 0 /* approximation at bit level (for tests) */ +# define BITCOST_ACCURACY 0 +# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) +# define WEIGHT(stat, opt) ((void)(opt), ZSTD_bitWeight(stat)) +#elif 0 /* fractional bit accuracy (for tests) */ +# define BITCOST_ACCURACY 8 +# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) +# define WEIGHT(stat,opt) ((void)(opt), ZSTD_fracWeight(stat)) +#else /* opt==approx, ultra==accurate */ +# define BITCOST_ACCURACY 8 +# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) +# define WEIGHT(stat,opt) ((opt) ? ZSTD_fracWeight(stat) : ZSTD_bitWeight(stat)) +#endif + +/* ZSTD_bitWeight() : + * provide estimated "cost" of a stat in full bits only */ +MEM_STATIC U32 ZSTD_bitWeight(U32 stat) +{ + return (ZSTD_highbit32(stat+1) * BITCOST_MULTIPLIER); +} + +/* ZSTD_fracWeight() : + * provide fractional-bit "cost" of a stat, + * using linear interpolation approximation */ +MEM_STATIC U32 ZSTD_fracWeight(U32 rawStat) +{ + U32 const stat = rawStat + 1; + U32 const hb = ZSTD_highbit32(stat); + U32 const BWeight = hb * BITCOST_MULTIPLIER; + /* Fweight was meant for "Fractional weight" + * but it's effectively a value between 1 and 2 + * using fixed point arithmetic */ + U32 const FWeight = (stat << BITCOST_ACCURACY) >> hb; + U32 const weight = BWeight + FWeight; + assert(hb + BITCOST_ACCURACY < 31); + return weight; +} + +#if (DEBUGLEVEL>=2) +/* debugging function, + * @return price in bytes as fractional value + * for debug messages only */ +MEM_STATIC double ZSTD_fCost(int price) +{ + return (double)price / (BITCOST_MULTIPLIER*8); +} +#endif + +static int ZSTD_compressedLiterals(optState_t const* const optPtr) +{ + return optPtr->literalCompressionMode != ZSTD_ps_disable; +} + +static void ZSTD_setBasePrices(optState_t* optPtr, int optLevel) +{ + if (ZSTD_compressedLiterals(optPtr)) + optPtr->litSumBasePrice = WEIGHT(optPtr->litSum, optLevel); + optPtr->litLengthSumBasePrice = WEIGHT(optPtr->litLengthSum, optLevel); + optPtr->matchLengthSumBasePrice = WEIGHT(optPtr->matchLengthSum, optLevel); + optPtr->offCodeSumBasePrice = WEIGHT(optPtr->offCodeSum, optLevel); +} + + +static U32 sum_u32(const unsigned table[], size_t nbElts) +{ + size_t n; + U32 total = 0; + for (n=0; n0); + unsigned const newStat = base + (table[s] >> shift); + sum += newStat; + table[s] = newStat; + } + return sum; +} + +/* ZSTD_scaleStats() : + * reduce all elt frequencies in table if sum too large + * return the resulting sum of elements */ +static U32 ZSTD_scaleStats(unsigned* table, U32 lastEltIndex, U32 logTarget) +{ + U32 const prevsum = sum_u32(table, lastEltIndex+1); + U32 const factor = prevsum >> logTarget; + DEBUGLOG(5, "ZSTD_scaleStats (nbElts=%u, target=%u)", (unsigned)lastEltIndex+1, (unsigned)logTarget); + assert(logTarget < 30); + if (factor <= 1) return prevsum; + return ZSTD_downscaleStats(table, lastEltIndex, ZSTD_highbit32(factor), base_1guaranteed); +} + +/* ZSTD_rescaleFreqs() : + * if first block (detected by optPtr->litLengthSum == 0) : init statistics + * take hints from dictionary if there is one + * and init from zero if there is none, + * using src for literals stats, and baseline stats for sequence symbols + * otherwise downscale existing stats, to be used as seed for next block. + */ +static void +ZSTD_rescaleFreqs(optState_t* const optPtr, + const BYTE* const src, size_t const srcSize, + int const optLevel) +{ + int const compressedLiterals = ZSTD_compressedLiterals(optPtr); + DEBUGLOG(5, "ZSTD_rescaleFreqs (srcSize=%u)", (unsigned)srcSize); + optPtr->priceType = zop_dynamic; + + if (optPtr->litLengthSum == 0) { /* no literals stats collected -> first block assumed -> init */ + + /* heuristic: use pre-defined stats for too small inputs */ + if (srcSize <= ZSTD_PREDEF_THRESHOLD) { + DEBUGLOG(5, "srcSize <= %i : use predefined stats", ZSTD_PREDEF_THRESHOLD); + optPtr->priceType = zop_predef; + } + + assert(optPtr->symbolCosts != NULL); + if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) { + + /* huffman stats covering the full value set : table presumed generated by dictionary */ + optPtr->priceType = zop_dynamic; + + if (compressedLiterals) { + /* generate literals statistics from huffman table */ + unsigned lit; + assert(optPtr->litFreq != NULL); + optPtr->litSum = 0; + for (lit=0; lit<=MaxLit; lit++) { + U32 const scaleLog = 11; /* scale to 2K */ + U32 const bitCost = HUF_getNbBitsFromCTable(optPtr->symbolCosts->huf.CTable, lit); + assert(bitCost <= scaleLog); + optPtr->litFreq[lit] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->litSum += optPtr->litFreq[lit]; + } } + + { unsigned ll; + FSE_CState_t llstate; + FSE_initCState(&llstate, optPtr->symbolCosts->fse.litlengthCTable); + optPtr->litLengthSum = 0; + for (ll=0; ll<=MaxLL; ll++) { + U32 const scaleLog = 10; /* scale to 1K */ + U32 const bitCost = FSE_getMaxNbBits(llstate.symbolTT, ll); + assert(bitCost < scaleLog); + optPtr->litLengthFreq[ll] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->litLengthSum += optPtr->litLengthFreq[ll]; + } } + + { unsigned ml; + FSE_CState_t mlstate; + FSE_initCState(&mlstate, optPtr->symbolCosts->fse.matchlengthCTable); + optPtr->matchLengthSum = 0; + for (ml=0; ml<=MaxML; ml++) { + U32 const scaleLog = 10; + U32 const bitCost = FSE_getMaxNbBits(mlstate.symbolTT, ml); + assert(bitCost < scaleLog); + optPtr->matchLengthFreq[ml] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->matchLengthSum += optPtr->matchLengthFreq[ml]; + } } + + { unsigned of; + FSE_CState_t ofstate; + FSE_initCState(&ofstate, optPtr->symbolCosts->fse.offcodeCTable); + optPtr->offCodeSum = 0; + for (of=0; of<=MaxOff; of++) { + U32 const scaleLog = 10; + U32 const bitCost = FSE_getMaxNbBits(ofstate.symbolTT, of); + assert(bitCost < scaleLog); + optPtr->offCodeFreq[of] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->offCodeSum += optPtr->offCodeFreq[of]; + } } + + } else { /* first block, no dictionary */ + + assert(optPtr->litFreq != NULL); + if (compressedLiterals) { + /* base initial cost of literals on direct frequency within src */ + unsigned lit = MaxLit; + HIST_count_simple(optPtr->litFreq, &lit, src, srcSize); /* use raw first block to init statistics */ + optPtr->litSum = ZSTD_downscaleStats(optPtr->litFreq, MaxLit, 8, base_0possible); + } + + { unsigned const baseLLfreqs[MaxLL+1] = { + 4, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1 + }; + ZSTD_memcpy(optPtr->litLengthFreq, baseLLfreqs, sizeof(baseLLfreqs)); + optPtr->litLengthSum = sum_u32(baseLLfreqs, MaxLL+1); + } + + { unsigned ml; + for (ml=0; ml<=MaxML; ml++) + optPtr->matchLengthFreq[ml] = 1; + } + optPtr->matchLengthSum = MaxML+1; + + { unsigned const baseOFCfreqs[MaxOff+1] = { + 6, 2, 1, 1, 2, 3, 4, 4, + 4, 3, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 + }; + ZSTD_memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs)); + optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1); + } + + } + + } else { /* new block : scale down accumulated statistics */ + + if (compressedLiterals) + optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 12); + optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 11); + optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 11); + optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 11); + } + + ZSTD_setBasePrices(optPtr, optLevel); +} + +/* ZSTD_rawLiteralsCost() : + * price of literals (only) in specified segment (which length can be 0). + * does not include price of literalLength symbol */ +static U32 ZSTD_rawLiteralsCost(const BYTE* const literals, U32 const litLength, + const optState_t* const optPtr, + int optLevel) +{ + DEBUGLOG(8, "ZSTD_rawLiteralsCost (%u literals)", litLength); + if (litLength == 0) return 0; + + if (!ZSTD_compressedLiterals(optPtr)) + return (litLength << 3) * BITCOST_MULTIPLIER; /* Uncompressed - 8 bytes per literal. */ + + if (optPtr->priceType == zop_predef) + return (litLength*6) * BITCOST_MULTIPLIER; /* 6 bit per literal - no statistic used */ + + /* dynamic statistics */ + { U32 price = optPtr->litSumBasePrice * litLength; + U32 const litPriceMax = optPtr->litSumBasePrice - BITCOST_MULTIPLIER; + U32 u; + assert(optPtr->litSumBasePrice >= BITCOST_MULTIPLIER); + for (u=0; u < litLength; u++) { + U32 litPrice = WEIGHT(optPtr->litFreq[literals[u]], optLevel); + if (UNLIKELY(litPrice > litPriceMax)) litPrice = litPriceMax; + price -= litPrice; + } + return price; + } +} + +/* ZSTD_litLengthPrice() : + * cost of literalLength symbol */ +static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optPtr, int optLevel) +{ + assert(litLength <= ZSTD_BLOCKSIZE_MAX); + if (optPtr->priceType == zop_predef) + return WEIGHT(litLength, optLevel); + + /* ZSTD_LLcode() can't compute litLength price for sizes >= ZSTD_BLOCKSIZE_MAX + * because it isn't representable in the zstd format. + * So instead just pretend it would cost 1 bit more than ZSTD_BLOCKSIZE_MAX - 1. + * In such a case, the block would be all literals. + */ + if (litLength == ZSTD_BLOCKSIZE_MAX) + return BITCOST_MULTIPLIER + ZSTD_litLengthPrice(ZSTD_BLOCKSIZE_MAX - 1, optPtr, optLevel); + + /* dynamic statistics */ + { U32 const llCode = ZSTD_LLcode(litLength); + return (LL_bits[llCode] * BITCOST_MULTIPLIER) + + optPtr->litLengthSumBasePrice + - WEIGHT(optPtr->litLengthFreq[llCode], optLevel); + } +} + +/* ZSTD_getMatchPrice() : + * Provides the cost of the match part (offset + matchLength) of a sequence. + * Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence. + * @offBase : sumtype, representing an offset or a repcode, and using numeric representation of ZSTD_storeSeq() + * @optLevel: when <2, favors small offset for decompression speed (improved cache efficiency) + */ +FORCE_INLINE_TEMPLATE U32 +ZSTD_getMatchPrice(U32 const offBase, + U32 const matchLength, + const optState_t* const optPtr, + int const optLevel) +{ + U32 price; + U32 const offCode = ZSTD_highbit32(offBase); + U32 const mlBase = matchLength - MINMATCH; + assert(matchLength >= MINMATCH); + + if (optPtr->priceType == zop_predef) /* fixed scheme, does not use statistics */ + return WEIGHT(mlBase, optLevel) + + ((16 + offCode) * BITCOST_MULTIPLIER); /* emulated offset cost */ + + /* dynamic statistics */ + price = (offCode * BITCOST_MULTIPLIER) + (optPtr->offCodeSumBasePrice - WEIGHT(optPtr->offCodeFreq[offCode], optLevel)); + if ((optLevel<2) /*static*/ && offCode >= 20) + price += (offCode-19)*2 * BITCOST_MULTIPLIER; /* handicap for long distance offsets, favor decompression speed */ + + /* match Length */ + { U32 const mlCode = ZSTD_MLcode(mlBase); + price += (ML_bits[mlCode] * BITCOST_MULTIPLIER) + (optPtr->matchLengthSumBasePrice - WEIGHT(optPtr->matchLengthFreq[mlCode], optLevel)); + } + + price += BITCOST_MULTIPLIER / 5; /* heuristic : make matches a bit more costly to favor less sequences -> faster decompression speed */ + + DEBUGLOG(8, "ZSTD_getMatchPrice(ml:%u) = %u", matchLength, price); + return price; +} + +/* ZSTD_updateStats() : + * assumption : literals + litLength <= iend */ +static void ZSTD_updateStats(optState_t* const optPtr, + U32 litLength, const BYTE* literals, + U32 offBase, U32 matchLength) +{ + /* literals */ + if (ZSTD_compressedLiterals(optPtr)) { + U32 u; + for (u=0; u < litLength; u++) + optPtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD; + optPtr->litSum += litLength*ZSTD_LITFREQ_ADD; + } + + /* literal Length */ + { U32 const llCode = ZSTD_LLcode(litLength); + optPtr->litLengthFreq[llCode]++; + optPtr->litLengthSum++; + } + + /* offset code : follows storeSeq() numeric representation */ + { U32 const offCode = ZSTD_highbit32(offBase); + assert(offCode <= MaxOff); + optPtr->offCodeFreq[offCode]++; + optPtr->offCodeSum++; + } + + /* match Length */ + { U32 const mlBase = matchLength - MINMATCH; + U32 const mlCode = ZSTD_MLcode(mlBase); + optPtr->matchLengthFreq[mlCode]++; + optPtr->matchLengthSum++; + } +} + + +/* ZSTD_readMINMATCH() : + * function safe only for comparisons + * assumption : memPtr must be at least 4 bytes before end of buffer */ +MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length) +{ + switch (length) + { + default : + case 4 : return MEM_read32(memPtr); + case 3 : if (MEM_isLittleEndian()) + return MEM_read32(memPtr)<<8; + else + return MEM_read32(memPtr)>>8; + } +} + + +/* Update hashTable3 up to ip (excluded) + Assumption : always within prefix (i.e. not within extDict) */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertAndFindFirstIndexHash3 (const ZSTD_MatchState_t* ms, + U32* nextToUpdate3, + const BYTE* const ip) +{ + U32* const hashTable3 = ms->hashTable3; + U32 const hashLog3 = ms->hashLog3; + const BYTE* const base = ms->window.base; + U32 idx = *nextToUpdate3; + U32 const target = (U32)(ip - base); + size_t const hash3 = ZSTD_hash3Ptr(ip, hashLog3); + assert(hashLog3 > 0); + + while(idx < target) { + hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx; + idx++; + } + + *nextToUpdate3 = target; + return hashTable3[hash3]; +} + + +/*-************************************* +* Binary Tree search +***************************************/ +/** ZSTD_insertBt1() : add one or multiple positions to tree. + * @param ip assumed <= iend-8 . + * @param target The target of ZSTD_updateTree_internal() - we are filling to this position + * @return : nb of positions added */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertBt1( + const ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + U32 const target, + U32 const mls, const int extDict) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hashLog = cParams->hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 matchIndex = hashTable[h]; + size_t commonLengthSmaller=0, commonLengthLarger=0; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* match; + const U32 curr = (U32)(ip-base); + const U32 btLow = btMask >= curr ? 0 : curr - btMask; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = smallerPtr + 1; + U32 dummy32; /* to be nullified at the end */ + /* windowLow is based on target because + * we only need positions that will be in the window at the end of the tree update. + */ + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, target, cParams->windowLog); + U32 matchEndIdx = curr+8+1; + size_t bestLength = 8; + U32 nbCompares = 1U << cParams->searchLog; +#ifdef ZSTD_C_PREDICT + U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0); + U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1); + predictedSmall += (predictedSmall>0); + predictedLarge += (predictedLarge>0); +#endif /* ZSTD_C_PREDICT */ + + DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr); + + assert(curr <= target); + assert(ip <= iend-8); /* required for h calculation */ + hashTable[h] = curr; /* Update Hash Table */ + + assert(windowLow > 0); + for (; nbCompares && (matchIndex >= windowLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + assert(matchIndex < curr); + +#ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */ + const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */ + if (matchIndex == predictedSmall) { + /* no need to check length, result known */ + *smallerPtr = matchIndex; + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + predictedSmall = predictPtr[1] + (predictPtr[1]>0); + continue; + } + if (matchIndex == predictedLarge) { + *largerPtr = matchIndex; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + predictedLarge = predictPtr[0] + (predictPtr[0]>0); + continue; + } +#endif + + if (!extDict || (matchIndex+matchLength >= dictLimit)) { + assert(matchIndex+matchLength >= dictLimit); /* might be wrong if actually extDict */ + match = base + matchIndex; + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + } + + if (matchLength > bestLength) { + bestLength = matchLength; + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + } + + if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ + break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */ + } + + if (match[matchLength] < ip[matchLength]) { /* necessarily within buffer */ + /* match is smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + smallerPtr = nextPtr+1; /* new "candidate" => larger than match, which was smaller than target */ + matchIndex = nextPtr[1]; /* new matchIndex, larger than previous and closer to current */ + } else { + /* match is larger than current */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; + { U32 positions = 0; + if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384)); /* speed optimization */ + assert(matchEndIdx > curr + 8); + return MAX(positions, matchEndIdx - (curr + 8)); + } +} + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_updateTree_internal( + ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + const U32 mls, const ZSTD_dictMode_e dictMode) +{ + const BYTE* const base = ms->window.base; + U32 const target = (U32)(ip - base); + U32 idx = ms->nextToUpdate; + DEBUGLOG(7, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)", + idx, target, dictMode); + + while(idx < target) { + U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, target, mls, dictMode == ZSTD_extDict); + assert(idx < (U32)(idx + forward)); + idx += forward; + } + assert((size_t)(ip - base) <= (size_t)(U32)(-1)); + assert((size_t)(iend - base) <= (size_t)(U32)(-1)); + ms->nextToUpdate = target; +} + +void ZSTD_updateTree(ZSTD_MatchState_t* ms, const BYTE* ip, const BYTE* iend) { + ZSTD_updateTree_internal(ms, ip, iend, ms->cParams.minMatch, ZSTD_noDict); +} + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 +ZSTD_insertBtAndGetAllMatches ( + ZSTD_match_t* matches, /* store result (found matches) in this table (presumed large enough) */ + ZSTD_MatchState_t* ms, + U32* nextToUpdate3, + const BYTE* const ip, const BYTE* const iLimit, + const ZSTD_dictMode_e dictMode, + const U32 rep[ZSTD_REP_NUM], + const U32 ll0, /* tells if associated literal length is 0 or not. This value must be 0 or 1 */ + const U32 lengthToBeat, + const U32 mls /* template */) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1); + const BYTE* const base = ms->window.base; + U32 const curr = (U32)(ip-base); + U32 const hashLog = cParams->hashLog; + U32 const minMatch = (mls==3) ? 3 : 4; + U32* const hashTable = ms->hashTable; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 matchIndex = hashTable[h]; + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask= (1U << btLog) - 1; + size_t commonLengthSmaller=0, commonLengthLarger=0; + const BYTE* const dictBase = ms->window.dictBase; + U32 const dictLimit = ms->window.dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + U32 const btLow = (btMask >= curr) ? 0 : curr - btMask; + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog); + U32 const matchLow = windowLow ? windowLow : 1; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = bt + 2*(curr&btMask) + 1; + U32 matchEndIdx = curr+8+1; /* farthest referenced position of any match => detects repetitive patterns */ + U32 dummy32; /* to be nullified at the end */ + U32 mnum = 0; + U32 nbCompares = 1U << cParams->searchLog; + + const ZSTD_MatchState_t* dms = dictMode == ZSTD_dictMatchState ? ms->dictMatchState : NULL; + const ZSTD_compressionParameters* const dmsCParams = + dictMode == ZSTD_dictMatchState ? &dms->cParams : NULL; + const BYTE* const dmsBase = dictMode == ZSTD_dictMatchState ? dms->window.base : NULL; + const BYTE* const dmsEnd = dictMode == ZSTD_dictMatchState ? dms->window.nextSrc : NULL; + U32 const dmsHighLimit = dictMode == ZSTD_dictMatchState ? (U32)(dmsEnd - dmsBase) : 0; + U32 const dmsLowLimit = dictMode == ZSTD_dictMatchState ? dms->window.lowLimit : 0; + U32 const dmsIndexDelta = dictMode == ZSTD_dictMatchState ? windowLow - dmsHighLimit : 0; + U32 const dmsHashLog = dictMode == ZSTD_dictMatchState ? dmsCParams->hashLog : hashLog; + U32 const dmsBtLog = dictMode == ZSTD_dictMatchState ? dmsCParams->chainLog - 1 : btLog; + U32 const dmsBtMask = dictMode == ZSTD_dictMatchState ? (1U << dmsBtLog) - 1 : 0; + U32 const dmsBtLow = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit; + + size_t bestLength = lengthToBeat-1; + DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", curr); + + /* check repCode */ + assert(ll0 <= 1); /* necessarily 1 or 0 */ + { U32 const lastR = ZSTD_REP_NUM + ll0; + U32 repCode; + for (repCode = ll0; repCode < lastR; repCode++) { + U32 const repOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode]; + U32 const repIndex = curr - repOffset; + U32 repLen = 0; + assert(curr >= dictLimit); + if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < curr-dictLimit) { /* equivalent to `curr > repIndex >= dictLimit` */ + /* We must validate the repcode offset because when we're using a dictionary the + * valid offset range shrinks when the dictionary goes out of bounds. + */ + if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) { + repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch; + } + } else { /* repIndex < dictLimit || repIndex >= curr */ + const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ? + dmsBase + repIndex - dmsIndexDelta : + dictBase + repIndex; + assert(curr >= windowLow); + if ( dictMode == ZSTD_extDict + && ( ((repOffset-1) /*intentional overflow*/ < curr - windowLow) /* equivalent to `curr > repIndex >= windowLow` */ + & (ZSTD_index_overlap_check(dictLimit, repIndex)) ) + && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) { + repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch; + } + if (dictMode == ZSTD_dictMatchState + && ( ((repOffset-1) /*intentional overflow*/ < curr - (dmsLowLimit + dmsIndexDelta)) /* equivalent to `curr > repIndex >= dmsLowLimit` */ + & (ZSTD_index_overlap_check(dictLimit, repIndex)) ) + && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) { + repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch; + } } + /* save longer solution */ + if (repLen > bestLength) { + DEBUGLOG(8, "found repCode %u (ll0:%u, offset:%u) of length %u", + repCode, ll0, repOffset, repLen); + bestLength = repLen; + matches[mnum].off = REPCODE_TO_OFFBASE(repCode - ll0 + 1); /* expect value between 1 and 3 */ + matches[mnum].len = (U32)repLen; + mnum++; + if ( (repLen > sufficient_len) + | (ip+repLen == iLimit) ) { /* best possible */ + return mnum; + } } } } + + /* HC3 match finder */ + if ((mls == 3) /*static*/ && (bestLength < mls)) { + U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip); + if ((matchIndex3 >= matchLow) + & (curr - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) { + size_t mlen; + if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) { + const BYTE* const match = base + matchIndex3; + mlen = ZSTD_count(ip, match, iLimit); + } else { + const BYTE* const match = dictBase + matchIndex3; + mlen = ZSTD_count_2segments(ip, match, iLimit, dictEnd, prefixStart); + } + + /* save best solution */ + if (mlen >= mls /* == 3 > bestLength */) { + DEBUGLOG(8, "found small match with hlog3, of length %u", + (U32)mlen); + bestLength = mlen; + assert(curr > matchIndex3); + assert(mnum==0); /* no prior solution */ + matches[0].off = OFFSET_TO_OFFBASE(curr - matchIndex3); + matches[0].len = (U32)mlen; + mnum = 1; + if ( (mlen > sufficient_len) | + (ip+mlen == iLimit) ) { /* best possible length */ + ms->nextToUpdate = curr+1; /* skip insertion */ + return 1; + } } } + /* no dictMatchState lookup: dicts don't have a populated HC3 table */ + } /* if (mls == 3) */ + + hashTable[h] = curr; /* Update Hash Table */ + + for (; nbCompares && (matchIndex >= matchLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + const BYTE* match; + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + assert(curr > matchIndex); + + if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) { + assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */ + match = base + matchIndex; + if (matchIndex >= dictLimit) assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */ + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit); + } else { + match = dictBase + matchIndex; + assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */ + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* prepare for match[matchLength] read */ + } + + if (matchLength > bestLength) { + DEBUGLOG(8, "found match of length %u at distance %u (offBase=%u)", + (U32)matchLength, curr - matchIndex, OFFSET_TO_OFFBASE(curr - matchIndex)); + assert(matchEndIdx > matchIndex); + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + bestLength = matchLength; + matches[mnum].off = OFFSET_TO_OFFBASE(curr - matchIndex); + matches[mnum].len = (U32)matchLength; + mnum++; + if ( (matchLength > ZSTD_OPT_NUM) + | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) { + if (dictMode == ZSTD_dictMatchState) nbCompares = 0; /* break should also skip searching dms */ + break; /* drop, to preserve bt consistency (miss a little bit of compression) */ + } } + + if (match[matchLength] < ip[matchLength]) { + /* match smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + smallerPtr = nextPtr+1; /* new candidate => larger than match, which was smaller than current */ + matchIndex = nextPtr[1]; /* new matchIndex, larger than previous, closer to current */ + } else { + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; + + assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dictMatchState && nbCompares) { + size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls); + U32 dictMatchIndex = dms->hashTable[dmsH]; + const U32* const dmsBt = dms->chainTable; + commonLengthSmaller = commonLengthLarger = 0; + for (; nbCompares && (dictMatchIndex > dmsLowLimit); --nbCompares) { + const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE* match = dmsBase + dictMatchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dmsEnd, prefixStart); + if (dictMatchIndex+matchLength >= dmsHighLimit) + match = base + dictMatchIndex + dmsIndexDelta; /* to prepare for next usage of match[matchLength] */ + + if (matchLength > bestLength) { + matchIndex = dictMatchIndex + dmsIndexDelta; + DEBUGLOG(8, "found dms match of length %u at distance %u (offBase=%u)", + (U32)matchLength, curr - matchIndex, OFFSET_TO_OFFBASE(curr - matchIndex)); + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + bestLength = matchLength; + matches[mnum].off = OFFSET_TO_OFFBASE(curr - matchIndex); + matches[mnum].len = (U32)matchLength; + mnum++; + if ( (matchLength > ZSTD_OPT_NUM) + | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) { + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } } + + if (dictMatchIndex <= dmsBtLow) { break; } /* beyond tree size, stop the search */ + if (match[matchLength] < ip[matchLength]) { + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + dictMatchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + } else { + /* match is larger than current */ + commonLengthLarger = matchLength; + dictMatchIndex = nextPtr[0]; + } } } /* if (dictMode == ZSTD_dictMatchState) */ + + assert(matchEndIdx > curr+8); + ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */ + return mnum; +} + +typedef U32 (*ZSTD_getAllMatchesFn)( + ZSTD_match_t*, + ZSTD_MatchState_t*, + U32*, + const BYTE*, + const BYTE*, + const U32 rep[ZSTD_REP_NUM], + U32 const ll0, + U32 const lengthToBeat); + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_btGetAllMatches_internal( + ZSTD_match_t* matches, + ZSTD_MatchState_t* ms, + U32* nextToUpdate3, + const BYTE* ip, + const BYTE* const iHighLimit, + const U32 rep[ZSTD_REP_NUM], + U32 const ll0, + U32 const lengthToBeat, + const ZSTD_dictMode_e dictMode, + const U32 mls) +{ + assert(BOUNDED(3, ms->cParams.minMatch, 6) == mls); + DEBUGLOG(8, "ZSTD_BtGetAllMatches(dictMode=%d, mls=%u)", (int)dictMode, mls); + if (ip < ms->window.base + ms->nextToUpdate) + return 0; /* skipped area */ + ZSTD_updateTree_internal(ms, ip, iHighLimit, mls, dictMode); + return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, mls); +} + +#define ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls) ZSTD_btGetAllMatches_##dictMode##_##mls + +#define GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, mls) \ + static U32 ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls)( \ + ZSTD_match_t* matches, \ + ZSTD_MatchState_t* ms, \ + U32* nextToUpdate3, \ + const BYTE* ip, \ + const BYTE* const iHighLimit, \ + const U32 rep[ZSTD_REP_NUM], \ + U32 const ll0, \ + U32 const lengthToBeat) \ + { \ + return ZSTD_btGetAllMatches_internal( \ + matches, ms, nextToUpdate3, ip, iHighLimit, \ + rep, ll0, lengthToBeat, ZSTD_##dictMode, mls); \ + } + +#define GEN_ZSTD_BT_GET_ALL_MATCHES(dictMode) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 3) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 4) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 5) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 6) + +GEN_ZSTD_BT_GET_ALL_MATCHES(noDict) +GEN_ZSTD_BT_GET_ALL_MATCHES(extDict) +GEN_ZSTD_BT_GET_ALL_MATCHES(dictMatchState) + +#define ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMode) \ + { \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 3), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 4), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 5), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 6) \ + } + +static ZSTD_getAllMatchesFn +ZSTD_selectBtGetAllMatches(ZSTD_MatchState_t const* ms, ZSTD_dictMode_e const dictMode) +{ + ZSTD_getAllMatchesFn const getAllMatchesFns[3][4] = { + ZSTD_BT_GET_ALL_MATCHES_ARRAY(noDict), + ZSTD_BT_GET_ALL_MATCHES_ARRAY(extDict), + ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMatchState) + }; + U32 const mls = BOUNDED(3, ms->cParams.minMatch, 6); + assert((U32)dictMode < 3); + assert(mls - 3 < 4); + return getAllMatchesFns[(int)dictMode][mls - 3]; +} + +/************************* +* LDM helper functions * +*************************/ + +/* Struct containing info needed to make decision about ldm inclusion */ +typedef struct { + RawSeqStore_t seqStore; /* External match candidates store for this block */ + U32 startPosInBlock; /* Start position of the current match candidate */ + U32 endPosInBlock; /* End position of the current match candidate */ + U32 offset; /* Offset of the match candidate */ +} ZSTD_optLdm_t; + +/* ZSTD_optLdm_skipRawSeqStoreBytes(): + * Moves forward in @rawSeqStore by @nbBytes, + * which will update the fields 'pos' and 'posInSequence'. + */ +static void ZSTD_optLdm_skipRawSeqStoreBytes(RawSeqStore_t* rawSeqStore, size_t nbBytes) +{ + U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes); + while (currPos && rawSeqStore->pos < rawSeqStore->size) { + rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos]; + if (currPos >= currSeq.litLength + currSeq.matchLength) { + currPos -= currSeq.litLength + currSeq.matchLength; + rawSeqStore->pos++; + } else { + rawSeqStore->posInSequence = currPos; + break; + } + } + if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) { + rawSeqStore->posInSequence = 0; + } +} + +/* ZSTD_opt_getNextMatchAndUpdateSeqStore(): + * Calculates the beginning and end of the next match in the current block. + * Updates 'pos' and 'posInSequence' of the ldmSeqStore. + */ +static void +ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 currPosInBlock, + U32 blockBytesRemaining) +{ + rawSeq currSeq; + U32 currBlockEndPos; + U32 literalsBytesRemaining; + U32 matchBytesRemaining; + + /* Setting match end position to MAX to ensure we never use an LDM during this block */ + if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) { + optLdm->startPosInBlock = UINT_MAX; + optLdm->endPosInBlock = UINT_MAX; + return; + } + /* Calculate appropriate bytes left in matchLength and litLength + * after adjusting based on ldmSeqStore->posInSequence */ + currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos]; + assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength); + currBlockEndPos = currPosInBlock + blockBytesRemaining; + literalsBytesRemaining = (optLdm->seqStore.posInSequence < currSeq.litLength) ? + currSeq.litLength - (U32)optLdm->seqStore.posInSequence : + 0; + matchBytesRemaining = (literalsBytesRemaining == 0) ? + currSeq.matchLength - ((U32)optLdm->seqStore.posInSequence - currSeq.litLength) : + currSeq.matchLength; + + /* If there are more literal bytes than bytes remaining in block, no ldm is possible */ + if (literalsBytesRemaining >= blockBytesRemaining) { + optLdm->startPosInBlock = UINT_MAX; + optLdm->endPosInBlock = UINT_MAX; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, blockBytesRemaining); + return; + } + + /* Matches may be < minMatch by this process. In that case, we will reject them + when we are deciding whether or not to add the ldm */ + optLdm->startPosInBlock = currPosInBlock + literalsBytesRemaining; + optLdm->endPosInBlock = optLdm->startPosInBlock + matchBytesRemaining; + optLdm->offset = currSeq.offset; + + if (optLdm->endPosInBlock > currBlockEndPos) { + /* Match ends after the block ends, we can't use the whole match */ + optLdm->endPosInBlock = currBlockEndPos; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, currBlockEndPos - currPosInBlock); + } else { + /* Consume nb of bytes equal to size of sequence left */ + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, literalsBytesRemaining + matchBytesRemaining); + } +} + +/* ZSTD_optLdm_maybeAddMatch(): + * Adds a match if it's long enough, + * based on it's 'matchStartPosInBlock' and 'matchEndPosInBlock', + * into 'matches'. Maintains the correct ordering of 'matches'. + */ +static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches, + const ZSTD_optLdm_t* optLdm, U32 currPosInBlock, + U32 minMatch) +{ + U32 const posDiff = currPosInBlock - optLdm->startPosInBlock; + /* Note: ZSTD_match_t actually contains offBase and matchLength (before subtracting MINMATCH) */ + U32 const candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff; + + /* Ensure that current block position is not outside of the match */ + if (currPosInBlock < optLdm->startPosInBlock + || currPosInBlock >= optLdm->endPosInBlock + || candidateMatchLength < minMatch) { + return; + } + + if (*nbMatches == 0 || ((candidateMatchLength > matches[*nbMatches-1].len) && *nbMatches < ZSTD_OPT_NUM)) { + U32 const candidateOffBase = OFFSET_TO_OFFBASE(optLdm->offset); + DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offBase: %u matchLength %u) at block position=%u", + candidateOffBase, candidateMatchLength, currPosInBlock); + matches[*nbMatches].len = candidateMatchLength; + matches[*nbMatches].off = candidateOffBase; + (*nbMatches)++; + } +} + +/* ZSTD_optLdm_processMatchCandidate(): + * Wrapper function to update ldm seq store and call ldm functions as necessary. + */ +static void +ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, + ZSTD_match_t* matches, U32* nbMatches, + U32 currPosInBlock, U32 remainingBytes, + U32 minMatch) +{ + if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) { + return; + } + + if (currPosInBlock >= optLdm->endPosInBlock) { + if (currPosInBlock > optLdm->endPosInBlock) { + /* The position at which ZSTD_optLdm_processMatchCandidate() is called is not necessarily + * at the end of a match from the ldm seq store, and will often be some bytes + * over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots" + */ + U32 const posOvershoot = currPosInBlock - optLdm->endPosInBlock; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot); + } + ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes); + } + ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock, minMatch); +} + + +/*-******************************* +* Optimal parser +*********************************/ + +#if 0 /* debug */ + +static void +listStats(const U32* table, int lastEltID) +{ + int const nbElts = lastEltID + 1; + int enb; + for (enb=0; enb < nbElts; enb++) { + (void)table; + /* RAWLOG(2, "%3i:%3i, ", enb, table[enb]); */ + RAWLOG(2, "%4i,", table[enb]); + } + RAWLOG(2, " \n"); +} + +#endif + +#define LIT_PRICE(_p) (int)ZSTD_rawLiteralsCost(_p, 1, optStatePtr, optLevel) +#define LL_PRICE(_l) (int)ZSTD_litLengthPrice(_l, optStatePtr, optLevel) +#define LL_INCPRICE(_l) (LL_PRICE(_l) - LL_PRICE(_l-1)) + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t +ZSTD_compressBlock_opt_generic(ZSTD_MatchState_t* ms, + SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, + const int optLevel, + const ZSTD_dictMode_e dictMode) +{ + optState_t* const optStatePtr = &ms->opt; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + const BYTE* const base = ms->window.base; + const BYTE* const prefixStart = base + ms->window.dictLimit; + const ZSTD_compressionParameters* const cParams = &ms->cParams; + + ZSTD_getAllMatchesFn getAllMatches = ZSTD_selectBtGetAllMatches(ms, dictMode); + + U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1); + U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4; + U32 nextToUpdate3 = ms->nextToUpdate; + + ZSTD_optimal_t* const opt = optStatePtr->priceTable; + ZSTD_match_t* const matches = optStatePtr->matchTable; + ZSTD_optimal_t lastStretch; + ZSTD_optLdm_t optLdm; + + ZSTD_memset(&lastStretch, 0, sizeof(ZSTD_optimal_t)); + + optLdm.seqStore = ms->ldmSeqStore ? *ms->ldmSeqStore : kNullRawSeqStore; + optLdm.endPosInBlock = optLdm.startPosInBlock = optLdm.offset = 0; + ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip)); + + /* init */ + DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u", + (U32)(ip - base), ms->window.dictLimit, ms->nextToUpdate); + assert(optLevel <= 2); + ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize, optLevel); + ip += (ip==prefixStart); + + /* Match Loop */ + while (ip < ilimit) { + U32 cur, last_pos = 0; + + /* find first match */ + { U32 const litlen = (U32)(ip - anchor); + U32 const ll0 = !litlen; + U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, ip, iend, rep, ll0, minMatch); + ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, + (U32)(ip-istart), (U32)(iend-ip), + minMatch); + if (!nbMatches) { + DEBUGLOG(8, "no match found at cPos %u", (unsigned)(ip-istart)); + ip++; + continue; + } + + /* Match found: let's store this solution, and eventually find more candidates. + * During this forward pass, @opt is used to store stretches, + * defined as "a match followed by N literals". + * Note how this is different from a Sequence, which is "N literals followed by a match". + * Storing stretches allows us to store different match predecessors + * for each literal position part of a literals run. */ + + /* initialize opt[0] */ + opt[0].mlen = 0; /* there are only literals so far */ + opt[0].litlen = litlen; + /* No need to include the actual price of the literals before the first match + * because it is static for the duration of the forward pass, and is included + * in every subsequent price. But, we include the literal length because + * the cost variation of litlen depends on the value of litlen. + */ + opt[0].price = LL_PRICE(litlen); + ZSTD_STATIC_ASSERT(sizeof(opt[0].rep[0]) == sizeof(rep[0])); + ZSTD_memcpy(&opt[0].rep, rep, sizeof(opt[0].rep)); + + /* large match -> immediate encoding */ + { U32 const maxML = matches[nbMatches-1].len; + U32 const maxOffBase = matches[nbMatches-1].off; + DEBUGLOG(6, "found %u matches of maxLength=%u and maxOffBase=%u at cPos=%u => start new series", + nbMatches, maxML, maxOffBase, (U32)(ip-prefixStart)); + + if (maxML > sufficient_len) { + lastStretch.litlen = 0; + lastStretch.mlen = maxML; + lastStretch.off = maxOffBase; + DEBUGLOG(6, "large match (%u>%u) => immediate encoding", + maxML, sufficient_len); + cur = 0; + last_pos = maxML; + goto _shortestPath; + } } + + /* set prices for first matches starting position == 0 */ + assert(opt[0].price >= 0); + { U32 pos; + U32 matchNb; + for (pos = 1; pos < minMatch; pos++) { + opt[pos].price = ZSTD_MAX_PRICE; + opt[pos].mlen = 0; + opt[pos].litlen = litlen + pos; + } + for (matchNb = 0; matchNb < nbMatches; matchNb++) { + U32 const offBase = matches[matchNb].off; + U32 const end = matches[matchNb].len; + for ( ; pos <= end ; pos++ ) { + int const matchPrice = (int)ZSTD_getMatchPrice(offBase, pos, optStatePtr, optLevel); + int const sequencePrice = opt[0].price + matchPrice; + DEBUGLOG(7, "rPos:%u => set initial price : %.2f", + pos, ZSTD_fCost(sequencePrice)); + opt[pos].mlen = pos; + opt[pos].off = offBase; + opt[pos].litlen = 0; /* end of match */ + opt[pos].price = sequencePrice + LL_PRICE(0); + } + } + last_pos = pos-1; + opt[pos].price = ZSTD_MAX_PRICE; + } + } + + /* check further positions */ + for (cur = 1; cur <= last_pos; cur++) { + const BYTE* const inr = ip + cur; + assert(cur <= ZSTD_OPT_NUM); + DEBUGLOG(7, "cPos:%i==rPos:%u", (int)(inr-istart), cur); + + /* Fix current position with one literal if cheaper */ + { U32 const litlen = opt[cur-1].litlen + 1; + int const price = opt[cur-1].price + + LIT_PRICE(ip+cur-1) + + LL_INCPRICE(litlen); + assert(price < 1000000000); /* overflow check */ + if (price <= opt[cur].price) { + ZSTD_optimal_t const prevMatch = opt[cur]; + DEBUGLOG(7, "cPos:%i==rPos:%u : better price (%.2f<=%.2f) using literal (ll==%u) (hist:%u,%u,%u)", + (int)(inr-istart), cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price), litlen, + opt[cur-1].rep[0], opt[cur-1].rep[1], opt[cur-1].rep[2]); + opt[cur] = opt[cur-1]; + opt[cur].litlen = litlen; + opt[cur].price = price; + if ( (optLevel >= 1) /* additional check only for higher modes */ + && (prevMatch.litlen == 0) /* replace a match */ + && (LL_INCPRICE(1) < 0) /* ll1 is cheaper than ll0 */ + && LIKELY(ip + cur < iend) + ) { + /* check next position, in case it would be cheaper */ + int with1literal = prevMatch.price + LIT_PRICE(ip+cur) + LL_INCPRICE(1); + int withMoreLiterals = price + LIT_PRICE(ip+cur) + LL_INCPRICE(litlen+1); + DEBUGLOG(7, "then at next rPos %u : match+1lit %.2f vs %ulits %.2f", + cur+1, ZSTD_fCost(with1literal), litlen+1, ZSTD_fCost(withMoreLiterals)); + if ( (with1literal < withMoreLiterals) + && (with1literal < opt[cur+1].price) ) { + /* update offset history - before it disappears */ + U32 const prev = cur - prevMatch.mlen; + Repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, prevMatch.off, opt[prev].litlen==0); + assert(cur >= prevMatch.mlen); + DEBUGLOG(7, "==> match+1lit is cheaper (%.2f < %.2f) (hist:%u,%u,%u) !", + ZSTD_fCost(with1literal), ZSTD_fCost(withMoreLiterals), + newReps.rep[0], newReps.rep[1], newReps.rep[2] ); + opt[cur+1] = prevMatch; /* mlen & offbase */ + ZSTD_memcpy(opt[cur+1].rep, &newReps, sizeof(Repcodes_t)); + opt[cur+1].litlen = 1; + opt[cur+1].price = with1literal; + if (last_pos < cur+1) last_pos = cur+1; + } + } + } else { + DEBUGLOG(7, "cPos:%i==rPos:%u : literal would cost more (%.2f>%.2f)", + (int)(inr-istart), cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price)); + } + } + + /* Offset history is not updated during match comparison. + * Do it here, now that the match is selected and confirmed. + */ + ZSTD_STATIC_ASSERT(sizeof(opt[cur].rep) == sizeof(Repcodes_t)); + assert(cur >= opt[cur].mlen); + if (opt[cur].litlen == 0) { + /* just finished a match => alter offset history */ + U32 const prev = cur - opt[cur].mlen; + Repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, opt[cur].off, opt[prev].litlen==0); + ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(Repcodes_t)); + } + + /* last match must start at a minimum distance of 8 from oend */ + if (inr > ilimit) continue; + + if (cur == last_pos) break; + + if ( (optLevel==0) /*static_test*/ + && (opt[cur+1].price <= opt[cur].price + (BITCOST_MULTIPLIER/2)) ) { + DEBUGLOG(7, "skip current position : next rPos(%u) price is cheaper", cur+1); + continue; /* skip unpromising positions; about ~+6% speed, -0.01 ratio */ + } + + assert(opt[cur].price >= 0); + { U32 const ll0 = (opt[cur].litlen == 0); + int const previousPrice = opt[cur].price; + int const basePrice = previousPrice + LL_PRICE(0); + U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, inr, iend, opt[cur].rep, ll0, minMatch); + U32 matchNb; + + ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, + (U32)(inr-istart), (U32)(iend-inr), + minMatch); + + if (!nbMatches) { + DEBUGLOG(7, "rPos:%u : no match found", cur); + continue; + } + + { U32 const longestML = matches[nbMatches-1].len; + DEBUGLOG(7, "cPos:%i==rPos:%u, found %u matches, of longest ML=%u", + (int)(inr-istart), cur, nbMatches, longestML); + + if ( (longestML > sufficient_len) + || (cur + longestML >= ZSTD_OPT_NUM) + || (ip + cur + longestML >= iend) ) { + lastStretch.mlen = longestML; + lastStretch.off = matches[nbMatches-1].off; + lastStretch.litlen = 0; + last_pos = cur + longestML; + goto _shortestPath; + } } + + /* set prices using matches found at position == cur */ + for (matchNb = 0; matchNb < nbMatches; matchNb++) { + U32 const offset = matches[matchNb].off; + U32 const lastML = matches[matchNb].len; + U32 const startML = (matchNb>0) ? matches[matchNb-1].len+1 : minMatch; + U32 mlen; + + DEBUGLOG(7, "testing match %u => offBase=%4u, mlen=%2u, llen=%2u", + matchNb, matches[matchNb].off, lastML, opt[cur].litlen); + + for (mlen = lastML; mlen >= startML; mlen--) { /* scan downward */ + U32 const pos = cur + mlen; + int const price = basePrice + (int)ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel); + + if ((pos > last_pos) || (price < opt[pos].price)) { + DEBUGLOG(7, "rPos:%u (ml=%2u) => new better price (%.2f<%.2f)", + pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price)); + while (last_pos < pos) { + /* fill empty positions, for future comparisons */ + last_pos++; + opt[last_pos].price = ZSTD_MAX_PRICE; + opt[last_pos].litlen = !0; /* just needs to be != 0, to mean "not an end of match" */ + } + opt[pos].mlen = mlen; + opt[pos].off = offset; + opt[pos].litlen = 0; + opt[pos].price = price; + } else { + DEBUGLOG(7, "rPos:%u (ml=%2u) => new price is worse (%.2f>=%.2f)", + pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price)); + if (optLevel==0) break; /* early update abort; gets ~+10% speed for about -0.01 ratio loss */ + } + } } } + opt[last_pos+1].price = ZSTD_MAX_PRICE; + } /* for (cur = 1; cur <= last_pos; cur++) */ + + lastStretch = opt[last_pos]; + assert(cur >= lastStretch.mlen); + cur = last_pos - lastStretch.mlen; + +_shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */ + assert(opt[0].mlen == 0); + assert(last_pos >= lastStretch.mlen); + assert(cur == last_pos - lastStretch.mlen); + + if (lastStretch.mlen==0) { + /* no solution : all matches have been converted into literals */ + assert(lastStretch.litlen == (ip - anchor) + last_pos); + ip += last_pos; + continue; + } + assert(lastStretch.off > 0); + + /* Update offset history */ + if (lastStretch.litlen == 0) { + /* finishing on a match : update offset history */ + Repcodes_t const reps = ZSTD_newRep(opt[cur].rep, lastStretch.off, opt[cur].litlen==0); + ZSTD_memcpy(rep, &reps, sizeof(Repcodes_t)); + } else { + ZSTD_memcpy(rep, lastStretch.rep, sizeof(Repcodes_t)); + assert(cur >= lastStretch.litlen); + cur -= lastStretch.litlen; + } + + /* Let's write the shortest path solution. + * It is stored in @opt in reverse order, + * starting from @storeEnd (==cur+2), + * effectively partially @opt overwriting. + * Content is changed too: + * - So far, @opt stored stretches, aka a match followed by literals + * - Now, it will store sequences, aka literals followed by a match + */ + { U32 const storeEnd = cur + 2; + U32 storeStart = storeEnd; + U32 stretchPos = cur; + + DEBUGLOG(6, "start reverse traversal (last_pos:%u, cur:%u)", + last_pos, cur); (void)last_pos; + assert(storeEnd < ZSTD_OPT_SIZE); + DEBUGLOG(6, "last stretch copied into pos=%u (llen=%u,mlen=%u,ofc=%u)", + storeEnd, lastStretch.litlen, lastStretch.mlen, lastStretch.off); + if (lastStretch.litlen > 0) { + /* last "sequence" is unfinished: just a bunch of literals */ + opt[storeEnd].litlen = lastStretch.litlen; + opt[storeEnd].mlen = 0; + storeStart = storeEnd-1; + opt[storeStart] = lastStretch; + } { + opt[storeEnd] = lastStretch; /* note: litlen will be fixed */ + storeStart = storeEnd; + } + while (1) { + ZSTD_optimal_t nextStretch = opt[stretchPos]; + opt[storeStart].litlen = nextStretch.litlen; + DEBUGLOG(6, "selected sequence (llen=%u,mlen=%u,ofc=%u)", + opt[storeStart].litlen, opt[storeStart].mlen, opt[storeStart].off); + if (nextStretch.mlen == 0) { + /* reaching beginning of segment */ + break; + } + storeStart--; + opt[storeStart] = nextStretch; /* note: litlen will be fixed */ + assert(nextStretch.litlen + nextStretch.mlen <= stretchPos); + stretchPos -= nextStretch.litlen + nextStretch.mlen; + } + + /* save sequences */ + DEBUGLOG(6, "sending selected sequences into seqStore"); + { U32 storePos; + for (storePos=storeStart; storePos <= storeEnd; storePos++) { + U32 const llen = opt[storePos].litlen; + U32 const mlen = opt[storePos].mlen; + U32 const offBase = opt[storePos].off; + U32 const advance = llen + mlen; + DEBUGLOG(6, "considering seq starting at %i, llen=%u, mlen=%u", + (int)(anchor - istart), (unsigned)llen, (unsigned)mlen); + + if (mlen==0) { /* only literals => must be last "sequence", actually starting a new stream of sequences */ + assert(storePos == storeEnd); /* must be last sequence */ + ip = anchor + llen; /* last "sequence" is a bunch of literals => don't progress anchor */ + continue; /* will finish */ + } + + assert(anchor + llen <= iend); + ZSTD_updateStats(optStatePtr, llen, anchor, offBase, mlen); + ZSTD_storeSeq(seqStore, llen, anchor, iend, offBase, mlen); + anchor += advance; + ip = anchor; + } } + DEBUGLOG(7, "new offset history : %u, %u, %u", rep[0], rep[1], rep[2]); + + /* update all costs */ + ZSTD_setBasePrices(optStatePtr, optLevel); + } + } /* while (ip < ilimit) */ + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} +#endif /* build exclusions */ + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +static size_t ZSTD_compressBlock_opt0( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode) +{ + return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /* optLevel */, dictMode); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +static size_t ZSTD_compressBlock_opt2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode) +{ + return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /* optLevel */, dictMode); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btopt( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressBlock_btopt"); + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_noDict); +} +#endif + + + + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +/* ZSTD_initStats_ultra(): + * make a first compression pass, just to seed stats with more accurate starting values. + * only works on first block, with no dictionary and no ldm. + * this function cannot error out, its narrow contract must be respected. + */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_initStats_ultra(ZSTD_MatchState_t* ms, + SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + U32 tmpRep[ZSTD_REP_NUM]; /* updated rep codes will sink here */ + ZSTD_memcpy(tmpRep, rep, sizeof(tmpRep)); + + DEBUGLOG(4, "ZSTD_initStats_ultra (srcSize=%zu)", srcSize); + assert(ms->opt.litLengthSum == 0); /* first block */ + assert(seqStore->sequences == seqStore->sequencesStart); /* no ldm */ + assert(ms->window.dictLimit == ms->window.lowLimit); /* no dictionary */ + assert(ms->window.dictLimit - ms->nextToUpdate <= 1); /* no prefix (note: intentional overflow, defined as 2-complement) */ + + ZSTD_compressBlock_opt2(ms, seqStore, tmpRep, src, srcSize, ZSTD_noDict); /* generate stats into ms->opt*/ + + /* invalidate first scan from history, only keep entropy stats */ + ZSTD_resetSeqStore(seqStore); + ms->window.base -= srcSize; + ms->window.dictLimit += (U32)srcSize; + ms->window.lowLimit = ms->window.dictLimit; + ms->nextToUpdate = ms->window.dictLimit; + +} + +size_t ZSTD_compressBlock_btultra( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressBlock_btultra (srcSize=%zu)", srcSize); + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_btultra2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + U32 const curr = (U32)((const BYTE*)src - ms->window.base); + DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize); + + /* 2-passes strategy: + * this strategy makes a first pass over first block to collect statistics + * in order to seed next round's statistics with it. + * After 1st pass, function forgets history, and starts a new block. + * Consequently, this can only work if no data has been previously loaded in tables, + * aka, no dictionary, no prefix, no ldm preprocessing. + * The compression ratio gain is generally small (~0.5% on first block), + * the cost is 2x cpu time on first block. */ + assert(srcSize <= ZSTD_BLOCKSIZE_MAX); + if ( (ms->opt.litLengthSum==0) /* first block */ + && (seqStore->sequences == seqStore->sequencesStart) /* no ldm */ + && (ms->window.dictLimit == ms->window.lowLimit) /* no dictionary */ + && (curr == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */ + && (srcSize > ZSTD_PREDEF_THRESHOLD) /* input large enough to not employ default stats */ + ) { + ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize); + } + + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btopt_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_btopt_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_extDict); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btultra_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_btultra_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_extDict); +} +#endif + +/* note : no btultra2 variant for extDict nor dictMatchState, + * because btultra2 is not meant to work with dictionaries + * and is only specific for the first block (no prefix) */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_opt.h b/src/commonlib/bsd/zstd/compress/zstd_opt.h new file mode 100644 index 0000000000..365c0a573e --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_opt.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_OPT_H +#define ZSTD_OPT_H + +#include "zstd_compress_internal.h" + +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) +/* used in ZSTD_loadDictionaryContent() */ +void ZSTD_updateTree(ZSTD_MatchState_t* ms, const BYTE* ip, const BYTE* iend); +#endif + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btopt( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btopt_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btopt_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_BTOPT ZSTD_compressBlock_btopt +#define ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE ZSTD_compressBlock_btopt_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT ZSTD_compressBlock_btopt_extDict +#else +#define ZSTD_COMPRESSBLOCK_BTOPT NULL +#define ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT NULL +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btultra( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btultra_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btultra_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + + /* note : no btultra2 variant for extDict nor dictMatchState, + * because btultra2 is not meant to work with dictionaries + * and is only specific for the first block (no prefix) */ +size_t ZSTD_compressBlock_btultra2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_BTULTRA ZSTD_compressBlock_btultra +#define ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE ZSTD_compressBlock_btultra_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT ZSTD_compressBlock_btultra_extDict +#define ZSTD_COMPRESSBLOCK_BTULTRA2 ZSTD_compressBlock_btultra2 +#else +#define ZSTD_COMPRESSBLOCK_BTULTRA NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA2 NULL +#endif + +#endif /* ZSTD_OPT_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_preSplit.c b/src/commonlib/bsd/zstd/compress/zstd_preSplit.c new file mode 100644 index 0000000000..b4a2a738e5 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_preSplit.c @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "../common/zstd_compiler.h" /* ZSTD_ALIGNOF */ +#include "../common/mem.h" /* S64 */ +#include "../common/zstd_deps.h" /* ZSTD_memset */ +#include "../common/zstd_internal.h" /* ZSTD_STATIC_ASSERT */ +#include "hist.h" /* HIST_add */ +#include "zstd_preSplit.h" + + +#define BLOCKSIZE_MIN 3500 +#define THRESHOLD_PENALTY_RATE 16 +#define THRESHOLD_BASE (THRESHOLD_PENALTY_RATE - 2) +#define THRESHOLD_PENALTY 3 + +#define HASHLENGTH 2 +#define HASHLOG_MAX 10 +#define HASHTABLESIZE (1 << HASHLOG_MAX) +#define HASHMASK (HASHTABLESIZE - 1) +#define KNUTH 0x9e3779b9 + +/* for hashLog > 8, hash 2 bytes. + * for hashLog == 8, just take the byte, no hashing. + * The speed of this method relies on compile-time constant propagation */ +FORCE_INLINE_TEMPLATE unsigned hash2(const void *p, unsigned hashLog) +{ + assert(hashLog >= 8); + if (hashLog == 8) return (U32)((const BYTE*)p)[0]; + assert(hashLog <= HASHLOG_MAX); + return (U32)(MEM_read16(p)) * KNUTH >> (32 - hashLog); +} + + +typedef struct { + unsigned events[HASHTABLESIZE]; + size_t nbEvents; +} Fingerprint; +typedef struct { + Fingerprint pastEvents; + Fingerprint newEvents; +} FPStats; + +static void initStats(FPStats* fpstats) +{ + ZSTD_memset(fpstats, 0, sizeof(FPStats)); +} + +FORCE_INLINE_TEMPLATE void +addEvents_generic(Fingerprint* fp, const void* src, size_t srcSize, size_t samplingRate, unsigned hashLog) +{ + const char* p = (const char*)src; + size_t limit = srcSize - HASHLENGTH + 1; + size_t n; + assert(srcSize >= HASHLENGTH); + for (n = 0; n < limit; n+=samplingRate) { + fp->events[hash2(p+n, hashLog)]++; + } + fp->nbEvents += limit/samplingRate; +} + +FORCE_INLINE_TEMPLATE void +recordFingerprint_generic(Fingerprint* fp, const void* src, size_t srcSize, size_t samplingRate, unsigned hashLog) +{ + ZSTD_memset(fp, 0, sizeof(unsigned) * ((size_t)1 << hashLog)); + fp->nbEvents = 0; + addEvents_generic(fp, src, srcSize, samplingRate, hashLog); +} + +typedef void (*RecordEvents_f)(Fingerprint* fp, const void* src, size_t srcSize); + +#define FP_RECORD(_rate) ZSTD_recordFingerprint_##_rate + +#define ZSTD_GEN_RECORD_FINGERPRINT(_rate, _hSize) \ + static void FP_RECORD(_rate)(Fingerprint* fp, const void* src, size_t srcSize) \ + { \ + recordFingerprint_generic(fp, src, srcSize, _rate, _hSize); \ + } + +ZSTD_GEN_RECORD_FINGERPRINT(1, 10) +ZSTD_GEN_RECORD_FINGERPRINT(5, 10) +ZSTD_GEN_RECORD_FINGERPRINT(11, 9) +ZSTD_GEN_RECORD_FINGERPRINT(43, 8) + + +static U64 abs64(S64 s64) { return (U64)((s64 < 0) ? -s64 : s64); } + +static U64 fpDistance(const Fingerprint* fp1, const Fingerprint* fp2, unsigned hashLog) +{ + U64 distance = 0; + size_t n; + assert(hashLog <= HASHLOG_MAX); + for (n = 0; n < ((size_t)1 << hashLog); n++) { + distance += + abs64((S64)fp1->events[n] * (S64)fp2->nbEvents - (S64)fp2->events[n] * (S64)fp1->nbEvents); + } + return distance; +} + +/* Compare newEvents with pastEvents + * return 1 when considered "too different" + */ +static int compareFingerprints(const Fingerprint* ref, + const Fingerprint* newfp, + int penalty, + unsigned hashLog) +{ + assert(ref->nbEvents > 0); + assert(newfp->nbEvents > 0); + { U64 p50 = (U64)ref->nbEvents * (U64)newfp->nbEvents; + U64 deviation = fpDistance(ref, newfp, hashLog); + U64 threshold = p50 * (U64)(THRESHOLD_BASE + penalty) / THRESHOLD_PENALTY_RATE; + return deviation >= threshold; + } +} + +static void mergeEvents(Fingerprint* acc, const Fingerprint* newfp) +{ + size_t n; + for (n = 0; n < HASHTABLESIZE; n++) { + acc->events[n] += newfp->events[n]; + } + acc->nbEvents += newfp->nbEvents; +} + +static void flushEvents(FPStats* fpstats) +{ + size_t n; + for (n = 0; n < HASHTABLESIZE; n++) { + fpstats->pastEvents.events[n] = fpstats->newEvents.events[n]; + } + fpstats->pastEvents.nbEvents = fpstats->newEvents.nbEvents; + ZSTD_memset(&fpstats->newEvents, 0, sizeof(fpstats->newEvents)); +} + +static void removeEvents(Fingerprint* acc, const Fingerprint* slice) +{ + size_t n; + for (n = 0; n < HASHTABLESIZE; n++) { + assert(acc->events[n] >= slice->events[n]); + acc->events[n] -= slice->events[n]; + } + acc->nbEvents -= slice->nbEvents; +} + +#define CHUNKSIZE (8 << 10) +static size_t ZSTD_splitBlock_byChunks(const void* blockStart, size_t blockSize, + int level, + void* workspace, size_t wkspSize) +{ + static const RecordEvents_f records_fs[] = { + FP_RECORD(43), FP_RECORD(11), FP_RECORD(5), FP_RECORD(1) + }; + static const unsigned hashParams[] = { 8, 9, 10, 10 }; + const RecordEvents_f record_f = (assert(0<=level && level<=3), records_fs[level]); + FPStats* const fpstats = (FPStats*)workspace; + const char* p = (const char*)blockStart; + int penalty = THRESHOLD_PENALTY; + size_t pos = 0; + assert(blockSize == (128 << 10)); + assert(workspace != NULL); + assert((size_t)workspace % ZSTD_ALIGNOF(FPStats) == 0); + ZSTD_STATIC_ASSERT(ZSTD_SLIPBLOCK_WORKSPACESIZE >= sizeof(FPStats)); + assert(wkspSize >= sizeof(FPStats)); (void)wkspSize; + + initStats(fpstats); + record_f(&fpstats->pastEvents, p, CHUNKSIZE); + for (pos = CHUNKSIZE; pos <= blockSize - CHUNKSIZE; pos += CHUNKSIZE) { + record_f(&fpstats->newEvents, p + pos, CHUNKSIZE); + if (compareFingerprints(&fpstats->pastEvents, &fpstats->newEvents, penalty, hashParams[level])) { + return pos; + } else { + mergeEvents(&fpstats->pastEvents, &fpstats->newEvents); + if (penalty > 0) penalty--; + } + } + assert(pos == blockSize); + return blockSize; + (void)flushEvents; (void)removeEvents; +} + +/* ZSTD_splitBlock_fromBorders(): very fast strategy : + * compare fingerprint from beginning and end of the block, + * derive from their difference if it's preferable to split in the middle, + * repeat the process a second time, for finer grained decision. + * 3 times did not brought improvements, so I stopped at 2. + * Benefits are good enough for a cheap heuristic. + * More accurate splitting saves more, but speed impact is also more perceptible. + * For better accuracy, use more elaborate variant *_byChunks. + */ +static size_t ZSTD_splitBlock_fromBorders(const void* blockStart, size_t blockSize, + void* workspace, size_t wkspSize) +{ +#define SEGMENT_SIZE 512 + FPStats* const fpstats = (FPStats*)workspace; + Fingerprint* middleEvents = (Fingerprint*)(void*)((char*)workspace + 512 * sizeof(unsigned)); + assert(blockSize == (128 << 10)); + assert(workspace != NULL); + assert((size_t)workspace % ZSTD_ALIGNOF(FPStats) == 0); + ZSTD_STATIC_ASSERT(ZSTD_SLIPBLOCK_WORKSPACESIZE >= sizeof(FPStats)); + assert(wkspSize >= sizeof(FPStats)); (void)wkspSize; + + initStats(fpstats); + HIST_add(fpstats->pastEvents.events, blockStart, SEGMENT_SIZE); + HIST_add(fpstats->newEvents.events, (const char*)blockStart + blockSize - SEGMENT_SIZE, SEGMENT_SIZE); + fpstats->pastEvents.nbEvents = fpstats->newEvents.nbEvents = SEGMENT_SIZE; + if (!compareFingerprints(&fpstats->pastEvents, &fpstats->newEvents, 0, 8)) + return blockSize; + + HIST_add(middleEvents->events, (const char*)blockStart + blockSize/2 - SEGMENT_SIZE/2, SEGMENT_SIZE); + middleEvents->nbEvents = SEGMENT_SIZE; + { U64 const distFromBegin = fpDistance(&fpstats->pastEvents, middleEvents, 8); + U64 const distFromEnd = fpDistance(&fpstats->newEvents, middleEvents, 8); + U64 const minDistance = SEGMENT_SIZE * SEGMENT_SIZE / 3; + if (abs64((S64)distFromBegin - (S64)distFromEnd) < minDistance) + return 64 KB; + return (distFromBegin > distFromEnd) ? 32 KB : 96 KB; + } +} + +size_t ZSTD_splitBlock(const void* blockStart, size_t blockSize, + int level, + void* workspace, size_t wkspSize) +{ + DEBUGLOG(6, "ZSTD_splitBlock (level=%i)", level); + assert(0<=level && level<=4); + if (level == 0) + return ZSTD_splitBlock_fromBorders(blockStart, blockSize, workspace, wkspSize); + /* level >= 1*/ + return ZSTD_splitBlock_byChunks(blockStart, blockSize, level-1, workspace, wkspSize); +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_preSplit.h b/src/commonlib/bsd/zstd/compress/zstd_preSplit.h new file mode 100644 index 0000000000..3adda529fa --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_preSplit.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_PRESPLIT_H +#define ZSTD_PRESPLIT_H + +#include /* size_t */ + +#define ZSTD_SLIPBLOCK_WORKSPACESIZE 8208 + +/* ZSTD_splitBlock(): + * @level must be a value between 0 and 4. + * higher levels spend more energy to detect block boundaries. + * @workspace must be aligned for size_t. + * @wkspSize must be at least >= ZSTD_SLIPBLOCK_WORKSPACESIZE + * note: + * For the time being, this function only accepts full 128 KB blocks. + * Therefore, @blockSize must be == 128 KB. + * While this could be extended to smaller sizes in the future, + * it is not yet clear if this would be useful. TBD. + */ +size_t ZSTD_splitBlock(const void* blockStart, size_t blockSize, + int level, + void* workspace, size_t wkspSize); + +#endif /* ZSTD_PRESPLIT_H */ diff --git a/src/commonlib/bsd/zstd/decompress/huf_decompress.c b/src/commonlib/bsd/zstd/decompress/huf_decompress.c new file mode 100644 index 0000000000..2248ba8deb --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/huf_decompress.c @@ -0,0 +1,1946 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * huff0 huffman decoder, + * part of Finite State Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************************************** +* Dependencies +****************************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */ +#include "../common/zstd_compiler.h" +#include "../common/bitstream.h" /* BIT_* */ +#include "../common/fse.h" /* to compress headers */ +#include "../common/huf.h" +#include "../common/error_private.h" +#include "../common/zstd_internal.h" +#include "../common/zstd_bits.h" /* ZSTD_highbit32, ZSTD_countTrailingZeros64 */ + +/* ************************************************************** +* Constants +****************************************************************/ + +#define HUF_DECODER_FAST_TABLELOG 11 + +/* ************************************************************** +* Macros +****************************************************************/ + +#ifdef HUF_DISABLE_FAST_DECODE +# define HUF_ENABLE_FAST_DECODE 0 +#else +# define HUF_ENABLE_FAST_DECODE 1 +#endif + +/* These two optional macros force the use one way or another of the two + * Huffman decompression implementations. You can't force in both directions + * at the same time. + */ +#if defined(HUF_FORCE_DECOMPRESS_X1) && \ + defined(HUF_FORCE_DECOMPRESS_X2) +#error "Cannot force the use of the X1 and X2 decoders at the same time!" +#endif + +/* When DYNAMIC_BMI2 is enabled, fast decoders are only called when bmi2 is + * supported at runtime, so we can add the BMI2 target attribute. + * When it is disabled, we will still get BMI2 if it is enabled statically. + */ +#if DYNAMIC_BMI2 +# define HUF_FAST_BMI2_ATTRS BMI2_TARGET_ATTRIBUTE +#else +# define HUF_FAST_BMI2_ATTRS +#endif + +#ifdef __cplusplus +# define HUF_EXTERN_C extern "C" +#else +# define HUF_EXTERN_C +#endif +#define HUF_ASM_DECL HUF_EXTERN_C + +#if DYNAMIC_BMI2 +# define HUF_NEED_BMI2_FUNCTION 1 +#else +# define HUF_NEED_BMI2_FUNCTION 0 +#endif + +/* ************************************************************** +* Error Management +****************************************************************/ +#define HUF_isError ERR_isError + + +/* ************************************************************** +* Byte alignment for workSpace management +****************************************************************/ +#define HUF_ALIGN(x, a) HUF_ALIGN_MASK((x), (a) - 1) +#define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) + + +/* ************************************************************** +* BMI2 Variant Wrappers +****************************************************************/ +typedef size_t (*HUF_DecompressUsingDTableFn)(void *dst, size_t dstSize, + const void *cSrc, + size_t cSrcSize, + const HUF_DTable *DTable); + +#if DYNAMIC_BMI2 + +#define HUF_DGEN(fn) \ + \ + static size_t fn##_default( \ + void* dst, size_t dstSize, \ + const void* cSrc, size_t cSrcSize, \ + const HUF_DTable* DTable) \ + { \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + \ + static BMI2_TARGET_ATTRIBUTE size_t fn##_bmi2( \ + void* dst, size_t dstSize, \ + const void* cSrc, size_t cSrcSize, \ + const HUF_DTable* DTable) \ + { \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + \ + static size_t fn(void* dst, size_t dstSize, void const* cSrc, \ + size_t cSrcSize, HUF_DTable const* DTable, int flags) \ + { \ + if (flags & HUF_flags_bmi2) { \ + return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable); \ + } + +#else + +#define HUF_DGEN(fn) \ + static size_t fn(void* dst, size_t dstSize, void const* cSrc, \ + size_t cSrcSize, HUF_DTable const* DTable, int flags) \ + { \ + (void)flags; \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } + +#endif + + +/*-***************************/ +/* generic DTableDesc */ +/*-***************************/ +typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc; + +static DTableDesc HUF_getDTableDesc(const HUF_DTable* table) +{ + DTableDesc dtd; + ZSTD_memcpy(&dtd, table, sizeof(dtd)); + return dtd; +} + +static size_t HUF_initFastDStream(BYTE const* ip) { + BYTE const lastByte = ip[7]; + size_t const bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; + size_t const value = MEM_readLEST(ip) | 1; + assert(bitsConsumed <= 8); + assert(sizeof(size_t) == 8); + return value << bitsConsumed; +} + + +/** + * The input/output arguments to the Huffman fast decoding loop: + * + * ip [in/out] - The input pointers, must be updated to reflect what is consumed. + * op [in/out] - The output pointers, must be updated to reflect what is written. + * bits [in/out] - The bitstream containers, must be updated to reflect the current state. + * dt [in] - The decoding table. + * ilowest [in] - The beginning of the valid range of the input. Decoders may read + * down to this pointer. It may be below iend[0]. + * oend [in] - The end of the output stream. op[3] must not cross oend. + * iend [in] - The end of each input stream. ip[i] may cross iend[i], + * as long as it is above ilowest, but that indicates corruption. + */ +typedef struct { + BYTE const* ip[4]; + BYTE* op[4]; + U64 bits[4]; + void const* dt; + BYTE const* ilowest; + BYTE* oend; + BYTE const* iend[4]; +} HUF_DecompressFastArgs; + +typedef void (*HUF_DecompressFastLoopFn)(HUF_DecompressFastArgs*); + +/** + * Initializes args for the fast decoding loop. + * @returns 1 on success + * 0 if the fallback implementation should be used. + * Or an error code on failure. + */ +static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* dst, size_t dstSize, void const* src, size_t srcSize, const HUF_DTable* DTable) +{ + void const* dt = DTable + 1; + U32 const dtLog = HUF_getDTableDesc(DTable).tableLog; + + const BYTE* const istart = (const BYTE*)src; + + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); + + /* The fast decoding loop assumes 64-bit little-endian. + * This condition is false on x32. + */ + if (!MEM_isLittleEndian() || MEM_32bits()) + return 0; + + /* Avoid nullptr addition */ + if (dstSize == 0) + return 0; + assert(dst != NULL); + + /* strict minimum : jump table + 1 byte per stream */ + if (srcSize < 10) + return ERROR(corruption_detected); + + /* Must have at least 8 bytes per stream because we don't handle initializing smaller bit containers. + * If table log is not correct at this point, fallback to the old decoder. + * On small inputs we don't have enough data to trigger the fast loop, so use the old decoder. + */ + if (dtLog != HUF_DECODER_FAST_TABLELOG) + return 0; + + /* Read the jump table. */ + { + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = srcSize - (length1 + length2 + length3 + 6); + args->iend[0] = istart + 6; /* jumpTable */ + args->iend[1] = args->iend[0] + length1; + args->iend[2] = args->iend[1] + length2; + args->iend[3] = args->iend[2] + length3; + + /* HUF_initFastDStream() requires this, and this small of an input + * won't benefit from the ASM loop anyways. + */ + if (length1 < 8 || length2 < 8 || length3 < 8 || length4 < 8) + return 0; + if (length4 > srcSize) return ERROR(corruption_detected); /* overflow */ + } + /* ip[] contains the position that is currently loaded into bits[]. */ + args->ip[0] = args->iend[1] - sizeof(U64); + args->ip[1] = args->iend[2] - sizeof(U64); + args->ip[2] = args->iend[3] - sizeof(U64); + args->ip[3] = (BYTE const*)src + srcSize - sizeof(U64); + + /* op[] contains the output pointers. */ + args->op[0] = (BYTE*)dst; + args->op[1] = args->op[0] + (dstSize+3)/4; + args->op[2] = args->op[1] + (dstSize+3)/4; + args->op[3] = args->op[2] + (dstSize+3)/4; + + /* No point to call the ASM loop for tiny outputs. */ + if (args->op[3] >= oend) + return 0; + + /* bits[] is the bit container. + * It is read from the MSB down to the LSB. + * It is shifted left as it is read, and zeros are + * shifted in. After the lowest valid bit a 1 is + * set, so that CountTrailingZeros(bits[]) can be used + * to count how many bits we've consumed. + */ + args->bits[0] = HUF_initFastDStream(args->ip[0]); + args->bits[1] = HUF_initFastDStream(args->ip[1]); + args->bits[2] = HUF_initFastDStream(args->ip[2]); + args->bits[3] = HUF_initFastDStream(args->ip[3]); + + /* The decoders must be sure to never read beyond ilowest. + * This is lower than iend[0], but allowing decoders to read + * down to ilowest can allow an extra iteration or two in the + * fast loop. + */ + args->ilowest = istart; + + args->oend = oend; + args->dt = dt; + + return 1; +} + +static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressFastArgs const* args, int stream, BYTE* segmentEnd) +{ + /* Validate that we haven't overwritten. */ + if (args->op[stream] > segmentEnd) + return ERROR(corruption_detected); + /* Validate that we haven't read beyond iend[]. + * Note that ip[] may be < iend[] because the MSB is + * the next bit to read, and we may have consumed 100% + * of the stream, so down to iend[i] - 8 is valid. + */ + if (args->ip[stream] < args->iend[stream] - 8) + return ERROR(corruption_detected); + + /* Construct the BIT_DStream_t. */ + assert(sizeof(size_t) == 8); + bit->bitContainer = MEM_readLEST(args->ip[stream]); + bit->bitsConsumed = ZSTD_countTrailingZeros64(args->bits[stream]); + bit->start = (const char*)args->ilowest; + bit->limitPtr = bit->start + sizeof(size_t); + bit->ptr = (const char*)args->ip[stream]; + + return 0; +} + +/* Calls X(N) for each stream 0, 1, 2, 3. */ +#define HUF_4X_FOR_EACH_STREAM(X) \ + do { \ + X(0); \ + X(1); \ + X(2); \ + X(3); \ + } while (0) + +/* Calls X(N, var) for each stream 0, 1, 2, 3. */ +#define HUF_4X_FOR_EACH_STREAM_WITH_VAR(X, var) \ + do { \ + X(0, (var)); \ + X(1, (var)); \ + X(2, (var)); \ + X(3, (var)); \ + } while (0) + + +#ifndef HUF_FORCE_DECOMPRESS_X2 + +/*-***************************/ +/* single-symbol decoding */ +/*-***************************/ +typedef struct { BYTE nbBits; BYTE byte; } HUF_DEltX1; /* single-symbol decoding */ + +/** + * Packs 4 HUF_DEltX1 structs into a U64. This is used to lay down 4 entries at + * a time. + */ +static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) { + U64 D4; + if (MEM_isLittleEndian()) { + D4 = (U64)((symbol << 8) + nbBits); + } else { + D4 = (U64)(symbol + (nbBits << 8)); + } + assert(D4 < (1U << 16)); + D4 *= 0x0001000100010001ULL; + return D4; +} + +/** + * Increase the tableLog to targetTableLog and rescales the stats. + * If tableLog > targetTableLog this is a no-op. + * @returns New tableLog + */ +static U32 HUF_rescaleStats(BYTE* huffWeight, U32* rankVal, U32 nbSymbols, U32 tableLog, U32 targetTableLog) +{ + if (tableLog > targetTableLog) + return tableLog; + if (tableLog < targetTableLog) { + U32 const scale = targetTableLog - tableLog; + U32 s; + /* Increase the weight for all non-zero probability symbols by scale. */ + for (s = 0; s < nbSymbols; ++s) { + huffWeight[s] += (BYTE)((huffWeight[s] == 0) ? 0 : scale); + } + /* Update rankVal to reflect the new weights. + * All weights except 0 get moved to weight + scale. + * Weights [1, scale] are empty. + */ + for (s = targetTableLog; s > scale; --s) { + rankVal[s] = rankVal[s - scale]; + } + for (s = scale; s > 0; --s) { + rankVal[s] = 0; + } + } + return targetTableLog; +} + +typedef struct { + U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; + U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX + 1]; + U32 statsWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; + BYTE symbols[HUF_SYMBOLVALUE_MAX + 1]; + BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; +} HUF_ReadDTableX1_Workspace; + +size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags) +{ + U32 tableLog = 0; + U32 nbSymbols = 0; + size_t iSize; + void* const dtPtr = DTable + 1; + HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr; + HUF_ReadDTableX1_Workspace* wksp = (HUF_ReadDTableX1_Workspace*)workSpace; + + DEBUG_STATIC_ASSERT(HUF_DECOMPRESS_WORKSPACE_SIZE >= sizeof(*wksp)); + if (sizeof(*wksp) > wkspSize) return ERROR(tableLog_tooLarge); + + DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); + /* ZSTD_memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), flags); + if (HUF_isError(iSize)) return iSize; + + + /* Table header */ + { DTableDesc dtd = HUF_getDTableDesc(DTable); + U32 const maxTableLog = dtd.maxTableLog + 1; + U32 const targetTableLog = MIN(maxTableLog, HUF_DECODER_FAST_TABLELOG); + tableLog = HUF_rescaleStats(wksp->huffWeight, wksp->rankVal, nbSymbols, tableLog, targetTableLog); + if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */ + dtd.tableType = 0; + dtd.tableLog = (BYTE)tableLog; + ZSTD_memcpy(DTable, &dtd, sizeof(dtd)); + } + + /* Compute symbols and rankStart given rankVal: + * + * rankVal already contains the number of values of each weight. + * + * symbols contains the symbols ordered by weight. First are the rankVal[0] + * weight 0 symbols, followed by the rankVal[1] weight 1 symbols, and so on. + * symbols[0] is filled (but unused) to avoid a branch. + * + * rankStart contains the offset where each rank belongs in the DTable. + * rankStart[0] is not filled because there are no entries in the table for + * weight 0. + */ + { int n; + U32 nextRankStart = 0; + int const unroll = 4; + int const nLimit = (int)nbSymbols - unroll + 1; + for (n=0; n<(int)tableLog+1; n++) { + U32 const curr = nextRankStart; + nextRankStart += wksp->rankVal[n]; + wksp->rankStart[n] = curr; + } + for (n=0; n < nLimit; n += unroll) { + int u; + for (u=0; u < unroll; ++u) { + size_t const w = wksp->huffWeight[n+u]; + wksp->symbols[wksp->rankStart[w]++] = (BYTE)(n+u); + } + } + for (; n < (int)nbSymbols; ++n) { + size_t const w = wksp->huffWeight[n]; + wksp->symbols[wksp->rankStart[w]++] = (BYTE)n; + } + } + + /* fill DTable + * We fill all entries of each weight in order. + * That way length is a constant for each iteration of the outer loop. + * We can switch based on the length to a different inner loop which is + * optimized for that particular case. + */ + { U32 w; + int symbol = wksp->rankVal[0]; + int rankStart = 0; + for (w=1; wrankVal[w]; + int const length = (1 << w) >> 1; + int uStart = rankStart; + BYTE const nbBits = (BYTE)(tableLog + 1 - w); + int s; + int u; + switch (length) { + case 1: + for (s=0; ssymbols[symbol + s]; + D.nbBits = nbBits; + dt[uStart] = D; + uStart += 1; + } + break; + case 2: + for (s=0; ssymbols[symbol + s]; + D.nbBits = nbBits; + dt[uStart+0] = D; + dt[uStart+1] = D; + uStart += 2; + } + break; + case 4: + for (s=0; ssymbols[symbol + s], nbBits); + MEM_write64(dt + uStart, D4); + uStart += 4; + } + break; + case 8: + for (s=0; ssymbols[symbol + s], nbBits); + MEM_write64(dt + uStart, D4); + MEM_write64(dt + uStart + 4, D4); + uStart += 8; + } + break; + default: + for (s=0; ssymbols[symbol + s], nbBits); + for (u=0; u < length; u += 16) { + MEM_write64(dt + uStart + u + 0, D4); + MEM_write64(dt + uStart + u + 4, D4); + MEM_write64(dt + uStart + u + 8, D4); + MEM_write64(dt + uStart + u + 12, D4); + } + assert(u == length); + uStart += length; + } + break; + } + symbol += symbolCount; + rankStart += symbolCount * length; + } + } + return iSize; +} + +FORCE_INLINE_TEMPLATE BYTE +HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */ + BYTE const c = dt[val].byte; + BIT_skipBits(Dstream, dt[val].nbBits); + return c; +} + +#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \ + do { *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog); } while (0) + +#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ + HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \ + } while (0) + +#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits()) \ + HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \ + } while (0) + +HINT_INLINE size_t +HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog) +{ + BYTE* const pStart = p; + + /* up to 4 symbols at a time */ + if ((pEnd - p) > 3) { + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) { + HUF_DECODE_SYMBOLX1_2(p, bitDPtr); + HUF_DECODE_SYMBOLX1_1(p, bitDPtr); + HUF_DECODE_SYMBOLX1_2(p, bitDPtr); + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + } + } else { + BIT_reloadDStream(bitDPtr); + } + + /* [0-3] symbols remaining */ + if (MEM_32bits()) + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd)) + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + + /* no more data to retrieve from bitstream, no need to reload */ + while (p < pEnd) + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + + return (size_t)(pEnd-pStart); +} + +FORCE_INLINE_TEMPLATE size_t +HUF_decompress1X1_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + BYTE* op = (BYTE*)dst; + BYTE* const oend = ZSTD_maybeNullPtrAdd(op, dstSize); + const void* dtPtr = DTable + 1; + const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; + BIT_DStream_t bitD; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) ); + + HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog); + + if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); + + return dstSize; +} + +/* HUF_decompress4X1_usingDTable_internal_body(): + * Conditions : + * @dstSize >= 6 + */ +FORCE_INLINE_TEMPLATE size_t +HUF_decompress4X1_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + /* Check */ + if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */ + + { const BYTE* const istart = (const BYTE*) cSrc; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + BYTE* const olimit = oend - 3; + const void* const dtPtr = DTable + 1; + const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); + const BYTE* const istart1 = istart + 6; /* jumpTable */ + const BYTE* const istart2 = istart1 + length1; + const BYTE* const istart3 = istart2 + length2; + const BYTE* const istart4 = istart3 + length3; + const size_t segmentSize = (dstSize+3) / 4; + BYTE* const opStart2 = ostart + segmentSize; + BYTE* const opStart3 = opStart2 + segmentSize; + BYTE* const opStart4 = opStart3 + segmentSize; + BYTE* op1 = ostart; + BYTE* op2 = opStart2; + BYTE* op3 = opStart3; + BYTE* op4 = opStart4; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + U32 endSignal = 1; + + if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ + assert(dstSize >= 6); /* validated above */ + CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); + CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); + CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); + CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); + + /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */ + if ((size_t)(oend - op4) >= sizeof(size_t)) { + for ( ; (endSignal) & (op4 < olimit) ; ) { + HUF_DECODE_SYMBOLX1_2(op1, &bitD1); + HUF_DECODE_SYMBOLX1_2(op2, &bitD2); + HUF_DECODE_SYMBOLX1_2(op3, &bitD3); + HUF_DECODE_SYMBOLX1_2(op4, &bitD4); + HUF_DECODE_SYMBOLX1_1(op1, &bitD1); + HUF_DECODE_SYMBOLX1_1(op2, &bitD2); + HUF_DECODE_SYMBOLX1_1(op3, &bitD3); + HUF_DECODE_SYMBOLX1_1(op4, &bitD4); + HUF_DECODE_SYMBOLX1_2(op1, &bitD1); + HUF_DECODE_SYMBOLX1_2(op2, &bitD2); + HUF_DECODE_SYMBOLX1_2(op3, &bitD3); + HUF_DECODE_SYMBOLX1_2(op4, &bitD4); + HUF_DECODE_SYMBOLX1_0(op1, &bitD1); + HUF_DECODE_SYMBOLX1_0(op2, &bitD2); + HUF_DECODE_SYMBOLX1_0(op3, &bitD3); + HUF_DECODE_SYMBOLX1_0(op4, &bitD4); + endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished; + } + } + + /* check corruption */ + /* note : should not be necessary : op# advance in lock step, and we control op4. + * but curiously, binary generated by gcc 7.2 & 7.3 with -mbmi2 runs faster when >=1 test is present */ + if (op1 > opStart2) return ERROR(corruption_detected); + if (op2 > opStart3) return ERROR(corruption_detected); + if (op3 > opStart4) return ERROR(corruption_detected); + /* note : op4 supposed already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX1(op4, &bitD4, oend, dt, dtLog); + + /* check */ + { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endCheck) return ERROR(corruption_detected); } + + /* decoded size */ + return dstSize; + } +} + +#if HUF_NEED_BMI2_FUNCTION +static BMI2_TARGET_ATTRIBUTE +size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} +#endif + +static +size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 + +HUF_ASM_DECL void HUF_decompress4X1_usingDTable_internal_fast_asm_loop(HUF_DecompressFastArgs* args) ZSTDLIB_HIDDEN; + +#endif + +static HUF_FAST_BMI2_ATTRS +void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* args) +{ + U64 bits[4]; + BYTE const* ip[4]; + BYTE* op[4]; + U16 const* const dtable = (U16 const*)args->dt; + BYTE* const oend = args->oend; + BYTE const* const ilowest = args->ilowest; + + /* Copy the arguments to local variables */ + ZSTD_memcpy(&bits, &args->bits, sizeof(bits)); + ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip)); + ZSTD_memcpy(&op, &args->op, sizeof(op)); + + assert(MEM_isLittleEndian()); + assert(!MEM_32bits()); + + for (;;) { + BYTE* olimit; + int stream; + + /* Assert loop preconditions */ +#ifndef NDEBUG + for (stream = 0; stream < 4; ++stream) { + assert(op[stream] <= (stream == 3 ? oend : op[stream + 1])); + assert(ip[stream] >= ilowest); + } +#endif + /* Compute olimit */ + { + /* Each iteration produces 5 output symbols per stream */ + size_t const oiters = (size_t)(oend - op[3]) / 5; + /* Each iteration consumes up to 11 bits * 5 = 55 bits < 7 bytes + * per stream. + */ + size_t const iiters = (size_t)(ip[0] - ilowest) / 7; + /* We can safely run iters iterations before running bounds checks */ + size_t const iters = MIN(oiters, iiters); + size_t const symbols = iters * 5; + + /* We can simply check that op[3] < olimit, instead of checking all + * of our bounds, since we can't hit the other bounds until we've run + * iters iterations, which only happens when op[3] == olimit. + */ + olimit = op[3] + symbols; + + /* Exit fast decoding loop once we reach the end. */ + if (op[3] == olimit) + break; + + /* Exit the decoding loop if any input pointer has crossed the + * previous one. This indicates corruption, and a precondition + * to our loop is that ip[i] >= ip[0]. + */ + for (stream = 1; stream < 4; ++stream) { + if (ip[stream] < ip[stream - 1]) + goto _out; + } + } + +#ifndef NDEBUG + for (stream = 1; stream < 4; ++stream) { + assert(ip[stream] >= ip[stream - 1]); + } +#endif + +#define HUF_4X1_DECODE_SYMBOL(_stream, _symbol) \ + do { \ + int const index = (int)(bits[(_stream)] >> 53); \ + int const entry = (int)dtable[index]; \ + bits[(_stream)] <<= (entry & 0x3F); \ + op[(_stream)][(_symbol)] = (BYTE)((entry >> 8) & 0xFF); \ + } while (0) + +#define HUF_4X1_RELOAD_STREAM(_stream) \ + do { \ + int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \ + int const nbBits = ctz & 7; \ + int const nbBytes = ctz >> 3; \ + op[(_stream)] += 5; \ + ip[(_stream)] -= nbBytes; \ + bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \ + bits[(_stream)] <<= nbBits; \ + } while (0) + + /* Manually unroll the loop because compilers don't consistently + * unroll the inner loops, which destroys performance. + */ + do { + /* Decode 5 symbols in each of the 4 streams */ + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 1); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 2); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 3); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 4); + + /* Reload each of the 4 the bitstreams */ + HUF_4X_FOR_EACH_STREAM(HUF_4X1_RELOAD_STREAM); + } while (op[3] < olimit); + +#undef HUF_4X1_DECODE_SYMBOL +#undef HUF_4X1_RELOAD_STREAM + } + +_out: + + /* Save the final values of each of the state variables back to args. */ + ZSTD_memcpy(&args->bits, &bits, sizeof(bits)); + ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip)); + ZSTD_memcpy(&args->op, &op, sizeof(op)); +} + +/** + * @returns @p dstSize on success (>= 6) + * 0 if the fallback implementation should be used + * An error if an error occurred + */ +static HUF_FAST_BMI2_ATTRS +size_t +HUF_decompress4X1_usingDTable_internal_fast( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable, + HUF_DecompressFastLoopFn loopFn) +{ + void const* dt = DTable + 1; + BYTE const* const ilowest = (BYTE const*)cSrc; + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); + HUF_DecompressFastArgs args; + { size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable); + FORWARD_IF_ERROR(ret, "Failed to init fast loop args"); + if (ret == 0) + return 0; + } + + assert(args.ip[0] >= args.ilowest); + loopFn(&args); + + /* Our loop guarantees that ip[] >= ilowest and that we haven't + * overwritten any op[]. + */ + assert(args.ip[0] >= ilowest); + assert(args.ip[0] >= ilowest); + assert(args.ip[1] >= ilowest); + assert(args.ip[2] >= ilowest); + assert(args.ip[3] >= ilowest); + assert(args.op[3] <= oend); + + assert(ilowest == args.ilowest); + assert(ilowest + 6 == args.iend[0]); + (void)ilowest; + + /* finish bit streams one by one. */ + { size_t const segmentSize = (dstSize+3) / 4; + BYTE* segmentEnd = (BYTE*)dst; + int i; + for (i = 0; i < 4; ++i) { + BIT_DStream_t bit; + if (segmentSize <= (size_t)(oend - segmentEnd)) + segmentEnd += segmentSize; + else + segmentEnd = oend; + FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption"); + /* Decompress and validate that we've produced exactly the expected length. */ + args.op[i] += HUF_decodeStreamX1(args.op[i], &bit, segmentEnd, (HUF_DEltX1 const*)dt, HUF_DECODER_FAST_TABLELOG); + if (args.op[i] != segmentEnd) return ERROR(corruption_detected); + } + } + + /* decoded size */ + assert(dstSize != 0); + return dstSize; +} + +HUF_DGEN(HUF_decompress1X1_usingDTable_internal) + +static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable, int flags) +{ + HUF_DecompressUsingDTableFn fallbackFn = HUF_decompress4X1_usingDTable_internal_default; + HUF_DecompressFastLoopFn loopFn = HUF_decompress4X1_usingDTable_internal_fast_c_loop; + +#if DYNAMIC_BMI2 + if (flags & HUF_flags_bmi2) { + fallbackFn = HUF_decompress4X1_usingDTable_internal_bmi2; +# if ZSTD_ENABLE_ASM_X86_64_BMI2 + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop; + } +# endif + } else { + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); + } +#endif + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__) + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop; + } +#endif + + if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) { + size_t const ret = HUF_decompress4X1_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn); + if (ret != 0) + return ret; + } + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); +} + +static size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags); +} + +#endif /* HUF_FORCE_DECOMPRESS_X2 */ + + +#ifndef HUF_FORCE_DECOMPRESS_X1 + +/* *************************/ +/* double-symbols decoding */ +/* *************************/ + +typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2; /* double-symbols decoding */ +typedef struct { BYTE symbol; } sortedSymbol_t; +typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; +typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX]; + +/** + * Constructs a HUF_DEltX2 in a U32. + */ +static U32 HUF_buildDEltX2U32(U32 symbol, U32 nbBits, U32 baseSeq, int level) +{ + U32 seq; + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, sequence) == 0); + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, nbBits) == 2); + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, length) == 3); + DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U32)); + if (MEM_isLittleEndian()) { + seq = level == 1 ? symbol : (baseSeq + (symbol << 8)); + return seq + (nbBits << 16) + ((U32)level << 24); + } else { + seq = level == 1 ? (symbol << 8) : ((baseSeq << 8) + symbol); + return (seq << 16) + (nbBits << 8) + (U32)level; + } +} + +/** + * Constructs a HUF_DEltX2. + */ +static HUF_DEltX2 HUF_buildDEltX2(U32 symbol, U32 nbBits, U32 baseSeq, int level) +{ + HUF_DEltX2 DElt; + U32 const val = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level); + DEBUG_STATIC_ASSERT(sizeof(DElt) == sizeof(val)); + ZSTD_memcpy(&DElt, &val, sizeof(val)); + return DElt; +} + +/** + * Constructs 2 HUF_DEltX2s and packs them into a U64. + */ +static U64 HUF_buildDEltX2U64(U32 symbol, U32 nbBits, U16 baseSeq, int level) +{ + U32 DElt = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level); + return (U64)DElt + ((U64)DElt << 32); +} + +/** + * Fills the DTable rank with all the symbols from [begin, end) that are each + * nbBits long. + * + * @param DTableRank The start of the rank in the DTable. + * @param begin The first symbol to fill (inclusive). + * @param end The last symbol to fill (exclusive). + * @param nbBits Each symbol is nbBits long. + * @param tableLog The table log. + * @param baseSeq If level == 1 { 0 } else { the first level symbol } + * @param level The level in the table. Must be 1 or 2. + */ +static void HUF_fillDTableX2ForWeight( + HUF_DEltX2* DTableRank, + sortedSymbol_t const* begin, sortedSymbol_t const* end, + U32 nbBits, U32 tableLog, + U16 baseSeq, int const level) +{ + U32 const length = 1U << ((tableLog - nbBits) & 0x1F /* quiet static-analyzer */); + const sortedSymbol_t* ptr; + assert(level >= 1 && level <= 2); + switch (length) { + case 1: + for (ptr = begin; ptr != end; ++ptr) { + HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level); + *DTableRank++ = DElt; + } + break; + case 2: + for (ptr = begin; ptr != end; ++ptr) { + HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level); + DTableRank[0] = DElt; + DTableRank[1] = DElt; + DTableRank += 2; + } + break; + case 4: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + DTableRank += 4; + } + break; + case 8: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2)); + DTableRank += 8; + } + break; + default: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + HUF_DEltX2* const DTableRankEnd = DTableRank + length; + for (; DTableRank != DTableRankEnd; DTableRank += 8) { + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2)); + } + } + break; + } +} + +/* HUF_fillDTableX2Level2() : + * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */ +static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 targetLog, const U32 consumedBits, + const U32* rankVal, const int minWeight, const int maxWeight1, + const sortedSymbol_t* sortedSymbols, U32 const* rankStart, + U32 nbBitsBaseline, U16 baseSeq) +{ + /* Fill skipped values (all positions up to rankVal[minWeight]). + * These are positions only get a single symbol because the combined weight + * is too large. + */ + if (minWeight>1) { + U32 const length = 1U << ((targetLog - consumedBits) & 0x1F /* quiet static-analyzer */); + U64 const DEltX2 = HUF_buildDEltX2U64(baseSeq, consumedBits, /* baseSeq */ 0, /* level */ 1); + int const skipSize = rankVal[minWeight]; + assert(length > 1); + assert((U32)skipSize < length); + switch (length) { + case 2: + assert(skipSize == 1); + ZSTD_memcpy(DTable, &DEltX2, sizeof(DEltX2)); + break; + case 4: + assert(skipSize <= 4); + ZSTD_memcpy(DTable + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + 2, &DEltX2, sizeof(DEltX2)); + break; + default: + { + int i; + for (i = 0; i < skipSize; i += 8) { + ZSTD_memcpy(DTable + i + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 6, &DEltX2, sizeof(DEltX2)); + } + } + } + } + + /* Fill each of the second level symbols by weight. */ + { + int w; + for (w = minWeight; w < maxWeight1; ++w) { + int const begin = rankStart[w]; + int const end = rankStart[w+1]; + U32 const nbBits = nbBitsBaseline - w; + U32 const totalBits = nbBits + consumedBits; + HUF_fillDTableX2ForWeight( + DTable + rankVal[w], + sortedSymbols + begin, sortedSymbols + end, + totalBits, targetLog, + baseSeq, /* level */ 2); + } + } +} + +static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog, + const sortedSymbol_t* sortedList, + const U32* rankStart, rankValCol_t* rankValOrigin, const U32 maxWeight, + const U32 nbBitsBaseline) +{ + U32* const rankVal = rankValOrigin[0]; + const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */ + const U32 minBits = nbBitsBaseline - maxWeight; + int w; + int const wEnd = (int)maxWeight + 1; + + /* Fill DTable in order of weight. */ + for (w = 1; w < wEnd; ++w) { + int const begin = (int)rankStart[w]; + int const end = (int)rankStart[w+1]; + U32 const nbBits = nbBitsBaseline - w; + + if (targetLog-nbBits >= minBits) { + /* Enough room for a second symbol. */ + int start = rankVal[w]; + U32 const length = 1U << ((targetLog - nbBits) & 0x1F /* quiet static-analyzer */); + int minWeight = nbBits + scaleLog; + int s; + if (minWeight < 1) minWeight = 1; + /* Fill the DTable for every symbol of weight w. + * These symbols get at least 1 second symbol. + */ + for (s = begin; s != end; ++s) { + HUF_fillDTableX2Level2( + DTable + start, targetLog, nbBits, + rankValOrigin[nbBits], minWeight, wEnd, + sortedList, rankStart, + nbBitsBaseline, sortedList[s].symbol); + start += length; + } + } else { + /* Only a single symbol. */ + HUF_fillDTableX2ForWeight( + DTable + rankVal[w], + sortedList + begin, sortedList + end, + nbBits, targetLog, + /* baseSeq */ 0, /* level */ 1); + } + } +} + +typedef struct { + rankValCol_t rankVal[HUF_TABLELOG_MAX]; + U32 rankStats[HUF_TABLELOG_MAX + 1]; + U32 rankStart0[HUF_TABLELOG_MAX + 3]; + sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1]; + BYTE weightList[HUF_SYMBOLVALUE_MAX + 1]; + U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; +} HUF_ReadDTableX2_Workspace; + +size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, int flags) +{ + U32 tableLog, maxW, nbSymbols; + DTableDesc dtd = HUF_getDTableDesc(DTable); + U32 maxTableLog = dtd.maxTableLog; + size_t iSize; + void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */ + HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr; + U32 *rankStart; + + HUF_ReadDTableX2_Workspace* const wksp = (HUF_ReadDTableX2_Workspace*)workSpace; + + if (sizeof(*wksp) > wkspSize) return ERROR(GENERIC); + + rankStart = wksp->rankStart0 + 1; + ZSTD_memset(wksp->rankStats, 0, sizeof(wksp->rankStats)); + ZSTD_memset(wksp->rankStart0, 0, sizeof(wksp->rankStart0)); + + DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */ + if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); + /* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), flags); + if (HUF_isError(iSize)) return iSize; + + /* check result */ + if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */ + if (tableLog <= HUF_DECODER_FAST_TABLELOG && maxTableLog > HUF_DECODER_FAST_TABLELOG) maxTableLog = HUF_DECODER_FAST_TABLELOG; + + /* find maxWeight */ + for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */ + + /* Get start index of each weight */ + { U32 w, nextRankStart = 0; + for (w=1; wrankStats[w]; + rankStart[w] = curr; + } + rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/ + rankStart[maxW+1] = nextRankStart; + } + + /* sort symbols by weight */ + { U32 s; + for (s=0; sweightList[s]; + U32 const r = rankStart[w]++; + wksp->sortedSymbol[r].symbol = (BYTE)s; + } + rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */ + } + + /* Build rankVal */ + { U32* const rankVal0 = wksp->rankVal[0]; + { int const rescale = (maxTableLog-tableLog) - 1; /* tableLog <= maxTableLog */ + U32 nextRankVal = 0; + U32 w; + for (w=1; wrankStats[w] << (w+rescale); + rankVal0[w] = curr; + } } + { U32 const minBits = tableLog+1 - maxW; + U32 consumed; + for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) { + U32* const rankValPtr = wksp->rankVal[consumed]; + U32 w; + for (w = 1; w < maxW+1; w++) { + rankValPtr[w] = rankVal0[w] >> consumed; + } } } } + + HUF_fillDTableX2(dt, maxTableLog, + wksp->sortedSymbol, + wksp->rankStart0, wksp->rankVal, maxW, + tableLog+1); + + dtd.tableLog = (BYTE)maxTableLog; + dtd.tableType = 1; + ZSTD_memcpy(DTable, &dtd, sizeof(dtd)); + return iSize; +} + + +FORCE_INLINE_TEMPLATE U32 +HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + ZSTD_memcpy(op, &dt[val].sequence, 2); + BIT_skipBits(DStream, dt[val].nbBits); + return dt[val].length; +} + +FORCE_INLINE_TEMPLATE U32 +HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + ZSTD_memcpy(op, &dt[val].sequence, 1); + if (dt[val].length==1) { + BIT_skipBits(DStream, dt[val].nbBits); + } else { + if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) { + BIT_skipBits(DStream, dt[val].nbBits); + if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8)) + /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */ + DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); + } + } + return 1; +} + +#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \ + do { ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); } while (0) + +#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \ + } while (0) + +#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits()) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \ + } while (0) + +HINT_INLINE size_t +HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, + const HUF_DEltX2* const dt, const U32 dtLog) +{ + BYTE* const pStart = p; + + /* up to 8 symbols at a time */ + if ((size_t)(pEnd - p) >= sizeof(bitDPtr->bitContainer)) { + if (dtLog <= 11 && MEM_64bits()) { + /* up to 10 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-9)) { + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } + } else { + /* up to 8 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) { + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_1(p, bitDPtr); + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } + } + } else { + BIT_reloadDStream(bitDPtr); + } + + /* closer to end : up to 2 symbols at a time */ + if ((size_t)(pEnd - p) >= 2) { + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2)) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + + while (p <= pEnd-2) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */ + } + + if (p < pEnd) + p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog); + + return p-pStart; +} + +FORCE_INLINE_TEMPLATE size_t +HUF_decompress1X2_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + BIT_DStream_t bitD; + + /* Init */ + CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) ); + + /* decode */ + { BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, dstSize); + const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */ + const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + HUF_decodeStreamX2(ostart, &bitD, oend, dt, dtd.tableLog); + } + + /* check */ + if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); + + /* decoded size */ + return dstSize; +} + +/* HUF_decompress4X2_usingDTable_internal_body(): + * Conditions: + * @dstSize >= 6 + */ +FORCE_INLINE_TEMPLATE size_t +HUF_decompress4X2_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */ + + { const BYTE* const istart = (const BYTE*) cSrc; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + BYTE* const olimit = oend - (sizeof(size_t)-1); + const void* const dtPtr = DTable+1; + const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); + const BYTE* const istart1 = istart + 6; /* jumpTable */ + const BYTE* const istart2 = istart1 + length1; + const BYTE* const istart3 = istart2 + length2; + const BYTE* const istart4 = istart3 + length3; + size_t const segmentSize = (dstSize+3) / 4; + BYTE* const opStart2 = ostart + segmentSize; + BYTE* const opStart3 = opStart2 + segmentSize; + BYTE* const opStart4 = opStart3 + segmentSize; + BYTE* op1 = ostart; + BYTE* op2 = opStart2; + BYTE* op3 = opStart3; + BYTE* op4 = opStart4; + U32 endSignal = 1; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ + assert(dstSize >= 6 /* validated above */); + CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); + CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); + CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); + CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); + + /* 16-32 symbols per loop (4-8 symbols per stream) */ + if ((size_t)(oend - op4) >= sizeof(size_t)) { + for ( ; (endSignal) & (op4 < olimit); ) { +#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished; + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished; +#else + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + endSignal = (U32)LIKELY((U32) + (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished)); +#endif + } + } + + /* check corruption */ + if (op1 > opStart2) return ERROR(corruption_detected); + if (op2 > opStart3) return ERROR(corruption_detected); + if (op3 > opStart4) return ERROR(corruption_detected); + /* note : op4 already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog); + + /* check */ + { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endCheck) return ERROR(corruption_detected); } + + /* decoded size */ + return dstSize; + } +} + +#if HUF_NEED_BMI2_FUNCTION +static BMI2_TARGET_ATTRIBUTE +size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} +#endif + +static +size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 + +HUF_ASM_DECL void HUF_decompress4X2_usingDTable_internal_fast_asm_loop(HUF_DecompressFastArgs* args) ZSTDLIB_HIDDEN; + +#endif + +static HUF_FAST_BMI2_ATTRS +void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* args) +{ + U64 bits[4]; + BYTE const* ip[4]; + BYTE* op[4]; + BYTE* oend[4]; + HUF_DEltX2 const* const dtable = (HUF_DEltX2 const*)args->dt; + BYTE const* const ilowest = args->ilowest; + + /* Copy the arguments to local registers. */ + ZSTD_memcpy(&bits, &args->bits, sizeof(bits)); + ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip)); + ZSTD_memcpy(&op, &args->op, sizeof(op)); + + oend[0] = op[1]; + oend[1] = op[2]; + oend[2] = op[3]; + oend[3] = args->oend; + + assert(MEM_isLittleEndian()); + assert(!MEM_32bits()); + + for (;;) { + BYTE* olimit; + int stream; + + /* Assert loop preconditions */ +#ifndef NDEBUG + for (stream = 0; stream < 4; ++stream) { + assert(op[stream] <= oend[stream]); + assert(ip[stream] >= ilowest); + } +#endif + /* Compute olimit */ + { + /* Each loop does 5 table lookups for each of the 4 streams. + * Each table lookup consumes up to 11 bits of input, and produces + * up to 2 bytes of output. + */ + /* We can consume up to 7 bytes of input per iteration per stream. + * We also know that each input pointer is >= ip[0]. So we can run + * iters loops before running out of input. + */ + size_t iters = (size_t)(ip[0] - ilowest) / 7; + /* Each iteration can produce up to 10 bytes of output per stream. + * Each output stream my advance at different rates. So take the + * minimum number of safe iterations among all the output streams. + */ + for (stream = 0; stream < 4; ++stream) { + size_t const oiters = (size_t)(oend[stream] - op[stream]) / 10; + iters = MIN(iters, oiters); + } + + /* Each iteration produces at least 5 output symbols. So until + * op[3] crosses olimit, we know we haven't executed iters + * iterations yet. This saves us maintaining an iters counter, + * at the expense of computing the remaining # of iterations + * more frequently. + */ + olimit = op[3] + (iters * 5); + + /* Exit the fast decoding loop once we reach the end. */ + if (op[3] == olimit) + break; + + /* Exit the decoding loop if any input pointer has crossed the + * previous one. This indicates corruption, and a precondition + * to our loop is that ip[i] >= ip[0]. + */ + for (stream = 1; stream < 4; ++stream) { + if (ip[stream] < ip[stream - 1]) + goto _out; + } + } + +#ifndef NDEBUG + for (stream = 1; stream < 4; ++stream) { + assert(ip[stream] >= ip[stream - 1]); + } +#endif + +#define HUF_4X2_DECODE_SYMBOL(_stream, _decode3) \ + do { \ + if ((_decode3) || (_stream) != 3) { \ + int const index = (int)(bits[(_stream)] >> 53); \ + HUF_DEltX2 const entry = dtable[index]; \ + MEM_write16(op[(_stream)], entry.sequence); \ + bits[(_stream)] <<= (entry.nbBits) & 0x3F; \ + op[(_stream)] += (entry.length); \ + } \ + } while (0) + +#define HUF_4X2_RELOAD_STREAM(_stream) \ + do { \ + HUF_4X2_DECODE_SYMBOL(3, 1); \ + { \ + int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \ + int const nbBits = ctz & 7; \ + int const nbBytes = ctz >> 3; \ + ip[(_stream)] -= nbBytes; \ + bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \ + bits[(_stream)] <<= nbBits; \ + } \ + } while (0) + + /* Manually unroll the loop because compilers don't consistently + * unroll the inner loops, which destroys performance. + */ + do { + /* Decode 5 symbols from each of the first 3 streams. + * The final stream will be decoded during the reload phase + * to reduce register pressure. + */ + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + + /* Decode one symbol from the final stream */ + HUF_4X2_DECODE_SYMBOL(3, 1); + + /* Decode 4 symbols from the final stream & reload bitstreams. + * The final stream is reloaded last, meaning that all 5 symbols + * are decoded from the final stream before it is reloaded. + */ + HUF_4X_FOR_EACH_STREAM(HUF_4X2_RELOAD_STREAM); + } while (op[3] < olimit); + } + +#undef HUF_4X2_DECODE_SYMBOL +#undef HUF_4X2_RELOAD_STREAM + +_out: + + /* Save the final values of each of the state variables back to args. */ + ZSTD_memcpy(&args->bits, &bits, sizeof(bits)); + ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip)); + ZSTD_memcpy(&args->op, &op, sizeof(op)); +} + + +static HUF_FAST_BMI2_ATTRS size_t +HUF_decompress4X2_usingDTable_internal_fast( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable, + HUF_DecompressFastLoopFn loopFn) { + void const* dt = DTable + 1; + const BYTE* const ilowest = (const BYTE*)cSrc; + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); + HUF_DecompressFastArgs args; + { + size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable); + FORWARD_IF_ERROR(ret, "Failed to init asm args"); + if (ret == 0) + return 0; + } + + assert(args.ip[0] >= args.ilowest); + loopFn(&args); + + /* note : op4 already verified within main loop */ + assert(args.ip[0] >= ilowest); + assert(args.ip[1] >= ilowest); + assert(args.ip[2] >= ilowest); + assert(args.ip[3] >= ilowest); + assert(args.op[3] <= oend); + + assert(ilowest == args.ilowest); + assert(ilowest + 6 == args.iend[0]); + (void)ilowest; + + /* finish bitStreams one by one */ + { + size_t const segmentSize = (dstSize+3) / 4; + BYTE* segmentEnd = (BYTE*)dst; + int i; + for (i = 0; i < 4; ++i) { + BIT_DStream_t bit; + if (segmentSize <= (size_t)(oend - segmentEnd)) + segmentEnd += segmentSize; + else + segmentEnd = oend; + FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption"); + args.op[i] += HUF_decodeStreamX2(args.op[i], &bit, segmentEnd, (HUF_DEltX2 const*)dt, HUF_DECODER_FAST_TABLELOG); + if (args.op[i] != segmentEnd) + return ERROR(corruption_detected); + } + } + + /* decoded size */ + return dstSize; +} + +static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable, int flags) +{ + HUF_DecompressUsingDTableFn fallbackFn = HUF_decompress4X2_usingDTable_internal_default; + HUF_DecompressFastLoopFn loopFn = HUF_decompress4X2_usingDTable_internal_fast_c_loop; + +#if DYNAMIC_BMI2 + if (flags & HUF_flags_bmi2) { + fallbackFn = HUF_decompress4X2_usingDTable_internal_bmi2; +# if ZSTD_ENABLE_ASM_X86_64_BMI2 + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop; + } +# endif + } else { + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); + } +#endif + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__) + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop; + } +#endif + + if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) { + size_t const ret = HUF_decompress4X2_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn); + if (ret != 0) + return ret; + } + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); +} + +HUF_DGEN(HUF_decompress1X2_usingDTable_internal) + +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, + workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, flags); +} + +static size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize, + workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags); +} + +#endif /* HUF_FORCE_DECOMPRESS_X1 */ + + +/* ***********************************/ +/* Universal decompression selectors */ +/* ***********************************/ + + +#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2) +typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t; +static const algo_time_t algoTime[16 /* Quantization */][2 /* single, double */] = +{ + /* single, double, quad */ + {{0,0}, {1,1}}, /* Q==0 : impossible */ + {{0,0}, {1,1}}, /* Q==1 : impossible */ + {{ 150,216}, { 381,119}}, /* Q == 2 : 12-18% */ + {{ 170,205}, { 514,112}}, /* Q == 3 : 18-25% */ + {{ 177,199}, { 539,110}}, /* Q == 4 : 25-32% */ + {{ 197,194}, { 644,107}}, /* Q == 5 : 32-38% */ + {{ 221,192}, { 735,107}}, /* Q == 6 : 38-44% */ + {{ 256,189}, { 881,106}}, /* Q == 7 : 44-50% */ + {{ 359,188}, {1167,109}}, /* Q == 8 : 50-56% */ + {{ 582,187}, {1570,114}}, /* Q == 9 : 56-62% */ + {{ 688,187}, {1712,122}}, /* Q ==10 : 62-69% */ + {{ 825,186}, {1965,136}}, /* Q ==11 : 69-75% */ + {{ 976,185}, {2131,150}}, /* Q ==12 : 75-81% */ + {{1180,186}, {2070,175}}, /* Q ==13 : 81-87% */ + {{1377,185}, {1731,202}}, /* Q ==14 : 87-93% */ + {{1412,185}, {1695,202}}, /* Q ==15 : 93-99% */ +}; +#endif + +/** HUF_selectDecoder() : + * Tells which decoder is likely to decode faster, + * based on a set of pre-computed metrics. + * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . + * Assumption : 0 < dstSize <= 128 KB */ +U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize) +{ + assert(dstSize > 0); + assert(dstSize <= 128*1024); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)dstSize; + (void)cSrcSize; + return 0; +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)dstSize; + (void)cSrcSize; + return 1; +#else + /* decoder timing evaluation */ + { U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize); /* Q < 16 */ + U32 const D256 = (U32)(dstSize >> 8); + U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256); + U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256); + DTime1 += DTime1 >> 5; /* small advantage to algorithm using less memory, to reduce cache eviction */ + return DTime1 < DTime0; + } +#endif +} + +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ + if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ + if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)algoNb; + assert(algoNb == 0); + return HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)algoNb; + assert(algoNb == 1); + return HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags); +#else + return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags): + HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags); +#endif + } +} + + +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)dtd; + assert(dtd.tableType == 0); + return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)dtd; + assert(dtd.tableType == 1); + return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#else + return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) : + HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#endif +} + +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags); +} +#endif + +size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)dtd; + assert(dtd.tableType == 0); + return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)dtd; + assert(dtd.tableType == 1); + return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#else + return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) : + HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#endif +} + +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize == 0) return ERROR(corruption_detected); + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)algoNb; + assert(algoNb == 0); + return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)algoNb; + assert(algoNb == 1); + return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags); +#else + return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags) : + HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags); +#endif + } +} diff --git a/src/commonlib/bsd/zstd/decompress/zstd_ddict.c b/src/commonlib/bsd/zstd/decompress/zstd_ddict.c new file mode 100644 index 0000000000..d1ec182f4c --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_ddict.c @@ -0,0 +1,246 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* zstd_ddict.c : + * concentrates all logic that needs to know the internals of ZSTD_DDict object */ + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customFree */ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ +#include "../common/cpu.h" /* bmi2 */ +#include "../common/mem.h" /* low level memory routines */ +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/huf.h" +#include "zstd_decompress_internal.h" +#include "zstd_ddict.h" + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) +# include "../legacy/zstd_legacy.h" +#endif + + + +/*-******************************************************* +* Types +*********************************************************/ +struct ZSTD_DDict_s { + void* dictBuffer; + const void* dictContent; + size_t dictSize; + ZSTD_entropyDTables_t entropy; + U32 dictID; + U32 entropyPresent; + ZSTD_customMem cMem; +}; /* typedef'd to ZSTD_DDict within "zstd.h" */ + +const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict) +{ + assert(ddict != NULL); + return ddict->dictContent; +} + +size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict) +{ + assert(ddict != NULL); + return ddict->dictSize; +} + +void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) +{ + DEBUGLOG(4, "ZSTD_copyDDictParameters"); + assert(dctx != NULL); + assert(ddict != NULL); + dctx->dictID = ddict->dictID; + dctx->prefixStart = ddict->dictContent; + dctx->virtualStart = ddict->dictContent; + dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize; + dctx->previousDstEnd = dctx->dictEnd; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + dctx->dictContentBeginForFuzzing = dctx->prefixStart; + dctx->dictContentEndForFuzzing = dctx->previousDstEnd; +#endif + if (ddict->entropyPresent) { + dctx->litEntropy = 1; + dctx->fseEntropy = 1; + dctx->LLTptr = ddict->entropy.LLTable; + dctx->MLTptr = ddict->entropy.MLTable; + dctx->OFTptr = ddict->entropy.OFTable; + dctx->HUFptr = ddict->entropy.hufTable; + dctx->entropy.rep[0] = ddict->entropy.rep[0]; + dctx->entropy.rep[1] = ddict->entropy.rep[1]; + dctx->entropy.rep[2] = ddict->entropy.rep[2]; + } else { + dctx->litEntropy = 0; + dctx->fseEntropy = 0; + } +} + + +static size_t +ZSTD_loadEntropy_intoDDict(ZSTD_DDict* ddict, + ZSTD_dictContentType_e dictContentType) +{ + ddict->dictID = 0; + ddict->entropyPresent = 0; + if (dictContentType == ZSTD_dct_rawContent) return 0; + + if (ddict->dictSize < 8) { + if (dictContentType == ZSTD_dct_fullDict) + return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ + return 0; /* pure content mode */ + } + { U32 const magic = MEM_readLE32(ddict->dictContent); + if (magic != ZSTD_MAGIC_DICTIONARY) { + if (dictContentType == ZSTD_dct_fullDict) + return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ + return 0; /* pure content mode */ + } + } + ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_FRAMEIDSIZE); + + /* load entropy tables */ + RETURN_ERROR_IF(ZSTD_isError(ZSTD_loadDEntropy( + &ddict->entropy, ddict->dictContent, ddict->dictSize)), + dictionary_corrupted, ""); + ddict->entropyPresent = 1; + return 0; +} + + +static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) { + ddict->dictBuffer = NULL; + ddict->dictContent = dict; + if (!dict) dictSize = 0; + } else { + void* const internalBuffer = ZSTD_customMalloc(dictSize, ddict->cMem); + ddict->dictBuffer = internalBuffer; + ddict->dictContent = internalBuffer; + if (!internalBuffer) return ERROR(memory_allocation); + ZSTD_memcpy(internalBuffer, dict, dictSize); + } + ddict->dictSize = dictSize; + ddict->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */ + + /* parse dictionary content */ + FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) , ""); + + return 0; +} + +ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_customMem customMem) +{ + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + + { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_customMalloc(sizeof(ZSTD_DDict), customMem); + if (ddict == NULL) return NULL; + ddict->cMem = customMem; + { size_t const initResult = ZSTD_initDDict_internal(ddict, + dict, dictSize, + dictLoadMethod, dictContentType); + if (ZSTD_isError(initResult)) { + ZSTD_freeDDict(ddict); + return NULL; + } } + return ddict; + } +} + +/*! ZSTD_createDDict() : +* Create a digested dictionary, to start decompression without startup delay. +* `dict` content is copied inside DDict. +* Consequently, `dict` can be released after `ZSTD_DDict` creation */ +ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize) +{ + ZSTD_customMem const allocator = { NULL, NULL, NULL }; + return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, allocator); +} + +/*! ZSTD_createDDict_byReference() : + * Create a digested dictionary, to start decompression without startup delay. + * Dictionary content is simply referenced, it will be accessed during decompression. + * Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */ +ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize) +{ + ZSTD_customMem const allocator = { NULL, NULL, NULL }; + return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator); +} + + +const ZSTD_DDict* ZSTD_initStaticDDict( + void* sBuffer, size_t sBufferSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + size_t const neededSpace = sizeof(ZSTD_DDict) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); + ZSTD_DDict* const ddict = (ZSTD_DDict*)sBuffer; + assert(sBuffer != NULL); + assert(dict != NULL); + if ((size_t)sBuffer & 7) return NULL; /* 8-aligned */ + if (sBufferSize < neededSpace) return NULL; + if (dictLoadMethod == ZSTD_dlm_byCopy) { + ZSTD_memcpy(ddict+1, dict, dictSize); /* local copy */ + dict = ddict+1; + } + if (ZSTD_isError( ZSTD_initDDict_internal(ddict, + dict, dictSize, + ZSTD_dlm_byRef, dictContentType) )) + return NULL; + return ddict; +} + + +size_t ZSTD_freeDDict(ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; /* support free on NULL */ + { ZSTD_customMem const cMem = ddict->cMem; + ZSTD_customFree(ddict->dictBuffer, cMem); + ZSTD_customFree(ddict, cMem); + return 0; + } +} + +/*! ZSTD_estimateDDictSize() : + * Estimate amount of memory that will be needed to create a dictionary for decompression. + * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */ +size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod) +{ + return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); +} + +size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; /* support sizeof on NULL */ + return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ; +} + +/*! ZSTD_getDictID_fromDDict() : + * Provides the dictID of the dictionary loaded into `ddict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; + return ddict->dictID; +} diff --git a/src/commonlib/bsd/zstd/decompress/zstd_ddict.h b/src/commonlib/bsd/zstd/decompress/zstd_ddict.h new file mode 100644 index 0000000000..ef8000417a --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_ddict.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +#ifndef ZSTD_DDICT_H +#define ZSTD_DDICT_H + +/*-******************************************************* + * Dependencies + *********************************************************/ +#include "../common/zstd_deps.h" /* size_t */ +#include "../zstd.h" /* ZSTD_DDict, and several public functions */ + + +/*-******************************************************* + * Interface + *********************************************************/ + +/* note: several prototypes are already published in `zstd.h` : + * ZSTD_createDDict() + * ZSTD_createDDict_byReference() + * ZSTD_createDDict_advanced() + * ZSTD_freeDDict() + * ZSTD_initStaticDDict() + * ZSTD_sizeof_DDict() + * ZSTD_estimateDDictSize() + * ZSTD_getDictID_fromDict() + */ + +const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict); +size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict); + +void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); + + + +#endif /* ZSTD_DDICT_H */ diff --git a/src/commonlib/bsd/zstd/decompress/zstd_decompress.c b/src/commonlib/bsd/zstd/decompress/zstd_decompress.c new file mode 100644 index 0000000000..e24795d15e --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_decompress.c @@ -0,0 +1,922 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/* *************************************************************** +* Tuning parameters +*****************************************************************/ + +/*! +* LEGACY_SUPPORT : +* if set to 1+, ZSTD_decompress() can decode older formats (v0.1+) +*/ +#ifndef ZSTD_LEGACY_SUPPORT +# define ZSTD_LEGACY_SUPPORT 0 +#endif + +/*! + * MAXWINDOWSIZE_DEFAULT : + * maximum window size accepted by DStream __by default__. + * Frames requiring more memory will be rejected. + * It's possible to set a different limit using ZSTD_DCtx_setMaxWindowSize(). + */ +#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT +# define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + 1) +#endif + +/*! + * NO_FORWARD_PROGRESS_MAX : + * maximum allowed nb of calls to ZSTD_decompressStream() + * without any forward progress + * (defined as: no byte read from input, and no byte flushed to output) + * before triggering an error. + */ +#ifndef ZSTD_NO_FORWARD_PROGRESS_MAX +# define ZSTD_NO_FORWARD_PROGRESS_MAX 16 +#endif + + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */ +#include "../common/error_private.h" +#include "../common/zstd_internal.h" /* blockProperties_t */ +#include "../common/mem.h" /* low level memory routines */ +#include "../common/zstd_bits.h" /* ZSTD_highbit32 */ +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/huf.h" +#include +#include "zstd_decompress_internal.h" /* ZSTD_DCtx */ +#include "zstd_ddict.h" /* ZSTD_DDictDictContent */ +#include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */ + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) +# include "../legacy/zstd_legacy.h" +#endif + +/*-************************************************************* +* Context management +***************************************************************/ +size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) +{ + if (dctx==NULL) return 0; /* support sizeof NULL */ + return sizeof(*dctx) + + dctx->inBuffSize + dctx->outBuffSize; +} + +size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); } + +static size_t ZSTD_startingInputLength(ZSTD_format_e format) +{ + size_t const startingInputLength = ZSTD_FRAMEHEADERSIZE_PREFIX(format); + /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */ + assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) ); + return startingInputLength; +} + +static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx) +{ + assert(dctx->streamStage == zdss_init); + dctx->format = ZSTD_f_zstd1; + dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; + dctx->outBufferMode = ZSTD_bm_buffered; + dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum; + dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict; + dctx->disableHufAsm = 0; + dctx->maxBlockSizeParam = 0; +} + +static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) +{ + dctx->staticSize = 0; + dctx->ddict = NULL; + dctx->dictEnd = NULL; + dctx->ddictIsCold = 0; + dctx->dictUses = ZSTD_dont_use; + dctx->inBuff = NULL; + dctx->inBuffSize = 0; + dctx->outBuffSize = 0; + dctx->streamStage = zdss_init; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + dctx->legacyContext = NULL; + dctx->previousLegacyVersion = 0; +#endif + dctx->noForwardProgress = 0; + dctx->oversizedDuration = 0; + dctx->isFrameDecompression = 1; +#if DYNAMIC_BMI2 + dctx->bmi2 = ZSTD_cpuSupportsBmi2(); +#endif + ZSTD_DCtx_resetParameters(dctx); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + dctx->dictContentEndForFuzzing = NULL; +#endif +} + +ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize) +{ + ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace; + + if ((size_t)workspace & 7) return NULL; /* 8-aligned */ + if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */ + + ZSTD_initDCtx_internal(dctx); + dctx->staticSize = workspaceSize; + dctx->inBuff = (char*)(dctx+1); + return dctx; +} + +static ZSTD_DCtx* ZSTD_createDCtx_internal(ZSTD_customMem customMem) { + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + + { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_customMalloc(sizeof(*dctx), customMem); + if (!dctx) return NULL; + dctx->customMem = customMem; + ZSTD_initDCtx_internal(dctx); + return dctx; + } +} + +ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) +{ + return ZSTD_createDCtx_internal(customMem); +} + +ZSTD_DCtx* ZSTD_createDCtx(void) +{ + DEBUGLOG(3, "ZSTD_createDCtx"); + return ZSTD_createDCtx_internal(ZSTD_defaultCMem); +} + +static void ZSTD_clearDict(ZSTD_DCtx* dctx) +{ + dctx->ddict = NULL; + dctx->dictUses = ZSTD_dont_use; +} + +size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx) +{ + if (dctx==NULL) return 0; /* support free on NULL */ + RETURN_ERROR_IF(dctx->staticSize, memory_allocation, "not compatible with static DCtx"); + { ZSTD_customMem const cMem = dctx->customMem; + ZSTD_clearDict(dctx); + ZSTD_customFree(dctx->inBuff, cMem); + dctx->inBuff = NULL; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (dctx->legacyContext) + ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion); +#endif + ZSTD_customFree(dctx, cMem); + return 0; + } +} + +/* no longer useful */ +void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) +{ + size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx); + ZSTD_memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */ +} + + +/*-************************************************************* + * Frame header decoding + ***************************************************************/ + +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +unsigned ZSTD_isFrame(const void* buffer, size_t size) +{ + if (size < ZSTD_FRAMEIDSIZE) return 0; + { U32 const magic = MEM_readLE32(buffer); + if (magic == ZSTD_MAGICNUMBER) return 1; + if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1; + } +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (ZSTD_isLegacy(buffer, size)) return 1; +#endif + return 0; +} + +/*! ZSTD_isSkippableFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + */ +unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size) +{ + if (size < ZSTD_FRAMEIDSIZE) return 0; + { U32 const magic = MEM_readLE32(buffer); + if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1; + } + return 0; +} + +/** ZSTD_frameHeaderSize_internal() : + * srcSize must be large enough to reach header size fields. + * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless. + * @return : size of the Frame Header + * or an error code, which can be tested with ZSTD_isError() */ +static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format) +{ + size_t const minInputSize = ZSTD_startingInputLength(format); + RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong, ""); + + { BYTE const fhd = ((const BYTE*)src)[minInputSize-1]; + U32 const dictID= fhd & 3; + U32 const singleSegment = (fhd >> 5) & 1; + U32 const fcsId = fhd >> 6; + return minInputSize + !singleSegment + + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId] + + (singleSegment && !fcsId); + } +} + +/** ZSTD_frameHeaderSize() : + * srcSize must be >= ZSTD_frameHeaderSize_prefix. + * @return : size of the Frame Header, + * or an error code (if srcSize is too small) */ +size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) +{ + return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1); +} + +/** ZSTD_getFrameHeader_advanced() : + * decode Frame Header, or require larger `srcSize`. + * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless + * @return : 0, `zfhPtr` is correctly filled, + * >0, `srcSize` is too small, value is wanted `srcSize` amount, +** or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format) +{ + const BYTE* ip = (const BYTE*)src; + size_t const minInputSize = ZSTD_startingInputLength(format); + + DEBUGLOG(5, "ZSTD_getFrameHeader_advanced: minInputSize = %zu, srcSize = %zu", minInputSize, srcSize); + + if (srcSize > 0) { + /* note : technically could be considered an assert(), since it's an invalid entry */ + RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter : src==NULL, but srcSize>0"); + } + if (srcSize < minInputSize) { + if (srcSize > 0 && format != ZSTD_f_zstd1_magicless) { + /* when receiving less than @minInputSize bytes, + * control these bytes at least correspond to a supported magic number + * in order to error out early if they don't. + **/ + size_t const toCopy = MIN(4, srcSize); + unsigned char hbuf[4]; MEM_writeLE32(hbuf, ZSTD_MAGICNUMBER); + assert(src != NULL); + ZSTD_memcpy(hbuf, src, toCopy); + if ( MEM_readLE32(hbuf) != ZSTD_MAGICNUMBER ) { + /* not a zstd frame : let's check if it's a skippable frame */ + MEM_writeLE32(hbuf, ZSTD_MAGIC_SKIPPABLE_START); + ZSTD_memcpy(hbuf, src, toCopy); + if ((MEM_readLE32(hbuf) & ZSTD_MAGIC_SKIPPABLE_MASK) != ZSTD_MAGIC_SKIPPABLE_START) { + RETURN_ERROR(prefix_unknown, + "first bytes don't correspond to any supported magic number"); + } } } + return minInputSize; + } + + ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzers may not understand that zfhPtr will be read only if return value is zero, since they are 2 different signals */ + if ( (format != ZSTD_f_zstd1_magicless) + && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) { + if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { + /* skippable frame */ + if (srcSize < ZSTD_SKIPPABLEHEADERSIZE) + return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */ + ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); + zfhPtr->frameType = ZSTD_skippableFrame; + zfhPtr->dictID = MEM_readLE32(src) - ZSTD_MAGIC_SKIPPABLE_START; + zfhPtr->headerSize = ZSTD_SKIPPABLEHEADERSIZE; + zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE); + return 0; + } + RETURN_ERROR(prefix_unknown, ""); + } + + /* ensure there is enough `srcSize` to fully read/decode frame header */ + { size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format); + if (srcSize < fhsize) return fhsize; + zfhPtr->headerSize = (U32)fhsize; + } + + { BYTE const fhdByte = ip[minInputSize-1]; + size_t pos = minInputSize; + U32 const dictIDSizeCode = fhdByte&3; + U32 const checksumFlag = (fhdByte>>2)&1; + U32 const singleSegment = (fhdByte>>5)&1; + U32 const fcsID = fhdByte>>6; + U64 windowSize = 0; + U32 dictID = 0; + U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; + RETURN_ERROR_IF((fhdByte & 0x08) != 0, frameParameter_unsupported, + "reserved bits, must be zero"); + + if (!singleSegment) { + BYTE const wlByte = ip[pos++]; + U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN; + RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge, ""); + windowSize = (1ULL << windowLog); + windowSize += (windowSize >> 3) * (wlByte&7); + } + switch(dictIDSizeCode) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : break; + case 1 : dictID = ip[pos]; pos++; break; + case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break; + case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break; + } + switch(fcsID) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : if (singleSegment) frameContentSize = ip[pos]; break; + case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break; + case 2 : frameContentSize = MEM_readLE32(ip+pos); break; + case 3 : frameContentSize = MEM_readLE64(ip+pos); break; + } + if (singleSegment) windowSize = frameContentSize; + + zfhPtr->frameType = ZSTD_frame; + zfhPtr->frameContentSize = frameContentSize; + zfhPtr->windowSize = windowSize; + zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); + zfhPtr->dictID = dictID; + zfhPtr->checksumFlag = checksumFlag; + } + return 0; +} + +/** ZSTD_getFrameHeader() : + * decode Frame Header, or require larger `srcSize`. + * note : this function does not consume input, it only reads it. + * @return : 0, `zfhPtr` is correctly filled, + * >0, `srcSize` is too small, value is wanted `srcSize` amount, + * or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_getFrameHeader(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize) +{ + return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1); +} + +static size_t readSkippableFrameSize(void const* src, size_t srcSize) +{ + size_t const skippableHeaderSize = ZSTD_SKIPPABLEHEADERSIZE; + U32 sizeU32; + + RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, ""); + + sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE); + RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32, + frameParameter_unsupported, ""); + { size_t const skippableSize = skippableHeaderSize + sizeU32; + RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, ""); + return skippableSize; + } +} + +/** ZSTD_decodeFrameHeader() : + * `headerSize` must be the size provided by ZSTD_frameHeaderSize(). + * If multiple DDict references are enabled, also will choose the correct DDict to use. + * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */ +static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize) +{ + size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format); + if (ZSTD_isError(result)) return result; /* invalid header */ + RETURN_ERROR_IF(result>0, srcSize_wrong, "headerSize too small"); + +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Skip the dictID check in fuzzing mode, because it makes the search + * harder. + */ + RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID), + dictionary_wrong, ""); +#endif + dctx->validateChecksum = (dctx->fParams.checksumFlag && !dctx->forceIgnoreChecksum) ? 1 : 0; + if (dctx->validateChecksum) XXH64_reset(&dctx->xxhState, 0); + dctx->processedCSize += headerSize; + return 0; +} + +static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_copyRawBlock"); + RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, ""); + if (dst == NULL) { + if (srcSize == 0) return 0; + RETURN_ERROR(dstBuffer_null, ""); + } + ZSTD_memmove(dst, src, srcSize); + return srcSize; +} + +static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, + BYTE b, + size_t regenSize) +{ + RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, ""); + if (dst == NULL) { + if (regenSize == 0) return 0; + RETURN_ERROR(dstBuffer_null, ""); + } + ZSTD_memset(dst, b, regenSize); + return regenSize; +} + +static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, int streaming) +{ +#if ZSTD_TRACE + if (dctx->traceCtx && ZSTD_trace_decompress_end != NULL) { + ZSTD_Trace trace; + ZSTD_memset(&trace, 0, sizeof(trace)); + trace.version = ZSTD_VERSION_NUMBER; + trace.streaming = streaming; + if (dctx->ddict) { + trace.dictionaryID = ZSTD_getDictID_fromDDict(dctx->ddict); + trace.dictionarySize = ZSTD_DDict_dictSize(dctx->ddict); + trace.dictionaryIsCold = dctx->ddictIsCold; + } + trace.uncompressedSize = (size_t)uncompressedSize; + trace.compressedSize = (size_t)compressedSize; + trace.dctx = dctx; + ZSTD_trace_decompress_end(dctx->traceCtx, &trace); + } +#else + (void)dctx; + (void)uncompressedSize; + (void)compressedSize; + (void)streaming; +#endif +} + +/*! ZSTD_decompressFrame() : + * @dctx must be properly initialized + * will update *srcPtr and *srcSizePtr, + * to make *srcPtr progress by one frame. */ +static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void** srcPtr, size_t *srcSizePtr) +{ + const BYTE* const istart = (const BYTE*)(*srcPtr); + const BYTE* ip = istart; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = dstCapacity != 0 ? ostart + dstCapacity : ostart; + BYTE* op = ostart; + size_t remainingSrcSize = *srcSizePtr; + + DEBUGLOG(4, "ZSTD_decompressFrame (srcSize:%i)", (int)*srcSizePtr); + + /* check */ + RETURN_ERROR_IF( + remainingSrcSize < ZSTD_FRAMEHEADERSIZE_MIN(dctx->format)+ZSTD_blockHeaderSize, + srcSize_wrong, ""); + + /* Frame Header */ + { size_t const frameHeaderSize = ZSTD_frameHeaderSize_internal( + ip, ZSTD_FRAMEHEADERSIZE_PREFIX(dctx->format), dctx->format); + if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize; + RETURN_ERROR_IF(remainingSrcSize < frameHeaderSize+ZSTD_blockHeaderSize, + srcSize_wrong, ""); + FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) , ""); + ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize; + } + + /* Shrink the blockSizeMax if enabled */ + if (dctx->maxBlockSizeParam != 0) + dctx->fParams.blockSizeMax = MIN(dctx->fParams.blockSizeMax, (unsigned)dctx->maxBlockSizeParam); + + /* Loop on each block */ + while (1) { + BYTE* oBlockEnd = oend; + size_t decodedSize; + blockProperties_t blockProperties; + size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties); + if (ZSTD_isError(cBlockSize)) return cBlockSize; + + ip += ZSTD_blockHeaderSize; + remainingSrcSize -= ZSTD_blockHeaderSize; + RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, ""); + + if (ip >= op && ip < oBlockEnd) { + /* We are decompressing in-place. Limit the output pointer so that we + * don't overwrite the block that we are currently reading. This will + * fail decompression if the input & output pointers aren't spaced + * far enough apart. + * + * This is important to set, even when the pointers are far enough + * apart, because ZSTD_decompressBlock_internal() can decide to store + * literals in the output buffer, after the block it is decompressing. + * Since we don't want anything to overwrite our input, we have to tell + * ZSTD_decompressBlock_internal to never write past ip. + * + * See ZSTD_allocateLiteralsBuffer() for reference. + */ + oBlockEnd = op + (ip - op); + } + + switch(blockProperties.blockType) + { + case bt_compressed: + assert(dctx->isFrameDecompression == 1); + decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, not_streaming); + break; + case bt_raw : + /* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */ + decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize); + break; + case bt_rle : + decodedSize = ZSTD_setRleBlock(op, (size_t)(oBlockEnd-op), *ip, blockProperties.origSize); + break; + case bt_reserved : + default: + RETURN_ERROR(corruption_detected, "invalid block type"); + } + FORWARD_IF_ERROR(decodedSize, "Block decompression failure"); + DEBUGLOG(5, "Decompressed block of dSize = %u", (unsigned)decodedSize); + if (dctx->validateChecksum) { + XXH64_update(&dctx->xxhState, op, decodedSize); + } + if (decodedSize) /* support dst = NULL,0 */ { + op += decodedSize; + } + assert(ip != NULL); + ip += cBlockSize; + remainingSrcSize -= cBlockSize; + if (blockProperties.lastBlock) break; + } + + if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) { + RETURN_ERROR_IF((U64)(op-ostart) != dctx->fParams.frameContentSize, + corruption_detected, ""); + } + if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */ + RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong, ""); + if (!dctx->forceIgnoreChecksum) { + U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState); + U32 checkRead; + checkRead = MEM_readLE32(ip); + RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, ""); + } + ip += 4; + remainingSrcSize -= 4; + } + ZSTD_DCtx_trace_end(dctx, (U64)(op-ostart), (U64)(ip-istart), /* streaming */ 0); + /* Allow caller to get size read */ + DEBUGLOG(4, "ZSTD_decompressFrame: decompressed frame of size %i, consuming %i bytes of input", (int)(op-ostart), (int)(ip - (const BYTE*)*srcPtr)); + *srcPtr = ip; + *srcSizePtr = remainingSrcSize; + return (size_t)(op-ostart); +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + const ZSTD_DDict* ddict) +{ + void* const dststart = dst; + int moreThan1Frame = 0; + + DEBUGLOG(5, "ZSTD_decompressMultiFrame"); + assert(dict==NULL || ddict==NULL); /* either dict or ddict set, not both */ + + if (ddict) { + dict = ZSTD_DDict_dictContent(ddict); + dictSize = ZSTD_DDict_dictSize(ddict); + } + + while (srcSize >= ZSTD_startingInputLength(dctx->format)) { + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (dctx->format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize)) { + size_t decodedSize; + size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize); + if (ZSTD_isError(frameSize)) return frameSize; + RETURN_ERROR_IF(dctx->staticSize, memory_allocation, + "legacy support is not compatible with static dctx"); + + decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize); + if (ZSTD_isError(decodedSize)) return decodedSize; + + { + unsigned long long const expectedSize = ZSTD_getFrameContentSize(src, srcSize); + RETURN_ERROR_IF(expectedSize == ZSTD_CONTENTSIZE_ERROR, corruption_detected, "Corrupted frame header!"); + if (expectedSize != ZSTD_CONTENTSIZE_UNKNOWN) { + RETURN_ERROR_IF(expectedSize != decodedSize, corruption_detected, + "Frame header size does not match decoded size!"); + } + } + + assert(decodedSize <= dstCapacity); + dst = (BYTE*)dst + decodedSize; + dstCapacity -= decodedSize; + + src = (const BYTE*)src + frameSize; + srcSize -= frameSize; + + continue; + } +#endif + + if (dctx->format == ZSTD_f_zstd1 && srcSize >= 4) { + U32 const magicNumber = MEM_readLE32(src); + DEBUGLOG(5, "reading magic number %08X", (unsigned)magicNumber); + if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { + /* skippable frame detected : skip it */ + size_t const skippableSize = readSkippableFrameSize(src, srcSize); + FORWARD_IF_ERROR(skippableSize, "invalid skippable frame"); + assert(skippableSize <= srcSize); + + src = (const BYTE *)src + skippableSize; + srcSize -= skippableSize; + continue; /* check next frame */ + } } + + if (ddict) { + /* we were called from ZSTD_decompress_usingDDict */ + FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(dctx, ddict), ""); + } else { + /* this will initialize correctly with no dict if dict == NULL, so + * use this in all cases but ddict */ + FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize), ""); + } + ZSTD_checkContinuity(dctx, dst, dstCapacity); + + { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity, + &src, &srcSize); + RETURN_ERROR_IF( + (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown) + && (moreThan1Frame==1), + srcSize_wrong, + "At least one frame successfully completed, " + "but following bytes are garbage: " + "it's more likely to be a srcSize error, " + "specifying more input bytes than size of frame(s). " + "Note: one could be unlucky, it might be a corruption error instead, " + "happening right at the place where we expect zstd magic bytes. " + "But this is _much_ less likely than a srcSize field error."); + if (ZSTD_isError(res)) return res; + assert(res <= dstCapacity); + if (res != 0) + dst = (BYTE*)dst + res; + dstCapacity -= res; + } + moreThan1Frame = 1; + } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */ + + RETURN_ERROR_IF(srcSize, srcSize_wrong, "input not entirely consumed"); + + return (size_t)((BYTE*)dst - (BYTE*)dststart); +} + +size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize) +{ + return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL); +} + +static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx) +{ + switch (dctx->dictUses) { + default: + assert(0 /* Impossible */); + ZSTD_FALLTHROUGH; + case ZSTD_dont_use: + ZSTD_clearDict(dctx); + return NULL; + case ZSTD_use_indefinitely: + return dctx->ddict; + case ZSTD_use_once: + dctx->dictUses = ZSTD_dont_use; + return dctx->ddict; + } +} + +size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + return ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ZSTD_getDDict(dctx)); +} + +static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + dctx->dictEnd = dctx->previousDstEnd; + dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart)); + dctx->prefixStart = dict; + dctx->previousDstEnd = (const char*)dict + dictSize; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + dctx->dictContentBeginForFuzzing = dctx->prefixStart; + dctx->dictContentEndForFuzzing = dctx->previousDstEnd; +#endif + return 0; +} + + +/*! ZSTD_loadDEntropy() : + * dict : must point at beginning of a valid zstd dictionary. + * @return : size of entropy tables read */ +size_t +ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy, + const void* const dict, size_t const dictSize) +{ + const BYTE* dictPtr = (const BYTE*)dict; + const BYTE* const dictEnd = dictPtr + dictSize; + + RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted, "dict is too small"); + assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY); /* dict must be valid */ + dictPtr += 8; /* skip header = magic + dictID */ + + ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, OFTable) == offsetof(ZSTD_entropyDTables_t, LLTable) + sizeof(entropy->LLTable)); + ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, MLTable) == offsetof(ZSTD_entropyDTables_t, OFTable) + sizeof(entropy->OFTable)); + ZSTD_STATIC_ASSERT(sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable) >= HUF_DECOMPRESS_WORKSPACE_SIZE); + { void* const workspace = &entropy->LLTable; /* use fse tables as temporary workspace; implies fse tables are grouped together */ + size_t const workspaceSize = sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable); +#ifdef HUF_FORCE_DECOMPRESS_X1 + /* in minimal huffman, we always use X1 variants */ + size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable, + dictPtr, dictEnd - dictPtr, + workspace, workspaceSize, /* flags */ 0); +#else + size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable, + dictPtr, (size_t)(dictEnd - dictPtr), + workspace, workspaceSize, /* flags */ 0); +#endif + RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, ""); + dictPtr += hSize; + } + + { short offcodeNCount[MaxOff+1]; + unsigned offcodeMaxValue = MaxOff, offcodeLog; + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted, ""); + RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, ""); + ZSTD_buildFSETable( entropy->OFTable, + offcodeNCount, offcodeMaxValue, + OF_base, OF_bits, + offcodeLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */0); + dictPtr += offcodeHeaderSize; + } + + { short matchlengthNCount[MaxML+1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog; + size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted, ""); + RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, ""); + ZSTD_buildFSETable( entropy->MLTable, + matchlengthNCount, matchlengthMaxValue, + ML_base, ML_bits, + matchlengthLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */ 0); + dictPtr += matchlengthHeaderSize; + } + + { short litlengthNCount[MaxLL+1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog; + size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted, ""); + RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, ""); + ZSTD_buildFSETable( entropy->LLTable, + litlengthNCount, litlengthMaxValue, + LL_base, LL_bits, + litlengthLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */ 0); + dictPtr += litlengthHeaderSize; + } + + RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, ""); + { int i; + size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12)); + for (i=0; i<3; i++) { + U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4; + RETURN_ERROR_IF(rep==0 || rep > dictContentSize, + dictionary_corrupted, ""); + entropy->rep[i] = rep; + } } + + return (size_t)(dictPtr - (const BYTE*)dict); +} + +static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize); + { U32 const magic = MEM_readLE32(dict); + if (magic != ZSTD_MAGIC_DICTIONARY) { + return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */ + } } + dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE); + + /* load entropy tables */ + { size_t const eSize = ZSTD_loadDEntropy(&dctx->entropy, dict, dictSize); + RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted, ""); + dict = (const char*)dict + eSize; + dictSize -= eSize; + } + dctx->litEntropy = dctx->fseEntropy = 1; + + /* reference dictionary content */ + return ZSTD_refDictContent(dctx, dict, dictSize); +} + +size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) +{ + assert(dctx != NULL); +#if ZSTD_TRACE + dctx->traceCtx = (ZSTD_trace_decompress_begin != NULL) ? ZSTD_trace_decompress_begin(dctx) : 0; +#endif + dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */ + dctx->stage = ZSTDds_getFrameHeaderSize; + dctx->processedCSize = 0; + dctx->decodedSize = 0; + dctx->previousDstEnd = NULL; + dctx->prefixStart = NULL; + dctx->virtualStart = NULL; + dctx->dictEnd = NULL; + dctx->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */ + dctx->litEntropy = dctx->fseEntropy = 0; + dctx->dictID = 0; + dctx->bType = bt_reserved; + dctx->isFrameDecompression = 1; + ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue)); + ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ + dctx->LLTptr = dctx->entropy.LLTable; + dctx->MLTptr = dctx->entropy.MLTable; + dctx->OFTptr = dctx->entropy.OFTable; + dctx->HUFptr = dctx->entropy.hufTable; + return 0; +} + +size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , ""); + if (dict && dictSize) + RETURN_ERROR_IF( + ZSTD_isError(ZSTD_decompress_insertDictionary(dctx, dict, dictSize)), + dictionary_corrupted, ""); + return 0; +} + + +/* ====== ZSTD_DDict ====== */ + +size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) +{ + DEBUGLOG(4, "ZSTD_decompressBegin_usingDDict"); + assert(dctx != NULL); + if (ddict) { + const char* const dictStart = (const char*)ZSTD_DDict_dictContent(ddict); + size_t const dictSize = ZSTD_DDict_dictSize(ddict); + const void* const dictEnd = dictStart + dictSize; + dctx->ddictIsCold = (dctx->dictEnd != dictEnd); + DEBUGLOG(4, "DDict is %s", + dctx->ddictIsCold ? "~cold~" : "hot!"); + } + FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , ""); + if (ddict) { /* NULL ddict is equivalent to no dictionary */ + ZSTD_copyDDictParameters(dctx, ddict); + } + return 0; +} + +/*! ZSTD_decompress_usingDDict() : +* Decompression using a pre-digested Dictionary +* Use dictionary without significant overhead. */ +size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_DDict* ddict) +{ + /* pass content and size in case legacy frames are encountered */ + return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, + NULL, 0, + ddict); +} diff --git a/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.c b/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.c new file mode 100644 index 0000000000..3a963792a4 --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.c @@ -0,0 +1,2188 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* zstd_decompress_block : + * this module takes care of decompressing _compressed_ block */ + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ +#include "../common/zstd_compiler.h" /* prefetch */ +#include "../common/cpu.h" /* bmi2 */ +#include "../common/mem.h" /* low level memory routines */ +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/huf.h" +#include "../common/zstd_internal.h" +#include "zstd_decompress_internal.h" /* ZSTD_DCtx */ +#include "zstd_ddict.h" /* ZSTD_DDictDictContent */ +#include "zstd_decompress_block.h" +#include "../common/zstd_bits.h" /* ZSTD_highbit32 */ + +/*_******************************************************* +* Macros +**********************************************************/ + +/* These two optional macros force the use one way or another of the two + * ZSTD_decompressSequences implementations. You can't force in both directions + * at the same time. + */ +#if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ + defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) +#error "Cannot force the use of the short and the long ZSTD_decompressSequences variants!" +#endif + + +/*_******************************************************* +* Memory operations +**********************************************************/ +static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); } + + +/*-************************************************************* + * Block decoding + ***************************************************************/ + +static size_t ZSTD_blockSizeMax(ZSTD_DCtx const* dctx) +{ + size_t const blockSizeMax = dctx->isFrameDecompression ? dctx->fParams.blockSizeMax : ZSTD_BLOCKSIZE_MAX; + assert(blockSizeMax <= ZSTD_BLOCKSIZE_MAX); + return blockSizeMax; +} + +/*! ZSTD_getcBlockSize() : + * Provides the size of compressed block from block header `src` */ +size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, + blockProperties_t* bpPtr) +{ + RETURN_ERROR_IF(srcSize < ZSTD_blockHeaderSize, srcSize_wrong, ""); + + { U32 const cBlockHeader = MEM_readLE24(src); + U32 const cSize = cBlockHeader >> 3; + bpPtr->lastBlock = cBlockHeader & 1; + bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3); + bpPtr->origSize = cSize; /* only useful for RLE */ + if (bpPtr->blockType == bt_rle) return 1; + RETURN_ERROR_IF(bpPtr->blockType == bt_reserved, corruption_detected, ""); + return cSize; + } +} + +/* Allocate buffer for literals, either overlapping current dst, or split between dst and litExtraBuffer, or stored entirely within litExtraBuffer */ +static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize, + const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately) +{ + size_t const blockSizeMax = ZSTD_blockSizeMax(dctx); + assert(litSize <= blockSizeMax); + assert(dctx->isFrameDecompression || streaming == not_streaming); + assert(expectedWriteSize <= blockSizeMax); + if (streaming == not_streaming && dstCapacity > blockSizeMax + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH) { + /* If we aren't streaming, we can just put the literals after the output + * of the current block. We don't need to worry about overwriting the + * extDict of our window, because it doesn't exist. + * So if we have space after the end of the block, just put it there. + */ + dctx->litBuffer = (BYTE*)dst + blockSizeMax + WILDCOPY_OVERLENGTH; + dctx->litBufferEnd = dctx->litBuffer + litSize; + dctx->litBufferLocation = ZSTD_in_dst; + } else if (litSize <= ZSTD_LITBUFFEREXTRASIZE) { + /* Literals fit entirely within the extra buffer, put them there to avoid + * having to split the literals. + */ + dctx->litBuffer = dctx->litExtraBuffer; + dctx->litBufferEnd = dctx->litBuffer + litSize; + dctx->litBufferLocation = ZSTD_not_in_dst; + } else { + assert(blockSizeMax > ZSTD_LITBUFFEREXTRASIZE); + /* Literals must be split between the output block and the extra lit + * buffer. We fill the extra lit buffer with the tail of the literals, + * and put the rest of the literals at the end of the block, with + * WILDCOPY_OVERLENGTH of buffer room to allow for overreads. + * This MUST not write more than our maxBlockSize beyond dst, because in + * streaming mode, that could overwrite part of our extDict window. + */ + if (splitImmediately) { + /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */ + dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH; + dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE; + } else { + /* initially this will be stored entirely in dst during huffman decoding, it will partially be shifted to litExtraBuffer after */ + dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize; + dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize; + } + dctx->litBufferLocation = ZSTD_split; + assert(dctx->litBufferEnd <= (BYTE*)dst + expectedWriteSize); + } +} + +/*! ZSTD_decodeLiteralsBlock() : + * Where it is possible to do so without being stomped by the output during decompression, the literals block will be stored + * in the dstBuffer. If there is room to do so, it will be stored in full in the excess dst space after where the current + * block will be output. Otherwise it will be stored at the end of the current dst blockspace, with a small portion being + * stored in dctx->litExtraBuffer to help keep it "ahead" of the current output write. + * + * @return : nb of bytes read from src (< srcSize ) + * note : symbol not declared but exposed for fullbench */ +static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, /* note : srcSize < BLOCKSIZE */ + void* dst, size_t dstCapacity, const streaming_operation streaming) +{ + DEBUGLOG(5, "ZSTD_decodeLiteralsBlock"); + RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, ""); + + { const BYTE* const istart = (const BYTE*) src; + SymbolEncodingType_e const litEncType = (SymbolEncodingType_e)(istart[0] & 3); + size_t const blockSizeMax = ZSTD_blockSizeMax(dctx); + + switch(litEncType) + { + case set_repeat: + DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block"); + RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, ""); + ZSTD_FALLTHROUGH; + + case set_compressed: + RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need up to 5 for case 3"); + { size_t lhSize, litSize, litCSize; + U32 singleStream=0; + U32 const lhlCode = (istart[0] >> 2) & 3; + U32 const lhc = MEM_readLE32(istart); + size_t hufSuccess; + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); + int const flags = 0 + | (ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0) + | (dctx->disableHufAsm ? HUF_flags_disableAsm : 0); + switch(lhlCode) + { + case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */ + /* 2 - 2 - 10 - 10 */ + singleStream = !lhlCode; + lhSize = 3; + litSize = (lhc >> 4) & 0x3FF; + litCSize = (lhc >> 14) & 0x3FF; + break; + case 2: + /* 2 - 2 - 14 - 14 */ + lhSize = 4; + litSize = (lhc >> 4) & 0x3FFF; + litCSize = lhc >> 18; + break; + case 3: + /* 2 - 2 - 18 - 18 */ + lhSize = 5; + litSize = (lhc >> 4) & 0x3FFFF; + litCSize = (lhc >> 22) + ((size_t)istart[4] << 10); + break; + } + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); + if (!singleStream) + RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong, + "Not enough literals (%zu) for the 4-streams mode (min %u)", + litSize, MIN_LITERALS_FOR_4_STREAMS); + RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, ""); + RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0); + + /* prefetch huffman table if cold */ + if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) { + PREFETCH_AREA(dctx->HUFptr, sizeof(dctx->entropy.hufTable)); + } + + if (litEncType==set_repeat) { + if (singleStream) { + hufSuccess = HUF_decompress1X_usingDTable( + dctx->litBuffer, litSize, istart+lhSize, litCSize, + dctx->HUFptr, flags); + } else { + assert(litSize >= MIN_LITERALS_FOR_4_STREAMS); + hufSuccess = HUF_decompress4X_usingDTable( + dctx->litBuffer, litSize, istart+lhSize, litCSize, + dctx->HUFptr, flags); + } + } else { + if (singleStream) { +#if defined(HUF_FORCE_DECOMPRESS_X2) + hufSuccess = HUF_decompress1X_DCtx_wksp( + dctx->entropy.hufTable, dctx->litBuffer, litSize, + istart+lhSize, litCSize, dctx->workspace, + sizeof(dctx->workspace), flags); +#else + hufSuccess = HUF_decompress1X1_DCtx_wksp( + dctx->entropy.hufTable, dctx->litBuffer, litSize, + istart+lhSize, litCSize, dctx->workspace, + sizeof(dctx->workspace), flags); +#endif + } else { + hufSuccess = HUF_decompress4X_hufOnly_wksp( + dctx->entropy.hufTable, dctx->litBuffer, litSize, + istart+lhSize, litCSize, dctx->workspace, + sizeof(dctx->workspace), flags); + } + } + if (dctx->litBufferLocation == ZSTD_split) + { + assert(litSize > ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE); + dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH; + dctx->litBufferEnd -= WILDCOPY_OVERLENGTH; + assert(dctx->litBufferEnd <= (BYTE*)dst + blockSizeMax); + } + + RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, ""); + + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + dctx->litEntropy = 1; + if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable; + return litCSize + lhSize; + } + + case set_basic: + { size_t litSize, lhSize; + U32 const lhlCode = ((istart[0]) >> 2) & 3; + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); + switch(lhlCode) + { + case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ + lhSize = 1; + litSize = istart[0] >> 3; + break; + case 1: + lhSize = 2; + litSize = MEM_readLE16(istart) >> 4; + break; + case 3: + lhSize = 3; + RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize = 3"); + litSize = MEM_readLE24(istart) >> 4; + break; + } + + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); + RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1); + if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ + RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, ""); + if (dctx->litBufferLocation == ZSTD_split) + { + ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize - ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memcpy(dctx->litExtraBuffer, istart + lhSize + litSize - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE); + } + else + { + ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize); + } + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + return lhSize+litSize; + } + /* direct reference into compressed stream */ + dctx->litPtr = istart+lhSize; + dctx->litSize = litSize; + dctx->litBufferEnd = dctx->litPtr + litSize; + dctx->litBufferLocation = ZSTD_not_in_dst; + return lhSize+litSize; + } + + case set_rle: + { U32 const lhlCode = ((istart[0]) >> 2) & 3; + size_t litSize, lhSize; + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); + switch(lhlCode) + { + case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ + lhSize = 1; + litSize = istart[0] >> 3; + break; + case 1: + lhSize = 2; + RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 3"); + litSize = MEM_readLE16(istart) >> 4; + break; + case 3: + lhSize = 3; + RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 4"); + litSize = MEM_readLE24(istart) >> 4; + break; + } + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); + RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1); + if (dctx->litBufferLocation == ZSTD_split) + { + ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize - ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memset(dctx->litExtraBuffer, istart[lhSize], ZSTD_LITBUFFEREXTRASIZE); + } + else + { + ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize); + } + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + return lhSize+1; + } + default: + RETURN_ERROR(corruption_detected, "impossible"); + } + } +} + +/* Hidden declaration for fullbench */ +size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, + void* dst, size_t dstCapacity); +size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, + void* dst, size_t dstCapacity) +{ + dctx->isFrameDecompression = 0; + return ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, not_streaming); +} + +/* Default FSE distribution tables. + * These are pre-calculated FSE decoding tables using default distributions as defined in specification : + * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions + * They were generated programmatically with following method : + * - start from default distributions, present in /lib/common/zstd_internal.h + * - generate tables normally, using ZSTD_buildFSETable() + * - printout the content of tables + * - prettify output, report below, test with fuzzer to ensure it's correct */ + +/* Default FSE distribution table for Literal Lengths */ +static const ZSTD_seqSymbol LL_defaultDTable[(1<tableLog = 0; + DTableH->fastMode = 0; + + cell->nbBits = 0; + cell->nextState = 0; + assert(nbAddBits < 255); + cell->nbAdditionalBits = nbAddBits; + cell->baseValue = baseValue; +} + + +/* ZSTD_buildFSETable() : + * generate FSE decoding table for one symbol (ll, ml or off) + * cannot fail if input is valid => + * all inputs are presumed validated at this stage */ +FORCE_INLINE_TEMPLATE +void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt, + const short* normalizedCounter, unsigned maxSymbolValue, + const U32* baseValue, const U8* nbAdditionalBits, + unsigned tableLog, void* wksp, size_t wkspSize) +{ + ZSTD_seqSymbol* const tableDecode = dt+1; + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + + U16* symbolNext = (U16*)wksp; + BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1); + U32 highThreshold = tableSize - 1; + + + /* Sanity Checks */ + assert(maxSymbolValue <= MaxSeq); + assert(tableLog <= MaxFSELog); + assert(wkspSize >= ZSTD_BUILD_FSE_TABLE_WKSP_SIZE); + (void)wkspSize; + /* Init, lay down lowprob symbols */ + { ZSTD_seqSymbol_header DTableH; + DTableH.tableLog = tableLog; + DTableH.fastMode = 1; + { S16 const largeLimit= (S16)(1 << (tableLog-1)); + U32 s; + for (s=0; s= largeLimit) DTableH.fastMode=0; + assert(normalizedCounter[s]>=0); + symbolNext[s] = (U16)normalizedCounter[s]; + } } } + ZSTD_memcpy(dt, &DTableH, sizeof(DTableH)); + } + + /* Spread symbols */ + assert(tableSize <= 512); + /* Specialized symbol spreading for the case when there are + * no low probability (-1 count) symbols. When compressing + * small blocks we avoid low probability symbols to hit this + * case, since header decoding speed matters more. + */ + if (highThreshold == tableSize - 1) { + size_t const tableMask = tableSize-1; + size_t const step = FSE_TABLESTEP(tableSize); + /* First lay down the symbols in order. + * We use a uint64_t to lay down 8 bytes at a time. This reduces branch + * misses since small blocks generally have small table logs, so nearly + * all symbols have counts <= 8. We ensure we have 8 bytes at the end of + * our buffer to handle the over-write. + */ + { + U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s=0); + pos += (size_t)n; + } + } + /* Now we spread those positions across the table. + * The benefit of doing it in two stages is that we avoid the + * variable size inner loop, which caused lots of branch misses. + * Now we can run through all the positions without any branch misses. + * We unroll the loop twice, since that is what empirically worked best. + */ + { + size_t position = 0; + size_t s; + size_t const unroll = 2; + assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */ + for (s = 0; s < (size_t)tableSize; s += unroll) { + size_t u; + for (u = 0; u < unroll; ++u) { + size_t const uPosition = (position + (u * step)) & tableMask; + tableDecode[uPosition].baseValue = spread[s + u]; + } + position = (position + (unroll * step)) & tableMask; + } + assert(position == 0); + } + } else { + U32 const tableMask = tableSize-1; + U32 const step = FSE_TABLESTEP(tableSize); + U32 s, position = 0; + for (s=0; s highThreshold)) position = (position + step) & tableMask; /* lowprob area */ + } } + assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + } + + /* Build Decoding table */ + { + U32 u; + for (u=0; u max, corruption_detected, ""); + { U32 const symbol = *(const BYTE*)src; + U32 const baseline = baseValue[symbol]; + U8 const nbBits = nbAdditionalBits[symbol]; + ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits); + } + *DTablePtr = DTableSpace; + return 1; + case set_basic : + *DTablePtr = defaultTable; + return 0; + case set_repeat: + RETURN_ERROR_IF(!flagRepeatTable, corruption_detected, ""); + /* prefetch FSE table if used */ + if (ddictIsCold && (nbSeq > 24 /* heuristic */)) { + const void* const pStart = *DTablePtr; + size_t const pSize = sizeof(ZSTD_seqSymbol) * (SEQSYMBOL_TABLE_SIZE(maxLog)); + PREFETCH_AREA(pStart, pSize); + } + return 0; + case set_compressed : + { unsigned tableLog; + S16 norm[MaxSeq+1]; + size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); + RETURN_ERROR_IF(FSE_isError(headerSize), corruption_detected, ""); + RETURN_ERROR_IF(tableLog > maxLog, corruption_detected, ""); + ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog, wksp, wkspSize, bmi2); + *DTablePtr = DTableSpace; + return headerSize; + } + default : + assert(0); + RETURN_ERROR(GENERIC, "impossible"); + } +} + +size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, + const void* src, size_t srcSize) +{ + const BYTE* const istart = (const BYTE*)src; + const BYTE* const iend = istart + srcSize; + const BYTE* ip = istart; + int nbSeq; + DEBUGLOG(5, "ZSTD_decodeSeqHeaders"); + + /* check */ + RETURN_ERROR_IF(srcSize < MIN_SEQUENCES_SIZE, srcSize_wrong, ""); + + /* SeqHead */ + nbSeq = *ip++; + if (nbSeq > 0x7F) { + if (nbSeq == 0xFF) { + RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, ""); + nbSeq = MEM_readLE16(ip) + LONGNBSEQ; + ip+=2; + } else { + RETURN_ERROR_IF(ip >= iend, srcSize_wrong, ""); + nbSeq = ((nbSeq-0x80)<<8) + *ip++; + } + } + *nbSeqPtr = nbSeq; + + if (nbSeq == 0) { + /* No sequence : section ends immediately */ + RETURN_ERROR_IF(ip != iend, corruption_detected, + "extraneous data present in the Sequences section"); + return (size_t)(ip - istart); + } + + /* FSE table descriptors */ + RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong, ""); /* minimum possible size: 1 byte for symbol encoding types */ + RETURN_ERROR_IF(*ip & 3, corruption_detected, ""); /* The last field, Reserved, must be all-zeroes. */ + { SymbolEncodingType_e const LLtype = (SymbolEncodingType_e)(*ip >> 6); + SymbolEncodingType_e const OFtype = (SymbolEncodingType_e)((*ip >> 4) & 3); + SymbolEncodingType_e const MLtype = (SymbolEncodingType_e)((*ip >> 2) & 3); + ip++; + + /* Build DTables */ + { size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr, + LLtype, MaxLL, LLFSELog, + ip, iend-ip, + LL_base, LL_bits, + LL_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + ZSTD_DCtx_get_bmi2(dctx)); + RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected, "ZSTD_buildSeqTable failed"); + ip += llhSize; + } + + { size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr, + OFtype, MaxOff, OffFSELog, + ip, iend-ip, + OF_base, OF_bits, + OF_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + ZSTD_DCtx_get_bmi2(dctx)); + RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected, "ZSTD_buildSeqTable failed"); + ip += ofhSize; + } + + { size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr, + MLtype, MaxML, MLFSELog, + ip, iend-ip, + ML_base, ML_bits, + ML_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + ZSTD_DCtx_get_bmi2(dctx)); + RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected, "ZSTD_buildSeqTable failed"); + ip += mlhSize; + } + } + + return ip-istart; +} + + +typedef struct { + size_t litLength; + size_t matchLength; + size_t offset; +} seq_t; + +typedef struct { + size_t state; + const ZSTD_seqSymbol* table; +} ZSTD_fseState; + +typedef struct { + BIT_DStream_t DStream; + ZSTD_fseState stateLL; + ZSTD_fseState stateOffb; + ZSTD_fseState stateML; + size_t prevOffset[ZSTD_REP_NUM]; +} seqState_t; + +/*! ZSTD_overlapCopy8() : + * Copies 8 bytes from ip to op and updates op and ip where ip <= op. + * If the offset is < 8 then the offset is spread to at least 8 bytes. + * + * Precondition: *ip <= *op + * Postcondition: *op - *op >= 8 + */ +HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) { + assert(*ip <= *op); + if (offset < 8) { + /* close range match, overlap */ + static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ + static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */ + int const sub2 = dec64table[offset]; + (*op)[0] = (*ip)[0]; + (*op)[1] = (*ip)[1]; + (*op)[2] = (*ip)[2]; + (*op)[3] = (*ip)[3]; + *ip += dec32table[offset]; + ZSTD_copy4(*op+4, *ip); + *ip -= sub2; + } else { + ZSTD_copy8(*op, *ip); + } + *ip += 8; + *op += 8; + assert(*op - *ip >= 8); +} + +/*! ZSTD_safecopy() : + * Specialized version of memcpy() that is allowed to READ up to WILDCOPY_OVERLENGTH past the input buffer + * and write up to 16 bytes past oend_w (op >= oend_w is allowed). + * This function is only called in the uncommon case where the sequence is near the end of the block. It + * should be fast for a single long sequence, but can be slow for several short sequences. + * + * @param ovtype controls the overlap detection + * - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart. + * - ZSTD_overlap_src_before_dst: The src and dst may overlap and may be any distance apart. + * The src buffer must be before the dst buffer. + */ +static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) { + ptrdiff_t const diff = op - ip; + BYTE* const oend = op + length; + + assert((ovtype == ZSTD_no_overlap && (diff <= -8 || diff >= 8 || op >= oend_w)) || + (ovtype == ZSTD_overlap_src_before_dst && diff >= 0)); + + if (length < 8) { + /* Handle short lengths. */ + while (op < oend) *op++ = *ip++; + return; + } + if (ovtype == ZSTD_overlap_src_before_dst) { + /* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */ + assert(length >= 8); + ZSTD_overlapCopy8(&op, &ip, diff); + length -= 8; + assert(op - ip >= 8); + assert(op <= oend); + } + + if (oend <= oend_w) { + /* No risk of overwrite. */ + ZSTD_wildcopy(op, ip, length, ovtype); + return; + } + if (op <= oend_w) { + /* Wildcopy until we get close to the end. */ + assert(oend > oend_w); + ZSTD_wildcopy(op, ip, oend_w - op, ovtype); + ip += oend_w - op; + op += oend_w - op; + } + /* Handle the leftovers. */ + while (op < oend) *op++ = *ip++; +} + +/* ZSTD_safecopyDstBeforeSrc(): + * This version allows overlap with dst before src, or handles the non-overlap case with dst after src + * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */ +static void ZSTD_safecopyDstBeforeSrc(BYTE* op, const BYTE* ip, ptrdiff_t length) { + ptrdiff_t const diff = op - ip; + BYTE* const oend = op + length; + + if (length < 8 || diff > -8) { + /* Handle short lengths, close overlaps, and dst not before src. */ + while (op < oend) *op++ = *ip++; + return; + } + + if (op <= oend - WILDCOPY_OVERLENGTH && diff < -WILDCOPY_VECLEN) { + ZSTD_wildcopy(op, ip, oend - WILDCOPY_OVERLENGTH - op, ZSTD_no_overlap); + ip += oend - WILDCOPY_OVERLENGTH - op; + op += oend - WILDCOPY_OVERLENGTH - op; + } + + /* Handle the leftovers. */ + while (op < oend) *op++ = *ip++; +} + +/* ZSTD_execSequenceEnd(): + * This version handles cases that are near the end of the output buffer. It requires + * more careful checks to make sure there is no overflow. By separating out these hard + * and unlikely cases, we can speed up the common cases. + * + * NOTE: This function needs to be fast for a single long sequence, but doesn't need + * to be optimized for many small sequences, since those fall into ZSTD_execSequence(). + */ +FORCE_NOINLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequenceEnd(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; + + /* bounds checks : careful of address space overflow in 32-bit mode */ + RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer"); + RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer"); + assert(op < op + sequenceLength); + assert(oLitEnd < op + sequenceLength); + + /* copy literals */ + ZSTD_safecopy(op, oend_w, *litPtr, sequence.litLength, ZSTD_no_overlap); + op = oLitEnd; + *litPtr = iLitEnd; + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix */ + RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, ""); + match = dictEnd - (prefixStart - match); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst); + return sequenceLength; +} + +/* ZSTD_execSequenceEndSplitLitBuffer(): + * This version is intended to be used during instances where the litBuffer is still split. It is kept separate to avoid performance impact for the good case. + */ +FORCE_NOINLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op, + BYTE* const oend, const BYTE* const oend_w, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + + /* bounds checks : careful of address space overflow in 32-bit mode */ + RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer"); + RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer"); + assert(op < op + sequenceLength); + assert(oLitEnd < op + sequenceLength); + + /* copy literals */ + RETURN_ERROR_IF(op > *litPtr && op < *litPtr + sequence.litLength, dstSize_tooSmall, "output should not catch up to and overwrite literal buffer"); + ZSTD_safecopyDstBeforeSrc(op, *litPtr, sequence.litLength); + op = oLitEnd; + *litPtr = iLitEnd; + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix */ + RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, ""); + match = dictEnd - (prefixStart - match); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst); + return sequenceLength; +} + +HINT_INLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequence(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; /* risk : address space underflow on oend=NULL */ + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + assert(op != NULL /* Precondition */); + assert(oend_w < oend /* No underflow */); + +#if defined(__aarch64__) + /* prefetch sequence starting from match that will be used for copy later */ + PREFETCH_L1(match); +#endif + /* Handle edge cases in a slow path: + * - Read beyond end of literals + * - Match end is within WILDCOPY_OVERLIMIT of oend + * - 32-bit mode and the match length overflows + */ + if (UNLIKELY( + iLitEnd > litLimit || + oMatchEnd > oend_w || + (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH))) + return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); + + /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */ + assert(op <= oLitEnd /* No overflow */); + assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */); + assert(oMatchEnd <= oend /* No underflow */); + assert(iLitEnd <= litLimit /* Literal length is in bounds */); + assert(oLitEnd <= oend_w /* Can wildcopy literals */); + assert(oMatchEnd <= oend_w /* Can wildcopy matches */); + + /* Copy Literals: + * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9. + * We likely don't need the full 32-byte wildcopy. + */ + assert(WILDCOPY_OVERLENGTH >= 16); + ZSTD_copy16(op, (*litPtr)); + if (UNLIKELY(sequence.litLength > 16)) { + ZSTD_wildcopy(op + 16, (*litPtr) + 16, sequence.litLength - 16, ZSTD_no_overlap); + } + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* Copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix -> go into extDict */ + RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, ""); + match = dictEnd + (match - prefixStart); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + /* Match within prefix of 1 or more bytes */ + assert(op <= oMatchEnd); + assert(oMatchEnd <= oend_w); + assert(match >= prefixStart); + assert(sequence.matchLength >= 1); + + /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy + * without overlap checking. + */ + if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) { + /* We bet on a full wildcopy for matches, since we expect matches to be + * longer than literals (in general). In silesia, ~10% of matches are longer + * than 16 bytes. + */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap); + return sequenceLength; + } + assert(sequence.offset < WILDCOPY_VECLEN); + + /* Copy 8 bytes and spread the offset to be >= 8. */ + ZSTD_overlapCopy8(&op, &match, sequence.offset); + + /* If the match length is > 8 bytes, then continue with the wildcopy. */ + if (sequence.matchLength > 8) { + assert(op < oMatchEnd); + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8, ZSTD_overlap_src_before_dst); + } + return sequenceLength; +} + +HINT_INLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op, + BYTE* const oend, const BYTE* const oend_w, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + assert(op != NULL /* Precondition */); + assert(oend_w < oend /* No underflow */); + /* Handle edge cases in a slow path: + * - Read beyond end of literals + * - Match end is within WILDCOPY_OVERLIMIT of oend + * - 32-bit mode and the match length overflows + */ + if (UNLIKELY( + iLitEnd > litLimit || + oMatchEnd > oend_w || + (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH))) + return ZSTD_execSequenceEndSplitLitBuffer(op, oend, oend_w, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); + + /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */ + assert(op <= oLitEnd /* No overflow */); + assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */); + assert(oMatchEnd <= oend /* No underflow */); + assert(iLitEnd <= litLimit /* Literal length is in bounds */); + assert(oLitEnd <= oend_w /* Can wildcopy literals */); + assert(oMatchEnd <= oend_w /* Can wildcopy matches */); + + /* Copy Literals: + * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9. + * We likely don't need the full 32-byte wildcopy. + */ + assert(WILDCOPY_OVERLENGTH >= 16); + ZSTD_copy16(op, (*litPtr)); + if (UNLIKELY(sequence.litLength > 16)) { + ZSTD_wildcopy(op+16, (*litPtr)+16, sequence.litLength-16, ZSTD_no_overlap); + } + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* Copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix -> go into extDict */ + RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, ""); + match = dictEnd + (match - prefixStart); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } } + /* Match within prefix of 1 or more bytes */ + assert(op <= oMatchEnd); + assert(oMatchEnd <= oend_w); + assert(match >= prefixStart); + assert(sequence.matchLength >= 1); + + /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy + * without overlap checking. + */ + if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) { + /* We bet on a full wildcopy for matches, since we expect matches to be + * longer than literals (in general). In silesia, ~10% of matches are longer + * than 16 bytes. + */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap); + return sequenceLength; + } + assert(sequence.offset < WILDCOPY_VECLEN); + + /* Copy 8 bytes and spread the offset to be >= 8. */ + ZSTD_overlapCopy8(&op, &match, sequence.offset); + + /* If the match length is > 8 bytes, then continue with the wildcopy. */ + if (sequence.matchLength > 8) { + assert(op < oMatchEnd); + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8, ZSTD_overlap_src_before_dst); + } + return sequenceLength; +} + + +static void +ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt) +{ + const void* ptr = dt; + const ZSTD_seqSymbol_header* const DTableH = (const ZSTD_seqSymbol_header*)ptr; + DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); + DEBUGLOG(6, "ZSTD_initFseState : val=%u using %u bits", + (U32)DStatePtr->state, DTableH->tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +FORCE_INLINE_TEMPLATE void +ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16 nextState, U32 nbBits) +{ + size_t const lowBits = BIT_readBits(bitD, nbBits); + DStatePtr->state = nextState + lowBits; +} + +/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum + * offset bits. But we can only read at most STREAM_ACCUMULATOR_MIN_32 + * bits before reloading. This value is the maximum number of bytes we read + * after reloading when we are decoding long offsets. + */ +#define LONG_OFFSETS_MAX_EXTRA_BITS_32 \ + (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \ + ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \ + : 0) + +typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e; + +/** + * ZSTD_decodeSequence(): + * @p longOffsets : tells the decoder to reload more bit while decoding large offsets + * only used in 32-bit mode + * @return : Sequence (litL + matchL + offset) + */ +FORCE_INLINE_TEMPLATE seq_t +ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq) +{ + seq_t seq; + /* + * ZSTD_seqSymbol is a 64 bits wide structure. + * It can be loaded in one operation + * and its fields extracted by simply shifting or bit-extracting on aarch64. + * GCC doesn't recognize this and generates more unnecessary ldr/ldrb/ldrh + * operations that cause performance drop. This can be avoided by using this + * ZSTD_memcpy hack. + */ +#if defined(__aarch64__) && (defined(__GNUC__) && !defined(__clang__)) + ZSTD_seqSymbol llDInfoS, mlDInfoS, ofDInfoS; + ZSTD_seqSymbol* const llDInfo = &llDInfoS; + ZSTD_seqSymbol* const mlDInfo = &mlDInfoS; + ZSTD_seqSymbol* const ofDInfo = &ofDInfoS; + ZSTD_memcpy(llDInfo, seqState->stateLL.table + seqState->stateLL.state, sizeof(ZSTD_seqSymbol)); + ZSTD_memcpy(mlDInfo, seqState->stateML.table + seqState->stateML.state, sizeof(ZSTD_seqSymbol)); + ZSTD_memcpy(ofDInfo, seqState->stateOffb.table + seqState->stateOffb.state, sizeof(ZSTD_seqSymbol)); +#else + const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state; + const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state; + const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state; +#endif + seq.matchLength = mlDInfo->baseValue; + seq.litLength = llDInfo->baseValue; + { U32 const ofBase = ofDInfo->baseValue; + BYTE const llBits = llDInfo->nbAdditionalBits; + BYTE const mlBits = mlDInfo->nbAdditionalBits; + BYTE const ofBits = ofDInfo->nbAdditionalBits; + BYTE const totalBits = llBits+mlBits+ofBits; + + U16 const llNext = llDInfo->nextState; + U16 const mlNext = mlDInfo->nextState; + U16 const ofNext = ofDInfo->nextState; + U32 const llnbBits = llDInfo->nbBits; + U32 const mlnbBits = mlDInfo->nbBits; + U32 const ofnbBits = ofDInfo->nbBits; + + assert(llBits <= MaxLLBits); + assert(mlBits <= MaxMLBits); + assert(ofBits <= MaxOff); + /* + * As gcc has better branch and block analyzers, sometimes it is only + * valuable to mark likeliness for clang, it gives around 3-4% of + * performance. + */ + + /* sequence */ + { size_t offset; + if (ofBits > 1) { + ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); + ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); + ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 > LONG_OFFSETS_MAX_EXTRA_BITS_32); + ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 - LONG_OFFSETS_MAX_EXTRA_BITS_32 >= MaxMLBits); + if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) { + /* Always read extra bits, this keeps the logic simple, + * avoids branches, and avoids accidentally reading 0 bits. + */ + U32 const extraBits = LONG_OFFSETS_MAX_EXTRA_BITS_32; + offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); + BIT_reloadDStream(&seqState->DStream); + offset += BIT_readBitsFast(&seqState->DStream, extraBits); + } else { + offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); + } + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + } else { + U32 const ll0 = (llDInfo->baseValue == 0); + if (LIKELY((ofBits == 0))) { + offset = seqState->prevOffset[ll0]; + seqState->prevOffset[1] = seqState->prevOffset[!ll0]; + seqState->prevOffset[0] = offset; + } else { + offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1); + { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; + temp -= !temp; /* 0 is not valid: input corrupted => force offset to -1 => corruption detected at execSequence */ + if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } } } + seq.offset = offset; + } + + if (mlBits > 0) + seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/); + + if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) + BIT_reloadDStream(&seqState->DStream); + if (MEM_64bits() && UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) + BIT_reloadDStream(&seqState->DStream); + /* Ensure there are enough bits to read the rest of data in 64-bit mode. */ + ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); + + if (llBits > 0) + seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/); + + if (MEM_32bits()) + BIT_reloadDStream(&seqState->DStream); + + DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", + (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); + + if (!isLastSeq) { + /* don't update FSE state for last Sequence */ + ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */ + BIT_reloadDStream(&seqState->DStream); + } + } + + return seq; +} + +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) +#if DEBUGLEVEL >= 1 +static int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd) +{ + size_t const windowSize = dctx->fParams.windowSize; + /* No dictionary used. */ + if (dctx->dictContentEndForFuzzing == NULL) return 0; + /* Dictionary is our prefix. */ + if (prefixStart == dctx->dictContentBeginForFuzzing) return 1; + /* Dictionary is not our ext-dict. */ + if (dctx->dictEnd != dctx->dictContentEndForFuzzing) return 0; + /* Dictionary is not within our window size. */ + if ((size_t)(oLitEnd - prefixStart) >= windowSize) return 0; + /* Dictionary is active. */ + return 1; +} +#endif + +static void ZSTD_assertValidSequence( + ZSTD_DCtx const* dctx, + BYTE const* op, BYTE const* oend, + seq_t const seq, + BYTE const* prefixStart, BYTE const* virtualStart) +{ +#if DEBUGLEVEL >= 1 + if (dctx->isFrameDecompression) { + size_t const windowSize = dctx->fParams.windowSize; + size_t const sequenceSize = seq.litLength + seq.matchLength; + BYTE const* const oLitEnd = op + seq.litLength; + DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u", + (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); + assert(op <= oend); + assert((size_t)(oend - op) >= sequenceSize); + assert(sequenceSize <= ZSTD_blockSizeMax(dctx)); + if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) { + size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing); + /* Offset must be within the dictionary. */ + assert(seq.offset <= (size_t)(oLitEnd - virtualStart)); + assert(seq.offset <= windowSize + dictSize); + } else { + /* Offset must be within our window. */ + assert(seq.offset <= windowSize); + } + } +#else + (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart; +#endif +} +#endif + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG + + +FORCE_INLINE_TEMPLATE size_t +DONT_VECTORIZE +ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, maxDstSize); + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* litBufferEnd = dctx->litBufferEnd; + const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); + const BYTE* const vBase = (const BYTE*) (dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer (%i seqs)", nbSeq); + + /* Literals are split between internal buffer & output buffer */ + if (nbSeq) { + seqState_t seqState; + dctx->fseEntropy = 1; + { U32 i; for (i=0; ientropy.rep[i]; } + RETURN_ERROR_IF( + ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)), + corruption_detected, ""); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + assert(dst != NULL); + + ZSTD_STATIC_ASSERT( + BIT_DStream_unfinished < BIT_DStream_completed && + BIT_DStream_endOfBuffer < BIT_DStream_completed && + BIT_DStream_completed < BIT_DStream_overflow); + + /* decompress without overrunning litPtr begins */ + { seq_t sequence = {0,0,0}; /* some static analyzer believe that @sequence is not initialized (it necessarily is, since for(;;) loop as at least one iteration) */ + /* Align the decompression loop to 32 + 16 bytes. + * + * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression + * speed swings based on the alignment of the decompression loop. This + * performance swing is caused by parts of the decompression loop falling + * out of the DSB. The entire decompression loop should fit in the DSB, + * when it can't we get much worse performance. You can measure if you've + * hit the good case or the bad case with this perf command for some + * compressed file test.zst: + * + * perf stat -e cycles -e instructions -e idq.all_dsb_cycles_any_uops \ + * -e idq.all_mite_cycles_any_uops -- ./zstd -tq test.zst + * + * If you see most cycles served out of the MITE you've hit the bad case. + * If you see most cycles served out of the DSB you've hit the good case. + * If it is pretty even then you may be in an okay case. + * + * This issue has been reproduced on the following CPUs: + * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9 + * Use Instruments->Counters to get DSB/MITE cycles. + * I never got performance swings, but I was able to + * go from the good case of mostly DSB to half of the + * cycles served from MITE. + * - Coffeelake: Intel i9-9900k + * - Coffeelake: Intel i7-9700k + * + * I haven't been able to reproduce the instability or DSB misses on any + * of the following CPUS: + * - Haswell + * - Broadwell: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GH + * - Skylake + * + * Alignment is done for each of the three major decompression loops: + * - ZSTD_decompressSequences_bodySplitLitBuffer - presplit section of the literal buffer + * - ZSTD_decompressSequences_bodySplitLitBuffer - postsplit section of the literal buffer + * - ZSTD_decompressSequences_body + * Alignment choices are made to minimize large swings on bad cases and influence on performance + * from changes external to this code, rather than to overoptimize on the current commit. + * + * If you are seeing performance stability this script can help test. + * It tests on 4 commits in zstd where I saw performance change. + * + * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4 + */ +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); +# if __GNUC__ >= 7 + /* good for gcc-7, gcc-9, and gcc-11 */ + __asm__("nop"); + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 4"); +# if __GNUC__ == 8 || __GNUC__ == 10 + /* good for gcc-8 and gcc-10 */ + __asm__("nop"); + __asm__(".p2align 3"); +# endif +# endif +#endif + + /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */ + for ( ; nbSeq; nbSeq--) { + sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); + if (litPtr + sequence.litLength > dctx->litBufferEnd) break; + { size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } } + DEBUGLOG(6, "reached: (litPtr + sequence.litLength > dctx->litBufferEnd)"); + + /* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */ + if (nbSeq > 0) { + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + DEBUGLOG(6, "There are %i sequences left, and %zu/%zu literals left in buffer", nbSeq, leftoverLit, sequence.litLength); + if (leftoverLit) { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequence.litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } + nbSeq--; + } + } + + if (nbSeq > 0) { + /* there is remaining lit from extra buffer */ + +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); + __asm__("nop"); +# if __GNUC__ != 7 + /* worse for gcc-7 better for gcc-8, gcc-9, and gcc-10 and clang */ + __asm__(".p2align 4"); + __asm__("nop"); + __asm__(".p2align 3"); +# elif __GNUC__ >= 11 + __asm__(".p2align 3"); +# else + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 3"); +# endif +#endif + + for ( ; nbSeq ; nbSeq--) { + seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } + } + + /* check if reached exact end */ + DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq); + RETURN_ERROR_IF(nbSeq, corruption_detected, ""); + DEBUGLOG(5, "bitStream : start=%p, ptr=%p, bitsConsumed=%u", seqState.DStream.start, seqState.DStream.ptr, seqState.DStream.bitsConsumed); + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + if (dctx->litBufferLocation == ZSTD_split) { + /* split hasn't been reached yet, first get dst then copy litExtraBuffer */ + size_t const lastLLSize = (size_t)(litBufferEnd - litPtr); + DEBUGLOG(6, "copy last literals from segment : %u", (U32)lastLLSize); + RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + } + /* copy last literals from internal buffer */ + { size_t const lastLLSize = (size_t)(litBufferEnd - litPtr); + DEBUGLOG(6, "copy last literals from internal buffer : %u", (U32)lastLLSize); + RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } } + + DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart)); + return (size_t)(op - ostart); +} + +FORCE_INLINE_TEMPLATE size_t +DONT_VECTORIZE +ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ZSTD_maybeNullPtrAdd(ostart, maxDstSize) : dctx->litBuffer; + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* const prefixStart = (const BYTE*)(dctx->prefixStart); + const BYTE* const vBase = (const BYTE*)(dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd); + DEBUGLOG(5, "ZSTD_decompressSequences_body: nbSeq = %d", nbSeq); + + /* Regen sequences */ + if (nbSeq) { + seqState_t seqState; + dctx->fseEntropy = 1; + { U32 i; for (i = 0; i < ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; } + RETURN_ERROR_IF( + ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend - ip)), + corruption_detected, ""); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + assert(dst != NULL); + +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); + __asm__("nop"); +# if __GNUC__ >= 7 + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 3"); +# else + __asm__(".p2align 4"); + __asm__("nop"); + __asm__(".p2align 3"); +# endif +#endif + + for ( ; nbSeq ; nbSeq--) { + seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } + + /* check if reached exact end */ + assert(nbSeq == 0); + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + { size_t const lastLLSize = (size_t)(litEnd - litPtr); + DEBUGLOG(6, "copy last literals : %u", (U32)lastLLSize); + RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } } + + DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart)); + return (size_t)(op - ostart); +} + +static size_t +ZSTD_decompressSequences_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} + +static size_t +ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT + +FORCE_INLINE_TEMPLATE + +size_t ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence, + const BYTE* const prefixStart, const BYTE* const dictEnd) +{ + prefetchPos += sequence.litLength; + { const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart; + /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted. + * No consequence though : memory address is only used for prefetching, not for dereferencing */ + const BYTE* const match = ZSTD_wrappedPtrSub(ZSTD_wrappedPtrAdd(matchBase, prefetchPos), sequence.offset); + PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */ + } + return prefetchPos + sequence.matchLength; +} + +/* This decoding function employs prefetching + * to reduce latency impact of cache misses. + * It's generally employed when block contains a significant portion of long-distance matches + * or when coupled with a "cold" dictionary */ +FORCE_INLINE_TEMPLATE size_t +ZSTD_decompressSequencesLong_body( + ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ZSTD_maybeNullPtrAdd(ostart, maxDstSize); + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* litBufferEnd = dctx->litBufferEnd; + const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); + const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + + /* Regen sequences */ + if (nbSeq) { +#define STORED_SEQS 8 +#define STORED_SEQS_MASK (STORED_SEQS-1) +#define ADVANCED_SEQS STORED_SEQS + seq_t sequences[STORED_SEQS]; + int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); + seqState_t seqState; + int seqNb; + size_t prefetchPos = (size_t)(op-prefixStart); /* track position relative to prefixStart */ + + dctx->fseEntropy = 1; + { int i; for (i=0; ientropy.rep[i]; } + assert(dst != NULL); + assert(iend >= ip); + RETURN_ERROR_IF( + ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)), + corruption_detected, ""); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + + /* prepare in advance */ + for (seqNb=0; seqNblitBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) { + /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */ + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + if (leftoverLit) + { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + + prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); + sequences[seqNb & STORED_SEQS_MASK] = sequence; + op += oneSeqSize; + } } + else + { + /* lit buffer is either wholly contained in first or second split, or not split at all*/ + size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ? + ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength - WILDCOPY_OVERLENGTH, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) : + ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + + prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); + sequences[seqNb & STORED_SEQS_MASK] = sequence; + op += oneSeqSize; + } + } + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); + + /* finish queue */ + seqNb -= seqAdvance; + for ( ; seqNblitBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) { + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + if (leftoverLit) { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequence->litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } + } + else + { + size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ? + ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence->litLength - WILDCOPY_OVERLENGTH, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) : + ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } + } + + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + if (dctx->litBufferLocation == ZSTD_split) { /* first deplete literal buffer in dst, then copy litExtraBuffer */ + size_t const lastLLSize = litBufferEnd - litPtr; + RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + } + { size_t const lastLLSize = litBufferEnd - litPtr; + RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + } + + return (size_t)(op - ostart); +} + +static size_t +ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ + + + +#if DYNAMIC_BMI2 + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG +static BMI2_TARGET_ATTRIBUTE size_t +DONT_VECTORIZE +ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +static BMI2_TARGET_ATTRIBUTE size_t +DONT_VECTORIZE +ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT +static BMI2_TARGET_ATTRIBUTE size_t +ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ + +#endif /* DYNAMIC_BMI2 */ + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG +static size_t +ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequences"); +#if DYNAMIC_BMI2 + if (ZSTD_DCtx_get_bmi2(dctx)) { + return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +static size_t +ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer"); +#if DYNAMIC_BMI2 + if (ZSTD_DCtx_get_bmi2(dctx)) { + return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ + + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT +/* ZSTD_decompressSequencesLong() : + * decompression function triggered when a minimum share of offsets is considered "long", + * aka out of cache. + * note : "long" definition seems overloaded here, sometimes meaning "wider than bitstream register", and sometimes meaning "farther than memory cache distance". + * This function will try to mitigate main memory latency through the use of prefetching */ +static size_t +ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequencesLong"); +#if DYNAMIC_BMI2 + if (ZSTD_DCtx_get_bmi2(dctx)) { + return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ + + +/** + * @returns The total size of the history referenceable by zstd, including + * both the prefix and the extDict. At @p op any offset larger than this + * is invalid. + */ +static size_t ZSTD_totalHistorySize(BYTE* op, BYTE const* virtualStart) +{ + return (size_t)(op - virtualStart); +} + +typedef struct { + unsigned longOffsetShare; + unsigned maxNbAdditionalBits; +} ZSTD_OffsetInfo; + +/* ZSTD_getOffsetInfo() : + * condition : offTable must be valid + * @return : "share" of long offsets (arbitrarily defined as > (1<<23)) + * compared to maximum possible of (1< 22) info.longOffsetShare += 1; + } + + assert(tableLog <= OffFSELog); + info.longOffsetShare <<= (OffFSELog - tableLog); /* scale to OffFSELog */ + } + + return info; +} + +/** + * @returns The maximum offset we can decode in one read of our bitstream, without + * reloading more bits in the middle of the offset bits read. Any offsets larger + * than this must use the long offset decoder. + */ +static size_t ZSTD_maxShortOffset(void) +{ + if (MEM_64bits()) { + /* We can decode any offset without reloading bits. + * This might change if the max window size grows. + */ + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31); + return (size_t)-1; + } else { + /* The maximum offBase is (1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1. + * This offBase would require STREAM_ACCUMULATOR_MIN extra bits. + * Then we have to subtract ZSTD_REP_NUM to get the maximum possible offset. + */ + size_t const maxOffbase = ((size_t)1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1; + size_t const maxOffset = maxOffbase - ZSTD_REP_NUM; + assert(ZSTD_highbit32((U32)maxOffbase) == STREAM_ACCUMULATOR_MIN); + return maxOffset; + } +} + +size_t +ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, const streaming_operation streaming) +{ /* blockType == blockCompressed */ + const BYTE* ip = (const BYTE*)src; + DEBUGLOG(5, "ZSTD_decompressBlock_internal (cSize : %u)", (unsigned)srcSize); + + /* Note : the wording of the specification + * allows compressed block to be sized exactly ZSTD_blockSizeMax(dctx). + * This generally does not happen, as it makes little sense, + * since an uncompressed block would feature same size and have no decompression cost. + * Also, note that decoder from reference libzstd before < v1.5.4 + * would consider this edge case as an error. + * As a consequence, avoid generating compressed blocks of size ZSTD_blockSizeMax(dctx) + * for broader compatibility with the deployed ecosystem of zstd decoders */ + RETURN_ERROR_IF(srcSize > ZSTD_blockSizeMax(dctx), srcSize_wrong, ""); + + /* Decode literals section */ + { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming); + DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : cSize=%u, nbLiterals=%zu", (U32)litCSize, dctx->litSize); + if (ZSTD_isError(litCSize)) return litCSize; + ip += litCSize; + srcSize -= litCSize; + } + + /* Build Decoding Tables */ + { + /* Compute the maximum block size, which must also work when !frame and fParams are unset. + * Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t. + */ + size_t const blockSizeMax = MIN(dstCapacity, ZSTD_blockSizeMax(dctx)); + size_t const totalHistorySize = ZSTD_totalHistorySize(ZSTD_maybeNullPtrAdd((BYTE*)dst, blockSizeMax), (BYTE const*)dctx->virtualStart); + /* isLongOffset must be true if there are long offsets. + * Offsets are long if they are larger than ZSTD_maxShortOffset(). + * We don't expect that to be the case in 64-bit mode. + * + * We check here to see if our history is large enough to allow long offsets. + * If it isn't, then we can't possible have (valid) long offsets. If the offset + * is invalid, then it is okay to read it incorrectly. + * + * If isLongOffsets is true, then we will later check our decoding table to see + * if it is even possible to generate long offsets. + */ + ZSTD_longOffset_e isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (totalHistorySize > ZSTD_maxShortOffset())); + /* These macros control at build-time which decompressor implementation + * we use. If neither is defined, we do some inspection and dispatch at + * runtime. + */ +#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ + !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) + int usePrefetchDecoder = dctx->ddictIsCold; +#else + /* Set to 1 to avoid computing offset info if we don't need to. + * Otherwise this value is ignored. + */ + int usePrefetchDecoder = 1; +#endif + int nbSeq; + size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize); + if (ZSTD_isError(seqHSize)) return seqHSize; + ip += seqHSize; + srcSize -= seqHSize; + + RETURN_ERROR_IF((dst == NULL || dstCapacity == 0) && nbSeq > 0, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(MEM_64bits() && sizeof(size_t) == sizeof(void*) && (size_t)(-1) - (size_t)dst < (size_t)(1 << 20), dstSize_tooSmall, + "invalid dst"); + + /* If we could potentially have long offsets, or we might want to use the prefetch decoder, + * compute information about the share of long offsets, and the maximum nbAdditionalBits. + * NOTE: could probably use a larger nbSeq limit + */ + if (isLongOffset || (!usePrefetchDecoder && (totalHistorySize > (1u << 24)) && (nbSeq > 8))) { + ZSTD_OffsetInfo const info = ZSTD_getOffsetInfo(dctx->OFTptr, nbSeq); + if (isLongOffset && info.maxNbAdditionalBits <= STREAM_ACCUMULATOR_MIN) { + /* If isLongOffset, but the maximum number of additional bits that we see in our table is small + * enough, then we know it is impossible to have too long an offset in this block, so we can + * use the regular offset decoder. + */ + isLongOffset = ZSTD_lo_isRegularOffset; + } + if (!usePrefetchDecoder) { + U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */ + usePrefetchDecoder = (info.longOffsetShare >= minShare); + } + } + + dctx->ddictIsCold = 0; + +#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ + !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) + if (usePrefetchDecoder) { +#else + (void)usePrefetchDecoder; + { +#endif +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT + return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); +#endif + } + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG + /* else */ + if (dctx->litBufferLocation == ZSTD_split) + return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); + else + return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); +#endif + } +} + + +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize) +{ + if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */ + dctx->dictEnd = dctx->previousDstEnd; + dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart)); + dctx->prefixStart = dst; + dctx->previousDstEnd = dst; + } +} diff --git a/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.h b/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.h new file mode 100644 index 0000000000..d8ece22cfb --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +#ifndef ZSTD_DEC_BLOCK_H +#define ZSTD_DEC_BLOCK_H + +/*-******************************************************* + * Dependencies + *********************************************************/ +#include "../common/zstd_deps.h" /* size_t */ +#include "../zstd.h" /* DCtx, and some public functions */ +#include "../common/zstd_internal.h" /* blockProperties_t, and some public functions */ +#include "zstd_decompress_internal.h" /* ZSTD_seqSymbol */ + + +/* === Prototypes === */ + +/* note: prototypes already published within `zstd.h` : + * ZSTD_decompressBlock() + */ + +/* note: prototypes already published within `zstd_internal.h` : + * ZSTD_getcBlockSize() + * ZSTD_decodeSeqHeaders() + */ + + + /* Streaming state is used to inform allocation of the literal buffer */ +typedef enum { + not_streaming = 0, + is_streaming = 1 +} streaming_operation; + +/* ZSTD_decompressBlock_internal() : + * decompress block, starting at `src`, + * into destination buffer `dst`. + * @return : decompressed block size, + * or an error code (which can be tested using ZSTD_isError()) + */ +size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, const streaming_operation streaming); + +/* ZSTD_buildFSETable() : + * generate FSE decoding table for one symbol (ll, ml or off) + * this function must be called with valid parameters only + * (dt is large enough, normalizedCounter distribution total is a power of 2, max is within range, etc.) + * in which case it cannot fail. + * The workspace must be 4-byte aligned and at least ZSTD_BUILD_FSE_TABLE_WKSP_SIZE bytes, which is + * defined in zstd_decompress_internal.h. + * Internal use only. + */ +void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, + const short* normalizedCounter, unsigned maxSymbolValue, + const U32* baseValue, const U8* nbAdditionalBits, + unsigned tableLog, void* wksp, size_t wkspSize, + int bmi2); + +#endif /* ZSTD_DEC_BLOCK_H */ diff --git a/src/commonlib/bsd/zstd/decompress/zstd_decompress_internal.h b/src/commonlib/bsd/zstd/decompress/zstd_decompress_internal.h new file mode 100644 index 0000000000..ae1d750378 --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_decompress_internal.h @@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/* zstd_decompress_internal: + * objects and definitions shared within lib/decompress modules */ + + #ifndef ZSTD_DECOMPRESS_INTERNAL_H + #define ZSTD_DECOMPRESS_INTERNAL_H + + +/*-******************************************************* + * Dependencies + *********************************************************/ +#include "../common/mem.h" /* BYTE, U16, U32 */ +#include "../common/zstd_internal.h" /* constants : MaxLL, MaxML, MaxOff, LLFSELog, etc. */ + + + +/*-******************************************************* + * Constants + *********************************************************/ +static UNUSED_ATTR const U32 LL_base[MaxLL+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 18, 20, 22, 24, 28, 32, 40, + 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, + 0x2000, 0x4000, 0x8000, 0x10000 }; + +static UNUSED_ATTR const U32 OF_base[MaxOff+1] = { + 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, + 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, + 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, + 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD }; + +static UNUSED_ATTR const U8 OF_bits[MaxOff+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31 }; + +static UNUSED_ATTR const U32 ML_base[MaxML+1] = { + 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, + 35, 37, 39, 41, 43, 47, 51, 59, + 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, + 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; + + +/*-******************************************************* + * Decompression types + *********************************************************/ + typedef struct { + U32 fastMode; + U32 tableLog; + } ZSTD_seqSymbol_header; + + typedef struct { + U16 nextState; + BYTE nbAdditionalBits; + BYTE nbBits; + U32 baseValue; + } ZSTD_seqSymbol; + + #define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log))) + +#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE (sizeof(S16) * (MaxSeq + 1) + (1u << MaxFSELog) + sizeof(U64)) +#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32 ((ZSTD_BUILD_FSE_TABLE_WKSP_SIZE + sizeof(U32) - 1) / sizeof(U32)) +#define ZSTD_HUFFDTABLE_CAPACITY_LOG 12 + +typedef struct { + ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]; /* Note : Space reserved for FSE Tables */ + ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]; /* is also used as temporary workspace while building hufTable during DDict creation */ + ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]; /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */ + HUF_DTable hufTable[HUF_DTABLE_SIZE(ZSTD_HUFFDTABLE_CAPACITY_LOG)]; /* can accommodate HUF_decompress4X */ + U32 rep[ZSTD_REP_NUM]; + U32 workspace[ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32]; +} ZSTD_entropyDTables_t; + +typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader, + ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock, + ZSTDds_decompressLastBlock, ZSTDds_checkChecksum, + ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage; + +typedef enum { zdss_init=0, zdss_loadHeader, + zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage; + +typedef enum { + ZSTD_use_indefinitely = -1, /* Use the dictionary indefinitely */ + ZSTD_dont_use = 0, /* Do not use the dictionary (if one exists free it) */ + ZSTD_use_once = 1 /* Use the dictionary once and set to ZSTD_dont_use */ +} ZSTD_dictUses_e; + +/* Hashset for storing references to multiple ZSTD_DDict within ZSTD_DCtx */ +typedef struct { + const ZSTD_DDict** ddictPtrTable; + size_t ddictPtrTableSize; + size_t ddictPtrCount; +} ZSTD_DDictHashSet; + +#ifndef ZSTD_DECODER_INTERNAL_BUFFER +# define ZSTD_DECODER_INTERNAL_BUFFER (1 << 16) +#endif + +#define ZSTD_LBMIN 64 +#define ZSTD_LBMAX (128 << 10) + +/* extra buffer, compensates when dst is not large enough to store litBuffer */ +#define ZSTD_LITBUFFEREXTRASIZE BOUNDED(ZSTD_LBMIN, ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX) + +typedef enum { + ZSTD_not_in_dst = 0, /* Stored entirely within litExtraBuffer */ + ZSTD_in_dst = 1, /* Stored entirely within dst (in memory after current output write) */ + ZSTD_split = 2 /* Split between litExtraBuffer and dst */ +} ZSTD_litLocation_e; + +struct ZSTD_DCtx_s +{ + const ZSTD_seqSymbol* LLTptr; + const ZSTD_seqSymbol* MLTptr; + const ZSTD_seqSymbol* OFTptr; + const HUF_DTable* HUFptr; + ZSTD_entropyDTables_t entropy; + U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; /* space needed when building huffman tables */ + const void* previousDstEnd; /* detect continuity */ + const void* prefixStart; /* start of current segment */ + const void* virtualStart; /* virtual start of previous segment if it was just before current one */ + const void* dictEnd; /* end of previous segment */ + size_t expected; + ZSTD_FrameHeader fParams; + U64 processedCSize; + U64 decodedSize; + blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */ + ZSTD_dStage stage; + U32 litEntropy; + U32 fseEntropy; + XXH64_state_t xxhState; + size_t headerSize; + ZSTD_format_e format; + ZSTD_forceIgnoreChecksum_e forceIgnoreChecksum; /* User specified: if == 1, will ignore checksums in compressed frame. Default == 0 */ + U32 validateChecksum; /* if == 1, will validate checksum. Is == 1 if (fParams.checksumFlag == 1) and (forceIgnoreChecksum == 0). */ + const BYTE* litPtr; + ZSTD_customMem customMem; + size_t litSize; + size_t rleSize; + size_t staticSize; + int isFrameDecompression; +#if DYNAMIC_BMI2 + int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */ +#endif + + /* dictionary */ + const ZSTD_DDict* ddict; /* set by ZSTD_initDStream_usingDDict(), or ZSTD_DCtx_refDDict() */ + U32 dictID; + int ddictIsCold; /* if == 1 : dictionary is "new" for working context, and presumed "cold" (not in cpu cache) */ + ZSTD_dictUses_e dictUses; + ZSTD_refMultipleDDicts_e refMultipleDDicts; /* User specified: if == 1, will allow references to multiple DDicts. Default == 0 (disabled) */ + int disableHufAsm; + int maxBlockSizeParam; + + /* streaming */ + ZSTD_dStreamStage streamStage; + char* inBuff; + size_t inBuffSize; + size_t inPos; + size_t maxWindowSize; + char* outBuff; + size_t outBuffSize; + size_t outStart; + size_t outEnd; + size_t lhSize; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + void* legacyContext; + U32 previousLegacyVersion; + U32 legacyVersion; +#endif + U32 hostageByte; + int noForwardProgress; + ZSTD_bufferMode_e outBufferMode; + ZSTD_outBuffer expectedOutBuffer; + + /* workspace */ + BYTE* litBuffer; + const BYTE* litBufferEnd; + ZSTD_litLocation_e litBufferLocation; + BYTE litExtraBuffer[ZSTD_LITBUFFEREXTRASIZE + WILDCOPY_OVERLENGTH]; /* literal buffer can be split between storage within dst and within this scratch buffer */ + BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; + + size_t oversizedDuration; + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + void const* dictContentBeginForFuzzing; + void const* dictContentEndForFuzzing; +#endif + + /* Tracing */ +#if ZSTD_TRACE + ZSTD_TraceCtx traceCtx; +#endif +}; /* typedef'd to ZSTD_DCtx within "zstd.h" */ + +MEM_STATIC int ZSTD_DCtx_get_bmi2(const struct ZSTD_DCtx_s *dctx) { +#if DYNAMIC_BMI2 + return dctx->bmi2; +#else + (void)dctx; + return 0; +#endif +} + +/*-******************************************************* + * Shared internal functions + *********************************************************/ + +/*! ZSTD_loadDEntropy() : + * dict : must point at beginning of a valid zstd dictionary. + * @return : size of dictionary header (size of magic number + dict ID + entropy tables) */ +size_t ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy, + const void* const dict, size_t const dictSize); + +/*! ZSTD_checkContinuity() : + * check if next `dst` follows previous position, where decompression ended. + * If yes, do nothing (continue on current segment). + * If not, classify previous segment as "external dictionary", and start a new segment. + * This function cannot fail. */ +void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize); + + +#endif /* ZSTD_DECOMPRESS_INTERNAL_H */ diff --git a/src/commonlib/bsd/zstd/zdict.h b/src/commonlib/bsd/zstd/zdict.h new file mode 100644 index 0000000000..9befe96c1a --- /dev/null +++ b/src/commonlib/bsd/zstd/zdict.h @@ -0,0 +1,483 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_ZDICT_H +#define ZSTD_ZDICT_H + + +/*====== Dependencies ======*/ +#include /* size_t */ + +#if defined (__cplusplus) +extern "C" { +#endif + +/* ===== ZDICTLIB_API : control library symbols visibility ===== */ +#ifndef ZDICTLIB_VISIBLE + /* Backwards compatibility with old macro name */ +# ifdef ZDICTLIB_VISIBILITY +# define ZDICTLIB_VISIBLE ZDICTLIB_VISIBILITY +# elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZDICTLIB_VISIBLE __attribute__ ((visibility ("default"))) +# else +# define ZDICTLIB_VISIBLE +# endif +#endif + +#ifndef ZDICTLIB_HIDDEN +# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZDICTLIB_HIDDEN __attribute__ ((visibility ("hidden"))) +# else +# define ZDICTLIB_HIDDEN +# endif +#endif + +#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZDICTLIB_API __declspec(dllexport) ZDICTLIB_VISIBLE +#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZDICTLIB_API __declspec(dllimport) ZDICTLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define ZDICTLIB_API ZDICTLIB_VISIBLE +#endif + +/******************************************************************************* + * Zstd dictionary builder + * + * FAQ + * === + * Why should I use a dictionary? + * ------------------------------ + * + * Zstd can use dictionaries to improve compression ratio of small data. + * Traditionally small files don't compress well because there is very little + * repetition in a single sample, since it is small. But, if you are compressing + * many similar files, like a bunch of JSON records that share the same + * structure, you can train a dictionary on ahead of time on some samples of + * these files. Then, zstd can use the dictionary to find repetitions that are + * present across samples. This can vastly improve compression ratio. + * + * When is a dictionary useful? + * ---------------------------- + * + * Dictionaries are useful when compressing many small files that are similar. + * The larger a file is, the less benefit a dictionary will have. Generally, + * we don't expect dictionary compression to be effective past 100KB. And the + * smaller a file is, the more we would expect the dictionary to help. + * + * How do I use a dictionary? + * -------------------------- + * + * Simply pass the dictionary to the zstd compressor with + * `ZSTD_CCtx_loadDictionary()`. The same dictionary must then be passed to + * the decompressor, using `ZSTD_DCtx_loadDictionary()`. There are other + * more advanced functions that allow selecting some options, see zstd.h for + * complete documentation. + * + * What is a zstd dictionary? + * -------------------------- + * + * A zstd dictionary has two pieces: Its header, and its content. The header + * contains a magic number, the dictionary ID, and entropy tables. These + * entropy tables allow zstd to save on header costs in the compressed file, + * which really matters for small data. The content is just bytes, which are + * repeated content that is common across many samples. + * + * What is a raw content dictionary? + * --------------------------------- + * + * A raw content dictionary is just bytes. It doesn't have a zstd dictionary + * header, a dictionary ID, or entropy tables. Any buffer is a valid raw + * content dictionary. + * + * How do I train a dictionary? + * ---------------------------- + * + * Gather samples from your use case. These samples should be similar to each + * other. If you have several use cases, you could try to train one dictionary + * per use case. + * + * Pass those samples to `ZDICT_trainFromBuffer()` and that will train your + * dictionary. There are a few advanced versions of this function, but this + * is a great starting point. If you want to further tune your dictionary + * you could try `ZDICT_optimizeTrainFromBuffer_cover()`. If that is too slow + * you can try `ZDICT_optimizeTrainFromBuffer_fastCover()`. + * + * If the dictionary training function fails, that is likely because you + * either passed too few samples, or a dictionary would not be effective + * for your data. Look at the messages that the dictionary trainer printed, + * if it doesn't say too few samples, then a dictionary would not be effective. + * + * How large should my dictionary be? + * ---------------------------------- + * + * A reasonable dictionary size, the `dictBufferCapacity`, is about 100KB. + * The zstd CLI defaults to a 110KB dictionary. You likely don't need a + * dictionary larger than that. But, most use cases can get away with a + * smaller dictionary. The advanced dictionary builders can automatically + * shrink the dictionary for you, and select the smallest size that doesn't + * hurt compression ratio too much. See the `shrinkDict` parameter. + * A smaller dictionary can save memory, and potentially speed up + * compression. + * + * How many samples should I provide to the dictionary builder? + * ------------------------------------------------------------ + * + * We generally recommend passing ~100x the size of the dictionary + * in samples. A few thousand should suffice. Having too few samples + * can hurt the dictionaries effectiveness. Having more samples will + * only improve the dictionaries effectiveness. But having too many + * samples can slow down the dictionary builder. + * + * How do I determine if a dictionary will be effective? + * ----------------------------------------------------- + * + * Simply train a dictionary and try it out. You can use zstd's built in + * benchmarking tool to test the dictionary effectiveness. + * + * # Benchmark levels 1-3 without a dictionary + * zstd -b1e3 -r /path/to/my/files + * # Benchmark levels 1-3 with a dictionary + * zstd -b1e3 -r /path/to/my/files -D /path/to/my/dictionary + * + * When should I retrain a dictionary? + * ----------------------------------- + * + * You should retrain a dictionary when its effectiveness drops. Dictionary + * effectiveness drops as the data you are compressing changes. Generally, we do + * expect dictionaries to "decay" over time, as your data changes, but the rate + * at which they decay depends on your use case. Internally, we regularly + * retrain dictionaries, and if the new dictionary performs significantly + * better than the old dictionary, we will ship the new dictionary. + * + * I have a raw content dictionary, how do I turn it into a zstd dictionary? + * ------------------------------------------------------------------------- + * + * If you have a raw content dictionary, e.g. by manually constructing it, or + * using a third-party dictionary builder, you can turn it into a zstd + * dictionary by using `ZDICT_finalizeDictionary()`. You'll also have to + * provide some samples of the data. It will add the zstd header to the + * raw content, which contains a dictionary ID and entropy tables, which + * will improve compression ratio, and allow zstd to write the dictionary ID + * into the frame, if you so choose. + * + * Do I have to use zstd's dictionary builder? + * ------------------------------------------- + * + * No! You can construct dictionary content however you please, it is just + * bytes. It will always be valid as a raw content dictionary. If you want + * a zstd dictionary, which can improve compression ratio, use + * `ZDICT_finalizeDictionary()`. + * + * What is the attack surface of a zstd dictionary? + * ------------------------------------------------ + * + * Zstd is heavily fuzz tested, including loading fuzzed dictionaries, so + * zstd should never crash, or access out-of-bounds memory no matter what + * the dictionary is. However, if an attacker can control the dictionary + * during decompression, they can cause zstd to generate arbitrary bytes, + * just like if they controlled the compressed data. + * + ******************************************************************************/ + + +/*! ZDICT_trainFromBuffer(): + * Train a dictionary from an array of samples. + * Redirect towards ZDICT_optimizeTrainFromBuffer_fastCover() single-threaded, with d=8, steps=4, + * f=20, and accel=1. + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`, + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order. + * The resulting dictionary will be saved into `dictBuffer`. + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * Note: Dictionary training will fail if there are not enough samples to construct a + * dictionary, or if most of the samples are too small (< 8 bytes being the lower limit). + * If dictionary training fails, you should use zstd without a dictionary, as the dictionary + * would've been ineffective anyways. If you believe your samples would benefit from a dictionary + * please open an issue with details, and we can look into it. + * Note: ZDICT_trainFromBuffer()'s memory usage is about 6 MB. + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB. + * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`. + * In general, it's recommended to provide a few thousands samples, though this can vary a lot. + * It's recommended that total size of all samples be about ~x100 times the target size of dictionary. + */ +ZDICTLIB_API size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity, + const void* samplesBuffer, + const size_t* samplesSizes, unsigned nbSamples); + +typedef struct { + int compressionLevel; /**< optimize for a specific zstd compression level; 0 means default */ + unsigned notificationLevel; /**< Write log to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */ + unsigned dictID; /**< force dictID value; 0 means auto mode (32-bits random value) + * NOTE: The zstd format reserves some dictionary IDs for future use. + * You may use them in private settings, but be warned that they + * may be used by zstd in a public dictionary registry in the future. + * These dictionary IDs are: + * - low range : <= 32767 + * - high range : >= (2^31) + */ +} ZDICT_params_t; + +/*! ZDICT_finalizeDictionary(): + * Given a custom content as a basis for dictionary, and a set of samples, + * finalize dictionary by adding headers and statistics according to the zstd + * dictionary format. + * + * Samples must be stored concatenated in a flat buffer `samplesBuffer`, + * supplied with an array of sizes `samplesSizes`, providing the size of each + * sample in order. The samples are used to construct the statistics, so they + * should be representative of what you will compress with this dictionary. + * + * The compression level can be set in `parameters`. You should pass the + * compression level you expect to use in production. The statistics for each + * compression level differ, so tuning the dictionary for the compression level + * can help quite a bit. + * + * You can set an explicit dictionary ID in `parameters`, or allow us to pick + * a random dictionary ID for you, but we can't guarantee no collisions. + * + * The dstDictBuffer and the dictContent may overlap, and the content will be + * appended to the end of the header. If the header + the content doesn't fit in + * maxDictSize the beginning of the content is truncated to make room, since it + * is presumed that the most profitable content is at the end of the dictionary, + * since that is the cheapest to reference. + * + * `maxDictSize` must be >= max(dictContentSize, ZDICT_DICTSIZE_MIN). + * + * @return: size of dictionary stored into `dstDictBuffer` (<= `maxDictSize`), + * or an error code, which can be tested by ZDICT_isError(). + * Note: ZDICT_finalizeDictionary() will push notifications into stderr if + * instructed to, using notificationLevel>0. + * NOTE: This function currently may fail in several edge cases including: + * * Not enough samples + * * Samples are uncompressible + * * Samples are all exactly the same + */ +ZDICTLIB_API size_t ZDICT_finalizeDictionary(void* dstDictBuffer, size_t maxDictSize, + const void* dictContent, size_t dictContentSize, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, + ZDICT_params_t parameters); + + +/*====== Helper functions ======*/ +ZDICTLIB_API unsigned ZDICT_getDictID(const void* dictBuffer, size_t dictSize); /**< extracts dictID; @return zero if error (not a valid dictionary) */ +ZDICTLIB_API size_t ZDICT_getDictHeaderSize(const void* dictBuffer, size_t dictSize); /* returns dict header size; returns a ZSTD error code on failure */ +ZDICTLIB_API unsigned ZDICT_isError(size_t errorCode); +ZDICTLIB_API const char* ZDICT_getErrorName(size_t errorCode); + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_ZDICT_H */ + +#if defined(ZDICT_STATIC_LINKING_ONLY) && !defined(ZSTD_ZDICT_H_STATIC) +#define ZSTD_ZDICT_H_STATIC + +#if defined (__cplusplus) +extern "C" { +#endif + +/* This can be overridden externally to hide static symbols. */ +#ifndef ZDICTLIB_STATIC_API +# if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZDICTLIB_STATIC_API __declspec(dllexport) ZDICTLIB_VISIBLE +# elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZDICTLIB_STATIC_API __declspec(dllimport) ZDICTLIB_VISIBLE +# else +# define ZDICTLIB_STATIC_API ZDICTLIB_VISIBLE +# endif +#endif + +/* ==================================================================================== + * The definitions in this section are considered experimental. + * They should never be used with a dynamic library, as they may change in the future. + * They are provided for advanced usages. + * Use them only in association with static linking. + * ==================================================================================== */ + +#define ZDICT_DICTSIZE_MIN 256 +/* Deprecated: Remove in v1.6.0 */ +#define ZDICT_CONTENTSIZE_MIN 128 + +/*! ZDICT_cover_params_t: + * k and d are the only required parameters. + * For others, value 0 means default. + */ +typedef struct { + unsigned k; /* Segment size : constraint: 0 < k : Reasonable range [16, 2048+] */ + unsigned d; /* dmer size : constraint: 0 < d <= k : Reasonable range [6, 16] */ + unsigned steps; /* Number of steps : Only used for optimization : 0 means default (40) : Higher means more parameters checked */ + unsigned nbThreads; /* Number of threads : constraint: 0 < nbThreads : 1 means single-threaded : Only used for optimization : Ignored if ZSTD_MULTITHREAD is not defined */ + double splitPoint; /* Percentage of samples used for training: Only used for optimization : the first nbSamples * splitPoint samples will be used to training, the last nbSamples * (1 - splitPoint) samples will be used for testing, 0 means default (1.0), 1.0 when all samples are used for both training and testing */ + unsigned shrinkDict; /* Train dictionaries to shrink in size starting from the minimum size and selects the smallest dictionary that is shrinkDictMaxRegression% worse than the largest dictionary. 0 means no shrinking and 1 means shrinking */ + unsigned shrinkDictMaxRegression; /* Sets shrinkDictMaxRegression so that a smaller dictionary can be at worse shrinkDictMaxRegression% worse than the max dict size dictionary. */ + ZDICT_params_t zParams; +} ZDICT_cover_params_t; + +typedef struct { + unsigned k; /* Segment size : constraint: 0 < k : Reasonable range [16, 2048+] */ + unsigned d; /* dmer size : constraint: 0 < d <= k : Reasonable range [6, 16] */ + unsigned f; /* log of size of frequency array : constraint: 0 < f <= 31 : 1 means default(20)*/ + unsigned steps; /* Number of steps : Only used for optimization : 0 means default (40) : Higher means more parameters checked */ + unsigned nbThreads; /* Number of threads : constraint: 0 < nbThreads : 1 means single-threaded : Only used for optimization : Ignored if ZSTD_MULTITHREAD is not defined */ + double splitPoint; /* Percentage of samples used for training: Only used for optimization : the first nbSamples * splitPoint samples will be used to training, the last nbSamples * (1 - splitPoint) samples will be used for testing, 0 means default (0.75), 1.0 when all samples are used for both training and testing */ + unsigned accel; /* Acceleration level: constraint: 0 < accel <= 10, higher means faster and less accurate, 0 means default(1) */ + unsigned shrinkDict; /* Train dictionaries to shrink in size starting from the minimum size and selects the smallest dictionary that is shrinkDictMaxRegression% worse than the largest dictionary. 0 means no shrinking and 1 means shrinking */ + unsigned shrinkDictMaxRegression; /* Sets shrinkDictMaxRegression so that a smaller dictionary can be at worse shrinkDictMaxRegression% worse than the max dict size dictionary. */ + + ZDICT_params_t zParams; +} ZDICT_fastCover_params_t; + +/*! ZDICT_trainFromBuffer_cover(): + * Train a dictionary from an array of samples using the COVER algorithm. + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`, + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order. + * The resulting dictionary will be saved into `dictBuffer`. + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * See ZDICT_trainFromBuffer() for details on failure modes. + * Note: ZDICT_trainFromBuffer_cover() requires about 9 bytes of memory for each input byte. + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB. + * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`. + * In general, it's recommended to provide a few thousands samples, though this can vary a lot. + * It's recommended that total size of all samples be about ~x100 times the target size of dictionary. + */ +ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover( + void *dictBuffer, size_t dictBufferCapacity, + const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, + ZDICT_cover_params_t parameters); + +/*! ZDICT_optimizeTrainFromBuffer_cover(): + * The same requirements as above hold for all the parameters except `parameters`. + * This function tries many parameter combinations and picks the best parameters. + * `*parameters` is filled with the best parameters found, + * dictionary constructed with those parameters is stored in `dictBuffer`. + * + * All of the parameters d, k, steps are optional. + * If d is non-zero then we don't check multiple values of d, otherwise we check d = {6, 8}. + * if steps is zero it defaults to its default value. + * If k is non-zero then we don't check multiple values of k, otherwise we check steps values in [50, 2000]. + * + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * On success `*parameters` contains the parameters selected. + * See ZDICT_trainFromBuffer() for details on failure modes. + * Note: ZDICT_optimizeTrainFromBuffer_cover() requires about 8 bytes of memory for each input byte and additionally another 5 bytes of memory for each byte of memory for each thread. + */ +ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover( + void* dictBuffer, size_t dictBufferCapacity, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, + ZDICT_cover_params_t* parameters); + +/*! ZDICT_trainFromBuffer_fastCover(): + * Train a dictionary from an array of samples using a modified version of COVER algorithm. + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`, + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order. + * d and k are required. + * All other parameters are optional, will use default values if not provided + * The resulting dictionary will be saved into `dictBuffer`. + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * See ZDICT_trainFromBuffer() for details on failure modes. + * Note: ZDICT_trainFromBuffer_fastCover() requires 6 * 2^f bytes of memory. + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB. + * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`. + * In general, it's recommended to provide a few thousands samples, though this can vary a lot. + * It's recommended that total size of all samples be about ~x100 times the target size of dictionary. + */ +ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_fastCover(void *dictBuffer, + size_t dictBufferCapacity, const void *samplesBuffer, + const size_t *samplesSizes, unsigned nbSamples, + ZDICT_fastCover_params_t parameters); + +/*! ZDICT_optimizeTrainFromBuffer_fastCover(): + * The same requirements as above hold for all the parameters except `parameters`. + * This function tries many parameter combinations (specifically, k and d combinations) + * and picks the best parameters. `*parameters` is filled with the best parameters found, + * dictionary constructed with those parameters is stored in `dictBuffer`. + * All of the parameters d, k, steps, f, and accel are optional. + * If d is non-zero then we don't check multiple values of d, otherwise we check d = {6, 8}. + * if steps is zero it defaults to its default value. + * If k is non-zero then we don't check multiple values of k, otherwise we check steps values in [50, 2000]. + * If f is zero, default value of 20 is used. + * If accel is zero, default value of 1 is used. + * + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * On success `*parameters` contains the parameters selected. + * See ZDICT_trainFromBuffer() for details on failure modes. + * Note: ZDICT_optimizeTrainFromBuffer_fastCover() requires about 6 * 2^f bytes of memory for each thread. + */ +ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_fastCover(void* dictBuffer, + size_t dictBufferCapacity, const void* samplesBuffer, + const size_t* samplesSizes, unsigned nbSamples, + ZDICT_fastCover_params_t* parameters); + +typedef struct { + unsigned selectivityLevel; /* 0 means default; larger => select more => larger dictionary */ + ZDICT_params_t zParams; +} ZDICT_legacy_params_t; + +/*! ZDICT_trainFromBuffer_legacy(): + * Train a dictionary from an array of samples. + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`, + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order. + * The resulting dictionary will be saved into `dictBuffer`. + * `parameters` is optional and can be provided with values set to 0 to mean "default". + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * See ZDICT_trainFromBuffer() for details on failure modes. + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB. + * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`. + * In general, it's recommended to provide a few thousands samples, though this can vary a lot. + * It's recommended that total size of all samples be about ~x100 times the target size of dictionary. + * Note: ZDICT_trainFromBuffer_legacy() will send notifications into stderr if instructed to, using notificationLevel>0. + */ +ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_legacy( + void* dictBuffer, size_t dictBufferCapacity, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, + ZDICT_legacy_params_t parameters); + + +/* Deprecation warnings */ +/* It is generally possible to disable deprecation warnings from compiler, + for example with -Wno-deprecated-declarations for gcc + or _CRT_SECURE_NO_WARNINGS in Visual. + Otherwise, it's also possible to manually define ZDICT_DISABLE_DEPRECATE_WARNINGS */ +#ifdef ZDICT_DISABLE_DEPRECATE_WARNINGS +# define ZDICT_DEPRECATED(message) /* disable deprecation warnings */ +#else +# define ZDICT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ +# define ZDICT_DEPRECATED(message) [[deprecated(message)]] +# elif defined(__clang__) || (ZDICT_GCC_VERSION >= 405) +# define ZDICT_DEPRECATED(message) __attribute__((deprecated(message))) +# elif (ZDICT_GCC_VERSION >= 301) +# define ZDICT_DEPRECATED(message) __attribute__((deprecated)) +# elif defined(_MSC_VER) +# define ZDICT_DEPRECATED(message) __declspec(deprecated(message)) +# else +# pragma message("WARNING: You need to implement ZDICT_DEPRECATED for this compiler") +# define ZDICT_DEPRECATED(message) +# endif +#endif /* ZDICT_DISABLE_DEPRECATE_WARNINGS */ + +ZDICT_DEPRECATED("use ZDICT_finalizeDictionary() instead") +ZDICTLIB_STATIC_API +size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples); + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_ZDICT_H_STATIC */ diff --git a/src/commonlib/bsd/zstd/zstd.h b/src/commonlib/bsd/zstd/zstd.h new file mode 100644 index 0000000000..d88412c8dc --- /dev/null +++ b/src/commonlib/bsd/zstd/zstd.h @@ -0,0 +1,2646 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_H_235446 +#define ZSTD_H_235446 + + +/* ====== Dependencies ======*/ +#include /* size_t */ + +#include "zstd_errors.h" /* list of errors */ +#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) +#include /* INT_MAX */ +#endif /* ZSTD_STATIC_LINKING_ONLY */ + +#if defined (__cplusplus) +extern "C" { +#endif + +/* ===== ZSTDLIB_API : control library symbols visibility ===== */ +#ifndef ZSTDLIB_VISIBLE + /* Backwards compatibility with old macro name */ +# ifdef ZSTDLIB_VISIBILITY +# define ZSTDLIB_VISIBLE ZSTDLIB_VISIBILITY +# elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZSTDLIB_VISIBLE __attribute__ ((visibility ("default"))) +# else +# define ZSTDLIB_VISIBLE +# endif +#endif + +#ifndef ZSTDLIB_HIDDEN +# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZSTDLIB_HIDDEN __attribute__ ((visibility ("hidden"))) +# else +# define ZSTDLIB_HIDDEN +# endif +#endif + +#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBLE +#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define ZSTDLIB_API ZSTDLIB_VISIBLE +#endif + +/* Deprecation warnings : + * Should these warnings be a problem, it is generally possible to disable them, + * typically with -Wno-deprecated-declarations for gcc or _CRT_SECURE_NO_WARNINGS in Visual. + * Otherwise, it's also possible to define ZSTD_DISABLE_DEPRECATE_WARNINGS. + */ +#ifdef ZSTD_DISABLE_DEPRECATE_WARNINGS +# define ZSTD_DEPRECATED(message) /* disable deprecation warnings */ +#else +# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ +# define ZSTD_DEPRECATED(message) [[deprecated(message)]] +# elif (defined(GNUC) && (GNUC > 4 || (GNUC == 4 && GNUC_MINOR >= 5))) || defined(__clang__) || defined(__IAR_SYSTEMS_ICC__) +# define ZSTD_DEPRECATED(message) __attribute__((deprecated(message))) +# elif defined(__GNUC__) && (__GNUC__ >= 3) +# define ZSTD_DEPRECATED(message) __attribute__((deprecated)) +# elif defined(_MSC_VER) +# define ZSTD_DEPRECATED(message) __declspec(deprecated(message)) +# else +# pragma message("WARNING: You need to implement ZSTD_DEPRECATED for this compiler") +# define ZSTD_DEPRECATED(message) +# endif +#endif /* ZSTD_DISABLE_DEPRECATE_WARNINGS */ + + +/******************************************************************************* + Introduction + + zstd, short for Zstandard, is a fast lossless compression algorithm, targeting + real-time compression scenarios at zlib-level and better compression ratios. + The zstd compression library provides in-memory compression and decompression + functions. + + The library supports regular compression levels from 1 up to ZSTD_maxCLevel(), + which is currently 22. Levels >= 20, labeled `--ultra`, should be used with + caution, as they require more memory. The library also offers negative + compression levels, which extend the range of speed vs. ratio preferences. + The lower the level, the faster the speed (at the cost of compression). + + Compression can be done in: + - a single step (described as Simple API) + - a single step, reusing a context (described as Explicit context) + - unbounded multiple steps (described as Streaming compression) + + The compression ratio achievable on small data can be highly improved using + a dictionary. Dictionary compression can be performed in: + - a single step (described as Simple dictionary API) + - a single step, reusing a dictionary (described as Bulk-processing + dictionary API) + + Advanced experimental functions can be accessed using + `#define ZSTD_STATIC_LINKING_ONLY` before including zstd.h. + + Advanced experimental APIs should never be used with a dynamically-linked + library. They are not "stable"; their definitions or signatures may change in + the future. Only static linking is allowed. +*******************************************************************************/ + +/*------ Version ------*/ +#define ZSTD_VERSION_MAJOR 1 +#define ZSTD_VERSION_MINOR 5 +#define ZSTD_VERSION_RELEASE 7 +#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) + +/*! ZSTD_versionNumber() : + * Return runtime library version, the value is (MAJOR*100*100 + MINOR*100 + RELEASE). */ +ZSTDLIB_API unsigned ZSTD_versionNumber(void); + +#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE +#define ZSTD_QUOTE(str) #str +#define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str) +#define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION) + +/*! ZSTD_versionString() : + * Return runtime library version, like "1.4.5". Requires v1.3.0+. */ +ZSTDLIB_API const char* ZSTD_versionString(void); + +/* ************************************* + * Default constant + ***************************************/ +#ifndef ZSTD_CLEVEL_DEFAULT +# define ZSTD_CLEVEL_DEFAULT 3 +#endif + +/* ************************************* + * Constants + ***************************************/ + +/* All magic numbers are supposed read/written to/from files/memory using little-endian convention */ +#define ZSTD_MAGICNUMBER 0xFD2FB528 /* valid since v0.8.0 */ +#define ZSTD_MAGIC_DICTIONARY 0xEC30A437 /* valid since v0.7.0 */ +#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50 /* all 16 values, from 0x184D2A50 to 0x184D2A5F, signal the beginning of a skippable frame */ +#define ZSTD_MAGIC_SKIPPABLE_MASK 0xFFFFFFF0 + +#define ZSTD_BLOCKSIZELOG_MAX 17 +#define ZSTD_BLOCKSIZE_MAX (1<= ZSTD_compressBound(srcSize)` guarantees that zstd will have + * enough space to successfully compress the data. + * @return : compressed size written into `dst` (<= `dstCapacity), + * or an error code if it fails (which can be tested using ZSTD_isError()). */ +ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel); + +/*====== Decompression helper functions ======*/ + +/*! ZSTD_getFrameContentSize() : requires v1.3.0+ + * `src` should point to the start of a ZSTD encoded frame. + * `srcSize` must be at least as large as the frame header. + * hint : any size >= `ZSTD_frameHeaderSize_max` is large enough. + * @return : - decompressed size of `src` frame content, if known + * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined + * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) + * note 1 : a 0 return value means the frame is valid but "empty". + * When invoking this method on a skippable frame, it will return 0. + * note 2 : decompressed size is an optional field, it may not be present (typically in streaming mode). + * When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. + * In which case, it's necessary to use streaming mode to decompress data. + * Optionally, application can rely on some implicit limit, + * as ZSTD_decompress() only needs an upper bound of decompressed size. + * (For example, data could be necessarily cut into blocks <= 16 KB). + * note 3 : decompressed size is always present when compression is completed using single-pass functions, + * such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict(). + * note 4 : decompressed size can be very large (64-bits value), + * potentially larger than what local system can handle as a single memory segment. + * In which case, it's necessary to use streaming mode to decompress data. + * note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified. + * Always ensure return value fits within application's authorized limits. + * Each application can set its own limits. + * note 6 : This function replaces ZSTD_getDecompressedSize() */ +#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1) +#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2) +ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize); + +/*! ZSTD_getDecompressedSize() (obsolete): + * This function is now obsolete, in favor of ZSTD_getFrameContentSize(). + * Both functions work the same way, but ZSTD_getDecompressedSize() blends + * "empty", "unknown" and "error" results to the same return value (0), + * while ZSTD_getFrameContentSize() gives them separate return values. + * @return : decompressed size of `src` frame content _if known and not empty_, 0 otherwise. */ +ZSTD_DEPRECATED("Replaced by ZSTD_getFrameContentSize") +ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize); + +/*! ZSTD_findFrameCompressedSize() : Requires v1.4.0+ + * `src` should point to the start of a ZSTD frame or skippable frame. + * `srcSize` must be >= first frame size + * @return : the compressed size of the first frame starting at `src`, + * suitable to pass as `srcSize` to `ZSTD_decompress` or similar, + * or an error code if input is invalid + * Note 1: this method is called _find*() because it's not enough to read the header, + * it may have to scan through the frame's content, to reach its end. + * Note 2: this method also works with Skippable Frames. In which case, + * it returns the size of the complete skippable frame, + * which is always equal to its content size + 8 bytes for headers. */ +ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize); + + +/*====== Compression helper functions ======*/ + +/*! ZSTD_compressBound() : + * maximum compressed size in worst case single-pass scenario. + * When invoking `ZSTD_compress()`, or any other one-pass compression function, + * it's recommended to provide @dstCapacity >= ZSTD_compressBound(srcSize) + * as it eliminates one potential failure scenario, + * aka not enough room in dst buffer to write the compressed frame. + * Note : ZSTD_compressBound() itself can fail, if @srcSize >= ZSTD_MAX_INPUT_SIZE . + * In which case, ZSTD_compressBound() will return an error code + * which can be tested using ZSTD_isError(). + * + * ZSTD_COMPRESSBOUND() : + * same as ZSTD_compressBound(), but as a macro. + * It can be used to produce constants, which can be useful for static allocation, + * for example to size a static array on stack. + * Will produce constant value 0 if srcSize is too large. + */ +#define ZSTD_MAX_INPUT_SIZE ((sizeof(size_t)==8) ? 0xFF00FF00FF00FF00ULL : 0xFF00FF00U) +#define ZSTD_COMPRESSBOUND(srcSize) (((size_t)(srcSize) >= ZSTD_MAX_INPUT_SIZE) ? 0 : (srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */ +ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */ + + +/*====== Error helper functions ======*/ +/* ZSTD_isError() : + * Most ZSTD_* functions returning a size_t value can be tested for error, + * using ZSTD_isError(). + * @return 1 if error, 0 otherwise + */ +ZSTDLIB_API unsigned ZSTD_isError(size_t result); /*!< tells if a `size_t` function result is an error code */ +ZSTDLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult); /* convert a result into an error code, which can be compared to error enum list */ +ZSTDLIB_API const char* ZSTD_getErrorName(size_t result); /*!< provides readable string from a function result */ +ZSTDLIB_API int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed, requires v1.4.0+ */ +ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */ +ZSTDLIB_API int ZSTD_defaultCLevel(void); /*!< default compression level, specified by ZSTD_CLEVEL_DEFAULT, requires v1.5.0+ */ + + +/*************************************** +* Explicit context +***************************************/ +/*= Compression context + * When compressing many times, + * it is recommended to allocate a compression context just once, + * and reuse it for each successive compression operation. + * This will make the workload easier for system's memory. + * Note : re-using context is just a speed / resource optimization. + * It doesn't change the compression ratio, which remains identical. + * Note 2: For parallel execution in multi-threaded environments, + * use one different context per thread . + */ +typedef struct ZSTD_CCtx_s ZSTD_CCtx; +ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void); +ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); /* compatible with NULL pointer */ + +/*! ZSTD_compressCCtx() : + * Same as ZSTD_compress(), using an explicit ZSTD_CCtx. + * Important : in order to mirror `ZSTD_compress()` behavior, + * this function compresses at the requested compression level, + * __ignoring any other advanced parameter__ . + * If any advanced parameter was set using the advanced API, + * they will all be reset. Only @compressionLevel remains. + */ +ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel); + +/*= Decompression context + * When decompressing many times, + * it is recommended to allocate a context only once, + * and reuse it for each successive compression operation. + * This will make workload friendlier for system's memory. + * Use one context per thread for parallel execution. */ +typedef struct ZSTD_DCtx_s ZSTD_DCtx; +ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void); +ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */ + +/*! ZSTD_decompressDCtx() : + * Same as ZSTD_decompress(), + * requires an allocated ZSTD_DCtx. + * Compatible with sticky parameters (see below). + */ +ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + + +/********************************************* +* Advanced compression API (Requires v1.4.0+) +**********************************************/ + +/* API design : + * Parameters are pushed one by one into an existing context, + * using ZSTD_CCtx_set*() functions. + * Pushed parameters are sticky : they are valid for next compressed frame, and any subsequent frame. + * "sticky" parameters are applicable to `ZSTD_compress2()` and `ZSTD_compressStream*()` ! + * __They do not apply to one-shot variants such as ZSTD_compressCCtx()__ . + * + * It's possible to reset all parameters to "default" using ZSTD_CCtx_reset(). + * + * This API supersedes all other "advanced" API entry points in the experimental section. + * In the future, we expect to remove API entry points from experimental which are redundant with this API. + */ + + +/* Compression strategies, listed from fastest to strongest */ +typedef enum { ZSTD_fast=1, + ZSTD_dfast=2, + ZSTD_greedy=3, + ZSTD_lazy=4, + ZSTD_lazy2=5, + ZSTD_btlazy2=6, + ZSTD_btopt=7, + ZSTD_btultra=8, + ZSTD_btultra2=9 + /* note : new strategies _might_ be added in the future. + Only the order (from fast to strong) is guaranteed */ +} ZSTD_strategy; + +typedef enum { + + /* compression parameters + * Note: When compressing with a ZSTD_CDict these parameters are superseded + * by the parameters used to construct the ZSTD_CDict. + * See ZSTD_CCtx_refCDict() for more info (superseded-by-cdict). */ + ZSTD_c_compressionLevel=100, /* Set compression parameters according to pre-defined cLevel table. + * Note that exact compression parameters are dynamically determined, + * depending on both compression level and srcSize (when known). + * Default level is ZSTD_CLEVEL_DEFAULT==3. + * Special: value 0 means default, which is controlled by ZSTD_CLEVEL_DEFAULT. + * Note 1 : it's possible to pass a negative compression level. + * Note 2 : setting a level does not automatically set all other compression parameters + * to default. Setting this will however eventually dynamically impact the compression + * parameters which have not been manually set. The manually set + * ones will 'stick'. */ + /* Advanced compression parameters : + * It's possible to pin down compression parameters to some specific values. + * In which case, these values are no longer dynamically selected by the compressor */ + ZSTD_c_windowLog=101, /* Maximum allowed back-reference distance, expressed as power of 2. + * This will set a memory budget for streaming decompression, + * with larger values requiring more memory + * and typically compressing more. + * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX. + * Special: value 0 means "use default windowLog". + * Note: Using a windowLog greater than ZSTD_WINDOWLOG_LIMIT_DEFAULT + * requires explicitly allowing such size at streaming decompression stage. */ + ZSTD_c_hashLog=102, /* Size of the initial probe table, as a power of 2. + * Resulting memory usage is (1 << (hashLog+2)). + * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX. + * Larger tables improve compression ratio of strategies <= dFast, + * and improve speed of strategies > dFast. + * Special: value 0 means "use default hashLog". */ + ZSTD_c_chainLog=103, /* Size of the multi-probe search table, as a power of 2. + * Resulting memory usage is (1 << (chainLog+2)). + * Must be clamped between ZSTD_CHAINLOG_MIN and ZSTD_CHAINLOG_MAX. + * Larger tables result in better and slower compression. + * This parameter is useless for "fast" strategy. + * It's still useful when using "dfast" strategy, + * in which case it defines a secondary probe table. + * Special: value 0 means "use default chainLog". */ + ZSTD_c_searchLog=104, /* Number of search attempts, as a power of 2. + * More attempts result in better and slower compression. + * This parameter is useless for "fast" and "dFast" strategies. + * Special: value 0 means "use default searchLog". */ + ZSTD_c_minMatch=105, /* Minimum size of searched matches. + * Note that Zstandard can still find matches of smaller size, + * it just tweaks its search algorithm to look for this size and larger. + * Larger values increase compression and decompression speed, but decrease ratio. + * Must be clamped between ZSTD_MINMATCH_MIN and ZSTD_MINMATCH_MAX. + * Note that currently, for all strategies < btopt, effective minimum is 4. + * , for all strategies > fast, effective maximum is 6. + * Special: value 0 means "use default minMatchLength". */ + ZSTD_c_targetLength=106, /* Impact of this field depends on strategy. + * For strategies btopt, btultra & btultra2: + * Length of Match considered "good enough" to stop search. + * Larger values make compression stronger, and slower. + * For strategy fast: + * Distance between match sampling. + * Larger values make compression faster, and weaker. + * Special: value 0 means "use default targetLength". */ + ZSTD_c_strategy=107, /* See ZSTD_strategy enum definition. + * The higher the value of selected strategy, the more complex it is, + * resulting in stronger and slower compression. + * Special: value 0 means "use default strategy". */ + + ZSTD_c_targetCBlockSize=130, /* v1.5.6+ + * Attempts to fit compressed block size into approximately targetCBlockSize. + * Bound by ZSTD_TARGETCBLOCKSIZE_MIN and ZSTD_TARGETCBLOCKSIZE_MAX. + * Note that it's not a guarantee, just a convergence target (default:0). + * No target when targetCBlockSize == 0. + * This is helpful in low bandwidth streaming environments to improve end-to-end latency, + * when a client can make use of partial documents (a prominent example being Chrome). + * Note: this parameter is stable since v1.5.6. + * It was present as an experimental parameter in earlier versions, + * but it's not recommended using it with earlier library versions + * due to massive performance regressions. + */ + /* LDM mode parameters */ + ZSTD_c_enableLongDistanceMatching=160, /* Enable long distance matching. + * This parameter is designed to improve compression ratio + * for large inputs, by finding large matches at long distance. + * It increases memory usage and window size. + * Note: enabling this parameter increases default ZSTD_c_windowLog to 128 MB + * except when expressly set to a different value. + * Note: will be enabled by default if ZSTD_c_windowLog >= 128 MB and + * compression strategy >= ZSTD_btopt (== compression level 16+) */ + ZSTD_c_ldmHashLog=161, /* Size of the table for long distance matching, as a power of 2. + * Larger values increase memory usage and compression ratio, + * but decrease compression speed. + * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX + * default: windowlog - 7. + * Special: value 0 means "automatically determine hashlog". */ + ZSTD_c_ldmMinMatch=162, /* Minimum match size for long distance matcher. + * Larger/too small values usually decrease compression ratio. + * Must be clamped between ZSTD_LDM_MINMATCH_MIN and ZSTD_LDM_MINMATCH_MAX. + * Special: value 0 means "use default value" (default: 64). */ + ZSTD_c_ldmBucketSizeLog=163, /* Log size of each bucket in the LDM hash table for collision resolution. + * Larger values improve collision resolution but decrease compression speed. + * The maximum value is ZSTD_LDM_BUCKETSIZELOG_MAX. + * Special: value 0 means "use default value" (default: 3). */ + ZSTD_c_ldmHashRateLog=164, /* Frequency of inserting/looking up entries into the LDM hash table. + * Must be clamped between 0 and (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN). + * Default is MAX(0, (windowLog - ldmHashLog)), optimizing hash table usage. + * Larger values improve compression speed. + * Deviating far from default value will likely result in a compression ratio decrease. + * Special: value 0 means "automatically determine hashRateLog". */ + + /* frame parameters */ + ZSTD_c_contentSizeFlag=200, /* Content size will be written into frame header _whenever known_ (default:1) + * Content size must be known at the beginning of compression. + * This is automatically the case when using ZSTD_compress2(), + * For streaming scenarios, content size must be provided with ZSTD_CCtx_setPledgedSrcSize() */ + ZSTD_c_checksumFlag=201, /* A 32-bits checksum of content is written at end of frame (default:0) */ + ZSTD_c_dictIDFlag=202, /* When applicable, dictionary's ID is written into frame header (default:1) */ + + /* multi-threading parameters */ + /* These parameters are only active if multi-threading is enabled (compiled with build macro ZSTD_MULTITHREAD). + * Otherwise, trying to set any other value than default (0) will be a no-op and return an error. + * In a situation where it's unknown if the linked library supports multi-threading or not, + * setting ZSTD_c_nbWorkers to any value >= 1 and consulting the return value provides a quick way to check this property. + */ + ZSTD_c_nbWorkers=400, /* Select how many threads will be spawned to compress in parallel. + * When nbWorkers >= 1, triggers asynchronous mode when invoking ZSTD_compressStream*() : + * ZSTD_compressStream*() consumes input and flush output if possible, but immediately gives back control to caller, + * while compression is performed in parallel, within worker thread(s). + * (note : a strong exception to this rule is when first invocation of ZSTD_compressStream2() sets ZSTD_e_end : + * in which case, ZSTD_compressStream2() delegates to ZSTD_compress2(), which is always a blocking call). + * More workers improve speed, but also increase memory usage. + * Default value is `0`, aka "single-threaded mode" : no worker is spawned, + * compression is performed inside Caller's thread, and all invocations are blocking */ + ZSTD_c_jobSize=401, /* Size of a compression job. This value is enforced only when nbWorkers >= 1. + * Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads. + * 0 means default, which is dynamically determined based on compression parameters. + * Job size must be a minimum of overlap size, or ZSTDMT_JOBSIZE_MIN (= 512 KB), whichever is largest. + * The minimum size is automatically and transparently enforced. */ + ZSTD_c_overlapLog=402, /* Control the overlap size, as a fraction of window size. + * The overlap size is an amount of data reloaded from previous job at the beginning of a new job. + * It helps preserve compression ratio, while each job is compressed in parallel. + * This value is enforced only when nbWorkers >= 1. + * Larger values increase compression ratio, but decrease speed. + * Possible values range from 0 to 9 : + * - 0 means "default" : value will be determined by the library, depending on strategy + * - 1 means "no overlap" + * - 9 means "full overlap", using a full window size. + * Each intermediate rank increases/decreases load size by a factor 2 : + * 9: full window; 8: w/2; 7: w/4; 6: w/8; 5:w/16; 4: w/32; 3:w/64; 2:w/128; 1:no overlap; 0:default + * default value varies between 6 and 9, depending on strategy */ + + /* note : additional experimental parameters are also available + * within the experimental section of the API. + * At the time of this writing, they include : + * ZSTD_c_rsyncable + * ZSTD_c_format + * ZSTD_c_forceMaxWindow + * ZSTD_c_forceAttachDict + * ZSTD_c_literalCompressionMode + * ZSTD_c_srcSizeHint + * ZSTD_c_enableDedicatedDictSearch + * ZSTD_c_stableInBuffer + * ZSTD_c_stableOutBuffer + * ZSTD_c_blockDelimiters + * ZSTD_c_validateSequences + * ZSTD_c_blockSplitterLevel + * ZSTD_c_splitAfterSequences + * ZSTD_c_useRowMatchFinder + * ZSTD_c_prefetchCDictTables + * ZSTD_c_enableSeqProducerFallback + * ZSTD_c_maxBlockSize + * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. + * note : never ever use experimentalParam? names directly; + * also, the enums values themselves are unstable and can still change. + */ + ZSTD_c_experimentalParam1=500, + ZSTD_c_experimentalParam2=10, + ZSTD_c_experimentalParam3=1000, + ZSTD_c_experimentalParam4=1001, + ZSTD_c_experimentalParam5=1002, + /* was ZSTD_c_experimentalParam6=1003; is now ZSTD_c_targetCBlockSize */ + ZSTD_c_experimentalParam7=1004, + ZSTD_c_experimentalParam8=1005, + ZSTD_c_experimentalParam9=1006, + ZSTD_c_experimentalParam10=1007, + ZSTD_c_experimentalParam11=1008, + ZSTD_c_experimentalParam12=1009, + ZSTD_c_experimentalParam13=1010, + ZSTD_c_experimentalParam14=1011, + ZSTD_c_experimentalParam15=1012, + ZSTD_c_experimentalParam16=1013, + ZSTD_c_experimentalParam17=1014, + ZSTD_c_experimentalParam18=1015, + ZSTD_c_experimentalParam19=1016, + ZSTD_c_experimentalParam20=1017 +} ZSTD_cParameter; + +typedef struct { + size_t error; + int lowerBound; + int upperBound; +} ZSTD_bounds; + +/*! ZSTD_cParam_getBounds() : + * All parameters must belong to an interval with lower and upper bounds, + * otherwise they will either trigger an error or be automatically clamped. + * @return : a structure, ZSTD_bounds, which contains + * - an error status field, which must be tested using ZSTD_isError() + * - lower and upper bounds, both inclusive + */ +ZSTDLIB_API ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter cParam); + +/*! ZSTD_CCtx_setParameter() : + * Set one compression parameter, selected by enum ZSTD_cParameter. + * All parameters have valid bounds. Bounds can be queried using ZSTD_cParam_getBounds(). + * Providing a value beyond bound will either clamp it, or trigger an error (depending on parameter). + * Setting a parameter is generally only possible during frame initialization (before starting compression). + * Exception : when using multi-threading mode (nbWorkers >= 1), + * the following parameters can be updated _during_ compression (within same frame): + * => compressionLevel, hashLog, chainLog, searchLog, minMatch, targetLength and strategy. + * new parameters will be active for next job only (after a flush()). + * @return : an error code (which can be tested using ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value); + +/*! ZSTD_CCtx_setPledgedSrcSize() : + * Total input data size to be compressed as a single frame. + * Value will be written in frame header, unless if explicitly forbidden using ZSTD_c_contentSizeFlag. + * This value will also be controlled at end of frame, and trigger an error if not respected. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Note 1 : pledgedSrcSize==0 actually means zero, aka an empty frame. + * In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN. + * ZSTD_CONTENTSIZE_UNKNOWN is default value for any new frame. + * Note 2 : pledgedSrcSize is only valid once, for the next frame. + * It's discarded at the end of the frame, and replaced by ZSTD_CONTENTSIZE_UNKNOWN. + * Note 3 : Whenever all input data is provided and consumed in a single round, + * for example with ZSTD_compress2(), + * or invoking immediately ZSTD_compressStream2(,,,ZSTD_e_end), + * this value is automatically overridden by srcSize instead. + */ +ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize); + +typedef enum { + ZSTD_reset_session_only = 1, + ZSTD_reset_parameters = 2, + ZSTD_reset_session_and_parameters = 3 +} ZSTD_ResetDirective; + +/*! ZSTD_CCtx_reset() : + * There are 2 different things that can be reset, independently or jointly : + * - The session : will stop compressing current frame, and make CCtx ready to start a new one. + * Useful after an error, or to interrupt any ongoing compression. + * Any internal data not yet flushed is cancelled. + * Compression parameters and dictionary remain unchanged. + * They will be used to compress next frame. + * Resetting session never fails. + * - The parameters : changes all parameters back to "default". + * This also removes any reference to any dictionary or external sequence producer. + * Parameters can only be changed between 2 sessions (i.e. no compression is currently ongoing) + * otherwise the reset fails, and function returns an error value (which can be tested using ZSTD_isError()) + * - Both : similar to resetting the session, followed by resetting parameters. + */ +ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset); + + +/*********************************************** +* Advanced decompression API (Requires v1.4.0+) +************************************************/ + +/* The advanced API pushes parameters one by one into an existing DCtx context. + * Parameters are sticky, and remain valid for all following frames + * using the same DCtx context. + * It's possible to reset parameters to default values using ZSTD_DCtx_reset(). + * Note : This API is compatible with existing ZSTD_decompressDCtx() and ZSTD_decompressStream(). + * Therefore, no new decompression function is necessary. + */ + +typedef enum { + + ZSTD_d_windowLogMax=100, /* Select a size limit (in power of 2) beyond which + * the streaming API will refuse to allocate memory buffer + * in order to protect the host from unreasonable memory requirements. + * This parameter is only useful in streaming mode, since no internal buffer is allocated in single-pass mode. + * By default, a decompression context accepts window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT). + * Special: value 0 means "use default maximum windowLog". */ + + /* note : additional experimental parameters are also available + * within the experimental section of the API. + * At the time of this writing, they include : + * ZSTD_d_format + * ZSTD_d_stableOutBuffer + * ZSTD_d_forceIgnoreChecksum + * ZSTD_d_refMultipleDDicts + * ZSTD_d_disableHuffmanAssembly + * ZSTD_d_maxBlockSize + * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. + * note : never ever use experimentalParam? names directly + */ + ZSTD_d_experimentalParam1=1000, + ZSTD_d_experimentalParam2=1001, + ZSTD_d_experimentalParam3=1002, + ZSTD_d_experimentalParam4=1003, + ZSTD_d_experimentalParam5=1004, + ZSTD_d_experimentalParam6=1005 + +} ZSTD_dParameter; + +/*! ZSTD_dParam_getBounds() : + * All parameters must belong to an interval with lower and upper bounds, + * otherwise they will either trigger an error or be automatically clamped. + * @return : a structure, ZSTD_bounds, which contains + * - an error status field, which must be tested using ZSTD_isError() + * - both lower and upper bounds, inclusive + */ +ZSTDLIB_API ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam); + +/*! ZSTD_DCtx_setParameter() : + * Set one compression parameter, selected by enum ZSTD_dParameter. + * All parameters have valid bounds. Bounds can be queried using ZSTD_dParam_getBounds(). + * Providing a value beyond bound will either clamp it, or trigger an error (depending on parameter). + * Setting a parameter is only possible during frame initialization (before starting decompression). + * @return : 0, or an error code (which can be tested using ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int value); + +/*! ZSTD_DCtx_reset() : + * Return a DCtx to clean state. + * Session and parameters can be reset jointly or separately. + * Parameters can only be reset when no active frame is being decompressed. + * @return : 0, or an error code, which can be tested with ZSTD_isError() + */ +ZSTDLIB_API size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset); + + +/**************************** +* Streaming +****************************/ + +typedef struct ZSTD_inBuffer_s { + const void* src; /**< start of input buffer */ + size_t size; /**< size of input buffer */ + size_t pos; /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */ +} ZSTD_inBuffer; + +typedef struct ZSTD_outBuffer_s { + void* dst; /**< start of output buffer */ + size_t size; /**< size of output buffer */ + size_t pos; /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */ +} ZSTD_outBuffer; + +/************************** +* Simple dictionary API +***************************/ +/*! ZSTD_compress_usingDict() : + * Compression at an explicit compression level using a Dictionary. + * A dictionary can be any arbitrary data segment (also called a prefix), + * or a buffer with specified information (see zdict.h). + * Note : This function loads the dictionary, resulting in significant startup delay. + * It's intended for a dictionary used only once. + * Note 2 : When `dict == NULL || dictSize < 8` no dictionary is used. */ +ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + int compressionLevel); + +/*! ZSTD_decompress_usingDict() : + * Decompression using a known Dictionary. + * Dictionary must be identical to the one used during compression. + * Note : This function loads the dictionary, resulting in significant startup delay. + * It's intended for a dictionary used only once. + * Note : When `dict == NULL || dictSize < 8` no dictionary is used. */ +ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize); + + +/*********************************** + * Bulk processing dictionary API + **********************************/ +typedef struct ZSTD_CDict_s ZSTD_CDict; + +/*! ZSTD_createCDict() : + * When compressing multiple messages or blocks using the same dictionary, + * it's recommended to digest the dictionary only once, since it's a costly operation. + * ZSTD_createCDict() will create a state from digesting a dictionary. + * The resulting state can be used for future compression operations with very limited startup cost. + * ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only. + * @dictBuffer can be released after ZSTD_CDict creation, because its content is copied within CDict. + * Note 1 : Consider experimental function `ZSTD_createCDict_byReference()` if you prefer to not duplicate @dictBuffer content. + * Note 2 : A ZSTD_CDict can be created from an empty @dictBuffer, + * in which case the only thing that it transports is the @compressionLevel. + * This can be useful in a pipeline featuring ZSTD_compress_usingCDict() exclusively, + * expecting a ZSTD_CDict parameter with any data, including those without a known dictionary. */ +ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize, + int compressionLevel); + +/*! ZSTD_freeCDict() : + * Function frees memory allocated by ZSTD_createCDict(). + * If a NULL pointer is passed, no operation is performed. */ +ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict); + +/*! ZSTD_compress_usingCDict() : + * Compression using a digested Dictionary. + * Recommended when same dictionary is used multiple times. + * Note : compression level is _decided at dictionary creation time_, + * and frame parameters are hardcoded (dictID=yes, contentSize=yes, checksum=no) */ +ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict); + + +typedef struct ZSTD_DDict_s ZSTD_DDict; + +/*! ZSTD_createDDict() : + * Create a digested dictionary, ready to start decompression operation without startup delay. + * dictBuffer can be released after DDict creation, as its content is copied inside DDict. */ +ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize); + +/*! ZSTD_freeDDict() : + * Function frees memory allocated with ZSTD_createDDict() + * If a NULL pointer is passed, no operation is performed. */ +ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict); + +/*! ZSTD_decompress_usingDDict() : + * Decompression using a digested Dictionary. + * Recommended when same dictionary is used multiple times. */ +ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_DDict* ddict); + + +/******************************** + * Dictionary helper functions + *******************************/ + +/*! ZSTD_getDictID_fromDict() : Requires v1.4.0+ + * Provides the dictID stored within dictionary. + * if @return == 0, the dictionary is not conformant with Zstandard specification. + * It can still be loaded, but as a content-only dictionary. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize); + +/*! ZSTD_getDictID_fromCDict() : Requires v1.5.0+ + * Provides the dictID of the dictionary loaded into `cdict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict); + +/*! ZSTD_getDictID_fromDDict() : Requires v1.4.0+ + * Provides the dictID of the dictionary loaded into `ddict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict); + +/*! ZSTD_getDictID_fromFrame() : Requires v1.4.0+ + * Provides the dictID required to decompressed the frame stored within `src`. + * If @return == 0, the dictID could not be decoded. + * This could for one of the following reasons : + * - The frame does not require a dictionary to be decoded (most common case). + * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden piece of information. + * Note : this use case also happens when using a non-conformant dictionary. + * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). + * - This is not a Zstandard frame. + * When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize); + + +/******************************************************************************* + * Advanced dictionary and prefix API (Requires v1.4.0+) + * + * This API allows dictionaries to be used with ZSTD_compress2(), + * ZSTD_compressStream2(), and ZSTD_decompressDCtx(). + * Dictionaries are sticky, they remain valid when same context is reused, + * they only reset when the context is reset + * with ZSTD_reset_parameters or ZSTD_reset_session_and_parameters. + * In contrast, Prefixes are single-use. + ******************************************************************************/ + + +/*! ZSTD_CCtx_loadDictionary() : Requires v1.4.0+ + * Create an internal CDict from `dict` buffer. + * Decompression will have to use same dictionary. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special: Loading a NULL (or 0-size) dictionary invalidates previous dictionary, + * meaning "return to no-dictionary mode". + * Note 1 : Dictionary is sticky, it will be used for all future compressed frames, + * until parameters are reset, a new dictionary is loaded, or the dictionary + * is explicitly invalidated by loading a NULL dictionary. + * Note 2 : Loading a dictionary involves building tables. + * It's also a CPU consuming operation, with non-negligible impact on latency. + * Tables are dependent on compression parameters, and for this reason, + * compression parameters can no longer be changed after loading a dictionary. + * Note 3 :`dict` content will be copied internally. + * Use experimental ZSTD_CCtx_loadDictionary_byReference() to reference content instead. + * In such a case, dictionary buffer must outlive its users. + * Note 4 : Use ZSTD_CCtx_loadDictionary_advanced() + * to precisely select how dictionary content must be interpreted. + * Note 5 : This method does not benefit from LDM (long distance mode). + * If you want to employ LDM on some large dictionary content, + * prefer employing ZSTD_CCtx_refPrefix() described below. + */ +ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); + +/*! ZSTD_CCtx_refCDict() : Requires v1.4.0+ + * Reference a prepared dictionary, to be used for all future compressed frames. + * Note that compression parameters are enforced from within CDict, + * and supersede any compression parameter previously set within CCtx. + * The parameters ignored are labelled as "superseded-by-cdict" in the ZSTD_cParameter enum docs. + * The ignored parameters will be used again if the CCtx is returned to no-dictionary mode. + * The dictionary will remain valid for future compressed frames using same CCtx. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special : Referencing a NULL CDict means "return to no-dictionary mode". + * Note 1 : Currently, only one dictionary can be managed. + * Referencing a new dictionary effectively "discards" any previous one. + * Note 2 : CDict is just referenced, its lifetime must outlive its usage within CCtx. */ +ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); + +/*! ZSTD_CCtx_refPrefix() : Requires v1.4.0+ + * Reference a prefix (single-usage dictionary) for next compressed frame. + * A prefix is **only used once**. Tables are discarded at end of frame (ZSTD_e_end). + * Decompression will need same prefix to properly regenerate data. + * Compressing with a prefix is similar in outcome as performing a diff and compressing it, + * but performs much faster, especially during decompression (compression speed is tunable with compression level). + * This method is compatible with LDM (long distance mode). + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special: Adding any prefix (including NULL) invalidates any previous prefix or dictionary + * Note 1 : Prefix buffer is referenced. It **must** outlive compression. + * Its content must remain unmodified during compression. + * Note 2 : If the intention is to diff some large src data blob with some prior version of itself, + * ensure that the window size is large enough to contain the entire source. + * See ZSTD_c_windowLog. + * Note 3 : Referencing a prefix involves building tables, which are dependent on compression parameters. + * It's a CPU consuming operation, with non-negligible impact on latency. + * If there is a need to use the same prefix multiple times, consider loadDictionary instead. + * Note 4 : By default, the prefix is interpreted as raw content (ZSTD_dct_rawContent). + * Use experimental ZSTD_CCtx_refPrefix_advanced() to alter dictionary interpretation. */ +ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, + const void* prefix, size_t prefixSize); + +/*! ZSTD_DCtx_loadDictionary() : Requires v1.4.0+ + * Create an internal DDict from dict buffer, to be used to decompress all future frames. + * The dictionary remains valid for all future frames, until explicitly invalidated, or + * a new dictionary is loaded. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary, + * meaning "return to no-dictionary mode". + * Note 1 : Loading a dictionary involves building tables, + * which has a non-negligible impact on CPU usage and latency. + * It's recommended to "load once, use many times", to amortize the cost + * Note 2 :`dict` content will be copied internally, so `dict` can be released after loading. + * Use ZSTD_DCtx_loadDictionary_byReference() to reference dictionary content instead. + * Note 3 : Use ZSTD_DCtx_loadDictionary_advanced() to take control of + * how dictionary content is loaded and interpreted. + */ +ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); + +/*! ZSTD_DCtx_refDDict() : Requires v1.4.0+ + * Reference a prepared dictionary, to be used to decompress next frames. + * The dictionary remains active for decompression of future frames using same DCtx. + * + * If called with ZSTD_d_refMultipleDDicts enabled, repeated calls of this function + * will store the DDict references in a table, and the DDict used for decompression + * will be determined at decompression time, as per the dict ID in the frame. + * The memory for the table is allocated on the first call to refDDict, and can be + * freed with ZSTD_freeDCtx(). + * + * If called with ZSTD_d_refMultipleDDicts disabled (the default), only one dictionary + * will be managed, and referencing a dictionary effectively "discards" any previous one. + * + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special: referencing a NULL DDict means "return to no-dictionary mode". + * Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx. + */ +ZSTDLIB_API size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); + +/*! ZSTD_DCtx_refPrefix() : Requires v1.4.0+ + * Reference a prefix (single-usage dictionary) to decompress next frame. + * This is the reverse operation of ZSTD_CCtx_refPrefix(), + * and must use the same prefix as the one used during compression. + * Prefix is **only used once**. Reference is discarded at end of frame. + * End of frame is reached when ZSTD_decompressStream() returns 0. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Note 1 : Adding any prefix (including NULL) invalidates any previously set prefix or dictionary + * Note 2 : Prefix buffer is referenced. It **must** outlive decompression. + * Prefix buffer must remain unmodified up to the end of frame, + * reached when ZSTD_decompressStream() returns 0. + * Note 3 : By default, the prefix is treated as raw content (ZSTD_dct_rawContent). + * Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode (Experimental section) + * Note 4 : Referencing a raw content prefix has almost no cpu nor memory cost. + * A full dictionary is more costly, as it requires building tables. + */ +ZSTDLIB_API size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, + const void* prefix, size_t prefixSize); + +/* === Memory management === */ + +/*! ZSTD_sizeof_*() : Requires v1.4.0+ + * These functions give the _current_ memory usage of selected object. + * Note that object memory usage can evolve (increase or decrease) over time. */ +ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx); +ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx); +ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict); +ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_H_235446 */ + + +/* ************************************************************************************** + * ADVANCED AND EXPERIMENTAL FUNCTIONS + **************************************************************************************** + * The definitions in the following section are considered experimental. + * They are provided for advanced scenarios. + * They should never be used with a dynamic library, as prototypes may change in the future. + * Use them only in association with static linking. + * ***************************************************************************************/ + +#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) +#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY + +#if defined (__cplusplus) +extern "C" { +#endif + +/* This can be overridden externally to hide static symbols. */ +#ifndef ZSTDLIB_STATIC_API +# if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZSTDLIB_STATIC_API __declspec(dllexport) ZSTDLIB_VISIBLE +# elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZSTDLIB_STATIC_API __declspec(dllimport) ZSTDLIB_VISIBLE +# else +# define ZSTDLIB_STATIC_API ZSTDLIB_VISIBLE +# endif +#endif + +/**************************************************************************************** + * experimental API (static linking only) + **************************************************************************************** + * The following symbols and constants + * are not planned to join "stable API" status in the near future. + * They can still change in future versions. + * Some of them are planned to remain in the static_only section indefinitely. + * Some of them might be removed in the future (especially when redundant with existing stable functions) + * ***************************************************************************************/ + +#define ZSTD_FRAMEHEADERSIZE_PREFIX(format) ((format) == ZSTD_f_zstd1 ? 5 : 1) /* minimum input size required to query frame header size */ +#define ZSTD_FRAMEHEADERSIZE_MIN(format) ((format) == ZSTD_f_zstd1 ? 6 : 2) +#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* can be useful for static allocation */ +#define ZSTD_SKIPPABLEHEADERSIZE 8 + +/* compression parameter bounds */ +#define ZSTD_WINDOWLOG_MAX_32 30 +#define ZSTD_WINDOWLOG_MAX_64 31 +#define ZSTD_WINDOWLOG_MAX ((int)(sizeof(size_t) == 4 ? ZSTD_WINDOWLOG_MAX_32 : ZSTD_WINDOWLOG_MAX_64)) +#define ZSTD_WINDOWLOG_MIN 10 +#define ZSTD_HASHLOG_MAX ((ZSTD_WINDOWLOG_MAX < 30) ? ZSTD_WINDOWLOG_MAX : 30) +#define ZSTD_HASHLOG_MIN 6 +#define ZSTD_CHAINLOG_MAX_32 29 +#define ZSTD_CHAINLOG_MAX_64 30 +#define ZSTD_CHAINLOG_MAX ((int)(sizeof(size_t) == 4 ? ZSTD_CHAINLOG_MAX_32 : ZSTD_CHAINLOG_MAX_64)) +#define ZSTD_CHAINLOG_MIN ZSTD_HASHLOG_MIN +#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1) +#define ZSTD_SEARCHLOG_MIN 1 +#define ZSTD_MINMATCH_MAX 7 /* only for ZSTD_fast, other strategies are limited to 6 */ +#define ZSTD_MINMATCH_MIN 3 /* only for ZSTD_btopt+, faster strategies are limited to 4 */ +#define ZSTD_TARGETLENGTH_MAX ZSTD_BLOCKSIZE_MAX +#define ZSTD_TARGETLENGTH_MIN 0 /* note : comparing this constant to an unsigned results in a tautological test */ +#define ZSTD_STRATEGY_MIN ZSTD_fast +#define ZSTD_STRATEGY_MAX ZSTD_btultra2 +#define ZSTD_BLOCKSIZE_MAX_MIN (1 << 10) /* The minimum valid max blocksize. Maximum blocksizes smaller than this make compressBound() inaccurate. */ + + +#define ZSTD_OVERLAPLOG_MIN 0 +#define ZSTD_OVERLAPLOG_MAX 9 + +#define ZSTD_WINDOWLOG_LIMIT_DEFAULT 27 /* by default, the streaming decoder will refuse any frame + * requiring larger than (1< 0: + * If litLength != 0: + * rep == 1 --> offset == repeat_offset_1 + * rep == 2 --> offset == repeat_offset_2 + * rep == 3 --> offset == repeat_offset_3 + * If litLength == 0: + * rep == 1 --> offset == repeat_offset_2 + * rep == 2 --> offset == repeat_offset_3 + * rep == 3 --> offset == repeat_offset_1 - 1 + * + * Note: This field is optional. ZSTD_generateSequences() will calculate the value of + * 'rep', but repeat offsets do not necessarily need to be calculated from an external + * sequence provider perspective. For example, ZSTD_compressSequences() does not + * use this 'rep' field at all (as of now). + */ +} ZSTD_Sequence; + +typedef struct { + unsigned windowLog; /**< largest match distance : larger == more compression, more memory needed during decompression */ + unsigned chainLog; /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */ + unsigned hashLog; /**< dispatch table : larger == faster, more memory */ + unsigned searchLog; /**< nb of searches : larger == more compression, slower */ + unsigned minMatch; /**< match length searched : larger == faster decompression, sometimes less compression */ + unsigned targetLength; /**< acceptable match size for optimal parser (only) : larger == more compression, slower */ + ZSTD_strategy strategy; /**< see ZSTD_strategy definition above */ +} ZSTD_compressionParameters; + +typedef struct { + int contentSizeFlag; /**< 1: content size will be in frame header (when known) */ + int checksumFlag; /**< 1: generate a 32-bits checksum using XXH64 algorithm at end of frame, for error detection */ + int noDictIDFlag; /**< 1: no dictID will be saved into frame header (dictID is only useful for dictionary compression) */ +} ZSTD_frameParameters; + +typedef struct { + ZSTD_compressionParameters cParams; + ZSTD_frameParameters fParams; +} ZSTD_parameters; + +typedef enum { + ZSTD_dct_auto = 0, /* dictionary is "full" when starting with ZSTD_MAGIC_DICTIONARY, otherwise it is "rawContent" */ + ZSTD_dct_rawContent = 1, /* ensures dictionary is always loaded as rawContent, even if it starts with ZSTD_MAGIC_DICTIONARY */ + ZSTD_dct_fullDict = 2 /* refuses to load a dictionary if it does not respect Zstandard's specification, starting with ZSTD_MAGIC_DICTIONARY */ +} ZSTD_dictContentType_e; + +typedef enum { + ZSTD_dlm_byCopy = 0, /**< Copy dictionary content internally */ + ZSTD_dlm_byRef = 1 /**< Reference dictionary content -- the dictionary buffer must outlive its users. */ +} ZSTD_dictLoadMethod_e; + +typedef enum { + ZSTD_f_zstd1 = 0, /* zstd frame format, specified in zstd_compression_format.md (default) */ + ZSTD_f_zstd1_magicless = 1 /* Variant of zstd frame format, without initial 4-bytes magic number. + * Useful to save 4 bytes per generated frame. + * Decoder cannot recognise automatically this format, requiring this instruction. */ +} ZSTD_format_e; + +typedef enum { + /* Note: this enum controls ZSTD_d_forceIgnoreChecksum */ + ZSTD_d_validateChecksum = 0, + ZSTD_d_ignoreChecksum = 1 +} ZSTD_forceIgnoreChecksum_e; + +typedef enum { + /* Note: this enum controls ZSTD_d_refMultipleDDicts */ + ZSTD_rmd_refSingleDDict = 0, + ZSTD_rmd_refMultipleDDicts = 1 +} ZSTD_refMultipleDDicts_e; + +typedef enum { + /* Note: this enum and the behavior it controls are effectively internal + * implementation details of the compressor. They are expected to continue + * to evolve and should be considered only in the context of extremely + * advanced performance tuning. + * + * Zstd currently supports the use of a CDict in three ways: + * + * - The contents of the CDict can be copied into the working context. This + * means that the compression can search both the dictionary and input + * while operating on a single set of internal tables. This makes + * the compression faster per-byte of input. However, the initial copy of + * the CDict's tables incurs a fixed cost at the beginning of the + * compression. For small compressions (< 8 KB), that copy can dominate + * the cost of the compression. + * + * - The CDict's tables can be used in-place. In this model, compression is + * slower per input byte, because the compressor has to search two sets of + * tables. However, this model incurs no start-up cost (as long as the + * working context's tables can be reused). For small inputs, this can be + * faster than copying the CDict's tables. + * + * - The CDict's tables are not used at all, and instead we use the working + * context alone to reload the dictionary and use params based on the source + * size. See ZSTD_compress_insertDictionary() and ZSTD_compress_usingDict(). + * This method is effective when the dictionary sizes are very small relative + * to the input size, and the input size is fairly large to begin with. + * + * Zstd has a simple internal heuristic that selects which strategy to use + * at the beginning of a compression. However, if experimentation shows that + * Zstd is making poor choices, it is possible to override that choice with + * this enum. + */ + ZSTD_dictDefaultAttach = 0, /* Use the default heuristic. */ + ZSTD_dictForceAttach = 1, /* Never copy the dictionary. */ + ZSTD_dictForceCopy = 2, /* Always copy the dictionary. */ + ZSTD_dictForceLoad = 3 /* Always reload the dictionary */ +} ZSTD_dictAttachPref_e; + +typedef enum { + ZSTD_lcm_auto = 0, /**< Automatically determine the compression mode based on the compression level. + * Negative compression levels will be uncompressed, and positive compression + * levels will be compressed. */ + ZSTD_lcm_huffman = 1, /**< Always attempt Huffman compression. Uncompressed literals will still be + * emitted if Huffman compression is not profitable. */ + ZSTD_lcm_uncompressed = 2 /**< Always emit uncompressed literals. */ +} ZSTD_literalCompressionMode_e; + +typedef enum { + /* Note: This enum controls features which are conditionally beneficial. + * Zstd can take a decision on whether or not to enable the feature (ZSTD_ps_auto), + * but setting the switch to ZSTD_ps_enable or ZSTD_ps_disable force enable/disable the feature. + */ + ZSTD_ps_auto = 0, /* Let the library automatically determine whether the feature shall be enabled */ + ZSTD_ps_enable = 1, /* Force-enable the feature */ + ZSTD_ps_disable = 2 /* Do not use the feature */ +} ZSTD_ParamSwitch_e; +#define ZSTD_paramSwitch_e ZSTD_ParamSwitch_e /* old name */ + +/*************************************** +* Frame header and size functions +***************************************/ + +/*! ZSTD_frameHeaderSize() : + * srcSize must be large enough, aka >= ZSTD_FRAMEHEADERSIZE_PREFIX. + * @return : size of the Frame Header, + * or an error code (if srcSize is too small) */ +ZSTDLIB_STATIC_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); + +typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_FrameType_e; +#define ZSTD_frameType_e ZSTD_FrameType_e /* old name */ +typedef struct { + unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */ + unsigned long long windowSize; /* can be very large, up to <= frameContentSize */ + unsigned blockSizeMax; + ZSTD_FrameType_e frameType; /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */ + unsigned headerSize; + unsigned dictID; /* for ZSTD_skippableFrame, contains the skippable magic variant [0-15] */ + unsigned checksumFlag; + unsigned _reserved1; + unsigned _reserved2; +} ZSTD_FrameHeader; +#define ZSTD_frameHeader ZSTD_FrameHeader /* old name */ + +/*! ZSTD_getFrameHeader() : + * decode Frame Header into `zfhPtr`, or requires larger `srcSize`. + * @return : 0 => header is complete, `zfhPtr` is correctly filled, + * >0 => `srcSize` is too small, @return value is the wanted `srcSize` amount, `zfhPtr` is not filled, + * or an error code, which can be tested using ZSTD_isError() */ +ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize); +/*! ZSTD_getFrameHeader_advanced() : + * same as ZSTD_getFrameHeader(), + * with added capability to select a format (like ZSTD_f_zstd1_magicless) */ +ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format); + +/*! ZSTD_DECOMPRESS_MARGIN() : + * Similar to ZSTD_decompressionMargin(), but instead of computing the margin from + * the compressed frame, compute it from the original size and the blockSizeLog. + * See ZSTD_decompressionMargin() for details. + * + * WARNING: This macro does not support multi-frame input, the input must be a single + * zstd frame. If you need that support use the function, or implement it yourself. + * + * @param originalSize The original uncompressed size of the data. + * @param blockSize The block size == MIN(windowSize, ZSTD_BLOCKSIZE_MAX). + * Unless you explicitly set the windowLog smaller than + * ZSTD_BLOCKSIZELOG_MAX you can just use ZSTD_BLOCKSIZE_MAX. + */ +#define ZSTD_DECOMPRESSION_MARGIN(originalSize, blockSize) ((size_t)( \ + ZSTD_FRAMEHEADERSIZE_MAX /* Frame header */ + \ + 4 /* checksum */ + \ + ((originalSize) == 0 ? 0 : 3 * (((originalSize) + (blockSize) - 1) / blockSize)) /* 3 bytes per block */ + \ + (blockSize) /* One block of margin */ \ + )) + +typedef enum { + ZSTD_sf_noBlockDelimiters = 0, /* ZSTD_Sequence[] has no block delimiters, just sequences */ + ZSTD_sf_explicitBlockDelimiters = 1 /* ZSTD_Sequence[] contains explicit block delimiters */ +} ZSTD_SequenceFormat_e; +#define ZSTD_sequenceFormat_e ZSTD_SequenceFormat_e /* old name */ + +/*! ZSTD_sequenceBound() : + * `srcSize` : size of the input buffer + * @return : upper-bound for the number of sequences that can be generated + * from a buffer of srcSize bytes + * + * note : returns number of sequences - to get bytes, multiply by sizeof(ZSTD_Sequence). + */ +ZSTDLIB_STATIC_API size_t ZSTD_sequenceBound(size_t srcSize); + +/*! ZSTD_generateSequences() : + * WARNING: This function is meant for debugging and informational purposes ONLY! + * Its implementation is flawed, and it will be deleted in a future version. + * It is not guaranteed to succeed, as there are several cases where it will give + * up and fail. You should NOT use this function in production code. + * + * This function is deprecated, and will be removed in a future version. + * + * Generate sequences using ZSTD_compress2(), given a source buffer. + * + * @param zc The compression context to be used for ZSTD_compress2(). Set any + * compression parameters you need on this context. + * @param outSeqs The output sequences buffer of size @p outSeqsSize + * @param outSeqsCapacity The size of the output sequences buffer. + * ZSTD_sequenceBound(srcSize) is an upper bound on the number + * of sequences that can be generated. + * @param src The source buffer to generate sequences from of size @p srcSize. + * @param srcSize The size of the source buffer. + * + * Each block will end with a dummy sequence + * with offset == 0, matchLength == 0, and litLength == length of last literals. + * litLength may be == 0, and if so, then the sequence of (of: 0 ml: 0 ll: 0) + * simply acts as a block delimiter. + * + * @returns The number of sequences generated, necessarily less than + * ZSTD_sequenceBound(srcSize), or an error code that can be checked + * with ZSTD_isError(). + */ +ZSTD_DEPRECATED("For debugging only, will be replaced by ZSTD_extractSequences()") +ZSTDLIB_STATIC_API size_t +ZSTD_generateSequences(ZSTD_CCtx* zc, + ZSTD_Sequence* outSeqs, size_t outSeqsCapacity, + const void* src, size_t srcSize); + +/*! ZSTD_mergeBlockDelimiters() : + * Given an array of ZSTD_Sequence, remove all sequences that represent block delimiters/last literals + * by merging them into the literals of the next sequence. + * + * As such, the final generated result has no explicit representation of block boundaries, + * and the final last literals segment is not represented in the sequences. + * + * The output of this function can be fed into ZSTD_compressSequences() with CCtx + * setting of ZSTD_c_blockDelimiters as ZSTD_sf_noBlockDelimiters + * @return : number of sequences left after merging + */ +ZSTDLIB_STATIC_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize); + +/*! ZSTD_compressSequences() : + * Compress an array of ZSTD_Sequence, associated with @src buffer, into dst. + * @src contains the entire input (not just the literals). + * If @srcSize > sum(sequence.length), the remaining bytes are considered all literals + * If a dictionary is included, then the cctx should reference the dict (see: ZSTD_CCtx_refCDict(), ZSTD_CCtx_loadDictionary(), etc.). + * The entire source is compressed into a single frame. + * + * The compression behavior changes based on cctx params. In particular: + * If ZSTD_c_blockDelimiters == ZSTD_sf_noBlockDelimiters, the array of ZSTD_Sequence is expected to contain + * no block delimiters (defined in ZSTD_Sequence). Block boundaries are roughly determined based on + * the block size derived from the cctx, and sequences may be split. This is the default setting. + * + * If ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, the array of ZSTD_Sequence is expected to contain + * valid block delimiters (defined in ZSTD_Sequence). Behavior is undefined if no block delimiters are provided. + * + * When ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, it's possible to decide generating repcodes + * using the advanced parameter ZSTD_c_repcodeResolution. Repcodes will improve compression ratio, though the benefit + * can vary greatly depending on Sequences. On the other hand, repcode resolution is an expensive operation. + * By default, it's disabled at low (<10) compression levels, and enabled above the threshold (>=10). + * ZSTD_c_repcodeResolution makes it possible to directly manage this processing in either direction. + * + * If ZSTD_c_validateSequences == 0, this function blindly accepts the Sequences provided. Invalid Sequences cause undefined + * behavior. If ZSTD_c_validateSequences == 1, then the function will detect invalid Sequences (see doc/zstd_compression_format.md for + * specifics regarding offset/matchlength requirements) and then bail out and return an error. + * + * In addition to the two adjustable experimental params, there are other important cctx params. + * - ZSTD_c_minMatch MUST be set as less than or equal to the smallest match generated by the match finder. It has a minimum value of ZSTD_MINMATCH_MIN. + * - ZSTD_c_compressionLevel accordingly adjusts the strength of the entropy coder, as it would in typical compression. + * - ZSTD_c_windowLog affects offset validation: this function will return an error at higher debug levels if a provided offset + * is larger than what the spec allows for a given window log and dictionary (if present). See: doc/zstd_compression_format.md + * + * Note: Repcodes are, as of now, always re-calculated within this function, ZSTD_Sequence.rep is effectively unused. + * Dev Note: Once ability to ingest repcodes become available, the explicit block delims mode must respect those repcodes exactly, + * and cannot emit an RLE block that disagrees with the repcode history. + * @return : final compressed size, or a ZSTD error code. + */ +ZSTDLIB_STATIC_API size_t +ZSTD_compressSequences(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + const void* src, size_t srcSize); + + +/*! ZSTD_compressSequencesAndLiterals() : + * This is a variant of ZSTD_compressSequences() which, + * instead of receiving (src,srcSize) as input parameter, receives (literals,litSize), + * aka all the literals, already extracted and laid out into a single continuous buffer. + * This can be useful if the process generating the sequences also happens to generate the buffer of literals, + * thus skipping an extraction + caching stage. + * It's a speed optimization, useful when the right conditions are met, + * but it also features the following limitations: + * - Only supports explicit delimiter mode + * - Currently does not support Sequences validation (so input Sequences are trusted) + * - Not compatible with frame checksum, which must be disabled + * - If any block is incompressible, will fail and return an error + * - @litSize must be == sum of all @.litLength fields in @inSeqs. Any discrepancy will generate an error. + * - @litBufCapacity is the size of the underlying buffer into which literals are written, starting at address @literals. + * @litBufCapacity must be at least 8 bytes larger than @litSize. + * - @decompressedSize must be correct, and correspond to the sum of all Sequences. Any discrepancy will generate an error. + * @return : final compressed size, or a ZSTD error code. + */ +ZSTDLIB_STATIC_API size_t +ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const ZSTD_Sequence* inSeqs, size_t nbSequences, + const void* literals, size_t litSize, size_t litBufCapacity, + size_t decompressedSize); + + +/*! ZSTD_writeSkippableFrame() : + * Generates a zstd skippable frame containing data given by src, and writes it to dst buffer. + * + * Skippable frames begin with a 4-byte magic number. There are 16 possible choices of magic number, + * ranging from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15. + * As such, the parameter magicVariant controls the exact skippable frame magic number variant used, + * so the magic number used will be ZSTD_MAGIC_SKIPPABLE_START + magicVariant. + * + * Returns an error if destination buffer is not large enough, if the source size is not representable + * with a 4-byte unsigned int, or if the parameter magicVariant is greater than 15 (and therefore invalid). + * + * @return : number of bytes written or a ZSTD error. + */ +ZSTDLIB_STATIC_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + unsigned magicVariant); + +/*! ZSTD_isSkippableFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame. + */ +ZSTDLIB_STATIC_API unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size); + + + +/*************************************** +* Memory management +***************************************/ + +/*! ZSTD_estimate*() : + * These functions make it possible to estimate memory usage + * of a future {D,C}Ctx, before its creation. + * This is useful in combination with ZSTD_initStatic(), + * which makes it possible to employ a static buffer for ZSTD_CCtx* state. + * + * ZSTD_estimateCCtxSize() will provide a memory budget large enough + * to compress data of any size using one-shot compression ZSTD_compressCCtx() or ZSTD_compress2() + * associated with any compression level up to max specified one. + * The estimate will assume the input may be arbitrarily large, + * which is the worst case. + * + * Note that the size estimation is specific for one-shot compression, + * it is not valid for streaming (see ZSTD_estimateCStreamSize*()) + * nor other potential ways of using a ZSTD_CCtx* state. + * + * When srcSize can be bound by a known and rather "small" value, + * this knowledge can be used to provide a tighter budget estimation + * because the ZSTD_CCtx* state will need less memory for small inputs. + * This tighter estimation can be provided by employing more advanced functions + * ZSTD_estimateCCtxSize_usingCParams(), which can be used in tandem with ZSTD_getCParams(), + * and ZSTD_estimateCCtxSize_usingCCtxParams(), which can be used in tandem with ZSTD_CCtxParams_setParameter(). + * Both can be used to estimate memory using custom compression parameters and arbitrary srcSize limits. + * + * Note : only single-threaded compression is supported. + * ZSTD_estimateCCtxSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. + */ +ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int maxCompressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params); +ZSTDLIB_STATIC_API size_t ZSTD_estimateDCtxSize(void); + +/*! ZSTD_estimate?DictSize() : + * ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict(). + * ZSTD_estimateCDictSize_advanced() makes it possible to control compression parameters precisely, like ZSTD_createCDict_advanced(). + * Note : dictionaries created by reference (`ZSTD_dlm_byRef`) are logically smaller. + */ +ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod); +ZSTDLIB_STATIC_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod); + +/*! ZSTD_initStatic*() : + * Initialize an object using a pre-allocated fixed-size buffer. + * workspace: The memory area to emplace the object into. + * Provided pointer *must be 8-bytes aligned*. + * Buffer must outlive object. + * workspaceSize: Use ZSTD_estimate*Size() to determine + * how large workspace must be to support target scenario. + * @return : pointer to object (same address as workspace, just different type), + * or NULL if error (size too small, incorrect alignment, etc.) + * Note : zstd will never resize nor malloc() when using a static buffer. + * If the object requires more memory than available, + * zstd will just error out (typically ZSTD_error_memory_allocation). + * Note 2 : there is no corresponding "free" function. + * Since workspace is allocated externally, it must be freed externally too. + * Note 3 : cParams : use ZSTD_getCParams() to convert a compression level + * into its associated cParams. + * Limitation 1 : currently not compatible with internal dictionary creation, triggered by + * ZSTD_CCtx_loadDictionary(), ZSTD_initCStream_usingDict() or ZSTD_initDStream_usingDict(). + * Limitation 2 : static cctx currently not compatible with multi-threading. + * Limitation 3 : static dctx is incompatible with legacy support. + */ +ZSTDLIB_STATIC_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize); + +ZSTDLIB_STATIC_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize); + +ZSTDLIB_STATIC_API const ZSTD_CDict* ZSTD_initStaticCDict( + void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams); + +ZSTDLIB_STATIC_API const ZSTD_DDict* ZSTD_initStaticDDict( + void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType); + + +/*! Custom memory allocation : + * These prototypes make it possible to pass your own allocation/free functions. + * ZSTD_customMem is provided at creation time, using ZSTD_create*_advanced() variants listed below. + * All allocation/free operations will be completed using these custom variants instead of regular ones. + */ +typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size); +typedef void (*ZSTD_freeFunction) (void* opaque, void* address); +typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem; +static +#ifdef __GNUC__ +__attribute__((__unused__)) +#endif + +#if defined(__clang__) && __clang_major__ >= 5 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif +ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */ +#if defined(__clang__) && __clang_major__ >= 5 +#pragma clang diagnostic pop +#endif + +ZSTDLIB_STATIC_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); +ZSTDLIB_STATIC_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem); + +ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams, + ZSTD_customMem customMem); + +/*! Thread pool : + * These prototypes make it possible to share a thread pool among multiple compression contexts. + * This can limit resources for applications with multiple threads where each one uses + * a threaded compression mode (via ZSTD_c_nbWorkers parameter). + * ZSTD_createThreadPool creates a new thread pool with a given number of threads. + * Note that the lifetime of such pool must exist while being used. + * ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value + * to use an internal thread pool). + * ZSTD_freeThreadPool frees a thread pool, accepts NULL pointer. + */ +typedef struct POOL_ctx_s ZSTD_threadPool; +ZSTDLIB_STATIC_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads); +ZSTDLIB_STATIC_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); /* accept NULL pointer */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool); + + +/* + * This API is temporary and is expected to change or disappear in the future! + */ +ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_advanced2( + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + const ZSTD_CCtx_params* cctxParams, + ZSTD_customMem customMem); + +ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_advanced( + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_customMem customMem); + + +/*************************************** +* Advanced compression functions +***************************************/ + +/*! ZSTD_createCDict_byReference() : + * Create a digested dictionary for compression + * Dictionary content is just referenced, not duplicated. + * As a consequence, `dictBuffer` **must** outlive CDict, + * and its content must remain unmodified throughout the lifetime of CDict. + * note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef */ +ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel); + +/*! ZSTD_getCParams() : + * @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. + * `estimatedSrcSize` value is optional, select 0 if not known */ +ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); + +/*! ZSTD_getParams() : + * same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`. + * All fields of `ZSTD_frameParameters` are set to default : contentSize=1, checksum=0, noDictID=0 */ +ZSTDLIB_STATIC_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); + +/*! ZSTD_checkCParams() : + * Ensure param values remain within authorized range. + * @return 0 on success, or an error code (can be checked with ZSTD_isError()) */ +ZSTDLIB_STATIC_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params); + +/*! ZSTD_adjustCParams() : + * optimize params for a given `srcSize` and `dictSize`. + * `srcSize` can be unknown, in which case use ZSTD_CONTENTSIZE_UNKNOWN. + * `dictSize` must be `0` when there is no dictionary. + * cPar can be invalid : all parameters will be clamped within valid range in the @return struct. + * This function never fails (wide contract) */ +ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize); + +/*! ZSTD_CCtx_setCParams() : + * Set all parameters provided within @p cparams into the working @p cctx. + * Note : if modifying parameters during compression (MT mode only), + * note that changes to the .windowLog parameter will be ignored. + * @return 0 on success, or an error code (can be checked with ZSTD_isError()). + * On failure, no parameters are updated. + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams); + +/*! ZSTD_CCtx_setFParams() : + * Set all parameters provided within @p fparams into the working @p cctx. + * @return 0 on success, or an error code (can be checked with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setFParams(ZSTD_CCtx* cctx, ZSTD_frameParameters fparams); + +/*! ZSTD_CCtx_setParams() : + * Set all parameters provided within @p params into the working @p cctx. + * @return 0 on success, or an error code (can be checked with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params); + +/*! ZSTD_compress_advanced() : + * Note : this function is now DEPRECATED. + * It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters. + * This prototype will generate compilation warnings. */ +ZSTD_DEPRECATED("use ZSTD_compress2") +ZSTDLIB_STATIC_API +size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + ZSTD_parameters params); + +/*! ZSTD_compress_usingCDict_advanced() : + * Note : this function is now DEPRECATED. + * It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_loadDictionary() and other parameter setters. + * This prototype will generate compilation warnings. */ +ZSTD_DEPRECATED("use ZSTD_compress2 with ZSTD_CCtx_loadDictionary") +ZSTDLIB_STATIC_API +size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict, + ZSTD_frameParameters fParams); + + +/*! ZSTD_CCtx_loadDictionary_byReference() : + * Same as ZSTD_CCtx_loadDictionary(), but dictionary content is referenced, instead of being copied into CCtx. + * It saves some memory, but also requires that `dict` outlives its usage within `cctx` */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); + +/*! ZSTD_CCtx_loadDictionary_advanced() : + * Same as ZSTD_CCtx_loadDictionary(), but gives finer control over + * how to load the dictionary (by copy ? by reference ?) + * and how to interpret it (automatic ? force raw mode ? full mode only ?) */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); + +/*! ZSTD_CCtx_refPrefix_advanced() : + * Same as ZSTD_CCtx_refPrefix(), but gives finer control over + * how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType); + +/* === experimental parameters === */ +/* these parameters can be used with ZSTD_setParameter() + * they are not guaranteed to remain supported in the future */ + + /* Enables rsyncable mode, + * which makes compressed files more rsync friendly + * by adding periodic synchronization points to the compressed data. + * The target average block size is ZSTD_c_jobSize / 2. + * It's possible to modify the job size to increase or decrease + * the granularity of the synchronization point. + * Once the jobSize is smaller than the window size, + * it will result in compression ratio degradation. + * NOTE 1: rsyncable mode only works when multithreading is enabled. + * NOTE 2: rsyncable performs poorly in combination with long range mode, + * since it will decrease the effectiveness of synchronization points, + * though mileage may vary. + * NOTE 3: Rsyncable mode limits maximum compression speed to ~400 MB/s. + * If the selected compression level is already running significantly slower, + * the overall speed won't be significantly impacted. + */ + #define ZSTD_c_rsyncable ZSTD_c_experimentalParam1 + +/* Select a compression format. + * The value must be of type ZSTD_format_e. + * See ZSTD_format_e enum definition for details */ +#define ZSTD_c_format ZSTD_c_experimentalParam2 + +/* Force back-reference distances to remain < windowSize, + * even when referencing into Dictionary content (default:0) */ +#define ZSTD_c_forceMaxWindow ZSTD_c_experimentalParam3 + +/* Controls whether the contents of a CDict + * are used in place, or copied into the working context. + * Accepts values from the ZSTD_dictAttachPref_e enum. + * See the comments on that enum for an explanation of the feature. */ +#define ZSTD_c_forceAttachDict ZSTD_c_experimentalParam4 + +/* Controlled with ZSTD_ParamSwitch_e enum. + * Default is ZSTD_ps_auto. + * Set to ZSTD_ps_disable to never compress literals. + * Set to ZSTD_ps_enable to always compress literals. (Note: uncompressed literals + * may still be emitted if huffman is not beneficial to use.) + * + * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use + * literals compression based on the compression parameters - specifically, + * negative compression levels do not use literal compression. + */ +#define ZSTD_c_literalCompressionMode ZSTD_c_experimentalParam5 + +/* User's best guess of source size. + * Hint is not valid when srcSizeHint == 0. + * There is no guarantee that hint is close to actual source size, + * but compression ratio may regress significantly if guess considerably underestimates */ +#define ZSTD_c_srcSizeHint ZSTD_c_experimentalParam7 + +/* Controls whether the new and experimental "dedicated dictionary search + * structure" can be used. This feature is still rough around the edges, be + * prepared for surprising behavior! + * + * How to use it: + * + * When using a CDict, whether to use this feature or not is controlled at + * CDict creation, and it must be set in a CCtxParams set passed into that + * construction (via ZSTD_createCDict_advanced2()). A compression will then + * use the feature or not based on how the CDict was constructed; the value of + * this param, set in the CCtx, will have no effect. + * + * However, when a dictionary buffer is passed into a CCtx, such as via + * ZSTD_CCtx_loadDictionary(), this param can be set on the CCtx to control + * whether the CDict that is created internally can use the feature or not. + * + * What it does: + * + * Normally, the internal data structures of the CDict are analogous to what + * would be stored in a CCtx after compressing the contents of a dictionary. + * To an approximation, a compression using a dictionary can then use those + * data structures to simply continue what is effectively a streaming + * compression where the simulated compression of the dictionary left off. + * Which is to say, the search structures in the CDict are normally the same + * format as in the CCtx. + * + * It is possible to do better, since the CDict is not like a CCtx: the search + * structures are written once during CDict creation, and then are only read + * after that, while the search structures in the CCtx are both read and + * written as the compression goes along. This means we can choose a search + * structure for the dictionary that is read-optimized. + * + * This feature enables the use of that different structure. + * + * Note that some of the members of the ZSTD_compressionParameters struct have + * different semantics and constraints in the dedicated search structure. It is + * highly recommended that you simply set a compression level in the CCtxParams + * you pass into the CDict creation call, and avoid messing with the cParams + * directly. + * + * Effects: + * + * This will only have any effect when the selected ZSTD_strategy + * implementation supports this feature. Currently, that's limited to + * ZSTD_greedy, ZSTD_lazy, and ZSTD_lazy2. + * + * Note that this means that the CDict tables can no longer be copied into the + * CCtx, so the dict attachment mode ZSTD_dictForceCopy will no longer be + * usable. The dictionary can only be attached or reloaded. + * + * In general, you should expect compression to be faster--sometimes very much + * so--and CDict creation to be slightly slower. Eventually, we will probably + * make this mode the default. + */ +#define ZSTD_c_enableDedicatedDictSearch ZSTD_c_experimentalParam8 + +/* ZSTD_c_stableInBuffer + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable. + * + * Tells the compressor that input data presented with ZSTD_inBuffer + * will ALWAYS be the same between calls. + * Technically, the @src pointer must never be changed, + * and the @pos field can only be updated by zstd. + * However, it's possible to increase the @size field, + * allowing scenarios where more data can be appended after compressions starts. + * These conditions are checked by the compressor, + * and compression will fail if they are not respected. + * Also, data in the ZSTD_inBuffer within the range [src, src + pos) + * MUST not be modified during compression or it will result in data corruption. + * + * When this flag is enabled zstd won't allocate an input window buffer, + * because the user guarantees it can reference the ZSTD_inBuffer until + * the frame is complete. But, it will still allocate an output buffer + * large enough to fit a block (see ZSTD_c_stableOutBuffer). This will also + * avoid the memcpy() from the input buffer to the input window buffer. + * + * NOTE: So long as the ZSTD_inBuffer always points to valid memory, using + * this flag is ALWAYS memory safe, and will never access out-of-bounds + * memory. However, compression WILL fail if conditions are not respected. + * + * WARNING: The data in the ZSTD_inBuffer in the range [src, src + pos) MUST + * not be modified during compression or it will result in data corruption. + * This is because zstd needs to reference data in the ZSTD_inBuffer to find + * matches. Normally zstd maintains its own window buffer for this purpose, + * but passing this flag tells zstd to rely on user provided buffer instead. + */ +#define ZSTD_c_stableInBuffer ZSTD_c_experimentalParam9 + +/* ZSTD_c_stableOutBuffer + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable. + * + * Tells he compressor that the ZSTD_outBuffer will not be resized between + * calls. Specifically: (out.size - out.pos) will never grow. This gives the + * compressor the freedom to say: If the compressed data doesn't fit in the + * output buffer then return ZSTD_error_dstSizeTooSmall. This allows us to + * always decompress directly into the output buffer, instead of decompressing + * into an internal buffer and copying to the output buffer. + * + * When this flag is enabled zstd won't allocate an output buffer, because + * it can write directly to the ZSTD_outBuffer. It will still allocate the + * input window buffer (see ZSTD_c_stableInBuffer). + * + * Zstd will check that (out.size - out.pos) never grows and return an error + * if it does. While not strictly necessary, this should prevent surprises. + */ +#define ZSTD_c_stableOutBuffer ZSTD_c_experimentalParam10 + +/* ZSTD_c_blockDelimiters + * Default is 0 == ZSTD_sf_noBlockDelimiters. + * + * For use with sequence compression API: ZSTD_compressSequences(). + * + * Designates whether or not the given array of ZSTD_Sequence contains block delimiters + * and last literals, which are defined as sequences with offset == 0 and matchLength == 0. + * See the definition of ZSTD_Sequence for more specifics. + */ +#define ZSTD_c_blockDelimiters ZSTD_c_experimentalParam11 + +/* ZSTD_c_validateSequences + * Default is 0 == disabled. Set to 1 to enable sequence validation. + * + * For use with sequence compression API: ZSTD_compressSequences*(). + * Designates whether or not provided sequences are validated within ZSTD_compressSequences*() + * during function execution. + * + * When Sequence validation is disabled (default), Sequences are compressed as-is, + * so they must correct, otherwise it would result in a corruption error. + * + * Sequence validation adds some protection, by ensuring that all values respect boundary conditions. + * If a Sequence is detected invalid (see doc/zstd_compression_format.md for + * specifics regarding offset/matchlength requirements) then the function will bail out and + * return an error. + */ +#define ZSTD_c_validateSequences ZSTD_c_experimentalParam12 + +/* ZSTD_c_blockSplitterLevel + * note: this parameter only influences the first splitter stage, + * which is active before producing the sequences. + * ZSTD_c_splitAfterSequences controls the next splitter stage, + * which is active after sequence production. + * Note that both can be combined. + * Allowed values are between 0 and ZSTD_BLOCKSPLITTER_LEVEL_MAX included. + * 0 means "auto", which will select a value depending on current ZSTD_c_strategy. + * 1 means no splitting. + * Then, values from 2 to 6 are sorted in increasing cpu load order. + * + * Note that currently the first block is never split, + * to ensure expansion guarantees in presence of incompressible data. + */ +#define ZSTD_BLOCKSPLITTER_LEVEL_MAX 6 +#define ZSTD_c_blockSplitterLevel ZSTD_c_experimentalParam20 + +/* ZSTD_c_splitAfterSequences + * This is a stronger splitter algorithm, + * based on actual sequences previously produced by the selected parser. + * It's also slower, and as a consequence, mostly used for high compression levels. + * While the post-splitter does overlap with the pre-splitter, + * both can nonetheless be combined, + * notably with ZSTD_c_blockSplitterLevel at ZSTD_BLOCKSPLITTER_LEVEL_MAX, + * resulting in higher compression ratio than just one of them. + * + * Default is ZSTD_ps_auto. + * Set to ZSTD_ps_disable to never use block splitter. + * Set to ZSTD_ps_enable to always use block splitter. + * + * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use + * block splitting based on the compression parameters. + */ +#define ZSTD_c_splitAfterSequences ZSTD_c_experimentalParam13 + +/* ZSTD_c_useRowMatchFinder + * Controlled with ZSTD_ParamSwitch_e enum. + * Default is ZSTD_ps_auto. + * Set to ZSTD_ps_disable to never use row-based matchfinder. + * Set to ZSTD_ps_enable to force usage of row-based matchfinder. + * + * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use + * the row-based matchfinder based on support for SIMD instructions and the window log. + * Note that this only pertains to compression strategies: greedy, lazy, and lazy2 + */ +#define ZSTD_c_useRowMatchFinder ZSTD_c_experimentalParam14 + +/* ZSTD_c_deterministicRefPrefix + * Default is 0 == disabled. Set to 1 to enable. + * + * Zstd produces different results for prefix compression when the prefix is + * directly adjacent to the data about to be compressed vs. when it isn't. + * This is because zstd detects that the two buffers are contiguous and it can + * use a more efficient match finding algorithm. However, this produces different + * results than when the two buffers are non-contiguous. This flag forces zstd + * to always load the prefix in non-contiguous mode, even if it happens to be + * adjacent to the data, to guarantee determinism. + * + * If you really care about determinism when using a dictionary or prefix, + * like when doing delta compression, you should select this option. It comes + * at a speed penalty of about ~2.5% if the dictionary and data happened to be + * contiguous, and is free if they weren't contiguous. We don't expect that + * intentionally making the dictionary and data contiguous will be worth the + * cost to memcpy() the data. + */ +#define ZSTD_c_deterministicRefPrefix ZSTD_c_experimentalParam15 + +/* ZSTD_c_prefetchCDictTables + * Controlled with ZSTD_ParamSwitch_e enum. Default is ZSTD_ps_auto. + * + * In some situations, zstd uses CDict tables in-place rather than copying them + * into the working context. (See docs on ZSTD_dictAttachPref_e above for details). + * In such situations, compression speed is seriously impacted when CDict tables are + * "cold" (outside CPU cache). This parameter instructs zstd to prefetch CDict tables + * when they are used in-place. + * + * For sufficiently small inputs, the cost of the prefetch will outweigh the benefit. + * For sufficiently large inputs, zstd will by default memcpy() CDict tables + * into the working context, so there is no need to prefetch. This parameter is + * targeted at a middle range of input sizes, where a prefetch is cheap enough to be + * useful but memcpy() is too expensive. The exact range of input sizes where this + * makes sense is best determined by careful experimentation. + * + * Note: for this parameter, ZSTD_ps_auto is currently equivalent to ZSTD_ps_disable, + * but in the future zstd may conditionally enable this feature via an auto-detection + * heuristic for cold CDicts. + * Use ZSTD_ps_disable to opt out of prefetching under any circumstances. + */ +#define ZSTD_c_prefetchCDictTables ZSTD_c_experimentalParam16 + +/* ZSTD_c_enableSeqProducerFallback + * Allowed values are 0 (disable) and 1 (enable). The default setting is 0. + * + * Controls whether zstd will fall back to an internal sequence producer if an + * external sequence producer is registered and returns an error code. This fallback + * is block-by-block: the internal sequence producer will only be called for blocks + * where the external sequence producer returns an error code. Fallback parsing will + * follow any other cParam settings, such as compression level, the same as in a + * normal (fully-internal) compression operation. + * + * The user is strongly encouraged to read the full Block-Level Sequence Producer API + * documentation (below) before setting this parameter. */ +#define ZSTD_c_enableSeqProducerFallback ZSTD_c_experimentalParam17 + +/* ZSTD_c_maxBlockSize + * Allowed values are between 1KB and ZSTD_BLOCKSIZE_MAX (128KB). + * The default is ZSTD_BLOCKSIZE_MAX, and setting to 0 will set to the default. + * + * This parameter can be used to set an upper bound on the blocksize + * that overrides the default ZSTD_BLOCKSIZE_MAX. It cannot be used to set upper + * bounds greater than ZSTD_BLOCKSIZE_MAX or bounds lower than 1KB (will make + * compressBound() inaccurate). Only currently meant to be used for testing. + */ +#define ZSTD_c_maxBlockSize ZSTD_c_experimentalParam18 + +/* ZSTD_c_repcodeResolution + * This parameter only has an effect if ZSTD_c_blockDelimiters is + * set to ZSTD_sf_explicitBlockDelimiters (may change in the future). + * + * This parameter affects how zstd parses external sequences, + * provided via the ZSTD_compressSequences*() API + * or from an external block-level sequence producer. + * + * If set to ZSTD_ps_enable, the library will check for repeated offsets within + * external sequences, even if those repcodes are not explicitly indicated in + * the "rep" field. Note that this is the only way to exploit repcode matches + * while using compressSequences*() or an external sequence producer, since zstd + * currently ignores the "rep" field of external sequences. + * + * If set to ZSTD_ps_disable, the library will not exploit repeated offsets in + * external sequences, regardless of whether the "rep" field has been set. This + * reduces sequence compression overhead by about 25% while sacrificing some + * compression ratio. + * + * The default value is ZSTD_ps_auto, for which the library will enable/disable + * based on compression level (currently: level<10 disables, level>=10 enables). + */ +#define ZSTD_c_repcodeResolution ZSTD_c_experimentalParam19 +#define ZSTD_c_searchForExternalRepcodes ZSTD_c_experimentalParam19 /* older name */ + + +/*! ZSTD_CCtx_getParameter() : + * Get the requested compression parameter value, selected by enum ZSTD_cParameter, + * and store it into int* value. + * @return : 0, or an error code (which can be tested with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value); + + +/*! ZSTD_CCtx_params : + * Quick howto : + * - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure + * - ZSTD_CCtxParams_setParameter() : Push parameters one by one into + * an existing ZSTD_CCtx_params structure. + * This is similar to + * ZSTD_CCtx_setParameter(). + * - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to + * an existing CCtx. + * These parameters will be applied to + * all subsequent frames. + * - ZSTD_compressStream2() : Do compression using the CCtx. + * - ZSTD_freeCCtxParams() : Free the memory, accept NULL pointer. + * + * This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams() + * for static allocation of CCtx for single-threaded compression. + */ +ZSTDLIB_STATIC_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void); +ZSTDLIB_STATIC_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); /* accept NULL pointer */ + +/*! ZSTD_CCtxParams_reset() : + * Reset params to default values. + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params); + +/*! ZSTD_CCtxParams_init() : + * Initializes the compression parameters of cctxParams according to + * compression level. All other parameters are reset to their default values. + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel); + +/*! ZSTD_CCtxParams_init_advanced() : + * Initializes the compression and frame parameters of cctxParams according to + * params. All other parameters are reset to their default values. + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params); + +/*! ZSTD_CCtxParams_setParameter() : Requires v1.4.0+ + * Similar to ZSTD_CCtx_setParameter. + * Set one compression parameter, selected by enum ZSTD_cParameter. + * Parameters must be applied to a ZSTD_CCtx using + * ZSTD_CCtx_setParametersUsingCCtxParams(). + * @result : a code representing success or failure (which can be tested with + * ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value); + +/*! ZSTD_CCtxParams_getParameter() : + * Similar to ZSTD_CCtx_getParameter. + * Get the requested value of one compression parameter, selected by enum ZSTD_cParameter. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value); + +/*! ZSTD_CCtx_setParametersUsingCCtxParams() : + * Apply a set of ZSTD_CCtx_params to the compression context. + * This can be done even after compression is started, + * if nbWorkers==0, this will have no impact until a new compression is started. + * if nbWorkers>=1, new parameters will be picked up at next job, + * with a few restrictions (windowLog, pledgedSrcSize, nbWorkers, jobSize, and overlapLog are not updated). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParametersUsingCCtxParams( + ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params); + + +/*************************************** +* Advanced decompression functions +***************************************/ + +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +ZSTDLIB_STATIC_API unsigned ZSTD_isFrame(const void* buffer, size_t size); + +/*! ZSTD_createDDict_byReference() : + * Create a digested dictionary, ready to start decompression operation without startup delay. + * Dictionary content is referenced, and therefore stays in dictBuffer. + * It is important that dictBuffer outlives DDict, + * it must remain read accessible throughout the lifetime of DDict */ +ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize); + +/*! ZSTD_DCtx_loadDictionary_byReference() : + * Same as ZSTD_DCtx_loadDictionary(), + * but references `dict` content instead of copying it into `dctx`. + * This saves memory if `dict` remains around., + * However, it's imperative that `dict` remains accessible (and unmodified) while being used, so it must outlive decompression. */ +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); + +/*! ZSTD_DCtx_loadDictionary_advanced() : + * Same as ZSTD_DCtx_loadDictionary(), + * but gives direct control over + * how to load the dictionary (by copy ? by reference ?) + * and how to interpret it (automatic ? force raw mode ? full mode only ?). */ +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); + +/*! ZSTD_DCtx_refPrefix_advanced() : + * Same as ZSTD_DCtx_refPrefix(), but gives finer control over + * how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */ +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType); + +/*! ZSTD_DCtx_setMaxWindowSize() : + * Refuses allocating internal buffers for frames requiring a window size larger than provided limit. + * This protects a decoder context from reserving too much memory for itself (potential attack scenario). + * This parameter is only useful in streaming mode, since no internal buffer is allocated in single-pass mode. + * By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + * @return : 0, or an error code (which can be tested using ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize); + +/*! ZSTD_DCtx_getParameter() : + * Get the requested decompression parameter value, selected by enum ZSTD_dParameter, + * and store it into int* value. + * @return : 0, or an error code (which can be tested with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value); + +/* ZSTD_d_format + * experimental parameter, + * allowing selection between ZSTD_format_e input compression formats + */ +#define ZSTD_d_format ZSTD_d_experimentalParam1 +/* ZSTD_d_stableOutBuffer + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable. + * + * Tells the decompressor that the ZSTD_outBuffer will ALWAYS be the same + * between calls, except for the modifications that zstd makes to pos (the + * caller must not modify pos). This is checked by the decompressor, and + * decompression will fail if it ever changes. Therefore the ZSTD_outBuffer + * MUST be large enough to fit the entire decompressed frame. This will be + * checked when the frame content size is known. The data in the ZSTD_outBuffer + * in the range [dst, dst + pos) MUST not be modified during decompression + * or you will get data corruption. + * + * When this flag is enabled zstd won't allocate an output buffer, because + * it can write directly to the ZSTD_outBuffer, but it will still allocate + * an input buffer large enough to fit any compressed block. This will also + * avoid the memcpy() from the internal output buffer to the ZSTD_outBuffer. + * If you need to avoid the input buffer allocation use the buffer-less + * streaming API. + * + * NOTE: So long as the ZSTD_outBuffer always points to valid memory, using + * this flag is ALWAYS memory safe, and will never access out-of-bounds + * memory. However, decompression WILL fail if you violate the preconditions. + * + * WARNING: The data in the ZSTD_outBuffer in the range [dst, dst + pos) MUST + * not be modified during decompression or you will get data corruption. This + * is because zstd needs to reference data in the ZSTD_outBuffer to regenerate + * matches. Normally zstd maintains its own buffer for this purpose, but passing + * this flag tells zstd to use the user provided buffer. + */ +#define ZSTD_d_stableOutBuffer ZSTD_d_experimentalParam2 + +/* ZSTD_d_forceIgnoreChecksum + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable + * + * Tells the decompressor to skip checksum validation during decompression, regardless + * of whether checksumming was specified during compression. This offers some + * slight performance benefits, and may be useful for debugging. + * Param has values of type ZSTD_forceIgnoreChecksum_e + */ +#define ZSTD_d_forceIgnoreChecksum ZSTD_d_experimentalParam3 + +/* ZSTD_d_refMultipleDDicts + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable + * + * If enabled and dctx is allocated on the heap, then additional memory will be allocated + * to store references to multiple ZSTD_DDict. That is, multiple calls of ZSTD_refDDict() + * using a given ZSTD_DCtx, rather than overwriting the previous DDict reference, will instead + * store all references. At decompression time, the appropriate dictID is selected + * from the set of DDicts based on the dictID in the frame. + * + * Usage is simply calling ZSTD_refDDict() on multiple dict buffers. + * + * Param has values of byte ZSTD_refMultipleDDicts_e + * + * WARNING: Enabling this parameter and calling ZSTD_DCtx_refDDict(), will trigger memory + * allocation for the hash table. ZSTD_freeDCtx() also frees this memory. + * Memory is allocated as per ZSTD_DCtx::customMem. + * + * Although this function allocates memory for the table, the user is still responsible for + * memory management of the underlying ZSTD_DDict* themselves. + */ +#define ZSTD_d_refMultipleDDicts ZSTD_d_experimentalParam4 + +/* ZSTD_d_disableHuffmanAssembly + * Set to 1 to disable the Huffman assembly implementation. + * The default value is 0, which allows zstd to use the Huffman assembly + * implementation if available. + * + * This parameter can be used to disable Huffman assembly at runtime. + * If you want to disable it at compile time you can define the macro + * ZSTD_DISABLE_ASM. + */ +#define ZSTD_d_disableHuffmanAssembly ZSTD_d_experimentalParam5 + +/* ZSTD_d_maxBlockSize + * Allowed values are between 1KB and ZSTD_BLOCKSIZE_MAX (128KB). + * The default is ZSTD_BLOCKSIZE_MAX, and setting to 0 will set to the default. + * + * Forces the decompressor to reject blocks whose content size is + * larger than the configured maxBlockSize. When maxBlockSize is + * larger than the windowSize, the windowSize is used instead. + * This saves memory on the decoder when you know all blocks are small. + * + * This option is typically used in conjunction with ZSTD_c_maxBlockSize. + * + * WARNING: This causes the decoder to reject otherwise valid frames + * that have block sizes larger than the configured maxBlockSize. + */ +#define ZSTD_d_maxBlockSize ZSTD_d_experimentalParam6 + + +/*! ZSTD_DCtx_setFormat() : + * This function is REDUNDANT. Prefer ZSTD_DCtx_setParameter(). + * Instruct the decoder context about what kind of data to decode next. + * This instruction is mandatory to decode data without a fully-formed header, + * such ZSTD_f_zstd1_magicless for example. + * @return : 0, or an error code (which can be tested using ZSTD_isError()). */ +ZSTD_DEPRECATED("use ZSTD_DCtx_setParameter() instead") +ZSTDLIB_STATIC_API +size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format); + + +/******************************************************************** +* Advanced streaming functions +* Warning : most of these functions are now redundant with the Advanced API. +* Once Advanced API reaches "stable" status, +* redundant functions will be deprecated, and then at some point removed. +********************************************************************/ + +typedef struct { + unsigned long long ingested; /* nb input bytes read and buffered */ + unsigned long long consumed; /* nb input bytes actually compressed */ + unsigned long long produced; /* nb of compressed bytes generated and buffered */ + unsigned long long flushed; /* nb of compressed bytes flushed : not provided; can be tracked from caller side */ + unsigned currentJobID; /* MT only : latest started job nb */ + unsigned nbActiveWorkers; /* MT only : nb of workers actively compressing at probe time */ +} ZSTD_frameProgression; + +/* ZSTD_getFrameProgression() : + * tells how much data has been ingested (read from input) + * consumed (input actually compressed) and produced (output) for current frame. + * Note : (ingested - consumed) is amount of input data buffered internally, not yet compressed. + * Aggregates progression inside active worker threads. + */ +ZSTDLIB_STATIC_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx); + +/*! ZSTD_toFlushNow() : + * Tell how many bytes are ready to be flushed immediately. + * Useful for multithreading scenarios (nbWorkers >= 1). + * Probe the oldest active job, defined as oldest job not yet entirely flushed, + * and check its output buffer. + * @return : amount of data stored in oldest job and ready to be flushed immediately. + * if @return == 0, it means either : + * + there is no active job (could be checked with ZSTD_frameProgression()), or + * + oldest job is still actively compressing data, + * but everything it has produced has also been flushed so far, + * therefore flush speed is limited by production speed of oldest job + * irrespective of the speed of concurrent (and newer) jobs. + */ +ZSTDLIB_STATIC_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx); + + +/* ********************* BLOCK-LEVEL SEQUENCE PRODUCER API ********************* + * + * *** OVERVIEW *** + * The Block-Level Sequence Producer API allows users to provide their own custom + * sequence producer which libzstd invokes to process each block. The produced list + * of sequences (literals and matches) is then post-processed by libzstd to produce + * valid compressed blocks. + * + * This block-level offload API is a more granular complement of the existing + * frame-level offload API compressSequences() (introduced in v1.5.1). It offers + * an easier migration story for applications already integrated with libzstd: the + * user application continues to invoke the same compression functions + * ZSTD_compress2() or ZSTD_compressStream2() as usual, and transparently benefits + * from the specific advantages of the external sequence producer. For example, + * the sequence producer could be tuned to take advantage of known characteristics + * of the input, to offer better speed / ratio, or could leverage hardware + * acceleration not available within libzstd itself. + * + * See contrib/externalSequenceProducer for an example program employing the + * Block-Level Sequence Producer API. + * + * *** USAGE *** + * The user is responsible for implementing a function of type + * ZSTD_sequenceProducer_F. For each block, zstd will pass the following + * arguments to the user-provided function: + * + * - sequenceProducerState: a pointer to a user-managed state for the sequence + * producer. + * + * - outSeqs, outSeqsCapacity: an output buffer for the sequence producer. + * outSeqsCapacity is guaranteed >= ZSTD_sequenceBound(srcSize). The memory + * backing outSeqs is managed by the CCtx. + * + * - src, srcSize: an input buffer for the sequence producer to parse. + * srcSize is guaranteed to be <= ZSTD_BLOCKSIZE_MAX. + * + * - dict, dictSize: a history buffer, which may be empty, which the sequence + * producer may reference as it parses the src buffer. Currently, zstd will + * always pass dictSize == 0 into external sequence producers, but this will + * change in the future. + * + * - compressionLevel: a signed integer representing the zstd compression level + * set by the user for the current operation. The sequence producer may choose + * to use this information to change its compression strategy and speed/ratio + * tradeoff. Note: the compression level does not reflect zstd parameters set + * through the advanced API. + * + * - windowSize: a size_t representing the maximum allowed offset for external + * sequences. Note that sequence offsets are sometimes allowed to exceed the + * windowSize if a dictionary is present, see doc/zstd_compression_format.md + * for details. + * + * The user-provided function shall return a size_t representing the number of + * sequences written to outSeqs. This return value will be treated as an error + * code if it is greater than outSeqsCapacity. The return value must be non-zero + * if srcSize is non-zero. The ZSTD_SEQUENCE_PRODUCER_ERROR macro is provided + * for convenience, but any value greater than outSeqsCapacity will be treated as + * an error code. + * + * If the user-provided function does not return an error code, the sequences + * written to outSeqs must be a valid parse of the src buffer. Data corruption may + * occur if the parse is not valid. A parse is defined to be valid if the + * following conditions hold: + * - The sum of matchLengths and literalLengths must equal srcSize. + * - All sequences in the parse, except for the final sequence, must have + * matchLength >= ZSTD_MINMATCH_MIN. The final sequence must have + * matchLength >= ZSTD_MINMATCH_MIN or matchLength == 0. + * - All offsets must respect the windowSize parameter as specified in + * doc/zstd_compression_format.md. + * - If the final sequence has matchLength == 0, it must also have offset == 0. + * + * zstd will only validate these conditions (and fail compression if they do not + * hold) if the ZSTD_c_validateSequences cParam is enabled. Note that sequence + * validation has a performance cost. + * + * If the user-provided function returns an error, zstd will either fall back + * to an internal sequence producer or fail the compression operation. The user can + * choose between the two behaviors by setting the ZSTD_c_enableSeqProducerFallback + * cParam. Fallback compression will follow any other cParam settings, such as + * compression level, the same as in a normal compression operation. + * + * The user shall instruct zstd to use a particular ZSTD_sequenceProducer_F + * function by calling + * ZSTD_registerSequenceProducer(cctx, + * sequenceProducerState, + * sequenceProducer) + * This setting will persist until the next parameter reset of the CCtx. + * + * The sequenceProducerState must be initialized by the user before calling + * ZSTD_registerSequenceProducer(). The user is responsible for destroying the + * sequenceProducerState. + * + * *** LIMITATIONS *** + * This API is compatible with all zstd compression APIs which respect advanced parameters. + * However, there are three limitations: + * + * First, the ZSTD_c_enableLongDistanceMatching cParam is not currently supported. + * COMPRESSION WILL FAIL if it is enabled and the user tries to compress with a block-level + * external sequence producer. + * - Note that ZSTD_c_enableLongDistanceMatching is auto-enabled by default in some + * cases (see its documentation for details). Users must explicitly set + * ZSTD_c_enableLongDistanceMatching to ZSTD_ps_disable in such cases if an external + * sequence producer is registered. + * - As of this writing, ZSTD_c_enableLongDistanceMatching is disabled by default + * whenever ZSTD_c_windowLog < 128MB, but that's subject to change. Users should + * check the docs on ZSTD_c_enableLongDistanceMatching whenever the Block-Level Sequence + * Producer API is used in conjunction with advanced settings (like ZSTD_c_windowLog). + * + * Second, history buffers are not currently supported. Concretely, zstd will always pass + * dictSize == 0 to the external sequence producer (for now). This has two implications: + * - Dictionaries are not currently supported. Compression will *not* fail if the user + * references a dictionary, but the dictionary won't have any effect. + * - Stream history is not currently supported. All advanced compression APIs, including + * streaming APIs, work with external sequence producers, but each block is treated as + * an independent chunk without history from previous blocks. + * + * Third, multi-threading within a single compression is not currently supported. In other words, + * COMPRESSION WILL FAIL if ZSTD_c_nbWorkers > 0 and an external sequence producer is registered. + * Multi-threading across compressions is fine: simply create one CCtx per thread. + * + * Long-term, we plan to overcome all three limitations. There is no technical blocker to + * overcoming them. It is purely a question of engineering effort. + */ + +#define ZSTD_SEQUENCE_PRODUCER_ERROR ((size_t)(-1)) + +typedef size_t (*ZSTD_sequenceProducer_F) ( + void* sequenceProducerState, + ZSTD_Sequence* outSeqs, size_t outSeqsCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + int compressionLevel, + size_t windowSize +); + +/*! ZSTD_registerSequenceProducer() : + * Instruct zstd to use a block-level external sequence producer function. + * + * The sequenceProducerState must be initialized by the caller, and the caller is + * responsible for managing its lifetime. This parameter is sticky across + * compressions. It will remain set until the user explicitly resets compression + * parameters. + * + * Sequence producer registration is considered to be an "advanced parameter", + * part of the "advanced API". This means it will only have an effect on compression + * APIs which respect advanced parameters, such as compress2() and compressStream2(). + * Older compression APIs such as compressCCtx(), which predate the introduction of + * "advanced parameters", will ignore any external sequence producer setting. + * + * The sequence producer can be "cleared" by registering a NULL function pointer. This + * removes all limitations described above in the "LIMITATIONS" section of the API docs. + * + * The user is strongly encouraged to read the full API documentation (above) before + * calling this function. */ +ZSTDLIB_STATIC_API void +ZSTD_registerSequenceProducer( + ZSTD_CCtx* cctx, + void* sequenceProducerState, + ZSTD_sequenceProducer_F sequenceProducer +); + +/*! ZSTD_CCtxParams_registerSequenceProducer() : + * Same as ZSTD_registerSequenceProducer(), but operates on ZSTD_CCtx_params. + * This is used for accurate size estimation with ZSTD_estimateCCtxSize_usingCCtxParams(), + * which is needed when creating a ZSTD_CCtx with ZSTD_initStaticCCtx(). + * + * If you are using the external sequence producer API in a scenario where ZSTD_initStaticCCtx() + * is required, then this function is for you. Otherwise, you probably don't need it. + * + * See tests/zstreamtest.c for example usage. */ +ZSTDLIB_STATIC_API void +ZSTD_CCtxParams_registerSequenceProducer( + ZSTD_CCtx_params* params, + void* sequenceProducerState, + ZSTD_sequenceProducer_F sequenceProducer +); + + +/********************************************************************* +* Buffer-less and synchronous inner streaming functions (DEPRECATED) +* +* This API is deprecated, and will be removed in a future version. +* It allows streaming (de)compression with user allocated buffers. +* However, it is hard to use, and not as well tested as the rest of +* our API. +* +* Please use the normal streaming API instead: ZSTD_compressStream2, +* and ZSTD_decompressStream. +* If there is functionality that you need, but it doesn't provide, +* please open an issue on our GitHub. +********************************************************************* */ + +/** + Buffer-less streaming compression (synchronous mode) + + A ZSTD_CCtx object is required to track streaming operations. + Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource. + ZSTD_CCtx object can be reused multiple times within successive compression operations. + + Start by initializing a context. + Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression. + + Then, consume your input using ZSTD_compressContinue(). + There are some important considerations to keep in mind when using this advanced function : + - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffers only. + - Interface is synchronous : input is consumed entirely and produces 1+ compressed blocks. + - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario. + Worst case evaluation is provided by ZSTD_compressBound(). + ZSTD_compressContinue() doesn't guarantee recover after a failed compression. + - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog). + It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks) + - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps. + In which case, it will "discard" the relevant memory section from its history. + + Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum. + It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame. + Without last block mark, frames are considered unfinished (hence corrupted) by compliant decoders. + + `ZSTD_CCtx` object can be reused (ZSTD_compressBegin()) to compress again. +*/ + +/*===== Buffer-less streaming compression functions =====*/ +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */ + +ZSTD_DEPRECATED("This function will likely be removed in a future release. It is misleading and has very limited utility.") +ZSTDLIB_STATIC_API +size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */ + +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* The ZSTD_compressBegin_advanced() and ZSTD_compressBegin_usingCDict_advanced() are now DEPRECATED and will generate a compiler warning */ +ZSTD_DEPRECATED("use advanced API to access custom parameters") +ZSTDLIB_STATIC_API +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */ +ZSTD_DEPRECATED("use advanced API to access custom parameters") +ZSTDLIB_STATIC_API +size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */ +/** + Buffer-less streaming decompression (synchronous mode) + + A ZSTD_DCtx object is required to track streaming operations. + Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it. + A ZSTD_DCtx object can be reused multiple times. + + First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader(). + Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough. + Data fragment must be large enough to ensure successful decoding. + `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough. + result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled. + >0 : `srcSize` is too small, please provide at least result bytes on next attempt. + errorCode, which can be tested using ZSTD_isError(). + + It fills a ZSTD_FrameHeader structure with important information to correctly decode the frame, + such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`). + Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information. + As a consequence, check that values remain within valid application range. + For example, do not allocate memory blindly, check that `windowSize` is within expectation. + Each application can set its own limits, depending on local restrictions. + For extended interoperability, it is recommended to support `windowSize` of at least 8 MB. + + ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize` bytes. + ZSTD_decompressContinue() is very sensitive to contiguity, + if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place, + or that previous contiguous segment is large enough to properly handle maximum back-reference distance. + There are multiple ways to guarantee this condition. + + The most memory efficient way is to use a round buffer of sufficient size. + Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(), + which can return an error code if required value is too large for current system (in 32-bits mode). + In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one, + up to the moment there is not enough room left in the buffer to guarantee decoding another full block, + which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`. + At which point, decoding can resume from the beginning of the buffer. + Note that already decoded data stored in the buffer should be flushed before being overwritten. + + There are alternatives possible, for example using two or more buffers of size `windowSize` each, though they consume more memory. + + Finally, if you control the compression process, you can also ignore all buffer size rules, + as long as the encoder and decoder progress in "lock-step", + aka use exactly the same buffer sizes, break contiguity at the same place, etc. + + Once buffers are setup, start decompression, with ZSTD_decompressBegin(). + If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict(). + + Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively. + ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue(). + ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail. + + result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity). + It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item. + It can also be an error code, which can be tested with ZSTD_isError(). + + A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero. + Context can then be reset to start a new decompression. + + Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType(). + This information is not required to properly decode a frame. + + == Special case : skippable frames == + + Skippable frames allow integration of user-defined data into a flow of concatenated frames. + Skippable frames will be ignored (skipped) by decompressor. + The format of skippable frames is as follows : + a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F + b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits + c) Frame Content - any content (User Data) of length equal to Frame Size + For skippable frames ZSTD_getFrameHeader() returns zfhPtr->frameType==ZSTD_skippableFrame. + For skippable frames ZSTD_decompressContinue() always returns 0 : it only skips the content. +*/ + +/*===== Buffer-less streaming decompression functions =====*/ + +ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */ + +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx); +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); + +/* misc */ +ZSTD_DEPRECATED("This function will likely be removed in the next minor release. It is misleading and has very limited utility.") +ZSTDLIB_STATIC_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); +typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e; +ZSTDLIB_STATIC_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); + + + + +/* ========================================= */ +/** Block level API (DEPRECATED) */ +/* ========================================= */ + +/*! + + This API is deprecated in favor of the regular compression API. + You can get the frame header down to 2 bytes by setting: + - ZSTD_c_format = ZSTD_f_zstd1_magicless + - ZSTD_c_contentSizeFlag = 0 + - ZSTD_c_checksumFlag = 0 + - ZSTD_c_dictIDFlag = 0 + + This API is not as well tested as our normal API, so we recommend not using it. + We will be removing it in a future version. If the normal API doesn't provide + the functionality you need, please open a GitHub issue. + + Block functions produce and decode raw zstd blocks, without frame metadata. + Frame metadata cost is typically ~12 bytes, which can be non-negligible for very small blocks (< 100 bytes). + But users will have to take in charge needed metadata to regenerate data, such as compressed and content sizes. + + A few rules to respect : + - Compressing and decompressing require a context structure + + Use ZSTD_createCCtx() and ZSTD_createDCtx() + - It is necessary to init context before starting + + compression : any ZSTD_compressBegin*() variant, including with dictionary + + decompression : any ZSTD_decompressBegin*() variant, including with dictionary + - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB + + If input is larger than a block size, it's necessary to split input data into multiple blocks + + For inputs larger than a single block, consider using regular ZSTD_compress() instead. + Frame metadata is not that costly, and quickly becomes negligible as source size grows larger than a block. + - When a block is considered not compressible enough, ZSTD_compressBlock() result will be 0 (zero) ! + ===> In which case, nothing is produced into `dst` ! + + User __must__ test for such outcome and deal directly with uncompressed data + + A block cannot be declared incompressible if ZSTD_compressBlock() return value was != 0. + Doing so would mess up with statistics history, leading to potential data corruption. + + ZSTD_decompressBlock() _doesn't accept uncompressed data as input_ !! + + In case of multiple successive blocks, should some of them be uncompressed, + decoder must be informed of their existence in order to follow proper history. + Use ZSTD_insertBlock() for such a case. +*/ + +/*===== Raw zstd block functions =====*/ +ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx); +ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */ + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */ diff --git a/src/commonlib/bsd/zstd/zstd_errors.h b/src/commonlib/bsd/zstd/zstd_errors.h new file mode 100644 index 0000000000..658c9ef4bd --- /dev/null +++ b/src/commonlib/bsd/zstd/zstd_errors.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_ERRORS_H_398273423 +#define ZSTD_ERRORS_H_398273423 + +#if defined (__cplusplus) +extern "C" { +#endif + +/* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */ +#ifndef ZSTDERRORLIB_VISIBLE + /* Backwards compatibility with old macro name */ +# ifdef ZSTDERRORLIB_VISIBILITY +# define ZSTDERRORLIB_VISIBLE ZSTDERRORLIB_VISIBILITY +# elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZSTDERRORLIB_VISIBLE __attribute__ ((visibility ("default"))) +# else +# define ZSTDERRORLIB_VISIBLE +# endif +#endif + +#ifndef ZSTDERRORLIB_HIDDEN +# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZSTDERRORLIB_HIDDEN __attribute__ ((visibility ("hidden"))) +# else +# define ZSTDERRORLIB_HIDDEN +# endif +#endif + +#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBLE +#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBLE +#endif + +/*-********************************************* + * Error codes list + *-********************************************* + * Error codes _values_ are pinned down since v1.3.1 only. + * Therefore, don't rely on values if you may link to any version < v1.3.1. + * + * Only values < 100 are considered stable. + * + * note 1 : this API shall be used with static linking only. + * dynamic linking is not yet officially supported. + * note 2 : Prefer relying on the enum than on its value whenever possible + * This is the only supported way to use the error list < v1.3.1 + * note 3 : ZSTD_isError() is always correct, whatever the library version. + **********************************************/ +typedef enum { + ZSTD_error_no_error = 0, + ZSTD_error_GENERIC = 1, + ZSTD_error_prefix_unknown = 10, + ZSTD_error_version_unsupported = 12, + ZSTD_error_frameParameter_unsupported = 14, + ZSTD_error_frameParameter_windowTooLarge = 16, + ZSTD_error_corruption_detected = 20, + ZSTD_error_checksum_wrong = 22, + ZSTD_error_literals_headerWrong = 24, + ZSTD_error_dictionary_corrupted = 30, + ZSTD_error_dictionary_wrong = 32, + ZSTD_error_dictionaryCreation_failed = 34, + ZSTD_error_parameter_unsupported = 40, + ZSTD_error_parameter_combination_unsupported = 41, + ZSTD_error_parameter_outOfBound = 42, + ZSTD_error_tableLog_tooLarge = 44, + ZSTD_error_maxSymbolValue_tooLarge = 46, + ZSTD_error_maxSymbolValue_tooSmall = 48, + ZSTD_error_cannotProduce_uncompressedBlock = 49, + ZSTD_error_stabilityCondition_notRespected = 50, + ZSTD_error_stage_wrong = 60, + ZSTD_error_init_missing = 62, + ZSTD_error_memory_allocation = 64, + ZSTD_error_workSpace_tooSmall= 66, + ZSTD_error_dstSize_tooSmall = 70, + ZSTD_error_srcSize_wrong = 72, + ZSTD_error_dstBuffer_null = 74, + ZSTD_error_noForwardProgress_destFull = 80, + ZSTD_error_noForwardProgress_inputEmpty = 82, + /* following error codes are __NOT STABLE__, they can be removed or changed in future versions */ + ZSTD_error_frameIndex_tooLarge = 100, + ZSTD_error_seekableIO = 102, + ZSTD_error_dstBuffer_wrong = 104, + ZSTD_error_srcBuffer_wrong = 105, + ZSTD_error_sequenceProducer_failed = 106, + ZSTD_error_externalSequences_invalid = 107, + ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */ +} ZSTD_ErrorCode; + +ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); /**< Same as ZSTD_getErrorName, but using a `ZSTD_ErrorCode` enum argument */ + + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_ERRORS_H_398273423 */ diff --git a/util/cbfstool/Makefile.mk b/util/cbfstool/Makefile.mk index 8577874044..d3f07f9777 100644 --- a/util/cbfstool/Makefile.mk +++ b/util/cbfstool/Makefile.mk @@ -12,6 +12,34 @@ compressionobj += lzma.o compressionobj += LzFind.o compressionobj += LzmaDec.o compressionobj += LzmaEnc.o +# ZSTD +# common +compressionobj += debug.o +compressionobj += entropy_common.o +compressionobj += error_private.o +compressionobj += fse_decompress.o +compressionobj += zstd_common.o +# compress +compressionobj += fse_compress.o +compressionobj += hist.o +compressionobj += huf_compress.o +compressionobj += zstd_compress.o +compressionobj += zstd_compress_literals.o +compressionobj += zstd_compress_sequences.o +compressionobj += zstd_compress_superblock.o +compressionobj += zstd_double_fast.o +compressionobj += zstd_fast.o +compressionobj += zstd_lazy.o +compressionobj += zstd_ldm.o +compressionobj += zstd_preSplit.o +compressionobj += zstd_opt.o +# xxhash.o Already included for LZ4 +# decompress +compressionobj += huf_decompress.o +compressionobj += zstd_ddict.o +compressionobj += zstd_decompress_block.o +compressionobj += zstd_decompress.o +#compressionobj += huf_decomppress_amd64.o cbfsobj := cbfsobj += cbfstool.o @@ -132,6 +160,7 @@ TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/host/lib/include # have right now. TOOLCPPFLAGS += -I$(top)/src TOOLCPPFLAGS += -I$(top)/src/vendorcode/intel/edk2/uefi_2.4/MdePkg/Include +TOOLCPPFLAGS += -I$(top)/src/commonlib/bsd/zstd/ TOOLLDFLAGS ?= @@ -147,6 +176,7 @@ TOOLCFLAGS+=-std=c11 endif LZ4CFLAGS ?= -Wno-strict-prototypes +ZSTDCPPFLAGS ?= -DZSTD_DISABLE_ASM=1 VBOOT_HOSTLIB = $(VBOOT_HOST_BUILD)/libvboot_host.a @@ -189,6 +219,10 @@ $(objutil)/cbfstool/%.o: $(top)/src/commonlib/bsd/%.c printf " HOSTCC $(subst $(objutil)/,,$(@))\n" $(HOSTCC) $(TOOLCPPFLAGS) $(TOOLCFLAGS) $(HOSTCFLAGS) -c -o $@ $< +$(objutil)/cbfstool/%.o: $(top)/src/commonlib/bsd/zstd/*/%.c + printf " HOSTCC $(subst $(objutil)/,,$(@))\n" + $(HOSTCC) $(TOOLCPPFLAGS) $(TOOLCFLAGS) $(HOSTCFLAGS) $(ZSTDCPPFLAGS) -c -o $@ $< + $(objutil)/cbfstool/%.o: $(top)/util/cbfstool/lz4/lib/%.c printf " HOSTCC $(subst $(objutil)/,,$(@))\n" $(HOSTCC) $(TOOLCPPFLAGS) $(TOOLCFLAGS) $(HOSTCFLAGS) $(LZ4CFLAGS) -c -o $@ $< diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h index 3336e08930..cb903b1ba3 100644 --- a/util/cbfstool/cbfs.h +++ b/util/cbfstool/cbfs.h @@ -25,6 +25,7 @@ static const struct typedesc_t types_cbfs_compression[] = { {CBFS_COMPRESS_NONE, "none"}, {CBFS_COMPRESS_LZMA, "LZMA"}, {CBFS_COMPRESS_LZ4, "LZ4"}, + {CBFS_COMPRESS_ZSTD, "ZSTD"}, {0, NULL}, }; diff --git a/util/cbfstool/compress.c b/util/cbfstool/compress.c index 96df1a7499..d2cc5dd6b2 100644 --- a/util/cbfstool/compress.c +++ b/util/cbfstool/compress.c @@ -6,9 +6,11 @@ #include #include "common.h" #include "lz4/lib/lz4frame.h" +#include #include -static int lz4_compress(char *in, int in_len, char *out, int *out_len) +static int +lz4_compress(char *in, int in_len, char *out, int *out_len) { LZ4F_preferences_t prefs = { .compressionLevel = 20, @@ -53,6 +55,52 @@ static int lzma_decompress(char *in, int in_len, char *out, unused int out_len, { return do_lzma_uncompress(out, out_len, in, in_len, actual_size); } + +static int zstd_compress(char *in, int in_len, char *out, int *out_len) +{ + size_t worst_size = ZSTD_compressBound(in_len); + size_t ret; + + void *bounce = malloc(worst_size); + if (!bounce) + return -1; + ret = ZSTD_compress(bounce, worst_size, in, in_len, ZSTD_maxCLevel()); + if (ZSTD_isError(ret)) { + ERROR("ZSTD_compress (v%s) returned %zu (%s)\n", + ZSTD_versionString(), ret, ZSTD_getErrorName(ret)); + free(bounce); + return -2; + } + if (ret >= (size_t)in_len) { + free(bounce); + return -3; + } + *out_len = (int)ret; + + memcpy(out, bounce, *out_len); + free(bounce); + return 0; +} + +static int zstd_decompress(char *in, int in_len, char *out, int out_len, + size_t *actual_size) +{ + ZSTD_DCtx* dctx = ZSTD_createDCtx(); + size_t ret = ZSTD_decompressDCtx(dctx, out, out_len, in, in_len); + ZSTD_freeDCtx(dctx); + + if (ret == 0) + return -1; + if (ZSTD_isError(ret)) { + ERROR("ZSTD_decompress (v%s) returned %zu (%s)\n", + ZSTD_versionString(), ret, ZSTD_getErrorName(ret)); + return -2; + } + if (actual_size != NULL) + *actual_size = ret; + return 0; +} + static int none_compress(char *in, int in_len, char *out, int *out_len) { memcpy(out, in, in_len); @@ -82,6 +130,9 @@ comp_func_ptr compression_function(enum cbfs_compression algo) case CBFS_COMPRESS_LZ4: compress = lz4_compress; break; + case CBFS_COMPRESS_ZSTD: + compress = zstd_compress; + break; default: ERROR("Unknown compression algorithm %d!\n", algo); return NULL; @@ -102,6 +153,9 @@ decomp_func_ptr decompression_function(enum cbfs_compression algo) case CBFS_COMPRESS_LZ4: decompress = lz4_decompress; break; + case CBFS_COMPRESS_ZSTD: + decompress = zstd_decompress; + break; default: ERROR("Unknown compression algorithm %d!\n", algo); return NULL; From 4ca5e9c8c6406e4e175896cbf4947c3ea3d52811 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 22 Nov 2025 17:08:13 +0100 Subject: [PATCH 010/789] rules.h: Add ENV_RAMSTAGE_LOADER Define ENV_RAMSTAGE_LOADER in rules.h similar to ENV_PAYLOAD_LOADER to simplify the current code and avoid code duplication when adding zstd support. Change-Id: I8c049c640b11c6f0b51e37dd2c368bb786ca9b0f Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/90153 Reviewed-by: Matt DeVillier Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel --- src/include/rules.h | 8 ++++++++ src/lib/cbfs.c | 14 +++----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/include/rules.h b/src/include/rules.h index 673138bfe6..053cd6bc09 100644 --- a/src/include/rules.h +++ b/src/include/rules.h @@ -267,6 +267,14 @@ #define ENV_PAYLOAD_LOADER ENV_RAMSTAGE #endif +#if CONFIG(POSTCAR_STAGE) +#define ENV_RAMSTAGE_LOADER ENV_POSTCAR +#elif CONFIG(SEPARATE_ROMSTAGE) +#define ENV_RAMSTAGE_LOADER ENV_SEPARATE_ROMSTAGE +#else +#define ENV_RAMSTAGE_LOADER ENV_BOOTBLOCK +#endif + #define ENV_ROMSTAGE_OR_BEFORE \ (ENV_DECOMPRESSOR || ENV_BOOTBLOCK || ENV_SEPARATE_ROMSTAGE || \ (ENV_SEPARATE_VERSTAGE && !CONFIG(VBOOT_STARTS_IN_ROMSTAGE))) diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 0c47359260..4ec65a864c 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -150,17 +150,9 @@ static inline bool cbfs_lzma_enabled(void) /* Payload loader (ramstage) always needs LZMA. */ if (ENV_PAYLOAD_LOADER) return true; - /* Only other use of LZMA is ramstage compression. */ - if (!CONFIG(COMPRESS_RAMSTAGE_LZMA)) - return false; - /* If there is a postcar, it loads the ramstage. */ - if (CONFIG(POSTCAR_STAGE)) - return ENV_POSTCAR; - /* If there is no postcar but a separate romstage, it loads the ramstage. */ - if (CONFIG(SEPARATE_ROMSTAGE)) - return ENV_SEPARATE_ROMSTAGE; - /* Otherwise, the combined bootblock+romstage loads the ramstage. */ - return ENV_BOOTBLOCK; + if (ENV_RAMSTAGE_LOADER && CONFIG(COMPRESS_RAMSTAGE_LZMA)) + return true; + return false; } static bool cbfs_file_hash_mismatch(const void *buffer, size_t size, From 2d99da12a9c1189d78517b5d700ba92276bf1640 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 22 Nov 2022 16:33:29 +0100 Subject: [PATCH 011/789] commonlib/bsd: Add zstd support This adds the option to compress ramstage and payloads with zstd. zstd compressed ramstages are typically +5% bigger than lzma compressed ramstages. The decompressor .text section grows by 20KiB and the decompressor needs 16KiB more heap than the lzma decompressor. To use less heap inside the zstd decompressor the build time define ZSTD_DECODER_INTERNAL_BUFFER is used. Quote: The build macro `ZSTD_DECODER_INTERNAL_BUFFER` can be set to control the amount of extra memory used during decompression to store literals. This defaults to 64kB. Reducing this value reduces the memory footprint of `ZSTD_DCtx` decompression contexts, but might also result in a small decompression speed cost TEST=Booted on Lenovo X220 with zstd ramstage showed no disadvantage over a bigger internal buffer used. TEST=Booted on Lenovo X220. The zstd decompressor is twice as fast as the lzma decompressor. cbmem -t shows: - finished ZSTD decompress (ignore for x86) 79,444 (24,494) - finished LZMA decompress (ignore for x86) 94,971 (45,545) TEST=Booted on QEMU Q35, QEMU aarch64 virt, QEMU riscv RV64 with zstd compressed ramstage. Change-Id: Ic1b1f53327c598d07bd83d4391e8012d41696a16 Signed-off-by: Arthur Heymans Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/69893 Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) --- Makefile.mk | 7 ++- payloads/Kconfig | 6 +++ src/Kconfig | 13 ++++++ src/commonlib/Makefile.mk | 2 + .../bsd/include/commonlib/bsd/compression.h | 2 +- src/commonlib/bsd/zstd/Makefile.mk | 43 +++++++++++++++++++ .../bsd/zstd/decompress/zstd_decompress.c | 2 +- src/commonlib/bsd/zstd_wrapper.c | 18 ++++++++ .../include/commonlib/timestamp_serialized.h | 4 ++ src/lib/cbfs.c | 27 ++++++++++++ src/lib/selfboot.c | 13 ++++++ tests/lib/cbfs-lookup-test.c | 8 ++++ tests/lib/cbfs-verification-test.c | 6 +++ 13 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 src/commonlib/bsd/zstd/Makefile.mk create mode 100644 src/commonlib/bsd/zstd_wrapper.c diff --git a/Makefile.mk b/Makefile.mk index 75787b32d4..cab60b33a4 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -455,6 +455,8 @@ cbfs-files-handler= \ CBFS_COMPRESS_FLAG:=none ifeq ($(CONFIG_COMPRESS_RAMSTAGE_LZMA),y) CBFS_COMPRESS_FLAG:=LZMA +else ifeq ($(CONFIG_COMPRESS_RAMSTAGE_ZSTD),y) +CBFS_COMPRESS_FLAG:=ZSTD endif ifeq ($(CONFIG_COMPRESS_RAMSTAGE_LZ4),y) CBFS_COMPRESS_FLAG:=LZ4 @@ -463,9 +465,10 @@ endif CBFS_PAYLOAD_COMPRESS_FLAG:=none ifeq ($(CONFIG_COMPRESSED_PAYLOAD_LZMA),y) CBFS_PAYLOAD_COMPRESS_FLAG:=LZMA -endif -ifeq ($(CONFIG_COMPRESSED_PAYLOAD_LZ4),y) +else ifeq ($(CONFIG_COMPRESSED_PAYLOAD_LZ4),y) CBFS_PAYLOAD_COMPRESS_FLAG:=LZ4 +else ifeq ($(CONFIG_COMPRESSED_PAYLOAD_ZSTD),y) +CBFS_PAYLOAD_COMPRESS_FLAG:=ZSTD endif CBFS_SECONDARY_PAYLOAD_COMPRESS_FLAG:=none diff --git a/payloads/Kconfig b/payloads/Kconfig index be902a1b4b..e30b1ec76c 100644 --- a/payloads/Kconfig +++ b/payloads/Kconfig @@ -86,6 +86,12 @@ config COMPRESSED_PAYLOAD_LZMA In order to reduce the size payloads take up in the ROM chip coreboot can compress them using the LZMA algorithm. +config COMPRESSED_PAYLOAD_ZSTD + bool "Use ZSTD compression for payloads" + help + In order to reduce the size payloads take up in the ROM chip + coreboot can compress them using the ZSTD algorithm. + config COMPRESSED_PAYLOAD_LZ4 bool "Use LZ4 compression for payloads" help diff --git a/src/Kconfig b/src/Kconfig index a7a34b26a5..2b5a2241cc 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -202,10 +202,16 @@ config MB_COMPRESS_RAMSTAGE_LZ4 help Select this in a mainboard to use LZ4 compression by default +config MB_COMPRESS_RAMSTAGE_ZSTD + bool + help + Select this in a mainboard to use ZSTD compression by default + choice prompt "Ramstage compression" depends on HAVE_RAMSTAGE && !UNCOMPRESSED_RAMSTAGE default COMPRESS_RAMSTAGE_LZ4 if MB_COMPRESS_RAMSTAGE_LZ4 + default COMPRESS_RAMSTAGE_ZSTD if MB_COMPRESS_RAMSTAGE_ZSTD default COMPRESS_RAMSTAGE_LZMA config COMPRESS_RAMSTAGE_LZMA @@ -226,6 +232,13 @@ config COMPRESS_RAMSTAGE_LZ4 If you're not sure, stick with LZMA. +config COMPRESS_RAMSTAGE_ZSTD + bool "Compress ramstage with ZSTD" + help + Compress ramstage with ZSTD. + This is faster than LZMA but uses more BSS. + However it decompresses faster on slower CPUs and is suited for + platforms with high speed SPI interfaces, but limited computing power. endchoice config COMPRESS_PRERAM_STAGES diff --git a/src/commonlib/Makefile.mk b/src/commonlib/Makefile.mk index 44f63e1ea6..b4bc1b8fae 100644 --- a/src/commonlib/Makefile.mk +++ b/src/commonlib/Makefile.mk @@ -1,6 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only subdirs-y += storage +subdirs-y += bsd/zstd bootblock-y += mem_pool.c verstage-y += mem_pool.c @@ -58,6 +59,7 @@ ramstage-y += bsd/lz4_wrapper.c postcar-y += bsd/lz4_wrapper.c all-y += list.c +all-y += bsd/zstd_wrapper.c ramstage-y += sort.c diff --git a/src/commonlib/bsd/include/commonlib/bsd/compression.h b/src/commonlib/bsd/include/commonlib/bsd/compression.h index 1f70fa4c60..b13bc4c8b6 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/compression.h +++ b/src/commonlib/bsd/include/commonlib/bsd/compression.h @@ -19,6 +19,6 @@ size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn); size_t ulz4f(const void *src, void *dst); /* Decompresses ZSTD image */ -size_t uzstdfn(const void *src, size_t srcn, void *dst, size_t dstn); +size_t uzstdn(const void *src, size_t srcn, void *dst, size_t dstn); #endif /* _COMMONLIB_COMPRESSION_H_ */ diff --git a/src/commonlib/bsd/zstd/Makefile.mk b/src/commonlib/bsd/zstd/Makefile.mk new file mode 100644 index 0000000000..d04ad31e98 --- /dev/null +++ b/src/commonlib/bsd/zstd/Makefile.mk @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +zstd_support=n +ifeq ($(CONFIG_COMPRESS_RAMSTAGE_ZSTD),y) +zstd_support=y +endif +ifeq ($(CONFIG_COMPRESSED_PAYLOAD_ZSTD),y) +zstd_support=y +endif + +ifeq ($(zstd_support),y) +all-y += decompress/huf_decompress.c +all-y += decompress/zstd_ddict.c +all-y += decompress/zstd_decompress_block.c +all-y += decompress/zstd_decompress.c + +all-y += common/entropy_common.c +all-y += common/fse_decompress.c + +CPPFLAGS_common += -DZSTD_DISABLE_ASM=1 +# Measured on Intel Sandy Bridge i5-2540M at 800Mhz: +# Setting code size reduction time loss +# -DHUF_FORCE_DECOMPRESS_X1=1 6.4 KiB 6% +# -DHUF_FORCE_DECOMPRESS_X2=1 5.4 KiB 7% +# -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT=1 8.1 KiB 19% +# -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG=1 7.8 KiB 15% + +CPPFLAGS_common += -DHUF_FORCE_DECOMPRESS_X1=1 +CPPFLAGS_common += -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT=1 +CPPFLAGS_common += -DZSTD_STRIP_ERROR_STRINGS=1 + +# Huffman fast decode needs 64bit and LE +CPPFLAGS_x86_32 += -DHUF_DISABLE_FAST_DECODE=1 +# Measured on Intel Sandy Bridge i5-2540M at 800Mhz (x86_64 only): +# Setting code size reduction time loss +# -DHUF_DISABLE_FAST_DECODE=1 2.3 KiB 5% + +CPPFLAGS_common += -DDYNAMIC_BMI2=0 -DSTATIC_BMI2=0 -DZSTD_DECODER_INTERNAL_BUFFER=2048 +endif + +CPPFLAGS_common += -I$(src)/commonlib/bsd/zstd +CPPFLAGS_common += -I$(src)/commonlib/bsd/zstd/common +CPPFLAGS_common += -I$(src)/commonlib/bsd/zstd/decompress diff --git a/src/commonlib/bsd/zstd/decompress/zstd_decompress.c b/src/commonlib/bsd/zstd/decompress/zstd_decompress.c index e24795d15e..e87776a68c 100644 --- a/src/commonlib/bsd/zstd/decompress/zstd_decompress.c +++ b/src/commonlib/bsd/zstd/decompress/zstd_decompress.c @@ -667,7 +667,7 @@ size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity, &src, &srcSize); RETURN_ERROR_IF( - (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown) + (ERR_getErrorCode(res) == ZSTD_error_prefix_unknown) && (moreThan1Frame==1), srcSize_wrong, "At least one frame successfully completed, " diff --git a/src/commonlib/bsd/zstd_wrapper.c b/src/commonlib/bsd/zstd_wrapper.c new file mode 100644 index 0000000000..8905120635 --- /dev/null +++ b/src/commonlib/bsd/zstd_wrapper.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#include +#include +#include +#include +#define ZSTD_STATIC_LINKING_ONLY 1 +#include +#undef ZSTD_STATIC_LINKING_ONLY +#include + +size_t uzstdn(const void *src, size_t srcn, void *dst, size_t dstn) +{ + static ZSTD_DCtx dctx __aligned(8); + if (!ZSTD_initStaticDCtx(&dctx, sizeof(dctx))) + return 0; + return ZSTD_decompressDCtx(&dctx, dst, dstn, src, srcn); +} diff --git a/src/commonlib/include/commonlib/timestamp_serialized.h b/src/commonlib/include/commonlib/timestamp_serialized.h index 2a159f64b8..3999b35069 100644 --- a/src/commonlib/include/commonlib/timestamp_serialized.h +++ b/src/commonlib/include/commonlib/timestamp_serialized.h @@ -37,6 +37,8 @@ enum timestamp_id { TS_ULZMA_END = 16, TS_ULZ4F_START = 17, TS_ULZ4F_END = 18, + TS_UZSTDF_START = 19, + TS_UZSTDF_END = 20, TS_DEVICE_INIT_CHIPS = 30, TS_DEVICE_ENUMERATE = 31, TS_DEVICE_CONFIGURE = 40, @@ -236,6 +238,8 @@ static const struct timestamp_id_to_name { TS_NAME_DEF(TS_ULZMA_END, 0, "finished LZMA decompress (ignore for x86)"), TS_NAME_DEF(TS_ULZ4F_START, TS_ULZ4F_END, "starting LZ4 decompress (ignore for x86)"), TS_NAME_DEF(TS_ULZ4F_END, 0, "finished LZ4 decompress (ignore for x86)"), + TS_NAME_DEF(TS_UZSTDF_START, TS_UZSTDF_END, "starting ZSTD decompress (ignore for x86)"), + TS_NAME_DEF(TS_UZSTDF_END, 0, "finished ZSTD decompress (ignore for x86)"), TS_NAME_DEF(TS_DEVICE_INIT_CHIPS, TS_DEVICE_ENUMERATE, "early chipset initialization"), TS_NAME_DEF(TS_DEVICE_ENUMERATE, TS_DEVICE_CONFIGURE, "device enumeration"), TS_NAME_DEF(TS_DEVICE_CONFIGURE, TS_DEVICE_ENABLE, "device configuration"), diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 4ec65a864c..1dd9288bff 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -155,6 +155,15 @@ static inline bool cbfs_lzma_enabled(void) return false; } +static inline bool cbfs_zstd_enabled(void) +{ + if (ENV_PAYLOAD_LOADER && CONFIG(COMPRESSED_PAYLOAD_ZSTD)) + return true; + if (ENV_RAMSTAGE_LOADER && CONFIG(COMPRESS_RAMSTAGE_ZSTD)) + return true; + return false; +} + static bool cbfs_file_hash_mismatch(const void *buffer, size_t size, const union cbfs_mdata *mdata, bool skip_verification) { @@ -267,6 +276,24 @@ static size_t cbfs_load_and_decompress(const struct region_device *rdev, void *b rdev_munmap(rdev, map); + return out_size; + case CBFS_COMPRESS_ZSTD: + if (!cbfs_zstd_enabled()) + return 0; + + map = rdev_mmap_full(rdev); + if (map == NULL) + return 0; + + if (!cbfs_file_hash_mismatch(map, in_size, mdata, skip_verification)) { + /* Note: timestamp not useful for memory-mapped media (x86) */ + timestamp_add_now(TS_UZSTDF_START); + out_size = uzstdn(map, in_size, buffer, buffer_size); + timestamp_add_now(TS_UZSTDF_END); + } + + rdev_munmap(rdev, map); + return out_size; default: diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index e21c493701..5a2321815e 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -87,6 +87,19 @@ static int load_one_segment(uint8_t *dest, return 0; break; } + case CBFS_COMPRESS_ZSTD: { + if (!CONFIG(COMPRESSED_PAYLOAD_ZSTD)) + return 0; + + printk(BIOS_DEBUG, "using ZSTD\n"); + timestamp_add_now(TS_UZSTDF_START); + len = uzstdn(src, len, dest, memsz); + timestamp_add_now(TS_UZSTDF_END); + if (!len) /* Decompression Error. */ + return 0; + break; + } + case CBFS_COMPRESS_NONE: { printk(BIOS_DEBUG, "it's not compressed!\n"); memcpy(dest, src, len); diff --git a/tests/lib/cbfs-lookup-test.c b/tests/lib/cbfs-lookup-test.c index 75628683b6..d6cc5d95a2 100644 --- a/tests/lib/cbfs-lookup-test.c +++ b/tests/lib/cbfs-lookup-test.c @@ -62,6 +62,14 @@ size_t ulzman(const void *src, size_t srcn, void *dst, size_t dstn) return dstn; } +size_t uzstdn(const void *src, size_t srcn, void *dst, size_t dstn) +{ + check_expected(srcn); + check_expected(dstn); + memcpy(dst, src, dstn); + return dstn; +} + size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn) { check_expected(srcn); diff --git a/tests/lib/cbfs-verification-test.c b/tests/lib/cbfs-verification-test.c index b1a39bcaac..8abc36c053 100644 --- a/tests/lib/cbfs-verification-test.c +++ b/tests/lib/cbfs-verification-test.c @@ -52,6 +52,12 @@ size_t ulzman(const void *src, size_t srcn, void *dst, size_t dstn) return 0; } +size_t uzstdn(const void *src, size_t srcn, void *dst, size_t dstn) +{ + fail_msg("Unexpected call to %s", __func__); + return 0; +} + size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn) { fail_msg("Unexpected call to %s", __func__); From 35be1ab679a4a9579749f311cce242f3255c98cd Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 20 Sep 2025 10:33:15 +0200 Subject: [PATCH 012/789] configs: Build test ramstage zstd compressed Build test the zstd code on qemu x86 and qemu aarch64. Change-Id: Ib1f10b983492e01f74c7218e03e04615a41e7312 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/89277 Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- configs/config.emulation_qemu_aarch64_zstd | 3 +++ configs/config.emulation_qemu_zstd | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 configs/config.emulation_qemu_aarch64_zstd create mode 100644 configs/config.emulation_qemu_zstd diff --git a/configs/config.emulation_qemu_aarch64_zstd b/configs/config.emulation_qemu_aarch64_zstd new file mode 100644 index 0000000000..c1cf7c02c5 --- /dev/null +++ b/configs/config.emulation_qemu_aarch64_zstd @@ -0,0 +1,3 @@ +CONFIG_VENDOR_EMULATION=y +CONFIG_BOARD_EMULATION_QEMU_AARCH64=y +CONFIG_COMPRESS_RAMSTAGE_ZSTD=y diff --git a/configs/config.emulation_qemu_zstd b/configs/config.emulation_qemu_zstd new file mode 100644 index 0000000000..4b0a6feea9 --- /dev/null +++ b/configs/config.emulation_qemu_zstd @@ -0,0 +1,3 @@ +CONFIG_VENDOR_EMULATION=y +CONFIG_BOARD_EMULATION_QEMU_X86_Q35=y +CONFIG_COMPRESS_RAMSTAGE_ZSTD=y From 7c4d9e0862ee8078c83adaf625fe09dc3d8f2da1 Mon Sep 17 00:00:00 2001 From: Alicja Michalska Date: Thu, 18 Dec 2025 20:52:51 +0100 Subject: [PATCH 013/789] mb/google/*: Update Kconfig names with all known board names In addition to adding all currently-known names for the boards, add SoC names to baseboards to make finding boards based on SoC family easier. Change-Id: I389f68f09409ce3eb51422dbcfe7e80d463a1594 Signed-off-by: Alicja Michalska Reviewed-on: https://review.coreboot.org/c/coreboot/+/90555 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/google/asurada/Kconfig.name | 4 +- src/mainboard/google/auron/Kconfig.name | 2 +- src/mainboard/google/beltino/Kconfig.name | 2 +- src/mainboard/google/bluey/Kconfig.name | 2 +- src/mainboard/google/brox/Kconfig.name | 2 +- src/mainboard/google/brya/Kconfig.name | 4 +- src/mainboard/google/butterfly/Kconfig.name | 2 +- src/mainboard/google/cherry/Kconfig.name | 6 +-- src/mainboard/google/corsola/Kconfig.name | 31 +++++++++----- src/mainboard/google/cyan/Kconfig.name | 2 +- src/mainboard/google/daisy/Kconfig.name | 2 +- src/mainboard/google/dedede/Kconfig.name | 40 ++++++++++++++++--- src/mainboard/google/drallion/Kconfig.name | 4 +- src/mainboard/google/eve/Kconfig.name | 2 +- src/mainboard/google/fatcat/Kconfig.name | 32 +++++++-------- src/mainboard/google/fizz/Kconfig.name | 2 +- src/mainboard/google/foster/Kconfig.name | 2 +- src/mainboard/google/gale/Kconfig.name | 2 +- src/mainboard/google/geralt/Kconfig.name | 4 +- src/mainboard/google/glados/Kconfig.name | 2 +- src/mainboard/google/gru/Kconfig.name | 2 +- src/mainboard/google/guybrush/Kconfig.name | 2 +- src/mainboard/google/hatch/Kconfig.name | 2 +- src/mainboard/google/herobrine/Kconfig.name | 10 ++--- src/mainboard/google/jecht/Kconfig.name | 2 +- src/mainboard/google/kahlee/Kconfig.name | 2 +- src/mainboard/google/kukui/Kconfig.name | 16 ++++---- src/mainboard/google/link/Kconfig.name | 2 +- src/mainboard/google/mistral/Kconfig.name | 2 +- src/mainboard/google/myst/Kconfig.name | 2 +- src/mainboard/google/nyan/Kconfig.name | 2 +- src/mainboard/google/nyan_big/Kconfig.name | 2 +- src/mainboard/google/nyan_blaze/Kconfig.name | 2 +- src/mainboard/google/oak/Kconfig.name | 2 +- src/mainboard/google/ocelot/Kconfig.name | 22 +++++----- src/mainboard/google/octopus/Kconfig.name | 2 +- src/mainboard/google/parrot/Kconfig.name | 2 +- src/mainboard/google/peach_pit/Kconfig.name | 2 +- src/mainboard/google/poppy/Kconfig.name | 2 +- src/mainboard/google/puff/Kconfig.name | 2 +- src/mainboard/google/rambi/Kconfig.name | 2 +- src/mainboard/google/rauru/Kconfig.name | 6 +-- src/mainboard/google/reef/Kconfig.name | 2 +- src/mainboard/google/rex/Kconfig.name | 20 +++++----- src/mainboard/google/sarien/Kconfig.name | 2 +- src/mainboard/google/skyrim/Kconfig.name | 2 +- src/mainboard/google/skywalker/Kconfig.name | 6 +-- src/mainboard/google/slippy/Kconfig.name | 2 +- src/mainboard/google/smaug/Kconfig.name | 2 +- src/mainboard/google/storm/Kconfig.name | 2 +- src/mainboard/google/stout/Kconfig.name | 2 +- src/mainboard/google/trogdor/Kconfig.name | 16 +++++--- src/mainboard/google/veyron/Kconfig.name | 2 +- .../google/veyron_mickey/Kconfig.name | 2 +- .../google/veyron_rialto/Kconfig.name | 2 +- src/mainboard/google/volteer/Kconfig.name | 2 +- src/mainboard/google/zork/Kconfig.name | 2 +- 57 files changed, 176 insertions(+), 129 deletions(-) diff --git a/src/mainboard/google/asurada/Kconfig.name b/src/mainboard/google/asurada/Kconfig.name index 278655180e..159b11e380 100644 --- a/src/mainboard/google/asurada/Kconfig.name +++ b/src/mainboard/google/asurada/Kconfig.name @@ -1,12 +1,12 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Asurada" +comment "Asurada (MediaTek Kompanio 820 (MT8192))" config BOARD_GOOGLE_ASURADA bool "-> Asurada" config BOARD_GOOGLE_HAYATO - bool "-> Hayato" + bool "-> Hayato (ASUS Chromebook Flip CM3 (CM3200))" config BOARD_GOOGLE_SPHERION bool "-> Spherion (Acer Chromebook 514 (CB514-2H, CB514-2HT))" diff --git a/src/mainboard/google/auron/Kconfig.name b/src/mainboard/google/auron/Kconfig.name index 1db2149b4c..953228e73c 100644 --- a/src/mainboard/google/auron/Kconfig.name +++ b/src/mainboard/google/auron/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Auron" +comment "Auron (Intel Broadwell (5th Gen))" config BOARD_GOOGLE_AURON_PAINE bool "-> Auron_Paine (Acer C740 Chromebook)" diff --git a/src/mainboard/google/beltino/Kconfig.name b/src/mainboard/google/beltino/Kconfig.name index a794330c63..fe9dc27814 100644 --- a/src/mainboard/google/beltino/Kconfig.name +++ b/src/mainboard/google/beltino/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Beltino" +comment "Beltino (Intel Haswell (4th Gen))" config BOARD_GOOGLE_MCCLOUD bool "-> Mccloud (Acer Chromebox CXI)" diff --git a/src/mainboard/google/bluey/Kconfig.name b/src/mainboard/google/bluey/Kconfig.name index 3925717a65..274c1e5042 100644 --- a/src/mainboard/google/bluey/Kconfig.name +++ b/src/mainboard/google/bluey/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Bluey" +comment "Bluey (Qualcomm Snapdragon X Plus (X1P-42-100))" config BOARD_GOOGLE_BLUEY bool "-> Bluey" diff --git a/src/mainboard/google/brox/Kconfig.name b/src/mainboard/google/brox/Kconfig.name index ca231025fc..4c73eebcf3 100644 --- a/src/mainboard/google/brox/Kconfig.name +++ b/src/mainboard/google/brox/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Brox" +comment "Brox (Intel RaptorLake (13th Gen))" config BOARD_GOOGLE_BROX bool "-> Brox" diff --git a/src/mainboard/google/brya/Kconfig.name b/src/mainboard/google/brya/Kconfig.name index 2565a426ef..c4a5c06dc7 100644 --- a/src/mainboard/google/brya/Kconfig.name +++ b/src/mainboard/google/brya/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Brya" +comment "Brya (Intel AlderLake/RaptorLake/TwinLake (12 - 13th Gen))" config BOARD_GOOGLE_AGAH bool "-> Agah" @@ -189,7 +189,7 @@ config BOARD_GOOGLE_TEREID bool "-> Tereid" config BOARD_GOOGLE_TIVVIKS - bool "-> Tivviks" + bool "-> Tivviks" config BOARD_GOOGLE_TRULO bool "-> Trulo" diff --git a/src/mainboard/google/butterfly/Kconfig.name b/src/mainboard/google/butterfly/Kconfig.name index fdde138279..e02eeb9609 100644 --- a/src/mainboard/google/butterfly/Kconfig.name +++ b/src/mainboard/google/butterfly/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Butterfly" +comment "Butterfly (Intel SandyBridge (2nd Gen))" config BOARD_GOOGLE_BUTTERFLY bool "-> Butterfly (HP Pavilion Chromebook 14)" diff --git a/src/mainboard/google/cherry/Kconfig.name b/src/mainboard/google/cherry/Kconfig.name index 666bce4bf0..bef53bab40 100644 --- a/src/mainboard/google/cherry/Kconfig.name +++ b/src/mainboard/google/cherry/Kconfig.name @@ -1,12 +1,12 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Cherry" +comment "Cherry (MediaTek Kompanio 1200 (MT8195))" config BOARD_GOOGLE_CHERRY bool "-> Cherry" config BOARD_GOOGLE_DOJO - bool "-> Dojo" + bool "-> Dojo (HP Chromebook x360 (13b-ca0002sa))" config BOARD_GOOGLE_TOMATO - bool "-> Tomato" + bool "-> Tomato (Acer Chromebook Spin 513 (CP513-2H))" diff --git a/src/mainboard/google/corsola/Kconfig.name b/src/mainboard/google/corsola/Kconfig.name index 5de50c3533..774f07649e 100644 --- a/src/mainboard/google/corsola/Kconfig.name +++ b/src/mainboard/google/corsola/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Kingler" +comment "Kingler (MediaTek Kompanio 520 (MT8186))" config BOARD_GOOGLE_KINGLER bool "-> Kingler" @@ -12,18 +12,27 @@ config BOARD_GOOGLE_PONYTA bool "-> Ponyta" config BOARD_GOOGLE_SQUIRTLE - bool "-> Squirtle" + bool "-> Squirtle (Acer Chromebook Spin 311 (R724T))" config BOARD_GOOGLE_STEELIX - bool "-> Steelix" + bool "-> Steelix/Magneton (see help text for details)" + help + The "Steelix" board supports the following devices: + - Lenovo 300e Yoga Chromebook Gen 4 (Steelix, convertible) + - Lenovo IdeaPad Slim 3 Chromebook (14M868) (Magneton, clamshell) config BOARD_GOOGLE_VOLTORB - bool "-> Voltorb" + bool "-> Voltorb (Acer Chromebook 311 (C723/C732T))" -comment "Krabby" +comment "Krabby (MediaTek Kompanio 520 (MT8186))" config BOARD_GOOGLE_CHINCHOU - bool "-> Chinchou" + bool "-> Chinchou/Chinochou360 (see help text for details)" + help + The "Chinochou" board supports the following devices: + - Asus Chromebook CZ1104CM2A/CZ1204CM2A + - Asus Chromebook CZ1104FM2A/CZ1204FM2A/CZ1104CM2A/CZ1204CM2A + - Asus Chromebook CZ1104FM2A/CZ1204FM2A Flip config BOARD_GOOGLE_KRABBY bool "-> Krabby" @@ -35,15 +44,19 @@ config BOARD_GOOGLE_SKITTY bool "-> Skitty" config BOARD_GOOGLE_TENTACRUEL - bool "-> Tentacruel" + bool "-> Tentacruel/Tentacool (see help text for details)" + help + The "Tentacruel" board supports the following devices: + - ASUS Chromebook CM14 Flip (CM1402F) (Tentacruel, convertible) + - ASUS Chromebook CM14 (CM1402C) (Tentacool, clamshell) config BOARD_GOOGLE_VELUZA bool "-> Veluza" -comment "Staryu" +comment "Staryu (MediaTek Kompanio 528 (MT8186T))" config BOARD_GOOGLE_STARMIE - bool "-> Starmie" + bool "-> Starmie (ASUS Chromebook Enterprise CM30 (CM3001))" config BOARD_GOOGLE_WUGTRIO bool "-> Wugtrio" diff --git a/src/mainboard/google/cyan/Kconfig.name b/src/mainboard/google/cyan/Kconfig.name index 6edc464919..7400aee7d6 100644 --- a/src/mainboard/google/cyan/Kconfig.name +++ b/src/mainboard/google/cyan/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Cyan" +comment "Cyan (Intel Braswell)" config BOARD_GOOGLE_BANON bool "-> Banon (Acer Chromebook 15 (CB3-532))" diff --git a/src/mainboard/google/daisy/Kconfig.name b/src/mainboard/google/daisy/Kconfig.name index f5152a1ec1..cb16bceac0 100644 --- a/src/mainboard/google/daisy/Kconfig.name +++ b/src/mainboard/google/daisy/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Daisy" +comment "Daisy (Samsung Exynos 5250)" config BOARD_GOOGLE_DAISY bool "-> Daisy (Samsung Chromebook (2012))" diff --git a/src/mainboard/google/dedede/Kconfig.name b/src/mainboard/google/dedede/Kconfig.name index fd130ecb8d..1b1c467950 100644 --- a/src/mainboard/google/dedede/Kconfig.name +++ b/src/mainboard/google/dedede/Kconfig.name @@ -1,9 +1,16 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Dedede" +comment "Dedede (Intel JasperLake)" config BOARD_GOOGLE_BEADRIX - bool "-> Beadrix" + bool "-> Beadrix (Multiple devices - See help text)" + help + The "Beadrix" board supports the following devces: + - DINATECH Gen1 Chromebook SG20JL1C + - Multilaser Chromebook M11C-PC919 + - Evolve III Chromebook 11 E1 + - Positivo Chromebook N2320 + - Allied Chromebook 11 N5100E config BOARD_GOOGLE_BLIPPER bool "-> Blipper (Lenovo 3i-15 Chromebook)" @@ -57,10 +64,26 @@ config BOARD_GOOGLE_GOOEY bool "-> Gooey" config BOARD_GOOGLE_HABOKI - bool "-> HABOKI" + bool "-> Haboki" config BOARD_GOOGLE_KRACKO - bool "-> Kracko" + bool "-> Kracko/Kracko360 (Multiple devices - See help text)" + help + The "Kracko" board is for "clamshell" form factor. + The "Kracko360" board is for "convertible" form factor. + They support the following devices: + - ADVAN Chromebook 116J + - Centerm Chromebook M610 + - CTL Chromebook NL72 + - CTL Chromebook NL72T + - Edxis Chromebook 11 + - LG Chromebook 11TC50Q/11TQ50Q + - Poin2 Chromebook 11B + - Poin2 Chromebook 11E + - Zyrex Chromebook M432-64 + - Multilaser Chromebook M11HC-PC916 + - Positivo Chromebook N2310 + - Positivo Chromebook N2312 config BOARD_GOOGLE_LALALA bool "-> Lalala" @@ -78,7 +101,14 @@ config BOARD_GOOGLE_METAKNIGHT bool "-> Metaknight (NEC Chromebook Y3)" config BOARD_GOOGLE_PIRIKA - bool "-> Pirika" + bool "-> Pirika (Multiple devices - See help text)" + help + The Drawcia board supports the following devices: + - Axioo Chromebook P14 + - CTL Chromebook Enterprise + - Gateway Chromebook 14 + - Arai Nimbus S1 Chromebook Enterprise + - Edxis E-Lite Chromebook 14 config BOARD_GOOGLE_SASUKE bool "-> Sasuke (Samsung Galaxy Chromebook Go)" diff --git a/src/mainboard/google/drallion/Kconfig.name b/src/mainboard/google/drallion/Kconfig.name index eed2505bcf..3b3f67041e 100644 --- a/src/mainboard/google/drallion/Kconfig.name +++ b/src/mainboard/google/drallion/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Drallion" +comment "Drallion (Intel CometLake (10th Gen) with ISH)" config BOARD_GOOGLE_DRALLION - bool "-> Drallion" + bool "-> Drallion/Drallion360 (Dell Latitude 7410 Chromebook Enterprise)" diff --git a/src/mainboard/google/eve/Kconfig.name b/src/mainboard/google/eve/Kconfig.name index 59d691c045..62e50ff793 100644 --- a/src/mainboard/google/eve/Kconfig.name +++ b/src/mainboard/google/eve/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Eve" +comment "Eve (Intel KabyLake (7th Gen))" config BOARD_GOOGLE_EVE bool "-> Eve (Google Pixelbook)" diff --git a/src/mainboard/google/fatcat/Kconfig.name b/src/mainboard/google/fatcat/Kconfig.name index 61582c5102..fbd244e25d 100644 --- a/src/mainboard/google/fatcat/Kconfig.name +++ b/src/mainboard/google/fatcat/Kconfig.name @@ -1,48 +1,48 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Fatcat" +comment "Fatcat (Intel PantherLake (Ultra 3rd Gen))" config BOARD_GOOGLE_FATCAT - bool "-> Fatcat" + bool "-> Fatcat" config BOARD_GOOGLE_FATCAT4ES - bool "-> Fatcat4ES" + bool "-> Fatcat4ES" config BOARD_GOOGLE_FATCATISH - bool "-> Fatcat_ish" + bool "-> Fatcat_ish" config BOARD_GOOGLE_FATCATITE - bool "-> Fatcatite" + bool "-> Fatcatite" config BOARD_GOOGLE_FATCATITE4ES - bool "-> Fatcatite4ES" + bool "-> Fatcatite4ES" config BOARD_GOOGLE_FATCATNUVO - bool "-> Fatcatnuvo" + bool "-> Fatcatnuvo" config BOARD_GOOGLE_FATCATNUVO4ES - bool "-> Fatcatnuvo4ES" + bool "-> Fatcatnuvo4ES" config BOARD_GOOGLE_FELINO - bool "-> Felino" + bool "-> Felino" config BOARD_GOOGLE_FELINO4ES - bool "-> Felino4ES" + bool "-> Felino4ES" config BOARD_GOOGLE_FRANCKA - bool "-> Francka" + bool "-> Francka" config BOARD_GOOGLE_KINMEN4ES - bool "-> Kinmen4ES" + bool "-> Kinmen4ES" config BOARD_GOOGLE_KINMEN - bool "-> Kinmen" + bool "-> Kinmen" config BOARD_GOOGLE_LAPIS - bool "-> Lapis" + bool "-> Lapis" config BOARD_GOOGLE_MOONSTONE - bool "-> Moonstone" + bool "-> Moonstone" config BOARD_GOOGLE_RUBY - bool "-> Ruby" + bool "-> Ruby" diff --git a/src/mainboard/google/fizz/Kconfig.name b/src/mainboard/google/fizz/Kconfig.name index 928afd8122..15c82802c5 100644 --- a/src/mainboard/google/fizz/Kconfig.name +++ b/src/mainboard/google/fizz/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Fizz" +comment "Fizz (Intel KabyLake/Kabylake-R (7th/8th Gen))" config BOARD_GOOGLE_FIZZ bool "-> Fizz (Multiple devices - See help text)" diff --git a/src/mainboard/google/foster/Kconfig.name b/src/mainboard/google/foster/Kconfig.name index 6a22b74832..12bc11bb37 100644 --- a/src/mainboard/google/foster/Kconfig.name +++ b/src/mainboard/google/foster/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Foster" +comment "Foster (Nvidia Tegra X1 (T210))" config BOARD_GOOGLE_FOSTER bool "-> Foster" diff --git a/src/mainboard/google/gale/Kconfig.name b/src/mainboard/google/gale/Kconfig.name index 56d3181fad..a43fd963cd 100644 --- a/src/mainboard/google/gale/Kconfig.name +++ b/src/mainboard/google/gale/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Gale" +comment "Gale (Qualcomm IPQ4019)" config BOARD_GOOGLE_GALE bool "-> Gale (Google WiFi)" diff --git a/src/mainboard/google/geralt/Kconfig.name b/src/mainboard/google/geralt/Kconfig.name index 4195d6f3fd..285fd637c6 100644 --- a/src/mainboard/google/geralt/Kconfig.name +++ b/src/mainboard/google/geralt/Kconfig.name @@ -1,9 +1,9 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Geralt" +comment "Geralt (MediaTek Kompanio 838 (MT8188))" config BOARD_GOOGLE_GERALT bool "-> Geralt" config BOARD_GOOGLE_CIRI - bool "-> Ciri" + bool "-> Ciri (Lenovo Chromebook Duet Gen9 (11M889))" diff --git a/src/mainboard/google/glados/Kconfig.name b/src/mainboard/google/glados/Kconfig.name index 57711d40be..50d5b0d9a5 100644 --- a/src/mainboard/google/glados/Kconfig.name +++ b/src/mainboard/google/glados/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Glados" +comment "Glados (Intel Skylake (6th Gen))" config BOARD_GOOGLE_ASUKA bool "-> Asuka (Dell Chromebook 13 3380)" diff --git a/src/mainboard/google/gru/Kconfig.name b/src/mainboard/google/gru/Kconfig.name index f72a350816..e6b55b7e1a 100644 --- a/src/mainboard/google/gru/Kconfig.name +++ b/src/mainboard/google/gru/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Gru" +comment "Gru (Rockchip RK3399)" config BOARD_GOOGLE_KEVIN bool "-> Kevin (Samsung Chromebook Plus)" diff --git a/src/mainboard/google/guybrush/Kconfig.name b/src/mainboard/google/guybrush/Kconfig.name index fc1f864475..b62ee3154a 100644 --- a/src/mainboard/google/guybrush/Kconfig.name +++ b/src/mainboard/google/guybrush/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Guybrush" +comment "Guybrush (AMD Ryzen Mobile 5000 (Cezanne))" config BOARD_GOOGLE_DEWATT bool "-> Dewatt (Acer Chromebook Spin 514)" diff --git a/src/mainboard/google/hatch/Kconfig.name b/src/mainboard/google/hatch/Kconfig.name index 57441dc820..2dd8ef88a0 100644 --- a/src/mainboard/google/hatch/Kconfig.name +++ b/src/mainboard/google/hatch/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Hatch" +comment "Hatch (Intel CometLake (10th Gen))" config BOARD_GOOGLE_AKEMI bool "-> Akemi (IdeaPad Flex 5/5i Chromebook)" diff --git a/src/mainboard/google/herobrine/Kconfig.name b/src/mainboard/google/herobrine/Kconfig.name index 71b93c2d35..7e9ef66d62 100644 --- a/src/mainboard/google/herobrine/Kconfig.name +++ b/src/mainboard/google/herobrine/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Herobrine" +comment "Herobrine (Qualcomm Snapdragon 7c+ Gen3 (SC7280))" config BOARD_GOOGLE_HEROBRINE bool "-> Herobrine" @@ -15,16 +15,16 @@ config BOARD_GOOGLE_PIGLIN bool "-> Piglin" config BOARD_GOOGLE_HOGLIN - bool "-> Hoglin" + bool "-> Hoglin" config BOARD_GOOGLE_VILLAGER - bool "-> Villager" + bool "-> Villager" config BOARD_GOOGLE_EVOKER - bool "-> Evoker" + bool "-> Evoker" config BOARD_GOOGLE_ZOGLIN - bool "-> Zoglin" + bool "-> Zoglin" config BOARD_GOOGLE_ZOMBIE bool "-> Zombie" diff --git a/src/mainboard/google/jecht/Kconfig.name b/src/mainboard/google/jecht/Kconfig.name index 2da82b422d..8528d020ec 100644 --- a/src/mainboard/google/jecht/Kconfig.name +++ b/src/mainboard/google/jecht/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Jecht" +comment "Jecht (Intel Broadwell (5th Gen))" config BOARD_GOOGLE_GUADO bool "-> Guado (ASUS Chromebox CN62)" diff --git a/src/mainboard/google/kahlee/Kconfig.name b/src/mainboard/google/kahlee/Kconfig.name index b102307bd2..46f1b763a8 100644 --- a/src/mainboard/google/kahlee/Kconfig.name +++ b/src/mainboard/google/kahlee/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Kahlee" +comment "Kahlee (AMD StoneyRidge)" config BOARD_GOOGLE_ALEENA bool "-> Aleena/Kasumi (Acer Chromebook 315 (CB315-2H), 311 (C721) / Spin 311 (R721T))" diff --git a/src/mainboard/google/kukui/Kconfig.name b/src/mainboard/google/kukui/Kconfig.name index d7f54f6d50..425429834a 100644 --- a/src/mainboard/google/kukui/Kconfig.name +++ b/src/mainboard/google/kukui/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Kukui" +comment "Kukui (MediaTek Kompanio 500 (MT8183))" config BOARD_GOOGLE_KUKUI bool "-> Kukui" @@ -12,7 +12,7 @@ config BOARD_GOOGLE_KODAMA bool "-> Kodama (Lenovo 10e Chromebook Tablet)" config BOARD_GOOGLE_KAKADU - bool "-> Kakadu" + bool "-> Kakadu (ASUS Chromebook Detachable CM3)" config BOARD_GOOGLE_FLAPJACK bool "-> Flapjack" @@ -20,7 +20,7 @@ config BOARD_GOOGLE_FLAPJACK config BOARD_GOOGLE_KATSU bool "-> Katsu (ASUS Chromebook Detachable CZ1)" -comment "Jacuzzi" +comment "Jacuzzi (MediaTek Kompanio 500 (MT8183))" config BOARD_GOOGLE_JACUZZI bool "-> Jacuzzi" @@ -29,7 +29,7 @@ config BOARD_GOOGLE_JUNIPER bool "-> Juniper (Acer Chromebook Spin 311 (CP311-3H))" config BOARD_GOOGLE_KAPPA - bool "-> Kappa" + bool "-> Kappa (HP Chromebook 11a)" config BOARD_GOOGLE_DAMU bool "-> Damu (ASUS Chromebook Flip CM3 (CM3200))" @@ -41,7 +41,7 @@ config BOARD_GOOGLE_STERN bool "-> Stern" config BOARD_GOOGLE_WILLOW - bool "-> Willow" + bool "-> Willow (Acer Chromebook 311 (C722/C722T))" config BOARD_GOOGLE_ESCHE bool "-> Esche (HP Chromebook 11MK G9 EE)" @@ -50,16 +50,16 @@ config BOARD_GOOGLE_BURNET bool "-> Burnet (HP Chromebook x360 11MK G3 EE)" config BOARD_GOOGLE_FENNEL - bool "-> Fennel" + bool "-> Fennel (Lenovo IdeaPad 3 Chromebook)" config BOARD_GOOGLE_COZMO bool "-> Cozmo (Acer Chromebook 314 (CB314-2H/CB314-2HT))" config BOARD_GOOGLE_MAKOMO - bool "-> Makomo" + bool "-> Makomo (Lenovo 100e Chromebook (2nd Gen))" config BOARD_GOOGLE_MUNNA bool "-> Munna" config BOARD_GOOGLE_PICO - bool "-> Pico" + bool "-> Pico (Acer Chromebook Spin 311)" diff --git a/src/mainboard/google/link/Kconfig.name b/src/mainboard/google/link/Kconfig.name index 87d548bd64..d53ffa10bb 100644 --- a/src/mainboard/google/link/Kconfig.name +++ b/src/mainboard/google/link/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Link" +comment "Link (Intel IvyBridge (3rd Gen))" config BOARD_GOOGLE_LINK bool "-> Link (Google Chromebook Pixel (2013))" diff --git a/src/mainboard/google/mistral/Kconfig.name b/src/mainboard/google/mistral/Kconfig.name index b8f6fa2d9f..0c7517356a 100644 --- a/src/mainboard/google/mistral/Kconfig.name +++ b/src/mainboard/google/mistral/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Mistral" +comment "Mistral (Qualcomm Dragonwing QCS405)" config BOARD_GOOGLE_MISTRAL bool "-> Mistral" diff --git a/src/mainboard/google/myst/Kconfig.name b/src/mainboard/google/myst/Kconfig.name index 56fcc1924f..da8bb4b4e7 100644 --- a/src/mainboard/google/myst/Kconfig.name +++ b/src/mainboard/google/myst/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Myst" +comment "Myst (AMD Ryzen Mobile 7000 (Phoenix))" config BOARD_GOOGLE_MYST bool "-> Myst" diff --git a/src/mainboard/google/nyan/Kconfig.name b/src/mainboard/google/nyan/Kconfig.name index 8bd2621b5b..db1dd42242 100644 --- a/src/mainboard/google/nyan/Kconfig.name +++ b/src/mainboard/google/nyan/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Nyan" +comment "Nyan (NVIDIA Tegra K1 (CD570M))" config BOARD_GOOGLE_NYAN bool "-> Nyan" diff --git a/src/mainboard/google/nyan_big/Kconfig.name b/src/mainboard/google/nyan_big/Kconfig.name index dc841b15a5..bda75aa648 100644 --- a/src/mainboard/google/nyan_big/Kconfig.name +++ b/src/mainboard/google/nyan_big/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Nyan Big" +comment "Nyan Big (Nvidia Tegra K1 (T124))" config BOARD_GOOGLE_NYAN_BIG bool "-> Nyan Big (Acer Chromebook 13 (CB5-311))" diff --git a/src/mainboard/google/nyan_blaze/Kconfig.name b/src/mainboard/google/nyan_blaze/Kconfig.name index aae2fb7b3d..a16805580a 100644 --- a/src/mainboard/google/nyan_blaze/Kconfig.name +++ b/src/mainboard/google/nyan_blaze/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Nyan Blaze" +comment "Nyan Blaze (NVIDIA Tegra K1 (CD570M))" config BOARD_GOOGLE_NYAN_BLAZE bool "-> Nyan Blaze (HP Chromebook 14 G3)" diff --git a/src/mainboard/google/oak/Kconfig.name b/src/mainboard/google/oak/Kconfig.name index ceba037655..9829b55c32 100644 --- a/src/mainboard/google/oak/Kconfig.name +++ b/src/mainboard/google/oak/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Oak" +comment "Oak (MediaTek Kompanio 500 (MT8173))" config BOARD_GOOGLE_OAK bool "-> Oak" diff --git a/src/mainboard/google/ocelot/Kconfig.name b/src/mainboard/google/ocelot/Kconfig.name index a57bc43c45..8e5badc67d 100644 --- a/src/mainboard/google/ocelot/Kconfig.name +++ b/src/mainboard/google/ocelot/Kconfig.name @@ -1,33 +1,33 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Ocelot" +comment "Ocelot (Intel WildcatLake (Ultra 3rd Gen))" config BOARD_GOOGLE_KODKOD - bool "-> Kodkod" + bool "-> Kodkod" config BOARD_GOOGLE_MATSU - bool "-> Matsu" + bool "-> Matsu" config BOARD_GOOGLE_OCELOT - bool "-> Ocelot" + bool "-> Ocelot" config BOARD_GOOGLE_OCELOTITE - bool "-> Ocelotite" + bool "-> Ocelotite" config BOARD_GOOGLE_OCELOTMCHP - bool "-> Ocelotmchp" + bool "-> Ocelotmchp" config BOARD_GOOGLE_OJAL - bool "-> Ojal" + bool "-> Ojal" config BOARD_GOOGLE_OCELOT4ES - bool "-> Ocelot4ES" + bool "-> Ocelot4ES" config BOARD_GOOGLE_OCELOTITE4ES - bool "-> Ocelotite4ES" + bool "-> Ocelotite4ES" config BOARD_GOOGLE_OCELOTMCHP4ES - bool "-> Ocelotmchp4ES" + bool "-> Ocelotmchp4ES" config BOARD_GOOGLE_OCICAT - bool "-> Ocicat" + bool "-> Ocicat" diff --git a/src/mainboard/google/octopus/Kconfig.name b/src/mainboard/google/octopus/Kconfig.name index 7519a2e7bf..90bd4ab449 100644 --- a/src/mainboard/google/octopus/Kconfig.name +++ b/src/mainboard/google/octopus/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Octopus" +comment "Octopus (Intel GeminiLake)" config BOARD_GOOGLE_AMPTON bool "-> Ampton (ASUS Chromebook Flip C214)" diff --git a/src/mainboard/google/parrot/Kconfig.name b/src/mainboard/google/parrot/Kconfig.name index bbaa6cf828..c8155e2679 100644 --- a/src/mainboard/google/parrot/Kconfig.name +++ b/src/mainboard/google/parrot/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Parrot" +comment "Parrot (Intel SandyBridge (2nd Gen))" config BOARD_GOOGLE_PARROT bool "-> Parrot (Acer C7/C710 Chromebook)" diff --git a/src/mainboard/google/peach_pit/Kconfig.name b/src/mainboard/google/peach_pit/Kconfig.name index 29eddb5594..dc0ab31134 100644 --- a/src/mainboard/google/peach_pit/Kconfig.name +++ b/src/mainboard/google/peach_pit/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Peach Pit" +comment "Peach Pit (Samsung Exynos 5420)" config BOARD_GOOGLE_PEACH_PIT bool "-> Peach Pit (Samsung Chromebook 2 11\")" diff --git a/src/mainboard/google/poppy/Kconfig.name b/src/mainboard/google/poppy/Kconfig.name index 7999d77dc3..3566de21ef 100644 --- a/src/mainboard/google/poppy/Kconfig.name +++ b/src/mainboard/google/poppy/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Poppy" +comment "Poppy (Intel KabyLake/KabyLake-R (7th/8th Gen))" config BOARD_GOOGLE_ATLAS bool "-> Atlas (Google Pixelbook Go)" diff --git a/src/mainboard/google/puff/Kconfig.name b/src/mainboard/google/puff/Kconfig.name index d8a997e7fb..947e91057d 100644 --- a/src/mainboard/google/puff/Kconfig.name +++ b/src/mainboard/google/puff/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Puff" +comment "Puff (Intel CometLake (10th Gen))" config BOARD_GOOGLE_AMBASSADOR bool "-> Ambassador (Meet Compute System [Intel 10th Gen])" diff --git a/src/mainboard/google/rambi/Kconfig.name b/src/mainboard/google/rambi/Kconfig.name index cd63c425dc..07324384bb 100644 --- a/src/mainboard/google/rambi/Kconfig.name +++ b/src/mainboard/google/rambi/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Rambi" +comment "Rambi (Intel Baytrail)" config BOARD_GOOGLE_BANJO bool "-> Banjo (Acer Chromebook 15 (CB3-531))" diff --git a/src/mainboard/google/rauru/Kconfig.name b/src/mainboard/google/rauru/Kconfig.name index f09ee43e15..cac699c553 100644 --- a/src/mainboard/google/rauru/Kconfig.name +++ b/src/mainboard/google/rauru/Kconfig.name @@ -1,12 +1,12 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Rauru" +comment "Rauru (MediaTek Kompanio Ultra 910 (MT8196))" config BOARD_GOOGLE_HYLIA - bool "-> Hylia" + bool "-> Hylia (Acer Chromebook Plus Spin 514 (CP514-5HN/CPE594-2N))" config BOARD_GOOGLE_NAVI - bool "-> Navi" + bool "-> Navi (Lenovo Chromebook Plus (14M9610))" config BOARD_GOOGLE_RAURU bool "-> Rauru" diff --git a/src/mainboard/google/reef/Kconfig.name b/src/mainboard/google/reef/Kconfig.name index e392c926cc..c8d176c2b8 100644 --- a/src/mainboard/google/reef/Kconfig.name +++ b/src/mainboard/google/reef/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Reef" +comment "Reef (Intel ApolloLake)" config BOARD_GOOGLE_REEF bool "-> Reef/Electro (Acer Chromebook Spin 11 R751T)" diff --git a/src/mainboard/google/rex/Kconfig.name b/src/mainboard/google/rex/Kconfig.name index 96aa4c63f1..0d1da6f015 100644 --- a/src/mainboard/google/rex/Kconfig.name +++ b/src/mainboard/google/rex/Kconfig.name @@ -1,12 +1,12 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Rex" +comment "Rex (Intel MeteorLake (Ultra 1st Gen))" config BOARD_GOOGLE_DEKU - bool "-> Deku" + bool "-> Deku" config BOARD_GOOGLE_DEKU4ES - bool "-> Deku4ES" + bool "-> Deku4ES" config BOARD_GOOGLE_KARIS bool "-> Karis (Acer Chromebook Plus Spin 714)" @@ -15,25 +15,25 @@ config BOARD_GOOGLE_KARIS4ES bool "-> Karis4ES" config BOARD_GOOGLE_OVIS - bool "-> Ovis" + bool "-> Ovis" config BOARD_GOOGLE_OVIS4ES - bool "-> Ovis4ES" + bool "-> Ovis4ES" config BOARD_GOOGLE_REX0 - bool "-> Rex 0" + bool "-> Rex 0" config BOARD_GOOGLE_REX_EC_ISH - bool "-> Rex EC ISH" + bool "-> Rex EC ISH" config BOARD_GOOGLE_REX4ES - bool "-> Rex4ES" + bool "-> Rex4ES" config BOARD_GOOGLE_REX4ES_EC_ISH - bool "-> Rex4ES EC ISH" + bool "-> Rex4ES EC ISH" config BOARD_GOOGLE_REX64 - bool "-> Rex 64" + bool "-> Rex 64" config BOARD_GOOGLE_SCREEBO bool "-> Screebo (ASUS ExpertBook CX54 Chromebook Plus (CX5403))" diff --git a/src/mainboard/google/sarien/Kconfig.name b/src/mainboard/google/sarien/Kconfig.name index ad31cb1285..817fd6d278 100644 --- a/src/mainboard/google/sarien/Kconfig.name +++ b/src/mainboard/google/sarien/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Sarien" +comment "Sarien (Intel WhiskeyLake (8th Gen))" config BOARD_GOOGLE_ARCADA bool "-> Arcada (Latitude 5300 2-in-1 Chromebook Enterprise)" diff --git a/src/mainboard/google/skyrim/Kconfig.name b/src/mainboard/google/skyrim/Kconfig.name index 5a9668c598..12d28eee97 100644 --- a/src/mainboard/google/skyrim/Kconfig.name +++ b/src/mainboard/google/skyrim/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Skyrim" +comment "Skyrim (AMD Ryzen Mobile 7000 (Mendocino))" config BOARD_GOOGLE_CRYSTALDRIFT bool "-> Crystaldrift (SPC Chromebook V1)" diff --git a/src/mainboard/google/skywalker/Kconfig.name b/src/mainboard/google/skywalker/Kconfig.name index 6c67574e94..258c8bd633 100644 --- a/src/mainboard/google/skywalker/Kconfig.name +++ b/src/mainboard/google/skywalker/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only OR MIT -comment "Skywalker" +comment "Skywalker (MediaTek Kompanio 540 (MT8189))" config BOARD_GOOGLE_ANAKIN bool "-> Anakin" @@ -18,7 +18,7 @@ config BOARD_GOOGLE_OBIWAN bool "-> Obiwan" config BOARD_GOOGLE_PADME - bool "-> Padme" + bool "-> Padme" config BOARD_GOOGLE_SKYWALKER bool "-> Skywalker" @@ -27,4 +27,4 @@ config BOARD_GOOGLE_TARKIN bool "-> Tarkin" config BOARD_GOOGLE_YODA - bool "-> Yoda" + bool "-> Yoda" diff --git a/src/mainboard/google/slippy/Kconfig.name b/src/mainboard/google/slippy/Kconfig.name index f258a2f9a4..fb07f75ed7 100644 --- a/src/mainboard/google/slippy/Kconfig.name +++ b/src/mainboard/google/slippy/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Slippy" +comment "Slippy (Intel Haswell (4th Gen))" config BOARD_GOOGLE_FALCO bool "-> Falco (HP Chromebook 14)" diff --git a/src/mainboard/google/smaug/Kconfig.name b/src/mainboard/google/smaug/Kconfig.name index 169a179aab..5273f92f5a 100644 --- a/src/mainboard/google/smaug/Kconfig.name +++ b/src/mainboard/google/smaug/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Smaug" +comment "Smaug (Nvidia Tegra X1 (T210))" config BOARD_GOOGLE_SMAUG bool "-> Smaug (Google Pixel C)" diff --git a/src/mainboard/google/storm/Kconfig.name b/src/mainboard/google/storm/Kconfig.name index d2f74da3e8..b252f99465 100644 --- a/src/mainboard/google/storm/Kconfig.name +++ b/src/mainboard/google/storm/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Storm" +comment "Storm (Qualcomm IPQ8064)" config BOARD_GOOGLE_STORM bool "-> Storm (OnHub Router TGR1900)" diff --git a/src/mainboard/google/stout/Kconfig.name b/src/mainboard/google/stout/Kconfig.name index f3d61533cf..a1fbee03ea 100644 --- a/src/mainboard/google/stout/Kconfig.name +++ b/src/mainboard/google/stout/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Stout" +comment "Stout (Intel SandyBridge (2nd Gen))" config BOARD_GOOGLE_STOUT bool "-> Stout (Lenovo Thinkpad X131e Chromebook)" diff --git a/src/mainboard/google/trogdor/Kconfig.name b/src/mainboard/google/trogdor/Kconfig.name index c3a00ab2aa..a8d41ef028 100644 --- a/src/mainboard/google/trogdor/Kconfig.name +++ b/src/mainboard/google/trogdor/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Trogdor" +comment "Trogdor (Qualcomm Snapdragon 7c (SC7180))" config BOARD_GOOGLE_BUBS bool "-> Bubs" @@ -12,10 +12,10 @@ config BOARD_GOOGLE_GELARSHIE bool "-> Gelarshie" config BOARD_GOOGLE_HOMESTAR - bool "-> Homestar" + bool "-> Homestar (Lenovo IdeaPad Duet 5 Chromebook)" config BOARD_GOOGLE_KINGOFTOWN - bool "-> Kingoftown" + bool "-> Kingoftown (HP Fortis 11 G9 Q Chromebook)" config BOARD_GOOGLE_LAZOR bool "-> Lazor (Acer Chromebook Spin 513, CP513-1H/1HL, R841T/LT)" @@ -27,16 +27,20 @@ config BOARD_GOOGLE_MRBLAND bool "-> Mrbland" config BOARD_GOOGLE_PAZQUEL - bool "-> Pazquel" + bool "-> Pazquel (see help text for details)" + help + The "Pazquel" board supports the following devices: + - Orbic Chromebook 4G + - Libera-Merdeka Chromebook C100/C110/C120/C150 config BOARD_GOOGLE_POMPOM - bool "-> Pompom" + bool "-> Pompom (Dynabook Chromebook C1)" config BOARD_GOOGLE_QUACKINGSTICK bool "-> Quackingstick (Acer Chromebook Tab 510 / Enterprise Tab 510)" config BOARD_GOOGLE_WORMDINGLER - bool "-> Wormdingler" + bool "-> Wormdingler (Lenovo IdeaPad Duet 3 Chromebook)" config BOARD_GOOGLE_TROGDOR bool "-> Trogdor" diff --git a/src/mainboard/google/veyron/Kconfig.name b/src/mainboard/google/veyron/Kconfig.name index 7e174a0931..952e9a8047 100644 --- a/src/mainboard/google/veyron/Kconfig.name +++ b/src/mainboard/google/veyron/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Veyron" +comment "Veyron (Rockchip RK3288)" config BOARD_GOOGLE_VEYRON_JAQ bool "-> Veyron_Jaq (Haier Chromebook 11)" diff --git a/src/mainboard/google/veyron_mickey/Kconfig.name b/src/mainboard/google/veyron_mickey/Kconfig.name index 207b447532..ff62fd1389 100644 --- a/src/mainboard/google/veyron_mickey/Kconfig.name +++ b/src/mainboard/google/veyron_mickey/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Veyron Mickey" +comment "Veyron Mickey (Rockchip RK3288)" config BOARD_GOOGLE_VEYRON_MICKEY bool "-> Veyron_Mickey (Asus Chromebit CS10)" diff --git a/src/mainboard/google/veyron_rialto/Kconfig.name b/src/mainboard/google/veyron_rialto/Kconfig.name index 490752ea4d..dd17d28871 100644 --- a/src/mainboard/google/veyron_rialto/Kconfig.name +++ b/src/mainboard/google/veyron_rialto/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Veyron Rialto" +comment "Veyron Rialto (Rockchip RK3288)" config BOARD_GOOGLE_VEYRON_RIALTO bool "-> Veyron_Rialto" diff --git a/src/mainboard/google/volteer/Kconfig.name b/src/mainboard/google/volteer/Kconfig.name index c3a2401bc9..fcae344309 100644 --- a/src/mainboard/google/volteer/Kconfig.name +++ b/src/mainboard/google/volteer/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Volteer" +comment "Volteer (Intel TigerLake (11th Gen))" config BOARD_GOOGLE_CHRONICLER bool "-> Chronicler (FMV Chromebook 14F)" diff --git a/src/mainboard/google/zork/Kconfig.name b/src/mainboard/google/zork/Kconfig.name index 43e1232792..035fd7380c 100644 --- a/src/mainboard/google/zork/Kconfig.name +++ b/src/mainboard/google/zork/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Zork" +comment "Zork (AMD Ryzen Mobile 3000 (Picasso))" config BOARD_GOOGLE_BERKNIP bool "-> Berknip (HP Pro c645 Chromebook Enterprise)" From 59d438f5c7a0174c4fedc6a18ee3b1205c9fb1e0 Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Fri, 19 Dec 2025 16:46:33 +0530 Subject: [PATCH 014/789] mb/google/bluey: Remove GSCVD region from Bluey and BlueyH variants BUG=b:452872947 TEST=Build all the variants of baseboard Google/Bluey. Change-Id: I1ac76d8fcefbc5f27373723dbabda109ca042fa5 Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90562 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/Kconfig | 4 ++ src/mainboard/google/bluey/chromeos-nogsc.fmd | 41 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/mainboard/google/bluey/chromeos-nogsc.fmd diff --git a/src/mainboard/google/bluey/Kconfig b/src/mainboard/google/bluey/Kconfig index 8c90202643..c185938caf 100644 --- a/src/mainboard/google/bluey/Kconfig +++ b/src/mainboard/google/bluey/Kconfig @@ -176,4 +176,8 @@ config MAINBOARD_GPIO_PIN_FOR_GSC_AP_INTERRUPT used for the interrupt line from the Google Security Chip (GSC) to the Application Processor (AP). +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos-nogsc.fmd" if BOARD_GOOGLE_MODEL_BLUEY + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos.fmd" + endif # BOARD_GOOGLE_BLUEY_COMMON diff --git a/src/mainboard/google/bluey/chromeos-nogsc.fmd b/src/mainboard/google/bluey/chromeos-nogsc.fmd new file mode 100644 index 0000000000..aa6b996b3a --- /dev/null +++ b/src/mainboard/google/bluey/chromeos-nogsc.fmd @@ -0,0 +1,41 @@ +## SPDX-License-Identifier: GPL-2.0-only + +FLASH@0x0 CONFIG_ROM_SIZE { + WP_RO 12M { + RO_SECTION { + BOOTBLOCK 512K + FMAP 4K + COREBOOT(CBFS) + GBB 0x2f00 + RO_FRID 0x100 + } + RO_VPD(PRESERVE) 16K + } + + RW_MISC 184K { + UNIFIED_MRC_CACHE(PRESERVE) 128K { + RECOVERY_MRC_CACHE 64K + RW_MRC_CACHE 64K + } + RW_ELOG(PRESERVE) 4K + RW_SHARED 4K { + SHARED_DATA + } + RW_VPD(PRESERVE) 32K + RW_NVRAM(PRESERVE) 16K + } + + RW_SECTION_A 4608K { + VBLOCK_A 8K + FW_MAIN_A(CBFS) + RW_FWID_A 256 + } + + RW_SECTION_B 4608K { + VBLOCK_B 8K + FW_MAIN_B(CBFS) + RW_FWID_B 256 + } + + RW_LEGACY(CBFS) +} From fa80ab014665884a1342f95bdfdef7e4c53db83f Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 9 Dec 2025 16:22:10 +0200 Subject: [PATCH 015/789] src/Kconfig: add MAINBOARD_NEEDS_CMOS_OPTIONS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The addition provides a way to select USE_OPTION_TABLE for a mainboard which depends on the CMOS backend for options. This is needed to support update mechanism based on Top Swap that permits recovery via a CMOS reset (see [0]). The indirection is necessary because USE_OPTION_TABLE is part of a `choice`. [0]: https://mail.coreboot.org/archives/list/coreboot@coreboot.org/thread/C6JN2PB7K7D67EG7OIKB6BBERZU5YV35/ Change-Id: I9e8f044077a5158650627a305c352cc9de578293 Signed-off-by: Sergii Dmytruk Reviewed-on: https://review.coreboot.org/c/coreboot/+/90433 Reviewed-by: Michał Kopeć Tested-by: build bot (Jenkins) Reviewed-by: Filip Lewiński Reviewed-by: Filip Gołaś --- src/Kconfig | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Kconfig b/src/Kconfig index 2b5a2241cc..6c59e4fa5b 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -151,7 +151,7 @@ choice prompt "Option backend to use" default USE_CBFS_FILE_OPTION_BACKEND if HAVE_CBFS_FILE_OPTION_BACKEND default USE_MAINBOARD_SPECIFIC_OPTION_BACKEND if HAVE_MAINBOARD_SPECIFIC_OPTION_BACKEND - default USE_OPTION_TABLE if NVRAMCUI_SECONDARY_PAYLOAD + default USE_OPTION_TABLE if NVRAMCUI_SECONDARY_PAYLOAD || MAINBOARD_NEEDS_CMOS_OPTIONS default USE_UEFI_VARIABLE_STORE if DRIVERS_EFI_VARIABLE_STORE && \ PAYLOAD_EDK2 && SMMSTORE_V2 @@ -904,6 +904,12 @@ config CMOS_LAYOUT_FILE default "src/mainboard/\$(MAINBOARDDIR)/cmos.layout" depends on HAVE_OPTION_TABLE +config MAINBOARD_NEEDS_CMOS_OPTIONS + bool + help + Select this option if a mainboard depends on storing options in CMOS + for the implementation of some feature. + config PCI_IO_CFG_EXT bool default n From f773a0faaccc8d2aa5192f923fe44527f20ee04e Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 9 Dec 2025 16:29:55 +0200 Subject: [PATCH 016/789] cpu/intel/fit/Makefile.mk: make FIT in TOPSWAP point at MCU in COREBOOT_TS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a correction of CB:89570 (commit 04ea4724e2d0 ("Makefile.mk: separate bootblocks into BOOTBLOCK and TOPSWAP")) which has FITs in both BOOTBLOCK and TOPSWAP point at microcode in COREBOOT region. This can be tested by comparing outputs of build/util/cbfstool/ifittool -f build/coreboot.rom -r TOPSWAP -D and build/util/cbfstool/ifittool -f build/coreboot.rom -r BOOTBLOCK -D with microcode addresses as shown by uefitool build/coreboot.rom The addresses in two regions must not be identical and their last six hex digits must match what uefitool shows in "Base:" field (not "Offset:"). Change-Id: Ie37aee7a26be18d1a4d8993afd2a2484c38c0b1e Signed-off-by: Sergii Dmytruk Reviewed-on: https://review.coreboot.org/c/coreboot/+/90434 Tested-by: build bot (Jenkins) Reviewed-by: Filip Gołaś Reviewed-by: Michał Kopeć Reviewed-by: Filip Lewiński --- src/cpu/intel/fit/Makefile.mk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cpu/intel/fit/Makefile.mk b/src/cpu/intel/fit/Makefile.mk index 2729c0a6ae..1594f45a4e 100644 --- a/src/cpu/intel/fit/Makefile.mk +++ b/src/cpu/intel/fit/Makefile.mk @@ -16,6 +16,10 @@ intel_fit-align := 16 ifeq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) regions-for-file-intel_fit = BOOTBLOCK regions-for-file-intel_fit_ts = TOPSWAP + +TS_MCU_REGION = COREBOOT_TS +else +TS_MCU_REGION = COREBOOT endif $(call add_intermediate, set_fit_ptr, $(IFITTOOL)) @@ -45,7 +49,7 @@ $(call add_intermediate, add_ts_mcu_fit, set_ts_fit_ptr $(IFITTOOL)) ifneq ($(FIT_ENTRY),) $(IFITTOOL) -f $< -A -n $(FIT_ENTRY) -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r $(TS_FIT_REGION) endif # FIT_ENTRY - $(IFITTOOL) -f $< -a -n cpu_microcode_blob.bin -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r $(TS_FIT_REGION) -R COREBOOT + $(IFITTOOL) -f $< -a -n cpu_microcode_blob.bin -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r $(TS_FIT_REGION) -R $(TS_MCU_REGION) cbfs-files-y += intel_fit_ts intel_fit_ts-file := fit_table.c:struct From cbac0d7a257629e977a1d625c83e7a2a4b1a84bb Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 9 Dec 2025 16:39:41 +0200 Subject: [PATCH 017/789] Makefile.mk,cpu/intel/fit/Makefile.mk: introduce CBFS_REGIONS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take advantage of cbfstool's ability to operate on multiple regions and introduce a variable with a list of main CBFS regions: it's just "COREBOOT" in most cases, but becomes "COREBOOT,COREBOOT_TS" when Top Swap update mechanism is enabled (see [0]). This is meant to simplify Makefiles by avoiding extra branches in existing and future changes. [0]: https://mail.coreboot.org/archives/list/coreboot@coreboot.org/thread/C6JN2PB7K7D67EG7OIKB6BBERZU5YV35/ Change-Id: If537d0d21a2867fafc2241ea9a0b4c0c6ca290a8 Signed-off-by: Sergii Dmytruk Reviewed-on: https://review.coreboot.org/c/coreboot/+/90435 Reviewed-by: Filip Lewiński Reviewed-by: Filip Gołaś Tested-by: build bot (Jenkins) Reviewed-by: Michał Kopeć --- Makefile.mk | 18 ++++++++++-------- src/cpu/intel/fit/Makefile.mk | 5 +---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Makefile.mk b/Makefile.mk index cab60b33a4..347ffc626f 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -974,22 +974,24 @@ $(objcbfs)/%.elf: $(objcbfs)/%.debug $(objcbfs)/%.map # 4) replace all '*' characters with spaces extract_nth=$(subst *,$(spc),$(patsubst -%-,%,$(word $(1), $(subst |,- -,-$(2)-)))) -# regions-for-file - Returns a cbfstool regions parameter -# $(call regions-for-file,$(filename)) -# returns "REGION1,REGION2,..." -# -# This is the default implementation. When using a boot strategy employing -# multiple CBFSes in fmap regions, override it. -regions-for-file ?= $(if $(value regions-for-file-$(1)), $(regions-for-file-$(1)), COREBOOT) +CBFS_REGIONS := COREBOOT ifeq ($(CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK),y) ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) TS_OPTIONS := -j $(CONFIG_INTEL_TOP_SWAP_BOOTBLOCK_SIZE) else -regions-for-file = $(if $(value regions-for-file-$(1)), $(regions-for-file-$(1)), COREBOOT,COREBOOT_TS) +CBFS_REGIONS := COREBOOT,COREBOOT_TS endif endif +# regions-for-file - Returns a cbfstool regions parameter +# $(call regions-for-file,$(filename)) +# returns "REGION1,REGION2,..." +# +# This is the default implementation. When using a boot strategy employing +# multiple CBFSes in fmap regions, override it. +regions-for-file ?= $(if $(value regions-for-file-$(1)), $(regions-for-file-$(1)), $(CBFS_REGIONS)) + ifeq ($(CONFIG_CBFS_AUTOGEN_ATTRIBUTES),y) cbfs-autogen-attributes=-g endif diff --git a/src/cpu/intel/fit/Makefile.mk b/src/cpu/intel/fit/Makefile.mk index 1594f45a4e..4a01449e4e 100644 --- a/src/cpu/intel/fit/Makefile.mk +++ b/src/cpu/intel/fit/Makefile.mk @@ -69,10 +69,7 @@ pbp.bin-type := raw $(call add_intermediate, add_pbp_fit, set_fit_ptr $(IFITTOOL)) @printf " UPDATE-FIT Platform Boot Policy binary\n" - $(IFITTOOL) -f $< -a -n pbp.bin -t 4 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r COREBOOT -ifeq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) - $(IFITTOOL) -f $< -a -n pbp.bin -t 4 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r COREBOOT_TS -endif + $(IFITTOOL) -f $< -a -n pbp.bin -t 4 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r $(CBFS_REGIONS) endif # CONFIG_HAVE_PBP_BIN From 739808011af70f0ad283ddc76b6ca88610521b4d Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Tue, 9 Dec 2025 16:45:53 +0200 Subject: [PATCH 018/789] Makefile.mk: don't add bootblock after other files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a correction of CB:89570 (commit 04ea4724e2d0 ("Makefile.mk: separate bootblocks into BOOTBLOCK and TOPSWAP")). It wasn't obvious that CBFS verification depends on bootblock being added first (otherwise cbfstool considers CBFS verification to be disabled because anchor is part of a bootblock). Correct this and add a comment for anyone else who might edit this code in the future. The issue manifested itself in build failing to perform CBFS verification via cbfstool when the firmware was built with CBFS_VERIFICATION enabled. Change-Id: If775480394270fc05206cde0707c511b126265d3 Signed-off-by: Filip Gołaś Signed-off-by: Sergii Dmytruk Reviewed-on: https://review.coreboot.org/c/coreboot/+/90436 Reviewed-by: Filip Lewiński Tested-by: build bot (Jenkins) Reviewed-by: Michał Kopeć --- Makefile.mk | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Makefile.mk b/Makefile.mk index 347ffc626f..3a20cffd62 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -1296,9 +1296,16 @@ $(shell rm -f $(obj)/coreboot.pre) ifneq ($(CONFIG_UPDATE_IMAGE),y) $(obj)/coreboot.pre: $$(prebuilt-files) $(CBFSTOOL) $(obj)/fmap.fmap $(obj)/fmap.desc $(objcbfs)/bootblock.bin $(CBFSTOOL) $@.tmp create -M $(obj)/fmap.fmap -r $(shell cat $(obj)/fmap.desc) +# The bootblock must exist in the image before we call `prebuild-files`, +# otherwise their hashes won't be added into the CBFS header and CBFS +# verification will fail. printf " BOOTBLOCK\n" ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) $(call add_bootblock,$@.tmp,$(objcbfs)/bootblock.bin) +else + @printf " PREP place bootblocks in $(BB_FIT_REGION) and $(TS_FIT_REGION)\n" + @printf " $(BB_FIT_REGION),$(TS_FIT_REGION)\n" + $(CBFSTOOL) $@.tmp add -r $(BB_FIT_REGION),$(TS_FIT_REGION) $(bootblock_add_params) endif # ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) $(prebuild-files) true mv $@.tmp $@ @@ -1329,15 +1336,6 @@ add_intermediate = \ $(1): $(obj)/coreboot.pre $(2) | $(INTERMEDIATE) \ $(eval INTERMEDIATE+=$(1)) $(eval PHONY+=$(1)) -ifeq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) -$(call add_intermediate, prep_bb_regions, $(CBFSTOOL)) - @printf " PREP place bootblocks in BOOTBLOCK and TOPSWAP\n" - @printf " BOOTBLOCK\n" - $(CBFSTOOL) $< add -r $(BB_FIT_REGION) $(bootblock_add_params) - @printf " TOPSWAP\n" - $(CBFSTOOL) $< add -r $(TS_FIT_REGION) $(bootblock_add_params) -endif - $(obj)/coreboot.rom: $(obj)/coreboot.pre $(CBFSTOOL) $(IFITTOOL) $$(INTERMEDIATE) @printf " CBFS $(subst $(obj)/,,$(@))\n" # The full ROM may be larger than the CBFS part, so create an empty From 7c7feca2588271c7fa4e3bd33e23eacab80ba2c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Go=C5=82a=C5=9B?= Date: Wed, 10 Dec 2025 16:44:24 +0200 Subject: [PATCH 019/789] CBFS verification: support Top Swap redundancy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Separating the bootblock into two copies (in BOOTBLOCK and TOPSWAP fmap regions) breaks the CBFS verification as TSPI CRTM knows nothing about the new regions and looks for bootblock in a hard-coded COREBOOT fmap region. Introduce and use cbfs_unverified_area_type_alloc() which is an extension of cbfs_unverified_area_alloc(), very similar to how cbfs_ro_type_map() is an extension of cbfs_ro_map(). This allows to specify a region of the bootblock file and skip verification because bootblock serves as a container of hashes and is not verified itself. The branching is done on the state of RTC BUC to always use the current bootblock. Somewhat confusingly, the measurement always uses BOOTBLOCK region because with active Top Swap that's the way to access a memory-mapped TOPSWAP region. Makefile.mk now verifies both COREBOOT and COREBOOT_TS regions. cbfstool needed a few updates as well: - recognize both "BOOTBLOCK" and "TOPSWAP" regions - recognize both "COREBOOT" and "COREBOOT_TS" regions - reset metadata cache before processing each region as cache may now be invalid SMM doesn't link with vboot functions, so cbfs_file_hash_mismatch() has to skip verification in SMM due to the use of CMOS options backend. This is a part of the bootblock redundancy feature proposed on the mailing list: https://mail.coreboot.org/archives/list/coreboot@coreboot.org/thread/C6JN2PB7K7D67EG7OIKB6BBERZU5YV35/ Tested by successfully booting into Protectli VP6670 with Top Swap and CBFS Verification features enabled and Top Swap state being toggled. Change-Id: Ia75e714ae84d8c0ae09b27495e3056313b109999 Signed-off-by: Filip Gołaś Signed-off-by: Sergii Dmytruk Reviewed-on: https://review.coreboot.org/c/coreboot/+/89691 Reviewed-by: Michał Kopeć Reviewed-by: Filip Lewiński Tested-by: build bot (Jenkins) --- Makefile.mk | 6 ++++-- src/include/cbfs.h | 18 +++++++++++----- src/lib/cbfs.c | 21 ++++++++++++++++-- src/security/tpm/tspi/crtm.c | 27 ++++++++++++++++++++++- util/cbfstool/cbfs_sections.h | 2 ++ util/cbfstool/cbfstool.c | 38 ++++++++++++++++++++++++--------- util/cbfstool/platform_fixups.c | 6 ++++-- 7 files changed, 96 insertions(+), 22 deletions(-) diff --git a/Makefile.mk b/Makefile.mk index 3a20cffd62..a823a115a4 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -984,6 +984,8 @@ CBFS_REGIONS := COREBOOT,COREBOOT_TS endif endif +CBFS_REGION_COUNT := $(words $(subst $(comma),$(spc),$(CBFS_REGIONS))) + # regions-for-file - Returns a cbfstool regions parameter # $(call regions-for-file,$(filename)) # returns "REGION1,REGION2,..." @@ -1356,8 +1358,8 @@ endif # CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE $(CBFSTOOL) $@ layout @printf " CBFSPRINT $(subst $(obj)/,,$(@))\n\n" ifeq ($(CONFIG_CBFS_VERIFICATION),y) - line=$$($(CBFSTOOL) $@ print -kv 2>/dev/null | grep -F '[CBFS VERIFICATION (COREBOOT)]') ;\ - if ! printf "$$line" | grep -q 'fully valid'; then \ + line=$$($(CBFSTOOL) $@ print -kv -r $(CBFS_REGIONS) 2>/dev/null | grep -F '[CBFS VERIFICATION') ;\ + if [ "$$(printf "$$line" | grep -c 'fully valid')" -ne $(CBFS_REGION_COUNT) ]; then \ echo "CBFS verification error: $$line" ;\ exit 1 ;\ fi diff --git a/src/include/cbfs.h b/src/include/cbfs.h index 27a285e51d..f7067f9009 100644 --- a/src/include/cbfs.h +++ b/src/include/cbfs.h @@ -201,7 +201,8 @@ void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out, bool force_ro, enum cbfs_type *type); void *_cbfs_unverified_area_alloc(const char *area, const char *name, - cbfs_allocator_t allocator, void *arg, size_t *size_out); + cbfs_allocator_t allocator, void *arg, size_t *size_out, + enum cbfs_type *type); struct _cbfs_default_allocator_arg { void *buf; @@ -242,7 +243,14 @@ static inline void *cbfs_unverified_area_alloc(const char *area, const char *nam cbfs_allocator_t allocator, void *arg, size_t *size_out) { - return _cbfs_unverified_area_alloc(area, name, allocator, arg, size_out); + return _cbfs_unverified_area_alloc(area, name, allocator, arg, size_out, NULL); +} + +static inline void *cbfs_unverified_area_type_alloc(const char *area, const char *name, + cbfs_allocator_t allocator, void *arg, + size_t *size_out, enum cbfs_type *type) +{ + return _cbfs_unverified_area_alloc(area, name, allocator, arg, size_out, type); } static inline void *cbfs_map(const char *name, size_t *size_out) @@ -268,7 +276,7 @@ static inline void *cbfs_ro_type_map(const char *name, size_t *size_out, enum cb static inline void *cbfs_unverified_area_map(const char *area, const char *name, size_t *size_out) { - return _cbfs_unverified_area_alloc(area, name, NULL, NULL, size_out); + return _cbfs_unverified_area_alloc(area, name, NULL, NULL, size_out, NULL); } static inline size_t _cbfs_load(const char *name, void *buf, size_t size, bool force_ro, @@ -307,7 +315,7 @@ static inline size_t cbfs_unverified_area_load(const char *area, const char *nam void *buf, size_t size) { struct _cbfs_default_allocator_arg arg = { .buf = buf, .buf_size = size }; - if (_cbfs_unverified_area_alloc(area, name, _cbfs_default_allocator, &arg, &size)) + if (_cbfs_unverified_area_alloc(area, name, _cbfs_default_allocator, &arg, &size, NULL)) return size; else return 0; @@ -341,7 +349,7 @@ static inline void *cbfs_unverified_area_cbmem_alloc(const char *area, const cha uint32_t cbmem_id, size_t *size_out) { return _cbfs_unverified_area_alloc(area, name, _cbfs_cbmem_allocator, - (void *)(uintptr_t)cbmem_id, size_out); + (void *)(uintptr_t)cbmem_id, size_out, NULL); } static inline size_t cbfs_get_size(const char *name) diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 1dd9288bff..0c602474b3 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -173,7 +173,12 @@ static bool cbfs_file_hash_mismatch(const void *buffer, size_t size, const struct vb2_hash *hash = NULL; - if (CONFIG(CBFS_VERIFICATION) && !skip_verification) { + /* + * Skipping this block in SMM because vboot library isn't linked to SMM stage. This is + * an issue only if using a CMOS options backend, then SMM refers to an option and tries + * to verify cmos.layout here. + */ + if (CONFIG(CBFS_VERIFICATION) && !ENV_SMM && !skip_verification) { hash = cbfs_file_hash(mdata); if (!hash) { ERROR("'%s' does not have a file hash!\n", mdata->h.filename); @@ -546,7 +551,8 @@ void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg, } void *_cbfs_unverified_area_alloc(const char *area, const char *name, - cbfs_allocator_t allocator, void *arg, size_t *size_out) + cbfs_allocator_t allocator, void *arg, size_t *size_out, + enum cbfs_type *type) { struct region_device area_rdev, file_rdev; union cbfs_mdata mdata; @@ -562,6 +568,17 @@ void *_cbfs_unverified_area_alloc(const char *area, const char *name, return NULL; } + if (type) { + const enum cbfs_type real_type = be32toh(mdata.h.type); + if (*type == CBFS_TYPE_QUERY) + *type = real_type; + else if (*type != real_type) { + ERROR("'%s' type mismatch (is %u, expected %u)\n", + mdata.h.filename, real_type, *type); + return NULL; + } + } + if (rdev_chain(&file_rdev, &area_rdev, data_offset, be32toh(mdata.h.len))) return NULL; diff --git a/src/security/tpm/tspi/crtm.c b/src/security/tpm/tspi/crtm.c index 4e0a9b727a..def2fc3513 100644 --- a/src/security/tpm/tspi/crtm.c +++ b/src/security/tpm/tspi/crtm.c @@ -9,6 +9,10 @@ #include #include +/* This include is available as only if CONFIG_SOC_INTEL_COMMON_BLOCK is + set, which is not guaranteed for this file. */ +#include + static int tpm_log_initialized; static inline int tpm_log_available(void) { @@ -72,7 +76,28 @@ static tpm_result_t tspi_init_crtm(void) /* Mapping measures the file. We know we can safely map here because bootblock-as-a-file is only used on x86, where we don't need cache to map. */ enum cbfs_type type = CBFS_TYPE_BOOTBLOCK; - void *mapping = cbfs_ro_type_map("bootblock", NULL, &type); + void *mapping = NULL; + + if (CONFIG(INTEL_TOP_SWAP_SEPARATE_REGIONS)) { + enum ts_config top_swap = get_rtc_buc_top_swap_status(); + if (top_swap == TS_ENABLE) + printk(BIOS_INFO, + "CRTM Top Swap: Measuring bootblock in TOPSWAP (will be logged as BOOTBLOCK).\n"); + else + printk(BIOS_INFO, + "CRTM Top Swap: Measuring bootblock in BOOTBLOCK.\n"); + + /* + * Whether Top Swap is active or not, FMAP always refers to the same + * memory ranges but the contents of BOOTBLOCK and TOPSWAP are swapped. + * Hence always using BOOTBLOCK region to access the active bootblock. + */ + mapping = cbfs_unverified_area_type_alloc("BOOTBLOCK", "bootblock", + NULL, NULL, NULL, &type); + } else { + mapping = cbfs_ro_type_map("bootblock", NULL, &type); + } + if (!mapping) { printk(BIOS_INFO, "TSPI: Couldn't measure bootblock into CRTM!\n"); diff --git a/util/cbfstool/cbfs_sections.h b/util/cbfstool/cbfs_sections.h index 99a4761b64..c3479bbfd2 100644 --- a/util/cbfstool/cbfs_sections.h +++ b/util/cbfstool/cbfs_sections.h @@ -10,7 +10,9 @@ #define SECTION_NAME_FMAP "FMAP" #define SECTION_NAME_PRIMARY_CBFS "COREBOOT" +#define SECTION_NAME_TOPSWAP_CBFS "COREBOOT_TS" #define SECTION_NAME_BOOTBLOCK "BOOTBLOCK" +#define SECTION_NAME_TOPSWAP "TOPSWAP" #define SECTION_ANNOTATION_CBFS "CBFS" diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index 5555b57364..68dbd32984 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -135,6 +135,18 @@ struct mh_cache { bool initialized; }; +static bool is_main_cbfs_region(const char *region_name) +{ + return strcmp(region_name, SECTION_NAME_PRIMARY_CBFS) == 0 || + strcmp(region_name, SECTION_NAME_TOPSWAP_CBFS) == 0; +} + +static bool is_topswap_region(const char *region_name) +{ + return strcmp(region_name, SECTION_NAME_TOPSWAP_CBFS) == 0 || + strcmp(region_name, SECTION_NAME_TOPSWAP) == 0; +} + static struct mh_cache *get_mh_cache(void) { static struct mh_cache mhc; @@ -148,22 +160,24 @@ static struct mh_cache *get_mh_cache(void) if (!fmap) goto no_metadata_hash; + const char *bootblock_region = SECTION_NAME_BOOTBLOCK; + if (is_topswap_region(param.region_name)) + bootblock_region = SECTION_NAME_TOPSWAP; + /* Find the metadata_hash container. If there is a "BOOTBLOCK" FMAP section, it's there. If not, it's a normal file in the primary CBFS section. */ size_t offset, size; struct buffer buffer; - if (fmap_find_area(fmap, SECTION_NAME_BOOTBLOCK)) { - if (!partitioned_file_read_region(&buffer, param.image_file, - SECTION_NAME_BOOTBLOCK)) + if (fmap_find_area(fmap, bootblock_region)) { + if (!partitioned_file_read_region(&buffer, param.image_file, bootblock_region)) goto no_metadata_hash; - mhc.region = SECTION_NAME_BOOTBLOCK; + mhc.region = bootblock_region; offset = 0; size = buffer.size; } else { struct cbfs_image cbfs; struct cbfs_file *mh_container; - if (!partitioned_file_read_region(&buffer, param.image_file, - SECTION_NAME_PRIMARY_CBFS)) + if (!partitioned_file_read_region(&buffer, param.image_file, SECTION_NAME_PRIMARY_CBFS)) goto no_metadata_hash; mhc.region = SECTION_NAME_PRIMARY_CBFS; if (cbfs_image_from_buffer(&cbfs, &buffer, param.headeroffset)) @@ -245,7 +259,7 @@ static int update_anchor(struct mh_cache *mhc, uint8_t *fmap_hash) will recalculate and update the metadata hash in the bootblock if needed. */ static int maybe_update_metadata_hash(struct cbfs_image *cbfs) { - if (strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS)) + if (!is_main_cbfs_region(param.region_name)) return 0; /* Metadata hash only embedded in primary CBFS. */ struct mh_cache *mhc = get_mh_cache(); @@ -268,6 +282,7 @@ static int maybe_update_metadata_hash(struct cbfs_image *cbfs) static int maybe_update_fmap_hash(void) { if (strcmp(param.region_name, SECTION_NAME_BOOTBLOCK) && + strcmp(param.region_name, SECTION_NAME_TOPSWAP) && strcmp(param.region_name, SECTION_NAME_FMAP) && param.type != CBFS_TYPE_BOOTBLOCK && param.type != CBFS_TYPE_AMDFW) @@ -1603,7 +1618,7 @@ static int cbfs_print(void) vb2_digest_size(real_hash.algo)); printf("[METADATA HASH]\t%s:%s", vb2_get_hash_algorithm_name(real_hash.algo), hash_str); - if (!strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS)) { + if (is_main_cbfs_region(param.region_name)) { if (!memcmp(mhc->cbfs_hash.raw, real_hash.raw, vb2_digest_size(real_hash.algo))) { printf(":valid"); @@ -2364,6 +2379,10 @@ int main(int argc, char **argv) strcpy(region_name_scratch, param.region_name); param.region_name = strtok(region_name_scratch, ","); for (unsigned region = 0; region < num_regions; ++region) { + // Reset metadata cache in case region uses anchor from a different + // location. + get_mh_cache()->initialized = false; + if (!param.region_name) { ERROR("Encountered illegal degenerate region name in -r list\n"); ERROR("The image will be left unmodified.\n"); @@ -2371,8 +2390,7 @@ int main(int argc, char **argv) return 1; } - if (strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS) - == 0) + if (is_main_cbfs_region(param.region_name)) seen_primary_cbfs = true; param.image_region = image_regions + region; diff --git a/util/cbfstool/platform_fixups.c b/util/cbfstool/platform_fixups.c index 7e29cd7e2b..97fdd2e15b 100644 --- a/util/cbfstool/platform_fixups.c +++ b/util/cbfstool/platform_fixups.c @@ -312,12 +312,14 @@ static int mediatek_fixup(struct buffer *buffer, unused size_t offset) platform_fixup_func platform_fixups_probe(struct buffer *buffer, size_t offset, const char *region_name) { - if (!strcmp(region_name, SECTION_NAME_BOOTBLOCK)) { + if (!strcmp(region_name, SECTION_NAME_BOOTBLOCK) || + !strcmp(region_name, SECTION_NAME_TOPSWAP)) { if (qualcomm_probe(buffer, offset)) return qualcomm_fixup; else if (mediatek_probe(buffer)) return mediatek_fixup; - } else if (!strcmp(region_name, SECTION_NAME_PRIMARY_CBFS)) { + } else if (!strcmp(region_name, SECTION_NAME_PRIMARY_CBFS) || + !strcmp(region_name, SECTION_NAME_TOPSWAP_CBFS)) { /* TODO: add fixups for primary CBFS bootblock platforms, if needed */ } else { ERROR("%s called for unexpected FMAP region %s!\n", __func__, region_name); From 56a7ae4389d201f69377740fa0858748d684f5f7 Mon Sep 17 00:00:00 2001 From: Jarried Lin Date: Thu, 18 Dec 2025 14:24:31 +0800 Subject: [PATCH 020/789] soc/mediatek/mt8196: Notify MCUPM to support MTE Before CPU resume, it is necessary to reinitialize the MTE-related settings of booker in MCUPM to prevent the loss of booker configurations after resume. BUG=b:467186613 TEST=Build pass, Verify S/R OK on Navi and Sapphire. Change-Id: Ieaf4c2ea0f8a5c372a5dbf4d0f6c44fbd978e6a6 Signed-off-by: Jarried Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90546 Reviewed-by: Yidi Lin Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu --- src/soc/mediatek/mt8196/booker.c | 4 ++++ src/soc/mediatek/mt8196/include/soc/mcupm_plat.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/soc/mediatek/mt8196/booker.c b/src/soc/mediatek/mt8196/booker.c index 13a0248653..2525043f5f 100644 --- a/src/soc/mediatek/mt8196/booker.c +++ b/src/soc/mediatek/mt8196/booker.c @@ -4,6 +4,7 @@ #include #include #include +#include #define REG_READ_ONLY_HASH_VALUE (MCUCFG_BASE + 0x059C) #define REG_MCUSYS_RESERVED_REG2 (MCUCFG_BASE + 0xFFE8) @@ -61,6 +62,9 @@ void booker_mte_init(uint64_t mte_tag_addr) { int i; + /* Notify MCUPM to configure MTE on resume path. */ + setbits32p(MTE_ENABLE_REG, 0xF); + printk(BIOS_DEBUG, "%s: MTE tag addr %#llx\n", __func__, mte_tag_addr); /* Setting MTU TAG */ diff --git a/src/soc/mediatek/mt8196/include/soc/mcupm_plat.h b/src/soc/mediatek/mt8196/include/soc/mcupm_plat.h index 6ce58e4799..37d62c96df 100644 --- a/src/soc/mediatek/mt8196/include/soc/mcupm_plat.h +++ b/src/soc/mediatek/mt8196/include/soc/mcupm_plat.h @@ -92,5 +92,6 @@ #define ABNORMALBOOT_REG GPR_BASE_ADDR_MCU(1) #define WARMBOOT_REG GPR_BASE_ADDR_MCU(23) +#define MTE_ENABLE_REG GPR_BASE_ADDR_MCU(25) #endif /* __SOC_MEDIATEK_MT8196_INCLUDE_SOC_MCUPM_PLAT_H__ */ From 7e7ba6fb11d4d8d241116d12eb5215854294ac40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Lewi=C5=84ski?= Date: Mon, 8 Dec 2025 14:39:57 +0100 Subject: [PATCH 021/789] security/lockdown/lockdown.c: option to lock COREBOOT and BOOTBLOCK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an option to lock the regions BOOTBLOCK and COREBOOT, leaving the regions TOPSWAP and COREBOOT_TS for updates in an Intel Top Swap redundancy scenario. This means that the user can now write and choose to boot from the update regions, selecting the attempt_slot_b CMOS option, and there is a protected golden copy of the entire firmware, that cannot be overwritten and can be reverted to by resetting CMOS. This is part of an ongoing implementation of a redundancy feature proposed on the mailing list: https://mail.coreboot.org/archives/list/coreboot@coreboot.org/thread/C6JN2PB7K7D67EG7OIKB6BBERZU5YV35/ Change-Id: Ia6dea22c41e2fc778af6ca7049b72c92686ec85f Signed-off-by: Filip Lewiński Reviewed-on: https://review.coreboot.org/c/coreboot/+/90413 Tested-by: build bot (Jenkins) Reviewed-by: Sergii Dmytruk --- src/security/lockdown/Kconfig | 12 ++++++++++++ src/security/lockdown/lockdown.c | 20 ++++++++++++++++++++ src/soc/intel/common/Kconfig.common | 14 ++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/src/security/lockdown/Kconfig b/src/security/lockdown/Kconfig index 8de7979904..95a768a148 100644 --- a/src/security/lockdown/Kconfig +++ b/src/security/lockdown/Kconfig @@ -73,6 +73,18 @@ config BOOTMEDIA_LOCK_WPRO_VBOOT_RO is either triggered by coreboot (when INTEL_CHIPSET_LOCKDOWN is set) or has to be triggered later (e.g. by the payload or the OS). +config BOOTMEDIA_LOCK_TOPSWAP + bool "Write-protect the COREBOOT & BOOTBLOCK regions" + depends on TOP_SWAP_REDUNDANCY + depends on BOOTMEDIA_LOCK_CONTROLLER + help + Select this if you want to write-protect the BOOTBLOCK and COREBOOT + (Slot A) regions as specified in the Top Swap FMAP. You will be able to + write to the TOPSWAP and COREBOOT_TS (Slot B) regions and set the + attempt_slot_b CMOS option to run updated firmware. The BOOTBLOCK and + COREBOOT regions will remain a read-only golden copy, which you can + then revert to by resetting CMOS. + endchoice config BOOTMEDIA_LOCK_IN_VERSTAGE diff --git a/src/security/lockdown/lockdown.c b/src/security/lockdown/lockdown.c index c2e2ac3501..6a75111f6b 100644 --- a/src/security/lockdown/lockdown.c +++ b/src/security/lockdown/lockdown.c @@ -27,6 +27,9 @@ void boot_device_security_lockdown(void) } else if (CONFIG(BOOTMEDIA_LOCK_WPRO_VBOOT_RO)) { printk(BIOS_DEBUG, "'WP_RO only'"); lock_type = CTRLR_WP; + } else if (CONFIG(BOOTMEDIA_LOCK_TOPSWAP)) { + printk(BIOS_DEBUG, "'COREBOOT + BOOTBLOCK'"); + lock_type = CTRLR_WP; } printk(BIOS_DEBUG, " using CTRL...\n"); } else { @@ -45,6 +48,11 @@ void boot_device_security_lockdown(void) printk(BIOS_ERR, "BM-LOCKDOWN: Could not find region 'WP_RO'\n"); else rdev = &dev; + } else if (CONFIG(BOOTMEDIA_LOCK_TOPSWAP)) { + if (fmap_locate_area_as_rdev("COREBOOT", &dev) < 0) + printk(BIOS_ERR, "BM-LOCKDOWN: Could not find region 'COREBOOT'\n"); + else + rdev = &dev; } else { rdev = boot_device_ro(); } @@ -53,6 +61,18 @@ void boot_device_security_lockdown(void) printk(BIOS_INFO, "BM-LOCKDOWN: Enabled bootmedia protection\n"); else printk(BIOS_ERR, "BM-LOCKDOWN: Failed to enable bootmedia protection\n"); + + if (CONFIG(BOOTMEDIA_LOCK_TOPSWAP)) { + /* + * Additionally set a protected range for the BOOTBLOCK region + */ + if (fmap_locate_area_as_rdev("BOOTBLOCK", &dev) < 0) + printk(BIOS_ERR, "BM-LOCKDOWN: Could not find region 'BOOTBLOCK'\n"); + else if (boot_device_wp_region(&dev, lock_type) >= 0) + printk(BIOS_INFO, "BM-LOCKDOWN: Enabled bootmedia protection for BOOTBLOCK\n"); + else + printk(BIOS_ERR, "BM-LOCKDOWN: Failed to enable bootmedia protection for BOOTBLOCK\n"); + } } static void lock(void *unused) diff --git a/src/soc/intel/common/Kconfig.common b/src/soc/intel/common/Kconfig.common index 964a564303..a1a2f39cfb 100644 --- a/src/soc/intel/common/Kconfig.common +++ b/src/soc/intel/common/Kconfig.common @@ -66,6 +66,20 @@ config INTEL_TOP_SWAP_OPTION_CONTROL option. Note that the option must be present in the board's cmos.layout. file. +config TOP_SWAP_REDUNDANCY + bool "Toggle the Intel Top Swap - based redundancy" + depends on HAVE_OPTION_TABLE && INTEL_HAS_TOP_SWAP + select INTEL_ADD_TOP_SWAP_BOOTBLOCK + select MAINBOARD_NEEDS_CMOS_OPTIONS + select INTEL_TOP_SWAP_SEPARATE_REGIONS + select INTEL_TOP_SWAP_OPTION_CONTROL + help + Toggle the Intel Top Swap based redundancy, where the BOOTBLOCK and COREBOOT + regions form a read-only golden copy and TOPSWAP and COREBOOT_TS are an + update partition. CMOS option "attempt_top_swap" decides which of the slots + gets booted, which means the platform can be reverted to the known-good copy + via CMOS reset. + endif config SOC_INTEL_COMMON From 003ea8511527967dd2a5beeb50d9761b904cf5ad Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Mon, 15 Dec 2025 21:10:06 +0800 Subject: [PATCH 022/789] soc/mediatek/mt8196: Support logo display on DISP_PATH_DUAL_MIPI path The mtk_ddp_ovlsys_start function is updated to take edid and path as arguments. This allows the function to configure the framebuffer address and overlay for DISP_PATH_DUAL_MIPI path. BUG=b:319511268 TEST=cherry pick CB:90504 and manual enable BMP_LOGO related configs. The logo is drawn in the ramstage. Change-Id: I60809f7062907617f2af1badcad9f53477911020 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90537 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu Reviewed-by: Chen-Tsung Hsieh --- src/soc/mediatek/common/display.c | 7 ++++--- src/soc/mediatek/common/include/soc/display.h | 3 ++- src/soc/mediatek/mt8196/ddp.c | 14 +++++++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c index d1880e4299..1f7277a0e6 100644 --- a/src/soc/mediatek/common/display.c +++ b/src/soc/mediatek/common/display.c @@ -78,7 +78,8 @@ static void panel_configure_backlight(struct panel_description *panel, static void display_logo(struct panel_description *panel, uintptr_t fb_addr, - const struct edid *edid) + const struct edid *edid, + enum disp_path_sel path) { memset((void *)fb_addr, 0, edid->bytes_per_line * edid->y_resolution); @@ -90,7 +91,7 @@ static void display_logo(struct panel_description *panel, }; render_logo_to_framebuffer(&config); - mtk_ddp_ovlsys_start(fb_addr); + mtk_ddp_ovlsys_start(fb_addr, edid, path); panel_configure_backlight(panel, true); } @@ -209,7 +210,7 @@ int mtk_display_init(void) fb_set_dual_pipe_flag(info, true); if (CONFIG(BMP_LOGO)) - display_logo(panel, fb_addr, &edid); + display_logo(panel, fb_addr, &edid, panel->disp_path); return 0; } diff --git a/src/soc/mediatek/common/include/soc/display.h b/src/soc/mediatek/common/include/soc/display.h index ca8782280e..c71d15bb66 100644 --- a/src/soc/mediatek/common/include/soc/display.h +++ b/src/soc/mediatek/common/include/soc/display.h @@ -37,6 +37,7 @@ void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, enum disp_path_sel path, struct dsc_config *dsc_config); void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, struct dsc_config *dsc_config); -void mtk_ddp_ovlsys_start(uintptr_t fb_addr); +void mtk_ddp_ovlsys_start(uintptr_t fb_addr, const struct edid *edid, + enum disp_path_sel path); #endif diff --git a/src/soc/mediatek/mt8196/ddp.c b/src/soc/mediatek/mt8196/ddp.c index ba317d4e79..012c6c9b3b 100644 --- a/src/soc/mediatek/mt8196/ddp.c +++ b/src/soc/mediatek/mt8196/ddp.c @@ -695,10 +695,22 @@ void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, ovlsys_layer_config(fmt, bpp, width, height, path); } -void mtk_ddp_ovlsys_start(uintptr_t fb_addr) +void mtk_ddp_ovlsys_start(uintptr_t fb_addr, const struct edid *edid, + enum disp_path_sel path) { + uint32_t offset; + write32(&ovl_exdma2_reg->ovl_addr, fb_addr); setbits32(&ovl_exdma2_reg->ovl_en, BIT(0)); setbits32(&ovl_exdma2_reg->ovl_l_en, BIT(0)); setbits32(&ovl_blenders[0]->bld_l_en, BIT(0)); + + if (!DUAL_PIPE(path)) + return; + + offset = edid->x_resolution * edid->framebuffer_bits_per_pixel / 8 / 2; + write32(&ovl1_exdma2_reg->ovl_addr, fb_addr + offset); + setbits32(&ovl1_exdma2_reg->ovl_en, BIT(0)); + setbits32(&ovl1_exdma2_reg->ovl_l_en, BIT(0)); + setbits32(&ovl1_blenders[0]->bld_l_en, BIT(0)); } From 0e217cf1d3ebfea1b17782867775e37cd5689def Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Thu, 18 Dec 2025 20:17:19 +0800 Subject: [PATCH 023/789] soc/mediatek/mt8196: Increase FRAMEBUFFER to 32MiB Increase FRAMEBUFFER from 24MiB to 32MiB to support UHD display panel. BUG=b:319511268 TEST=emerge-tanjiro coreboot Change-Id: Ib9cf14328d1b5d56246d4cc1ecfd3613af008d00 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90549 Tested-by: build bot (Jenkins) Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Yu-Ping Wu --- src/soc/mediatek/mt8196/include/soc/memlayout.ld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/mediatek/mt8196/include/soc/memlayout.ld b/src/soc/mediatek/mt8196/include/soc/memlayout.ld index 8c64d661db..2bd3a26b71 100644 --- a/src/soc/mediatek/mt8196/include/soc/memlayout.ld +++ b/src/soc/mediatek/mt8196/include/soc/memlayout.ld @@ -73,5 +73,5 @@ SECTIONS RESV_MEMORY_GPUEB(0xA0000000, 2M) /* Reserved memory for the dedicated secured memory allocator of GPU Mali firmware */ GPU_SEC_BUF(0xA2000000, 16M) - FRAMEBUFFER(0xBEC00000, 24M) + FRAMEBUFFER(0xBEC00000, 32M) } From ac170631d56f8632f713d1d9f0e7867a03f4add3 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Wed, 10 Dec 2025 08:38:50 +0000 Subject: [PATCH 024/789] mb/starlabs/starlite: Fix ddr5 entry This fixes the duplicate ddr6 entry which should have been ddr5. Change-Id: I3bbee8a2fbacc7fa057e225fcfe307877b4f2716 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90442 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Paul Menzel --- src/mainboard/starlabs/starlite_adl/variants/mk_v/romstage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/romstage.c b/src/mainboard/starlabs/starlite_adl/variants/mk_v/romstage.c index 235a8b4565..13c31ea809 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/romstage.c +++ b/src/mainboard/starlabs/starlite_adl/variants/mk_v/romstage.c @@ -31,7 +31,7 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) .dq0 = { 3, 2, 1, 0, 7, 4, 6, 5 }, .dq1 = { 8, 10, 11, 9, 14, 13, 12, 15 }, }, - .ddr6 = { + .ddr5 = { .dq0 = { 8, 9, 10, 11, 12, 13, 14, 15 }, .dq1 = { 7, 6, 5, 4, 3, 2, 1, 0 }, }, From 84ff3d3d125d34e17fa247c6d5821c981ab53ba7 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Thu, 30 Oct 2025 16:55:15 +0000 Subject: [PATCH 025/789] ec/starlabs/merlin: Add charge LED brightness control Add support for controlling charge LED brightness similar to the existing power LED brightness control. This includes: - New Kconfig option EC_STARLABS_CHARGE_LED - Charge LED CFR option in cfr.h - Implementation in ite.c using shared led_brightness array - ECRAM_CHARGE_LED register definition Refactor LED brightness enum values into shared led_brightness array for reuse between power and charge LED controls. EC changes for charge LED brightness TEST=build/boot starlabs/lite_adl and verify LED control via CFR Change-Id: I0f243d666e1fdc7d6df9859bb1cdcf460b6029ec Signed-off-by: Matt DeVillier Signed-off-by: Ali Hamid Reviewed-on: https://review.coreboot.org/c/coreboot/+/90563 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Sean Rhodes --- src/ec/starlabs/merlin/Kconfig | 8 +++++- src/ec/starlabs/merlin/cfr.h | 24 ++++++++++++++---- src/ec/starlabs/merlin/ite.c | 25 ++++++++++++++++--- src/ec/starlabs/merlin/variants/glk/ecdefs.h | 1 + src/ec/starlabs/merlin/variants/glkr/ecdefs.h | 1 + src/ec/starlabs/merlin/variants/kbl/ecdefs.h | 1 + .../starlabs/merlin/variants/merlin/ecdefs.h | 1 + 7 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/ec/starlabs/merlin/Kconfig b/src/ec/starlabs/merlin/Kconfig index c21ac68a0a..e650c81772 100644 --- a/src/ec/starlabs/merlin/Kconfig +++ b/src/ec/starlabs/merlin/Kconfig @@ -94,6 +94,12 @@ config EC_STARLABS_POWER_LED bool "Enable lowering the brightess of the Power LED" default y help - Select the in the mainboard supports reducing the LED brightness + Select if the mainboard supports reducing the power LED brightness + +config EC_STARLABS_CHARGE_LED + bool "Enable lowering the brightess of the Charge LED" + default y + help + Select if the mainboard supports reducing the charge LED brightness endif diff --git a/src/ec/starlabs/merlin/cfr.h b/src/ec/starlabs/merlin/cfr.h index 51b3adad1a..170ec7a0dd 100644 --- a/src/ec/starlabs/merlin/cfr.h +++ b/src/ec/starlabs/merlin/cfr.h @@ -98,6 +98,13 @@ static const struct sm_object lid_switch = SM_DECLARE_ENUM({ SM_ENUM_VALUE_END }, }); +const struct sm_enum_value led_brightness[] = { + { "Normal", LED_NORMAL }, + { "Reduced", LED_REDUCED }, + { "Off", LED_OFF }, + SM_ENUM_VALUE_END +}; + /* * Power LED Brightness */ @@ -106,9 +113,16 @@ static const struct sm_object power_led = SM_DECLARE_ENUM({ .ui_name = "Power LED Brightness", .ui_helptext = "Control the maximum brightness of the power LED", .default_value = LED_NORMAL, - .values = (const struct sm_enum_value[]) { - { "Normal", LED_NORMAL }, - { "Reduced", LED_REDUCED }, - { "Off", LED_OFF }, - SM_ENUM_VALUE_END }, + .values = led_brightness, +}); + +/* + * Charge LED Brightness + */ +static const struct sm_object charge_led = SM_DECLARE_ENUM({ + .opt_name = "charge_led", + .ui_name = "Charge LED Brightness", + .ui_helptext = "Control the maximum brightness of the charge LED", + .default_value = LED_NORMAL, + .values = led_brightness, }); diff --git a/src/ec/starlabs/merlin/ite.c b/src/ec/starlabs/merlin/ite.c index c239b061ad..953c9e3de6 100644 --- a/src/ec/starlabs/merlin/ite.c +++ b/src/ec/starlabs/merlin/ite.c @@ -345,7 +345,7 @@ static void merlin_init(struct device *dev) * Default: 0 * */ - const uint8_t power_led[] = { + const uint8_t led_brightness[] = { LED_NORMAL, LED_REDUCED, LED_OFF @@ -355,8 +355,27 @@ static void merlin_init(struct device *dev) ec_write(ECRAM_POWER_LED, get_ec_value_from_option("power_led", LED_NORMAL, - power_led, - ARRAY_SIZE(power_led), + led_brightness, + ARRAY_SIZE(led_brightness), + UINT_MAX, + UINT_MAX)); + + /* + * Charge LED Brightness + * + * Setting: charge_led + * + * Values: 0, 1, 2 + * Default: 0 + * + */ + + if (CONFIG(EC_STARLABS_CHARGE_LED)) + ec_write(ECRAM_CHARGE_LED, + get_ec_value_from_option("charge_led", + LED_NORMAL, + led_brightness, + ARRAY_SIZE(led_brightness), UINT_MAX, UINT_MAX)); } diff --git a/src/ec/starlabs/merlin/variants/glk/ecdefs.h b/src/ec/starlabs/merlin/variants/glk/ecdefs.h index ed518f400a..d5bfc037d3 100644 --- a/src/ec/starlabs/merlin/variants/glk/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/glk/ecdefs.h @@ -19,6 +19,7 @@ #define ECRAM_KBL_TIMEOUT 0x1a #define ECRAM_FN_LOCK_STATE 0x2c #define ECRAM_FN_CTRL_REVERSE 0x2d +#define ECRAM_CHARGE_LED dead_code_t(uint8_t) #define ECRAM_MAX_CHARGE dead_code_t(uint8_t) #define ECRAM_FAN_MODE dead_code_t(uint8_t) #define ECRAM_CHARGING_SPEED dead_code_t(uint8_t) diff --git a/src/ec/starlabs/merlin/variants/glkr/ecdefs.h b/src/ec/starlabs/merlin/variants/glkr/ecdefs.h index 6d469b2785..3836820895 100644 --- a/src/ec/starlabs/merlin/variants/glkr/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/glkr/ecdefs.h @@ -22,6 +22,7 @@ #define ECRAM_KBL_TIMEOUT 0x12 #define ECRAM_FN_LOCK_STATE 0x15 #define ECRAM_FN_CTRL_REVERSE 0x13 +#define ECRAM_CHARGE_LED dead_code_t(uint8_t) #define ECRAM_MAX_CHARGE dead_code_t(uint8_t) #define ECRAM_FAN_MODE dead_code_t(uint8_t) #define ECRAM_CHARGING_SPEED dead_code_t(uint8_t) diff --git a/src/ec/starlabs/merlin/variants/kbl/ecdefs.h b/src/ec/starlabs/merlin/variants/kbl/ecdefs.h index b0f743f711..206ccf2715 100644 --- a/src/ec/starlabs/merlin/variants/kbl/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/kbl/ecdefs.h @@ -20,6 +20,7 @@ #define ECRAM_FN_LOCK_STATE 0x2c #define ECRAM_FAN_MODE 0x42 #define ECRAM_FN_CTRL_REVERSE 0x43 +#define ECRAM_CHARGE_LED dead_code_t(uint8_t) #define ECRAM_MAX_CHARGE dead_code_t(uint8_t) #define ECRAM_CHARGING_SPEED dead_code_t(uint8_t) #define ECRAM_LID_SWITCH dead_code_t(uint8_t) diff --git a/src/ec/starlabs/merlin/variants/merlin/ecdefs.h b/src/ec/starlabs/merlin/variants/merlin/ecdefs.h index 4fab635f3d..f924ad0fbf 100644 --- a/src/ec/starlabs/merlin/variants/merlin/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/merlin/ecdefs.h @@ -19,6 +19,7 @@ #define ECRAM_TRACKPAD_STATE 0x0c #define ECRAM_FN_LOCK_STATE 0x0f #define ECRAM_FN_CTRL_REVERSE 0x17 +#define ECRAM_CHARGE_LED 0x18 #define ECRAM_MAX_CHARGE 0x1a #define ECRAM_FAN_MODE 0x1b #define ECRAM_CHARGING_SPEED 0x1d From ab2c69c4f306d0ebd3baa49dd1389b99f1b751f7 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 1 Dec 2025 18:11:06 -0600 Subject: [PATCH 026/789] mb/starlabs/starbook: Add CFR options for power/charge LED brightness Add CFR options to expose EC controls to set the brightness of the power and charge LEDs (normal/dim/off). TEST=build/boot starbook_mtl, verify LED control via CFR Change-Id: I7e1fe4efaab4327c8b95b108a9014e50058d6ed4 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90564 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel --- src/mainboard/starlabs/starbook/cfr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/starlabs/starbook/cfr.c b/src/mainboard/starlabs/starbook/cfr.c index cddc9af16f..69e48d1023 100644 --- a/src/mainboard/starlabs/starbook/cfr.c +++ b/src/mainboard/starlabs/starbook/cfr.c @@ -38,6 +38,8 @@ static struct sm_obj_form power = { #if CONFIG(EC_STARLABS_CHARGING_SPEED) &charging_speed, #endif + &power_led, + &charge_led, &power_on_after_fail_bool, NULL }, From 951c28c1bf3538af255d0ba4ff5f05d303b14580 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 1 Dec 2025 18:14:45 -0600 Subject: [PATCH 027/789] mb/starlabs/starfighter: Add CFR options for power/charge LED brightness Add CFR options to expose EC controls to set the brightness of the power and charge LEDs (normal/dim/off). TEST=build/boot starfighter_mtl, verify LED control via CFR Change-Id: I2af8372f923f92af62e48da77d4bddb87ab1eba0 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90565 Reviewed-by: Sean Rhodes Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/starfighter/cfr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/starlabs/starfighter/cfr.c b/src/mainboard/starlabs/starfighter/cfr.c index 166a9dbb81..ff3567f860 100644 --- a/src/mainboard/starlabs/starfighter/cfr.c +++ b/src/mainboard/starlabs/starfighter/cfr.c @@ -37,6 +37,8 @@ static struct sm_obj_form power = { #if CONFIG(EC_STARLABS_CHARGING_SPEED) &charging_speed, #endif + &power_led, + &charge_led, &power_on_after_fail_bool, NULL }, From 975e48faaf7d716867d824bfc5e71790c1af3038 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 1 Dec 2025 17:58:48 -0600 Subject: [PATCH 028/789] mb/starlabs/starlite_adl: Add CFR option for charge LED brightness Add a CFR option to expose the newly-added EC control to set the charge LED brightness (normal/dim/off). TEST=build/boot starlabs/lite_adl, verify charge LED control via CFR Change-Id: I090437e8de2fd65bfad93a2037fd9346347e9fc1 Signed-off-by: Matt DeVillier Signed-off-by: Ali Hamid Reviewed-on: https://review.coreboot.org/c/coreboot/+/90566 Reviewed-by: Paul Menzel Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/starlite_adl/cfr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/starlabs/starlite_adl/cfr.c b/src/mainboard/starlabs/starlite_adl/cfr.c index 2ed505a17f..da0b77bd94 100644 --- a/src/mainboard/starlabs/starlite_adl/cfr.c +++ b/src/mainboard/starlabs/starlite_adl/cfr.c @@ -48,6 +48,7 @@ static struct sm_obj_form power = { &charging_speed, #endif &power_led, + &charge_led, &power_on_after_fail_bool, NULL }, From 695041a9bf54493afa89ae17a5be6024ce37a9f7 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 29 Nov 2025 17:56:28 -0600 Subject: [PATCH 029/789] mb/starlabs/*: Increase size of SMMSTORE region to 512KB The previous default size of 256KB provided for only 64KB of actual space for EFI variables, and after accounting for fragmentation, did not provide enough free space for applying updates, such as for the UEFI revocation database (DBX). Increasing it to 512KB allows for 192KB space for variables, and allows the UEFI DBX to be updated properly via fwupd. TEST=build/boot starlite_adl, verify UEFI DBX able to be successfully updated via fwupd. Change-Id: I0fd28e38f5d3ad1e4db33fa3ab075929044ac831 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90284 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes Reviewed-by: Paul Menzel --- src/mainboard/starlabs/byte_adl/variants/mk_ii/board.fmd | 6 +++--- src/mainboard/starlabs/lite/board.fmd | 4 ++-- src/mainboard/starlabs/starbook/variants/adl/board.fmd | 6 +++--- src/mainboard/starlabs/starbook/variants/adl_n/board.fmd | 6 +++--- src/mainboard/starlabs/starbook/variants/cml/board.fmd | 6 +++--- src/mainboard/starlabs/starbook/variants/kbl/board.fmd | 6 +++--- src/mainboard/starlabs/starbook/variants/mtl/board.fmd | 6 +++--- src/mainboard/starlabs/starbook/variants/rpl/board.fmd | 6 +++--- src/mainboard/starlabs/starbook/variants/tgl/board.fmd | 6 +++--- src/mainboard/starlabs/starfighter/variants/mtl/board.fmd | 6 +++--- src/mainboard/starlabs/starfighter/variants/rpl/board.fmd | 6 +++--- src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd | 6 +++--- 12 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/board.fmd b/src/mainboard/starlabs/byte_adl/variants/mk_ii/board.fmd index 3c64b27134..2197262237 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/board.fmd +++ b/src/mainboard/starlabs/byte_adl/variants/mk_ii/board.fmd @@ -6,9 +6,9 @@ FLASH 0x1000000 { SI_BIOS 0xa00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/lite/board.fmd b/src/mainboard/starlabs/lite/board.fmd index 5e16badf5c..065ea619bd 100644 --- a/src/mainboard/starlabs/lite/board.fmd +++ b/src/mainboard/starlabs/lite/board.fmd @@ -44,7 +44,7 @@ # the header. FLASH 8M { OBBP@0x382000 { - OBB@0x0 0x2ae000 { + OBB@0x0 0x2ee000 { FMAP@0xe000 0x10000 COREBOOT(CBFS)@0x1e000 0x210000 FPF_STATUS@0x22e000 0x10000 @@ -53,7 +53,7 @@ FLASH 8M { RW_MRC_CACHE@0x10000 0x10000 RW_VAR_MRC_CACHE@0x20000 0x10000 } - SMMSTORE@0x26e000 0x40000 + SMMSTORE@0x26e000 0x80000 } } } diff --git a/src/mainboard/starlabs/starbook/variants/adl/board.fmd b/src/mainboard/starlabs/starbook/variants/adl/board.fmd index b652a36fe6..7495d43cec 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/adl/board.fmd @@ -6,9 +6,9 @@ FLASH 0x2000000 { SI_BIOS 0x1000000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/adl_n/board.fmd b/src/mainboard/starlabs/starbook/variants/adl_n/board.fmd index bc72a6098d..9cf12adf81 100644 --- a/src/mainboard/starlabs/starbook/variants/adl_n/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/adl_n/board.fmd @@ -6,9 +6,9 @@ FLASH 0x1000000 { SI_BIOS 0xa00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/cml/board.fmd b/src/mainboard/starlabs/starbook/variants/cml/board.fmd index 9018104edd..747141d188 100644 --- a/src/mainboard/starlabs/starbook/variants/cml/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/cml/board.fmd @@ -6,9 +6,9 @@ FLASH 16M { BIOS@0x400000 0xC00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x200 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x200 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/kbl/board.fmd b/src/mainboard/starlabs/starbook/variants/kbl/board.fmd index ef63457460..c9eee557ca 100644 --- a/src/mainboard/starlabs/starbook/variants/kbl/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/kbl/board.fmd @@ -1,9 +1,9 @@ FLASH 8M { BIOS@0x200000 0x600000 { RW_MRC_CACHE@0x0 0x10000 - SMMSTORE@0x10000 0x40000 - CONSOLE@0x50000 0x20000 - FMAP@0x70000 0x200 + SMMSTORE@0x10000 0x80000 + CONSOLE@0x90000 0x20000 + FMAP@0xB0000 0x200 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/mtl/board.fmd b/src/mainboard/starlabs/starbook/variants/mtl/board.fmd index cfa449253d..c1691514ab 100644 --- a/src/mainboard/starlabs/starbook/variants/mtl/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/mtl/board.fmd @@ -6,9 +6,9 @@ FLASH 0x2000000 { SI_BIOS 0xe00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/rpl/board.fmd b/src/mainboard/starlabs/starbook/variants/rpl/board.fmd index 6dcecabde7..b921fa1f2b 100644 --- a/src/mainboard/starlabs/starbook/variants/rpl/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/rpl/board.fmd @@ -6,9 +6,9 @@ FLASH 0x2000000 { SI_BIOS 0x1000000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/tgl/board.fmd b/src/mainboard/starlabs/starbook/variants/tgl/board.fmd index e7405bee77..26e341f50b 100644 --- a/src/mainboard/starlabs/starbook/variants/tgl/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/tgl/board.fmd @@ -6,9 +6,9 @@ FLASH 0x1000000 { SI_BIOS 0xb00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd b/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd index 1c11c433a2..ad7674988f 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd +++ b/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd @@ -6,9 +6,9 @@ FLASH 0x2000000 { SI_BIOS 0x1000000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/board.fmd b/src/mainboard/starlabs/starfighter/variants/rpl/board.fmd index 7f89c336ca..1990e9f88d 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/board.fmd +++ b/src/mainboard/starlabs/starfighter/variants/rpl/board.fmd @@ -6,9 +6,9 @@ FLASH 0x2000000 { SI_BIOS 0x1000000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd b/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd index bc72a6098d..9cf12adf81 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd +++ b/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd @@ -6,9 +6,9 @@ FLASH 0x1000000 { SI_BIOS 0xa00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } From 080ca011fe10565af8779abf1789e6f04b57e986 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Thu, 18 Dec 2025 12:12:38 -0600 Subject: [PATCH 030/789] Documentation: Finalize 25.12 release notes This adds a few items which were merged after the preliminary release notes were merged, and updates the statistics for actual release tag. Change-Id: I3b59568a67a3caa553c5f409edfed3053c1d4b7d Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90553 Tested-by: build bot (Jenkins) Reviewed-by: Alicja Michalska Reviewed-by: Felix Singer --- .../releases/coreboot-25.12-relnotes.md | 67 ++++++++++++++++--- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/Documentation/releases/coreboot-25.12-relnotes.md b/Documentation/releases/coreboot-25.12-relnotes.md index 894d8f9da7..d49c9dbce3 100644 --- a/Documentation/releases/coreboot-25.12-relnotes.md +++ b/Documentation/releases/coreboot-25.12-relnotes.md @@ -1,9 +1,9 @@ -Upcoming release - coreboot 25.12 +coreboot 25.12 release ======================================================================== The coreboot project is pleased to announce the release of coreboot 25.12, continuing our commitment to advancing open-source firmware -development. This release incorporates over 680 commits from more than +development. This release incorporates over 750 commits from more than 110 contributors, including numerous first-time authors. Key improvements include: @@ -84,6 +84,14 @@ configuration (30b43839448) and VCM type and address settings configuration under modern operating systems, particularly Windows, as proper SSDB and PLD configuration is required for full functionality. +DSM (Device Specific Method) generation has been refactored into +per-UUID functions (ea099e8b8c9, c8f89e00e4c), with new support for +CVF (Computer Vision Framework) DSM and I2C V2 DSM functions +(a64b93562d0, 1532eb60ee7). The driver now supports ACPI device type +selection (ae0d2324021) and ROM type/address configuration for camera +sensors (6459a2007a5), improving compatibility with various camera +implementations. + ### soc/qualcomm/x1p42100: Expanded platform support and debug capabilities @@ -103,6 +111,15 @@ layout refinements (c3afc13a0a5) optimize BL31 region placement and TZ Application memory alignment, improving overall platform memory utilization and security boundaries. +The platform now includes CMD-DB (Command Database) driver support +(01bc527afa2), enabling resource address and configuration data +lookup for hardware accelerators. The CMD-DB region is properly mapped +as non-cacheable in MMU (a4cc1784860, 2277edff88b), ensuring correct +access patterns for shared resource management. ARM64 architecture +improvements include distinct PRERAM and POSTRAM stack regions +(641f7ac677b, 1b599a88449), with PRERAM stack relocated to BSRAM +memory (4d53aa77042) for improved memory utilization. + ### soc/intel: LPCAMM (Low Power Compression Attached Memory Module) support @@ -135,6 +152,23 @@ Measurement) initialization support has been added (33fc33c132c), improving security and system reliability. +### include/acpi: Comprehensive APEI (Advanced Platform Error Interface) infrastructure + +Extensive APEI struct definitions have been added to support advanced +error reporting capabilities (679ea61d4de, b689671e79d, 7a41dc416be, +5251284e392). The implementation includes structs for Machine Check +Exception (MCE), Non-Maskable Interrupt (NMI), and PCIe AER (Advanced +Error Reporting) error sources, providing a foundation for BERT (Boot +Error Record Table), HEST (Hardware Error Source Table), and EINJ +(Error Injection Table) implementations. + +These additions enable platforms to properly report hardware errors +to operating systems, supporting firmware-first error handling models +and improving system reliability diagnostics. The struct definitions +follow ACPI specification standards and include proper validation +(847d91b82e5, b70309350f8). + + ### commonlib: Code consolidation and endian handling improvements The `` header implementations from both coreboot and @@ -191,8 +225,19 @@ Additional coreboot changes * Intel FSP UPD header typedef additions (2ce4e094690) * Azalia verb table implementation rework for improved maintainability (31fc5b06a6b) across multiple platforms +* Azalia driver timing fixes including proper 521us delay after RESET# + de-assertion (ecf202b8e4a) and link-reset improvements + (6e074550a5c, 152914272c1) * Intel touch driver enhancements for new devices with improved I2C speed handling (f1708cf21a2, fce489e9e5c, 1af54d9784b) +* Generic graphics driver support extended to non-VGA devices + (0f1ae4ae5f1), expanding compatibility beyond traditional VGA + displays +* MediaTek ARMv9 MTE (Memory Tagging Extension) tag memory support + added to bootmem (3d5135fdd07, 9203cc827f9), enabling proper memory + tagging for security-enhanced platforms +* Parallel charging infrastructure and support for Google Bluey platforms + (de87ea0efad, 896984e800a), enabling faster charging capabilities * Qualcomm USB Type-C support with PHY configuration and repeater support (8ffa58723a2, 45cedbb9922, 155041ad4cf, b18dfde22a7) * SoundWire drivers for Cirrus Logic CS35L56 and CS42L43 codecs @@ -264,15 +309,15 @@ Platform Updates Statistics from the 25.09 to the 25.12 release -------------------------------------------- -* Total Commits: 687 -* Average Commits per day: 8.79 -* Total lines added: 57757 -* Average lines added per commit: 84.07 -* Number of patches adding more than 100 lines: 69 -* Average lines added per small commit: 42.00 -* Total lines removed: 9190 -* Average lines removed per commit: 13.38 -* Total difference between added and removed: 48567 +* Total Commits: 757 +* Average Commits per day: 8.94 +* Total lines added: 62219 +* Average lines added per commit: 82.19 +* Number of patches adding more than 100 lines: 77 +* Average lines added per small commit: 42.02 +* Total lines removed: 9669 +* Average lines removed per commit: 12.77 +* Total difference between added and removed: 52550 * Total authors: 106 * New authors: 21 From 188cd88ac7d6f7af4b0a2ca832e096c1e9d8bf6f Mon Sep 17 00:00:00 2001 From: Payne Lin Date: Fri, 19 Dec 2025 15:38:38 +0800 Subject: [PATCH 031/789] soc/mediatek/mt8196: Correct MIPI register control Configuring pll_con1 is wrong. Change it to voltage_sel. BUG=b:424782827 TEST=Build pass, boot ok. Verify display output on the following platforms: - 8196 Navi: eDP path. - 8189 Skywalker: eDP path. - 8189 Padme: single MIPI path (without DSC). - 8196 Sapphire: dual MIPI path (with DSC). Change-Id: I300af87f3b7850cb994bc01c0572279ba18efac0 Signed-off-by: Payne Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90557 Reviewed-by: Yu-Ping Wu Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Yidi Lin Tested-by: build bot (Jenkins) --- src/soc/mediatek/mt8196/dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soc/mediatek/mt8196/dsi.c b/src/soc/mediatek/mt8196/dsi.c index 6d6705986b..0ea12b2931 100644 --- a/src/soc/mediatek/mt8196/dsi.c +++ b/src/soc/mediatek/mt8196/dsi.c @@ -19,10 +19,10 @@ void mtk_dsi_configure_mipi_tx(struct mipi_tx_regs *mipi_tx_reg, u32 data_rate, /* Select different voltage when different data rate */ if (data_rate < (u32)2500 * MHz) { - clrsetbits32(&mipi_tx_reg->pll_con1, RG_DSI_PRD_REF_SEL, RG_DSI_PRD_REF_MINI); + clrsetbits32(&mipi_tx_reg->voltage_sel, RG_DSI_PRD_REF_SEL, RG_DSI_PRD_REF_MINI); write32(&mipi_tx_reg->cdphy_preserved, 0xFFFF00F0); } else { - clrsetbits32(&mipi_tx_reg->pll_con1, RG_DSI_PRD_REF_SEL, RG_DSI_PRD_REF_DEF); + clrsetbits32(&mipi_tx_reg->voltage_sel, RG_DSI_PRD_REF_SEL, RG_DSI_PRD_REF_DEF); write32(&mipi_tx_reg->cdphy_preserved, 0xFFFF0030); } From de4148888c9c5bd24d9a754d15145d70a6db4127 Mon Sep 17 00:00:00 2001 From: Felix Singer Date: Sat, 20 Dec 2025 10:02:30 +0100 Subject: [PATCH 032/789] tests: Disable generation of lcov HTML The issues still appears even after commit 65833355ca36 ("tests: Disable gcov warnings"). So, disable the HTML generation completely until the issue is figured out. Change-Id: I683889ff8a0769697154079f99fe1d6ff9773281 Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/90578 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) Reviewed-by: Alicja Michalska --- tests/Makefile.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Makefile.mk b/tests/Makefile.mk index 08ba3dc3cb..9e3f86a138 100644 --- a/tests/Makefile.mk +++ b/tests/Makefile.mk @@ -149,8 +149,8 @@ clean-junit.xml-unit-tests: ifeq ($(COV),1) coverage-report: lcov -o $(testobj)/tests.info -c -d $(testobj) --exclude '$(testsrc)/*' - genhtml --ignore-errors inconsistent,corrupt -q -o $(testobj)/$(coverage_dir) -t "coreboot unit tests" \ - -s $(testobj)/tests.info + # TODO: fix inconsistent and corrupt error reports + # genhtml --ignore-errors inconsistent,corrupt -q -o $(testobj)/$(coverage_dir) -t "coreboot unit tests" -s $(testobj)/tests.info clean-coverage-report: rm -Rf $(testobj)/$(coverage_dir) From bceb2c83ad537a16c4aeddaefc36e3985774d344 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 19 Dec 2025 15:25:02 -0600 Subject: [PATCH 033/789] mb/{google/intel}: Fix/add missing MIPI camera SSDB lanes_used/link_used Ensure all mipi_camera sensor configurations have both ssdb.lanes_used and ssdb.link_used defined, and that these values correctly match the corresponding (known good) CIO2 IPU port configuration: - ssdb.lanes_used must match cio2_lanes_used = {x} for CAMx - ssdb.link_used must match cio2_prt[x] for CAMx Change-Id: Ifbf22c69d29c71138b7f59f08782d90425a09e30 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90571 Tested-by: build bot (Jenkins) Reviewed-by: Eric Lai --- src/mainboard/google/brya/variants/anraggar/overridetree.cb | 1 + src/mainboard/google/brya/variants/brya0/overridetree.cb | 4 ++-- src/mainboard/google/brya/variants/meliks/overridetree.cb | 2 +- src/mainboard/google/brya/variants/pirrha/overridetree.cb | 2 +- src/mainboard/google/brya/variants/redrix/overridetree.cb | 4 ++-- src/mainboard/google/brya/variants/redrix4es/overridetree.cb | 4 ++-- src/mainboard/google/brya/variants/skolas/overridetree.cb | 4 ++-- src/mainboard/google/brya/variants/skolas4es/overridetree.cb | 2 +- src/mainboard/google/brya/variants/teliks/overridetree.cb | 1 + src/mainboard/google/brya/variants/telith/overridetree.cb | 1 + src/mainboard/google/brya/variants/xivu/overridetree.cb | 2 +- .../google/dedede/variants/waddledoo/overridetree.cb | 3 ++- src/mainboard/google/fatcat/variants/fatcat/overridetree.cb | 2 ++ src/mainboard/google/rex/variants/kanix/overridetree.cb | 2 +- src/mainboard/google/rex/variants/karis/overridetree.cb | 2 +- src/mainboard/google/rex/variants/rex0/overridetree.cb | 4 ++-- src/mainboard/google/rex/variants/screebo/overridetree.cb | 2 +- src/mainboard/intel/adlrvp/devicetree.cb | 2 ++ src/mainboard/intel/adlrvp/devicetree_m.cb | 2 ++ src/mainboard/intel/adlrvp/devicetree_n.cb | 2 ++ .../intel/jasperlake_rvp/variants/jslrvp/devicetree.cb | 3 ++- .../intel/mtlrvp/variants/baseboard/mtlrvp_p/devicetree.cb | 2 ++ src/mainboard/intel/ptlrvp/variants/ptlrvp/overridetree.cb | 2 ++ .../intel/ptlrvp/variants/ptlrvp_chromeec/overridetree.cb | 2 ++ 24 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/mainboard/google/brya/variants/anraggar/overridetree.cb b/src/mainboard/google/brya/variants/anraggar/overridetree.cb index 877eec4700..5b71e31795 100644 --- a/src/mainboard/google/brya/variants/anraggar/overridetree.cb +++ b/src/mainboard/google/brya/variants/anraggar/overridetree.cb @@ -270,6 +270,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/brya0/overridetree.cb b/src/mainboard/google/brya/variants/brya0/overridetree.cb index 3139af5218..40f75629cf 100644 --- a/src/mainboard/google/brya/variants/brya0/overridetree.cb +++ b/src/mainboard/google/brya/variants/brya0/overridetree.cb @@ -543,7 +543,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" @@ -653,7 +653,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/meliks/overridetree.cb b/src/mainboard/google/brya/variants/meliks/overridetree.cb index 26cc775217..1e11eafa90 100644 --- a/src/mainboard/google/brya/variants/meliks/overridetree.cb +++ b/src/mainboard/google/brya/variants/meliks/overridetree.cb @@ -264,7 +264,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/pirrha/overridetree.cb b/src/mainboard/google/brya/variants/pirrha/overridetree.cb index 48f317157d..561ab72473 100644 --- a/src/mainboard/google/brya/variants/pirrha/overridetree.cb +++ b/src/mainboard/google/brya/variants/pirrha/overridetree.cb @@ -303,7 +303,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/redrix/overridetree.cb b/src/mainboard/google/brya/variants/redrix/overridetree.cb index 9f79c6ab21..822babaead 100644 --- a/src/mainboard/google/brya/variants/redrix/overridetree.cb +++ b/src/mainboard/google/brya/variants/redrix/overridetree.cb @@ -420,7 +420,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" @@ -463,7 +463,7 @@ chip soc/intel/alderlake register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/brya/variants/redrix4es/overridetree.cb b/src/mainboard/google/brya/variants/redrix4es/overridetree.cb index d36f91e414..4ebc017eab 100644 --- a/src/mainboard/google/brya/variants/redrix4es/overridetree.cb +++ b/src/mainboard/google/brya/variants/redrix4es/overridetree.cb @@ -350,7 +350,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" @@ -396,7 +396,7 @@ chip soc/intel/alderlake register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/brya/variants/skolas/overridetree.cb b/src/mainboard/google/brya/variants/skolas/overridetree.cb index 0f5a6cf651..ac0e5f51da 100644 --- a/src/mainboard/google/brya/variants/skolas/overridetree.cb +++ b/src/mainboard/google/brya/variants/skolas/overridetree.cb @@ -542,7 +542,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" @@ -652,7 +652,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/skolas4es/overridetree.cb b/src/mainboard/google/brya/variants/skolas4es/overridetree.cb index 95a27df342..b4e505c305 100644 --- a/src/mainboard/google/brya/variants/skolas4es/overridetree.cb +++ b/src/mainboard/google/brya/variants/skolas4es/overridetree.cb @@ -383,7 +383,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/teliks/overridetree.cb b/src/mainboard/google/brya/variants/teliks/overridetree.cb index 121f432af1..9e4f90c0ab 100644 --- a/src/mainboard/google/brya/variants/teliks/overridetree.cb +++ b/src/mainboard/google/brya/variants/teliks/overridetree.cb @@ -287,6 +287,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/telith/overridetree.cb b/src/mainboard/google/brya/variants/telith/overridetree.cb index 7b5ebee441..1a6982d1d2 100644 --- a/src/mainboard/google/brya/variants/telith/overridetree.cb +++ b/src/mainboard/google/brya/variants/telith/overridetree.cb @@ -413,6 +413,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/xivu/overridetree.cb b/src/mainboard/google/brya/variants/xivu/overridetree.cb index 5b1dc9fd3d..364f720374 100644 --- a/src/mainboard/google/brya/variants/xivu/overridetree.cb +++ b/src/mainboard/google/brya/variants/xivu/overridetree.cb @@ -253,7 +253,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb b/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb index 228a1720a6..321b05eda5 100644 --- a/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb @@ -146,7 +146,7 @@ chip soc/intel/jasperlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" @@ -221,6 +221,7 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" register "ssdb.lanes_used" = "1" + register "ssdb.link_used" = "0" register "num_freq_entries" = "1" register "link_freq[0]" = "180000000" register "remote_name" = ""IPU0"" diff --git a/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb b/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb index f520410847..f95d9e8255 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb @@ -665,6 +665,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz @@ -770,6 +771,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz diff --git a/src/mainboard/google/rex/variants/kanix/overridetree.cb b/src/mainboard/google/rex/variants/kanix/overridetree.cb index a9feef6b16..2b110cead7 100644 --- a/src/mainboard/google/rex/variants/kanix/overridetree.cb +++ b/src/mainboard/google/rex/variants/kanix/overridetree.cb @@ -509,7 +509,7 @@ chip soc/intel/meteorlake register "has_power_resource" = "true" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "4" register "ssdb.platform" = "PLAT_MTL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/rex/variants/karis/overridetree.cb b/src/mainboard/google/rex/variants/karis/overridetree.cb index 580bb9d033..f16560841d 100644 --- a/src/mainboard/google/rex/variants/karis/overridetree.cb +++ b/src/mainboard/google/rex/variants/karis/overridetree.cb @@ -464,7 +464,7 @@ chip soc/intel/meteorlake register "has_power_resource" = "true" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "4" register "ssdb.platform" = "PLAT_MTL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/rex/variants/rex0/overridetree.cb b/src/mainboard/google/rex/variants/rex0/overridetree.cb index c82d773ff0..af20b62edf 100644 --- a/src/mainboard/google/rex/variants/rex0/overridetree.cb +++ b/src/mainboard/google/rex/variants/rex0/overridetree.cb @@ -469,7 +469,7 @@ chip soc/intel/meteorlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "4" register "ssdb.platform" = "PLAT_MTL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" @@ -627,7 +627,7 @@ chip soc/intel/meteorlake register "has_power_resource" = "true" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_MTL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/rex/variants/screebo/overridetree.cb b/src/mainboard/google/rex/variants/screebo/overridetree.cb index b1e8ff7ce1..3d730a5820 100644 --- a/src/mainboard/google/rex/variants/screebo/overridetree.cb +++ b/src/mainboard/google/rex/variants/screebo/overridetree.cb @@ -515,7 +515,7 @@ chip soc/intel/meteorlake register "chip_name" = ""Ov 08X40 Camera"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "4" register "ssdb.platform" = "PLAT_MTL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/intel/adlrvp/devicetree.cb b/src/mainboard/intel/adlrvp/devicetree.cb index 5c12bb3b80..5451156ad1 100644 --- a/src/mainboard/intel/adlrvp/devicetree.cb +++ b/src/mainboard/intel/adlrvp/devicetree.cb @@ -354,6 +354,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" @@ -409,6 +410,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "num_freq_entries" = "1" register "link_freq[0]" = "450000000" diff --git a/src/mainboard/intel/adlrvp/devicetree_m.cb b/src/mainboard/intel/adlrvp/devicetree_m.cb index 7d197b0eca..6886babeb2 100644 --- a/src/mainboard/intel/adlrvp/devicetree_m.cb +++ b/src/mainboard/intel/adlrvp/devicetree_m.cb @@ -288,6 +288,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" @@ -343,6 +344,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "num_freq_entries" = "1" register "link_freq[0]" = "450000000" diff --git a/src/mainboard/intel/adlrvp/devicetree_n.cb b/src/mainboard/intel/adlrvp/devicetree_n.cb index 73b6828a38..5207d553a9 100644 --- a/src/mainboard/intel/adlrvp/devicetree_n.cb +++ b/src/mainboard/intel/adlrvp/devicetree_n.cb @@ -296,6 +296,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" @@ -351,6 +352,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "num_freq_entries" = "1" register "link_freq[0]" = "450000000" diff --git a/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb b/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb index d1fe840129..fadd309dab 100644 --- a/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb +++ b/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb @@ -378,6 +378,7 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_JSL" register "num_freq_entries" = "1" register "link_freq[0]" = "360000000" @@ -415,7 +416,7 @@ chip soc/intel/jasperlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/intel/mtlrvp/variants/baseboard/mtlrvp_p/devicetree.cb b/src/mainboard/intel/mtlrvp/variants/baseboard/mtlrvp_p/devicetree.cb index a01364dde1..995e765fff 100644 --- a/src/mainboard/intel/mtlrvp/variants/baseboard/mtlrvp_p/devicetree.cb +++ b/src/mainboard/intel/mtlrvp/variants/baseboard/mtlrvp_p/devicetree.cb @@ -441,6 +441,7 @@ chip soc/intel/meteorlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "4" register "ssdb.platform" = "PLAT_MTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560000000" @@ -484,6 +485,7 @@ chip soc/intel/meteorlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_MTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560000000" diff --git a/src/mainboard/intel/ptlrvp/variants/ptlrvp/overridetree.cb b/src/mainboard/intel/ptlrvp/variants/ptlrvp/overridetree.cb index 73294ec6f1..0ffdd6e629 100644 --- a/src/mainboard/intel/ptlrvp/variants/ptlrvp/overridetree.cb +++ b/src/mainboard/intel/ptlrvp/variants/ptlrvp/overridetree.cb @@ -665,6 +665,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz @@ -770,6 +771,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz diff --git a/src/mainboard/intel/ptlrvp/variants/ptlrvp_chromeec/overridetree.cb b/src/mainboard/intel/ptlrvp/variants/ptlrvp_chromeec/overridetree.cb index 2c7782f841..d6ac1a333a 100644 --- a/src/mainboard/intel/ptlrvp/variants/ptlrvp_chromeec/overridetree.cb +++ b/src/mainboard/intel/ptlrvp/variants/ptlrvp_chromeec/overridetree.cb @@ -665,6 +665,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz @@ -770,6 +771,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz From c5eecee5e9120b915f3f616b9bbdd3e8d51ad80e Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 19 Dec 2025 18:06:56 -0600 Subject: [PATCH 034/789] mb/google/rex: Add IPUA device and sensor names Add missing configuration items for rex variants to have functional MIPI cameras under Windows/mainline Linux: - Add IPUA device to graphics device configuration - Add sensor_name register to sensor device configurations Screebo was missing the gfx/generic configuration for all other display outputs present in other variants, so add that as well. TEST=build/boot Win11/Linux on karis and screebo, verify MIPI camera functional under both OSes using the standard driver stack. Change-Id: I14ec0efd88c43ca94ebde2be4652775bcb6d73c3 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90573 Tested-by: build bot (Jenkins) Reviewed-by: Eric Lai --- .../google/rex/variants/kanix/overridetree.cb | 8 ++++- .../google/rex/variants/karis/overridetree.cb | 7 ++++- .../google/rex/variants/rex0/overridetree.cb | 9 +++++- .../rex/variants/screebo/overridetree.cb | 30 +++++++++++++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/mainboard/google/rex/variants/kanix/overridetree.cb b/src/mainboard/google/rex/variants/kanix/overridetree.cb index 2b110cead7..37f3d7ca0a 100644 --- a/src/mainboard/google/rex/variants/kanix/overridetree.cb +++ b/src/mainboard/google/rex/variants/kanix/overridetree.cb @@ -152,7 +152,7 @@ chip soc/intel/meteorlake device domain 0 on device ref igpu on chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" register "device[0].type" = "panel" @@ -170,6 +170,11 @@ chip soc/intel/meteorlake register "device[4].pld" = "ACPI_PLD_TYPE_C(LEFT, RIGHT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) unused register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" + device generic 0 on end end end # Integrated Graphics Device @@ -505,6 +510,7 @@ chip soc/intel/meteorlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" diff --git a/src/mainboard/google/rex/variants/karis/overridetree.cb b/src/mainboard/google/rex/variants/karis/overridetree.cb index f16560841d..c24c7c7cd7 100644 --- a/src/mainboard/google/rex/variants/karis/overridetree.cb +++ b/src/mainboard/google/rex/variants/karis/overridetree.cb @@ -130,7 +130,7 @@ chip soc/intel/meteorlake device domain 0 on device ref igpu on chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" register "device[0].type" = "panel" @@ -148,6 +148,10 @@ chip soc/intel/meteorlake register "device[4].pld" = "ACPI_PLD_TYPE_C(LEFT, RIGHT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) unused register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" device generic 0 on end end end # Integrated Graphics Device @@ -460,6 +464,7 @@ chip soc/intel/meteorlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" diff --git a/src/mainboard/google/rex/variants/rex0/overridetree.cb b/src/mainboard/google/rex/variants/rex0/overridetree.cb index af20b62edf..d26dd567ee 100644 --- a/src/mainboard/google/rex/variants/rex0/overridetree.cb +++ b/src/mainboard/google/rex/variants/rex0/overridetree.cb @@ -148,7 +148,7 @@ chip soc/intel/meteorlake device domain 0 on device ref igpu on chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" register "device[0].type" = "panel" @@ -167,6 +167,11 @@ chip soc/intel/meteorlake register "device[4].pld" = "ACPI_PLD_TYPE_C(RIGHT, LEFT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel, so GFX device is added for TCP3 register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" + device generic 0 on end end end # Integrated Graphics Device @@ -466,6 +471,7 @@ chip soc/intel/meteorlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 13b10 Camera"" + register "sensor_name" = ""09B13U"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" @@ -623,6 +629,7 @@ chip soc/intel/meteorlake register "acpi_uid" = "0" register "acpi_name" = ""CAM1"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" diff --git a/src/mainboard/google/rex/variants/screebo/overridetree.cb b/src/mainboard/google/rex/variants/screebo/overridetree.cb index 3d730a5820..60d28bcaa5 100644 --- a/src/mainboard/google/rex/variants/screebo/overridetree.cb +++ b/src/mainboard/google/rex/variants/screebo/overridetree.cb @@ -152,6 +152,35 @@ chip soc/intel/meteorlake }" device domain 0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "7" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + # DDIB for HDMI + register "device[1].name" = ""DD01"" + # TCP0 (DP-1) for port C0 + register "device[2].name" = ""DD02"" + register "device[2].use_pld" = "true" + register "device[2].pld" = "ACPI_PLD_TYPE_C(LEFT, LEFT, ACPI_PLD_GROUP(1, 1))" + # TCP1 (DP-2) is unused for any ports but still enumerated in the kernel + register "device[3].name" = ""DD03"" + # TCP2 (DP-3) for port C1 + register "device[4].name" = ""DD04"" + register "device[4].use_pld" = "true" + register "device[4].pld" = "ACPI_PLD_TYPE_C(RIGHT, RIGHT, ACPI_PLD_GROUP(2, 1))" + # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel + register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" + + device generic 0 on end + end + end # Integrated Graphics Device device ref dtt on chip drivers/intel/dptf ## sensor information @@ -513,6 +542,7 @@ chip soc/intel/meteorlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 08X40 Camera"" + register "sensor_name" = ""CJFME55"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" register "ssdb.link_used" = "4" From 82c06da5843f1a9cd3f779b72b7436b1b7b17990 Mon Sep 17 00:00:00 2001 From: Felix Singer Date: Mon, 22 Dec 2025 07:10:53 +0000 Subject: [PATCH 035/789] 3rdparty/fsp: Update to upstream master Updating from commit id 9623d524500c: 2025-08-21 11:29:54 -0700 - (BirchStream FSP (0041D92)) to commit id a5b3d0e056ad: 2025-12-22 09:38:25 +0800 - (Renaming directory back to "IoT" to fix the corrupted path) This brings in 29 new commits: a5b3d0e056ad Renaming directory back to "IoT" to fix the corrupted path b221ba5eb8fa Renaming directory back to "IoT" to fix the corrupted path 2e4673109868 ECG BTL-S Hybrid MR2 (6311_03) FSP 07e258cd90b1 ECG BTL-S Hybrid MR2 (6311_03) FSP 8701f48b18f0 Edge Platforms ARL -S MR3 (5303_41) FSP 19e14bfd1fe6 Edge Platforms ARL-U/H MR3 (5272_44) FSP 48af2c8e8a27 Edge Platforms MTL-U/H_MTL-PS MR4 (5272_44) FSP 4da2c4207396 Edge Platforms ADL-N/ASL/TWL IPU2026.1 (v6457_50) 3eda9a327426 NEX AZB IPU 2025.2 (6033_00) FSP 066a84c5950a Edge Platforms ADL -PS IPU 2026.1 (6311_00) FSP c18800c791d6 Edge Platforms ADL -PS IPU 2025.4 (6074_01) FSP 4e19ab2857bd Edge Platforms ADL -S IPU 2026.1 (6311_00) FSP cd05b3f8bd07 Edge Platforms ADL -S IPU 2025.4 (6074_00) FSP 2348ab42fd74 Edge Platforms ADL -P IPU 2026.1 (6311_00) FSP b392cfd566f2 Edge Platforms ADL -P IPU 2026.1 (6311_00) FSP 2fcf87972e49 Modify folder name 975246e2ae82 Edge Platforms RPL -S/S Refresh IPU 2026.1 (6311_00) FSP a53f7ccb4b71 Edge Platforms RPL -P IPU 2026.1 (6311_00) FSP 77028f7f3b07 Edge Platforms ADL -PS IPU 2026.1 (6311_00) FSP 7ac503b829e6 Edge Platforms ADL -S IPU 2026.1 (6311_00) FSP 3ffd2a70fb83 Edge Platforms ADL -P IPU 2026.1 (6311_00) FSP ba2bddbc0418 IPU2026.1 239368c7d743 Edge Platforms TGL-UP3/H IPU 2026.1 (8063_03) FSP 41d3ae12bdb6 Merge branch 'master' of https://github.com/intel/FSP 8340338aaee7 Edge Platforms RPL-PS IPU2026.1 (6311_00) FSP 7c4aaf2266e8 ECG ARL-S MR2 (5192_41) FSP bb073b44232f ECG ARL-UH MR2 (5204_40) FSP 5d0424c89ddd IoT TWL MR1/ASL MR4 (6247_00) e1ce5bb0748a IoT TWL MR1/ASL MR4 (6247_00) Change-Id: Ia8084c7f8025936e694644579eeef4da37c4fe89 Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/90336 Tested-by: build bot (Jenkins) Reviewed-by: Werner Zeh Reviewed-by: Matt DeVillier --- 3rdparty/fsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/fsp b/3rdparty/fsp index 9623d52450..a5b3d0e056 160000 --- a/3rdparty/fsp +++ b/3rdparty/fsp @@ -1 +1 @@ -Subproject commit 9623d524500c140a6b11d2c727cb282b54962f09 +Subproject commit a5b3d0e056ad713f0055334427bc424f91aa6602 From 206025754f0b39627ebba7a5d7305668d65d9d9e Mon Sep 17 00:00:00 2001 From: Felix Singer Date: Mon, 22 Dec 2025 18:46:38 +0100 Subject: [PATCH 036/789] libpayload/tests: Remove unrecognized flag --ignore-errors inconsistent That parameter was mistakenly added here while trying to silent lcov complaints. Drop it again since it's not supported here. Change-Id: I77bed4ebb7d3ef6daea39c812bacfcad7a72aee7 Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/90597 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- payloads/libpayload/tests/Makefile.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payloads/libpayload/tests/Makefile.mk b/payloads/libpayload/tests/Makefile.mk index 9ab8c3b71c..a6cee5f480 100644 --- a/payloads/libpayload/tests/Makefile.mk +++ b/payloads/libpayload/tests/Makefile.mk @@ -273,7 +273,7 @@ clean-junit.xml-unit-tests: ifeq ($(COV),1) coverage-report: - lcov --ignore-errors inconsistent -o $(testobj)/tests.info -c -d $(testobj) --exclude '$(testsrc)/*' + lcov -o $(testobj)/tests.info -c -d $(testobj) --exclude '$(testsrc)/*' genhtml -q -o $(coverage-dir) -t "coreboot unit tests" -s $(testobj)/tests.info clean-coverage-report: From ba5b5ea406c72570552d9b69946d669420b879c3 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Thu, 18 Dec 2025 17:03:24 +0800 Subject: [PATCH 037/789] soc/mediatek/mt8196: Move DPM and SPM initialization Move dpm_init() and spm_init() from mainboard_init() in rauru to soc_init() in mt8196. This centralizes the power management initialization within the SoC-specific code. BUG=none TEST=Build pass, boot ok. Change-Id: Ic2914fd0fc85032c96ce076416e9b9c46fe19e0d Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90550 Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) Reviewed-by: Chen-Tsung Hsieh --- src/mainboard/google/rauru/mainboard.c | 8 -------- src/soc/mediatek/mt8196/soc.c | 14 +++++++++++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/mainboard/google/rauru/mainboard.c b/src/mainboard/google/rauru/mainboard.c index d0ed3ad7f7..93489426b8 100644 --- a/src/mainboard/google/rauru/mainboard.c +++ b/src/mainboard/google/rauru/mainboard.c @@ -7,13 +7,11 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -128,12 +126,6 @@ static void mainboard_init(struct device *dev) if (CONFIG(RAURU_SDCARD_INIT)) mtk_msdc_configure_sdcard(); - if (dpm_init()) - printk(BIOS_ERR, "dpm init failed, DVFS may not work\n"); - - if (spm_init()) - printk(BIOS_ERR, "spm init failed, Suspend may not work\n"); - if (CONFIG(ARM64_USE_ARM_TRUSTED_FIRMWARE)) register_reset_to_bl31(GPIO_AP_EC_WARM_RST_REQ.id, true); } diff --git a/src/soc/mediatek/mt8196/soc.c b/src/soc/mediatek/mt8196/soc.c index bacbe0c2c5..24077a0fbc 100644 --- a/src/soc/mediatek/mt8196/soc.c +++ b/src/soc/mediatek/mt8196/soc.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +56,7 @@ static void mte_setup(void) booker_mte_init(mte_start); } -static void soc_init(struct device *dev) +static void fsp_init(void) { uint32_t storage_type = mainboard_get_storage_type(); @@ -63,8 +65,18 @@ static void soc_init(struct device *dev) mtk_fsp_add_param(FSP_PARAM_TYPE_STORAGE, sizeof(storage_type), &storage_type); pi_image_add_mtk_fsp_params(); mtk_fsp_load_and_run(); +} +static void soc_init(struct device *dev) +{ mtk_mmu_disable_l2c_sram(); + + if (dpm_init()) + printk(BIOS_ERR, "dpm init failed, DVFS may not work\n"); + if (spm_init()) + printk(BIOS_ERR, "spm init failed, Suspend may not work\n"); + + fsp_init(); sspm_init(); gpueb_init(); mcupm_init(); From 61c9450d62aec2746ce1b4c24b9e7ca67cbd223b Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Fri, 19 Dec 2025 15:27:51 +0800 Subject: [PATCH 038/789] soc/mediatek/common: Pass dsi_regs to mtk_dsi_cphy_timing() Pass dsi_regs to mtk_dsi_cphy_timing() to be consistent with other DSI APIs and mtk_dsi_dphy_timing(). This also supports C-PHY with dual channel, although there is currently no such a device. BUG=b:424782827 TEST=emerge-tanjiro coreboot BRANCH=none Change-Id: I81805aa181c46fb29c70d18553dbf0c0c06c2888 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90558 Reviewed-by: Yidi Lin Tested-by: build bot (Jenkins) Reviewed-by: Chen-Tsung Hsieh --- src/soc/mediatek/common/dsi_common.c | 3 +-- src/soc/mediatek/common/include/soc/dsi_common.h | 3 ++- src/soc/mediatek/common/mtk_mipi_cphy.c | 11 ++++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/soc/mediatek/common/dsi_common.c b/src/soc/mediatek/common/dsi_common.c index 008817ade9..3ff8c5b049 100644 --- a/src/soc/mediatek/common/dsi_common.c +++ b/src/soc/mediatek/common/dsi_common.c @@ -481,8 +481,7 @@ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, mtk_dsi_reset(dsi); struct mtk_phy_timing phy_timing = {}; if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) - /* Dual channel is not implemented for CPHY. */ - mtk_dsi_cphy_timing(data_rate, &phy_timing); + mtk_dsi_cphy_timing(dsi, data_rate, &phy_timing); else mtk_dsi_dphy_timing(dsi, data_rate, &phy_timing); diff --git a/src/soc/mediatek/common/include/soc/dsi_common.h b/src/soc/mediatek/common/include/soc/dsi_common.h index 57961d10bb..626e8414b6 100644 --- a/src/soc/mediatek/common/include/soc/dsi_common.h +++ b/src/soc/mediatek/common/include/soc/dsi_common.h @@ -174,7 +174,8 @@ void mtk_dsi_override_phy_timing(struct mtk_phy_timing *timing); void mtk_dsi_cphy_enable(struct mipi_tx_regs *mipi_tx_reg); void mtk_dsi_cphy_enable_cmdq_6byte(struct dsi_regs *dsi_reg); void mtk_dsi_cphy_lane_sel_setting(struct mipi_tx_regs *mipi_tx_reg); -void mtk_dsi_cphy_timing(u32 data_rate, struct mtk_phy_timing *timing); +void mtk_dsi_cphy_timing(struct dsi_regs *dsi_reg, u32 data_rate, + struct mtk_phy_timing *timing); void mtk_dsi_cphy_vdo_timing(const u32 lanes, const struct edid *edid, const struct mtk_phy_timing *phy_timing, const u32 bytes_per_pixel, const u32 hbp, const u32 hfp, diff --git a/src/soc/mediatek/common/mtk_mipi_cphy.c b/src/soc/mediatek/common/mtk_mipi_cphy.c index 3e78376951..ecf7915f67 100644 --- a/src/soc/mediatek/common/mtk_mipi_cphy.c +++ b/src/soc/mediatek/common/mtk_mipi_cphy.c @@ -42,7 +42,8 @@ void mtk_dsi_cphy_enable_cmdq_6byte(struct dsi_regs *dsi_reg) clrbits32(&dsi_reg->dsi_cmd_type1_hs, CMD_CPHY_6BYTE_EN); } -void mtk_dsi_cphy_timing(u32 data_rate, struct mtk_phy_timing *timing) +void mtk_dsi_cphy_timing(struct dsi_regs *dsi_reg, u32 data_rate, + struct mtk_phy_timing *timing) { u32 cycle_time, value; @@ -72,14 +73,14 @@ void mtk_dsi_cphy_timing(u32 data_rate, struct mtk_phy_timing *timing) value = timing->lpx | timing->da_hs_prepare << 8 | timing->da_hs_zero << 16 | timing->da_hs_trail << 24; - write32(&dsi0->dsi_phy_timecon0, value); + write32(&dsi_reg->dsi_phy_timecon0, value); value = timing->ta_go | timing->ta_sure << 8 | timing->ta_get << 16 | timing->da_hs_exit << 24; - write32(&dsi0->dsi_phy_timecon1, value); + write32(&dsi_reg->dsi_phy_timecon1, value); - write32(&dsi0->dsi_cphy_con0, 0x012C0003); - write32(&dsi0->dsi_bllp_wc, 16 * 3); + write32(&dsi_reg->dsi_cphy_con0, 0x012C0003); + write32(&dsi_reg->dsi_bllp_wc, 16 * 3); } void mtk_dsi_cphy_vdo_timing(const u32 lanes, From 7d50f632133e28d00c4e217cde9f8ef50737b05e Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Fri, 19 Dec 2025 16:07:31 +0800 Subject: [PATCH 039/789] soc/mediatek: Drop mtk_ddp_soc_mode_set() We'd like to replace dsc_cfg->pic_width with edid->mode.ha in MT8196's dsc_configure_registers() and then deprecate the 'pic_width' field. To do that, we will first need to pass the edid struct pointer from mtk_ddp_mode_set() all the way to that function. Currently mtk_ddp_mode_set() is in the MediaTek common code, which calls SoC's mtk_ddp_soc_mode_set(), but the edid isn't passed. To simplify the edid pointer passing, drop mtk_ddp_soc_mode_set() and replace it with SoC's mtk_ddp_mode_set(). To minimize the duplicate code of calculating vrefresh, introduce mtk_get_vrefresh() to the display API, and reference it from SoC's code. BUG=b:424782827 TEST=emerge-tanjiro coreboot BRANCH=none Change-Id: Ifb84c6b954dde2f25c3ac491a5392b7725c13a43 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90559 Reviewed-by: Chen-Tsung Hsieh Tested-by: build bot (Jenkins) Reviewed-by: Yidi Lin --- src/soc/mediatek/common/display.c | 34 ++++++++----------- src/soc/mediatek/common/include/soc/display.h | 4 +-- src/soc/mediatek/mt8186/ddp.c | 11 ++++-- src/soc/mediatek/mt8188/ddp.c | 11 ++++-- src/soc/mediatek/mt8189/ddp.c | 11 ++++-- src/soc/mediatek/mt8195/ddp.c | 11 ++++-- src/soc/mediatek/mt8196/ddp.c | 11 ++++-- 7 files changed, 57 insertions(+), 36 deletions(-) diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c index 1f7277a0e6..52d6d808f7 100644 --- a/src/soc/mediatek/common/display.c +++ b/src/soc/mediatek/common/display.c @@ -184,12 +184,13 @@ int mtk_display_init(void) name = edid.ascii_string; if (name[0] == '\0') name = "unknown name"; - printk(BIOS_INFO, "%s: '%s %s' %dx%d@%dHz\n", __func__, - edid.manufacturer_name, name, edid.mode.ha, edid.mode.va, - edid.mode.refresh); edid_set_framebuffer_bits_per_pixel(&edid, 32, 0); + printk(BIOS_INFO, "%s: '%s %s' %dx%d@%dHz bpp %u\n", __func__, + edid.manufacturer_name, name, edid.mode.ha, edid.mode.va, + edid.mode.refresh, edid.framebuffer_bits_per_pixel / 8); + mtk_ddp_mode_set(&edid, panel->disp_path, dsc_config_var); if (panel->disp_path == DISP_PATH_EDP) { @@ -215,28 +216,23 @@ int mtk_display_init(void) return 0; } -void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, - struct dsc_config *dsc_config) +u32 mtk_get_vrefresh(const struct edid *edid) { - u32 fmt = OVL_INFMT_RGBA8888; - u32 bpp = edid->framebuffer_bits_per_pixel / 8; u32 width = edid->mode.ha; u32 height = edid->mode.va; u32 vrefresh = edid->mode.refresh; - printk(BIOS_DEBUG, "%s: display resolution: %ux%u@%u bpp %u\n", __func__, width, height, - vrefresh, bpp); + if (vrefresh) + return vrefresh; - if (!vrefresh) { - if (!width || !height) - vrefresh = 60; - else - vrefresh = edid->mode.pixel_clock * 1000 / - ((width + edid->mode.hbl) * (height + edid->mode.vbl)); + if (!width || !height) + vrefresh = 60; + else + vrefresh = edid->mode.pixel_clock * 1000 / + ((width + edid->mode.hbl) * (height + edid->mode.vbl)); - printk(BIOS_WARNING, "%s: vrefresh is not provided; using %u\n", __func__, - vrefresh); - } + printk(BIOS_WARNING, "%s: vrefresh is not provided; using %u\n", __func__, + vrefresh); - mtk_ddp_soc_mode_set(fmt, bpp, width, height, vrefresh, path, dsc_config); + return vrefresh; } diff --git a/src/soc/mediatek/common/include/soc/display.h b/src/soc/mediatek/common/include/soc/display.h index c71d15bb66..62ea9b0c23 100644 --- a/src/soc/mediatek/common/include/soc/display.h +++ b/src/soc/mediatek/common/include/soc/display.h @@ -4,6 +4,7 @@ #define __SOC_MEDIATEK_COMMON_DISPLAY_H__ #include +#include #include #include @@ -33,8 +34,7 @@ void mtk_display_disable_secure_mode(void); int mtk_display_init(void); void mtk_ddp_init(void); -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config); +u32 mtk_get_vrefresh(const struct edid *edid); void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, struct dsc_config *dsc_config); void mtk_ddp_ovlsys_start(uintptr_t fb_addr, const struct edid *edid, diff --git a/src/soc/mediatek/mt8186/ddp.c b/src/soc/mediatek/mt8186/ddp.c index df796fcba4..f1d17bc502 100644 --- a/src/soc/mediatek/mt8186/ddp.c +++ b/src/soc/mediatek/mt8186/ddp.c @@ -142,10 +142,15 @@ void mtk_ddp_init(void) write32((void *)(SMI_LARB0 + SMI_LARB_PORT_L0_OVL_RDMA0), 0); } -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, + struct dsc_config *dsc_config) { + u32 bpp = edid->framebuffer_bits_per_pixel / 8; + u32 width = edid->mode.ha; + u32 height = edid->mode.va; + u32 vrefresh = mtk_get_vrefresh(edid); + main_disp_path_setup(width, height, vrefresh); rdma_start(); - ovl_layer_config(fmt, bpp, width, height); + ovl_layer_config(OVL_INFMT_RGBA8888, bpp, width, height); } diff --git a/src/soc/mediatek/mt8188/ddp.c b/src/soc/mediatek/mt8188/ddp.c index dfc0de3217..b5d1227111 100644 --- a/src/soc/mediatek/mt8188/ddp.c +++ b/src/soc/mediatek/mt8188/ddp.c @@ -146,10 +146,15 @@ void mtk_ddp_init(void) write32p(SMI_LARB0 + SMI_LARB_PORT_L0_OVL_RDMA0, 0); } -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, + struct dsc_config *dsc_config) { + u32 bpp = edid->framebuffer_bits_per_pixel / 8; + u32 width = edid->mode.ha; + u32 height = edid->mode.va; + u32 vrefresh = mtk_get_vrefresh(edid); + main_disp_path_setup(width, height, vrefresh, path); rdma_start(); - ovl_layer_config(fmt, bpp, width, height); + ovl_layer_config(OVL_INFMT_RGBA8888, bpp, width, height); } diff --git a/src/soc/mediatek/mt8189/ddp.c b/src/soc/mediatek/mt8189/ddp.c index 6959fdbc1c..ec633a911e 100644 --- a/src/soc/mediatek/mt8189/ddp.c +++ b/src/soc/mediatek/mt8189/ddp.c @@ -138,10 +138,15 @@ void mtk_ddp_init(void) __func__, read32(&smi_larb0->port_l0_ovl_rdma[0])); } -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, + struct dsc_config *dsc_config) { + u32 bpp = edid->framebuffer_bits_per_pixel / 8; + u32 width = edid->mode.ha; + u32 height = edid->mode.va; + u32 vrefresh = mtk_get_vrefresh(edid); + main_disp_path_setup(width, height, vrefresh, path); rdma_start(); - ovl_layer_config(fmt, bpp, width, height); + ovl_layer_config(OVL_INFMT_RGBA8888, bpp, width, height); } diff --git a/src/soc/mediatek/mt8195/ddp.c b/src/soc/mediatek/mt8195/ddp.c index 28fc34b68d..e84be64021 100644 --- a/src/soc/mediatek/mt8195/ddp.c +++ b/src/soc/mediatek/mt8195/ddp.c @@ -151,11 +151,16 @@ void mtk_ddp_init(void) write32((void *)(SMI_LARB0 + SMI_LARB_PORT_L0_OVL_RDMA0), 0); } -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, + struct dsc_config *dsc_config) { + u32 bpp = edid->framebuffer_bits_per_pixel / 8; + u32 width = edid->mode.ha; + u32 height = edid->mode.va; + u32 vrefresh = mtk_get_vrefresh(edid); + main_disp_path_setup(width, height, vrefresh); rdma_start(); - ovl_layer_config(fmt, bpp, width, height); + ovl_layer_config(OVL_INFMT_RGBA8888, bpp, width, height); ovl_bgclr_in_sel(1); } diff --git a/src/soc/mediatek/mt8196/ddp.c b/src/soc/mediatek/mt8196/ddp.c index 012c6c9b3b..78255fb856 100644 --- a/src/soc/mediatek/mt8196/ddp.c +++ b/src/soc/mediatek/mt8196/ddp.c @@ -685,14 +685,19 @@ void mtk_ddp_init(void) disp_clock_on(); } -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, + struct dsc_config *dsc_config) { + u32 bpp = edid->framebuffer_bits_per_pixel / 8; + u32 width = edid->mode.ha; + u32 height = edid->mode.va; + u32 vrefresh = mtk_get_vrefresh(edid); + if (width > 0x1FFF || height > 0x1FFF) printk(BIOS_WARNING, "%s: w/h: %d/%d exceed hw limit %u\n", __func__, width, height, 0x1FFF); main_disp_path_setup(width, height, vrefresh, path, dsc_config); - ovlsys_layer_config(fmt, bpp, width, height, path); + ovlsys_layer_config(OVL_INFMT_RGBA8888, bpp, width, height, path); } void mtk_ddp_ovlsys_start(uintptr_t fb_addr, const struct edid *edid, From 456403d9ba38bf156ae6c1d3dc072f30a523785c Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Fri, 19 Dec 2025 16:22:06 +0800 Subject: [PATCH 040/789] soc/mediatek/mt8196: Stop using dsc_config.pic_width The pic_width and pic_height in the dsc_config struct are equivalent to edid.mode.ha and edid.mode.va. The duplicate information should be removed from the panel_serializable_data struct, by removing from dsc_config. To do that, replace references of dsc_config.pic_width with edid.mode.ha in the MT8196 code. BUG=b:424782827 TEST=emerge-tanjiro coreboot BRANCH=none Change-Id: Id1014886851a999ccdfec7ec86df2e7341ba9ffd Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90560 Reviewed-by: Chen-Tsung Hsieh Tested-by: build bot (Jenkins) Reviewed-by: Yidi Lin --- src/soc/mediatek/mt8196/ddp.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/soc/mediatek/mt8196/ddp.c b/src/soc/mediatek/mt8196/ddp.c index 78255fb856..5c4366a80e 100644 --- a/src/soc/mediatek/mt8196/ddp.c +++ b/src/soc/mediatek/mt8196/ddp.c @@ -69,8 +69,10 @@ static const struct disp_pipe_regs disp_pipe1_regs = { }; static void dsc_configure_registers(struct disp_dsc_regs *reg, u16 w, u16 h, - const struct dsc_config *dsc_cfg) + const struct dsc_config *dsc_cfg, + const struct edid *edid) { + u32 pic_width = edid->mode.ha; u32 init_delay_limit, init_delay_height; u32 pic_group_width, pic_height_ext_num; u32 slice_group_width; @@ -84,11 +86,11 @@ static void dsc_configure_registers(struct disp_dsc_regs *reg, u16 w, u16 h, if (dsc_cfg->bits_per_component == 0xA) dsc_cfg_mode = 0x828; - assert(dsc_cfg->pic_width > 0); - assert(dsc_cfg->pic_width >= dsc_cfg->slice_width); + assert(pic_width > 0); + assert(pic_width >= dsc_cfg->slice_width); assert(dsc_cfg->slice_width > 0); - slice_mode = dsc_cfg->pic_width / dsc_cfg->slice_width - 1; - pic_group_width = DIV_ROUND_UP(dsc_cfg->pic_width, 3); + slice_mode = pic_width / dsc_cfg->slice_width - 1; + pic_group_width = DIV_ROUND_UP(pic_width, 3); pic_height_ext_num = DIV_ROUND_UP(h, dsc_cfg->slice_height); slice_group_width = DIV_ROUND_UP(dsc_cfg->slice_width, 3); pad_num = ALIGN_PADDING(dsc_cfg->slice_chunk_size * (slice_mode + 1), 3); @@ -139,7 +141,7 @@ static void dsc_configure_registers(struct disp_dsc_regs *reg, u16 w, u16 h, val = pad_num; clrsetbits32(®->dsc_pad, mask, val); - val = dsc_cfg->slice_width | dsc_cfg->pic_width << 16; + val = dsc_cfg->slice_width | pic_width << 16; write32(®->dsc_enc_width, val); mask = DSC_PIC_PREPAD_HEIGHT_SEL | DSC_PIC_PREPAD_WIDTH_SEL; @@ -288,7 +290,8 @@ static void dsc_configure_registers(struct disp_dsc_regs *reg, u16 w, u16 h, } static void dsc_config(struct disp_dsc_regs *reg, u16 w, u16 h, - const struct dsc_config *dsc_cfg) + const struct dsc_config *dsc_cfg, + const struct edid *edid) { bool dsc_enable; @@ -304,7 +307,7 @@ static void dsc_config(struct disp_dsc_regs *reg, u16 w, u16 h, return; } - dsc_configure_registers(reg, w, h, dsc_cfg); + dsc_configure_registers(reg, w, h, dsc_cfg, edid); } static void blender_config(struct blender *reg, u16 width, u16 height, @@ -581,7 +584,7 @@ static void disp_config_blender(struct blender *const blenders[], size_t size, u } static void main_disp_path_setup(u16 width, u16 height, u32 vrefresh, enum disp_path_sel path, - const struct dsc_config *dsc_cfg) + const struct dsc_config *dsc_cfg, const struct edid *edid) { u16 w = width; size_t num_pipe = DUAL_PIPE(path) ? 2 : 1; @@ -617,7 +620,7 @@ static void main_disp_path_setup(u16 width, u16 height, u32 vrefresh, enum disp_ postmask_start(pipes[i].postmask); dither_config(pipes[i].dither, w, height); dither_start(pipes[i].dither); - dsc_config(pipes[i].dsc, w, height, dsc_cfg); + dsc_config(pipes[i].dsc, w, height, dsc_cfg, edid); dsc_start(pipes[i].dsc); } @@ -696,7 +699,7 @@ void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, if (width > 0x1FFF || height > 0x1FFF) printk(BIOS_WARNING, "%s: w/h: %d/%d exceed hw limit %u\n", __func__, width, height, 0x1FFF); - main_disp_path_setup(width, height, vrefresh, path, dsc_config); + main_disp_path_setup(width, height, vrefresh, path, dsc_config, edid); ovlsys_layer_config(OVL_INFMT_RGBA8888, bpp, width, height, path); } From e6c3250912da6bff5c5bc310e775abc6efa689ce Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Fri, 19 Dec 2025 15:51:39 +0800 Subject: [PATCH 041/789] mipi/panel: Remove pic_width and pic_height from dsc_config The pic_width and pic_height fields of dsc_config are equivalent to edid.mode.ha and edid.mode.va, respectively. To remove duplicate information in panel_serializable_data, remove these two fields from dsc_config. BUG=b:424782827 TEST=emerge-tanjiro coreboot BRANCH=none Change-Id: I7f1dd4b431a610fa928b29da420b0c0e0bef5fcc Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90561 Reviewed-by: Yidi Lin Reviewed-by: Chen-Tsung Hsieh Tested-by: build bot (Jenkins) --- src/drivers/mipi/panel-BOE_NS130069_M00.c | 2 -- src/include/mipi/panel.h | 8 -------- 2 files changed, 10 deletions(-) diff --git a/src/drivers/mipi/panel-BOE_NS130069_M00.c b/src/drivers/mipi/panel-BOE_NS130069_M00.c index 2e2accebfa..cf36af8648 100644 --- a/src/drivers/mipi/panel-BOE_NS130069_M00.c +++ b/src/drivers/mipi/panel-BOE_NS130069_M00.c @@ -576,8 +576,6 @@ struct panel_serializable_data BOE_NS130069_M00 = { .convert_rgb = 1, .simple_422 = false, .bits_per_pixel = 8 << 4, - .pic_height = 2190, - .pic_width = 3504, .slice_height = 30, .slice_width = 876, .slice_chunk_size = 876, diff --git a/src/include/mipi/panel.h b/src/include/mipi/panel.h index d306f06fb4..e2123a6e22 100644 --- a/src/include/mipi/panel.h +++ b/src/include/mipi/panel.h @@ -85,14 +85,6 @@ struct dsc_config { * @slice_height: Slice height in pixels */ u16 slice_height; - /* - * @pic_width: Width of the input display frame in pixels - */ - u16 pic_width; - /* - * @pic_height: Vertical height of the input display frame - */ - u16 pic_height; /* * @rc_tgt_offset_high: * Offset to bits/group used by RC to determine QP adjustment From 94b326469baf5b2a993e37f6c3acf50fe16b4951 Mon Sep 17 00:00:00 2001 From: Venkateshwar S Date: Sun, 21 Dec 2025 22:38:26 -0800 Subject: [PATCH 042/789] mb/google/bluey: Increase FW_MAIN_A/B slot size to 8.5MB This patch increases the size of the FW_MAIN_A and FW_MAIN_B slots to 8.5MB to accommodate APDP, Ramdump and ADSP-lite images. A 5MB estimated size of QTEE image is also taken into account to avoid future resizing. Size required for QTEE: Current size -> 2776K, Estimated size -> 5120K (5MB) Additional size needed -> 5120K-2776K = 2344K Size required for new images: Ramdump - 449K APDP - 0.7K ramdump_meta - 0.1K apdp_meta - 1.4K ADSP_Lite - 1192K Total = 1643K Additional size needed (QTEE + new images): 2344K+1643K = 3987K Current Layout of FW_MAIN_A/B slots: Total size - 4608K (4.5MB) Used size - 4126K Free size - 482K Additional size needed (excluding free size): 3987K-482K = 3505K Total size of FW_MAIN_A/B slots: 4608K+3505K = 8133K An additional buffer of 591K is included in the final size to provide room for increase in size of other blobs. So, Final size of FW_MAIN_A/B slots: 8133K+591K = 8704K (8.5MB). TEST=Create an image.serial.bin and ensure it boots on X1P42100. Change-Id: I3b3ba5c4bf8b5d3830174a890ea7cd089e3f274f Signed-off-by: Venkateshwar S Reviewed-on: https://review.coreboot.org/c/coreboot/+/90594 Reviewed-by: Subrata Banik Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/chromeos-nogsc.fmd | 4 ++-- src/mainboard/google/bluey/chromeos.fmd | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mainboard/google/bluey/chromeos-nogsc.fmd b/src/mainboard/google/bluey/chromeos-nogsc.fmd index aa6b996b3a..6ffe1d335c 100644 --- a/src/mainboard/google/bluey/chromeos-nogsc.fmd +++ b/src/mainboard/google/bluey/chromeos-nogsc.fmd @@ -25,13 +25,13 @@ FLASH@0x0 CONFIG_ROM_SIZE { RW_NVRAM(PRESERVE) 16K } - RW_SECTION_A 4608K { + RW_SECTION_A 8704K { VBLOCK_A 8K FW_MAIN_A(CBFS) RW_FWID_A 256 } - RW_SECTION_B 4608K { + RW_SECTION_B 8704K { VBLOCK_B 8K FW_MAIN_B(CBFS) RW_FWID_B 256 diff --git a/src/mainboard/google/bluey/chromeos.fmd b/src/mainboard/google/bluey/chromeos.fmd index 98f03b5851..01a2331b22 100644 --- a/src/mainboard/google/bluey/chromeos.fmd +++ b/src/mainboard/google/bluey/chromeos.fmd @@ -26,13 +26,13 @@ FLASH@0x0 CONFIG_ROM_SIZE { RW_NVRAM(PRESERVE) 16K } - RW_SECTION_A 4608K { + RW_SECTION_A 8704K { VBLOCK_A 8K FW_MAIN_A(CBFS) RW_FWID_A 256 } - RW_SECTION_B 4608K { + RW_SECTION_B 8704K { VBLOCK_B 8K FW_MAIN_B(CBFS) RW_FWID_B 256 From bb3f40627d8368daf1c27c40ee7d3bb267c67eab Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sun, 21 Dec 2025 19:14:17 +0100 Subject: [PATCH 043/789] util/autoport: Fix style issue in generated code Checkpatch emits the following warning about autoport-generated code: WARNING: space prohibited between function name and open parenthesis '(' So, simply get rid of that space. Change-Id: If52e3d56c6b254efb61c70c8e482014dd4208172 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/90584 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Nicholas Reviewed-by: Paul Menzel --- util/autoport/ec_fixme.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/autoport/ec_fixme.go b/util/autoport/ec_fixme.go index e0a6554016..17c431c65e 100644 --- a/util/autoport/ec_fixme.go +++ b/util/autoport/ec_fixme.go @@ -55,7 +55,7 @@ Method(_PTS,1) MainboardInit += ` printk(BIOS_DEBUG, "Replaying EC dump ..."); for (i = 0; i < 256; i++) - ec_write (i, dmp[i]); + ec_write(i, dmp[i]); printk(BIOS_DEBUG, "done\n"); } ` From dc68f5b265e4c6d96547f6e6da31763a91b6eddc Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 6 Nov 2025 11:28:09 -0800 Subject: [PATCH 044/789] soc/intel/pantherlake: Let common code set PL1 to TDP Update PL1 override values from a fixed value to zero, indicating that the platform should use the default TDP value. This change allows the common code to dynamically set PL1 according to the specific TDP SKU, improving flexibility and ensuring correct power limit configuration across different hardware variants. Previously, PL1 was hardcoded to 15 for some SKUs, which could lead to instabilities for SKUs with different TDP requirements. TEST=No instability was observed on certain Fatcat SKUs. Change-Id: Ibfb6b52aa15ad66740abc39f6f869dfa5e90de3c Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/89934 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora Reviewed-by: Ryu, Jamie M Reviewed-by: Kim, Wonkyu --- src/soc/intel/pantherlake/chipset_ptl.cb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index e646c5dc4e..ccd727d6cd 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -3,7 +3,7 @@ chip soc/intel/pantherlake device cpu_cluster 0 on end register "power_limits_config[PTL_CORE_1]" = "{ - .tdp_pl1_override = 15, + .tdp_pl1_override = 0, /* Use TDP */ .tdp_pl2_override = 55, .tdp_pl4 = 163, .tdp_pl4_fastvmode = 150, @@ -24,7 +24,7 @@ chip soc/intel/pantherlake }" register "power_limits_config[PTL_CORE_2]" = "{ - .tdp_pl1_override = 15, + .tdp_pl1_override = 0, /* Use TDP */ .tdp_pl2_override = 55, .tdp_pl4 = 163, .tdp_pl4_fastvmode = 150, @@ -37,7 +37,7 @@ chip soc/intel/pantherlake }" register "power_limits_config[PTL_CORE_3]" = "{ - .tdp_pl1_override = 25, + .tdp_pl1_override = 0, /* Use TDP */ .tdp_pl2_override = 65, .tdp_pl4 = 175, .tdp_pl4_fastvmode = 160, @@ -58,7 +58,7 @@ chip soc/intel/pantherlake }" register "power_limits_config[PTL_CORE_4]" = "{ - .tdp_pl1_override = 25, + .tdp_pl1_override = 0, /* Use TDP */ .tdp_pl2_override = 65, .tdp_pl4 = 160, .tdp_pl4_fastvmode = 140 From 1dfa80f02cbfd9ce49e18a9e4e18799d7c0b642c Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Fri, 21 Nov 2025 12:13:28 -0800 Subject: [PATCH 045/789] soc/intel/pantherlake: Add configurable TDP support This commit introduces a mechanism to configure the Thermal Design Power (TDP) for Panther Lake, allowing board designers to override the default TDP reported by hardware and select the value that matches their specific board requirements. Previously, the TDP value was determined solely by the hardware, which limited flexibility for platforms that support multiple TDP options. By adding a new field to the `soc_intel_pantherlake_config` structure and implementing the `soc_get_cpu_tdp()` function, this change enables boards to opt out of the default TDP and specify a custom value. BUG=b:465698900 Change-Id: I6e401c2c7d7d0cda24fa07ec024813874fac3ed5 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/90150 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/Makefile.mk | 2 ++ src/soc/intel/pantherlake/chip.h | 9 +++++++++ src/soc/intel/pantherlake/romstage/fsp_params.c | 3 ++- src/soc/intel/pantherlake/systemagent.c | 6 ++++-- src/soc/intel/pantherlake/tdp.c | 12 ++++++++++++ src/soc/intel/pantherlake/tdp.h | 10 ++++++++++ 6 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 src/soc/intel/pantherlake/tdp.c create mode 100644 src/soc/intel/pantherlake/tdp.h diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index 6476bf6e36..ab118c5055 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -24,6 +24,7 @@ romstage-y += espi.c romstage-y += meminit.c romstage-y += pcie_rp.c romstage-y += reset.c +romstage-y += tdp.c ramstage-y += acpi.c ramstage-y += cbfs_preload.c @@ -43,6 +44,7 @@ ramstage-y += retimer.c ramstage-y += soundwire.c ramstage-y += systemagent.c ramstage-y += tcss.c +ramstage-y += tdp.c ramstage-y += xhci.c ramstage-$(CONFIG_DRIVERS_INTEL_TOUCH) += touch.c diff --git a/src/soc/intel/pantherlake/chip.h b/src/soc/intel/pantherlake/chip.h index d383d63fa5..1301813aaf 100644 --- a/src/soc/intel/pantherlake/chip.h +++ b/src/soc/intel/pantherlake/chip.h @@ -485,6 +485,15 @@ struct soc_intel_pantherlake_config { uint16_t ps2_threshold[NUM_VR_DOMAINS]; uint16_t ps3_threshold[NUM_VR_DOMAINS]; + /* + * Thermal Design Power setting. + * + * Certain Panther Lake SKUs are compatible with multiple TDP options. For these + * SKUs, the following field can be set to choose the TDP that best fits the + * board's power and thermal requirements. + */ + enum soc_intel_pantherlake_cpu_tdps tdp; + /* * SerialIO device mode selection: * PchSerialIoDisabled, diff --git a/src/soc/intel/pantherlake/romstage/fsp_params.c b/src/soc/intel/pantherlake/romstage/fsp_params.c index 63a3f3b013..46458af5ce 100644 --- a/src/soc/intel/pantherlake/romstage/fsp_params.c +++ b/src/soc/intel/pantherlake/romstage/fsp_params.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "ux.h" @@ -321,7 +322,7 @@ static const struct soc_intel_pantherlake_power_map *get_map(const struct soc_in return NULL; } - uint8_t tdp = get_cpu_tdp(); + enum soc_intel_pantherlake_cpu_tdps tdp = soc_get_cpu_tdp(); for (size_t i = 0; i < ARRAY_SIZE(cpuid_to_ptl); i++) { const struct soc_intel_pantherlake_power_map *current = &cpuid_to_ptl[i]; if (current->cpu_id == sa_pci_id && current->cpu_tdp == tdp) diff --git a/src/soc/intel/pantherlake/systemagent.c b/src/soc/intel/pantherlake/systemagent.c index 82e5d244c7..c1a081cb1b 100644 --- a/src/soc/intel/pantherlake/systemagent.c +++ b/src/soc/intel/pantherlake/systemagent.c @@ -16,6 +16,7 @@ #include #include #include +#include /* * SoC implementation @@ -145,7 +146,7 @@ static void configure_tdp(struct device *dev) struct soc_power_limits_config *soc_config; struct device *sa; uint16_t sa_pci_id; - u8 tdp; + enum soc_intel_pantherlake_cpu_tdps tdp; size_t i; bool config_tdp = false; struct soc_intel_pantherlake_config *config; @@ -161,7 +162,7 @@ static void configure_tdp(struct device *dev) return; } - tdp = get_cpu_tdp(); + tdp = soc_get_cpu_tdp(); /* * Choose power limits configuration based on the CPU SA PCI ID and @@ -174,6 +175,7 @@ static void configure_tdp(struct device *dev) if (config->enable_fast_vmode[VR_DOMAIN_IA] && soc_config->tdp_pl4_fastvmode) soc_config->tdp_pl4 = soc_config->tdp_pl4_fastvmode; + soc_config->tdp_pl1_override = tdp; set_power_limits(MOBILE_SKU_PL1_TIME_SEC, soc_config); config_tdp = true; printk(BIOS_DEBUG, "Configured power limits for SA PCI ID: 0x%4x\n", diff --git a/src/soc/intel/pantherlake/tdp.c b/src/soc/intel/pantherlake/tdp.c new file mode 100644 index 0000000000..e73370a69f --- /dev/null +++ b/src/soc/intel/pantherlake/tdp.c @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +enum soc_intel_pantherlake_cpu_tdps soc_get_cpu_tdp(void) +{ + const struct soc_intel_pantherlake_config *config = config_of_soc(); + return config->tdp || get_cpu_tdp(); +} diff --git a/src/soc/intel/pantherlake/tdp.h b/src/soc/intel/pantherlake/tdp.h new file mode 100644 index 0000000000..46f5188a24 --- /dev/null +++ b/src/soc/intel/pantherlake/tdp.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_PANTHERLAKE_TDP_H_ +#define _SOC_PANTHERLAKE_TDP_H_ + +#include + +enum soc_intel_pantherlake_cpu_tdps soc_get_cpu_tdp(void); + +#endif /* _SOC_PANTHERLAKE_TDP_H_ */ From 3f00ecb05c3aabacc89b860bf63fc2356f2c6711 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 4 Dec 2025 15:28:54 -0800 Subject: [PATCH 046/789] soc/intel/pantherlake: Add ChromeOS board-specific TDP setting This commit introduces ChromeOS-specific logic to the Panther Lake SoC TDP selection. It addresses the need to correctly set the CPU TDP to 15 W without having to set the desired_tdp flag in each mainboard device tree. BUG=b:465698900 Change-Id: Ibaee530159f7e3b94aac16ab50b749cb161cee10 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/90373 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/soc/intel/pantherlake/tdp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/soc/intel/pantherlake/tdp.c b/src/soc/intel/pantherlake/tdp.c index e73370a69f..63b3072499 100644 --- a/src/soc/intel/pantherlake/tdp.c +++ b/src/soc/intel/pantherlake/tdp.c @@ -7,6 +7,19 @@ enum soc_intel_pantherlake_cpu_tdps soc_get_cpu_tdp(void) { + if (CONFIG(MAINBOARD_HAS_CHROMEOS)) { + const unsigned int variable_tdp_mch_ids[] = { + PCI_DID_INTEL_PTL_U_ID_1, + PCI_DID_INTEL_PTL_U_ID_2, + PCI_DID_INTEL_PTL_U_ID_3 + }; + uint16_t mch_id = pci_read_config16(_PCI_DEV(ROOT, 0), PCI_DEVICE_ID); + + for (size_t i = 0; i < ARRAY_SIZE(variable_tdp_mch_ids); i++) + if (variable_tdp_mch_ids[i] == mch_id) + return TDP_15W; + } + const struct soc_intel_pantherlake_config *config = config_of_soc(); return config->tdp || get_cpu_tdp(); } From 75333ea7c8497457bab92ce1df01d06a6408caaa Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Mon, 22 Dec 2025 19:19:33 +0530 Subject: [PATCH 047/789] mb/google/bluey: Refactor is_pd_sync_required function BUG=none TEST=Verify boot on Google/Quenbi. Change-Id: Ic2f779d963105ef24b9cae3747ac7cc78ec9ae8b Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90596 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/romstage.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index e21777b715..dbfda5511e 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -55,11 +55,11 @@ static bool is_pd_sync_required(void) EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)); uint64_t ec_events = google_chromeec_get_events_b(); - if (!(ec_events & manual_pwron_event_mask) && - (ec_events & EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED))) - return true; + if (!(ec_events & EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED))) + return false; - if (google_chromeec_is_below_critical_threshold() || !google_chromeec_is_battery_present()) + if (!(ec_events & manual_pwron_event_mask) || + google_chromeec_is_below_critical_threshold() || !google_chromeec_is_battery_present()) return true; return false; From 7d38a96c44c9d97550f7f8e1ad379490fed6d037 Mon Sep 17 00:00:00 2001 From: Frank Wu Date: Mon, 22 Dec 2025 18:45:19 +0800 Subject: [PATCH 048/789] mb/google/skywalker: Create variant Vader Create the variant Vader. BUG=b:470833369 TEST=emerge-skywalker coreboot BRANCH=skywalker Change-Id: I92ace678b9b9206c36ed147426699cef6510b210 Signed-off-by: Frank Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90595 Reviewed-by: Dtrain Hsu Reviewed-by: Yu-Ping Wu Reviewed-by: Chen-Tsung Hsieh Tested-by: build bot (Jenkins) Reviewed-by: Yidi Lin --- src/mainboard/google/skywalker/Kconfig | 2 ++ src/mainboard/google/skywalker/Kconfig.name | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/mainboard/google/skywalker/Kconfig b/src/mainboard/google/skywalker/Kconfig index 6e8848af94..6556acae99 100644 --- a/src/mainboard/google/skywalker/Kconfig +++ b/src/mainboard/google/skywalker/Kconfig @@ -10,6 +10,7 @@ config BOARD_GOOGLE_SKYWALKER_COMMON BOARD_GOOGLE_PADME || \ BOARD_GOOGLE_SKYWALKER || \ BOARD_GOOGLE_TARKIN || \ + BOARD_GOOGLE_VADER || \ BOARD_GOOGLE_YODA if BOARD_GOOGLE_SKYWALKER_COMMON @@ -59,6 +60,7 @@ config MAINBOARD_PART_NUMBER default "Padme" if BOARD_GOOGLE_PADME default "Skywalker" if BOARD_GOOGLE_SKYWALKER default "Tarkin" if BOARD_GOOGLE_TARKIN + default "Vader" if BOARD_GOOGLE_VADER default "Yoda" if BOARD_GOOGLE_YODA config BOOT_DEVICE_SPI_FLASH_BUS diff --git a/src/mainboard/google/skywalker/Kconfig.name b/src/mainboard/google/skywalker/Kconfig.name index 258c8bd633..6f787c72b9 100644 --- a/src/mainboard/google/skywalker/Kconfig.name +++ b/src/mainboard/google/skywalker/Kconfig.name @@ -26,5 +26,8 @@ config BOARD_GOOGLE_SKYWALKER config BOARD_GOOGLE_TARKIN bool "-> Tarkin" +config BOARD_GOOGLE_VADER + bool "-> Vader" + config BOARD_GOOGLE_YODA bool "-> Yoda" From 331e93cbd23b5000e97b96592300bb615f913bed Mon Sep 17 00:00:00 2001 From: Felix Singer Date: Tue, 23 Dec 2025 18:53:22 +0100 Subject: [PATCH 049/789] libpayload/tests: Disable generation of lcov HTML Commit de4148888c9c ("tests: Disable generation of lcov HTML") only disabled the HTML generation for the coreboot tests, but not for libpayload tests. So do it here as well. Change-Id: I35458345c81de8b9936a17bb6fb5670b29a6d05e Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/90608 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- payloads/libpayload/tests/Makefile.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/payloads/libpayload/tests/Makefile.mk b/payloads/libpayload/tests/Makefile.mk index a6cee5f480..6b6c78d835 100644 --- a/payloads/libpayload/tests/Makefile.mk +++ b/payloads/libpayload/tests/Makefile.mk @@ -274,7 +274,8 @@ clean-junit.xml-unit-tests: ifeq ($(COV),1) coverage-report: lcov -o $(testobj)/tests.info -c -d $(testobj) --exclude '$(testsrc)/*' - genhtml -q -o $(coverage-dir) -t "coreboot unit tests" -s $(testobj)/tests.info + # TODO: figure out issues with inconsistent and corrupt data + # genhtml -q -o $(coverage-dir) -t "coreboot unit tests" -s $(testobj)/tests.info clean-coverage-report: rm -Rf $(coverage-dir) From 531c24cd0a53f2b9383af12b9f64c8f63a3e954b Mon Sep 17 00:00:00 2001 From: Zhaoming Luo Date: Mon, 22 Dec 2025 21:36:56 +0800 Subject: [PATCH 050/789] Documentation: Fix typo in 'particularly' Correct 'particullary' to 'particularly'. Change-Id: I6a4b78db143298b1b60106031fdd5d698ccf1e32 Signed-off-by: Zhaoming Luo Reviewed-on: https://review.coreboot.org/c/coreboot/+/90605 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Felix Singer --- Documentation/getting_started/architecture.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/getting_started/architecture.md b/Documentation/getting_started/architecture.md index 8910d775f7..1f360d0486 100644 --- a/Documentation/getting_started/architecture.md +++ b/Documentation/getting_started/architecture.md @@ -41,7 +41,7 @@ The bootblock loads the romstage or the verstage if verified boot is enabled. ### Cache-As-Ram The *Cache-As-Ram*, also called Non-Eviction mode, or *CAR* allows to use the -CPU cache like regular SRAM. This is particullary useful for high level +CPU cache like regular SRAM. This is particularly useful for high level languages like `C`, which need RAM for heap and stack. The CAR needs to be activated using vendor specific CPU instructions. From c093b52c20501a5ae3ddb5651b1effb5fc6598f6 Mon Sep 17 00:00:00 2001 From: Payne Lin Date: Wed, 24 Dec 2025 15:47:37 +0800 Subject: [PATCH 051/789] soc/mediatek: Correct BIAS_ON value to get bias ready Fix the value of BIAS_POWER_ON in the MT8189 dptx_reg.h file, by changing it from 0x01 to 0x03. The MT8189 needs to enable one more power register bit to make bias work rather than timeout. BUG=b:461384417 TEST=Boot up can see develop mode. BRANCH=skywalker Signed-off-by: Payne Lin Change-Id: I345b23af0b5802e71d6d7bcd3fe806aaa71cc3cc Reviewed-on: https://review.coreboot.org/c/coreboot/+/90613 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu Reviewed-by: Yidi Lin --- src/soc/mediatek/common/dp/include/soc/dptx_reg_v2.h | 1 - src/soc/mediatek/mt8189/include/soc/dptx_reg.h | 1 + src/soc/mediatek/mt8196/include/soc/dptx_reg.h | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/soc/mediatek/common/dp/include/soc/dptx_reg_v2.h b/src/soc/mediatek/common/dp/include/soc/dptx_reg_v2.h index da0654ab9d..d1f4f411ef 100644 --- a/src/soc/mediatek/common/dp/include/soc/dptx_reg_v2.h +++ b/src/soc/mediatek/common/dp/include/soc/dptx_reg_v2.h @@ -157,7 +157,6 @@ #define REG_3F44_DP_ENC_4P_3 0x3F44 #define PHY_PWR_STATE_OW_EN_DP_ENC_4P_3 BIT(2) #define PHY_PWR_STATE_OW_EN_DP_ENC_4P_3_MASK BIT(2) -#define BIAS_POWER_ON (0x01 << 3) #define PHY_PWR_STATE_OW_VALUE_DP_ENC_4P_3_MASK GENMASK(4, 3) #define REG_3F80_DP_ENC_4P_3 0x3F80 #define PSR_PATGEN_AVT_EN_FLDMASK 0x20 diff --git a/src/soc/mediatek/mt8189/include/soc/dptx_reg.h b/src/soc/mediatek/mt8189/include/soc/dptx_reg.h index af2e6a131e..b65d6c2bed 100644 --- a/src/soc/mediatek/mt8189/include/soc/dptx_reg.h +++ b/src/soc/mediatek/mt8189/include/soc/dptx_reg.h @@ -5,6 +5,7 @@ #include +#define BIAS_POWER_ON (0x03 << 3) #define DP_PHY_DIG_TX_CTL_0 0x1444 #define RGS_AUX_LDO_EN_READY_MASK BIT(0) #define DRIVING_FORCE 0x18 diff --git a/src/soc/mediatek/mt8196/include/soc/dptx_reg.h b/src/soc/mediatek/mt8196/include/soc/dptx_reg.h index df7a29630a..a26328dd24 100644 --- a/src/soc/mediatek/mt8196/include/soc/dptx_reg.h +++ b/src/soc/mediatek/mt8196/include/soc/dptx_reg.h @@ -5,6 +5,7 @@ #include +#define BIAS_POWER_ON (0x01 << 3) #define DP_PHY_DIG_TX_CTL_0 0x1474 #define RGS_AUX_LDO_EN_READY_MASK BIT(1) #define DRIVING_FORCE 0x30 From aeb9dcf2fab17ebcb7ddc2f28c39ccd3ab8169d0 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Wed, 24 Dec 2025 15:23:28 +0800 Subject: [PATCH 052/789] libpayload: Add new memory type CB_MEM_TAG Add new memory type CB_MEM_TAG to coreboot_tables.h. This definition was missing when CB:90470 was instroduced. Change-Id: I76990706649bc1a4e45478760446dff40e871d77 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90612 Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- payloads/libpayload/include/coreboot_tables.h | 1 + 1 file changed, 1 insertion(+) diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h index 2f5b9be228..89b0dbc0a4 100644 --- a/payloads/libpayload/include/coreboot_tables.h +++ b/payloads/libpayload/include/coreboot_tables.h @@ -121,6 +121,7 @@ struct cb_memory_range { #define CB_MEM_NVS 4 #define CB_MEM_UNUSABLE 5 #define CB_MEM_VENDOR_RSVD 6 +#define CB_MEM_TAG 7 #define CB_MEM_TABLE 16 struct cb_memory { From f24a2f35bfa3c3adb1b11c17ddc1e5ce0d6110fd Mon Sep 17 00:00:00 2001 From: Walter Sonius Date: Thu, 25 Dec 2025 11:33:35 +0100 Subject: [PATCH 053/789] mb/asrock: Correct vendor name ASROCK to ASRock Both ASRock H110 Pro BTC+ and ASRock Q1900-ITX have their vendor name spelled as ASRock listed by Memtest86+ when ran on their OEM BIOS. This patch will restore that vendor name casing behaviour when Memtest86+ is run from a corebooted port of these mainboards. Cannot verify for the current mainboards in the repository but this casing is also consistent with the casing used on the vendor website: www.asrock.com Change-Id: Icca8a0c0cba4e093a64cc26996de1fb34ee60089 Signed-off-by: Walter Sonius Reviewed-on: https://review.coreboot.org/c/coreboot/+/90623 Tested-by: build bot (Jenkins) Reviewed-by: Felix Singer --- src/mainboard/asrock/Kconfig | 2 +- src/mainboard/asrock/Kconfig.name | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/asrock/Kconfig b/src/mainboard/asrock/Kconfig index 3fe439728d..ddbe9f5b0e 100644 --- a/src/mainboard/asrock/Kconfig +++ b/src/mainboard/asrock/Kconfig @@ -12,6 +12,6 @@ endchoice source "src/mainboard/asrock/*/Kconfig" config MAINBOARD_VENDOR - default "ASROCK" + default "ASRock" endif # VENDOR_ASROCK diff --git a/src/mainboard/asrock/Kconfig.name b/src/mainboard/asrock/Kconfig.name index a04cd2707b..c19475ee00 100644 --- a/src/mainboard/asrock/Kconfig.name +++ b/src/mainboard/asrock/Kconfig.name @@ -1,4 +1,4 @@ ## SPDX-License-Identifier: GPL-2.0-only config VENDOR_ASROCK - bool "ASROCK" + bool "ASRock" From ffac7d90dae961967c503da51e349e7ec8c619a6 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 23 Dec 2025 16:17:41 +0000 Subject: [PATCH 054/789] soc/intel/cnvi: Correct error values for _RST The saved error values were reversed, so correct these. This isn't a functional change, as the value isn't used in ACPI. Change-Id: I9d3abcb4b17c36d33f2660e5d20fd5e6fb15fc34 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90606 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/soc/intel/common/block/cnvi/cnvi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/soc/intel/common/block/cnvi/cnvi.c b/src/soc/intel/common/block/cnvi/cnvi.c index 9314c989ed..d7c07819de 100644 --- a/src/soc/intel/common/block/cnvi/cnvi.c +++ b/src/soc/intel/common/block/cnvi/cnvi.c @@ -205,12 +205,12 @@ static void cnvw_fill_ssdt(const struct device *dev) * } * Else * { - * PRRS = CNVI_PLDR_NOT_COMPLETE + * PRRS = CNVI_PLDR_TIMEOUT * } * } * Else * { - * PRRS = CNVI_PLDR_TIMEOUT + * PRRS = CNVI_PLDR_NOT_COMPLETE * } * } * Release (\_SB.PCI0.CNMT) @@ -363,13 +363,13 @@ static void cnvw_fill_ssdt(const struct device *dev) } acpigen_write_else(); { - acpigen_write_store_int_to_namestr(CNVI_PLDR_NOT_COMPLETE, "PRRS"); + acpigen_write_store_int_to_namestr(CNVI_PLDR_TIMEOUT, "PRRS"); } acpigen_pop_len(); } acpigen_write_else(); { - acpigen_write_store_int_to_namestr(CNVI_PLDR_TIMEOUT, "PRRS"); + acpigen_write_store_int_to_namestr(CNVI_PLDR_NOT_COMPLETE, "PRRS"); } acpigen_pop_len(); } From ea045bd322c0925f7e3ed463246e3164976f256f Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 23 Dec 2025 16:19:52 +0000 Subject: [PATCH 055/789] soc/intel/cnvi: Re-enable Bluetooth on reset timeout The current code left Bluetooth disabled if it times out during reset. Following the flow of the reference code, re-enable it to avoid it ending up "stuck" off. Change-Id: Ib1c49f28ec13068d9d7e59841ae35d1d26c30770 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90607 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/common/block/cnvi/cnvi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/soc/intel/common/block/cnvi/cnvi.c b/src/soc/intel/common/block/cnvi/cnvi.c index d7c07819de..817895af7d 100644 --- a/src/soc/intel/common/block/cnvi/cnvi.c +++ b/src/soc/intel/common/block/cnvi/cnvi.c @@ -206,6 +206,7 @@ static void cnvw_fill_ssdt(const struct device *dev) * Else * { * PRRS = CNVI_PLDR_TIMEOUT + * \_SB.PCI0.BTRK (One) * } * } * Else @@ -364,6 +365,8 @@ static void cnvw_fill_ssdt(const struct device *dev) acpigen_write_else(); { acpigen_write_store_int_to_namestr(CNVI_PLDR_TIMEOUT, "PRRS"); + acpigen_emit_namestring("\\_SB.PCI0.BTRK"); + acpigen_emit_byte(1); } acpigen_pop_len(); } From 4631f94e51aab5312c14ecaf29f0669b55fc1277 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 23 Dec 2025 20:13:56 +0000 Subject: [PATCH 056/789] drivers/usb/intel_bluetooth: Advertise D2 for S0W Bluetooth only signal wake while in USB suspend (D2). It is not possible for it to wake when in D3 (low-power mode) so D3 is incorrect. Change-Id: I1c2052507dfae235140e667b9a5580b4a7a8cb5d Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90609 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/drivers/usb/acpi/intel_bluetooth.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/src/drivers/usb/acpi/intel_bluetooth.c b/src/drivers/usb/acpi/intel_bluetooth.c index 4c882cde9d..e9488d3968 100644 --- a/src/drivers/usb/acpi/intel_bluetooth.c +++ b/src/drivers/usb/acpi/intel_bluetooth.c @@ -50,29 +50,9 @@ void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, bool audio_offload) { /* - * Name (_S0W, 3) + * Name (_S0W, 2) */ - if (get_uint_option("bluetooth_rtd3", 1)) - acpigen_write_name_integer("_S0W", ACPI_DEVICE_SLEEP_D3_HOT); - else - acpigen_write_name_integer("_S0W", ACPI_DEVICE_SLEEP_D0); - -/* - * Name (_DSD, Package (0x02) - * { - * ToUUID ("6211e2c0-58a3-4af3-90e1-927a4e0c55a4") - * Package (0x01) - * { - * Package (0x02) - * { - * "HotPlugSupportInD3", - * One - * } - * } - * }) - * - */ - acpi_device_add_hotplug_support_in_d3(NULL); + acpigen_write_name_integer("_S0W", ACPI_DEVICE_SLEEP_D2); /* * Name (RDLY, 0x69) From 091ac1005987a2c523341d08a9e0f82b3e622037 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 23 Dec 2025 20:17:21 +0000 Subject: [PATCH 057/789] soc/intel/cnvi: Correct S-state level for CNVP This power resource is valid in S5, so correct the level that is set. This makes it match the reference code, and the CNVi Bluetooth power resource. Change-Id: I430cafafc0326dc189a337bf2b67cf200afc4f17 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90610 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/common/block/cnvi/cnvi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/common/block/cnvi/cnvi.c b/src/soc/intel/common/block/cnvi/cnvi.c index 817895af7d..80fed3a23d 100644 --- a/src/soc/intel/common/block/cnvi/cnvi.c +++ b/src/soc/intel/common/block/cnvi/cnvi.c @@ -120,7 +120,7 @@ static void cnvw_fill_ssdt(const struct device *dev) acpigen_write_name_integer("WFDL", 50); /* - * PowerResource (CNVP, 0x00, 0x0000) + * PowerResource (CNVP, 0x05, 0x0000) * { * Method (_STA, 0, NotSerialized) // _STA: Status * { @@ -220,7 +220,7 @@ static void cnvw_fill_ssdt(const struct device *dev) * } * */ - acpigen_write_power_res("CNVP", 0, 0, NULL, 0); + acpigen_write_power_res("CNVP", 5, 0, NULL, 0); { acpigen_write_method("_STA", 0); { From 7c3d45d94fc4a44d0b6766bb59a5d082514e7fd8 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 23 Dec 2025 20:18:50 +0000 Subject: [PATCH 058/789] drivers/usb/intel_bluetooth: Correct S-state level for power resource This power resource is valid in S5, so correct the advertised level. Change-Id: I208182a7633c03d818a5b8892d305e3bcd5b835f Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90611 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/drivers/usb/acpi/intel_bluetooth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drivers/usb/acpi/intel_bluetooth.c b/src/drivers/usb/acpi/intel_bluetooth.c index e9488d3968..2ccb13bfe8 100644 --- a/src/drivers/usb/acpi/intel_bluetooth.c +++ b/src/drivers/usb/acpi/intel_bluetooth.c @@ -108,7 +108,7 @@ void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, acpigen_write_dsm_uuid_arr(uuid_callbacks, ARRAY_SIZE(uuid_callbacks)); /* - * PowerResource (BTRT, 0, 0) + * PowerResource (BTRT, 0x05, 0) * { * Method (_STA, 0, NotSerialized) * { @@ -139,7 +139,7 @@ void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, * } * } */ - acpigen_write_power_res("BTRT", 0, 0, NULL, 0); + acpigen_write_power_res("BTRT", 5, 0, NULL, 0); { acpigen_write_method("_STA", 0); { From 06c83d473b2682203fcf9ce8f64c399abff9e3a6 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 24 Dec 2025 08:49:36 +0000 Subject: [PATCH 059/789] ec/google/chromeec: Add function to read battery state of charge Implement google_chromeec_read_batt_state_of_charge() to retrieve the current battery percentage from the Embedded Controller. The function uses the CHARGE_STATE_CMD_GET_STATE host command to fetch the State of Charge (SoC) as calculated by the EC's fuel gauge logic. This provides a high-level percentage (0-100) suitable for power management decisions or UI display. Change-Id: Iec88476214088476214088476214088476214088 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90614 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/ec/google/chromeec/ec.c | 24 ++++++++++++++++++++++++ src/ec/google/chromeec/ec.h | 8 ++++++++ 2 files changed, 32 insertions(+) diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index 03ae01c03d..d7e956068c 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -1860,3 +1860,27 @@ void platform_do_early_poweroff(void) google_chromeec_reboot(EC_REBOOT_COLD_AP_OFF, 0); halt(); } + +/* + * Reads the current battery charge percentage. + * + * This function communicates with the Embedded Controller (EC) via a host + * command to retrieve the "State of Charge" (SoC) as calculated by the battery fuel gauge. + * + * Return: 0 on success, -1 on failure (communication error or EC rejection). + * Return Value (state): Pointer to a uint32_t where the battery state of charge + * (0-100) will be stored. + */ +int google_chromeec_read_batt_state_of_charge(uint32_t *state) +{ + struct ec_params_charge_state params; + struct ec_response_charge_state resp; + + params.cmd = CHARGE_STATE_CMD_GET_STATE; + + if (ec_cmd_charge_state(PLAT_EC, ¶ms, &resp) < 0) + return -1; + + *state = resp.get_state.batt_state_of_charge; + return 0; +} diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index 2f29b9d21c..e4120dabeb 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -538,4 +538,12 @@ bool chipset_emi_write_bytes(u16 port, size_t length, u8 *msg, u8 *csum); */ void chipset_ioport_range(uint16_t *base, size_t *size); +/* + * Reads the current battery charge percentage. + * + * @param state Pointer to a uint32_t where the battery state of charge (0-100) will be + * stored. + */ +int google_chromeec_read_batt_state_of_charge(uint32_t *state); + #endif /* _EC_GOOGLE_CHROMEEC_EC_H */ From 02b3674198cc68745a80fc1f8d2c564103f17ce6 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 24 Dec 2025 08:53:58 +0000 Subject: [PATCH 060/789] ec/google/chromeec: Add SoC calculation from battery dynamic info Implement google_chromeec_read_batt_state_of_charge_raw() to calculate the battery percentage using raw capacity metrics. Unlike the standard charge state command, this function retrieves data via EC_CMD_BATTERY_GET_DYNAMIC. It manually calculates the State of Charge (SoC) by comparing remaining_capacity against full_capacity. This provides a fallback mechanism for platforms where the high-level CHARGE_STATE_CMD_GET_STATE command is not implemented or when working directly with the fuel gauge's dynamic data cache. Includes: - Zero-capacity check to prevent division by zero. - 100% clamping to handle fuel gauge rounding/calibration drift. Change-Id: I86d6313884762140884762140884762140884762 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90615 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/ec/google/chromeec/ec.c | 34 ++++++++++++++++++++++++++++++++++ src/ec/google/chromeec/ec.h | 9 +++++++++ 2 files changed, 43 insertions(+) diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index d7e956068c..70ad5eee7c 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -1884,3 +1884,37 @@ int google_chromeec_read_batt_state_of_charge(uint32_t *state) *state = resp.get_state.batt_state_of_charge; return 0; } + +/* + * Calculates SoC from dynamic battery data. + * + * This function fetches "dynamic" battery metrics (voltage, current, and capacity) + * and manually calculates the percentage. This is often used when the high-level + * "Get Charge State" command is unavailable. + * + * Return: 0 on success, -1 on communication failure or invalid battery data. + * Return Value (state): Pointer to store the calculated State of Charge (0-100%). + */ +int google_chromeec_read_batt_state_of_charge_raw(uint32_t *state) +{ + struct ec_params_battery_dynamic_info params = { + .index = 0, + }; + struct ec_response_battery_dynamic_info resp; + + if (ec_cmd_battery_get_dynamic(PLAT_EC, ¶ms, &resp) != 0) + return -1; + + if (resp.full_capacity <= 0) + return -1; + + uint32_t soc = (uint32_t)resp.remaining_capacity * 100 / (uint32_t)resp.full_capacity; + + /* Clamp the value to 100% (some fuel gauges report slight overflows) */ + if (soc > 100) + soc = 100; + + *state = soc; + + return 0; +} diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index e4120dabeb..ffda39b5c1 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -546,4 +546,13 @@ void chipset_ioport_range(uint16_t *base, size_t *size); */ int google_chromeec_read_batt_state_of_charge(uint32_t *state); +/* + * Reads the current battery charge percentage from EC dynamic info CMD. + * This is often used when the high-level "Get Charge State" command is unavailable". + * + * @param state Pointer to a uint32_t where the battery state of charge (0-100) will be + * stored. + */ +int google_chromeec_read_batt_state_of_charge_raw(uint32_t *state); + #endif /* _EC_GOOGLE_CHROMEEC_EC_H */ From bab8ca2bd001657b9d4ad5945a88d81e83a50ef7 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 24 Dec 2025 17:39:17 +0000 Subject: [PATCH 061/789] ec/google/chromeec: Refactor Battery SoC calculation On certain platforms, such as Qualcomm X1P42100 (Hamoa), the AP cannot successfully execute the standard CHARGE_STATE_CMD_GET_STATE host command while in the S0 power state. This is typically due to hardware arbitration or access restrictions to the battery fuel gauge bus during active operating states. This patch introduces a mechanism to fallback to manual State of Charge (SoC) calculation using dynamic battery metrics: 1. Add EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC Kconfig: Allows platforms to opt-in to manual SoC calculation. 2. Refactor existing logic: The standard command is moved to an internal static helper google_chromeec_read_batt_state_of_charge_cmd(). 3. Unified API: google_chromeec_read_batt_state_of_charge() now switches between the standard command and the raw/dynamic calculation at compile-time based on the Kconfig selection. By using ec_cmd_battery_get_dynamic(), the AP retrieves cached telemetry from the EC. This avoids triggering synchronous bus transactions to the battery, ensuring SoC data is available even when direct fuel gauge access is restricted. BUG=none BRANCH=none TEST=Build for Hamoa and verify SoC is correctly calculated via the dynamic info path. Verify standard platforms still use the charge state command path. Change-Id: I4928017362140884762140884762140884762140 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90618 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/ec/google/chromeec/Kconfig | 16 ++++++++++++++++ src/ec/google/chromeec/ec.c | 28 +++++++++++++++++++++++++--- src/ec/google/chromeec/ec.h | 9 --------- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/ec/google/chromeec/Kconfig b/src/ec/google/chromeec/Kconfig index 9213e24302..0239a08904 100644 --- a/src/ec/google/chromeec/Kconfig +++ b/src/ec/google/chromeec/Kconfig @@ -234,6 +234,22 @@ config EC_GOOGLE_CHROMEEC_LPC_GENERIC_MEMORY_SIZE hex default 0x10000 +config EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC + bool + default n + help + Enable this option to calculate the battery State of Charge (SoC) + manually using remaining and full capacity metrics. + + On certain platforms, such as Qualcomm X1P42100 (Hamoa), the AP + cannot use the standard CHARGE_STATE_CMD_GET_STATE host command + while in the S0 power state due to hardware arbitration or + access restrictions to the battery fuel gauge. + + Selecting this option forces the use of ec_cmd_battery_get_dynamic(), + which retrieves cached telemetry from the EC rather than triggering + a synchronous bus transaction to the battery. + endif # EC_GOOGLE_CHROMEEC source "src/ec/google/chromeec/*/Kconfig" diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index 70ad5eee7c..f4da831006 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -1862,7 +1862,7 @@ void platform_do_early_poweroff(void) } /* - * Reads the current battery charge percentage. + * Reads the current battery charge percentage using CHARGE_STATE_CMD_GET_STATE CMD. * * This function communicates with the Embedded Controller (EC) via a host * command to retrieve the "State of Charge" (SoC) as calculated by the battery fuel gauge. @@ -1871,7 +1871,7 @@ void platform_do_early_poweroff(void) * Return Value (state): Pointer to a uint32_t where the battery state of charge * (0-100) will be stored. */ -int google_chromeec_read_batt_state_of_charge(uint32_t *state) +static int google_chromeec_read_batt_state_of_charge_cmd(uint32_t *state) { struct ec_params_charge_state params; struct ec_response_charge_state resp; @@ -1895,7 +1895,7 @@ int google_chromeec_read_batt_state_of_charge(uint32_t *state) * Return: 0 on success, -1 on communication failure or invalid battery data. * Return Value (state): Pointer to store the calculated State of Charge (0-100%). */ -int google_chromeec_read_batt_state_of_charge_raw(uint32_t *state) +static int google_chromeec_read_batt_state_of_charge_raw(uint32_t *state) { struct ec_params_battery_dynamic_info params = { .index = 0, @@ -1918,3 +1918,25 @@ int google_chromeec_read_batt_state_of_charge_raw(uint32_t *state) return 0; } + +/* + * Reads the current battery charge percentage. + * + * This function communicates with the Embedded Controller (EC) via a host + * command to retrieve the "State of Charge" (SoC) as calculated by the battery fuel gauge. + * + * Return: 0 on success, -1 on failure (communication error or EC rejection). + * Return Value (state): Pointer to a uint32_t where the battery state of charge + * (0-100) will be stored. + */ +int google_chromeec_read_batt_state_of_charge(uint32_t *state) +{ + int ret; + + if (CONFIG(EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC)) + ret = google_chromeec_read_batt_state_of_charge_raw(state); + else + ret = google_chromeec_read_batt_state_of_charge_cmd(state); + + return ret; +} diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index ffda39b5c1..e4120dabeb 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -546,13 +546,4 @@ void chipset_ioport_range(uint16_t *base, size_t *size); */ int google_chromeec_read_batt_state_of_charge(uint32_t *state); -/* - * Reads the current battery charge percentage from EC dynamic info CMD. - * This is often used when the high-level "Get Charge State" command is unavailable". - * - * @param state Pointer to a uint32_t where the battery state of charge (0-100) will be - * stored. - */ -int google_chromeec_read_batt_state_of_charge_raw(uint32_t *state); - #endif /* _EC_GOOGLE_CHROMEEC_EC_H */ From 3bebadd347e83629aacdcbb4afbee69b2d57e7f7 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 24 Dec 2025 17:54:08 +0000 Subject: [PATCH 062/789] mb/google/bluey: Enable dynamic SoC calculation and log battery level Enable EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC for the Quenbi and Quartz models. These Qualcomm-based boards require State of Charge (SoC) to be calculated from dynamic battery metrics because the standard charge state command is restricted during certain active power states. Additionally, add platform_dump_battery_soc_information() to romstage to log the battery percentage early in the boot process. This helps with debugging power-related issues during the early boot sequence when serial console is enabled. Details: - Select EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC for Quenbi and Quartz. - Call the SoC dump in platform_romstage_main() if CONSOLE_SERIAL is on. BUG=none TEST=Boot Quenbi/Quartz and verify "Battery state-of-charge X" appears in the romstage serial console logs. Change-Id: I6184762140884762140884762140884762140884 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90619 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/Kconfig | 2 ++ src/mainboard/google/bluey/romstage.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/mainboard/google/bluey/Kconfig b/src/mainboard/google/bluey/Kconfig index c185938caf..e5665ea752 100644 --- a/src/mainboard/google/bluey/Kconfig +++ b/src/mainboard/google/bluey/Kconfig @@ -31,6 +31,7 @@ config BOARD_GOOGLE_MODEL_QUENBI def_bool n select BOARD_GOOGLE_BASEBOARD_BLUEY select BOARD_ROMSIZE_KB_32768 + select EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC select MAINBOARD_HAS_CHROME_EC select MAINBOARD_HAS_FINGERPRINT_VIA_SPI select MAINBOARD_HAS_GOOGLE_TPM @@ -39,6 +40,7 @@ config BOARD_GOOGLE_MODEL_QUARTZ def_bool n select BOARD_GOOGLE_BASEBOARD_BLUEY select BOARD_ROMSIZE_KB_32768 + select EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC select MAINBOARD_HAS_CHROME_EC select MAINBOARD_HAS_FINGERPRINT_VIA_SPI select MAINBOARD_HAS_GOOGLE_TPM diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index dbfda5511e..3ada667376 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -77,11 +77,23 @@ int qclib_mainboard_override(struct qclib_cb_if_table *table) return 0; } +static void platform_dump_battery_soc_information(void) +{ + uint32_t batt_pct; + if (google_chromeec_read_batt_state_of_charge(&batt_pct)) + printk(BIOS_WARNING, "Failed to get battery level\n"); + else + printk(BIOS_INFO, "Battery state-of-charge %d\n", batt_pct); +} + void platform_romstage_main(void) { /* Watchdog must be checked first to avoid erasing watchdog info later. */ check_wdog(); + if (CONFIG(EC_GOOGLE_CHROMEEC) && CONFIG(CONSOLE_SERIAL)) + platform_dump_battery_soc_information(); + shrm_fw_load_reset(); /* QCLib: DDR init & train */ From a27a7f0c111326b78f7a3bfb6828be8a2fe98e6f Mon Sep 17 00:00:00 2001 From: Eren Peng Date: Tue, 23 Dec 2025 13:59:14 +0800 Subject: [PATCH 063/789] mb/google/trulo/var/kaladin: Decrease G2 touch stop delay time to 150 ms We found that our UI resume time will exceed using G2 touch panel. After discussing with vendor they suggested to reduce the stop delay time to 150ms. We can get pass result after this modification. Please see b/468147191 for more details. BUG=b:468147191 TEST=Pass UI Resume test with G2 touch panel Change-Id: Iec78e27c4716e3442babad4f377efccb26773183 Signed-off-by: Eren Peng Reviewed-on: https://review.coreboot.org/c/coreboot/+/90599 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/brya/variants/kaladin/overridetree.cb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/brya/variants/kaladin/overridetree.cb b/src/mainboard/google/brya/variants/kaladin/overridetree.cb index a31ed720c5..8f7f8e2be5 100644 --- a/src/mainboard/google/brya/variants/kaladin/overridetree.cb +++ b/src/mainboard/google/brya/variants/kaladin/overridetree.cb @@ -552,7 +552,7 @@ chip soc/intel/alderlake register "generic.reset_delay_ms" = "70" register "generic.reset_off_delay_ms" = "2" register "generic.stop_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_C4)" - register "generic.stop_delay_ms" = "280" + register "generic.stop_delay_ms" = "150" register "generic.stop_off_delay_ms" = "2" register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_C0)" register "generic.enable_delay_ms" = "1" @@ -571,7 +571,7 @@ chip soc/intel/alderlake register "generic.reset_delay_ms" = "70" register "generic.reset_off_delay_ms" = "2" register "generic.stop_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_C4)" - register "generic.stop_delay_ms" = "280" + register "generic.stop_delay_ms" = "150" register "generic.stop_off_delay_ms" = "2" register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_C0)" register "generic.enable_delay_ms" = "1" From d912ae91b0a8174a93d7701ae1c620df6fd45029 Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Wed, 24 Dec 2025 16:40:54 +0530 Subject: [PATCH 064/789] mb/google/bluey: Configure GPIOs for USB camera Configure and enable the GPIOs required for the USB camera. GPIO 10 (RESET_L) and GPIO 206 (ENABLE) are set as outputs and driven high during mainboard initialization to ensure the camera is powered on and ready for use by the OS. Schematics version: 0.2 BUG=b:453773922 TEST=Verify detection of USB camera using `lsusb` in the OS. Change-Id: I1f7afcf730f37b1a2e36e3230ae9774508465691 Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90616 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/mainboard/google/bluey/board.h | 4 ++++ src/mainboard/google/bluey/mainboard.c | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/mainboard/google/bluey/board.h b/src/mainboard/google/bluey/board.h index 40e63791dc..3260b283c7 100644 --- a/src/mainboard/google/bluey/board.h +++ b/src/mainboard/google/bluey/board.h @@ -40,6 +40,10 @@ #define GPIO_SD_CD_L GPIO(71) #endif +/* USB Camera specific GPIOs */ +#define GPIO_USB_CAM_RESET_L GPIO(10) +#define GPIO_USB_CAM_ENABLE GPIO(206) + void setup_chromeos_gpios(void); bool is_off_mode(void); void configure_parallel_charging(void); diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 7b31a8cba6..d8f4c453a5 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -42,8 +42,15 @@ static bool is_low_power_boot(void) return false; } +static void enable_usb_camera(void) +{ + gpio_output(GPIO_USB_CAM_RESET_L, 1); + gpio_output(GPIO_USB_CAM_ENABLE, 1); +} + static void setup_usb(void) { + enable_usb_camera(); setup_usb_host0(); } From 4a07174d0e2d267a48e68ad86660825453d29cee Mon Sep 17 00:00:00 2001 From: Xiang W Date: Mon, 22 Dec 2025 22:35:04 +0800 Subject: [PATCH 065/789] util/cbfstool: Fix RISC-V relocations The RISC-V relocations are not correct. Resolved by referring to binutils-gdb/blob/master/include/elf/riscv.h Change-Id: I38306f511c96be75192e222e86526a87714126ea Signed-off-by: Xiang W Reviewed-on: https://review.coreboot.org/c/coreboot/+/90600 Reviewed-by: Maximilian Brune Tested-by: build bot (Jenkins) --- util/cbfstool/elf.h | 103 ++++++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 41 deletions(-) diff --git a/util/cbfstool/elf.h b/util/cbfstool/elf.h index e2d0421929..b47e080e67 100644 --- a/util/cbfstool/elf.h +++ b/util/cbfstool/elf.h @@ -2714,48 +2714,69 @@ typedef Elf32_Addr Elf32_Conflict; #define R_M32R_NUM 256 /* Keep this the last entry. */ -/* RISC-V relocation types */ +/* RISC-V relocations */ #define R_RISCV_NONE 0 -#define R_RISCV_32 2 -#define R_RISCV_REL32 3 -#define R_RISCV_JAL 4 -#define R_RISCV_HI20 5 -#define R_RISCV_LO12_I 6 -#define R_RISCV_LO12_S 7 -#define R_RISCV_PCREL_LO12_I 8 -#define R_RISCV_PCREL_LO12_S 9 -#define R_RISCV_BRANCH 10 -#define R_RISCV_CALL 11 -#define R_RISCV_PCREL_HI20 12 -#define R_RISCV_CALL_PLT 13 -#define R_RISCV_64 18 -#define R_RISCV_GOT_HI20 22 -#define R_RISCV_GOT_LO12 23 -#define R_RISCV_COPY 24 -#define R_RISCV_JUMP_SLOT 25 -/* TLS relocations */ -#define R_RISCV_TPREL_HI20 30 -#define R_RISCV_TPREL_LO12_I 31 -#define R_RISCV_TPREL_LO12_S 32 -#define R_RISCV_TLS_DTPMOD32 38 -#define R_RISCV_TLS_DTPREL32 39 -#define R_RISCV_TLS_DTPMOD64 40 -#define R_RISCV_TLS_DTPREL64 41 -#define R_RISCV_TLS_GD 42 -#define R_RISCV_TLS_DTPREL_HI16 44 -#define R_RISCV_TLS_DTPREL_LO16 45 -#define R_RISCV_TLS_GOTTPREL 46 -#define R_RISCV_TLS_TPREL32 47 -#define R_RISCV_TLS_TPREL64 48 -#define R_RISCV_TLS_GOT_HI20 51 -#define R_RISCV_TLS_GOT_LO12 52 -#define R_RISCV_TLS_GD_HI20 53 -#define R_RISCV_TLS_GD_LO12 54 -#define R_RISCV_GLOB_DAT 57 -#define R_RISCV_ADD32 58 -#define R_RISCV_ADD64 59 -#define R_RISCV_SUB32 60 -#define R_RISCV_SUB64 61 +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 +#define R_RISCV_COPY 4 +#define R_RISCV_JUMP_SLOT 5 +#define R_RISCV_TLS_DTPMOD32 6 +#define R_RISCV_TLS_DTPMOD64 7 +#define R_RISCV_TLS_DTPREL32 8 +#define R_RISCV_TLS_DTPREL64 9 +#define R_RISCV_TLS_TPREL32 10 +#define R_RISCV_TLS_TPREL64 11 +#define R_RISCV_TLSDESC 12 + +#define R_RISCV_BRANCH 16 +#define R_RISCV_JAL 17 +#define R_RISCV_CALL 18 +#define R_RISCV_CALL_PLT 19 +#define R_RISCV_GOT_HI20 20 +#define R_RISCV_TLS_GOT_HI20 21 +#define R_RISCV_TLS_GD_HI20 22 +#define R_RISCV_PCREL_HI20 23 +#define R_RISCV_PCREL_LO12_I 24 +#define R_RISCV_PCREL_LO12_S 25 +#define R_RISCV_HI20 26 +#define R_RISCV_LO12_I 27 +#define R_RISCV_LO12_S 28 +#define R_RISCV_TPREL_HI20 29 +#define R_RISCV_TPREL_LO12_I 30 +#define R_RISCV_TPREL_LO12_S 31 +#define R_RISCV_TPREL_ADD 32 +#define R_RISCV_ADD8 33 +#define R_RISCV_ADD16 34 +#define R_RISCV_ADD32 35 +#define R_RISCV_ADD64 36 +#define R_RISCV_SUB8 37 +#define R_RISCV_SUB16 38 +#define R_RISCV_SUB32 39 +#define R_RISCV_SUB64 40 +#define R_RISCV_ALIGN 43 +#define R_RISCV_RVC_BRANCH 44 +#define R_RISCV_RVC_JUMP 45 +#define R_RISCV_RVC_LUI 46 +#define R_RISCV_GPREL_I 47 +#define R_RISCV_GPREL_S 48 +#define R_RISCV_TPREL_I 49 +#define R_RISCV_TPREL_S 50 +#define R_RISCV_RELAX 51 +#define R_RISCV_SUB6 52 +#define R_RISCV_SET6 53 +#define R_RISCV_SET8 54 +#define R_RISCV_SET16 55 +#define R_RISCV_SET32 56 +#define R_RISCV_32_PCREL 57 +#define R_RISCV_IRELATIVE 58 + +#define R_RISCV_SET_ULEB128 60 +#define R_RISCV_SUB_ULEB128 61 +#define R_RISCV_TLSDESC_HI20 62 +#define R_RISCV_TLSDESC_LOAD_LO12 63 +#define R_RISCV_TLSDESC_ADD_LO12 64 +#define R_RISCV_TLSDESC_CALL 65 #define EM_RISCV 0xF3 From e3fc4a1f693648c928bbcc63841caa8e98e970ed Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 27 Dec 2025 10:49:11 -0600 Subject: [PATCH 066/789] ec/starlabs/merlin: Reorganize Kconfig and guard options properly Reorganize the Kconfig file to improve structure and ensure proper dependencies, to prevent options from showing in menuconfig. Drop text string from EC_STARLABS_MERLIN as it should only be selected at the mainboard level. Ensure all config options are only available when one of the 3 Starlabs EC types is selected by the mainboard. TEST=use menuconfig to build for Lenovo T440p, verify Merlin EC option not shown. Change-Id: I3f961342de25a22a8ebe1ae03dcf09c6ac2a0fb8 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90627 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) Reviewed-by: Nicholas --- src/ec/starlabs/merlin/Kconfig | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/ec/starlabs/merlin/Kconfig b/src/ec/starlabs/merlin/Kconfig index e650c81772..0d2c6378b8 100644 --- a/src/ec/starlabs/merlin/Kconfig +++ b/src/ec/starlabs/merlin/Kconfig @@ -1,5 +1,12 @@ ## SPDX-License-Identifier: GPL-2.0-only +config EC_STARLABS_MERLIN + bool + default n + help + Use open source embedded controller firmware. Both firmwares have the + same features but differ in licensing and compilers. + config EC_STARLABS_NUVOTON bool select EC_ACPI @@ -18,6 +25,8 @@ config EC_STARLABS_ITE KBL - 3.12 or later And open-source Merlin firmware version 1.00 or later +if EC_STARLABS_MERLIN || EC_STARLABS_ITE || EC_STARLABS_NUVOTON + config EC_STARLABS_ADD_ITE_BIN bool "Add Star Labs EC binary file" default n @@ -63,13 +72,6 @@ config EC_STARLABS_BATTERY_OEM string default "Unknown" -config EC_STARLABS_MERLIN - bool "Use open-source Merlin EC Firmware" - default n - help - Use open source embedded controller firmware. Both firmwares have the - same features but differ in licensing and compilers. - if EC_STARLABS_MERLIN config EC_STARLABS_MAX_CHARGE @@ -102,4 +104,6 @@ config EC_STARLABS_CHARGE_LED help Select if the mainboard supports reducing the charge LED brightness -endif +endif # EC_STARLABS_MERLIN + +endif # EC_STARLABS_MERLIN || EC_STARLABS_ITE || EC_STARLABS_NUVOTON From a3236ef1109fc11811b525185f5caa074c21a4d8 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Wed, 27 Aug 2025 20:23:10 +0200 Subject: [PATCH 067/789] arch/x86/acpi_bert_storage.c: Fix array size calculation The naming of the parameters was quite confusing which caused them to be used incorrectly. For example the cper_ia32x64_ctx_sz_bytype function was given the register size in bytes, but it sill multiplied it by 8, thinking that it got the number of registers instead. Fix the parameter names to make it more obvious what is the number of register array entries and what is the actual size in bytes of the array. Change-Id: I17a0fadba57ee8ede996eead4cdfb20f1ab3031e Signed-off-by: Maximilian Brune Reviewed-on: https://review.coreboot.org/c/coreboot/+/90477 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/arch/x86/acpi_bert_storage.c | 17 ++++++++++------- src/arch/x86/include/arch/bert_storage.h | 2 +- src/include/cper.h | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/arch/x86/acpi_bert_storage.c b/src/arch/x86/acpi_bert_storage.c index 8b19403a5d..b271cffc66 100644 --- a/src/arch/x86/acpi_bert_storage.c +++ b/src/arch/x86/acpi_bert_storage.c @@ -324,14 +324,14 @@ acpi_hest_generic_data_v300_t *bert_append_genproc( * CPER_IA32X64_CTX_32BIT_DBG * CPER_IA32X64_CTX_64BIT_DBG * CPER_IA32X64_CTX_MEMMAPPED - * num is the number of bytes eventually used to fill the context's register + * array_size_bytes is the size (in bytes) eventually used to fill the context's register * array, e.g. 4 MSRs * sizeof(msr_t) * * status and entry data_length values are updated. */ cper_ia32x64_context_t *new_cper_ia32x64_ctx( acpi_generic_error_status_t *status, - cper_ia32x64_proc_error_section_t *x86err, int type, int num) + cper_ia32x64_proc_error_section_t *x86err, int type, int array_size_bytes) { size_t size; cper_ia32x64_context_t *ctx; @@ -355,7 +355,7 @@ cper_ia32x64_context_t *new_cper_ia32x64_ctx( return NULL; } - size = cper_ia32x64_ctx_sz_bytype(type, num); + size = cper_ia32x64_ctx_sz_bytype(type, array_size_bytes); ctx = bert_allocate_storage(size); if (!ctx) { printk(BIOS_ERR, "New IA32X64 %s context entry would exceed available region\n", @@ -366,7 +366,7 @@ cper_ia32x64_context_t *new_cper_ia32x64_ctx( revise_error_sizes(status, size); ctx->type = type; - ctx->array_size = num; + ctx->array_size = array_size_bytes; cper_bump_ia32x64_ctx_count(x86err); return ctx; @@ -553,13 +553,16 @@ cper_ia32x64_context_t *cper_new_ia32x64_context_msr( int i; msr_t *dest; - ctx = new_cper_ia32x64_ctx(status, x86err, CPER_IA32X64_CTX_MSR, num); + ctx = new_cper_ia32x64_ctx(status, x86err, CPER_IA32X64_CTX_MSR, num * sizeof(msr_t)); if (!ctx) return NULL; - /* already filled ctx->type = CPER_IA32X64_CTX_MSR; */ + /* + * already filled: + * - ctx->type = CPER_IA32X64_CTX_MSR + * - ctx->array_size = num * sizeof(msr_t) + */ ctx->msr_addr = addr; - ctx->array_size = num * sizeof(msr_t); dest = (msr_t *)((u8 *)(ctx + 1)); /* point to the Register Array */ diff --git a/src/arch/x86/include/arch/bert_storage.h b/src/arch/x86/include/arch/bert_storage.h index d979d64000..eb5db7f9cb 100644 --- a/src/arch/x86/include/arch/bert_storage.h +++ b/src/arch/x86/include/arch/bert_storage.h @@ -91,7 +91,7 @@ static inline acpi_hest_generic_data_v300_t *acpi_hest_generic_data3( /* Add a context to an existing IA32/X64-type error entry */ cper_ia32x64_context_t *new_cper_ia32x64_ctx( acpi_generic_error_status_t *status, - cper_ia32x64_proc_error_section_t *x86err, int type, int num); + cper_ia32x64_proc_error_section_t *x86err, int type, int array_size); /* Helper to add an MSR context to an existing IA32/X64-type error entry */ cper_ia32x64_context_t *cper_new_ia32x64_context_msr( diff --git a/src/include/cper.h b/src/include/cper.h index 50e858a219..d0f7b30581 100644 --- a/src/include/cper.h +++ b/src/include/cper.h @@ -459,7 +459,7 @@ static inline cper_timestamp_t cper_timestamp(int precise) * CPER_IA32X64_CTX_MEMMAPPED * num is the number of items in the context's register array */ -static inline size_t cper_ia32x64_ctx_sz_bytype(int type, int arr_num) +static inline size_t cper_ia32x64_ctx_sz_bytype(int type, int array_size) { size_t sz = sizeof(cper_ia32x64_context_t); @@ -476,7 +476,7 @@ static inline size_t cper_ia32x64_ctx_sz_bytype(int type, int arr_num) case CPER_IA32X64_CTX_MEMMAPPED: default: /* Table N.13: "size ... is determined by (Array Size / 8)" */ - return ALIGN_UP(sz + arr_num * 8, 16); + return ALIGN_UP(sz + array_size, 16); } } From 2b9653cf34070d85a46ed6a9a03e3a6da1ba49e2 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Wed, 27 Aug 2025 20:32:19 +0200 Subject: [PATCH 068/789] arch/x86/acpi_bert_storage.c: rename check -> proc_err_info The name check is a bit confusing, since it is not a check structure. The check structure is below it. Change-Id: I000e9e5f2ce8210fce76ef81b4242150d02fceed Signed-off-by: Maximilian Brune Reviewed-on: https://review.coreboot.org/c/coreboot/+/90478 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/arch/x86/acpi_bert_storage.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/arch/x86/acpi_bert_storage.c b/src/arch/x86/acpi_bert_storage.c index b271cffc66..e9b9fc563a 100644 --- a/src/arch/x86/acpi_bert_storage.c +++ b/src/arch/x86/acpi_bert_storage.c @@ -386,7 +386,7 @@ cper_ia32x64_proc_error_info_t *new_cper_ia32x64_check( cper_ia32x64_proc_error_section_t *x86err, enum cper_x86_check_type type) { - cper_ia32x64_proc_error_info_t *check; + cper_ia32x64_proc_error_info_t *proc_err_info; static const char * const check_names[] = { "cache", "TLB", @@ -409,19 +409,19 @@ cper_ia32x64_proc_error_info_t *new_cper_ia32x64_check( return NULL; } - check = bert_allocate_storage(sizeof(*check)); - if (!check) { + proc_err_info = bert_allocate_storage(sizeof(*proc_err_info)); + if (!proc_err_info) { printk(BIOS_ERR, "New IA32X64 %s check entry would exceed available region\n", check_names[type]); return NULL; } - revise_error_sizes(status, sizeof(*check)); + revise_error_sizes(status, sizeof(*proc_err_info)); - guidcpy(&check->type, &check_guids[type]); + guidcpy(&proc_err_info->type, &check_guids[type]); cper_bump_ia32x64_chk_count(x86err); - return check; + return proc_err_info; } /* Helper to append an ACPI Generic Error Data Entry plus a CPER IA32/X64 From a1e9cd3669373725e70cf31630e7581578b53aa4 Mon Sep 17 00:00:00 2001 From: Venkateshwar S Date: Mon, 29 Dec 2025 21:57:20 -0800 Subject: [PATCH 069/789] mb/google/bluey: Configure QUPV3_2_SE4 for ADSP I2C access Load I2C firmware to QUPV3_2_SE4 Serial Engine and configure it in GSI mode to enable ADSP-controlled access to charger and fuel gauge. Test=Create an image.serial.bin and ensure it boots on X1P42100. Change-Id: I58bfe5c65f3dbd2790512c5e013fa7b91cae2933 Signed-off-by: Venkateshwar S Reviewed-on: https://review.coreboot.org/c/coreboot/+/90647 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/mainboard/google/bluey/mainboard.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index d8f4c453a5..e18f492764 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -112,6 +112,10 @@ static void mainboard_init(struct device *dev) qupv3_se_fw_load_and_init(QUPV3_1_SE0, SE_PROTOCOL_I2C, MIXED); /* Touch I2C */ qupv3_se_fw_load_and_init(QUPV3_1_SE6, SE_PROTOCOL_UART, FIFO); /* BT UART */ qupv3_se_fw_load_and_init(QUPV3_0_SE0, SE_PROTOCOL_I2C, MIXED); /* Trackpad I2C */ + + /* ADSP I2C (Charger/Fuel gauge) */ + qupv3_se_fw_load_and_init(QUPV3_2_SE4, SE_PROTOCOL_I2C, GSI); + if (!CONFIG(MAINBOARD_NO_USB_A_PORT)) qupv3_se_fw_load_and_init(QUPV3_0_SE1, SE_PROTOCOL_I2C, MIXED); /* USB-A retimer */ qupv3_se_fw_load_and_init(QUPV3_0_SE5, SE_PROTOCOL_I2C, MIXED); /* eUSB repeater */ From 4063a4c3f1090f3b3dc05ebf25e2b77be78d0c7a Mon Sep 17 00:00:00 2001 From: mikelee Date: Wed, 31 Dec 2025 15:31:36 +0800 Subject: [PATCH 070/789] mb/google/skywalker: Create variant Mace Create the variant Mace. BUG=None TEST=emerge-skywalker coreboot BRANCH=None Change-Id: If016e1812d4005a5fd49fac635dc4d93fae3be5d Signed-off-by: mikelee Reviewed-on: https://review.coreboot.org/c/coreboot/+/90660 Reviewed-by: Yidi Lin Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- src/mainboard/google/skywalker/Kconfig | 2 ++ src/mainboard/google/skywalker/Kconfig.name | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/mainboard/google/skywalker/Kconfig b/src/mainboard/google/skywalker/Kconfig index 6556acae99..19cfab5d9a 100644 --- a/src/mainboard/google/skywalker/Kconfig +++ b/src/mainboard/google/skywalker/Kconfig @@ -6,6 +6,7 @@ config BOARD_GOOGLE_SKYWALKER_COMMON BOARD_GOOGLE_BAZE || \ BOARD_GOOGLE_DOOKU || \ BOARD_GOOGLE_GROGU || \ + BOARD_GOOGLE_MACE || \ BOARD_GOOGLE_OBIWAN || \ BOARD_GOOGLE_PADME || \ BOARD_GOOGLE_SKYWALKER || \ @@ -56,6 +57,7 @@ config MAINBOARD_PART_NUMBER default "Baze" if BOARD_GOOGLE_BAZE default "Dooku" if BOARD_GOOGLE_DOOKU default "Grogu" if BOARD_GOOGLE_GROGU + default "Mace" if BOARD_GOOGLE_MACE default "Obiwan" if BOARD_GOOGLE_OBIWAN default "Padme" if BOARD_GOOGLE_PADME default "Skywalker" if BOARD_GOOGLE_SKYWALKER diff --git a/src/mainboard/google/skywalker/Kconfig.name b/src/mainboard/google/skywalker/Kconfig.name index 6f787c72b9..aa5b6550bf 100644 --- a/src/mainboard/google/skywalker/Kconfig.name +++ b/src/mainboard/google/skywalker/Kconfig.name @@ -14,6 +14,9 @@ config BOARD_GOOGLE_DOOKU config BOARD_GOOGLE_GROGU bool "-> Grogu" +config BOARD_GOOGLE_MACE + bool "-> Mace" + config BOARD_GOOGLE_OBIWAN bool "-> Obiwan" From 25d159a7ecaef0c4966c5b64c86ae2157648a917 Mon Sep 17 00:00:00 2001 From: Vince Liu Date: Tue, 30 Dec 2025 17:24:57 +0800 Subject: [PATCH 071/789] mb/google/skywalker: Use FW_CONFIG for storage and dual init support Replace AUXADC with FW_CONFIG for storage type detection, and allow unprovisioned CBI to initialize both eMMC and UFS, providing greater flexibility for ODMs. BUG=b:469517374 TEST=boot successfully with both UFS and eMMC SKUs BRANCH=skywalker Signed-off-by: Vince Liu Change-Id: I400d0a452a5c25b5f429b99bf0b62591ac6cbe1f Reviewed-on: https://review.coreboot.org/c/coreboot/+/90649 Tested-by: build bot (Jenkins) Reviewed-by: Yidi Lin Reviewed-by: Yu-Ping Wu --- src/mainboard/google/skywalker/mainboard.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/skywalker/mainboard.c b/src/mainboard/google/skywalker/mainboard.c index e219861b63..a0a89fc215 100644 --- a/src/mainboard/google/skywalker/mainboard.c +++ b/src/mainboard/google/skywalker/mainboard.c @@ -124,7 +124,9 @@ static void mainboard_init(struct device *dev) { mt6359p_init_pmif_arb(); - if (mainboard_get_storage_type() == STORAGE_EMMC) { + if (!fw_config_is_provisioned()) { + mtk_msdc_configure_emmc(true); + } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_EMMC))) { mtk_msdc_configure_emmc(true); mtcmos_ufs_power_off(); } From b354b49d58f87da1bcbc6de073c254bba3708af8 Mon Sep 17 00:00:00 2001 From: Yang Wu Date: Tue, 30 Dec 2025 21:29:05 +0800 Subject: [PATCH 072/789] libpayload: Increase SYSINFO_MAX_GPIOS to 10 Some boards require exposing more GPIOs to the payload via sysinfo. Increase the maximum number of supported GPIO entries accordingly. For example Padme will pass 9 GPIOs to payload. BUG=b:461907110 TEST=Boot firmware and check GPIO counts in sysinfo. BRANCH=None Change-Id: Idb90896b82b56f65c3d46e53b36238717de0a6d1 Signed-off-by: Yang Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90654 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu Reviewed-by: Yidi Lin --- payloads/libpayload/include/sysinfo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/payloads/libpayload/include/sysinfo.h b/payloads/libpayload/include/sysinfo.h index f18ad62308..23e2d55409 100644 --- a/payloads/libpayload/include/sysinfo.h +++ b/payloads/libpayload/include/sysinfo.h @@ -34,8 +34,8 @@ /* Maximum number of memory range definitions. */ #define SYSINFO_MAX_MEM_RANGES 32 -/* Allow a maximum of 8 GPIOs */ -#define SYSINFO_MAX_GPIOS 8 +/* Allow a maximum of 10 GPIOs */ +#define SYSINFO_MAX_GPIOS 10 /* Up to 10 MAC addresses */ #define SYSINFO_MAX_MACS 10 From 49d34a6f6cc5ff6e912146d30f4ab254748ea606 Mon Sep 17 00:00:00 2001 From: Yang Wu Date: Tue, 30 Dec 2025 10:08:42 +0800 Subject: [PATCH 073/789] mb/google/skywalker: Add MIPI panel GPIOs via lb_gpio Add MIPI panel related GPIOs to lb_gpio so Depthcharge can manage panel reset and power signals when needed. The following GPIOs are added: - panel_resx (GPIO_EN_PP3300_EDP_X) - mipi_iovcc_en (GPIO_EN_PP6000_MIPI_DISP) - mipi_tp_rstn (GPIO_TCHSCR_RST_1V8_L) This allows Depthcharge to release reset and disable IOVCC in the required order to meet the panel power-off timing specification. [1] Preliminary+specification+TL121BVMS07+-00+V01+20250721.pdf BUG=b:461907110 TEST=Boot Padme and check cbmem log is correct. BRANCH=skywalker Change-Id: I7f73e41bc4814e8a5ca3579d235001cfafb77bf9 Signed-off-by: Yang Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90646 Reviewed-by: Yu-Ping Wu Reviewed-by: Yidi Lin Tested-by: build bot (Jenkins) --- src/mainboard/google/skywalker/chromeos.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mainboard/google/skywalker/chromeos.c b/src/mainboard/google/skywalker/chromeos.c index eace485648..bbb8fadcb5 100644 --- a/src/mainboard/google/skywalker/chromeos.c +++ b/src/mainboard/google/skywalker/chromeos.c @@ -97,6 +97,16 @@ void fill_lb_gpios(struct lb_gpios *gpios) {GPIO_EDP_BL_EN_1V8.id, ACTIVE_HIGH, -1, "backlight enable"}, }; lb_add_gpios(gpios, edp_pwm_backlight_gpios, ARRAY_SIZE(edp_pwm_backlight_gpios)); + + if (CONFIG(BOARD_GOOGLE_PADME)) { + /* Panel power control GPIOs for Depthcharge power-off sequence */ + struct lb_gpio mipi_panel_gpios[] = { + {GPIO_EN_PP3300_EDP_X.id, ACTIVE_LOW, -1, "panel_resx"}, + {GPIO_EN_PP6000_MIPI_DISP.id, ACTIVE_HIGH, -1, "mipi_iovcc_en"}, + {GPIO_TCHSCR_RST_1V8_L.id, ACTIVE_LOW, -1, "mipi_tp_rstn"}, + }; + lb_add_gpios(gpios, mipi_panel_gpios, ARRAY_SIZE(mipi_panel_gpios)); + } } int cr50_plat_irq_status(void) From 40eca2934fb458cdd3d0102097ad80e20620107e Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Wed, 31 Dec 2025 16:23:16 +0800 Subject: [PATCH 074/789] soc/mediatek/common: Track firmware splash screen rendering completion Add timestamp, TS_FIRMWARE_SPLASH_RENDERED, to precisely mark the moment the firmware splash screen has finished displaying. TEST=check cbmem log Change-Id: I5c5c61e03486a5939fdb2753c35326d53277c2b2 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90661 Reviewed-by: Hung-Te Lin Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) Reviewed-by: Chen-Tsung Hsieh --- src/soc/mediatek/common/display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c index 52d6d808f7..08139dfc3d 100644 --- a/src/soc/mediatek/common/display.c +++ b/src/soc/mediatek/common/display.c @@ -14,6 +14,7 @@ #include #include #include +#include static struct panel_serializable_data *get_mipi_cmd_from_cbfs(struct panel_description *desc) { @@ -94,6 +95,8 @@ static void display_logo(struct panel_description *panel, mtk_ddp_ovlsys_start(fb_addr, edid, path); panel_configure_backlight(panel, true); + + timestamp_add_now(TS_FIRMWARE_SPLASH_RENDERED); } int mtk_display_init(void) From 7273a5b9326397d6962cab998b1baacd84efb1a8 Mon Sep 17 00:00:00 2001 From: Keith Hui Date: Fri, 24 Oct 2025 15:50:16 -0400 Subject: [PATCH 075/789] mb/asus/p8x7x-series: Move CONFIG_SUPERIO_PNP_BASE to sio/nuvoton sio/nuvoton will soon make use of this for common code. Move the definition there; mainboard will only set it. To mitigate possible conflicts in case of multiple SIO chips on the same mainboard, rename Kconfig to add _NUVOTON_. Change all existing references to match. Change-Id: I8e0516411c74b162c31142b02bf5c45e4ca30a1d Signed-off-by: Keith Hui Reviewed-on: https://review.coreboot.org/c/coreboot/+/89741 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/asus/p8x7x-series/Kconfig | 3 +-- .../asus/p8x7x-series/variants/p8c_ws/early_init.c | 6 +++--- .../asus/p8x7x-series/variants/p8h77-v/early_init.c | 6 +++--- .../asus/p8x7x-series/variants/p8z77-m/early_init.c | 6 +++--- .../asus/p8x7x-series/variants/p8z77-m_pro/early_init.c | 2 +- .../asus/p8x7x-series/variants/p8z77-v/early_init.c | 6 +++--- .../asus/p8x7x-series/variants/p8z77-v_lx2/early_init.c | 6 +++--- src/superio/nuvoton/common/Kconfig | 6 ++++++ 8 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/mainboard/asus/p8x7x-series/Kconfig b/src/mainboard/asus/p8x7x-series/Kconfig index cfff67a0dc..ee4ee3eeb2 100644 --- a/src/mainboard/asus/p8x7x-series/Kconfig +++ b/src/mainboard/asus/p8x7x-series/Kconfig @@ -106,8 +106,7 @@ config CMOS_DEFAULT_FILE config CMOS_LAYOUT_FILE default "src/mainboard/\$(MAINBOARDDIR)/variants/\$(CONFIG_VARIANT_DIR)/cmos.layout" -config SUPERIO_PNP_BASE - hex +config SUPERIO_NUVOTON_PNP_BASE default 0x2e endif diff --git a/src/mainboard/asus/p8x7x-series/variants/p8c_ws/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8c_ws/early_init.c index f192e22f3c..ae3a3633f6 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8c_ws/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8c_ws/early_init.c @@ -5,9 +5,9 @@ #include #include -#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, 0) -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6776_SP1) -#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6776_ACPI) +#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, 0) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6776_SP1) +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6776_ACPI) void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/asus/p8x7x-series/variants/p8h77-v/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8h77-v/early_init.c index a7f7e9f077..69a2f4544c 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8h77-v/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8h77-v/early_init.c @@ -5,9 +5,9 @@ #include #include -#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, 0) -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_SP1) -#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_ACPI) +#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, 0) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_ACPI) void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c index 7e4647c6e2..3c6853eef4 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c @@ -10,9 +10,9 @@ #include -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_SP1) -#define GPIO0_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_WDT1_GPIO01_V) -#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_ACPI) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) +#define GPIO0_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_WDT1_GPIO01_V) +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_ACPI) void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c index 81d9a3a9c8..c3ccf1bbde 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c @@ -11,7 +11,7 @@ #include #include -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_SP1) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c index f693fbcb18..c2285a7254 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c @@ -5,9 +5,9 @@ #include #include -#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, 0) -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_SP1) -#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_ACPI) +#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, 0) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_ACPI) void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-v_lx2/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-v_lx2/early_init.c index a7f7e9f077..69a2f4544c 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8z77-v_lx2/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-v_lx2/early_init.c @@ -5,9 +5,9 @@ #include #include -#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, 0) -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_SP1) -#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_ACPI) +#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, 0) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_ACPI) void bootblock_mainboard_early_init(void) { diff --git a/src/superio/nuvoton/common/Kconfig b/src/superio/nuvoton/common/Kconfig index 376ae16422..2525c5d445 100644 --- a/src/superio/nuvoton/common/Kconfig +++ b/src/superio/nuvoton/common/Kconfig @@ -21,3 +21,9 @@ config HAVE_SHARED_PS2_PORT port. This one port usually works for keyboards only. Add the nvram option "swap_keyboard_and_mouse" to cmos.layout to allow changing this port into a mouse port. + +config SUPERIO_NUVOTON_PNP_BASE + hex + depends on SUPERIO_NUVOTON_COMMON_PRE_RAM + help + Set the base port of the super I/O chip. From 02c57577f3ed6be160ea7afe1f139d06994a852f Mon Sep 17 00:00:00 2001 From: Keith Hui Date: Thu, 23 Oct 2025 16:48:13 -0400 Subject: [PATCH 076/789] superio/nuvoton: Add common ACPI ASL code This commit gives the Nuvoton super I/O chip family a common ACPI ASL code, based on nct6776 with the addition of a suspend (_PTS) hook that disables keyboard wakeup when shutting down and records the power state for an alternate power loss resume logic, both to be completed by subsequent patches. This code is not active until included by a mainboard's ASL code, and the suspend hook needs to be invoked from there as well. This common code supports pretty much all the nct???? super I/O chips in tree except nct5104d, nct6687d, npcd378, wpcm450. Change-Id: I7d8cf66e69688d1c53e4c313358174883710b374 Signed-off-by: Keith Hui Reviewed-on: https://review.coreboot.org/c/coreboot/+/89740 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/superio/nuvoton/common/acpi/superio.asl | 214 ++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 src/superio/nuvoton/common/acpi/superio.asl diff --git a/src/superio/nuvoton/common/acpi/superio.asl b/src/superio/nuvoton/common/acpi/superio.asl new file mode 100644 index 0000000000..9e49cf5b9e --- /dev/null +++ b/src/superio/nuvoton/common/acpi/superio.asl @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * Include this file into a mainboard's DSDT _SB device tree and it will + * expose the NCT677x SuperIO and some of its functionality. + * + * It allows the change of IO ports, IRQs and DMA settings on logical + * devices, disabling and reenabling logical devices. + * + * LDN State + * NCT677X_PP Implemented, untested + * NCT677x_SP1 Implemented, untested + * NCT677x_SP2 Implemented, untested + * NCT677x_KBC Implemented, untested + * 0x308 GPIO Implemented, untested + * 0xb HWM Implemented, untested + * + * Controllable through preprocessor defines: + * + * SIO identities + * SUPERIO_DEV Device identifier for this SIO (e.g. SIO0; required) + * SUPERIO_CHIP_NAME Chip name (@) + * SUPERIO_FULL_CHIP_NAME Unicode device name (@) + * SUPERIO_PNP_BASE I/O address of the first PnP configuration register (@) + * Items with @ are required if multiple SIO chips are being used. + * + * Functionality exposed if defined: + * NCT677X_SHOW_PP Parallel port + * NCT677X_SHOW_SP1 Serial port 1 + * NCT677X_SHOW_SP2 Serial port 2 + * NCT677X_SHOW_KBC Keyboard controller + * NCT677X_SHOW_GPIO GPIO by I/O support + * NCT677X_SHOW_HWM Hardware monitor + */ +#include + +/* Get SUPERIO_PNP_BASE from Kconfig if not redefined */ +#ifndef SUPERIO_PNP_BASE +#define SUPERIO_PNP_BASE CONFIG_SUPERIO_NUVOTON_PNP_BASE +#endif + +#include + +#undef PNP_DEFAULT_PSC +#define PNP_DEFAULT_PSC Return (0) /* no power management */ + +#define ENABLE_KEYBOARD_WAKEUP SKWK +#define POWER_LOSS_LAST_STATE PLSF + +Device(SUPERIO_DEV) { + Name (_HID, EisaId("PNP0A05")) + Name (_STR, Unicode(SUPERIO_FULL_CHIP_NAME)) + Name (_UID, SUPERIO_UID(SUPERIO_DEV,)) + + /* SuperIO configuration ports */ + OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 2) + Field (CREG, ByteAcc, NoLock, Preserve) + { + PNP_ADDR_REG, 8, + PNP_DATA_REG, 8, + } + IndexField (PNP_ADDR_REG, PNP_DATA_REG, ByteAcc, NoLock, Preserve) + { + Offset (0x07), + PNP_LOGICAL_DEVICE, 8, /* Logical device selector */ + + Offset (0x30), + PNP_DEVICE_ACTIVE, 1, /* Logical device activation */ + ACT1, 1, /* Logical device activation */ + ACT2, 1, /* Logical device activation */ + ACT3, 1, /* Logical device activation */ + ACT4, 1, /* Logical device activation */ + ACT5, 1, /* Logical device activation */ + ACT6, 1, /* Logical device activation */ + ACT7, 1, /* Logical device activation */ + + Offset (0x60), + PNP_IO0_HIGH_BYTE, 8, /* First I/O port base - high byte */ + PNP_IO0_LOW_BYTE, 8, /* First I/O port base - low byte */ + Offset (0x62), + PNP_IO1_HIGH_BYTE, 8, /* Second I/O port base - high byte */ + PNP_IO1_LOW_BYTE, 8, /* Second I/O port base - low byte */ + Offset (0x64), + PNP_IO2_HIGH_BYTE, 8, /* Third I/O port base - high byte */ + PNP_IO2_LOW_BYTE, 8, /* Third I/O port base - low byte */ + Offset (0x70), + PNP_IRQ0, 8, /* First IRQ */ + Offset (0x72), + PNP_IRQ1, 8, /* Second IRQ */ + Offset (0x74), + PNP_DMA0, 8, /* DRQ */ + + Offset (0xe0), /* Config register 0xe0 etc. */ + ,6, + ENABLE_KEYBOARD_WAKEUP, 1, + Offset (0xe6), + ,4, + POWER_LOSS_LAST_STATE, 1, + Offset (0xf2), + SPME, 1, /* Enable PME */ + ,7, + OPT3, 8, + OPT4, 8, + ,8, + OPT6, 8, + OPT7, 8 + } + + Method (_CRS) + { + /* Announce the used I/O ports to the OS */ + Return (ResourceTemplate () { + IO (Decode16, SUPERIO_PNP_BASE, SUPERIO_PNP_BASE, 1, 2) + }) + } + + Method (SIOS, 1, NotSerialized) + { + ENTER_CONFIG_MODE(NCT677X_ACPI) + if (Arg0 == 5) + { + ENABLE_KEYBOARD_WAKEUP = 0 + /* Log "power off" state */ + POWER_LOSS_LAST_STATE = 1 + } + EXIT_CONFIG_MODE() + } + + Method (SIOW, 1, NotSerialized) + { + } + + #undef PNP_ENTER_MAGIC_1ST + #undef PNP_ENTER_MAGIC_2ND + #undef PNP_ENTER_MAGIC_3RD + #undef PNP_ENTER_MAGIC_4TH + #undef PNP_EXIT_MAGIC_1ST + #undef PNP_EXIT_SPECIAL_REG + #undef PNP_EXIT_SPECIAL_VAL + #define PNP_ENTER_MAGIC_1ST 0x87 + #define PNP_ENTER_MAGIC_2ND 0x87 + #define PNP_EXIT_MAGIC_1ST 0xaa + #include + +#ifdef NCT677X_SHOW_PP + #undef SUPERIO_PNP_HID + #undef SUPERIO_PNP_LDN + #undef SUPERIO_PNP_IO0 + #undef SUPERIO_PNP_IRQ0 + #undef SUPERIO_PNP_DMA + /* + * The extra code required to dynamically reflect ECP in the HID + * isn't currently justified, so the HID is hardcoded as not + * using ECP. "PNP0401" would indicate ECP. + */ + #define SUPERIO_PNP_HID "PNP0400" + #define SUPERIO_PNP_LDN NCT677X_PP + #define SUPERIO_PNP_IO0 0x08, 0x08 + #define SUPERIO_PNP_IRQ0 + #define SUPERIO_PNP_DMA + #include +#endif + +#undef SUPERIO_UART_DDN +#undef SUPERIO_UART_PM_REG + +#ifdef NCT677X_SHOW_SP1 + #undef SUPERIO_UART_LDN + #define SUPERIO_UART_LDN NCT677X_SP1 + #include +#endif + +#ifdef NCT677X_SHOW_SP2 + #undef SUPERIO_UART_LDN + #define SUPERIO_UART_LDN NCT677X_SP2 + #include +#endif + +#ifdef NCT677X_SHOW_KBC + #undef SUPERIO_KBC_LDN + #undef SUPERIO_KBC_PS2M + #undef SUPERIO_KBC_PS2LDN + #define SUPERIO_KBC_LDN NCT677X_KBC + #define SUPERIO_KBC_PS2M + #include +#endif + +#undef SUPERIO_PNP_HID +#undef SUPERIO_PNP_DMA + +#ifdef NCT677X_SHOW_HWM + #undef SUPERIO_PNP_LDN + #undef SUPERIO_PNP_IO0 + #undef SUPERIO_PNP_IO1 + #undef SUPERIO_PNP_IRQ0 + #define SUPERIO_PNP_LDN NCT677X_HWM_FPLED + #define SUPERIO_PNP_IO0 0x08, 0x08 + #define SUPERIO_PNP_IO1 0x08, 0x08 + #define SUPERIO_PNP_IRQ0 + #include +#endif + +#ifdef NCT677X_SHOW_GPIO + #undef SUPERIO_PNP_LDN + #undef SUPERIO_PNP_IO0 + #undef SUPERIO_PNP_IO1 + #undef SUPERIO_PNP_IRQ0 + #undef PNP_DEVICE_ACTIVE + #define PNP_DEVICE_ACTIVE ACT3 + #define SUPERIO_PNP_LDN 8 + #define SUPERIO_PNP_IO0 0x08, 0x08 + #include +#endif +} From bc240baba5faa5574ee7d441c4b3a669fcb900b4 Mon Sep 17 00:00:00 2001 From: Ivan Kuzneczov Date: Wed, 31 Dec 2025 02:33:22 +0000 Subject: [PATCH 077/789] Documentation: Add method for GRUB2 to load seabios from drive Confirmed on an image with GRUB2 payload and without seabios as secondary payload. Signed-off-by: Ivan Kuzneczov Change-Id: I093a9b9e8cabe6b21ec9d755a1592438209a86c6 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90658 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- Documentation/payloads.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/payloads.md b/Documentation/payloads.md index 76ff2cd7e7..4c494ab5a9 100644 --- a/Documentation/payloads.md +++ b/Documentation/payloads.md @@ -23,6 +23,12 @@ When chainloaded from GRUB2, the following menuentry could be used: module /vgaroms/seavgabios.bin } +GRUB2 loading seabios from drive via command prompt is also possible: + + multiboot (usb0,msdos1)/seabios/bios.bin.elf + module (usb0,msdos1)/seabios/vgabios.bin name=vgaroms/seavgabios.bin + boot + ## edk2 [edk2](https://github.com/tianocore/tianocore.github.io/wiki/Getting-Started-with-EDK-II) is an open-source modern, feature-rich, From 091e8140ea364be638f062666059657a32f2024e Mon Sep 17 00:00:00 2001 From: Yunlong Jia Date: Wed, 31 Dec 2025 08:47:20 +0000 Subject: [PATCH 078/789] spd/lp5: Add SPD for RS1G32LO5D2FDB-23BT Add RS1G32LO5D2FDB-23BT in the memory_parts.json and re-generate the SPD. BUG=b:472596025 TEST=util/spd_tools/bin/spd_gen spd/lp5/memory_parts.json lp5 Change-Id: Ic249e6216c927b5080873928509b32587a8a53f6 Signed-off-by: Yunlong Jia Reviewed-on: https://review.coreboot.org/c/coreboot/+/90662 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- spd/lp5/memory_parts.json | 11 +++++++++++ spd/lp5/set-0/parts_spd_manifest.generated.txt | 1 + spd/lp5/set-1/parts_spd_manifest.generated.txt | 1 + 3 files changed, 13 insertions(+) diff --git a/spd/lp5/memory_parts.json b/spd/lp5/memory_parts.json index bb725fcb73..40a8f65ec2 100644 --- a/spd/lp5/memory_parts.json +++ b/spd/lp5/memory_parts.json @@ -423,6 +423,17 @@ "ranksPerChannel": 2, "speedMbps": 6400 } + }, + { + "name": "RS1G32LO5D2FDB-23BT", + "attribs": { + "densityPerDieGb": 16, + "diesPerPackage": 2, + "bitWidthPerChannel": 16, + "ranksPerChannel": 1, + "speedMbps": 8533, + "lp5x": true + } } ] } diff --git a/spd/lp5/set-0/parts_spd_manifest.generated.txt b/spd/lp5/set-0/parts_spd_manifest.generated.txt index 7d3c3f378a..3976379d4a 100644 --- a/spd/lp5/set-0/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-0/parts_spd_manifest.generated.txt @@ -41,3 +41,4 @@ MT62F1G32D2DS-020 WT:D,spd-11.hex K3KL8L80EM-MGCV,spd-11.hex MT62F1G32D2DS-031RF WT:C,spd-3.hex MT62F2G32D4DS-031RF WT:C,spd-6.hex +RS1G32LO5D2FDB-23BT,spd-11.hex diff --git a/spd/lp5/set-1/parts_spd_manifest.generated.txt b/spd/lp5/set-1/parts_spd_manifest.generated.txt index 7d3c3f378a..3976379d4a 100644 --- a/spd/lp5/set-1/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-1/parts_spd_manifest.generated.txt @@ -41,3 +41,4 @@ MT62F1G32D2DS-020 WT:D,spd-11.hex K3KL8L80EM-MGCV,spd-11.hex MT62F1G32D2DS-031RF WT:C,spd-3.hex MT62F2G32D4DS-031RF WT:C,spd-6.hex +RS1G32LO5D2FDB-23BT,spd-11.hex From 9b5d98583889f9d6ba829c196f3ebc24a72a723e Mon Sep 17 00:00:00 2001 From: Pierce Chou Date: Tue, 16 Dec 2025 10:36:57 +0800 Subject: [PATCH 079/789] mb/google/ocelot/var/ocicat: Update audio settings Ocicat use ALC3247, and confirm with vendor, That ALC3247 driver is mapping to ALC236 not AL256. - Follow ocelot setting, add Audio settings - Update ALC236 Verb table - Enable hda codec BUG=b:469132497 TEST=Flash and boot on DUT, audio works normally Change-Id: Id60dcaadfefafb499b0555a81192b03b77ad9030 Signed-off-by: Pierce Chou Reviewed-on: https://review.coreboot.org/c/coreboot/+/90518 Reviewed-by: Pranava Y N Tested-by: build bot (Jenkins) --- .../google/ocelot/variants/ocicat/hda_verb.c | 135 +++++++++--------- .../ocelot/variants/ocicat/overridetree.cb | 2 + .../google/ocelot/variants/ocicat/variant.c | 21 +++ 3 files changed, 89 insertions(+), 69 deletions(-) diff --git a/src/mainboard/google/ocelot/variants/ocicat/hda_verb.c b/src/mainboard/google/ocelot/variants/ocicat/hda_verb.c index 2f703b78ee..bb978b8120 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/hda_verb.c +++ b/src/mainboard/google/ocelot/variants/ocicat/hda_verb.c @@ -4,15 +4,16 @@ const u32 cim_verb_data[] = { /* coreboot specific header */ - 0x10ec0256, /* Codec Vendor / Device ID: Realtek ALC256 */ - 0x10ec12ac, /* Subsystem ID */ - 0x00000013, /* Number of jacks (NID entries) */ + 0x10ec0236, // Codec Vendor / Device ID: Realtek ALC236 + 0x103C8C60, // Subsystem ID + 0x00000016, // Number of jacks (NID entries) AZALIA_RESET(0x1), - /* NID 0x01, HDA Codec Subsystem ID Verb Table */ - AZALIA_SUBVENDOR(0, 0x10ec12ac), + /* NID 0x01, HDA Codec Subsystem ID Verb table */ + AZALIA_SUBVENDOR(0, 0x103C8C60), /* Pin Widget Verb Table */ + /* * DMIC * Requirement is to use PCH DMIC. Hence, @@ -20,105 +21,101 @@ const u32 cim_verb_data[] = { * AZALIA_PIN_CFG(0, 0x12, 0x90A60130), * AZALIA_PIN_CFG(0, 0x13, 0x40000000), */ + /* Pin widget 0x14 - Front (Port-D) */ AZALIA_PIN_CFG(0, 0x14, 0x90170110), /* Pin widget 0x18 - NPC */ AZALIA_PIN_CFG(0, 0x18, 0x411111F0), /* Pin widget 0x19 - MIC2 (Port-F) */ - AZALIA_PIN_CFG(0, 0x19, 0x04A11040), + AZALIA_PIN_CFG(0, 0x19, 0x03A11020), /* Pin widget 0x1A - LINE1 (Port-C) */ AZALIA_PIN_CFG(0, 0x1a, 0x411111F0), /* Pin widget 0x1B - NPC */ AZALIA_PIN_CFG(0, 0x1b, 0x411111F0), /* Pin widget 0x1D - BEEP-IN */ - AZALIA_PIN_CFG(0, 0x1d, 0x40610041), + AZALIA_PIN_CFG(0, 0x1d, 0x40600001), /* Pin widget 0x1E - NPC */ AZALIA_PIN_CFG(0, 0x1e, 0x411111F0), /* Pin widget 0x21 - HP1-OUT (Port-I) */ - AZALIA_PIN_CFG(0, 0x21, 0x04211020), + AZALIA_PIN_CFG(0, 0x21, 0x03211040), + /* * Widget node 0x20 - 1 - * Codec hidden reset and speaker power 2W/4ohm - */ - 0x0205001A, - 0x0204C003, - 0x02050038, - 0x02047901, - /* - * Widget node 0x20 - 2 - * Class D power on Reset */ 0x0205003C, 0x02040354, 0x0205003C, 0x02040314, /* - * Widget node 0x20 - 3 - * Disable AGC and set AGC limit to -1.5dB - */ - 0x02050016, - 0x02040C50, - 0x02050012, - 0x0204EBC1, - /* - * Widget node 0x20 - 4 - * Set AGC Post gain +1.5dB then Enable AGC - */ - 0x02050013, - 0x02044023, - 0x02050016, - 0x02040E50, - /* - * Widget node 0x20 - 5 - * Silence detector enabling + Set EAPD to verb control - */ - 0x02050037, - 0x0204FE15, - 0x02050010, - 0x02040020, - /* - * Widget node 0x20 - 6 - * Silence data mode Threshold (-90dB) + * Widget node 0x20 - 2 + * Set JD2 pull high */ - 0x02050030, - 0x0204A000, 0x0205001B, 0x02040A4B, + 0x0205000B, + 0x02047778, /* - * Widget node 0x20 - 7 - * Default setting-1 + * Widget node 0x20 - 3 */ - 0x05750003, - 0x05740DA3, 0x02050046, 0x02040004, - /* - * Widget node 0x20 - 8 - * support 1 pin detect two port - */ - 0x02050009, - 0x0204E003, - 0x0205000A, - 0x02047770, - /* - * Widget node 0x20 - 9 - * To set LDO1/LDO2 as default - */ - 0x02050008, - 0x02046A0C, - 0x02050008, - 0x02046A0C, + 0x05750003, + 0x057409A3, + /* disable EQ first */ + 0x05350000, + 0x0534201A, + /* Left Channel */ + 0x0535001d, + 0x05340800, + 0x0535001e, + 0x05340800, + 0x05350003, + 0x05341F7B, + 0x05350004, + 0x05340000, + /* Right Channel */ + 0x05450000, + 0x05442000, + 0x0545001d, + 0x05440800, + 0x0545001e, + 0x05440800, + 0x05450003, + 0x05441F7B, + 0x05450004, + 0x05440000, + /* enable EQ */ + 0x05350000, + 0x0534E01A, + /* 2.2W/4ohm */ + 0x02050038, + 0x02046901, + /* Disable AGC and set AGC limit to 0dB */ + 0x02050016, + 0x02044C50, + 0x02050012, + 0x0204EBC0, + /* Set AGC Front and Post gain 0dB then Enable AGC */ + 0x02050013, + 0x0204401F, + 0x02050016, + 0x02044E50, + /* Headphone Pop */ + 0x05750007, + 0x057412B2, + 0x05750007, /* Padding */ + 0x057412B2, /* Padding */ }; const u32 pc_beep_verbs[] = { /* Dos beep path - 1 */ - 0x01470C00, 0x02050036, 0x02047151, - 0x01470740, + 0x02050010, + 0x02040020, /* Dos beep path - 2 */ - 0x0143b000, - 0x01470C02, + 0x0143B000, + 0x01470740, 0x01470C02, 0x01470C02, }; diff --git a/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb b/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb index ba43e1589e..e1f32ada9b 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb +++ b/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb @@ -17,6 +17,8 @@ fw_config end chip soc/intel/pantherlake + # HD Audio + register "pch_hda_audio_link_hda_enable" = "true" register "usb2_ports[0]" = "USB2_PORT_TYPE_C(OC_SKIP)" # Type C port - various configurations - TCP0 register "usb2_ports[1]" = "USB2_PORT_TYPE_C(OC_SKIP)" # Type C port - various configurations - TCP1 diff --git a/src/mainboard/google/ocelot/variants/ocicat/variant.c b/src/mainboard/google/ocelot/variants/ocicat/variant.c index 0bfbdf05ed..a7154dada0 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/variant.c +++ b/src/mainboard/google/ocelot/variants/ocicat/variant.c @@ -14,6 +14,11 @@ void variant_update_soc_memory_init_params(FSPM_UPD *memupd) { FSP_M_CONFIG *m_cfg = &memupd->FspmConfig; + /* HDA Audio */ + printk(BIOS_INFO, "Overriding HDA SDI lanes.\n"); + m_cfg->PchHdaSdiEnable[0] = true; + m_cfg->PchHdaSdiEnable[1] = false; + /* Override FSP-M SaGv frequency and gear for DDR5 boards */ m_cfg->SaGvFreq[0] = 3200; m_cfg->SaGvGear[0] = GEAR_4; @@ -46,3 +51,19 @@ void variant_update_soc_memory_init_params(FSPM_UPD *memupd) memcpy(m_cfg->PhyClockToCkdDimm, phy_clock_to_ckd_dimm, sizeof(phy_clock_to_ckd_dimm)); } + +/* + * HDA verb table loading is supported based on the firmware configuration. + * + * This function determines if the current platform has an HDA codec enabled by + * examining the `FW_CONFIG` value. Specifically, it checks if the + * `FW_CONFIG` includes the `AUDIO_ALC256_HDA` value, which is used to identify + * Fatcat SKUs with HDA codec support. + * + * Return true if the `FW_CONFIG` indicates HDA support (i.e., contains + * `AUDIO_ALC256_HDA`), false otherwise. + */ +bool mainboard_is_hda_codec_enabled(void) +{ + return true; +} From c3ff1addde6f92211934beed50261eccd8b8028b Mon Sep 17 00:00:00 2001 From: Pierce Chou Date: Tue, 16 Dec 2025 13:13:32 +0800 Subject: [PATCH 080/789] mb/google/ocelot/var/ocicat: Add WIFI SAR table - Add WIFI SAR table for intel WIFI SAR table - Follow new UFSC definitions to rename WIFI config BUG=b:469226622 TEST=Build and flash to DUT, check that SAR table is loaded by cbmem -1 | grep sar Change-Id: Iba3c4588c969a74dd83d176124addfa2d115edbd Signed-off-by: Pierce Chou Reviewed-on: https://review.coreboot.org/c/coreboot/+/90520 Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N --- .../ocelot/variants/ocicat/overridetree.cb | 16 ++++++++-------- .../google/ocelot/variants/ocicat/variant.c | 5 +++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb b/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb index e1f32ada9b..03f782fad3 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb +++ b/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb @@ -1,9 +1,4 @@ fw_config - field WIFI 2 4 - option WIFI_NONE 0 - option WIFI_CNVI_7 1 - option WIFI_PCIE_7 2 - end field STORAGE_TYPE 12 14 option STORAGE_TYPE_UNKNOWN 0 option STORAGE_TYPE_NVME_GEN4 1 @@ -14,6 +9,11 @@ fw_config option TOUCH_ELAN_TOP 1 option TOUCH_ELAN_DBTS 2 end + field WIFI_INTERFACE 26 27 + option WIFI_INTERFACE_UNKNOWN 0 + option WIFI_INTERFACE_CNVI_7 1 + option WIFI_INTERFACE_PCIE_7 2 + end end chip soc/intel/pantherlake @@ -328,7 +328,7 @@ chip soc/intel/pantherlake register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_B09)" device ref usb2_port8 on - probe WIFI WIFI_PCIE_7 + probe WIFI_INTERFACE WIFI_INTERFACE_PCIE_7 end end @@ -365,7 +365,7 @@ chip soc/intel/pantherlake end # Gen4 M.2 SSD device ref pcie_rp5 on - probe WIFI WIFI_PCIE_7 + probe WIFI_INTERFACE WIFI_INTERFACE_PCIE_7 register "pcie_rp[PCIE_RP(5)]" = "{ .clk_src = 0, .clk_req = 0, @@ -384,7 +384,7 @@ chip soc/intel/pantherlake end # CNVi device ref cnvi_bluetooth on - probe WIFI WIFI_CNVI_7 + probe WIFI_INTERFACE WIFI_INTERFACE_CNVI_7 chip soc/intel/common/block/cnvi register "wake" = "GPE0_PME_B0" device generic 0 on end diff --git a/src/mainboard/google/ocelot/variants/ocicat/variant.c b/src/mainboard/google/ocelot/variants/ocicat/variant.c index a7154dada0..733cf6bf3b 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/variant.c +++ b/src/mainboard/google/ocelot/variants/ocicat/variant.c @@ -10,6 +10,11 @@ #include #include +const char *get_wifi_sar_cbfs_filename(void) +{ + return get_wifi_sar_fw_config_filename(FW_CONFIG_FIELD(WIFI_INTERFACE)); +} + void variant_update_soc_memory_init_params(FSPM_UPD *memupd) { FSP_M_CONFIG *m_cfg = &memupd->FspmConfig; From b8680d53ac426b8352a1ae6f0cb72780a0d8d82f Mon Sep 17 00:00:00 2001 From: Pierce Chou Date: Tue, 23 Dec 2025 09:53:05 +0800 Subject: [PATCH 081/789] mb/google/ocelot/var/ocicat: Add fw_config definitions with UFSC Enable Unified Firmware and Secondary Source Configuration (UFSC) support for ocicat. UFSC standardizes the bitfields and bitmap definitions for firmware configuration. Update overridetree.cb with new UFSC definitions and enable EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC. BUG=b:471067114 TEST=Ensure the probed fw_config matches the written configuration. Change-Id: I6be36f6cec2b7e25b7e6170f12e71ae3fabf283e Signed-off-by: Pierce Chou Reviewed-on: https://review.coreboot.org/c/coreboot/+/90598 Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N --- src/mainboard/google/ocelot/Kconfig | 3 +- .../ocelot/variants/ocicat/overridetree.cb | 29 +++++++++++++------ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/mainboard/google/ocelot/Kconfig b/src/mainboard/google/ocelot/Kconfig index 1576db3671..f83e19aa6a 100644 --- a/src/mainboard/google/ocelot/Kconfig +++ b/src/mainboard/google/ocelot/Kconfig @@ -98,8 +98,6 @@ config BOARD_GOOGLE_MODEL_OJAL config BOARD_GOOGLE_MODEL_OCICAT def_bool n select BOARD_GOOGLE_BASEBOARD_OCELOT - select DRIVERS_GENERIC_BAYHUB_LV2 - select DRIVERS_GENERIC_MAX98357A select DRIVERS_INTEL_TOUCH select FSP_UGOP_EARLY_SIGN_OF_LIFE select SPD_CACHE_ENABLE @@ -137,6 +135,7 @@ config BOARD_GOOGLE_OJAL config BOARD_GOOGLE_OCICAT select BOARD_GOOGLE_MODEL_OCICAT + select EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC if BOARD_GOOGLE_OCELOT_COMMON diff --git a/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb b/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb index 03f782fad3..52ada4b77c 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb +++ b/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb @@ -1,18 +1,26 @@ fw_config + field AUDIO_CODEC 0 2 + option AUDIO_CODEC_UNKNOWN 0 + option AUDIO_CODEC_ALC3247 1 + end field STORAGE_TYPE 12 14 - option STORAGE_TYPE_UNKNOWN 0 - option STORAGE_TYPE_NVME_GEN4 1 - option STORAGE_UFS 2 + option STORAGE_TYPE_UNKNOWN 0 + option STORAGE_TYPE_NVME_GEN4 1 + option STORAGE_UFS 2 end field TOUCHSCREEN 17 18 option TOUCHSCREEN_UNKNOWN 0 - option TOUCH_ELAN_TOP 1 - option TOUCH_ELAN_DBTS 2 + option TOUCH_ELAN_TOP 1 + option TOUCH_ELAN_DBTS 2 + end + field SENSOR_HUB 23 23 + option ISH_ABSENT 0 + option ISH_PRESENT 1 end field WIFI_INTERFACE 26 27 - option WIFI_INTERFACE_UNKNOWN 0 - option WIFI_INTERFACE_CNVI_7 1 - option WIFI_INTERFACE_PCIE_7 2 + option WIFI_INTERFACE_UNKNOWN 0 + option WIFI_INTERFACE_CNVI_7 1 + option WIFI_INTERFACE_PCIE_7 2 end end @@ -464,11 +472,14 @@ chip soc/intel/pantherlake device ref smbus on end device ref hda on + probe AUDIO_CODEC AUDIO_CODEC_ALC3247 chip drivers/sof register "spkr_tplg" = "max98360a" register "jack_tplg" = "rt5682" register "mic_tplg" = "_2ch_pdm0" - device generic 0 on end + device generic 0 on + probe AUDIO_CODEC AUDIO_CODEC_ALC3247 + end end end end From 56013ce0ff12546997b85b8334544a6bf4d15043 Mon Sep 17 00:00:00 2001 From: Venkateshwar S Date: Tue, 30 Dec 2025 02:05:55 -0800 Subject: [PATCH 082/789] mainboard/google/bluey: Skip SHRM firmware load/reset in ramdump mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SHRM firmware load and reset sequence currently runs unconditionally during the boot process. This causes issues during RAM dump collection, where the contents of the SHRM region must remain intact for post‑crash analysis. This patch adds a Dload‑mode check (which indicates RAM‑dump mode) and skips shrm_fw_load_reset() when that bit is set. This prevents unintended SHRM resets during RAM dump capture and ensures the firmware load/reset sequence only runs during a normal cold boot. A RAM dump is a debug image used after a crash to preserve system memory for post‑crash analysis. Test=Create an image.serial.bin and ensure it boots on X1P42100. Change-Id: Ie3d1ff9462a48d21f1daae1f80322ea397731be5 Signed-off-by: Venkateshwar S Reviewed-on: https://review.coreboot.org/c/coreboot/+/90651 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/romstage.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index 3ada667376..06cd5626bd 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -94,7 +94,8 @@ void platform_romstage_main(void) if (CONFIG(EC_GOOGLE_CHROMEEC) && CONFIG(CONSOLE_SERIAL)) platform_dump_battery_soc_information(); - shrm_fw_load_reset(); + if (!qclib_check_dload_mode()) + shrm_fw_load_reset(); /* QCLib: DDR init & train */ qclib_load_and_run(); From fe0e14d716ffab43784f13b9ac8fae6f13672645 Mon Sep 17 00:00:00 2001 From: Venkateshwar S Date: Tue, 30 Dec 2025 02:08:15 -0800 Subject: [PATCH 083/789] soc/qualcomm/x1p42100: Skip SHRM meta firmware load in ramdump mode QCLib passes SHRM metadata to TME for authentication and to bring SHRM out of reset. In RAM dump mode, this sequence is unnecessary because the system is preserving state for post-crash analysis. This patch adds a RAM-dump-mode check and ensures: - SHRM metadata is not loaded or populated into the interface table when RAM dump mode is detected, preventing QCLib from sending it to TME. Test=Create an image.serial.bin and verify it boots on X1P42100. Change-Id: I921a2b99543ee462433bec8e8471ad836cabc5dd Signed-off-by: Venkateshwar S Reviewed-on: https://review.coreboot.org/c/coreboot/+/90652 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/soc/qualcomm/x1p42100/qclib.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/soc/qualcomm/x1p42100/qclib.c b/src/soc/qualcomm/x1p42100/qclib.c index c67b3591f0..6baabccb20 100644 --- a/src/soc/qualcomm/x1p42100/qclib.c +++ b/src/soc/qualcomm/x1p42100/qclib.c @@ -47,15 +47,17 @@ int qclib_soc_override(struct qclib_cb_if_table *table) } qclib_add_if_table_entry(QCLIB_TE_CPR_SETTINGS, _cpr_settings, data_size, 0); - /* Attempt to load shrm_meta Blob */ - data_size = cbfs_load(qclib_file(QCLIB_CBFS_SHRM_META), - _qc_blob_meta, REGION_SIZE(qc_blob_meta)); - if (!data_size) { - printk(BIOS_ERR, "[%s] /shrm_meta failed\n", __func__); - return -1; - } + if (!qclib_check_dload_mode()) { + /* Attempt to load shrm_meta Blob */ + data_size = cbfs_load(qclib_file(QCLIB_CBFS_SHRM_META), + _qc_blob_meta, REGION_SIZE(qc_blob_meta)); + if (!data_size) { + printk(BIOS_ERR, "[%s] /shrm_meta failed\n", __func__); + return -1; + } - qclib_add_if_table_entry(QCLIB_TE_SHRM_META_SETTINGS, _qc_blob_meta, data_size, 0); + qclib_add_if_table_entry(QCLIB_TE_SHRM_META_SETTINGS, _qc_blob_meta, data_size, 0); + } /* hook for platform specific policy configuration */ if (qclib_mainboard_override(table)) { From 7896d94c76589c83b9474eb1ba343e37c92f5c0d Mon Sep 17 00:00:00 2001 From: Venkateshwar S Date: Tue, 30 Dec 2025 00:36:39 -0800 Subject: [PATCH 084/789] soc/qualcomm/x1p42100: Avoid reserving display buffer region The display buffer was previously reserved as unavailable by coreboot, which prevented the kernel from mapping it. When the splash driver released the buffer, the kernel later crashed on access because the region was never mapped. This patch removes the reservation so the kernel can map the display buffer and reuse it safely. TEST=Create an image.serial.bin and ensure it boots on X1P42100. Check that the display memory region is mapped by kernel in UART logs: [ 0.000000][ T0] node 0: [mem 0x00000000e36a0000- 0x00000000f7bfffff] Change-Id: I507d48713690bac3030f81a29c7e123fd3a03b95 Signed-off-by: Venkateshwar S Reviewed-on: https://review.coreboot.org/c/coreboot/+/90648 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal Reviewed-by: Subrata Banik --- src/soc/qualcomm/x1p42100/soc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/soc/qualcomm/x1p42100/soc.c b/src/soc/qualcomm/x1p42100/soc.c index d1762237d5..78fa43a175 100644 --- a/src/soc/qualcomm/x1p42100/soc.c +++ b/src/soc/qualcomm/x1p42100/soc.c @@ -51,7 +51,6 @@ static void soc_read_resources(struct device *dev) reserved_ram_range(dev, index++, (uintptr_t)_dram_wlan, REGION_SIZE(dram_wlan)); reserved_ram_range(dev, index++, (uintptr_t)_dram_pil, REGION_SIZE(dram_pil)); reserved_ram_range(dev, index++, (uintptr_t)_dram_ta, REGION_SIZE(dram_ta)); - reserved_ram_range(dev, index++, (uintptr_t)_dram_display, REGION_SIZE(dram_display)); /* ACDB carveout region located at 0xFF800000 - (n*5.5 +1+32+3) where n is size of DDR */ reserved_ram_range(dev, index++, (uintptr_t)(_dram_llcc_lpi - calc_acdb_carveout_size()), From b8402a8dfc658f5b6aef7ca04e2dcadccf816c48 Mon Sep 17 00:00:00 2001 From: Venkateshwar S Date: Tue, 30 Dec 2025 02:27:20 -0800 Subject: [PATCH 085/789] src/qualcomm/common: Remove display buffer region declarations The display buffer reservation logic has been removed, so the related symbol declarations are no longer needed. TEST=Create an image.serial.bin and ensure it boots on X1P42100. Change-Id: I873fdcff4071e0d2cf683017557abdfdb13e8b16 Signed-off-by: Venkateshwar S Reviewed-on: https://review.coreboot.org/c/coreboot/+/90653 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/soc/qualcomm/common/include/soc/symbols_common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/soc/qualcomm/common/include/soc/symbols_common.h b/src/soc/qualcomm/common/include/soc/symbols_common.h index ee2d3510b6..847225216a 100644 --- a/src/soc/qualcomm/common/include/soc/symbols_common.h +++ b/src/soc/qualcomm/common/include/soc/symbols_common.h @@ -48,7 +48,6 @@ DECLARE_REGION(dram_llcc_lpi) DECLARE_REGION(dram_ta) DECLARE_REGION(dram_pdp) DECLARE_REGION(dram_pil) -DECLARE_REGION(dram_display) /* * DDR_SPACE (2 GB) aka `_dram`: 0x80000000 - 0x100000000 From 4030fc5f917ca4148ab16d65d7ace13f15b48f83 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 29 Dec 2025 10:07:33 -0600 Subject: [PATCH 086/789] device/Kconfig: Gate early libgfxinit default on ChromeOS Early libgfxinit is currently only used for ChromeOS ESOL features, so only auto-enable MAINBOARD_USE_EARLY_LIBGFXINIT when both MAINBOARD_HAS_EARLY_LIBGFXINIT and CHROMEOS are enabled, preventing unnecessary Ada toolchain requirements for non-ChromeOS builds. TEST=build/boot google/yaviks w/o CHROMEOS support, verify ADA/gnat not needed to compile. Change-Id: Ieec2a15783ce57015579d14aba0f67783c79b02c Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90636 Tested-by: build bot (Jenkins) Reviewed-by: Eric Lai --- src/device/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/Kconfig b/src/device/Kconfig index f185ecb4c3..39aa7dd193 100644 --- a/src/device/Kconfig +++ b/src/device/Kconfig @@ -126,7 +126,7 @@ endchoice choice prompt "Early (romstage) graphics initialization" - default MAINBOARD_USE_EARLY_LIBGFXINIT if MAINBOARD_HAS_EARLY_LIBGFXINIT + default MAINBOARD_USE_EARLY_LIBGFXINIT if MAINBOARD_HAS_EARLY_LIBGFXINIT && CHROMEOS default NO_EARLY_GFX_INIT config NO_EARLY_GFX_INIT From 3d980dae22274e3d3f806a2ca9b60cfe5b9ca6b9 Mon Sep 17 00:00:00 2001 From: Yanqiong Huang Date: Thu, 18 Dec 2025 19:19:07 +0800 Subject: [PATCH 087/789] mb/google/nissa/var/rull: Add 3 DDR modules to RAM id table Add HYNIX H9JCNNNCP3MLYR-N6E and MICRON MT62F1G32D4DR-031 WT:B as id 5, and add SAMSUNG K3LKBKB0BM-MGCP as id 6, resulting in the list below: DRAM Part Name ID to assign MT62F512M32D2DR-031 WT:B 0 (0000) H9JCNNNBK3MLYR-N6E 0 (0000) K3KL8L80CM-MGCT 1 (0001) H58G56BK7BX068 1 (0001) K3KL9L90CM-MGCT 2 (0010) H58G66BK8BX067 3 (0011) H58G56BK8BX068 4 (0100) MT62F1G32D2DS-023 WT:B 4 (0100) H58G56CK8BX146 4 (0100) H9JCNNNCP3MLYR-N6E 5 (0101) MT62F1G32D4DR-031 WT:B 5 (0101) K3LKBKB0BM-MGCP 6 (0110) BUG=b:470691660 TEST=Use part_id_gen to generate related settings Change-Id: Id37f83e54f5be12087010c8045b6dfe407820f48 Signed-off-by: Yanqiong Huang Reviewed-on: https://review.coreboot.org/c/coreboot/+/90548 Reviewed-by: Qinghong Zeng Tested-by: build bot (Jenkins) Reviewed-by: Eric Lai --- src/mainboard/google/brya/variants/rull/memory/Makefile.mk | 2 ++ .../google/brya/variants/rull/memory/dram_id.generated.txt | 3 +++ .../google/brya/variants/rull/memory/mem_parts_used.txt | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/mainboard/google/brya/variants/rull/memory/Makefile.mk b/src/mainboard/google/brya/variants/rull/memory/Makefile.mk index ae7be6dcd1..682003b9af 100644 --- a/src/mainboard/google/brya/variants/rull/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/rull/memory/Makefile.mk @@ -9,3 +9,5 @@ SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 1(0b0001) Parts = K3KL8L80CM SPD_SOURCES += spd/lp5/set-0/spd-8.hex # ID = 2(0b0010) Parts = K3KL9L90CM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-10.hex # ID = 3(0b0011) Parts = H58G66BK8BX067 SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 4(0b0100) Parts = H58G56BK8BX068, MT62F1G32D2DS-023 WT:B, H58G56CK8BX146 +SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 5(0b0101) Parts = H9JCNNNCP3MLYR-N6E, MT62F1G32D4DR-031 WT:B +SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 6(0b0110) Parts = K3LKBKB0BM-MGCP diff --git a/src/mainboard/google/brya/variants/rull/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/rull/memory/dram_id.generated.txt index 6a8d4b9db2..3f8483a688 100644 --- a/src/mainboard/google/brya/variants/rull/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/rull/memory/dram_id.generated.txt @@ -13,3 +13,6 @@ H58G66BK8BX067 3 (0011) H58G56BK8BX068 4 (0100) MT62F1G32D2DS-023 WT:B 4 (0100) H58G56CK8BX146 4 (0100) +H9JCNNNCP3MLYR-N6E 5 (0101) +MT62F1G32D4DR-031 WT:B 5 (0101) +K3LKBKB0BM-MGCP 6 (0110) diff --git a/src/mainboard/google/brya/variants/rull/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/rull/memory/mem_parts_used.txt index 4946ff0ab9..4b0c83cb1d 100644 --- a/src/mainboard/google/brya/variants/rull/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/rull/memory/mem_parts_used.txt @@ -18,3 +18,6 @@ H58G66BK8BX067 H58G56BK8BX068 MT62F1G32D2DS-023 WT:B H58G56CK8BX146 +H9JCNNNCP3MLYR-N6E +MT62F1G32D4DR-031 WT:B +K3LKBKB0BM-MGCP From 19deb55f0237c917876b992a5da37c4c4f57b8a0 Mon Sep 17 00:00:00 2001 From: Keith Hui Date: Sun, 28 Dec 2025 19:37:25 -0500 Subject: [PATCH 088/789] mb/asrock/fatal1ty_z87_professional: Temporarily refactor nuvoton_pnp_*() As the pair of non-ramstage Nuvoton SIO config mode entry/exit functions see wider use, they are being moved to sio/nuvoton/common/. This mainboard carries 2 local copies. This preparatory patch moves it out of smihandler.c into a temporary C file to prevent build breakage. It is to be removed when the shared copy is in place. WARNING: Disassembly of compiled SMM code shows a possible stack issue. Do not flash a binary with this patch applied but without the final shared version above. Change-Id: I685ebe6c2bb638d815ccf1fcdd1d73edc176c69e Signed-off-by: Keith Hui Reviewed-on: https://review.coreboot.org/c/coreboot/+/90655 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- .../fatal1ty_z87_professional/Makefile.mk | 2 ++ .../fatal1ty_z87_professional/mainboard.c | 18 -------------- .../fatal1ty_z87_professional/nuvoton.c | 24 +++++++++++++++++++ .../fatal1ty_z87_professional/smihandler.c | 18 -------------- 4 files changed, 26 insertions(+), 36 deletions(-) create mode 100644 src/mainboard/asrock/fatal1ty_z87_professional/nuvoton.c diff --git a/src/mainboard/asrock/fatal1ty_z87_professional/Makefile.mk b/src/mainboard/asrock/fatal1ty_z87_professional/Makefile.mk index 93f729d787..de5aa51b34 100644 --- a/src/mainboard/asrock/fatal1ty_z87_professional/Makefile.mk +++ b/src/mainboard/asrock/fatal1ty_z87_professional/Makefile.mk @@ -4,3 +4,5 @@ bootblock-y += bootblock.c bootblock-y += gpio.c romstage-y += gpio.c ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads +smm-y += nuvoton.c +ramstage-y += nuvoton.c diff --git a/src/mainboard/asrock/fatal1ty_z87_professional/mainboard.c b/src/mainboard/asrock/fatal1ty_z87_professional/mainboard.c index 1e62d65d2e..8e30e3c61c 100644 --- a/src/mainboard/asrock/fatal1ty_z87_professional/mainboard.c +++ b/src/mainboard/asrock/fatal1ty_z87_professional/mainboard.c @@ -10,24 +10,6 @@ #include #define GPIO1_DEV PNP_DEV(0x2e, NCT6776_WDT1_GPIO01A_V) -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} static void turn_off_leds(void *unused) { diff --git a/src/mainboard/asrock/fatal1ty_z87_professional/nuvoton.c b/src/mainboard/asrock/fatal1ty_z87_professional/nuvoton.c new file mode 100644 index 0000000000..56453329cb --- /dev/null +++ b/src/mainboard/asrock/fatal1ty_z87_professional/nuvoton.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +#define NUVOTON_ENTRY_KEY 0x87 +#define NUVOTON_EXIT_KEY 0xAA + +/* Enable configuration: pass entry key '0x87' into index port dev + * two times. */ +void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(NUVOTON_ENTRY_KEY, port); + outb(NUVOTON_ENTRY_KEY, port); +} + +/* Disable configuration: pass exit key '0xAA' into index port dev. */ +void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(NUVOTON_EXIT_KEY, port); +} diff --git a/src/mainboard/asrock/fatal1ty_z87_professional/smihandler.c b/src/mainboard/asrock/fatal1ty_z87_professional/smihandler.c index 6736c15bcd..5ecf42409c 100644 --- a/src/mainboard/asrock/fatal1ty_z87_professional/smihandler.c +++ b/src/mainboard/asrock/fatal1ty_z87_professional/smihandler.c @@ -7,24 +7,6 @@ #include #define GPIO1_DEV PNP_DEV(0x2e, NCT6776_WDT1_GPIO01A_V) -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} void mainboard_smi_sleep(u8 slp_typ) { From 0c2a3002d9fcffc9b22d1c39fc27ff8ebf9875bc Mon Sep 17 00:00:00 2001 From: Keith Hui Date: Sun, 28 Dec 2025 19:50:37 -0500 Subject: [PATCH 089/789] mb/asrock/z87_extreme4: Temporarily refactor nuvoton_pnp_*_conf_state() As the pair of non-ramstage Nuvoton SIO config mode entry/exit functions see wider use, they are being moved to sio/nuvoton/common. This mainboard carries 2 local copies. This preparatory patch moves them out of smihandler.c and mainboard.c into a temporary C file to prevent build breakage. It is to be removed when the shared copy is in place. WARNING: Disassembly of compiled SMM code shows a possible stack issue. Do not flash a binary with this patch applied but without the final shared version above. Change-Id: I7a5394478281ac3b92d257e2f0201264b95bb4e5 Signed-off-by: Keith Hui Reviewed-on: https://review.coreboot.org/c/coreboot/+/90656 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/asrock/z87_extreme4/Makefile.mk | 2 ++ src/mainboard/asrock/z87_extreme4/mainboard.c | 18 -------------- src/mainboard/asrock/z87_extreme4/nuvoton.c | 24 +++++++++++++++++++ .../asrock/z87_extreme4/smihandler.c | 18 -------------- 4 files changed, 26 insertions(+), 36 deletions(-) create mode 100644 src/mainboard/asrock/z87_extreme4/nuvoton.c diff --git a/src/mainboard/asrock/z87_extreme4/Makefile.mk b/src/mainboard/asrock/z87_extreme4/Makefile.mk index c3cf55d397..58368c333e 100644 --- a/src/mainboard/asrock/z87_extreme4/Makefile.mk +++ b/src/mainboard/asrock/z87_extreme4/Makefile.mk @@ -4,3 +4,5 @@ bootblock-y += bootblock.c bootblock-y += gpio.c romstage-y += gpio.c ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads +ramstage-y += nuvoton.c +smm-y += nuvoton.c diff --git a/src/mainboard/asrock/z87_extreme4/mainboard.c b/src/mainboard/asrock/z87_extreme4/mainboard.c index 1e62d65d2e..8e30e3c61c 100644 --- a/src/mainboard/asrock/z87_extreme4/mainboard.c +++ b/src/mainboard/asrock/z87_extreme4/mainboard.c @@ -10,24 +10,6 @@ #include #define GPIO1_DEV PNP_DEV(0x2e, NCT6776_WDT1_GPIO01A_V) -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} static void turn_off_leds(void *unused) { diff --git a/src/mainboard/asrock/z87_extreme4/nuvoton.c b/src/mainboard/asrock/z87_extreme4/nuvoton.c new file mode 100644 index 0000000000..56453329cb --- /dev/null +++ b/src/mainboard/asrock/z87_extreme4/nuvoton.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +#define NUVOTON_ENTRY_KEY 0x87 +#define NUVOTON_EXIT_KEY 0xAA + +/* Enable configuration: pass entry key '0x87' into index port dev + * two times. */ +void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(NUVOTON_ENTRY_KEY, port); + outb(NUVOTON_ENTRY_KEY, port); +} + +/* Disable configuration: pass exit key '0xAA' into index port dev. */ +void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(NUVOTON_EXIT_KEY, port); +} diff --git a/src/mainboard/asrock/z87_extreme4/smihandler.c b/src/mainboard/asrock/z87_extreme4/smihandler.c index d6ebcef9a0..462316a692 100644 --- a/src/mainboard/asrock/z87_extreme4/smihandler.c +++ b/src/mainboard/asrock/z87_extreme4/smihandler.c @@ -7,24 +7,6 @@ #include #define GPIO1_DEV PNP_DEV(0x2e, NCT6776_WDT1_GPIO01A_V) -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} void mainboard_smi_sleep(u8 slp_typ) { From 573c37a5182290e5ea3c4f8a6b1b8c855cfe509f Mon Sep 17 00:00:00 2001 From: Keith Hui Date: Sun, 28 Dec 2025 21:40:13 -0500 Subject: [PATCH 090/789] sio/nuvoton/common: Refactor nuvoton_pnp_*_config_state() Move the pair of non-ramstage Nuvoton SIO PNP config mode entry/exit functions from early_serial.c into nuvoton.h as inline functions for both pre-RAM and SMM code use. Availability is limited to __SIMPLE_DEVICE__ environments, or if this symbol is defined such as when mainboards specifically request it. Cuts outdated comment from early_serial.c and transplant its key parts to nuvoton.h. Remove the temporarily refactored local copies from mb/asrock/{z87_extreme4,fatal1ty_z87_professional}. Build tested on these two Asrock boards and asus/p8x7x-series. Change-Id: I0238f006dd86742f937e9dcd6134ed7be566677c Signed-off-by: Keith Hui Reviewed-on: https://review.coreboot.org/c/coreboot/+/90657 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- .../fatal1ty_z87_professional/Makefile.mk | 2 -- .../fatal1ty_z87_professional/nuvoton.c | 24 ------------- src/mainboard/asrock/z87_extreme4/Makefile.mk | 2 -- src/mainboard/asrock/z87_extreme4/nuvoton.c | 24 ------------- src/superio/nuvoton/common/early_serial.c | 34 ------------------- src/superio/nuvoton/common/nuvoton.h | 28 +++++++++++++-- 6 files changed, 26 insertions(+), 88 deletions(-) delete mode 100644 src/mainboard/asrock/fatal1ty_z87_professional/nuvoton.c delete mode 100644 src/mainboard/asrock/z87_extreme4/nuvoton.c diff --git a/src/mainboard/asrock/fatal1ty_z87_professional/Makefile.mk b/src/mainboard/asrock/fatal1ty_z87_professional/Makefile.mk index de5aa51b34..93f729d787 100644 --- a/src/mainboard/asrock/fatal1ty_z87_professional/Makefile.mk +++ b/src/mainboard/asrock/fatal1ty_z87_professional/Makefile.mk @@ -4,5 +4,3 @@ bootblock-y += bootblock.c bootblock-y += gpio.c romstage-y += gpio.c ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads -smm-y += nuvoton.c -ramstage-y += nuvoton.c diff --git a/src/mainboard/asrock/fatal1ty_z87_professional/nuvoton.c b/src/mainboard/asrock/fatal1ty_z87_professional/nuvoton.c deleted file mode 100644 index 56453329cb..0000000000 --- a/src/mainboard/asrock/fatal1ty_z87_professional/nuvoton.c +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} diff --git a/src/mainboard/asrock/z87_extreme4/Makefile.mk b/src/mainboard/asrock/z87_extreme4/Makefile.mk index 58368c333e..c3cf55d397 100644 --- a/src/mainboard/asrock/z87_extreme4/Makefile.mk +++ b/src/mainboard/asrock/z87_extreme4/Makefile.mk @@ -4,5 +4,3 @@ bootblock-y += bootblock.c bootblock-y += gpio.c romstage-y += gpio.c ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads -ramstage-y += nuvoton.c -smm-y += nuvoton.c diff --git a/src/mainboard/asrock/z87_extreme4/nuvoton.c b/src/mainboard/asrock/z87_extreme4/nuvoton.c deleted file mode 100644 index 56453329cb..0000000000 --- a/src/mainboard/asrock/z87_extreme4/nuvoton.c +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} diff --git a/src/superio/nuvoton/common/early_serial.c b/src/superio/nuvoton/common/early_serial.c index f86e7a27d0..f0162a8f9d 100644 --- a/src/superio/nuvoton/common/early_serial.c +++ b/src/superio/nuvoton/common/early_serial.c @@ -2,21 +2,6 @@ /* * A generic romstage (pre-ram) driver for Nuvoton variant Super I/O chips. - * - * The following is derived directly from the vendor Nuvoton's data-sheets: - * - * To toggle between `configuration mode` and `normal operation mode` as to - * manipulate the various LDN's in Nuvoton Super I/O's we are required to - * pass magic numbers `passwords keys`. - * - * NUVOTON_ENTRY_KEY := enable configuration : 0x87 - * NUVOTON_EXIT_KEY := disable configuration : 0xAA - * - * To modify a LDN's configuration register, we use the index port to select - * the index of the LDN and then write to the data port to alter the - * parameters. A default index, data port pair is 0x4E, 0x4F respectively, a - * user modified pair is 0x2E, 0x2F respectively. - * */ #include @@ -25,25 +10,6 @@ #include #include "nuvoton.h" -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} - /* Bring up early serial debugging output before the RAM is initialized. */ void nuvoton_enable_serial(pnp_devfn_t dev, u16 iobase) { diff --git a/src/superio/nuvoton/common/nuvoton.h b/src/superio/nuvoton/common/nuvoton.h index 0243c69b3e..77eafeb240 100644 --- a/src/superio/nuvoton/common/nuvoton.h +++ b/src/superio/nuvoton/common/nuvoton.h @@ -7,8 +7,32 @@ #include #include -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev); -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev); +#if ENV_PNP_SIMPLE_DEVICE +#include + +/* + * To toggle between `configuration mode` and `normal operation mode` as to + * manipulate the various LDN's in Nuvoton Super I/O's we are required to + * pass magic numbers `passwords keys`. + */ +#define NUVOTON_ENTRY_KEY 0x87 +#define NUVOTON_EXIT_KEY 0xAA + +static __always_inline void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(NUVOTON_ENTRY_KEY, port); + outb(NUVOTON_ENTRY_KEY, port); +} + +static __always_inline void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(NUVOTON_EXIT_KEY, port); +} + +#endif /* SIMPLE_DEVICE */ + void nuvoton_enable_serial(pnp_devfn_t dev, u16 iobase); #endif From 273e84976bdad6ac60682746e7069857019d1b6a Mon Sep 17 00:00:00 2001 From: Keith Hui Date: Tue, 28 Jan 2025 10:11:40 -0500 Subject: [PATCH 091/789] mb/asus/p8z77-v: Apply vendor PCH interrupt mapping Got this information from Bill Xie while troubleshooting CB:85413. Apply the differences from vendor to coreboot. Change-Id: I56f4314eca101cdfcac12594115d373472d1e1db Signed-off-by: Keith Hui Reviewed-on: https://review.coreboot.org/c/coreboot/+/86191 Reviewed-by: Angel Pons Reviewed-by: Bill XIE Tested-by: build bot (Jenkins) --- .../p8x7x-series/variants/p8z77-v/early_init.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c index c2285a7254..e2ab6e0d01 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -9,6 +10,21 @@ #define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) #define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_ACPI) +void mainboard_late_rcba_config(void) +{ + RCBA32(D31IP) = (INTC << D31IP_TTIP) | (INTB << D31IP_SIP2) | + (INTC << D31IP_SMIP) | (INTB << D31IP_SIP); + RCBA32(D22IP) = (INTB << D22IP_KTIP) | (INTC << D22IP_IDERIP) | + (INTB << D22IP_MEI2IP) | (INTA << D22IP_MEI1IP); + + DIR_ROUTE(D31IR, PIRQA, PIRQC, PIRQD, PIRQA); + DIR_ROUTE(D29IR, PIRQH, PIRQD, PIRQA, PIRQC); + DIR_ROUTE(D27IR, PIRQG, PIRQB, PIRQC, PIRQD); + DIR_ROUTE(D26IR, PIRQA, PIRQF, PIRQC, PIRQD); + DIR_ROUTE(D25IR, PIRQE, PIRQF, PIRQG, PIRQH); + DIR_ROUTE(D22IR, PIRQA, PIRQD, PIRQC, PIRQB); +} + void bootblock_mainboard_early_init(void) { nuvoton_pnp_enter_conf_state(GLOBAL_DEV); From 69668852903b97ef053164de27814804e59a0634 Mon Sep 17 00:00:00 2001 From: Yang Wu Date: Wed, 31 Dec 2025 21:13:30 +0800 Subject: [PATCH 092/789] mb/google/skywalker: Extend MIPI panel delay to meet T3 timing Measured on Padme, the T3 (AVEE-to-RESET) timing in the current MIPI panel power-on sequence is only ~120us, which is significantly shorter than the panel specification requirement (>=3ms). This may cause panel initialization instability due to RESET being asserted too early after AVEE is enabled. Increase the delay between AVEE enable and panel reset from 1ms to 5ms to satisfy the panel T3 (AVEE-to-RESET) timing requirement. IL79900A Power on off sequence V1.pdf BUG=b:451746079 TEST=Boot Padme and confirm panel power-on timing is correct. BRANCH=skywalker Change-Id: Ided93c34f7c6695a2928c23eea679f32a0ee9a17 Signed-off-by: Yang Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90664 Tested-by: build bot (Jenkins) Reviewed-by: Yidi Lin Reviewed-by: Yu-Ping Wu --- src/mainboard/google/skywalker/panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/skywalker/panel.c b/src/mainboard/google/skywalker/panel.c index 32d684217e..5856cf4044 100644 --- a/src/mainboard/google/skywalker/panel.c +++ b/src/mainboard/google/skywalker/panel.c @@ -60,7 +60,7 @@ void mipi_panel_power_on(void) mdelay(10); } gpio_output(GPIO_EN_PP3300_EDP_X, 0); - mdelay(1); + mdelay(5); gpio_output(GPIO_EN_PP3300_EDP_X, 1); mdelay(1); gpio_output(GPIO_TCHSCR_RST_1V8_L, 0); From 6f394ce50daf6daf879ac8d1134668d809aaf752 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Sat, 3 Jan 2026 11:07:15 +0800 Subject: [PATCH 093/789] coreboot_tables: Update CB_MEM_TAG and LB_MEM_TAG values to 17 Update the values of CB_MEM_TAG and LB_MEM_TAG from 7 to 17. This change is necessary to avoid conflicts with the ACPI System Address Map Interfaces specification. Change-Id: I802cd724b8f330a9f814fb952ab824cfc23c0e67 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90676 Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- payloads/libpayload/include/coreboot_tables.h | 2 +- src/commonlib/include/commonlib/coreboot_tables.h | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h index 89b0dbc0a4..01d86c272c 100644 --- a/payloads/libpayload/include/coreboot_tables.h +++ b/payloads/libpayload/include/coreboot_tables.h @@ -121,8 +121,8 @@ struct cb_memory_range { #define CB_MEM_NVS 4 #define CB_MEM_UNUSABLE 5 #define CB_MEM_VENDOR_RSVD 6 -#define CB_MEM_TAG 7 #define CB_MEM_TABLE 16 +#define CB_MEM_TAG 17 struct cb_memory { u32 tag; diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index 251e2c4491..817ca0e4f2 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -143,8 +143,12 @@ struct lb_memory_range { #define LB_MEM_NVS 4 /* ACPI NVS Memory */ #define LB_MEM_UNUSABLE 5 /* Unusable address space */ #define LB_MEM_VENDOR_RSVD 6 /* Vendor Reserved */ -#define LB_MEM_TAG 7 /* Armv9 tag storage for MTE */ -#define LB_MEM_TABLE 16 /* Ram configuration tables are kept in */ +/* + * The memory type [1 ... 16) needs to match + * https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/15_System_Address_Map_Interfaces/Sys_Address_Map_Interfaces.html + */ +#define LB_MEM_TABLE 16 /* Ram configuration tables are kept in */ +#define LB_MEM_TAG 17 /* Armv9 tag storage for MTE */ #define LB_MEM_SOFT_RESERVED 0xefffffff /* Specific purpose memory */ }; From eb814f3b12f791eb36a80350f79ee9a1fabfa960 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Sat, 3 Jan 2026 11:28:37 +0800 Subject: [PATCH 094/789] lib/bootmem: Remove forward declaration of bootmem_range_string This commit removes the forward declaration of the static function `bootmem_range_string` by reordering the definition of `bootmem_range_string` and the `type_strings` array. Change-Id: I533660cd06f64011b861656b729eadee07803bf0 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90677 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu --- src/lib/bootmem.c | 66 +++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/lib/bootmem.c b/src/lib/bootmem.c index dbd8450f06..416f1287c6 100644 --- a/src/lib/bootmem.c +++ b/src/lib/bootmem.c @@ -14,7 +14,38 @@ static int table_written; static struct memranges bootmem; static struct memranges bootmem_os; -static const char *bootmem_range_string(const enum bootmem_type tag); +struct range_strings { + enum bootmem_type tag; + const char *str; +}; + +static const struct range_strings type_strings[] = { + { BM_MEM_RAM, "RAM" }, + { BM_MEM_RESERVED, "RESERVED" }, + { BM_MEM_ACPI, "ACPI" }, + { BM_MEM_NVS, "NVS" }, + { BM_MEM_UNUSABLE, "UNUSABLE" }, + { BM_MEM_VENDOR_RSVD, "VENDOR RESERVED" }, + { BM_MEM_BL31, "BL31" }, + { BM_MEM_OPENSBI, "OPENSBI" }, + { BM_MEM_TABLE, "CONFIGURATION TABLES" }, + { BM_MEM_SOFT_RESERVED, "SOFT RESERVED" }, + { BM_MEM_RAMSTAGE, "RAMSTAGE" }, + { BM_MEM_PAYLOAD, "PAYLOAD" }, + { BM_MEM_TAG, "TAG STORAGE" }, +}; + +static const char *bootmem_range_string(const enum bootmem_type tag) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(type_strings); i++) { + if (type_strings[i].tag == tag) + return type_strings[i].str; + } + + return "UNKNOWN!"; +} static int bootmem_is_initialized(void) { @@ -150,39 +181,6 @@ void bootmem_write_memory_table(struct lb_memory *mem) table_written = 1; } -struct range_strings { - enum bootmem_type tag; - const char *str; -}; - -static const struct range_strings type_strings[] = { - { BM_MEM_RAM, "RAM" }, - { BM_MEM_RESERVED, "RESERVED" }, - { BM_MEM_ACPI, "ACPI" }, - { BM_MEM_NVS, "NVS" }, - { BM_MEM_UNUSABLE, "UNUSABLE" }, - { BM_MEM_VENDOR_RSVD, "VENDOR RESERVED" }, - { BM_MEM_BL31, "BL31" }, - { BM_MEM_OPENSBI, "OPENSBI" }, - { BM_MEM_TABLE, "CONFIGURATION TABLES" }, - { BM_MEM_SOFT_RESERVED, "SOFT RESERVED" }, - { BM_MEM_RAMSTAGE, "RAMSTAGE" }, - { BM_MEM_PAYLOAD, "PAYLOAD" }, - { BM_MEM_TAG, "TAG STORAGE" }, -}; - -static const char *bootmem_range_string(const enum bootmem_type tag) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(type_strings); i++) { - if (type_strings[i].tag == tag) - return type_strings[i].str; - } - - return "UNKNOWN!"; -} - void bootmem_dump_ranges(void) { int i; From 999dd8905ad3f3889438a3784e3fc03e791ac2d5 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Sat, 3 Jan 2026 11:33:45 +0800 Subject: [PATCH 095/789] lib/bootmem: Replace conditional return with assert in bootmem_add_range_from Promote the condition where new_tag equals from_tag from a runtime error to an assertion, indicating it as a critical programming error that should not occur. Change-Id: I1fe93b7ee0593d27f70ab3702ad4feae85857ea3 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90678 Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- src/lib/bootmem.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib/bootmem.c b/src/lib/bootmem.c index 416f1287c6..b6be5820d2 100644 --- a/src/lib/bootmem.c +++ b/src/lib/bootmem.c @@ -144,8 +144,7 @@ void bootmem_add_range(uint64_t start, uint64_t size, int bootmem_add_range_from(uint64_t start, uint64_t size, const enum bootmem_type new_tag, const enum bootmem_type from_tag) { - if (new_tag == from_tag) - return -1; + assert(new_tag != from_tag); if (!bootmem_region_targets_type(start, size, from_tag)) { printk(BIOS_ERR, "%s: Failed to add the range [%#llx, %#llx)" From dc162f84bec26b0022b91a744ca065881820fdd4 Mon Sep 17 00:00:00 2001 From: Swathi Tamilselvan Date: Wed, 10 Dec 2025 16:31:35 +0530 Subject: [PATCH 096/789] soc/qualcomm/common: Add RPMh driver support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add RPMh driver support, introducing the core driver that provides an interface to the RPMh protocol for managing ARC/VRM/BCM type resource requests. This includes basic TCS (Trigger Command Sets) handling and helper functions for sending RPMh requests. RPMh (Resource Power Manager – hardware) is a protocol that enables processors (e.g., APSS, LPASS) to send power-related commands to the RPMh hardware block. Dynamic management of power and clocks for shared resources is handled either directly by hardware or by RPM. Key features include: - Core infrastructure for submitting TCS (Trigger Command Sets) commands to the RPMh. - Regulator driver using RPMh for LDOs and SMPS control. - BCM (Bus Clock Manager) voting for clock resources. Test=Create an image.serial.bin and ensure it boots on X1P42100. Change-Id: I1f85459c68d0256e15765b0716856dc928080df9 Signed-off-by: Swathi Tamilselvan Reviewed-on: https://review.coreboot.org/c/coreboot/+/90466 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/soc/qualcomm/common/include/soc/rpmh.h | 25 + .../qualcomm/common/include/soc/rpmh_bcm.h | 17 + .../common/include/soc/rpmh_internal.h | 220 ++++++++ .../common/include/soc/rpmh_regulator.h | 220 ++++++++ .../qualcomm/common/include/soc/rpmh_rsc.h | 87 +++ src/soc/qualcomm/common/include/soc/tcs.h | 72 +++ src/soc/qualcomm/common/rpmh.c | 408 ++++++++++++++ src/soc/qualcomm/common/rpmh_bcm.c | 59 ++ src/soc/qualcomm/common/rpmh_regulator.c | 458 ++++++++++++++++ src/soc/qualcomm/common/rpmh_rsc.c | 511 ++++++++++++++++++ src/soc/qualcomm/x1p42100/Makefile.mk | 1 + 11 files changed, 2078 insertions(+) create mode 100644 src/soc/qualcomm/common/include/soc/rpmh.h create mode 100644 src/soc/qualcomm/common/include/soc/rpmh_bcm.h create mode 100644 src/soc/qualcomm/common/include/soc/rpmh_internal.h create mode 100644 src/soc/qualcomm/common/include/soc/rpmh_regulator.h create mode 100644 src/soc/qualcomm/common/include/soc/rpmh_rsc.h create mode 100644 src/soc/qualcomm/common/include/soc/tcs.h create mode 100644 src/soc/qualcomm/common/rpmh.c create mode 100644 src/soc/qualcomm/common/rpmh_bcm.c create mode 100644 src/soc/qualcomm/common/rpmh_regulator.c create mode 100644 src/soc/qualcomm/common/rpmh_rsc.c diff --git a/src/soc/qualcomm/common/include/soc/rpmh.h b/src/soc/qualcomm/common/include/soc/rpmh.h new file mode 100644 index 0000000000..5b7d76de0b --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/rpmh.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_RPMH_H__ +#define __SOC_QUALCOMM_RPMH_H__ + +#include +#include + +int rpmh_write(enum rpmh_state state, const struct tcs_cmd *cmd, u32 n); + +int rpmh_write_async(enum rpmh_state state, const struct tcs_cmd *cmd, u32 n); + +int rpmh_write_batch(enum rpmh_state state, const struct tcs_cmd *cmd, u32 *n); + +void rpmh_invalidate(void); + +int rpmh_write_sleep_and_wake(void); + +int rpmh_mode_solver_set(bool enable); + +int rpmh_init_fast_path(struct tcs_cmd *cmd, int n); + +int rpmh_update_fast_path(struct tcs_cmd *cmd, int n, u32 update_mask); + +#endif /* __SOC_QUALCOMM_RPMH_H__ */ diff --git a/src/soc/qualcomm/common/include/soc/rpmh_bcm.h b/src/soc/qualcomm/common/include/soc/rpmh_bcm.h new file mode 100644 index 0000000000..e359a26fcb --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/rpmh_bcm.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_RPMH_BCM_H__ +#define __SOC_QUALCOMM_RPMH_BCM_H__ + +#include + +/** + * rpmh_bcm_vote() - Send BCM (Bus Clock Manager) vote to RPMh + * @resource_name: BCM resource name + * @vote_value: Vote value to send + * + * Return: 0 on success, negative error code on failure + */ +int rpmh_bcm_vote(const char *resource_name, u32 vote_value); + +#endif /* __SOC_QUALCOMM_RPMH_BCM_H__ */ diff --git a/src/soc/qualcomm/common/include/soc/rpmh_internal.h b/src/soc/qualcomm/common/include/soc/rpmh_internal.h new file mode 100644 index 0000000000..23cc3a7456 --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/rpmh_internal.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_RPMH_INTERNAL_H__ +#define __SOC_QUALCOMM_RPMH_INTERNAL_H__ + +#include +#include + +#define MAX_NAME_LENGTH 20 + +#define USECS_1S 1000000 +#define USECS_100MS 100000 +#define USECS_10MS 10000 +#define USECS_100US 100 +#define USECS_5US 5 +#define LOOP_DELAY_US 1 +#define LOOP_DELAY_10US 10 + +/* DRV Channel IDs */ +enum { + CH0, + CH1, + MAX_CHANNEL, +}; + +#define TCS_TYPE_NR 5 +#define MAX_CMDS_PER_TCS 16 +#define MAX_TCS_PER_TYPE 3 +#define MAX_TCS_NR (MAX_TCS_PER_TYPE * TCS_TYPE_NR) +#define MAX_TCS_SLOTS (MAX_CMDS_PER_TCS * MAX_TCS_PER_TYPE) + +#define SOLVER_PRESENT 1 +#define HW_CHANNEL_PRESENT 2 + +#define CMD_DB_MAX_RESOURCES 250 + +/* TCS types */ +enum { + ACTIVE_TCS, + SLEEP_TCS, + WAKE_TCS, + CONTROL_TCS, + FAST_PATH_TCS, +}; + +/* RSC register offsets */ +enum { + RSC_DRV_TCS_OFFSET, + RSC_DRV_CMD_OFFSET, + DRV_SOLVER_CONFIG, + DRV_PRNT_CHLD_CONFIG, + RSC_DRV_IRQ_ENABLE, + RSC_DRV_IRQ_STATUS, + RSC_DRV_IRQ_CLEAR, + RSC_DRV_CMD_WAIT_FOR_CMPL, + RSC_DRV_CONTROL, + RSC_DRV_STATUS, + RSC_DRV_CMD_ENABLE, + RSC_DRV_CMD_MSGID, + RSC_DRV_CMD_ADDR, + RSC_DRV_CMD_DATA, + RSC_DRV_CMD_STATUS, + RSC_DRV_CMD_RESP_DATA, + RSC_DRV_CHN_TCS_TRIGGER, + RSC_DRV_CHN_TCS_COMPLETE, + RSC_DRV_CHN_SEQ_BUSY, + RSC_DRV_CHN_SEQ_PC, + RSC_DRV_CHN_UPDATE, + RSC_DRV_CHN_BUSY, + RSC_DRV_CHN_EN, +}; + +/* DRV TCS Configuration Information Register */ +#define DRV_NUM_TCS_MASK 0x3F +#define DRV_NUM_TCS_SHIFT 6 +#define DRV_NCPT_MASK 0x1F +#define DRV_NCPT_SHIFT 27 + +struct rsc_drv; + +/** + * struct cache_req: the request object for caching + * + * @addr: the address of the resource + * @sleep_val: the sleep vote + * @wake_val: the wake vote + */ +struct cache_req { + u32 addr; + u32 sleep_val; + u32 wake_val; +}; + +/** + * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests + * to the controller + * + * @drv: The controller. + * @type: Type of the TCS in this group - active, sleep, wake. + * @mask: Mask of the TCSes relative to all the TCSes in the RSC. + * @offset: Start of the TCS group relative to the TCSes in the RSC. + * @num_tcs: Number of TCSes in this type. + * @ncpt: Number of commands in each TCS. + * @req: Requests that are sent from the TCS. + * @slots: Bitmap indicating which slots are occupied. + */ +struct tcs_group { + struct rsc_drv *drv; + int type; + u32 mask; + u32 offset; + int num_tcs; + int ncpt; + const struct tcs_request *req[MAX_TCS_PER_TYPE]; + u32 slots[MAX_TCS_SLOTS / 32]; +}; + +/** + * struct rpmh_request: the message to be sent to rpmh-rsc + * + * @msg: the request + * @cmd: the payload that will be part of the @msg + */ +struct rpmh_request { + struct tcs_request msg; + struct tcs_cmd cmd[MAX_RPMH_PAYLOAD]; +}; + +/** + * struct rpmh_ctrlr: our representation of the controller + * + * @dirty: was the cache updated since flush + * @in_solver_mode: Controller is busy in solver mode + * @flags: Controller specific flags + * @batch_cache: Cache sleep and wake requests sent as batch + * @non_batch_cache_idx: Index for non-batch cache + * @non_batch_cache: Cache for non-batch requests + */ +struct rpmh_ctrlr { + bool dirty; + bool in_solver_mode; + u32 flags; + struct rpmh_request batch_cache[RPMH_ACTIVE_ONLY_STATE]; + u32 non_batch_cache_idx; + struct cache_req *non_batch_cache; +}; + +/** + * struct drv_channel: our representation of the drv channels + * + * @tcs: TCS groups + * @drv: DRV containing the channel + * @initialized: Whether channel is initialized + */ +struct drv_channel { + struct tcs_group tcs[TCS_TYPE_NR]; + struct rsc_drv *drv; + bool initialized; +}; + +/** + * struct rsc_drv: the Direct Resource Voter (DRV) of the + * Resource State Coordinator controller (RSC) + * + * @name: Controller identifier + * @base: Start address of the DRV registers in this controller + * @tcs_base: Start address of the TCS registers in this controller + * @tcs_distance: Distance between two TCSes + * @id: Instance id in the controller (Direct Resource Voter) + * @num_tcs: Number of TCSes in this DRV + * @num_channels: Number of channels in this DRV + * @in_solver_mode: Controller is busy in solver mode + * @initialized: Whether DRV is initialized + * @tcs: TCS groups + * @ch: DRV channels + * @tcs_in_use: S/W state of the TCS bitmap + * @client: Handle to the DRV's client + * @dev: RSC device + * @regs: Register offsets for RSC controller + */ +struct rsc_drv { + char name[MAX_NAME_LENGTH]; + void *base; + void *tcs_base; + u32 tcs_distance; + unsigned int id; + int num_tcs; + int num_channels; + bool in_solver_mode; + bool initialized; + struct tcs_group tcs[TCS_TYPE_NR]; + struct drv_channel ch[MAX_CHANNEL]; + u32 tcs_in_use[(MAX_TCS_NR + 31) / 32]; + struct rpmh_ctrlr client; + struct device *dev; + u32 *regs; +}; + +extern bool rpmh_standalone; + +int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg, int ch); +int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, + const struct tcs_request *msg, + int ch); +void rpmh_rsc_invalidate(struct rsc_drv *drv, int ch); +int rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable); +int rpmh_rsc_get_channel(struct rsc_drv *drv); +int rpmh_rsc_switch_channel(struct rsc_drv *drv, int ch); +int rpmh_rsc_drv_enable(struct rsc_drv *drv, bool enable); + +int rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch); + +int rpmh_rsc_init_fast_path(struct rsc_drv *drv, const struct tcs_request *msg, int ch); +int rpmh_rsc_update_fast_path(struct rsc_drv *drv, + const struct tcs_request *msg, + u32 update_mask, int ch); + +void rpmh_set_rsc_drv(struct rsc_drv *drv); + +#endif /* __SOC_QUALCOMM_RPMH_INTERNAL_H__ */ diff --git a/src/soc/qualcomm/common/include/soc/rpmh_regulator.h b/src/soc/qualcomm/common/include/soc/rpmh_regulator.h new file mode 100644 index 0000000000..310cd4c7ef --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/rpmh_regulator.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_RPMH_REGULATOR_H__ +#define __SOC_QUALCOMM_RPMH_REGULATOR_H__ + +#include +#include + +#define RPMH_ARC_LEVEL_SIZE 2 +#define RPMH_ARC_MAX_LEVELS 32 +#define RPMH_REGULATOR_LEVEL_OFF 0 + +/* Min and max limits of VRM resource request parameters */ +#define RPMH_VRM_MIN_UV 0 +#define RPMH_VRM_MAX_UV 8191000 +#define RPMH_VRM_STEP_UV 1000 +#define RPMH_VRM_HEADROOM_MIN_UV 0 +#define RPMH_VRM_HEADROOM_MAX_UV 511000 + +#define RPMH_VRM_MODE_MIN 0 +#define RPMH_VRM_MODE_MAX 7 + +/* XOB and PBS voting registers are found in the VRM hardware module */ +#define CMD_DB_HW_XOB CMD_DB_HW_VRM +#define CMD_DB_HW_PBS CMD_DB_HW_VRM + +/* Voltage unknown placeholder */ +#define VOLTAGE_UNKNOWN 1 + +/** + * enum rpmh_regulator_type - supported RPMh accelerator types + * @RPMH_REGULATOR_TYPE_VRM: RPMh VRM accelerator which supports voting on + * enable, voltage, mode, and headroom voltage of + * LDO, SMPS, VS, and BOB type PMIC regulators. + * @RPMH_REGULATOR_TYPE_ARC: RPMh ARC accelerator which supports voting on + * the CPR managed voltage level of LDO and SMPS + * type PMIC regulators. + * @RPMH_REGULATOR_TYPE_XOB: RPMh XOB accelerator which supports voting on + * the enable state of PMIC regulators. + * @RPMH_REGULATOR_TYPE_PBS: RPMh PBS accelerator which supports voting on + * the enable state of PBS resources. + * @RPMH_REGULATOR_TYPE_BCM: RPMh BCM (Bus Clock Manager) accelerator which + * supports voting on bandwidth and clock frequency + * requirements for interconnect and bus resources. + */ +enum rpmh_regulator_type { + RPMH_REGULATOR_TYPE_VRM, + RPMH_REGULATOR_TYPE_ARC, + RPMH_REGULATOR_TYPE_XOB, + RPMH_REGULATOR_TYPE_PBS, + RPMH_REGULATOR_TYPE_BCM, +}; + +/** + * enum rpmh_regulator_reg_index - RPMh accelerator register indices + * @RPMH_REGULATOR_REG_VRM_VOLTAGE: VRM voltage voting register index + * @RPMH_REGULATOR_REG_ARC_LEVEL: ARC voltage level voting register index + * @RPMH_REGULATOR_REG_PBS_ENABLE: PBS enable voting register index + * @RPMH_REGULATOR_REG_VRM_ENABLE: VRM enable voltage voting register index + * @RPMH_REGULATOR_REG_ARC_PSEUDO_ENABLE: Place-holder for enable aggregation + * @RPMH_REGULATOR_REG_XOB_ENABLE: XOB enable voting register index + * @RPMH_REGULATOR_REG_ENABLE: Common enable index + * @RPMH_REGULATOR_REG_VRM_MODE: VRM regulator mode voting register index + * @RPMH_REGULATOR_REG_VRM_HEADROOM: VRM headroom voltage voting register index + * @RPMH_REGULATOR_REG_MAX: Maximum number of registers + */ +enum rpmh_regulator_reg_index { + RPMH_REGULATOR_REG_VRM_VOLTAGE = 0, + RPMH_REGULATOR_REG_ARC_LEVEL = 0, + RPMH_REGULATOR_REG_PBS_ENABLE = 0, + RPMH_REGULATOR_REG_VRM_ENABLE = 1, + RPMH_REGULATOR_REG_ARC_PSEUDO_ENABLE = 1, + RPMH_REGULATOR_REG_XOB_ENABLE = 1, + RPMH_REGULATOR_REG_ENABLE = 1, + RPMH_REGULATOR_REG_VRM_MODE = 2, + RPMH_REGULATOR_REG_VRM_HEADROOM = 3, + RPMH_REGULATOR_REG_MAX = 4, +}; + +/** + * struct rpmh_regulator_request - internal request structure + */ +struct rpmh_regulator_request { + u32 reg[RPMH_REGULATOR_REG_MAX]; + u32 valid; +}; + +/** + * struct rpmh_vreg - individual rpmh regulator data structure + * @resource_name: Name of rpmh regulator resource + * @addr: Base address of the regulator resource within an RPMh accelerator + * @type: RPMh accelerator type for this regulator resource + * @level: Mapping from ARC resource specific voltage levels to consumer levels + * @level_count: The number of valid entries in the level array + * @req_active: Active set RPMh accelerator register request + * @req_sleep: Sleep set RPMh accelerator register request + */ + +struct rpmh_vreg { + const char *resource_name; + u32 addr; + enum rpmh_regulator_type type; + u32 level[RPMH_ARC_MAX_LEVELS]; + int level_count; + struct rpmh_regulator_request req_active; + struct rpmh_regulator_request req_sleep; +}; + + +/** + * rpmh_regulator_init() - initialize an rpmh regulator + * @vreg: Pointer to the rpmh regulator structure to initialize + * @dev: Device pointer for RPMh communication + * @resource_name: Name of the RPMh resource (e.g., "ldoa1") + * @type: Type of regulator (VRM, ARC, XOB, PBS) + * + * This function initializes an RPMh regulator by looking up its address + * in the command DB and loading any necessary configuration data. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_init(struct rpmh_vreg *vreg, const char *resource_name, + enum rpmh_regulator_type type); + +/** + * rpmh_regulator_vrm_set_voltage() - set the voltage of a VRM regulator + * @vreg: Pointer to the rpmh regulator + * @min_uv: Minimum voltage in microvolts + * @max_uv: Maximum voltage in microvolts + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * This function sets the voltage for a VRM type regulator. The actual + * voltage set will be the minimum value that satisfies min_uv. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_vrm_set_voltage(struct rpmh_vreg *vreg, int min_uv, int max_uv, + bool set_active, bool set_sleep); + +/** + * rpmh_regulator_vrm_set_mode() - set the mode of a VRM regulator + * @vreg: Pointer to the rpmh regulator + * @mode: PMIC mode value (use RPMH_REGULATOR_MODE_* defines) + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * This function sets the operating mode for a VRM type regulator. + * The mode value should be one of the RPMH_REGULATOR_MODE_PMIC*_* defines + * appropriate for the regulator type. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_vrm_set_mode(struct rpmh_vreg *vreg, u32 mode, + bool set_active, bool set_sleep); + +/** + * rpmh_regulator_enable() - enable a regulator + * @vreg: Pointer to the rpmh regulator + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * This function enables the regulator. Works for VRM, ARC, XOB, and PBS types. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_enable(struct rpmh_vreg *vreg, bool set_active, bool set_sleep); + +/** + * rpmh_regulator_disable() - disable a regulator + * @vreg: Pointer to the rpmh regulator + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * This function disables the regulator. Works for VRM, ARC, XOB, and PBS types. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_disable(struct rpmh_vreg *vreg, bool set_active, bool set_sleep); + +/** + * rpmh_regulator_arc_set_level() - set the voltage level of an ARC regulator + * @vreg: Pointer to the rpmh regulator + * @level: ARC voltage level (0 to level_count-1) + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * This function sets the voltage level for an ARC type regulator. + * The level is an index into the voltage level table loaded from command DB. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_arc_set_level(struct rpmh_vreg *vreg, u32 level, + bool set_active, bool set_sleep); + +/** + * rpmh_regulator_arc_get_level() - get the current voltage level of an ARC regulator + * @vreg: Pointer to the rpmh regulator + * + * This function returns the cached ARC voltage level that was last set. + * Note: This returns the requested level, not necessarily the actual hardware level, + * as there's no way to read back from RPMh hardware. + * + * Return: ARC voltage level (0 to level_count-1) on success, -1 on failure + */ +int rpmh_regulator_arc_get_level(struct rpmh_vreg *vreg); + +/** + * rpmh_regulator_arc_get_voltage_level() - get the voltage level value for an ARC level + * @vreg: Pointer to the rpmh regulator + * @level: ARC level index + * + * This function returns the actual voltage level value (vlvl) that corresponds + * to the given ARC hardware level (hlvl). + * + * Return: voltage level value on success, 0 on failure + */ +u32 rpmh_regulator_arc_get_voltage_level(struct rpmh_vreg *vreg, u32 level); + +#endif /* __SOC_QUALCOMM_RPMH_REGULATOR_H__ */ diff --git a/src/soc/qualcomm/common/include/soc/rpmh_rsc.h b/src/soc/qualcomm/common/include/soc/rpmh_rsc.h new file mode 100644 index 0000000000..cfe7d601ae --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/rpmh_rsc.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_RPMH_RSC_H__ +#define __SOC_QUALCOMM_RPMH_RSC_H__ + +#include +#include + +u32 rpmh_rsc_reg_offset_ver_2_7[] = { + [RSC_DRV_TCS_OFFSET] = 672, + [RSC_DRV_CMD_OFFSET] = 20, + [DRV_SOLVER_CONFIG] = 0x04, + [DRV_PRNT_CHLD_CONFIG] = 0x0C, + [RSC_DRV_IRQ_ENABLE] = 0x00, + [RSC_DRV_IRQ_STATUS] = 0x04, + [RSC_DRV_IRQ_CLEAR] = 0x08, + [RSC_DRV_CMD_WAIT_FOR_CMPL] = 0x10, + [RSC_DRV_CONTROL] = 0x14, + [RSC_DRV_STATUS] = 0x18, + [RSC_DRV_CMD_ENABLE] = 0x1C, + [RSC_DRV_CMD_MSGID] = 0x30, + [RSC_DRV_CMD_ADDR] = 0x34, + [RSC_DRV_CMD_DATA] = 0x38, + [RSC_DRV_CMD_STATUS] = 0x3C, + [RSC_DRV_CMD_RESP_DATA] = 0x40, + [RSC_DRV_CHN_SEQ_BUSY] = 0x0, + [RSC_DRV_CHN_SEQ_PC] = 0x0, + [RSC_DRV_CHN_TCS_TRIGGER] = 0x0, + [RSC_DRV_CHN_TCS_COMPLETE] = 0x0, + [RSC_DRV_CHN_UPDATE] = 0x0, + [RSC_DRV_CHN_BUSY] = 0x0, + [RSC_DRV_CHN_EN] = 0x0, +}; + +u32 rpmh_rsc_reg_offset_ver_3_0[] = { + [RSC_DRV_TCS_OFFSET] = 672, + [RSC_DRV_CMD_OFFSET] = 24, + [DRV_SOLVER_CONFIG] = 0x04, + [DRV_PRNT_CHLD_CONFIG] = 0x0C, + [RSC_DRV_IRQ_ENABLE] = 0x00, + [RSC_DRV_IRQ_STATUS] = 0x04, + [RSC_DRV_IRQ_CLEAR] = 0x08, + [RSC_DRV_CMD_WAIT_FOR_CMPL] = 0x20, + [RSC_DRV_CONTROL] = 0x24, + [RSC_DRV_STATUS] = 0x28, + [RSC_DRV_CMD_ENABLE] = 0x2C, + [RSC_DRV_CMD_MSGID] = 0x34, + [RSC_DRV_CMD_ADDR] = 0x38, + [RSC_DRV_CMD_DATA] = 0x3C, + [RSC_DRV_CMD_STATUS] = 0x40, + [RSC_DRV_CMD_RESP_DATA] = 0x44, + [RSC_DRV_CHN_SEQ_BUSY] = 0x464, + [RSC_DRV_CHN_SEQ_PC] = 0x468, + [RSC_DRV_CHN_TCS_TRIGGER] = 0x490, + [RSC_DRV_CHN_TCS_COMPLETE] = 0x494, + [RSC_DRV_CHN_UPDATE] = 0x498, + [RSC_DRV_CHN_BUSY] = 0x49C, + [RSC_DRV_CHN_EN] = 0x4A0, +}; + +u32 rpmh_rsc_reg_offset_ver_3_0_hw_channel[] = { + [RSC_DRV_TCS_OFFSET] = 336, + [RSC_DRV_CMD_OFFSET] = 24, + [DRV_SOLVER_CONFIG] = 0x04, + [DRV_PRNT_CHLD_CONFIG] = 0x0C, + [RSC_DRV_IRQ_ENABLE] = 0x00, + [RSC_DRV_IRQ_STATUS] = 0x04, + [RSC_DRV_IRQ_CLEAR] = 0x08, + [RSC_DRV_CMD_WAIT_FOR_CMPL] = 0x20, + [RSC_DRV_CONTROL] = 0x24, + [RSC_DRV_STATUS] = 0x28, + [RSC_DRV_CMD_ENABLE] = 0x2C, + [RSC_DRV_CMD_MSGID] = 0x34, + [RSC_DRV_CMD_ADDR] = 0x38, + [RSC_DRV_CMD_DATA] = 0x3C, + [RSC_DRV_CMD_STATUS] = 0x40, + [RSC_DRV_CMD_RESP_DATA] = 0x44, + [RSC_DRV_CHN_SEQ_BUSY] = 0x464, + [RSC_DRV_CHN_SEQ_PC] = 0x468, + [RSC_DRV_CHN_TCS_TRIGGER] = 0x490, + [RSC_DRV_CHN_TCS_COMPLETE] = 0x494, + [RSC_DRV_CHN_UPDATE] = 0x498, + [RSC_DRV_CHN_BUSY] = 0x49C, + [RSC_DRV_CHN_EN] = 0x4A0, +}; + +#endif /* __SOC_QUALCOMM_RPMH_RSC_H__ */ diff --git a/src/soc/qualcomm/common/include/soc/tcs.h b/src/soc/qualcomm/common/include/soc/tcs.h new file mode 100644 index 0000000000..260e010862 --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/tcs.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_TCS_H__ +#define __SOC_QUALCOMM_TCS_H__ + +#include + +#define MAX_RPMH_PAYLOAD 16 + +/** + * rpmh_state: state for the request + * + * RPMH_SLEEP_STATE: State of the resource when the processor subsystem + * is powered down. There is no client using the + * resource actively. + * RPMH_WAKE_ONLY_STATE: Resume resource state to the value previously + * requested before the processor was powered down. + * RPMH_ACTIVE_ONLY_STATE: Active or AMC mode requests. Resource state + * is aggregated immediately. + */ +enum rpmh_state { + RPMH_SLEEP_STATE, + RPMH_WAKE_ONLY_STATE, + RPMH_ACTIVE_ONLY_STATE, +}; + +/** + * struct tcs_cmd: an individual request to RPMH. + * + * @addr: the address of the resource slv_id:18:16 | offset:0:15 + * @data: the resource state request + * @wait: ensure that this command is complete before returning. + */ +struct tcs_cmd { + u32 addr; + u32 data; + u32 wait; +}; + +/** + * struct tcs_request: A set of tcs_cmds sent together in a TCS + * + * @state: state for the request. + * @wait_for_compl: wait until we get a response from the h/w accelerator + * @num_cmds: the number of @cmds in this request + * @cmds: an array of tcs_cmds + */ +struct tcs_request { + enum rpmh_state state; + u32 wait_for_compl; + u32 num_cmds; + struct tcs_cmd *cmds; +}; + +#define BCM_TCS_CMD_COMMIT_SHFT 30 +#define BCM_TCS_CMD_COMMIT_MASK 0x40000000 +#define BCM_TCS_CMD_VALID_SHFT 29 +#define BCM_TCS_CMD_VALID_MASK 0x20000000 +#define BCM_TCS_CMD_VOTE_X_SHFT 14 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_Y_SHFT 0 +#define BCM_TCS_CMD_VOTE_Y_MASK 0xfffc000 + +/* Construct a Bus Clock Manager (BCM) specific TCS command */ +#define BCM_TCS_CMD(commit, valid, vote_x, vote_y) \ + cpu_to_le32( \ + (((uint32_t)(commit) & 0x1) << BCM_TCS_CMD_COMMIT_SHFT) | \ + (((uint32_t)(valid) & 0x1) << BCM_TCS_CMD_VALID_SHFT) | \ + (((uint32_t)(vote_x) & BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_X_SHFT) | \ + (((uint32_t)(vote_y) & BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_Y_SHFT) \ + ) +#endif /* __SOC_QUALCOMM_TCS_H__ */ diff --git a/src/soc/qualcomm/common/rpmh.c b/src/soc/qualcomm/common/rpmh.c new file mode 100644 index 0000000000..bd348a07a9 --- /dev/null +++ b/src/soc/qualcomm/common/rpmh.c @@ -0,0 +1,408 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include + +#define RPMH_TIMEOUT_MS 10000 + +#define DEFINE_RPMH_MSG_ONSTACK(s, name) \ + struct rpmh_request name = { \ + .msg = { \ + .state = s, \ + .cmds = name.cmd, \ + .num_cmds = 0, \ + .wait_for_compl = 1, \ + }, \ + .cmd = { { 0 } }, \ + } + +#define ctrlr_to_drv(ctrlr) \ + ((struct rsc_drv *)((char *)(ctrlr) - offsetof(struct rsc_drv, client))) + +bool rpmh_standalone; + +static struct rsc_drv *g_rsc_drv = NULL; + +static struct rpmh_ctrlr *get_rpmh_ctrlr(void) +{ + return g_rsc_drv ? &g_rsc_drv->client : NULL; +} + +void rpmh_set_rsc_drv(struct rsc_drv *drv) +{ + g_rsc_drv = drv; +} + +static int check_ctrlr_state(struct rpmh_ctrlr *ctrlr, enum rpmh_state state) +{ + if (state != RPMH_ACTIVE_ONLY_STATE) + return 0; + + if (!(ctrlr->flags & SOLVER_PRESENT)) + return 0; + + if (ctrlr->in_solver_mode) + return -1; + + return 0; +} + +static struct cache_req *get_non_batch_cache_req(struct rpmh_ctrlr *ctrlr, u32 addr) +{ + struct cache_req *req = ctrlr->non_batch_cache; + unsigned int i; + + if (ctrlr->non_batch_cache_idx >= CMD_DB_MAX_RESOURCES) + return NULL; + + for (i = 0; i < ctrlr->non_batch_cache_idx; i++) { + req = &ctrlr->non_batch_cache[i]; + if (req->addr == addr) + return req; + } + + req = &ctrlr->non_batch_cache[ctrlr->non_batch_cache_idx]; + req->sleep_val = req->wake_val = UINT_MAX; + ctrlr->non_batch_cache_idx++; + + return req; +} + +static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr, + enum rpmh_state state, + struct tcs_cmd *cmd) +{ + struct cache_req *req; + u32 old_sleep_val, old_wake_val; + + req = get_non_batch_cache_req(ctrlr, cmd->addr); + if (!req) + return NULL; + + req->addr = cmd->addr; + old_sleep_val = req->sleep_val; + old_wake_val = req->wake_val; + + switch (state) { + case RPMH_ACTIVE_ONLY_STATE: + case RPMH_WAKE_ONLY_STATE: + req->wake_val = cmd->data; + break; + case RPMH_SLEEP_STATE: + req->sleep_val = cmd->data; + break; + } + + ctrlr->dirty |= (req->sleep_val != old_sleep_val || + req->wake_val != old_wake_val) && + req->sleep_val != UINT_MAX && + req->wake_val != UINT_MAX; + + return req; +} + +static int __rpmh_write(enum rpmh_state state, struct rpmh_request *rpm_msg) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ret = -1; + struct cache_req *req; + int i, ch; + + if (rpmh_standalone) + return 0; + + if (!ctrlr) + return -1; + + for (i = 0; i < rpm_msg->msg.num_cmds; i++) { + req = cache_rpm_request(ctrlr, state, &rpm_msg->msg.cmds[i]); + if (!req) + return -1; + } + + if (state == RPMH_ACTIVE_ONLY_STATE) { + ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); + if (ch < 0) + return ch; + + ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg->msg, ch); + } else { + ret = 0; + } + + return ret; +} + +static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state, + const struct tcs_cmd *cmd, u32 num_cmds) +{ + if (!cmd || !num_cmds || num_cmds > MAX_RPMH_PAYLOAD) + return -1; + + memcpy(req->cmd, cmd, num_cmds * sizeof(*cmd)); + + req->msg.state = state; + req->msg.cmds = req->cmd; + req->msg.num_cmds = num_cmds; + + return 0; +} + +int rpmh_write_async(enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) +{ + DEFINE_RPMH_MSG_ONSTACK(state, rpm_msg); + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ret; + + if (rpmh_standalone) + return 0; + + if (!ctrlr) + return -1; + + rpm_msg.msg.wait_for_compl = 0; + ret = check_ctrlr_state(ctrlr, state); + if (ret) + return ret; + + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n); + if (ret) + return ret; + + return __rpmh_write(state, &rpm_msg); +} + +int rpmh_write(enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) +{ + DEFINE_RPMH_MSG_ONSTACK(state, rpm_msg); + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ret; + + if (rpmh_standalone) + return 0; + + if (!ctrlr) + return -1; + + ret = check_ctrlr_state(ctrlr, state); + if (ret) + return ret; + + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n); + if (ret) + return ret; + + ret = __rpmh_write(state, &rpm_msg); + + return ret; +} + +static int flush_batch(struct rpmh_ctrlr *ctrlr, int ch) +{ + int ret; + + /* Send Sleep/Wake requests to the controller */ + ret = rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), + &ctrlr->batch_cache[RPMH_SLEEP_STATE].msg, ch); + if (ret) + return ret; + + return rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), + &ctrlr->batch_cache[RPMH_WAKE_ONLY_STATE].msg, ch); +} + +int rpmh_write_batch(enum rpmh_state state, const struct tcs_cmd *cmd, u32 *n) +{ + DEFINE_RPMH_MSG_ONSTACK(state, rpm_msg); + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ret, ch; + + if (rpmh_standalone) + return 0; + + if (!ctrlr) + return -1; + + ret = check_ctrlr_state(ctrlr, state); + if (ret) + return ret; + + if (state == RPMH_ACTIVE_ONLY_STATE) { + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, *n); + if (ret) + return ret; + } else { + memset(&ctrlr->batch_cache[state], 0, sizeof(struct rpmh_request)); + ret = __fill_rpmh_msg(&ctrlr->batch_cache[state], state, cmd, *n); + ctrlr->dirty = 1; + return ret; + } + + ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); + if (ch < 0) + return ch; + + ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg.msg, ch); + if (ret) { + printk(BIOS_ERR, "RPMH: Error sending message addr=%#x\n", + rpm_msg.msg.cmds[0].addr); + return ret; + } + + return 0; +} + +static int is_req_valid(struct cache_req *req) +{ + return (req->sleep_val != UINT_MAX && + req->wake_val != UINT_MAX && + req->sleep_val != req->wake_val); +} + +static int send_single(struct rpmh_ctrlr *ctrlr, enum rpmh_state state, + u32 addr, u32 data, int ch) +{ + DEFINE_RPMH_MSG_ONSTACK(state, rpm_msg); + + /* Wake sets are always complete and sleep sets are not */ + rpm_msg.msg.wait_for_compl = (state == RPMH_WAKE_ONLY_STATE); + rpm_msg.cmd[0].addr = addr; + rpm_msg.cmd[0].data = data; + rpm_msg.msg.num_cmds = 1; + + return rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), &rpm_msg.msg, ch); +} + +int rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch) +{ + struct cache_req *p; + int ret = 0, i; + + if (!ctrlr->dirty) { + printk(BIOS_DEBUG, "RPMH: Skipping flush, TCS has latest data\n"); + return 0; + } + + /* Invalidate the TCSes first to avoid stale data */ + rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr), ch); + + /* First flush the cached batch requests */ + ret = flush_batch(ctrlr, ch); + if (ret) + return ret; + + for (i = 0; i < ctrlr->non_batch_cache_idx; i++) { + p = &ctrlr->non_batch_cache[i]; + if (!is_req_valid(p)) { + printk(BIOS_DEBUG, "RPMH: skipping req: a:%#x s:%#x w:%#x\n", + p->addr, p->sleep_val, p->wake_val); + continue; + } + ret = send_single(ctrlr, RPMH_SLEEP_STATE, p->addr, + p->sleep_val, ch); + if (ret) + return ret; + ret = send_single(ctrlr, RPMH_WAKE_ONLY_STATE, p->addr, + p->wake_val, ch); + if (ret) + return ret; + } + + ctrlr->dirty = 0; + return ret; +} + +int rpmh_write_sleep_and_wake(void) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ch, ret; + + if (!ctrlr) + return -1; + + ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); + if (ch < 0) + return ch; + + ret = rpmh_flush(ctrlr, ch); + if (ret || !(ctrlr->flags & HW_CHANNEL_PRESENT)) + return ret; + + return rpmh_rsc_switch_channel(ctrlr_to_drv(ctrlr), ch); +} + +void rpmh_invalidate(void) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + + if (rpmh_standalone || !ctrlr) + return; + + memset(&ctrlr->batch_cache[RPMH_SLEEP_STATE], 0, sizeof(struct rpmh_request)); + memset(&ctrlr->batch_cache[RPMH_WAKE_ONLY_STATE], 0, sizeof(struct rpmh_request)); + ctrlr->dirty = 1; +} + +int rpmh_mode_solver_set(bool enable) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ret; + + if (rpmh_standalone || !ctrlr) + return 0; + + if (!(ctrlr->flags & SOLVER_PRESENT)) + return -1; + + ret = rpmh_rsc_mode_solver_set(ctrlr_to_drv(ctrlr), enable); + if (!ret) + ctrlr->in_solver_mode = enable; + + return ret; +} + +int rpmh_init_fast_path(struct tcs_cmd *cmd, int n) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + struct tcs_request req; + int ch; + + if (rpmh_standalone || !ctrlr) + return 0; + + ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); + if (ch < 0) + return ch; + + req.cmds = cmd; + req.num_cmds = n; + req.wait_for_compl = 0; + + return rpmh_rsc_init_fast_path(ctrlr_to_drv(ctrlr), &req, ch); +} + +int rpmh_update_fast_path(struct tcs_cmd *cmd, int n, u32 update_mask) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + struct tcs_request req; + int ch; + + if (rpmh_standalone || !ctrlr) + return 0; + + ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); + if (ch < 0) + return ch; + + req.cmds = cmd; + req.num_cmds = n; + req.wait_for_compl = 0; + + return rpmh_rsc_update_fast_path(ctrlr_to_drv(ctrlr), &req, + update_mask, ch); +} diff --git a/src/soc/qualcomm/common/rpmh_bcm.c b/src/soc/qualcomm/common/rpmh_bcm.c new file mode 100644 index 0000000000..01de7ffd88 --- /dev/null +++ b/src/soc/qualcomm/common/rpmh_bcm.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include +#include +#include +#include +#include + +/** + * rpmh_bcm_vote() - Send BCM (Bus Clock Manager) vote to RPMh + * @dev: Device pointer for RPMh communication + * @resource_name: BCM resource name (e.g., "MM0", "SH0") + * @vote_value: Vote value to send + * + * This function sends a BCM vote to RPMh to enable bandwidth/clock requirements. + * It looks up the resource address from Command DB and sends the vote via TCS command. + * + * Return: 0 on success, negative error code on failure + */ +int rpmh_bcm_vote(const char *resource_name, u32 vote_value) +{ + u32 bcm_addr; + struct tcs_cmd cmd; + int rc; + + if (!resource_name) { + printk(BIOS_ERR, "BCM: Invalid parameters\n"); + return -1; + } + + /* Get the RPMh address for the BCM resource from Command DB */ + bcm_addr = cmd_db_read_addr(resource_name); + if (!bcm_addr) { + printk(BIOS_ERR, "BCM: Could not find RPMh address for resource %s\n", + resource_name); + return -1; + } + + printk(BIOS_DEBUG, "BCM: Found address 0x%08X for resource %s\n", + bcm_addr, resource_name); + + /* Prepare TCS command */ + cmd.addr = bcm_addr; + cmd.data = vote_value; + cmd.wait = true; + + /* Send BCM vote via RPMh in active-only state */ + rc = rpmh_write(RPMH_ACTIVE_ONLY_STATE, &cmd, 1); + if (rc) { + printk(BIOS_ERR, "BCM: Failed to send vote for %s (addr=0x%08X, val=0x%08X): %d\n", + resource_name, bcm_addr, vote_value, rc); + return rc; + } + + printk(BIOS_INFO, "BCM: Successfully voted for %s (addr=0x%08X, val=0x%08X)\n", + resource_name, bcm_addr, vote_value); + + return 0; +} diff --git a/src/soc/qualcomm/common/rpmh_regulator.c b/src/soc/qualcomm/common/rpmh_regulator.c new file mode 100644 index 0000000000..c273333349 --- /dev/null +++ b/src/soc/qualcomm/common/rpmh_regulator.c @@ -0,0 +1,458 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * rpmh_regulator_load_arc_level_mapping() - load the RPMh ARC resource's + * voltage level mapping from command db + * @vreg: Pointer to the rpmh regulator + * + * Return: 0 on success, -1 on failure + */ +static int rpmh_regulator_load_arc_level_mapping(struct rpmh_vreg *vreg) +{ + size_t len = 0; + int i, j; + const u8 *buf; + + buf = cmd_db_read_aux_data(vreg->resource_name, &len); + if (!buf) { + printk(BIOS_ERR, "RPMH_REG: Could not retrieve ARC aux data for %s\n", + vreg->resource_name); + return -1; + } + + if (len == 0) { + printk(BIOS_ERR, "RPMH_REG: ARC level mapping data missing for %s\n", + vreg->resource_name); + return -1; + } + + if (len > RPMH_ARC_MAX_LEVELS * RPMH_ARC_LEVEL_SIZE) { + printk(BIOS_ERR, "RPMH_REG: Too many ARC levels defined for %s: %zu > %d\n", + vreg->resource_name, len, RPMH_ARC_MAX_LEVELS * RPMH_ARC_LEVEL_SIZE); + return -1; + } + + if (len % RPMH_ARC_LEVEL_SIZE) { + printk(BIOS_ERR, "RPMH_REG: Invalid ARC aux data size for %s: %zu\n", + vreg->resource_name, len); + return -1; + } + + vreg->level_count = len / RPMH_ARC_LEVEL_SIZE; + + for (i = 0; i < vreg->level_count; i++) { + vreg->level[i] = 0; + for (j = 0; j < RPMH_ARC_LEVEL_SIZE; j++) + vreg->level[i] |= buf[i * RPMH_ARC_LEVEL_SIZE + j] << (8 * j); + + /* The AUX data may be zero padded - ignore 0 valued entries at the end */ + if (i > 0 && vreg->level[i] == 0) { + vreg->level_count = i; + break; + } + + printk(BIOS_DEBUG, "RPMH_REG: %s ARC hlvl=%2d --> vlvl=%4u\n", + vreg->resource_name, i, vreg->level[i]); + } + + return 0; +} + +/** + * rpmh_regulator_send_request() - send the RPMh request + * @vreg: Pointer to the rpmh regulator + * @req: Request to send + * @state: RPMh state (active/sleep) + * @wait: Whether to wait for completion + * + * Return: 0 on success, -1 on failure + */ +static int rpmh_regulator_send_request(struct rpmh_vreg *vreg, + struct rpmh_regulator_request *req, + enum rpmh_state state, bool wait) +{ + struct tcs_cmd cmd[RPMH_REGULATOR_REG_MAX]; + int i, j = 0; + int rc; + + /* Build command array from valid registers */ + for (i = 0; i < RPMH_REGULATOR_REG_MAX; i++) { + if (req->valid & BIT(i)) { + cmd[j].addr = vreg->addr + i * 4; + cmd[j].data = req->reg[i]; + cmd[j].wait = true; + j++; + } + } + if (j == 0) + return 0; + + /* Send the request */ + if (wait) + rc = rpmh_write(state, cmd, j); + else + rc = rpmh_write_async(state, cmd, j); + + if (rc) { + printk(BIOS_ERR, "RPMH_REG: Failed to send %s request for %s, rc=%d\n", + state == RPMH_ACTIVE_ONLY_STATE ? "active" : "sleep", + vreg->resource_name, rc); + return rc; + } + + printk(BIOS_DEBUG, "RPMH_REG: Sent %s request for %s\n", + state == RPMH_ACTIVE_ONLY_STATE ? "active" : "sleep", + vreg->resource_name); + + return 0; +} + +/** + * rpmh_regulator_vrm_set_voltage() - set the voltage of a VRM regulator + * @vreg: Pointer to the rpmh regulator + * @min_uv: Minimum voltage in microvolts + * @max_uv: Maximum voltage in microvolts + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_vrm_set_voltage(struct rpmh_vreg *vreg, int min_uv, int max_uv, + bool set_active, bool set_sleep) +{ + int mv; + int rc = 0; + + if (!vreg || vreg->type != RPMH_REGULATOR_TYPE_VRM) + return -1; + + if (min_uv < RPMH_VRM_MIN_UV || max_uv > RPMH_VRM_MAX_UV) { + printk(BIOS_ERR, "RPMH_REG: Voltage range %d-%d uV out of bounds for %s\n", + min_uv, max_uv, vreg->resource_name); + return -1; + } + + mv = DIV_ROUND_UP(min_uv, 1000); + if (mv * 1000 > max_uv) { + printk(BIOS_ERR, "RPMH_REG: No set points available in range %d-%d uV for %s\n", + min_uv, max_uv, vreg->resource_name); + return -1; + } + + if (set_active) { + vreg->req_active.reg[RPMH_REGULATOR_REG_VRM_VOLTAGE] = mv; + vreg->req_active.valid |= BIT(RPMH_REGULATOR_REG_VRM_VOLTAGE); + rc = rpmh_regulator_send_request(vreg, &vreg->req_active, + RPMH_ACTIVE_ONLY_STATE, true); + if (rc) + return rc; + } + + if (set_sleep) { + vreg->req_sleep.reg[RPMH_REGULATOR_REG_VRM_VOLTAGE] = mv; + vreg->req_sleep.valid |= BIT(RPMH_REGULATOR_REG_VRM_VOLTAGE); + rc = rpmh_regulator_send_request(vreg, &vreg->req_sleep, + RPMH_SLEEP_STATE, false); + } + + return rc; +} + +/** + * rpmh_regulator_vrm_set_mode() - set the mode of a VRM regulator + * @vreg: Pointer to the rpmh regulator + * @mode: PMIC mode value + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_vrm_set_mode(struct rpmh_vreg *vreg, u32 mode, + bool set_active, bool set_sleep) +{ + int rc = 0; + + if (!vreg || vreg->type != RPMH_REGULATOR_TYPE_VRM) + return -1; + + if (mode < RPMH_VRM_MODE_MIN || mode > RPMH_VRM_MODE_MAX) { + printk(BIOS_ERR, "RPMH_REG: Mode %u out of range for %s\n", + mode, vreg->resource_name); + return -1; + } + + if (set_active) { + vreg->req_active.reg[RPMH_REGULATOR_REG_VRM_MODE] = mode; + vreg->req_active.valid |= BIT(RPMH_REGULATOR_REG_VRM_MODE); + rc = rpmh_regulator_send_request(vreg, &vreg->req_active, + RPMH_ACTIVE_ONLY_STATE, true); + if (rc) + return rc; + } + + if (set_sleep) { + vreg->req_sleep.reg[RPMH_REGULATOR_REG_VRM_MODE] = mode; + vreg->req_sleep.valid |= BIT(RPMH_REGULATOR_REG_VRM_MODE); + rc = rpmh_regulator_send_request(vreg, &vreg->req_sleep, + RPMH_SLEEP_STATE, false); + } + + return rc; +} + +/** + * rpmh_regulator_enable() - enable a regulator + * @vreg: Pointer to the rpmh regulator + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_enable(struct rpmh_vreg *vreg, bool set_active, bool set_sleep) +{ + int rc = 0; + int reg_index; + + if (!vreg) + return -1; + + /* Determine the correct enable register based on type */ + switch (vreg->type) { + case RPMH_REGULATOR_TYPE_VRM: + case RPMH_REGULATOR_TYPE_ARC: + case RPMH_REGULATOR_TYPE_XOB: + reg_index = RPMH_REGULATOR_REG_ENABLE; + break; + case RPMH_REGULATOR_TYPE_PBS: + reg_index = RPMH_REGULATOR_REG_PBS_ENABLE; + break; + default: + return -1; + } + + if (set_active) { + vreg->req_active.reg[reg_index] = 1; + vreg->req_active.valid |= BIT(reg_index); + rc = rpmh_regulator_send_request(vreg, &vreg->req_active, + RPMH_ACTIVE_ONLY_STATE, true); + if (rc) + return rc; + } + + if (set_sleep) { + vreg->req_sleep.reg[reg_index] = 1; + vreg->req_sleep.valid |= BIT(reg_index); + rc = rpmh_regulator_send_request(vreg, &vreg->req_sleep, + RPMH_SLEEP_STATE, false); + } + + return rc; +} + +/** + * rpmh_regulator_disable() - disable a regulator + * @vreg: Pointer to the rpmh regulator + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_disable(struct rpmh_vreg *vreg, bool set_active, bool set_sleep) +{ + int rc = 0; + int reg_index; + + if (!vreg) + return -1; + + /* Determine the correct enable register based on type */ + switch (vreg->type) { + case RPMH_REGULATOR_TYPE_VRM: + case RPMH_REGULATOR_TYPE_ARC: + case RPMH_REGULATOR_TYPE_XOB: + reg_index = RPMH_REGULATOR_REG_ENABLE; + break; + case RPMH_REGULATOR_TYPE_PBS: + reg_index = RPMH_REGULATOR_REG_PBS_ENABLE; + break; + default: + return -1; + } + + if (set_active) { + vreg->req_active.reg[reg_index] = 0; + vreg->req_active.valid |= BIT(reg_index); + rc = rpmh_regulator_send_request(vreg, &vreg->req_active, + RPMH_ACTIVE_ONLY_STATE, true); + if (rc) + return rc; + } + + if (set_sleep) { + vreg->req_sleep.reg[reg_index] = 0; + vreg->req_sleep.valid |= BIT(reg_index); + rc = rpmh_regulator_send_request(vreg, &vreg->req_sleep, + RPMH_SLEEP_STATE, false); + } + + return rc; +} + +/** + * rpmh_regulator_arc_set_level() - set the voltage level of an ARC regulator + * @vreg: Pointer to the rpmh regulator + * @level: ARC voltage level (0 to level_count-1) + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_arc_set_level(struct rpmh_vreg *vreg, u32 level, + bool set_active, bool set_sleep) +{ + int rc = 0; + + if (!vreg || vreg->type != RPMH_REGULATOR_TYPE_ARC) + return -1; + + if (level >= vreg->level_count) { + printk(BIOS_ERR, "RPMH_REG: Level %u out of range for %s (max %d)\n", + level, vreg->resource_name, vreg->level_count - 1); + return -1; + } + + if (set_active) { + vreg->req_active.reg[RPMH_REGULATOR_REG_ARC_LEVEL] = level; + vreg->req_active.valid |= BIT(RPMH_REGULATOR_REG_ARC_LEVEL); + rc = rpmh_regulator_send_request(vreg, &vreg->req_active, + RPMH_ACTIVE_ONLY_STATE, true); + if (rc) + return rc; + } + + if (set_sleep) { + vreg->req_sleep.reg[RPMH_REGULATOR_REG_ARC_LEVEL] = level; + vreg->req_sleep.valid |= BIT(RPMH_REGULATOR_REG_ARC_LEVEL); + rc = rpmh_regulator_send_request(vreg, &vreg->req_sleep, + RPMH_SLEEP_STATE, false); + } + + return rc; +} + +/** + * rpmh_regulator_arc_get_level() - get the current voltage level of an ARC regulator + * @vreg: Pointer to the rpmh regulator + * + * This function returns the cached ARC voltage level that was last set. + * Note: This returns the requested level, not necessarily the actual hardware level, + * as there's no way to read back from RPMh hardware. + * + * Return: ARC voltage level (0 to level_count-1) on success, -1 on failure + */ +int rpmh_regulator_arc_get_level(struct rpmh_vreg *vreg) +{ + if (!vreg || vreg->type != RPMH_REGULATOR_TYPE_ARC) + return -1; + + /* Return the active set level if valid, otherwise return 0 */ + if (vreg->req_active.valid & BIT(RPMH_REGULATOR_REG_ARC_LEVEL)) + return vreg->req_active.reg[RPMH_REGULATOR_REG_ARC_LEVEL]; + + return 0; +} + +/** + * rpmh_regulator_arc_get_voltage_level() - get the voltage level value for an ARC level + * @vreg: Pointer to the rpmh regulator + * @level: ARC level index + * + * This function returns the actual voltage level value (vlvl) that corresponds + * to the given ARC hardware level (hlvl). + * + * Return: voltage level value on success, 0 on failure + */ +u32 rpmh_regulator_arc_get_voltage_level(struct rpmh_vreg *vreg, u32 level) +{ + if (!vreg || vreg->type != RPMH_REGULATOR_TYPE_ARC) + return 0; + + if (level >= vreg->level_count) + return 0; + + return vreg->level[level]; +} + +/** + * rpmh_regulator_init() - initialize an rpmh regulator + * @vreg: Pointer to the rpmh regulator structure to initialize + * @dev: Device pointer for RPMh communication + * @resource_name: Name of the RPMh resource + * @type: Type of regulator (VRM, ARC, XOB, PBS) + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_init(struct rpmh_vreg *vreg, const char *resource_name, + enum rpmh_regulator_type type) +{ + enum cmd_db_hw_type hw_type; + int rc; + + if (!vreg || !resource_name) + return -1; + + memset(vreg, 0, sizeof(*vreg)); + + vreg->resource_name = resource_name; + vreg->type = type; + + /* Get the RPMh address for this resource */ + vreg->addr = cmd_db_read_addr(resource_name); + if (!vreg->addr) { + printk(BIOS_ERR, "RPMH_REG: Could not find RPMh address for %s\n", + resource_name); + return -1; + } + + /* Verify the slave ID matches the expected type */ + hw_type = cmd_db_read_slave_id(resource_name); + if (hw_type == CMD_DB_HW_INVALID) { + printk(BIOS_ERR, "RPMH_REG: Could not find slave ID for %s\n", + resource_name); + return -1; + } + + /* Validate hardware type matches regulator type */ + if ((type == RPMH_REGULATOR_TYPE_ARC && hw_type != CMD_DB_HW_ARC) || + (type == RPMH_REGULATOR_TYPE_VRM && hw_type != CMD_DB_HW_VRM) || + (type == RPMH_REGULATOR_TYPE_XOB && hw_type != CMD_DB_HW_XOB) || + (type == RPMH_REGULATOR_TYPE_BCM && hw_type != CMD_DB_HW_BCM) || + (type == RPMH_REGULATOR_TYPE_PBS && hw_type != CMD_DB_HW_PBS)) { + printk(BIOS_ERR, "RPMH_REG: Hardware type mismatch for %s\n", + resource_name); + return -1; + } + + /* Load ARC level mapping if this is an ARC regulator */ + if (type == RPMH_REGULATOR_TYPE_ARC) { + rc = rpmh_regulator_load_arc_level_mapping(vreg); + if (rc) { + printk(BIOS_ERR, "RPMH_REG: Failed to load ARC level mapping for %s\n", + resource_name); + return rc; + } + } + printk(BIOS_INFO, "RPMH_REG: Initialized %s at addr=0x%05X\n", + resource_name, vreg->addr); + + return 0; +} diff --git a/src/soc/qualcomm/common/rpmh_rsc.c b/src/soc/qualcomm/common/rpmh_rsc.c new file mode 100644 index 0000000000..e93d4454eb --- /dev/null +++ b/src/soc/qualcomm/common/rpmh_rsc.c @@ -0,0 +1,511 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TCS_AMC_MODE_ENABLE BIT(16) +#define TCS_AMC_MODE_TRIGGER BIT(24) + +/* TCS CMD register bit mask */ +#define CMD_MSGID_LEN 8 +#define CMD_MSGID_RESP_REQ BIT(8) +#define CMD_MSGID_WRITE BIT(16) +#define CMD_STATUS_ISSUED BIT(8) +#define CMD_STATUS_COMPL BIT(16) + +/* Offsets for DRV channel status register */ +#define CH0_CHN_BUSY BIT(0) +#define CH1_CHN_BUSY BIT(1) +#define CH0_WAKE_TCS_STATUS BIT(0) +#define CH0_SLEEP_TCS_STATUS BIT(1) +#define CH1_WAKE_TCS_STATUS BIT(2) +#define CH1_SLEEP_TCS_STATUS BIT(3) +#define CH_CLEAR_STATUS BIT(31) + +static inline void *tcs_reg_addr(const struct rsc_drv *drv, int reg, int tcs_id) +{ + if (!drv->tcs_distance) + return drv->tcs_base + drv->regs[RSC_DRV_TCS_OFFSET] * tcs_id + reg; + + return drv->tcs_base + drv->tcs_distance * tcs_id + reg; +} + +static inline void *tcs_cmd_addr(const struct rsc_drv *drv, int reg, int tcs_id, int cmd_id) +{ + return tcs_reg_addr(drv, reg, tcs_id) + drv->regs[RSC_DRV_CMD_OFFSET] * cmd_id; +} + +static u32 read_tcs_cmd(const struct rsc_drv *drv, int reg, int tcs_id, int cmd_id) +{ + return read32(tcs_cmd_addr(drv, reg, tcs_id, cmd_id)); +} + +static u32 read_tcs_reg(const struct rsc_drv *drv, int reg, int tcs_id) +{ + return read32(tcs_reg_addr(drv, reg, tcs_id)); +} + +static void write_tcs_cmd(const struct rsc_drv *drv, int reg, int tcs_id, + int cmd_id, u32 data) +{ + write32(tcs_cmd_addr(drv, reg, tcs_id, cmd_id), data); +} + +static void write_tcs_reg(const struct rsc_drv *drv, int reg, int tcs_id, u32 data) +{ + write32(tcs_reg_addr(drv, reg, tcs_id), data); +} + +static void write_tcs_reg_sync(const struct rsc_drv *drv, int reg, int tcs_id, u32 data) +{ + struct stopwatch sw; + + write32(tcs_reg_addr(drv, reg, tcs_id), data); + + /* Wait until we read back the same value */ + stopwatch_init_usecs_expire(&sw, USECS_1S); + while (read32(tcs_reg_addr(drv, reg, tcs_id)) != data) { + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "%s: error writing %#x to %d:%#x\n", drv->name, + data, tcs_id, reg); + break; + } + udelay(LOOP_DELAY_US); + } +} + +static void tcs_invalidate(struct rsc_drv *drv, int type, int ch) +{ + int m; + struct tcs_group *tcs = &drv->ch[ch].tcs[type]; + + /* Check if already empty */ + if (tcs->slots[0] == 0) + return; + + for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) { + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], m, 0); + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], m, 0); + } + + memset(tcs->slots, 0, sizeof(tcs->slots)); +} + +int rpmh_rsc_get_channel(struct rsc_drv *drv) +{ + int chn_update, chn_busy; + + if (drv->num_channels == 1) + return CH0; + + /* Select Unused channel */ + do { + chn_update = read32(drv->base + drv->regs[RSC_DRV_CHN_UPDATE]); + chn_busy = read32(drv->base + drv->regs[RSC_DRV_CHN_BUSY]); + } while (chn_busy != chn_update); + + if (chn_busy & CH0_CHN_BUSY) + return CH1; + else if (chn_busy & CH1_CHN_BUSY) + return CH0; + else + return -1; +} + +void rpmh_rsc_invalidate(struct rsc_drv *drv, int ch) +{ + tcs_invalidate(drv, SLEEP_TCS, ch); + tcs_invalidate(drv, WAKE_TCS, ch); +} + +static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, + enum rpmh_state state, + int ch) +{ + int type; + struct tcs_group *tcs; + + switch (state) { + case RPMH_ACTIVE_ONLY_STATE: + type = ACTIVE_TCS; + break; + case RPMH_WAKE_ONLY_STATE: + type = WAKE_TCS; + break; + case RPMH_SLEEP_STATE: + type = SLEEP_TCS; + break; + default: + return NULL; + } + + tcs = &drv->ch[ch].tcs[type]; + if (state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) + tcs = &drv->ch[ch].tcs[WAKE_TCS]; + + return tcs; +} + +static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger) +{ + u32 enable; + u32 reg = drv->regs[RSC_DRV_CONTROL]; + + enable = read_tcs_reg(drv, reg, tcs_id); + enable &= ~TCS_AMC_MODE_TRIGGER; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + enable &= ~TCS_AMC_MODE_ENABLE; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + + if (trigger) { + enable = TCS_AMC_MODE_ENABLE; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + enable |= TCS_AMC_MODE_TRIGGER; + write_tcs_reg(drv, reg, tcs_id, enable); + } +} + +static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, + const struct tcs_request *msg) +{ + u32 msgid; + u32 cmd_msgid = CMD_MSGID_LEN | CMD_MSGID_WRITE; + u32 cmd_enable = 0; + u32 cmd_complete; + struct tcs_cmd *cmd; + int i, j; + + cmd_msgid |= msg->wait_for_compl ? CMD_MSGID_RESP_REQ : 0; + cmd_complete = read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id); + + for (i = 0, j = cmd_id; i < msg->num_cmds; i++, j++) { + cmd = &msg->cmds[i]; + cmd_enable |= BIT(j); + cmd_complete |= cmd->wait << j; + msgid = cmd_msgid; + msgid |= cmd->wait ? CMD_MSGID_RESP_REQ : 0; + + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_MSGID], tcs_id, j, msgid); + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], tcs_id, j, cmd->addr); + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data); + } + + write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id, cmd_complete); + cmd_enable |= read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id); + write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, cmd_enable); +} + +static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs, + const struct tcs_request *msg) +{ + u32 curr_enabled; + u32 addr; + int j, k; + int i = tcs->offset; + + for (; i < tcs->offset + tcs->num_tcs; i++) { + if (!(drv->tcs_in_use[i / 32] & BIT(i % 32))) + continue; + + curr_enabled = read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], i); + + for (j = 0; j < tcs->ncpt; j++) { + if (!(curr_enabled & BIT(j))) + continue; + + addr = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], i, j); + for (k = 0; k < msg->num_cmds; k++) { + if (cmd_db_match_resource_addr(msg->cmds[k].addr, addr)) + return -1; + } + } + } + + return 0; +} + +static int find_free_tcs(struct tcs_group *tcs) +{ + const struct rsc_drv *drv = tcs->drv; + struct stopwatch sw; + int i; + u32 sts; + + for (i = tcs->offset; i < tcs->offset + tcs->num_tcs; i++) { + if (drv->tcs_in_use[i / 32] & BIT(i % 32)) + continue; + + stopwatch_init_usecs_expire(&sw, USECS_100US); + while (1) { + sts = read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], i); + if (sts) + return i; + if (stopwatch_expired(&sw)) + return -1; + udelay(LOOP_DELAY_US); + } + } + + return -1; +} + +static int claim_tcs_for_req(struct rsc_drv *drv, struct tcs_group *tcs, + const struct tcs_request *msg) +{ + int ret; + + ret = check_for_req_inflight(drv, tcs, msg); + if (ret) + return ret; + + return find_free_tcs(tcs); +} + +int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg, int ch) +{ + struct tcs_group *tcs; + struct stopwatch sw; + int tcs_id; + u32 status; + + tcs = get_tcs_for_msg(drv, msg->state, ch); + if (!tcs) + return -1; + + /* Controller is busy in 'solver' mode */ + if (drv->in_solver_mode) { + printk(BIOS_ERR, "RPMH RSC: Cannot send ACTIVE request in solver mode\n"); + return -1; + } + + /* Wait for a free tcs with hardware status verification */ + stopwatch_init_usecs_expire(&sw, USECS_100MS); + while (1) { + tcs_id = claim_tcs_for_req(drv, tcs, msg); + if (tcs_id >= 0) { + /* Double-check hardware status register */ + status = read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], tcs_id); + if (status) { /* 1 = IDLE, 0 = BUSY */ + break; + } + /* TCS claimed but hardware still busy, retry */ + printk(BIOS_DEBUG, "RPMH RSC: TCS %d claimed but HW busy, retrying\n", tcs_id); + } + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "RPMH RSC: No free TCS available (timeout after 100ms)\n"); + return -1; + } + udelay(LOOP_DELAY_10US); + } + + tcs->req[tcs_id - tcs->offset] = msg; + drv->tcs_in_use[tcs_id / 32] |= BIT(tcs_id % 32); + + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0); + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id, 0); + + __tcs_buffer_write(drv, tcs_id, 0, msg); + __tcs_set_trigger(drv, tcs_id, 1); + + /* Poll for completion if wait_for_compl is set */ + if (msg->wait_for_compl) { + stopwatch_init_usecs_expire(&sw, USECS_10MS); + while (1) { + u32 sts = read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], tcs_id); + if (sts) + break; + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "RPMH RSC: TCS %d timeout\n", tcs_id); + return -1; + } + udelay(LOOP_DELAY_US); + } + } + + drv->tcs_in_use[tcs_id / 32] &= ~BIT(tcs_id % 32); + + return 0; +} + +static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg, + int *tcs_id, int *cmd_id) +{ + int slot, offset; + int i = 0; + int slots_needed = msg->num_cmds; + + /* Find contiguous slots */ + do { + slot = 0; + for (i = 0; i < tcs->ncpt * tcs->num_tcs; i++) { + if (tcs->slots[i / 32] & BIT(i % 32)) { + slot = 0; + } else { + slot++; + if (slot >= slots_needed) + break; + } + } + if (slot < slots_needed) + return -1; + + i = i - slot + 1; + } while (i + slots_needed - 1 >= ((i / tcs->ncpt) + 1) * tcs->ncpt); + + /* Mark slots as used */ + for (slot = i; slot < i + slots_needed; slot++) + tcs->slots[slot / 32] |= BIT(slot % 32); + + offset = i / tcs->ncpt; + *tcs_id = offset + tcs->offset; + *cmd_id = i % tcs->ncpt; + + return 0; +} + +int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg, int ch) +{ + struct tcs_group *tcs; + int tcs_id = 0, cmd_id = 0; + int ret; + + if (!msg->num_cmds) + return 0; + + tcs = get_tcs_for_msg(drv, msg->state, ch); + if (!tcs) + return -1; + + ret = find_slots(tcs, msg, &tcs_id, &cmd_id); + if (!ret) + __tcs_buffer_write(drv, tcs_id, cmd_id, msg); + + return ret; +} + +int rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable) +{ + drv->in_solver_mode = enable; + return 0; +} + +int rpmh_rsc_switch_channel(struct rsc_drv *drv, int ch) +{ + struct stopwatch sw; + u32 sts; + u32 mask = (ch == 0) ? CH0_WAKE_TCS_STATUS : CH1_WAKE_TCS_STATUS; + + write32(drv->base + drv->regs[RSC_DRV_CHN_UPDATE], BIT(ch)); + + stopwatch_init_usecs_expire(&sw, USECS_100US); + while (1) { + sts = read32(drv->base + drv->regs[RSC_DRV_CHN_TCS_COMPLETE]); + if (sts & mask) + break; + if (stopwatch_expired(&sw)) + return -1; + udelay(LOOP_DELAY_US); + } + + write32(drv->base + drv->regs[RSC_DRV_CHN_TCS_COMPLETE], CH_CLEAR_STATUS); + + return 0; +} + +int rpmh_rsc_drv_enable(struct rsc_drv *drv, bool enable) +{ + int ret = 0, ch; + u32 chn_en; + + chn_en = read32(drv->base + drv->regs[RSC_DRV_CHN_EN]); + if (chn_en == enable) + return -1; + + if (enable) { + ch = 0; + ret = rpmh_flush(&drv->client, ch); + if (ret) + return ret; + + write32(drv->base + drv->regs[RSC_DRV_CHN_EN], enable); + ret = rpmh_rsc_switch_channel(drv, ch); + } else { + ch = rpmh_rsc_get_channel(drv); + if (ch < 0) + return ch; + + ret = rpmh_flush(&drv->client, ch); + if (ret) + return ret; + + ret = rpmh_rsc_switch_channel(drv, ch); + if (ret) + return ret; + + write32(drv->base + drv->regs[RSC_DRV_CHN_UPDATE], 0); + write32(drv->base + drv->regs[RSC_DRV_CHN_EN], enable); + } + + return ret; +} + +int rpmh_rsc_init_fast_path(struct rsc_drv *drv, const struct tcs_request *msg, int ch) +{ + int tcs_id; + + if (!drv->ch[ch].tcs[FAST_PATH_TCS].num_tcs) + return -1; + + tcs_id = drv->ch[ch].tcs[FAST_PATH_TCS].offset; + __tcs_buffer_write(drv, tcs_id, 0, msg); + + return 0; +} + +int rpmh_rsc_update_fast_path(struct rsc_drv *drv, + const struct tcs_request *msg, + u32 mask, int ch) +{ + struct stopwatch sw; + int i; + u32 sts; + int tcs_id; + struct tcs_cmd *cmd; + + if (!drv->ch[ch].tcs[FAST_PATH_TCS].num_tcs) + return -1; + + tcs_id = drv->ch[ch].tcs[FAST_PATH_TCS].offset; + + /* Ensure the TCS is free before writing */ + stopwatch_init_usecs_expire(&sw, USECS_5US); + while (1) { + sts = read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], tcs_id); + if (sts) + break; + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "Fast-path TCS is too busy\n"); + return -1; + } + udelay(LOOP_DELAY_US); + } + + /* Update only the data fields */ + for (i = 0; i < msg->num_cmds; i++) { + if (!(mask & BIT(i))) + continue; + cmd = &msg->cmds[i]; + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, i, cmd->data); + } + + /* Trigger the TCS */ + __tcs_set_trigger(drv, tcs_id, 1); + + return 0; +} diff --git a/src/soc/qualcomm/x1p42100/Makefile.mk b/src/soc/qualcomm/x1p42100/Makefile.mk index abf5971e20..46965a5375 100644 --- a/src/soc/qualcomm/x1p42100/Makefile.mk +++ b/src/soc/qualcomm/x1p42100/Makefile.mk @@ -53,6 +53,7 @@ ramstage-y += ../common/spmi.c ramstage-$(CONFIG_PCI) += pcie.c ramstage-y += cpucp_load_reset.c ramstage-y += ../common/cmd_db.c +ramstage-y += ../common/rpmh.c ../common/rpmh_bcm.c ../common/rpmh_regulator.c ../common/rpmh_rsc.c ################################################################################ From 02e6f2a21486613b1acbc1f4a028588c4cc617a0 Mon Sep 17 00:00:00 2001 From: Swathi Tamilselvan Date: Wed, 10 Dec 2025 22:40:07 +0530 Subject: [PATCH 097/789] soc/qualcomm/x1p42100: Add API to intialize RPMh resources for display Add API to initialize RPMh resources for display. It includes CMD-DB initialization, enable the MMCX power rail and cast a vote for the MM0 Bus Clock Manager (BCM) resource to enable display clocks. Test=1. Create an image.serial.bin and ensure it boots on X1P42100. 2. Verified MMCX rail enablement and MM0 BCM vote using ARC and BCM AOP dump with API invoking changes hooked up with follow-on commits. Serial Log: [INFO ] RPMH_REG: Initialized mmcx.lvl at addr=0x30080 [INFO ] ARC regulator initialized successfully [DEBUG] RPMH_REG: Sent active request for mmcx.lvl [INFO ] ARC level was set successfully [DEBUG] BCM: Found address 0x00050024 for resource MM0 [INFO ] BCM: Successfully voted for MM0 (addr=0x00050024, val=0x60004001) [INFO ] BCM vote for MM0 sent successfully Change-Id: I1997ce7a1ced4504d6a3170e5f2ddd4f52e0763d Signed-off-by: Swathi Tamilselvan Reviewed-on: https://review.coreboot.org/c/coreboot/+/90467 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/soc/qualcomm/x1p42100/Makefile.mk | 2 + src/soc/qualcomm/x1p42100/display/disp.c | 76 ++++++++ .../x1p42100/include/soc/addressmap.h | 6 + .../x1p42100/include/soc/rpmh_config.h | 42 +++++ src/soc/qualcomm/x1p42100/rpmh_rsc_init.c | 165 ++++++++++++++++++ 5 files changed, 291 insertions(+) create mode 100644 src/soc/qualcomm/x1p42100/display/disp.c create mode 100644 src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h create mode 100644 src/soc/qualcomm/x1p42100/rpmh_rsc_init.c diff --git a/src/soc/qualcomm/x1p42100/Makefile.mk b/src/soc/qualcomm/x1p42100/Makefile.mk index 46965a5375..4a51a20dd6 100644 --- a/src/soc/qualcomm/x1p42100/Makefile.mk +++ b/src/soc/qualcomm/x1p42100/Makefile.mk @@ -54,6 +54,8 @@ ramstage-$(CONFIG_PCI) += pcie.c ramstage-y += cpucp_load_reset.c ramstage-y += ../common/cmd_db.c ramstage-y += ../common/rpmh.c ../common/rpmh_bcm.c ../common/rpmh_regulator.c ../common/rpmh_rsc.c +ramstage-y += rpmh_rsc_init.c +ramstage-y += display/disp.c ################################################################################ diff --git a/src/soc/qualcomm/x1p42100/display/disp.c b/src/soc/qualcomm/x1p42100/display/disp.c new file mode 100644 index 0000000000..f09adab34f --- /dev/null +++ b/src/soc/qualcomm/x1p42100/display/disp.c @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * display_rpmh_init() - Initialize RPMh for display power management + * + * Initializes the RPMh (Resource Power Manager-Hardened) subsystem for display: + * - Waits for AOP boot + * - Initializes Command DB and RPMh RSC (Resource State Coordinator) + * - Configures MMCX ARC regulator for display power rail + * - Votes for MM0 BCM (Bus Clock Manager) for display bus clocks + * + * Return: CB_SUCCESS on success, CB_ERR on failure + */ +enum cb_err display_rpmh_init(void) +{ + enum cb_err ret; + struct rpmh_vreg arc_reg; + int rc; + volatile u32 *boot_cookie = (volatile u32 *)AOP_BOOT_COOKIE_ADDR; + + if (!wait_us(AOP_BOOT_TIMEOUT_US, *boot_cookie == AOP_BOOT_COOKIE)) { + printk(BIOS_ERR, "AOP not booted after %dus (cookie: 0x%x, expected: 0x%x)\n", + AOP_BOOT_TIMEOUT_US, *boot_cookie, AOP_BOOT_COOKIE); + return CB_ERR; + } + + printk(BIOS_INFO, "AOP boot detected (cookie: 0x%x)\n", *boot_cookie); + + ret = cmd_db_init(CMD_DB_BASE_ADDR, CMD_DB_SIZE); + if (ret != CB_SUCCESS) { + printk(BIOS_ERR, "Failed to initialize Command DB\n"); + return CB_ERR; + } + + rc = rpmh_rsc_init(); + if (rc) { + printk(BIOS_ERR, "Failed to initialize RPMh RSC\n"); + return CB_ERR; + } + + rc = rpmh_regulator_init(&arc_reg, "mmcx.lvl", RPMH_REGULATOR_TYPE_ARC); + if (rc) { + printk(BIOS_ERR, "Failed to initialize display power rail mmcx ARC regulator\n"); + return CB_ERR; + } + + printk(BIOS_INFO, "ARC regulator initialized successfully\n"); + + rc = rpmh_regulator_arc_set_level(&arc_reg, RPMH_REGULATOR_LEVEL_MIN_MM0, true, false); + if (rc) { + printk(BIOS_ERR, "Failed to set ARC level\n"); + return CB_ERR; + } + + printk(BIOS_INFO, "ARC level was set successfully\n"); + + rc = rpmh_bcm_vote("MM0", BCM_MM0_VOTE_VALUE); + if (rc) { + printk(BIOS_ERR, "Failed to send BCM vote for display bus clock manager MM0\n"); + return CB_ERR; + } + + printk(BIOS_INFO, "BCM vote for MM0 sent successfully\n"); + + return CB_SUCCESS; +} diff --git a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h index 1c309a06d4..8b22662e92 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h +++ b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h @@ -18,6 +18,12 @@ #define DISP_PLL1_BASE 0xAF01000 #define DISP_CC_BASE 0xAF08000 +#define RPMH_BASE 0x17520000 +#define CMD_DB_BASE_ADDR 0x81c60000 +#define CMD_DB_SIZE 0x20000 + +#define AOP_BOOT_COOKIE_ADDR 0xC3F0040 + #define CBMEM_TOP 0xC7800000 /* X1P42100 NCC0 PLL CONFIG ADDRESSES */ #define NCC0_NCC_CMU_NCC_PLL_CFG 0x199A2010 diff --git a/src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h b/src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h new file mode 100644 index 0000000000..c1f9c4630c --- /dev/null +++ b/src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_QUALCOMM_X1P42100_RPMH_CONFIG_H_ +#define _SOC_QUALCOMM_X1P42100_RPMH_CONFIG_H_ + +#include + +/* + * X1P42100 RPMh RSC Configuration + */ + +#define RPMH_RSC_DRV_ID 2 + +#define RPMH_TCS_OFFSET 0xd00 +#define RPMH_TCS_DISTANCE 0x2a0 + +/* TCS Configuration */ +#define RPMH_NUM_ACTIVE_TCS 2 +#define RPMH_NUM_SLEEP_TCS 3 +#define RPMH_NUM_WAKE_TCS 3 +#define RPMH_NUM_CONTROL_TCS 0 +#define RPMH_NUM_FAST_PATH_TCS 0 + +#define RPMH_NUM_CHANNELS 1 + +#define RPMH_HW_SOLVER_SUPPORTED true +#define RPMH_HW_CHANNEL_MODE false + +#define RPMH_RSC_NAME "apps_rsc" + +#define RPMH_REGULATOR_LEVEL_MIN_MM0 1 +#define RPMH_REGULATOR_LEVEL_TURBO_MM0 6 + +#define BCM_MM0_VOTE_VALUE 0x60004001 + +#define AOP_BOOT_COOKIE 0xA0C00C1E +#define AOP_BOOT_TIMEOUT_US 200000 + +int rpmh_rsc_init(void); +enum cb_err display_rpmh_init(void); + +#endif /* _SOC_QUALCOMM_X1P42100_RPMH_CONFIG_H_ */ diff --git a/src/soc/qualcomm/x1p42100/rpmh_rsc_init.c b/src/soc/qualcomm/x1p42100/rpmh_rsc_init.c new file mode 100644 index 0000000000..7ddb3ac10d --- /dev/null +++ b/src/soc/qualcomm/x1p42100/rpmh_rsc_init.c @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct rsc_drv rsc_driver; +static struct cache_req non_batch_cache[CMD_DB_MAX_RESOURCES]; + +/** + * rpmh_rsc_init - Initialize the RPMh RSC driver + * + * Initializes the RPMh Resource State Coordinator driver with platform-specific configuration. + * Configuration is read from soc/rpmh_config.h for this chipset. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_rsc_init(void) +{ + struct rsc_drv *drv = &rsc_driver; + u32 rsc_id, major_rsc_version, minor_rsc_version, config, max_tcs, ncpt; + int offset; + u32 solver_config; + + /* Check if already initialized */ + if (drv->initialized) { + printk(BIOS_INFO, "RPMH RSC: Already initialized, skipping re-initialization\n"); + return 0; + } + + memset(drv, 0, sizeof(*drv)); + + /* Set configuration from chipset-specific header */ + drv->base = (void *)RPMH_BASE; + drv->tcs_base = (void *)(RPMH_BASE + RPMH_TCS_OFFSET); + drv->tcs_distance = RPMH_TCS_DISTANCE; + drv->id = RPMH_RSC_DRV_ID; + drv->num_channels = RPMH_NUM_CHANNELS; + strncpy(drv->name, RPMH_RSC_NAME, sizeof(drv->name) - 1); + + /* Read hardware version */ + rsc_id = read32(drv->base); + major_rsc_version = (rsc_id >> 16) & 0xFF; + minor_rsc_version = (rsc_id >> 8) & 0xFF; + + /* Select register offsets based on version and HW channel mode */ + if (RPMH_HW_CHANNEL_MODE && major_rsc_version >= 3) { + drv->regs = rpmh_rsc_reg_offset_ver_3_0_hw_channel; + printk(BIOS_INFO, "RPMH RSC: Using v3.0 HW channel register offsets\n"); + } else if (major_rsc_version >= 3) { + drv->regs = rpmh_rsc_reg_offset_ver_3_0; + printk(BIOS_INFO, "RPMH RSC: Using v3.0 register offsets\n"); + } else { + drv->regs = rpmh_rsc_reg_offset_ver_2_7; + printk(BIOS_INFO, "RPMH RSC: Using v2.7 register offsets\n"); + } + + /* Read TCS configuration from hardware */ + config = read32(drv->base + drv->regs[DRV_PRNT_CHLD_CONFIG]); + max_tcs = (config >> (DRV_NUM_TCS_SHIFT * drv->id)) & DRV_NUM_TCS_MASK; + ncpt = (config >> DRV_NCPT_SHIFT) & DRV_NCPT_MASK; + + /* Configure TCS groups for Channel 0 - explicit approach */ + offset = 0; + drv->num_tcs = 0; + + if (RPMH_NUM_ACTIVE_TCS > 0) { + drv->ch[CH0].tcs[ACTIVE_TCS].drv = drv; + drv->ch[CH0].tcs[ACTIVE_TCS].type = ACTIVE_TCS; + drv->ch[CH0].tcs[ACTIVE_TCS].num_tcs = RPMH_NUM_ACTIVE_TCS; + drv->ch[CH0].tcs[ACTIVE_TCS].ncpt = ncpt; + drv->ch[CH0].tcs[ACTIVE_TCS].offset = offset; + drv->ch[CH0].tcs[ACTIVE_TCS].mask = ((1 << RPMH_NUM_ACTIVE_TCS) - 1) << offset; + offset += RPMH_NUM_ACTIVE_TCS; + drv->num_tcs += RPMH_NUM_ACTIVE_TCS; + printk(BIOS_DEBUG, "RPMH RSC: ACTIVE TCS: %d TCSes at offset %d (mask=0x%x)\n", + RPMH_NUM_ACTIVE_TCS, drv->ch[CH0].tcs[ACTIVE_TCS].offset, + drv->ch[CH0].tcs[ACTIVE_TCS].mask); + } + + if (RPMH_NUM_SLEEP_TCS > 0) { + drv->ch[CH0].tcs[SLEEP_TCS].drv = drv; + drv->ch[CH0].tcs[SLEEP_TCS].type = SLEEP_TCS; + drv->ch[CH0].tcs[SLEEP_TCS].num_tcs = RPMH_NUM_SLEEP_TCS; + drv->ch[CH0].tcs[SLEEP_TCS].ncpt = ncpt; + drv->ch[CH0].tcs[SLEEP_TCS].offset = offset; + drv->ch[CH0].tcs[SLEEP_TCS].mask = ((1 << RPMH_NUM_SLEEP_TCS) - 1) << offset; + offset += RPMH_NUM_SLEEP_TCS; + drv->num_tcs += RPMH_NUM_SLEEP_TCS; + printk(BIOS_DEBUG, "RPMH RSC: SLEEP TCS: %d TCSes at offset %d (mask=0x%x)\n", + RPMH_NUM_SLEEP_TCS, drv->ch[CH0].tcs[SLEEP_TCS].offset, + drv->ch[CH0].tcs[SLEEP_TCS].mask); + } + + if (RPMH_NUM_WAKE_TCS > 0) { + drv->ch[CH0].tcs[WAKE_TCS].drv = drv; + drv->ch[CH0].tcs[WAKE_TCS].type = WAKE_TCS; + drv->ch[CH0].tcs[WAKE_TCS].num_tcs = RPMH_NUM_WAKE_TCS; + drv->ch[CH0].tcs[WAKE_TCS].ncpt = ncpt; + drv->ch[CH0].tcs[WAKE_TCS].offset = offset; + drv->ch[CH0].tcs[WAKE_TCS].mask = ((1 << RPMH_NUM_WAKE_TCS) - 1) << offset; + offset += RPMH_NUM_WAKE_TCS; + drv->num_tcs += RPMH_NUM_WAKE_TCS; + printk(BIOS_DEBUG, "RPMH RSC: WAKE TCS: %d TCSes at offset %d (mask=0x%x)\n", + RPMH_NUM_WAKE_TCS, drv->ch[CH0].tcs[WAKE_TCS].offset, + drv->ch[CH0].tcs[WAKE_TCS].mask); + } + + /* Check if total TCS count exceeds hardware limit */ + if (drv->num_tcs > max_tcs) { + printk(BIOS_ERR, "RPMH RSC: TCS config exceeds hardware limit (configured: %d, max: %d)\n", + drv->num_tcs, max_tcs); + return -1; + } + + drv->ch[CH0].drv = drv; + drv->ch[CH0].initialized = true; + drv->client.non_batch_cache = non_batch_cache; + drv->client.non_batch_cache_idx = 0; + + for (int i = 0; i < CMD_DB_MAX_RESOURCES; i++) { + non_batch_cache[i].addr = 0; + non_batch_cache[i].sleep_val = UINT_MAX; + non_batch_cache[i].wake_val = UINT_MAX; + } + + /* Initialize TCS in-use bitmap */ + memset(drv->tcs_in_use, 0, sizeof(drv->tcs_in_use)); + + /* Detect solver mode from hardware */ + solver_config = read32(drv->base + drv->regs[DRV_SOLVER_CONFIG]); + solver_config = (solver_config >> 24) & 0x1; + + if (solver_config || RPMH_HW_SOLVER_SUPPORTED) { + drv->client.flags |= SOLVER_PRESENT; + printk(BIOS_INFO, "RPMH RSC: Hardware solver mode supported\n"); + + if (RPMH_HW_CHANNEL_MODE) { + drv->client.flags |= HW_CHANNEL_PRESENT; + drv->in_solver_mode = true; + drv->client.in_solver_mode = true; + printk(BIOS_INFO, "RPMH RSC: HW channel mode enabled\n"); + } else { + drv->in_solver_mode = false; + drv->client.in_solver_mode = false; + printk(BIOS_INFO, "RPMH RSC: Software control mode\n"); + } + } else { + printk(BIOS_INFO, "RPMH RSC: Hardware solver mode not supported\n"); + } + + drv->initialized = true; + + rpmh_set_rsc_drv(drv); + + printk(BIOS_INFO, "RPMH RSC: Initialized %s (drv-%d) at 0x%lx Version %d.%d\n", + drv->name, drv->id, (uintptr_t)drv->base, major_rsc_version, minor_rsc_version); + + return 0; +} From e1e7b9b20374fc3b1406d43e7b1ab2b0859f919f Mon Sep 17 00:00:00 2001 From: Swathi Tamilselvan Date: Mon, 15 Dec 2025 14:54:16 +0530 Subject: [PATCH 098/789] soc/qualcomm/x1p42100: Add API to enable display clocks Add API to enable the essential display clocks required for display subsystem initialization. Test=1. Build and boot on X1P42100. Change-Id: Ifc634f2c00eb933bf03b898e132ab5bf137149f8 Signed-off-by: Swathi Tamilselvan Reviewed-on: https://review.coreboot.org/c/coreboot/+/90468 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal Reviewed-by: Subrata Banik --- src/soc/qualcomm/x1p42100/clock.c | 67 +++++++++++++++++++ src/soc/qualcomm/x1p42100/display/disp.c | 56 ++++++++++++++++ src/soc/qualcomm/x1p42100/include/soc/clock.h | 7 ++ 3 files changed, 130 insertions(+) diff --git a/src/soc/qualcomm/x1p42100/clock.c b/src/soc/qualcomm/x1p42100/clock.c index 377f529a08..c2566c5d5b 100644 --- a/src/soc/qualcomm/x1p42100/clock.c +++ b/src/soc/qualcomm/x1p42100/clock.c @@ -294,6 +294,26 @@ static u32 *usb_sec_cbcr[USB_SEC_CLK_COUNT] = { [USB_SEC_SYS_NOC_USB_AXI_CBCR] = &gcc->gcc_sys_noc_usb_axi_cbcr, }; +static u32 *disp_gdsc[MAX_DISP_GDSC] = { + [DISP_CC_CORE_GDSC] = &disp_cc->mdss_core_gdscr, +}; + +static u32 *mdss_cbcr[MDSS_CLK_COUNT] = { + [GCC_DISP_AHB_CBCR] = &gcc->gcc_disp_ahb_cbcr, + [GCC_DISP_XO_CBCR] = &gcc->gcc_disp_xo_cbcr, + [GCC_DISP_HF_AXI_CBCR] = &gcc->gcc_disp_hf_axi_cbcr, + [DISP_CC_MDSS_AHB_CBCR] = &disp_cc->mdss_ahb_cbcr, + [DISP_CC_MDSS_MDP_CBCR] = &disp_cc->mdss_mdp_cbcr, + [DISP_CC_MDSS_VSYNC_CBCR] = &disp_cc->mdss_vsync_cbcr, + [DISP_CC_MDSS_RSCC_AHB_CBCR] = &disp_cc->mdss_rscc_ahb_cbcr, + [DISP_CC_MDSS_RSCC_VSYNC_CBCR] = &disp_cc->mdss_rscc_vsync_cbcr, + [DISP_CC_XO_CBCR] = &disp_cc->xo_cbcr, + [DISP_CC_MDSS_DPTX3_PIXEL0_CBCR] = &disp_cc->mdss_dptx3_pixel0_cbcr, + [DISP_CC_MDSS_DPTX3_LINK_CBCR] = &disp_cc->mdss_dptx3_link_cbcr, + [DISP_CC_MDSS_DPTX3_AUX_CBCR] = &disp_cc->mdss_dptx3_aux_cbcr, + [DISP_CC_MDSS_DPTX3_LINK_INTF_CBCR] = &disp_cc->mdss_dptx3_link_intf_cbcr, +}; + static struct clock_freq_config pcie_core_cfg[] = { { .hz = 100 * MHz, @@ -500,6 +520,14 @@ enum cb_err clock_enable_usb_gdsc(enum clk_usb_gdsc gdsc_type) return enable_and_poll_gdsc_status(usb_gdsc[gdsc_type]); } +enum cb_err clock_enable_disp_gdsc(enum clk_disp_gdsc gdsc_type) +{ + if (gdsc_type >= MAX_DISP_GDSC) + return CB_ERR; + + return enable_and_poll_gdsc_status(disp_gdsc[gdsc_type]); +} + enum cb_err usb_clock_enable(enum clk_usb clk_type) { if (clk_type >= USB_CLK_COUNT) @@ -623,6 +651,45 @@ static enum cb_err pll_init_and_set(struct x1p42100_ncc0_clock *ncc0, u32 l_val) return CB_SUCCESS; } +enum cb_err disp_pll_init_and_set(struct x1p42100_disp_pll_clock *disp_pll, u32 l_val, u32 alpha_val) +{ + int ret; + struct alpha_pll_reg_val_config disp_pll_cfg = {0}; + + disp_pll_cfg.reg_l = &disp_pll->pll_l; + disp_pll_cfg.l_val = l_val; + + disp_pll_cfg.reg_alpha = &disp_pll->pll_alpha; + disp_pll_cfg.alpha_val = alpha_val; + + disp_pll_cfg.reg_user_ctl = &disp_pll->pll_user_ctl; + disp_pll_cfg.user_ctl_val = 0x1; + + clock_configure_enable_gpll(&disp_pll_cfg, false, 0); + + disp_pll_cfg.reg_mode = &disp_pll->pll_mode; + disp_pll_cfg.reg_opmode = &disp_pll->pll_opmode; + ret = lucidole_pll_enable(&disp_pll_cfg); + if (ret != CB_SUCCESS) + return CB_ERR; + + return CB_SUCCESS; +} + +enum cb_err mdss_clock_enable(enum clk_mdss clk_type) +{ + if (clk_type >= MDSS_CLK_COUNT) + return CB_ERR; + + /* Enable clock */ + return clock_enable(mdss_cbcr[clk_type]); +} + +void enable_disp_clock_tcsr(void) +{ + write32(TCSR_GCC_EDP_CLKREF_EN_ADDR, 0x1); +} + static void speed_up_boot_cpu(void) { /* 1363.2 MHz */ diff --git a/src/soc/qualcomm/x1p42100/display/disp.c b/src/soc/qualcomm/x1p42100/display/disp.c index f09adab34f..f4a999ec80 100644 --- a/src/soc/qualcomm/x1p42100/display/disp.c +++ b/src/soc/qualcomm/x1p42100/display/disp.c @@ -4,12 +4,68 @@ #include #include #include +#include #include #include #include #include #include +static struct clock_freq_config disp_cc_mdss_ahb_cfg[] = { + { + .hz = SRC_XO_HZ, /* 19.2MHz */ + .src = SRC_XO_19_2MHZ_AHB, + .div = QCOM_CLOCK_DIV(1), + }, + { + .hz = CLK_37_5MHZ, + .src = SRC_DISP_CC_PLL1_MAIN_AHB, + .div = QCOM_CLOCK_DIV(16), + }, + { + .hz = CLK_75MHZ, + .src = SRC_DISP_CC_PLL1_MAIN_AHB, + .div = QCOM_CLOCK_DIV(8), + }, +}; + +static struct clock_freq_config disp_cc_mdss_mdp_cfg[] = { + { + .hz = CLK_575MHZ, + .src = SRC_DISP_CC_PLL0_MAIN_MDP, + .div = QCOM_CLOCK_DIV(3), + }, + { + .hz = CLK_400MHZ, + .src = SRC_DISP_CC_PLL1_MAIN_MDP, + .div = QCOM_CLOCK_DIV(1.5), + }, +}; + +void enable_mdss_clk(void) +{ + /* + * Display clock initialization sequence + * 1. Enable GCC clocks (AHB, AXI) - GCC clocks that are required for display + * 2. Enable GDSC (power domain) - powers up the display subsystem + * 3. Initialize display PLLs - required to use clock sources from disp_cc domain + * 4. Configure and enable disp_cc clocks - enable display clocks + */ + mdss_clock_enable(GCC_DISP_AHB_CBCR); + clock_enable_disp_gdsc(DISP_CC_CORE_GDSC); + mdss_clock_enable(GCC_DISP_HF_AXI_CBCR); + disp_pll_init_and_set(apss_disp_pll0, L_VAL_1725MHz, DISP_PLL0_ALPHA_VAL); + disp_pll_init_and_set(apss_disp_pll1, L_VAL_600MHz, DISP_PLL1_ALPHA_VAL); + clock_configure(&disp_cc->mdss_ahb_rcg, + disp_cc_mdss_ahb_cfg, CLK_75MHZ, ARRAY_SIZE(disp_cc_mdss_ahb_cfg)); + mdss_clock_enable(DISP_CC_MDSS_AHB_CBCR); + clock_configure(&disp_cc->mdss_mdp_rcg, + disp_cc_mdss_mdp_cfg, CLK_575MHZ, ARRAY_SIZE(disp_cc_mdss_mdp_cfg)); + mdss_clock_enable(DISP_CC_MDSS_MDP_CBCR); + mdss_clock_enable(DISP_CC_MDSS_VSYNC_CBCR); + enable_disp_clock_tcsr(); +} + /** * display_rpmh_init() - Initialize RPMh for display power management * diff --git a/src/soc/qualcomm/x1p42100/include/soc/clock.h b/src/soc/qualcomm/x1p42100/include/soc/clock.h index da082f66bd..73378ce59e 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/clock.h +++ b/src/soc/qualcomm/x1p42100/include/soc/clock.h @@ -16,6 +16,7 @@ #define CLK_400MHZ (400 * MHz) #define CLK_75MHZ (75 * MHz) #define CLK_575MHZ (575 * MHz) +#define CLK_37_5MHZ (37.5 * MHz) /* CPU PLL*/ #define L_VAL_1363P2MHz 0x47 @@ -745,14 +746,20 @@ void clock_enable_qup(int qup); void clock_configure_dfsr(int qup); void clock_configure_pcie(void); void clock_configure_usb(void); +void enable_disp_clock_tcsr(void); +void enable_mdss_clk(void); enum cb_err clock_enable_gdsc(enum clk_gdsc gdsc_type); enum cb_err clock_enable_pcie(enum clk_pcie clk_type); enum cb_err clock_configure_mux(enum clk_pcie clk_type, u32 src_type); enum cb_err usb_clock_configure_mux(enum clk_pipe_usb clk_type, u32 src_type); enum cb_err usb_clock_enable(enum clk_usb clk_type); enum cb_err clock_enable_usb_gdsc(enum clk_usb_gdsc gdsc_type); +enum cb_err clock_enable_disp_gdsc(enum clk_disp_gdsc gdsc_type); enum cb_err usb_prim_clock_enable(enum clk_usb_prim clk_type); enum cb_err usb_sec_clock_enable(enum clk_usb_sec clk_type); +enum cb_err mdss_clock_enable(enum clk_mdss clk_type); +enum cb_err disp_pll_init_and_set(struct x1p42100_disp_pll_clock *disp_pll, + u32 l_val, u32 alpha_val); void clock_configure_dfsr_table_x1p42100(int qup, struct clock_freq_config *clk_cfg, uint32_t num_perfs); From 0c26c4494d754cbb649a1789b15208267f9253df Mon Sep 17 00:00:00 2001 From: Swathi Tamilselvan Date: Mon, 15 Dec 2025 16:00:33 +0530 Subject: [PATCH 099/789] mainboard/google/bluey: Enable display clocks and MMCX power rail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support to enable MMCX power rail and vote for MM0 BCM resource required for display. This change includes support to enable display clocks. TEST= 1. Create an image.serial.bin and ensure it boots on X1P42100. 2. Verified MMCX rail enablement and MM0 BCM vote using ARC and BCM AOP dump. Serial Log: [INFO ] RPMH_REG: Initialized mmcx.lvl at addr=0x30080 [INFO ] ARC regulator initialized successfully [DEBUG] RPMH_REG: Sent active request for mmcx.lvl [INFO ] ARC level has been set successfully [DEBUG] BCM: Found address 0x00050024 for resource MM0 [INFO ] BCM: Successfully voted for MM0 (addr=0x00050024, val=0x60004001) [INFO ] BCM vote for MM0 sent successfully 3. Verified if the clocks are enabled by taking clock dump. Clock enablement is verified by dumping the 31st bit of the corresponding clock’s CBCR register. A value of 0 in bit 31 indicates that the clock is ON. The register details are part of HRD-X1P42100-S1 document. https://docs.qualcomm.com/bundle/resource/topics/HRD-X1P42100-S1/ Change-Id: I89715fb4e3a6122388068a819e24cb409e204155 Signed-off-by: Swathi Tamilselvan Reviewed-on: https://review.coreboot.org/c/coreboot/+/90507 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/mainboard.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index e18f492764..9f958a1862 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -9,10 +9,12 @@ #include #include #include +#include #include #include #include #include "board.h" +#include #include /* @@ -87,7 +89,11 @@ static void display_startup(void) return; } - /* TODO: add logic for display init */ + /* Initialize RPMh subsystem and display power rails */ + if (display_rpmh_init() != CB_SUCCESS) + return; + + enable_mdss_clk(); } static void mainboard_init(struct device *dev) From f8c10eda36bde8e8ce06242d2f8551dd866ece02 Mon Sep 17 00:00:00 2001 From: Yunlong Jia Date: Wed, 31 Dec 2025 09:02:47 +0000 Subject: [PATCH 100/789] mb/google/nissa/var/gothrax: Add Rayson parts to RAM ID table Add the support RAM parts for gothrax. Here is the ram part number list: DRAM Part Name ID to assign MT62F512M32D2DR-031 WT:B 0 (0000) H58G56AK6BX069 1 (0001) K3LKBKB0BM-MGCP 2 (0010) H9JCNNNBK3MLYR-N6E 0 (0000) H9JCNNNCP3MLYR-N6E 3 (0011) K3KL8L80CM-MGCT 4 (0100) RS1G32LO5D2FDB-23BT 5 (0101) BUG=b:472596025 BRANCH=None TEST=emerge-nissa coreboot Signed-off-by: Yunlong Jia Change-Id: Iff12898dd6fb08a7e932de6e1902886a6f251761 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90663 Tested-by: build bot (Jenkins) Reviewed-by: Eric Lai --- src/mainboard/google/brya/variants/gothrax/memory/Makefile.mk | 1 + .../google/brya/variants/gothrax/memory/dram_id.generated.txt | 1 + .../google/brya/variants/gothrax/memory/mem_parts_used.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/src/mainboard/google/brya/variants/gothrax/memory/Makefile.mk b/src/mainboard/google/brya/variants/gothrax/memory/Makefile.mk index c323ea6ae6..44065b51d0 100644 --- a/src/mainboard/google/brya/variants/gothrax/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/gothrax/memory/Makefile.mk @@ -9,3 +9,4 @@ SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 1(0b0001) Parts = H58G56AK6B SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = K3LKBKB0BM-MGCP SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 3(0b0011) Parts = H9JCNNNCP3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 4(0b0100) Parts = K3KL8L80CM-MGCT +SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 5(0b0101) Parts = RS1G32LO5D2FDB-23BT diff --git a/src/mainboard/google/brya/variants/gothrax/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/gothrax/memory/dram_id.generated.txt index 8892ad8cb6..9848a35a35 100644 --- a/src/mainboard/google/brya/variants/gothrax/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/gothrax/memory/dram_id.generated.txt @@ -10,3 +10,4 @@ K3LKBKB0BM-MGCP 2 (0010) H9JCNNNBK3MLYR-N6E 0 (0000) H9JCNNNCP3MLYR-N6E 3 (0011) K3KL8L80CM-MGCT 4 (0100) +RS1G32LO5D2FDB-23BT 5 (0101) diff --git a/src/mainboard/google/brya/variants/gothrax/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/gothrax/memory/mem_parts_used.txt index bb85c55f8b..baf0ab19af 100644 --- a/src/mainboard/google/brya/variants/gothrax/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/gothrax/memory/mem_parts_used.txt @@ -16,3 +16,4 @@ K3LKBKB0BM-MGCP, H9JCNNNBK3MLYR-N6E, H9JCNNNCP3MLYR-N6E, K3KL8L80CM-MGCT, +RS1G32LO5D2FDB-23BT, From b2b1eb3c5a252dd5831a5fa39b45e771c810c88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 6 Oct 2025 14:16:36 +0200 Subject: [PATCH 101/789] soc/amd/common/block/smn: Add simple SMN I/O accessors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add PCI I/O-based SMN accessors. These accessors can be used for early workarounds when the PCI ECAM MMCONF is not working yet. An example of such workaround is the patching of PCI ECAM MMCONF base address in Turin SoC, which has to be done via SMN, but it cannot use PCI ECAM MMCONF to access SMN yet. Change-Id: I5e0faaa48e4d7b4479e3af9b795ad2a879f569fd Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/89471 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- .../amd/common/block/include/amdblocks/smn.h | 8 +++++++ src/soc/amd/common/block/smn/smn.c | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/soc/amd/common/block/include/amdblocks/smn.h b/src/soc/amd/common/block/include/amdblocks/smn.h index 0268926bbe..ad6972114e 100644 --- a/src/soc/amd/common/block/include/amdblocks/smn.h +++ b/src/soc/amd/common/block/include/amdblocks/smn.h @@ -9,4 +9,12 @@ uint32_t smn_read32(uint32_t reg); uint64_t smn_read64(uint32_t reg); void smn_write32(uint32_t reg, uint32_t val); +#if defined(__SIMPLE_DEVICE__) + +uint32_t smn_io_read32(uint32_t reg); +uint64_t smn_io_read64(uint32_t reg); +void smn_io_write32(uint32_t reg, uint32_t val); + +#endif + #endif /* AMD_BLOCK_SMN_H */ diff --git a/src/soc/amd/common/block/smn/smn.c b/src/soc/amd/common/block/smn/smn.c index caf6a41004..41396701e2 100644 --- a/src/soc/amd/common/block/smn/smn.c +++ b/src/soc/amd/common/block/smn/smn.c @@ -25,3 +25,25 @@ void smn_write32(uint32_t reg, uint32_t val) pci_write_config32(SOC_GNB_DEV, SMN_INDEX_ADDR, reg); pci_write_config32(SOC_GNB_DEV, SMN_DATA_ADDR, val); } + + +#if defined(__SIMPLE_DEVICE__) + +uint32_t smn_io_read32(uint32_t reg) +{ + pci_io_write_config32(SOC_GNB_DEV, SMN_INDEX_ADDR, reg); + return pci_io_read_config32(SOC_GNB_DEV, SMN_DATA_ADDR); +} + +uint64_t smn_io_read64(uint32_t reg) +{ + return smn_io_read32(reg) | (uint64_t)smn_io_read32(reg + 4) << 32; +} + +void smn_io_write32(uint32_t reg, uint32_t val) +{ + pci_io_write_config32(SOC_GNB_DEV, SMN_INDEX_ADDR, reg); + pci_io_write_config32(SOC_GNB_DEV, SMN_DATA_ADDR, val); +} + +#endif From ba0483c94a118f32c750d8ebfbed9efd0b58810f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 4 Dec 2025 14:49:52 +0100 Subject: [PATCH 102/789] soc/amd/common/Makefile.mk: Strip quotes from AMDFW_CONFIG_FILE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Strip quotes from CONFIG_AMDFW_CONFIG_FILE, otherwise the IF condition may not catch the case when CONFIG_AMDFW_CONFIG_FILE is an empty string. TEST=Omit PSP blobs when building coreboot for Gigabyte MZ33-AR1 by clearing the AMDFW_CONFIG_FILE path. Change-Id: I1ecf61844c03c89b3429e23936172f79c8d4b2f4 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/90367 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Felix Held --- src/soc/amd/common/Makefile.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soc/amd/common/Makefile.mk b/src/soc/amd/common/Makefile.mk index 5d41968493..dbf655737f 100644 --- a/src/soc/amd/common/Makefile.mk +++ b/src/soc/amd/common/Makefile.mk @@ -11,7 +11,7 @@ ifneq ($(V),) OPT_DEBUG_AMDFWTOOL = --debug endif -ifneq ($(CONFIG_AMDFW_CONFIG_FILE), ) +ifneq ($(call strip_quotes, $(CONFIG_AMDFW_CONFIG_FILE)),) FIRMWARE_LOCATION=$(shell grep -e FIRMWARE_LOCATION $(CONFIG_AMDFW_CONFIG_FILE) | awk '{print $$2}') # Add all the files listed in the config file to the dependency list @@ -77,7 +77,7 @@ amdfwread-range-cmd = $(shell ( \ )) endif # ifeq ($(CONFIG_VBOOT_GSCVD),y) -endif # ifneq ($(CONFIG_AMDFW_CONFIG_FILE), ) +endif # ifneq ($(call strip_quotes, $(CONFIG_AMDFW_CONFIG_FILE)),) MAINBOARD_BLOBS_DIR := $(call strip_quotes, $(CONFIG_APCB_BLOBS_DIR)) From cf280eaa7f6cb6b2de17f8e879e2cb6b73965798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 4 Dec 2025 14:52:21 +0100 Subject: [PATCH 103/789] amdblocks/root_complex.h: Add new IOHC base addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting with Turin there are 8 IOHCs per SoC. Add new definitions for the missing IOHCs. Based on Turin C1 PPR (doc 57238). Change-Id: I31e93e680e3f0ba03d2595f632d6827b4e3042b8 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/90368 Reviewed-by: Felix Held Tested-by: build bot (Jenkins) --- src/soc/amd/common/block/include/amdblocks/root_complex.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/soc/amd/common/block/include/amdblocks/root_complex.h b/src/soc/amd/common/block/include/amdblocks/root_complex.h index bfabf973a7..c60872aa2a 100644 --- a/src/soc/amd/common/block/include/amdblocks/root_complex.h +++ b/src/soc/amd/common/block/include/amdblocks/root_complex.h @@ -11,6 +11,11 @@ #define SMN_IOHC_MISC_BASE_13D1 0x13d10000 #define SMN_IOHC_MISC_BASE_13E1 0x13e10000 +#define SMN_IOHC_MISC_BASE_1D41 0x1d410000 +#define SMN_IOHC_MISC_BASE_1D51 0x1d510000 +#define SMN_IOHC_MISC_BASE_1D61 0x1d610000 +#define SMN_IOHC_MISC_BASE_1D71 0x1d710000 + #define IOHC_MMIO_EN BIT(0) #define NON_PCI_RES_IDX_AUTO 0 From 17b36286c894dbaa72b9d278c47a5ffd429d3f92 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 29 Dec 2025 08:39:03 -0600 Subject: [PATCH 104/789] mb/google/hatch/var/kindred: Drop VBT for KLED variant The KLED VBT file is misconfigured and results in an error under Linux: [drm] ERROR VBT has malformed LFP data table pointers Inspecting the VBT using the Intel BMP tool reveals invalid data for many of the panel definitions, as well as other settings. KLED works perfectly fine with the kindred VBT, so use that instead. TEST=build/boot Win11/Linux on KLED, verify display output works properly. Change-Id: I09aaa5c17517633fdae508239ecf8e72e3990e33 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90637 Reviewed-by: Eric Lai Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- .../google/hatch/variants/kindred/Makefile.mk | 2 -- .../google/hatch/variants/kindred/kled-data.vbt | Bin 4612 -> 0 bytes .../google/hatch/variants/kindred/variant.c | 11 ----------- 3 files changed, 13 deletions(-) delete mode 100644 src/mainboard/google/hatch/variants/kindred/kled-data.vbt diff --git a/src/mainboard/google/hatch/variants/kindred/Makefile.mk b/src/mainboard/google/hatch/variants/kindred/Makefile.mk index 767e119dbc..1676fd9798 100644 --- a/src/mainboard/google/hatch/variants/kindred/Makefile.mk +++ b/src/mainboard/google/hatch/variants/kindred/Makefile.mk @@ -12,5 +12,3 @@ SPD_SOURCES += 16G_3200 # 0b111 bootblock-y += gpio.c ramstage-y += gpio.c ramstage-y += variant.c - -$(call add_vbt_to_cbfs, vbt-kled.bin, kled-data.vbt) diff --git a/src/mainboard/google/hatch/variants/kindred/kled-data.vbt b/src/mainboard/google/hatch/variants/kindred/kled-data.vbt deleted file mode 100644 index f07cb69c062a52918f8fbbf02c6d9474579ef699..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4612 zcmeHKU2GIp6h5=l{kt=>ot+Zdu2>Jyz;2;sw!n(D#M$l^yL8KLyQL}7qy=_?hK1Jt zXfc?sNuxX{*#|UeQ2IhtUc@Kk8@?D46D2XxCnF{%D85MK#el45?o59y!7dn33}@%u zbMBdYzd7gro~`d|>&0y6u2ihE9c{{i4rlynDsQE>WI8*Li1o$>+EVFwC;kYJz_|bB z6@Z)|)XEWEk0cL|=L?~pFu|sFQyD-y}?nt&Jd)pHVn+qd8JaS}oX#at648_CPOy6kapxkAQ z508#CVXRQV9<$9D_TD-`#W2@jG+gcB}0^DR51TS*c0GzWUb^rVTsH#WvT1Gd0o-_ee0ZoP1kUn8GtGAoc zhaJ2F3dj|+Ez*yO(4uxT64pm`0WF0$Q>|vuVK%6&>)ZxCI)jE`aVu$a+=SM|_0%YbS&6h%XagCB9DVbTOzVt|eYg z+(`Tcag4Z=cqj1y@er|V0&bKYMWC4=DhjsrTN2bNI39-LDcgR^wtIi2Nhe~qlx)e3 z6%^&N+YL9%Uk0FD_G~phFbILd77{j6hb>cFiekpD_mVWns^6}c%ibJS9ejb@tMV)n z`vT@RUb#FQU}T4Ie7W+g2zv0(|{l(hFH z_OXQDO4`p7`%S`HSz9Nw%`!eKYlmd^qKxm#+D9_`RL1XR?W)YK%eYd}HY#kZf_oKh zLSa)1o>8<<6!w{dmlf@Ig^4~4`?RNgtlftPecH=D_L@&=(40lbC86l|@f^i7D%1JY z?~u8?Ca5Hx)obZCymextQ-XB_$SC$ZmPVMVMu_yUz)*3SH6(S>DeGdS`Jy9#X@p!Y z7%^C*2aZK8gg|skv{EZ_6RJ#vR!XpLABElkC%Zv6^pTo5AE=|L%ahJvMF^AF9aIf< z0fJC+-T}e~8zwJx2iF+=C+B?-N-mCIxXxAJL&wvGzUN%CVVs{wa9Np>+~=%hB=@cC zJKGI)`nHli7v@No`29+*R5A`nn@Tf-!8$`ndoE};t4chRm5c65q6oDXXGYGgCWHnv zb^tWq zf7UL466f`W_J5$47m;HTt&hU%+sMfzW%oPj0?WaA;VmFXX8TcI%*nNgnsfn<&C!FQ XT9YyR=jFc3jpngs9ssn #include #include -#include #include void variant_devtree_update(void) @@ -45,13 +44,3 @@ const char *get_wifi_sar_cbfs_filename(void) return "wifi_sar-kled.hex"; return WIFI_SAR_CBFS_DEFAULT_FILENAME; } - -const char *mainboard_vbt_filename(void) -{ - uint32_t sku_id = google_chromeec_get_board_sku(); - - if (sku_id == 1 || sku_id == 2 || sku_id == 3 || sku_id == 4) - return "vbt-kled.bin"; - else - return "vbt.bin"; -} From 4decc72c23ed8a0d00a5681e5b4500ee4c7ac8f2 Mon Sep 17 00:00:00 2001 From: Cliff Huang Date: Mon, 29 Dec 2025 18:09:45 -0800 Subject: [PATCH 105/789] drivers/intel/touch: Change ELAN device name for Google's Rex touch device Change Google's Rex touch device name from TH_SENSOR_GOOGLE to TH_SENSOR_ELAN_REX to better reflect the specific vendor and platform combination. This provides clearer identification and avoids generic naming that could cause confusion with other Google touch implementations. BUG=none TEST=This change cannot be tested in isolation as it only contains naming changes. Testing requires hardware that supports Rex touchscreen functionality, such as: Fatcat board with Google's specialized cable connected to a Rex touchscreen. Verify that the new naming convention works correctly with change: https://review.coreboot.org/c/coreboot/+/89181 (This change uses the new naming convention introduced here). Touch functionality should work identically to before, with only the internal naming updated. Signed-off-by: Cliff Huang Change-Id: I40bb33dee14e9a567ad9dfcf956f3a9cca26dcad Reviewed-on: https://review.coreboot.org/c/coreboot/+/90645 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) Reviewed-by: Kim, Kyoung Il --- src/drivers/intel/touch/chip.h | 6 +++++- src/drivers/intel/touch/elan.h | 9 +++++---- src/drivers/intel/touch/touch.c | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/drivers/intel/touch/chip.h b/src/drivers/intel/touch/chip.h index 83b5cd7d37..6e2696ff3f 100644 --- a/src/drivers/intel/touch/chip.h +++ b/src/drivers/intel/touch/chip.h @@ -178,8 +178,12 @@ struct intel_thc_hidspi_info { enum intel_touch_device { TH_SENSOR_NONE, TH_SENSOR_WACOM, /* BOM22 for SPI only */ + /* + * TH_SENSOR_ELAN: the ELAN device for Intel's RVPs (default for ELAN) + * TH_SENSOR_ELAN_REX: the devece used in Google Rex; requires a special cable for Intel's RVP + */ TH_SENSOR_ELAN, /* BOM36 for SPI and BOM37 for I2C */ - TH_SENSOR_GOOGLE, /* ELAN9006 for SPI and ELAN6918 for I2C */ + TH_SENSOR_ELAN_REX, /* ELAN9006 for SPI and ELAN6918 for I2C */ TH_SENSOR_HYNITRON, /* NYITRON for I2C only */ TH_SENSOR_GENERIC, /* for device properity thru devicetree */ }; diff --git a/src/drivers/intel/touch/elan.h b/src/drivers/intel/touch/elan.h index 4f7b2a1ee0..baaa56880a 100644 --- a/src/drivers/intel/touch/elan.h +++ b/src/drivers/intel/touch/elan.h @@ -32,19 +32,20 @@ static const struct drivers_intel_touch_config elan_touch_config = { /* * ELAN9006 is used for HID-SPI interface, while ELAN6918 is used for HID-I2C - * interface. + * interface; This is Google Rex's touch device and requires a special cable + * in Intel's RVP and fatcat. */ -static const struct drivers_intel_touch_config google_touch_config = { +static const struct drivers_intel_touch_config elan_rex_touch_config = { .sensor_dev_name = "ELAN Touch Sensor Device", - .dev_hidi2c = { /* Google's I2C-based touch */ + .dev_hidi2c = { /* Google Rex's I2C-based touch */ .hid = "ELAN6918", .cid = "PNP0C50", .intf.hidi2c.addr = 0x10, .intf.hidi2c.descriptor_address = 0x1, .intf.hidi2c.connection_speed = I2C_SPEED_FAST, /* fast mode */ }, - .dev_hidspi = { /* Google's SPI-based touch */ + .dev_hidspi = { /* Google Rex's SPI-based touch */ .hid = "ELAN9006", .cid = "PNP0C51", .intf.hidspi.connection_speed = (32 * MHz), /* unit: Hz */ diff --git a/src/drivers/intel/touch/touch.c b/src/drivers/intel/touch/touch.c index 85dd7f9159..03738741b8 100644 --- a/src/drivers/intel/touch/touch.c +++ b/src/drivers/intel/touch/touch.c @@ -43,7 +43,7 @@ static const struct drivers_intel_touch_config *get_driver_config(const struct d switch (config->connected_device) { case TH_SENSOR_WACOM: return &wacom_touch_config; case TH_SENSOR_ELAN: return &elan_touch_config; - case TH_SENSOR_GOOGLE: return &google_touch_config; + case TH_SENSOR_ELAN_REX: return &elan_rex_touch_config; case TH_SENSOR_HYNITRON: return &hynitron_touch_config; case TH_SENSOR_GENERIC: return config; case TH_SENSOR_NONE: return NULL; From 82f9c593ab1e25d27ece3ac775e1d209030ce3c4 Mon Sep 17 00:00:00 2001 From: Ziang Wang Date: Mon, 20 Oct 2025 20:07:50 +0800 Subject: [PATCH 106/789] payloads/libpayload: Add support for RISC-V 64-bit architecture This patch adds config ARCH_RISCV_RV64 to support build of riscv64 payloads. New files under arch/riscv contain: - Basic ldscript and payload entry point. - Functions for riscv64 io and cache operations. - Default timer code based on mtime delegation. - Default cb_header_ptr passing with device tree to payload. Change-Id: Ieb3d456d5edda87a3a4886ccfc17a7824c630427 Signed-off-by: Ziang Wang Signed-off-by: Dong Wei Reviewed-on: https://review.coreboot.org/c/coreboot/+/89646 Reviewed-by: Maximilian Brune Tested-by: build bot (Jenkins) --- payloads/libpayload/Kconfig | 10 ++ payloads/libpayload/Makefile | 2 + payloads/libpayload/Makefile.mk | 1 + payloads/libpayload/arch/riscv/Kconfig | 4 + payloads/libpayload/arch/riscv/Makefile.mk | 7 ++ payloads/libpayload/arch/riscv/cache.c | 13 +++ payloads/libpayload/arch/riscv/coreboot.c | 34 ++++++ payloads/libpayload/arch/riscv/head.S | 24 ++++ .../libpayload/arch/riscv/libpayload.ldscript | 65 +++++++++++ payloads/libpayload/arch/riscv/main.c | 53 +++++++++ payloads/libpayload/arch/riscv/sysinfo.c | 70 ++++++++++++ payloads/libpayload/arch/riscv/timer.c | 53 +++++++++ payloads/libpayload/arch/riscv/util.S | 34 ++++++ payloads/libpayload/arch/riscv/virtual.c | 36 ++++++ payloads/libpayload/drivers/Makefile.mk | 1 + payloads/libpayload/drivers/timer/Kconfig | 6 + .../drivers/timer/riscv64_arch_timer.c | 16 +++ payloads/libpayload/include/riscv/arch/asm.h | 23 ++++ .../libpayload/include/riscv/arch/cache.h | 21 ++++ payloads/libpayload/include/riscv/arch/io.h | 106 ++++++++++++++++++ .../libpayload/include/riscv/arch/types.h | 33 ++++++ .../libpayload/include/riscv/arch/virtual.h | 14 +++ src/arch/riscv/boot.c | 73 +++++++++++- 23 files changed, 693 insertions(+), 6 deletions(-) create mode 100644 payloads/libpayload/arch/riscv/Kconfig create mode 100644 payloads/libpayload/arch/riscv/Makefile.mk create mode 100644 payloads/libpayload/arch/riscv/cache.c create mode 100644 payloads/libpayload/arch/riscv/coreboot.c create mode 100644 payloads/libpayload/arch/riscv/head.S create mode 100644 payloads/libpayload/arch/riscv/libpayload.ldscript create mode 100644 payloads/libpayload/arch/riscv/main.c create mode 100644 payloads/libpayload/arch/riscv/sysinfo.c create mode 100644 payloads/libpayload/arch/riscv/timer.c create mode 100644 payloads/libpayload/arch/riscv/util.S create mode 100644 payloads/libpayload/arch/riscv/virtual.c create mode 100644 payloads/libpayload/drivers/timer/riscv64_arch_timer.c create mode 100644 payloads/libpayload/include/riscv/arch/asm.h create mode 100644 payloads/libpayload/include/riscv/arch/cache.h create mode 100644 payloads/libpayload/include/riscv/arch/io.h create mode 100644 payloads/libpayload/include/riscv/arch/types.h create mode 100644 payloads/libpayload/include/riscv/arch/virtual.h diff --git a/payloads/libpayload/Kconfig b/payloads/libpayload/Kconfig index 44d656bcac..9ad454181f 100644 --- a/payloads/libpayload/Kconfig +++ b/payloads/libpayload/Kconfig @@ -127,6 +127,15 @@ config ARCH_ARM64 help Support the ARM64 architecture +config ARCH_RISCV_RV64 + bool "RISCV64" + depends on GPL + depends on EXPERIMENTAL + help + Support the RISC-V 64-bit architecture + Please note that support for riscv64 payload is experimental at this time, may have + fundamental change in the future. + config ARCH_MOCK bool "Mock architecture (for unit tests)" help @@ -523,3 +532,4 @@ source "arch/arm/Kconfig" source "arch/arm64/Kconfig" source "arch/x86/Kconfig" source "arch/mock/Kconfig" +source "arch/riscv/Kconfig" diff --git a/payloads/libpayload/Makefile b/payloads/libpayload/Makefile index a8c2641dc6..6ac1e90d26 100644 --- a/payloads/libpayload/Makefile +++ b/payloads/libpayload/Makefile @@ -111,6 +111,7 @@ ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64 ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86 ARCHDIR-$(CONFIG_LP_ARCH_MOCK) := mock +ARCHDIR-$(CONFIG_LP_ARCH_RISCV_RV64) := riscv ARCH-y := $(ARCHDIR-y) @@ -121,6 +122,7 @@ ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64 ARCH-$(CONFIG_LP_ARCH_X86_32) := x86_32 ARCH-$(CONFIG_LP_ARCH_X86_64) := x86_64 ARCH-$(CONFIG_LP_ARCH_MOCK) := mock +ARCH-$(CONFIG_LP_ARCH_RISCV_RV64) := riscv # Five cases where we don't need fully populated $(obj) lists: # 1. when no .config exists diff --git a/payloads/libpayload/Makefile.mk b/payloads/libpayload/Makefile.mk index 08249c2648..f7c2c8bda0 100644 --- a/payloads/libpayload/Makefile.mk +++ b/payloads/libpayload/Makefile.mk @@ -41,6 +41,7 @@ ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64 ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86 ARCHDIR-$(CONFIG_LP_ARCH_MOCK) := mock +ARCHDIR-$(CONFIG_LP_ARCH_RISCV_RV64) := riscv DESTDIR ?= install real-target: lib diff --git a/payloads/libpayload/arch/riscv/Kconfig b/payloads/libpayload/arch/riscv/Kconfig new file mode 100644 index 0000000000..03960ab1da --- /dev/null +++ b/payloads/libpayload/arch/riscv/Kconfig @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config ARCH_RISCV_RV64 + select LITTLE_ENDIAN diff --git a/payloads/libpayload/arch/riscv/Makefile.mk b/payloads/libpayload/arch/riscv/Makefile.mk new file mode 100644 index 0000000000..cb835bbfcb --- /dev/null +++ b/payloads/libpayload/arch/riscv/Makefile.mk @@ -0,0 +1,7 @@ +## SPDX-License-Identifier: GPL-2.0-only + +libc-y += head.S +libc-y += main.c sysinfo.c +libc-y += timer.c coreboot.c cache.c util.S virtual.c + +CFLAGS += -mcmodel=medany diff --git a/payloads/libpayload/arch/riscv/cache.c b/payloads/libpayload/arch/riscv/cache.c new file mode 100644 index 0000000000..d5dcb5e2a2 --- /dev/null +++ b/payloads/libpayload/arch/riscv/cache.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void tlb_invalidate_all(void) +{ + asm volatile ("sfence.vma" : : : "memory"); +} + +void dcache_clean_invalidate_all(void) +{ + +} diff --git a/payloads/libpayload/arch/riscv/coreboot.c b/payloads/libpayload/arch/riscv/coreboot.c new file mode 100644 index 0000000000..acd3e85fb1 --- /dev/null +++ b/payloads/libpayload/arch/riscv/coreboot.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +/* + * This pointer is no longer set in head.S by default like in other arch, payloads should have + * their own ways to init it from any source before using it. + * e.g. If run after OpenSBI, this could be retrieved from fdt node. + * If run directly after Ramstage, could be from arg0. + */ +void *cb_header_ptr; + +/* == Architecture specific == */ + +int cb_parse_arch_specific(struct cb_record *rec, struct sysinfo_t *info) +{ + switch (rec->tag) { + default: + return 0; + } + return 1; +} + +int get_coreboot_info(struct sysinfo_t *info) +{ + return cb_parse_header(cb_header_ptr, 1, info); +} + +void *get_cb_header_ptr(void) +{ + return cb_header_ptr; +} diff --git a/payloads/libpayload/arch/riscv/head.S b/payloads/libpayload/arch/riscv/head.S new file mode 100644 index 0000000000..aebbff979d --- /dev/null +++ b/payloads/libpayload/arch/riscv/head.S @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +/* + * Our entry point + */ +ENTRY(_entry) + + /* Setup new stack */ + lla t0, 1f + ld sp, 0(t0) + //mov sp, x1 + + /* Let's rock. */ + j start_main + + ret +ENDPROC(_entry) + +.section .entry, "ax", %progbits +.align 4 +1: +.quad _stack diff --git a/payloads/libpayload/arch/riscv/libpayload.ldscript b/payloads/libpayload/arch/riscv/libpayload.ldscript new file mode 100644 index 0000000000..168f61397a --- /dev/null +++ b/payloads/libpayload/arch/riscv/libpayload.ldscript @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +OUTPUT_ARCH(riscv) + +ENTRY(_entry) + +SECTIONS +{ + . = CONFIG_LP_BASE_ADDRESS; + + . = ALIGN(16); + _start = .; + + .text : { + _text = .; + *(.text._entry) + *(.text) + *(.text.*) + _etext = .; + } + + .rodata : { + _rodata = .; + *(.rodata) + *(.rodata.*) + _erodata = .; + } + + .data : { + _data = .; + *(.data) + *(.data.*) + _edata = .; + } + + .bss : { + _bss = .; + *(.sbss) + *(.sbss.*) + *(.bss) + *(.bss.*) + *(COMMON) + _ebss = .; + + /* Stack and heap */ + + . = ALIGN(16); + _heap = .; + . += CONFIG_LP_HEAP_SIZE; + . = ALIGN(16); + _eheap = .; + + _estack = .; + . += CONFIG_LP_STACK_SIZE; + . = ALIGN(16); + _stack = .; + } + + _end = .; + + /DISCARD/ : { + *(.comment) + *(.note*) + } +} diff --git a/payloads/libpayload/arch/riscv/main.c b/payloads/libpayload/arch/riscv/main.c new file mode 100644 index 0000000000..d0b400c8f2 --- /dev/null +++ b/payloads/libpayload/arch/riscv/main.c @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +uint64_t boot_hartid; +/** + * This is our C entry function - set up the system and jump into the payload entry point. + * Unlike other archs, we do not save a0~a2 from previous stage as global variables in head.S, + * but pass them to start_main directly as arg0, arg1, arg2 instead. + * + * arg0 is the preferred boot hart id. + * arg1 is a pointer to the DTB. + * This interface is static no matter whether previous stage is OpenSBI or coreboot Ramstage. + * + * arg2 is reserved for possible future usage. + */ +void start_main(uint64_t arg0, uint64_t arg1, uint64_t arg2); +void start_main(uint64_t arg0, uint64_t arg1, uint64_t arg2) +{ + extern int main(int argc, char **argv); + extern void *cb_header_ptr; + + /* cbtable pointer is stored in the dtb passed by previous stage */ + boot_hartid = arg0; + const void *dtb = (const void *)arg1; + if (dtb && fdt_is_valid(dtb)) { + /* Look for the "coreboot-table" node in the DTB */ + u32 node_offset = fdt_find_node_by_path(dtb, "/chosen", NULL, NULL); + if (node_offset) { + struct fdt_property prop; + if (fdt_read_prop(dtb, node_offset, "coreboot-table", &prop)) { + /* Extract the coreboot table pointer from the property */ + cb_header_ptr = (void *)be64dec(prop.data); + } + } + } + + /* Gather system information. */ + lib_get_sysinfo(); + +#if !CONFIG(LP_SKIP_CONSOLE_INIT) + console_init(); +#endif + + /* + * Go to the entry point. + * In the future we may care about the return value. + */ + main(0, NULL); + printf("Unexpected return from payload\n"); +} diff --git a/payloads/libpayload/arch/riscv/sysinfo.c b/payloads/libpayload/arch/riscv/sysinfo.c new file mode 100644 index 0000000000..353ede174e --- /dev/null +++ b/payloads/libpayload/arch/riscv/sysinfo.c @@ -0,0 +1,70 @@ +/* + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +/** + * This is a global structure that is used through the library - we set it + * up initially with some dummy values - hopefully they will be overridden. + */ +struct sysinfo_t lib_sysinfo = { + .cpu_khz = 200, +}; + +int lib_get_sysinfo(void) +{ + int ret; + + /* Get the CPU speed (for delays). */ + lib_sysinfo.cpu_khz = get_cpu_speed(); + + /* Get information from the coreboot tables, + * if they exist */ + + ret = get_coreboot_info(&lib_sysinfo); + + if (!lib_sysinfo.n_memranges) { + /* If we can't get a good memory range, use the default. */ + lib_sysinfo.n_memranges = 1; + + lib_sysinfo.memrange[0].base = 0; + lib_sysinfo.memrange[0].size = 1024 * 1024; + lib_sysinfo.memrange[0].type = CB_MEM_RAM; + } + + return ret; +} + +void lib_sysinfo_get_memranges(struct memrange **ranges, + uint64_t *nranges) +{ + *ranges = &lib_sysinfo.memrange[0]; + *nranges = lib_sysinfo.n_memranges; +} diff --git a/payloads/libpayload/arch/riscv/timer.c b/payloads/libpayload/arch/riscv/timer.c new file mode 100644 index 0000000000..1177e09802 --- /dev/null +++ b/payloads/libpayload/arch/riscv/timer.c @@ -0,0 +1,53 @@ +/* + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * @file riscv64/timer.c + * RISCV64 specific timer routines + */ + +#include + +/** + * @ingroup arch + * Global variable containing the speed of the processor in KHz. + */ +u32 cpu_khz; + +/** + * Calculate the speed of the processor for use in delays. + * + * @return The CPU speed in kHz. + */ +unsigned int get_cpu_speed(void) +{ + /* FIXME */ + cpu_khz = 1000000U; + + return cpu_khz; +} diff --git a/payloads/libpayload/arch/riscv/util.S b/payloads/libpayload/arch/riscv/util.S new file mode 100644 index 0000000000..3b15abc21d --- /dev/null +++ b/payloads/libpayload/arch/riscv/util.S @@ -0,0 +1,34 @@ +/* + * + * Copyright (C) 2012 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +/* This function puts the system into a halt. */ +ENTRY(halt) + j halt +ENDPROC(halt) diff --git a/payloads/libpayload/arch/riscv/virtual.c b/payloads/libpayload/arch/riscv/virtual.c new file mode 100644 index 0000000000..9450ac0d86 --- /dev/null +++ b/payloads/libpayload/arch/riscv/virtual.c @@ -0,0 +1,36 @@ +/* + * + * Copyright (C) 2008 coresystems GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +unsigned long virtual_offset = 0; + +int getpagesize(void) +{ + return 4096; +} diff --git a/payloads/libpayload/drivers/Makefile.mk b/payloads/libpayload/drivers/Makefile.mk index 23471b83c4..63daf67cdb 100644 --- a/payloads/libpayload/drivers/Makefile.mk +++ b/payloads/libpayload/drivers/Makefile.mk @@ -64,6 +64,7 @@ libc-y += timer/generic.c endif libc-$(CONFIG_LP_TIMER_RDTSC) += timer/rdtsc.c libc-$(CONFIG_LP_TIMER_ARM64_ARCH) += timer/arm64_arch_timer.c +libc-$(CONFIG_LP_TIMER_RISCV64_ARCH) += timer/riscv64_arch_timer.c # Video console drivers libc-$(CONFIG_LP_VIDEO_CONSOLE) += video/video.c diff --git a/payloads/libpayload/drivers/timer/Kconfig b/payloads/libpayload/drivers/timer/Kconfig index 406457af8e..1932a136da 100644 --- a/payloads/libpayload/drivers/timer/Kconfig +++ b/payloads/libpayload/drivers/timer/Kconfig @@ -36,6 +36,12 @@ config TIMER_ARM64_ARCH help The cntfrq register needs to have been pre-initialized. +config TIMER_RISCV64_ARCH + bool "Architecture Timer for RISCV64 platforms" + depends on ARCH_RISCV_RV64 + help + Payloads usually run in S-Mode, which has a time CSR for timer implementation. + config TIMER_RK3288 bool "Timer for Rockchip RK3288" diff --git a/payloads/libpayload/drivers/timer/riscv64_arch_timer.c b/payloads/libpayload/drivers/timer/riscv64_arch_timer.c new file mode 100644 index 0000000000..515ae47658 --- /dev/null +++ b/payloads/libpayload/drivers/timer/riscv64_arch_timer.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +uint64_t timer_hz(void) +{ + /* FIXME */ + return 1000000; +} + +uint64_t timer_raw_value(void) +{ + uint64_t value; + asm volatile ("csrr %0, time" : "=r" (value)); + return value; +} diff --git a/payloads/libpayload/include/riscv/arch/asm.h b/payloads/libpayload/include/riscv/arch/asm.h new file mode 100644 index 0000000000..5d8eae20e2 --- /dev/null +++ b/payloads/libpayload/include/riscv/arch/asm.h @@ -0,0 +1,23 @@ +/* + * + * Copyright 2013 Google Inc. + * + */ + +#ifndef __RISCV64_ASM_H +#define __RISCV64_ASM_H + +#define ENDPROC(name) \ + .type name, %function; \ + END(name) + +#define ENTRY(name) \ + .section .text.name, "ax", %progbits; \ + .global name; \ + .align 2; \ + name: + +#define END(name) \ + .size name, .-name + +#endif /* __RISCV64_ASM_H */ diff --git a/payloads/libpayload/include/riscv/arch/cache.h b/payloads/libpayload/include/riscv/arch/cache.h new file mode 100644 index 0000000000..d47b05dd41 --- /dev/null +++ b/payloads/libpayload/include/riscv/arch/cache.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef RISCV64_CACHE_H +#define RISCV64_CACHE_H + +#include +#include + +/* tlb invalidate all */ +void tlb_invalidate_all(void); + +void dcache_clean_invalidate_all(void); + +/* Invalidate all of the instruction cache for PE to PoU. */ +static inline void icache_invalidate_all(void) +{ + __asm__ __volatile__("fence.i\n\t"); +} + + +#endif /* RISCV64_CACHE_H */ diff --git a/payloads/libpayload/include/riscv/arch/io.h b/payloads/libpayload/include/riscv/arch/io.h new file mode 100644 index 0000000000..b586204bfe --- /dev/null +++ b/payloads/libpayload/include/riscv/arch/io.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ARCH_IO_H +#define _ARCH_IO_H + +#include +#include + +#define fence_i_r() __asm__ __volatile__("fence i,r" : : : "memory") +#define fence_ow_ow() __asm__ __volatile__("fence ow,ow" : : : "memory") + +/* + * readb/w/l writeb/w/l are deprecated. use read8/16/32 and write8/16/32 + * instead for future development. + */ + +static inline uint8_t readb(volatile const void *_a) +{ + return *(volatile const uint8_t *)_a; + fence_i_r(); +} + +static inline uint16_t readw(volatile const void *_a) +{ + return *(volatile const uint16_t *)_a; + fence_i_r(); +} + +static inline uint32_t readl(volatile const void *_a) +{ + return *(volatile const uint32_t *)_a; + fence_i_r(); +} + +static inline void writeb(uint8_t _v, volatile void *_a) +{ + fence_ow_ow(); + *(volatile uint8_t *)_a = _v; +} + +static inline void writew(uint16_t _v, volatile void *_a) +{ + fence_ow_ow(); + *(volatile uint16_t *)_a = _v; +} + +static inline void writel(uint32_t _v, volatile void *_a) +{ + fence_ow_ow(); + *(volatile uint32_t *)_a = _v; +} + +/* + * TODO: make the existing code use read8/16/32 and write8/16/32 then remove + * readb/w/l and writeb/w/l. + */ + +static inline uint8_t read8(volatile const void *addr) +{ + return *(volatile uint8_t *)addr; + fence_i_r(); +} + +static inline uint16_t read16(volatile const void *addr) +{ + return *(volatile uint16_t *)addr; + fence_i_r(); +} + +static inline uint32_t read32(volatile const void *addr) +{ + return *(volatile uint32_t *)addr; + fence_i_r(); +} + +static inline uint64_t read64(volatile const void *addr) +{ + return *(volatile uint64_t *)addr; + fence_i_r(); +} + +static inline void write8(volatile void *addr, uint8_t val) +{ + fence_ow_ow(); + *(volatile uint8_t *)addr = val; +} + +static inline void write16(volatile void *addr, uint16_t val) +{ + fence_ow_ow(); + *(volatile uint16_t *)addr = val; +} + +static inline void write32(volatile void *addr, uint32_t val) +{ + fence_ow_ow(); + *(volatile uint32_t *)addr = val; +} + +static inline void write64(volatile void *addr, uint64_t val) +{ + fence_ow_ow(); + *(volatile uint64_t *)addr = val; +} + +#endif diff --git a/payloads/libpayload/include/riscv/arch/types.h b/payloads/libpayload/include/riscv/arch/types.h new file mode 100644 index 0000000000..044e047f37 --- /dev/null +++ b/payloads/libpayload/include/riscv/arch/types.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ARCH_TYPES_H +#define _ARCH_TYPES_H + +typedef unsigned char uint8_t; +typedef unsigned char u8; +typedef signed char int8_t; +typedef signed char s8; + +typedef unsigned short uint16_t; +typedef unsigned short u16; +typedef signed short int16_t; +typedef signed short s16; + +typedef unsigned int uint32_t; +typedef unsigned int u32; +typedef signed int int32_t; +typedef signed int s32; + +typedef unsigned long long uint64_t; +typedef unsigned long long u64; +typedef signed long long int64_t; +typedef signed long long s64; + +typedef long time_t; +typedef long suseconds_t; + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#endif diff --git a/payloads/libpayload/include/riscv/arch/virtual.h b/payloads/libpayload/include/riscv/arch/virtual.h new file mode 100644 index 0000000000..4b107787d2 --- /dev/null +++ b/payloads/libpayload/include/riscv/arch/virtual.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ARCH_VIRTUAL_H +#define _ARCH_VIRTUAL_H + +extern unsigned long virtual_offset; + +#define virt_to_phys(virt) ((unsigned long) (virt) + virtual_offset) +#define phys_to_virt(phys) ((void *) ((unsigned long) (phys) - virtual_offset)) + +#define virt_to_bus(addr) virt_to_phys(addr) +#define bus_to_virt(addr) phys_to_virt(addr) + +#endif diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c index 6f744d3211..7d1cb3e92d 100644 --- a/src/arch/riscv/boot.c +++ b/src/arch/riscv/boot.c @@ -8,12 +8,58 @@ #include #include #include +#include +#include struct arch_prog_run_args { struct prog *prog; struct prog *opensbi; }; +/* + * At the moment devicetree is the default handoff format to the payload instead of + * coreboot tables (on RISC-V only). That may change in the future, but for now we will put a + * reference to the coreboot tables inside the FDT (similar to what we do in ACPI). + */ +static void *add_coreboot_table_to_fdt(void *fdt) +{ + if (!fdt || !fdt_is_valid(fdt)) { + printk(BIOS_ERR, "Invalid FDT provided\n"); + return fdt; + } + + void *coreboot_table = cbmem_find(CBMEM_ID_CBTABLE); + if (!coreboot_table) { + printk(BIOS_ERR, "coreboot table not found in CBMEM\n"); + return fdt; + } + + struct device_tree *tree = fdt_unflatten(fdt); + if (!tree) { + printk(BIOS_ERR, "Failed to unflatten FDT\n"); + return fdt; + } + + struct device_tree_node *chosen_node = dt_find_node_by_path(tree, "/chosen", NULL, NULL, 1); + if (!chosen_node) { + printk(BIOS_ERR, "Failed to find or create /chosen node\n"); + return fdt; + } + + printk(BIOS_INFO, "Adding cbtable@%p to fdt\n", coreboot_table); + dt_add_u64_prop(chosen_node, "coreboot-table", (uint64_t)(uintptr_t)coreboot_table); + + size_t next_size = dt_flat_size(tree); + void *next_fdt = malloc(next_size); + if (!next_fdt) { + printk(BIOS_ERR, "Failed to allocate memory for next-stage FDT\n"); + return fdt; + } + + dt_flatten(tree, next_fdt); + return next_fdt; +} + /* * A pointer to the Flattened Device Tree passed to coreboot by the boot ROM. * Presumably this FDT is also in ROM. @@ -51,14 +97,29 @@ void arch_prog_run(struct prog *prog) args.prog = prog; - /* In case of OpenSBI we have to load it before resuming all HARTs */ - if (ENV_RAMSTAGE && CONFIG(RISCV_OPENSBI)) { - struct prog sbi = PROG_INIT(PROG_OPENSBI, CONFIG_CBFS_PREFIX"/opensbi"); + if (ENV_RAMSTAGE) { + int hart_count = CONFIG_MAX_CPUS; + if (CONFIG(RISCV_GET_HART_COUNT_AT_RUNTIME)) + hart_count = smp_get_hart_count(); - if (!selfload_check(&sbi, BM_MEM_OPENSBI)) - die("OpenSBI load failed"); + /* Embed coreboot table pointer into fdt, so that payload can find it. */ + void *fdt = HLS()->fdt; + void *next_fdt = add_coreboot_table_to_fdt(fdt); - args.opensbi = &sbi; + /* Update per hart's fdt with "coreboot-table" node embedded */ + for (int i = 0; i < hart_count; i++) { + OTHER_HLS(i)->fdt = next_fdt; + } + + /* In case of OpenSBI we have to load it before resuming all HARTs */ + if (CONFIG(RISCV_OPENSBI)) { + struct prog sbi = PROG_INIT(PROG_OPENSBI, CONFIG_CBFS_PREFIX"/opensbi"); + + if (!selfload_check(&sbi, BM_MEM_OPENSBI)) + die("OpenSBI load failed"); + + args.opensbi = &sbi; + } } smp_resume((void (*)(void *))do_arch_prog_run, &args); From 14a7a2315e722ef83b567d1918d7990eb83a451c Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Wed, 31 Dec 2025 15:22:27 +0800 Subject: [PATCH 107/789] soc/mediatek/mt8196: Call fsp_init via boot state Refactor fsp_init to be called as a boot state entry (BS_DEV_INIT, BS_ON_ENTRY) instead of directly from soc_init. This ensures fsp initialization occurs at the appropriate boot stage. This change is necessary for FW logo rendering in the ramstage. fsp_init must be run before FW display starts rendering the logo. BUG=b:471111147 TEST=Check FW logo Change-Id: I41b32229d4c582d84afac5c336eb98b1b1274ba8 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90686 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Yu-Ping Wu Reviewed-by: Chen-Tsung Hsieh --- src/soc/mediatek/mt8196/soc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/soc/mediatek/mt8196/soc.c b/src/soc/mediatek/mt8196/soc.c index 24077a0fbc..e988a76926 100644 --- a/src/soc/mediatek/mt8196/soc.c +++ b/src/soc/mediatek/mt8196/soc.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include #include @@ -56,7 +57,7 @@ static void mte_setup(void) booker_mte_init(mte_start); } -static void fsp_init(void) +static void fsp_init(void *arg) { uint32_t storage_type = mainboard_get_storage_type(); @@ -67,6 +68,8 @@ static void fsp_init(void) mtk_fsp_load_and_run(); } +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, fsp_init, NULL); + static void soc_init(struct device *dev) { mtk_mmu_disable_l2c_sram(); @@ -76,7 +79,6 @@ static void soc_init(struct device *dev) if (spm_init()) printk(BIOS_ERR, "spm init failed, Suspend may not work\n"); - fsp_init(); sspm_init(); gpueb_init(); mcupm_init(); From e393fd00a4a06d305afbec244c38f98491ce5b1d Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Wed, 27 Aug 2025 21:12:43 +0200 Subject: [PATCH 108/789] include/cper.h: Update cper_ia32x64_context_t Use flexible array member cper_ia32x64_context to simplify the struct usage. Change-Id: I729cb914031b55b2b58bc9e459ee0ea15c7626e8 Signed-off-by: Maximilian Brune Reviewed-on: https://review.coreboot.org/c/coreboot/+/90479 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/arch/x86/acpi_bert_storage.c | 6 ++---- src/include/cper.h | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/arch/x86/acpi_bert_storage.c b/src/arch/x86/acpi_bert_storage.c index e9b9fc563a..321f66ac54 100644 --- a/src/arch/x86/acpi_bert_storage.c +++ b/src/arch/x86/acpi_bert_storage.c @@ -550,8 +550,6 @@ cper_ia32x64_context_t *cper_new_ia32x64_context_msr( cper_ia32x64_proc_error_section_t *x86err, u32 addr, int num) { cper_ia32x64_context_t *ctx; - int i; - msr_t *dest; ctx = new_cper_ia32x64_ctx(status, x86err, CPER_IA32X64_CTX_MSR, num * sizeof(msr_t)); if (!ctx) @@ -564,9 +562,9 @@ cper_ia32x64_context_t *cper_new_ia32x64_context_msr( */ ctx->msr_addr = addr; - dest = (msr_t *)((u8 *)(ctx + 1)); /* point to the Register Array */ + msr_t *dest = (msr_t *)(ctx->register_array); /* point to the Register Array */ - for (i = 0 ; i < num ; i++) + for (int i = 0 ; i < num ; i++) *(dest + i) = rdmsr(addr + i); return ctx; } diff --git a/src/include/cper.h b/src/include/cper.h index d0f7b30581..4dec2a2247 100644 --- a/src/include/cper.h +++ b/src/include/cper.h @@ -289,7 +289,7 @@ typedef struct cper_ia32x64_context { u16 array_size; u32 msr_addr; u64 mmap_addr; - /* N bytes of register array */ + u8 register_array[]; /* N bytes of register array */ } __packed cper_ia32x64_context_t; /* IA32/X64 Processor Context Information, Types field (Table N.13) */ From b9145e15888934992eed5dc70e5b4aaeb9103e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Fri, 5 Dec 2025 11:07:24 +0100 Subject: [PATCH 109/789] util/amdfwtool: Remove duplicated AMD_TA_IKEK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AMD_TA_IKEK occurrs twice in the amd_psp_fw_table, but the tool will only add it once anyways, so remove redundant entry. Change-Id: I7fd13552edf98d7adc749726c8bba46124aed495 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/90389 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- util/amdfwtool/amdfwtool.c | 1 - 1 file changed, 1 deletion(-) diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c index 9e9ada79a7..bac1c5bdbf 100644 --- a/util/amdfwtool/amdfwtool.c +++ b/util/amdfwtool/amdfwtool.c @@ -255,7 +255,6 @@ amd_fw_entry amd_psp_fw_table[] = { { .type = AMD_FW_AMF_WLAN, .inst = 2, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_AMF_WLAN, .inst = 3, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_AMF_MFD, .level = PSP_LVL2 | PSP_LVL2_AB }, - { .type = AMD_TA_IKEK, .level = PSP_BOTH | PSP_LVL2_AB, .skip_hashing = true }, { .type = AMD_FW_MPCCX, .subprog = 0, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_MPCCX, .subprog = 1, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_LSDMA, .level = PSP_LVL2 | PSP_LVL2_AB }, From 6b52f82df270bfce1ac99249f8fb8f7bdf11c597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Fri, 5 Dec 2025 11:03:57 +0100 Subject: [PATCH 110/789] util/amdfwtool: Remove AMD_FW_GFXIMU_2 entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AMD_FW_GFXIMU_2 entry has the same type value as AMD_FW_SRAM_FW_EXT. The tool may integrate one of these blobs incorrectly, because it searches for the first entry of given type in the amd_psp_fw_table. AMD_FW_GFXIMU_2 could have been added by mistake, because there is no board that actually defines PSP_GFX_IMMU_FILE_2 in fw.cfg file. Change-Id: I7e1f38c77156d06e9e6d801bdfa9b9eefcbb374e Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/90388 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- util/amdfwtool/amdfwtool.c | 1 - util/amdfwtool/amdfwtool.h | 1 - util/amdfwtool/data_parse.c | 4 ---- 3 files changed, 6 deletions(-) diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c index bac1c5bdbf..4184a60b74 100644 --- a/util/amdfwtool/amdfwtool.c +++ b/util/amdfwtool/amdfwtool.c @@ -266,7 +266,6 @@ amd_fw_entry amd_psp_fw_table[] = { { .type = AMD_FW_GFXIMU_0, .subprog = 1, .level = PSP_BOTH | PSP_LVL2_AB }, { .type = AMD_FW_GFXIMU_1, .subprog = 0, .level = PSP_BOTH | PSP_LVL2_AB }, { .type = AMD_FW_GFXIMU_1, .subprog = 1, .level = PSP_BOTH | PSP_LVL2_AB }, - { .type = AMD_FW_GFXIMU_2, .level = PSP_BOTH | PSP_LVL2_AB }, { .type = AMD_FW_SRAM_FW_EXT, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_UMSMU, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_S3IMG, .level = PSP_LVL2 | PSP_LVL2_AB }, diff --git a/util/amdfwtool/amdfwtool.h b/util/amdfwtool/amdfwtool.h index dbc1c4adc0..fe3f72b85d 100644 --- a/util/amdfwtool/amdfwtool.h +++ b/util/amdfwtool/amdfwtool.h @@ -118,7 +118,6 @@ typedef enum _amd_fw_type { AMD_FW_MINIMSMU = 0x9a, AMD_FW_GFXIMU_0 = 0x9b, AMD_FW_GFXIMU_1 = 0x9c, - AMD_FW_GFXIMU_2 = 0x9d, AMD_FW_SRAM_FW_EXT = 0x9d, AMD_FW_UMSMU = 0xa2, AMD_FW_S3IMG = 0xa0, diff --git a/util/amdfwtool/data_parse.c b/util/amdfwtool/data_parse.c index 13922d63c9..2ea37efd67 100644 --- a/util/amdfwtool/data_parse.c +++ b/util/amdfwtool/data_parse.c @@ -407,10 +407,6 @@ static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename, fw_type = AMD_FW_GFXIMU_1; instance = 0; subprog = 1; - } else if (strcmp(fw_name, "PSP_GFX_IMMU_FILE_2") == 0) { - fw_type = AMD_FW_GFXIMU_2; - instance = 0; - subprog = 0; } else if (strcmp(fw_name, "MINIMSMU_FILE_INS1") == 0) { fw_type = AMD_FW_MINIMSMU; instance = 1; From 7ed7abbd92b84c97461742eee888a261ba200140 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 24 Dec 2025 14:18:39 +0000 Subject: [PATCH 111/789] acpigen_ps2_keybd: map screenlock This is going to be used by some devices, map the next available extended code to it. Change-Id: Ib4fc6c33e10f273a73f3a6ca40deeefa3ab70f20 Signed-off-by: Fabio Baltieri Reviewed-on: https://review.coreboot.org/c/coreboot/+/90617 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/acpi/acpigen_ps2_keybd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/acpi/acpigen_ps2_keybd.c b/src/acpi/acpigen_ps2_keybd.c index f8b58d739b..38af89bfda 100644 --- a/src/acpi/acpigen_ps2_keybd.c +++ b/src/acpi/acpigen_ps2_keybd.c @@ -179,6 +179,8 @@ static uint32_t rest_of_keymaps[] = { KEYMAP(0x3a, KEY_CAPSLOCK), /* Insert Key */ KEYMAP(0xd2, KEY_INSERT), + /* Screen Lock */ + KEYMAP(0xab, KEY_SCREENLOCK), }; static void ssdt_generate_physmap(struct acpi_dp *dp, uint8_t num_top_row_keys, From ae48ff8c0b677a12b724540cc2ad2269a8df3b0c Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Fri, 12 Dec 2025 13:30:00 +0800 Subject: [PATCH 112/789] drivers/wwan/fm: Use _EVT method to enhance GPIO event handling Currently _Exx suppots the wake pin under 255, for Caboc it's wake pin is 325 which is out of range. This CL change to use _EVT method to enhance GPIO event handling. BUG=b:463410386 TEST=Compiled and tested on google/redrix and google/caboc: 1. emerge-brya coreboot, emerge-brox coreboot 2. Check /proc/interrupts has ACPI:Event 2. Wait for WWAN device to enter suspended state 3. Insert SIM card and modem is able to wake up WWAN device Change-Id: Ifbb83ab48bbe4876269010adb2710641bdc879a5 Signed-off-by: Tony Huang Reviewed-on: https://review.coreboot.org/c/coreboot/+/90492 Reviewed-by: Kevin Chiu Tested-by: build bot (Jenkins) --- src/drivers/wwan/fm/acpi_fm350gl.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/drivers/wwan/fm/acpi_fm350gl.c b/src/drivers/wwan/fm/acpi_fm350gl.c index 564ac03cfc..07054e33cb 100644 --- a/src/drivers/wwan/fm/acpi_fm350gl.c +++ b/src/drivers/wwan/fm/acpi_fm350gl.c @@ -285,18 +285,19 @@ wwan_fm350gl_acpi_event_method(const struct device *dev, if (CONFIG(GENERIC_GPIO_LIB)) pin = gpio_acpi_pin(pin); - if (pin > 0xff) { - printk(BIOS_ERR, "%s: pins above 0xFF are unsupported (pin %u)\n", - __func__, pin); - return; + if (pin <= 0xff) { + snprintf(name, sizeof(name), "_%c%02X", + wake_gpio->irq.mode == ACPI_IRQ_EDGE_TRIGGERED ? 'E' : 'L', pin); + acpigen_write_method_serialized(name, 0); + acpigen_notify(acpi_device_path(dev), 0x02); /* NOTIFY_DEVICE_WAKE */ + acpigen_write_method_end(); + } else { + acpigen_write_method_serialized("_EVT", 1); + acpigen_write_if_lequal_op_int(ARG0_OP, pin); + acpigen_notify(acpi_device_path(dev), 0x02); /* NOTIFY_DEVICE_WAKE */ + acpigen_pop_len(); + acpigen_write_method_end(); } - - snprintf(name, sizeof(name), "_%c%02X", - wake_gpio->irq.mode == ACPI_IRQ_EDGE_TRIGGERED ? 'E' : 'L', pin); - - acpigen_write_method_serialized(name, 0); - acpigen_notify(acpi_device_path(dev), 0x02); /* NOTIFY_DEVICE_WAKE */ - acpigen_write_method_end(); } static void wwan_fm350gl_acpi_gpio_events(const struct device *dev) From b7ad850fd6166e4caaec5415a409b75cb0c89622 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 6 Jan 2026 09:13:10 +0530 Subject: [PATCH 113/789] mb/google/bluey: Add percentage symbol to battery level log Update the battery state-of-charge print statement in romstage to include a percentage symbol. This makes the log output more readable and consistent with battery level reporting. Use '%%' to correctly escape and print the literal '%' sign in the printk statement. BUG=None TEST=Boot Bluey and verify romstage logs show "Battery state-of-charge 95%" instead of "Battery state-of-charge 95". Change-Id: I97b533567b56bfaba41508e35a6f324f0dbf331e Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90684 Reviewed-by: Kapil Porwal Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/romstage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index 06cd5626bd..1c6660112e 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -83,7 +83,7 @@ static void platform_dump_battery_soc_information(void) if (google_chromeec_read_batt_state_of_charge(&batt_pct)) printk(BIOS_WARNING, "Failed to get battery level\n"); else - printk(BIOS_INFO, "Battery state-of-charge %d\n", batt_pct); + printk(BIOS_INFO, "Battery state-of-charge %d%%\n", batt_pct); } void platform_romstage_main(void) From b00d2ad5c20b9f3234a33cef018320824749476d Mon Sep 17 00:00:00 2001 From: Sowmya V Date: Tue, 2 Dec 2025 14:05:46 +0530 Subject: [PATCH 114/789] vc/intel/fsp/fsp2_0/pantherlake: Update PTL FSP headers to FSP 3442.07 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Panther lake FSP headers from version 3373.03 to 3442.07 FspmUpd.h: Add below upds * Vdd2HVoltage * Vdd1Voltage * Vdd2LVoltage * VddqVoltage FspsUpd.h: Add below upds * UfsInlineEncryption * MaxActiveDisplays MemInfoHob.h: * FailingChannelMask - Limp Home mode failing channel bitmask BUG=b:463516609 TEST=Able to build google/fatcat with the latest header changes Change-Id: Ifd9d3476626f4028ea01eddef23b3b61f5e76d17 Signed-off-by: Sowmya V Reviewed-on: https://review.coreboot.org/c/coreboot/+/90332 Reviewed-by: Pranava Y N Reviewed-by: Jérémy Compostella Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- .../intel/fsp/fsp2_0/pantherlake/FspmUpd.h | 33 ++++++++++++++++--- .../intel/fsp/fsp2_0/pantherlake/FspsUpd.h | 22 ++++++++++--- .../intel/fsp/fsp2_0/pantherlake/MemInfoHob.h | 4 ++- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h index 5c26bcd685..ac166e6ccf 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h @@ -2463,12 +2463,12 @@ typedef struct { UINT8 DlvrRfiEnable; /** Offset 0x0949 - Pcore VR Hysteresis time window - Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. + 0 is default. Range of PcoreHysteresisWindow from 1ms to 50ms. **/ UINT8 PcoreHysteresisWindow; /** Offset 0x094A - Ecore VR Hysteresis time window - Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. + 0 is default. Range of EcoreHysteresisWindow from 1ms to 50ms. **/ UINT8 EcoreHysteresisWindow; @@ -2793,7 +2793,8 @@ typedef struct { Initialise SOL Init, BIT0 - (0 : Disable VGA Support, 1 : Enable VGA Support),, BIT1 - (0 : VGA Text Mode 3, 1 : VGA Graphics Mode 12), BIT2 - (0 : VGA Exit Supported, 1: NO VGA Exit), BIT3 - (0 : VGA Init During Display Init, 1 - VGA Init During - MRC Cold Boot), BIT4 - (0 : Enable Progress Bar, 1 : Disable Progress Bar) + MRC Cold Boot), BIT4 - (0 : Enable Progress Bar, 1 : Disable Progress Bar), BIT5 + - (0 : VGA Mode 12 16 Color Support, 1 : VGA Mode 12 Monochrome Black and White Support) 0:VGA Disable, 1:Mode 3 VGA, 2:Mode 12 VGA **/ UINT8 VgaInitControl; @@ -3121,7 +3122,31 @@ typedef struct { /** Offset 0x0B31 - Reserved **/ - UINT8 Reserved93[55]; + UINT8 Reserved93[17]; + +/** Offset 0x0B42 - VDD2 Voltage + Voltage is multiple of 5mV where 0 means Auto. +**/ + UINT16 Vdd2HVoltage; + +/** Offset 0x0B44 - VDD1 Voltage + Voltage is multiple of 5mV where 0 means Auto. +**/ + UINT16 Vdd1Voltage; + +/** Offset 0x0B46 - VDD2L Voltage Override + Voltage is multiple of 5mV where 0 means Auto. +**/ + UINT16 Vdd2LVoltage; + +/** Offset 0x0B48 - VDDQ Voltage Override + Voltage is multiple of 5mV where 0 means Auto. +**/ + UINT16 VddqVoltage; + +/** Offset 0x0B4A - Reserved +**/ + UINT8 Reserved94[30]; } FSP_M_CONFIG; /** Fsp M UPD Configuration diff --git a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h index b5194418b1..ae0ffe29dd 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h @@ -458,9 +458,17 @@ typedef struct { **/ UINT8 UfsEnable[2]; -/** Offset 0x014D - Reserved +/** Offset 0x014D - UFS Inline Encryption enable/disable + Enable/Disable UFS Inline Encryption feature, One byte for each Controller - (1,0) + to enable Inline Encryption for controller 0 and (0, 1) to enable Inline Encryption + for controller 1 + $EN_DIS +**/ + UINT8 UfsInlineEncryption[2]; + +/** Offset 0x014F - Reserved **/ - UINT8 Reserved12[4]; + UINT8 Reserved12[2]; /** Offset 0x0151 - Enable/Disable PCIe tunneling for USB4 Enable/Disable PCIe tunneling for USB4, default is enable @@ -2026,9 +2034,15 @@ typedef struct { **/ UINT8 LidStatus; -/** Offset 0x1401 - Reserved +/** Offset 0x1401 - Select MaxActiveDisplays + Max Active Display : 0 - Default VBT, 1 - 1 display, 2 - 2 displays, Maximum supported + is 2 displays only +**/ + UINT8 MaxActiveDisplays; + +/** Offset 0x1402 - Reserved **/ - UINT8 Reserved50[67]; + UINT8 Reserved50[66]; /** Offset 0x1444 - Address of PCH_DEVICE_INTERRUPT_CONFIG table. The address of the table of PCH_DEVICE_INTERRUPT_CONFIG. diff --git a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/MemInfoHob.h b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/MemInfoHob.h index c89cf2cab1..e50c114e41 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/MemInfoHob.h +++ b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/MemInfoHob.h @@ -312,7 +312,8 @@ typedef struct _PPR_RESULT_COLUMNS_HOB { - DIMM_INFO: Added SerialNumber, TotalWidth and DataWidth - DIMM_INFO: Removed SpdModuleMemoryBusWidth - MFG ID fields: use HOB_MANUFACTURER_ID_CODE instead of UINT16 for easier parsing - + Revision 4: + - Added FailingChannelMask **/ typedef struct { UINT8 Revision; @@ -363,6 +364,7 @@ typedef struct { UINT8 MaxRankCapacity; ///< Maximum possible rank capacity in [GB] UINT16 PprFailingChannelBitMask; ///< PPR failing channel mask BOOLEAN PprTargetedStatus[PPR_REQUEST_MAX]; ///< PPR status of each Targeted PPR request (0 = Targeted PPR was successful, 1 = PPR failed) + UINT8 FailingChannelMask; ///< Limp Home mode failing channel bitmask } MEMORY_INFO_DATA_HOB; /** From 7deb82d7444be2860e0e50b49dbb67986c459459 Mon Sep 17 00:00:00 2001 From: Kirubakaran E Date: Tue, 6 Jan 2026 20:54:08 -0800 Subject: [PATCH 115/789] mb/google/bluey: Configure QUPV3_0_SE3 and QUPV3_0_SE7 for USB-C0 and USB-C1 Retimer I2C access Load I2C firmware to QUPV3_0_SE3 and QUPV3_0_SE7 Serial Engines and configure both in MIXED mode to enable I2C access for USB-C0 and USB-C1 retimers. Test= 1. Created image.serial.bin and verified successful boot on X1P42100. 2. Read the corresponding QUP SE firmware revision read-only register and confirmed that the protocol field (bits 8-15) matches the programmed value. Register details are in HRD-X1P42100-S1 documentation: https://docs.qualcomm.com/bundle/resource/topics/HRD-X1P42100-S1/ Example:If programmed as I2C, the register value read is 0x00000303, where 3 denotes the I2C protocol. Change-Id: I337329628ac04246ab579e062a802a028cb4c560 Signed-off-by: Kirubakaran E Reviewed-on: https://review.coreboot.org/c/coreboot/+/90690 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/mainboard.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 9f958a1862..b93b4188db 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -122,6 +122,12 @@ static void mainboard_init(struct device *dev) /* ADSP I2C (Charger/Fuel gauge) */ qupv3_se_fw_load_and_init(QUPV3_2_SE4, SE_PROTOCOL_I2C, GSI); + /* USB-C0 Re-Timer I2C */ + qupv3_se_fw_load_and_init(QUPV3_0_SE3, SE_PROTOCOL_I2C, MIXED); + + /* USB-C1 Re-Timer I2C */ + qupv3_se_fw_load_and_init(QUPV3_0_SE7, SE_PROTOCOL_I2C, MIXED); + if (!CONFIG(MAINBOARD_NO_USB_A_PORT)) qupv3_se_fw_load_and_init(QUPV3_0_SE1, SE_PROTOCOL_I2C, MIXED); /* USB-A retimer */ qupv3_se_fw_load_and_init(QUPV3_0_SE5, SE_PROTOCOL_I2C, MIXED); /* eUSB repeater */ From 1da7c31810638eb300017a61781f00f7ceef540a Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Fri, 28 Nov 2025 15:31:28 +0100 Subject: [PATCH 116/789] include/cpu/x86/msr.h: Add MCA related MSRs They are needed in a later patch which is not yet upstream. source: AMD64 Architecture Programmers Manual Rev 3.42 Change-Id: I4f5bb5533d8f0e1765749d24ef0b22805ad1554a Signed-off-by: Maximilian Brune Reviewed-on: https://review.coreboot.org/c/coreboot/+/90480 Reviewed-by: Felix Held Tested-by: build bot (Jenkins) --- src/include/cpu/x86/msr.h | 15 +++++++++++++++ src/security/intel/txt/txt_register.h | 4 +--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/include/cpu/x86/msr.h b/src/include/cpu/x86/msr.h index a5226fb0b6..2fdb064608 100644 --- a/src/include/cpu/x86/msr.h +++ b/src/include/cpu/x86/msr.h @@ -40,9 +40,12 @@ #define IA32_SMM_MONITOR_CTL_MSR 0x9B #define SMBASE_RO_MSR 0x98 #define IA32_SMM_MONITOR_VALID (1 << 0) +#define IA32_SYSENTER_EIP 0x176 #define IA32_MCG_CAP 0x179 #define MCG_CTL_P (1 << 8) #define MCA_BANKS_MASK 0xff +#define IA32_MCG_STATUS 0x17A +#define MCG_STAT_EIPV (1 << 1) #define IA32_PERF_STATUS 0x198 #define IA32_PERF_CTL 0x199 #define IA32_THERM_INTERRUPT 0x19b @@ -74,6 +77,8 @@ #define MCA_STATUS_HI_ADDRV (1UL << (58 - 32)) #define MCA_STATUS_HI_PCC (1UL << (57 - 32)) #define MCA_STATUS_HI_COREID_VAL (1UL << (56 - 32)) +#define MCA_STATUS_HI_TCC (1UL << (55 - 32)) +#define MCA_STATUS_HI_SYNDV (1UL << (53 - 32)) #define MCA_STATUS_HI_CECC (1UL << (46 - 32)) #define MCA_STATUS_HI_UECC (1UL << (45 - 32)) #define MCA_STATUS_HI_DEFERRED (1UL << (44 - 32)) @@ -172,6 +177,16 @@ static inline int mca_pcc(msr_t msr) return !!(msr.hi & MCA_STATUS_HI_PCC); } +static inline int mca_tcc(msr_t msr) +{ + return !!(msr.hi & MCA_STATUS_HI_TCC); +} + +static inline int mca_syndv(msr_t msr) +{ + return !!(msr.hi & MCA_STATUS_HI_SYNDV); +} + static inline int mca_idv(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_COREID_VAL); diff --git a/src/security/intel/txt/txt_register.h b/src/security/intel/txt/txt_register.h index a00084511f..588fef1387 100644 --- a/src/security/intel/txt/txt_register.h +++ b/src/security/intel/txt/txt_register.h @@ -3,6 +3,7 @@ #ifndef SECURITY_INTEL_TXT_REGISTER_H_ #define SECURITY_INTEL_TXT_REGISTER_H_ +#include #include /* @@ -162,9 +163,6 @@ #define ACM_FORMAT_SIZE_128KB (128 * KiB / 4) #define ACM_FORMAT_SIZE_256KB (256 * KiB / 4) -/* MSRs */ -#define IA32_MCG_STATUS 0x17a - /* DPR register layout, either in PCI config space or TXT MMIO space */ union dpr_register { struct { From 3ded43722ac626cd15927cabdcb5db78f313628d Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Fri, 28 Nov 2025 16:33:10 +0100 Subject: [PATCH 117/789] soc/amd/cmn/block/acpi/ivrs: Use less PCI accesses Refactor code to use less redundant PCI accesses to decrease boot time. Change-Id: Ic2bb610ebf22dd43580ac94360d905b1c782224a Signed-off-by: Maximilian Brune Reviewed-on: https://review.coreboot.org/c/coreboot/+/90641 Reviewed-by: Felix Held Tested-by: build bot (Jenkins) --- src/soc/amd/common/block/acpi/ivrs.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/soc/amd/common/block/acpi/ivrs.c b/src/soc/amd/common/block/acpi/ivrs.c index 2301158a0a..48c3965926 100644 --- a/src/soc/amd/common/block/acpi/ivrs.c +++ b/src/soc/amd/common/block/acpi/ivrs.c @@ -305,6 +305,7 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) uint64_t mmio_x18_value; uint64_t mmio_x4000_value; uint32_t cap_offset_0; + uint32_t cap_offset_c; uint32_t cap_offset_10; struct acpi_ivrs_ivhd *ivhd; struct device *iommu_dev; @@ -342,6 +343,8 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) ivhd->iommu_base_high = pci_read_config32(iommu_dev, IOMMU_CAP_BASE_HI); cap_offset_0 = pci_read_config32(iommu_dev, ivhd->capability_offset); + cap_offset_c = pci_read_config32(iommu_dev, + ivhd->capability_offset + 0xC); cap_offset_10 = pci_read_config32(iommu_dev, ivhd->capability_offset + 0x10); mmio_x18_value = read64p(ivhd->iommu_base_low + 0x18); @@ -367,10 +370,8 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) ivhd->pci_segment_group = nb_dev->upstream->segment_group; - ivhd->iommu_info = pci_read_config16(iommu_dev, - ivhd->capability_offset + 0x10) & 0x1F; - ivhd->iommu_info |= (pci_read_config16(iommu_dev, - ivhd->capability_offset + 0xC) & 0x1F) << IOMMU_INFO_UNIT_ID_SHIFT; + ivhd->iommu_info = cap_offset_10 & 0x1F; + ivhd->iommu_info |= (cap_offset_c & 0x1F) << IOMMU_INFO_UNIT_ID_SHIFT; ivhd->iommu_feature_info = 0; ivhd->iommu_feature_info |= (mmio_x30_value & MMIO_EXT_FEATURE_HATS_MASK) @@ -409,10 +410,8 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) ? IOMMU_FEATURE_XT_SUP : 0); /* Enable EFR if supported */ - ivrs->iv_info = pci_read_config32(iommu_dev, - ivhd->capability_offset + 0x10) & 0x007fffe0; - if (pci_read_config32(iommu_dev, - ivhd->capability_offset) & EFR_FEATURE_SUP) + ivrs->iv_info = cap_offset_10 & 0x007fffe0; + if (cap_offset_0 & EFR_FEATURE_SUP) ivrs->iv_info |= IVINFO_EFR_SUPPORTED; From c7f0697867eced9928fce3065568a267a1412b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 6 Oct 2025 11:53:10 +0200 Subject: [PATCH 118/789] coreboot_tables: Add new CBMEM ID to hold the PCI RB aperture info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On AMD server systems there are multiple PCI root bridges. The root bridge scanning in UEFI Payload is not sufficient to detect the memory and I/O apertures properly. For example on Turin system, the I/O aperture on the first root bridge containing the FCH may not have any I/O resources detected on the PCI devices. This results in the I/O decoding to be disabled on the root bridge, effectively breaking the I/O based serial ports, e.g. on Super I/Os and BMCs. Add new CBMEM ID to report the PCI root bridge aperture information to the payload. The intention is to use the Universal Payload PCI Root Bridges Info HOB that is already supported in the UEFI Payload. The HOB will take priority over the root bridge scanning and properly report the apertures of the PCI root bridges on AMD system. Change-Id: If7f7dc6710f389884adfd292bc5ce77e0c37766f Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/89486 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h | 4 +++- src/commonlib/include/commonlib/coreboot_tables.h | 1 + src/lib/coreboot_table.c | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h index 20a1099f0a..a5cb0a7f8a 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h +++ b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h @@ -92,6 +92,7 @@ #define CBMEM_ID_AMD_OPENSIL 0x4153494C #define CBMEM_ID_PVMFW 0x666d7670 #define CBMEM_ID_BOOT_MODE 0x444D5442 +#define CBMEM_ID_RB_INFO 0x50524249 #define CBMEM_ID_TO_NAME_TABLE \ { CBMEM_ID_ACPI, "ACPI " }, \ @@ -176,5 +177,6 @@ { CBMEM_ID_CSE_BP_INFO, "CSE BP INFO"}, \ { CBMEM_ID_AMD_OPENSIL, "OPENSIL DATA"}, \ { CBMEM_ID_PVMFW, "PVMFW "}, \ - { CBMEM_ID_BOOT_MODE, "BOOT MODE "} + { CBMEM_ID_BOOT_MODE, "BOOT MODE "}, \ + { CBMEM_ID_RB_INFO, "PCI RB INFO"} #endif /* _CBMEM_ID_H_ */ diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index 817ca0e4f2..fcc7761044 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -90,6 +90,7 @@ enum { LB_TAG_EFI_FW_INFO = 0x0045, LB_TAG_CAPSULE = 0x0046, LB_TAG_CFR_ROOT = 0x0047, + LB_TAG_ROOT_BRIDGE_INFO = 0x0048, /* The following options are CMOS-related */ LB_TAG_CMOS_OPTION_TABLE = 0x00c8, LB_TAG_OPTION = 0x00c9, diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index d8ecdce868..85c5675507 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -274,6 +274,7 @@ static void add_cbmem_pointers(struct lb_header *header) {CBMEM_ID_FMAP, LB_TAG_FMAP}, {CBMEM_ID_VBOOT_WORKBUF, LB_TAG_VBOOT_WORKBUF}, {CBMEM_ID_TYPE_C_INFO, LB_TAG_TYPE_C_INFO}, + {CBMEM_ID_RB_INFO, LB_TAG_ROOT_BRIDGE_INFO}, }; int i; From f4fe5514fed2da762958396285670aee66e9769e Mon Sep 17 00:00:00 2001 From: Ian Feng Date: Thu, 8 Jan 2026 10:44:53 +0800 Subject: [PATCH 119/789] mb/google/ocelot/var/kodkod: Update gpio settings for NC pins - Remove unused I2C3 pin configurations. - Remove RST control. The ETU925 fingerprint module does not need to control the RST pin. BUG=b:452542491, b:467835297 TEST=emerge-ocelot coreboot Change-Id: Ib4db733187d1b15f89654b53c1cf98420d652546 Signed-off-by: Ian Feng Reviewed-on: https://review.coreboot.org/c/coreboot/+/90696 Reviewed-by: Pranava Y N Tested-by: build bot (Jenkins) Reviewed-by: Dtrain Hsu --- .../google/ocelot/variants/kodkod/gpio.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/mainboard/google/ocelot/variants/kodkod/gpio.c b/src/mainboard/google/ocelot/variants/kodkod/gpio.c index e8884d9c43..2259bda8c7 100644 --- a/src/mainboard/google/ocelot/variants/kodkod/gpio.c +++ b/src/mainboard/google/ocelot/variants/kodkod/gpio.c @@ -125,8 +125,8 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_C13, NONE), /* GPP_C14: NC */ PAD_NC(GPP_C14, NONE), - /* GPP_C15: SOC_FPS_RST# */ - PAD_CFG_GPO_LOCK(GPP_C15, 1, LOCK_CONFIG), + /* GPP_C15: NC */ + PAD_NC(GPP_C15, NONE), /* GPP_C16: NC */ PAD_NC(GPP_C16, NONE), /* GPP_C17: NC */ @@ -279,10 +279,10 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_H04, NONE), /* GPP_H05: NC */ PAD_NC(GPP_H05, NONE), - /* GPP_H06: SOC_I2C_3_SDA_iPCM */ - PAD_CFG_NF(GPP_H06, NONE, DEEP, NF1), - /* GPP_H07: SOC_I2C_3_SCL_iPCM */ - PAD_CFG_NF(GPP_H07, NONE, DEEP, NF1), + /* GPP_H06: NC */ + PAD_NC(GPP_H06, NONE), + /* GPP_H07: NC */ + PAD_NC(GPP_H07, NONE), /* GPP_H08: UART_0_CRXD_DTXD */ PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), /* GPP_H09: UART_0_CTXD_DRXD */ @@ -372,10 +372,6 @@ static const struct pad_config gpio_table[] = { static const struct pad_config early_gpio_table[] = { /* GPP_B17: SOC_SPI_TPM_INT# */ PAD_CFG_GPI_APIC_LOCK(GPP_B17, NONE, LEVEL, INVERT, LOCK_CONFIG), - /* GPP_H06: SOC_I2C_3_SDA_iPCM */ - PAD_CFG_NF(GPP_H06, NONE, DEEP, NF1), - /* GPP_H07: SOC_I2C_3_SCL_iPCM */ - PAD_CFG_NF(GPP_H07, NONE, DEEP, NF1), /* GPP_H08: UART_0_CRXD_DTXD */ PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), /* GPP_H09: UART_0_CTXD_DRXD */ @@ -392,8 +388,6 @@ static const struct pad_config romstage_gpio_table[] = { PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), /* GPP_C01: SPD_SOC_SMBDATA */ PAD_CFG_NF(GPP_C01, NONE, DEEP, NF1), - /* GPP_C15: FPS_RST_N */ - PAD_CFG_GPO(GPP_C15, 0, PLTRST), }; const struct pad_config *variant_gpio_table(size_t *num) From 829b8be43202b960d5be066cbd8c6ba25552a1d0 Mon Sep 17 00:00:00 2001 From: Tomasz Michalec Date: Thu, 13 Nov 2025 16:07:19 +0100 Subject: [PATCH 120/789] libpayload: Add bulk with timeout callback to USB Add bulk_timeout() callback to USB controllers that allows to issue bulk transaction with configurable timeout. This allows to peek if there is any incoming data from USB device without needing to wait 5 seconds if there is no data. 'finalize' argument is omitted in bulk_timeout(), because any recent controller doesn't use it in bulk() method anyway. For OHCI and UHCI, which are only controllers using 'finalize', issuing bulk_timeout() with USB_MAX_PROCESSING_TIME_US timeout is the same as issuing bulk() with 'finalize' set to zero. Change-Id: I82dbe307b566e4fc6cca314924168f7ad677efe7 Signed-off-by: Tomasz Michalec Reviewed-on: https://review.coreboot.org/c/coreboot/+/90043 Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel --- payloads/libpayload/drivers/usb/dwc2.c | 49 ++++++++++++------- .../libpayload/drivers/usb/dwc2_private.h | 1 - payloads/libpayload/drivers/usb/ehci.c | 26 ++++++---- payloads/libpayload/drivers/usb/ohci.c | 28 ++++++++--- payloads/libpayload/drivers/usb/uhci.c | 40 ++++++++++----- payloads/libpayload/drivers/usb/xhci.c | 24 +++++---- .../libpayload/drivers/usb/xhci_commands.c | 2 +- payloads/libpayload/drivers/usb/xhci_events.c | 15 +++--- .../libpayload/drivers/usb/xhci_private.h | 6 +-- payloads/libpayload/include/usb/usb.h | 10 ++++ 10 files changed, 134 insertions(+), 67 deletions(-) diff --git a/payloads/libpayload/drivers/usb/dwc2.c b/payloads/libpayload/drivers/usb/dwc2.c index e0b290f58c..5d9bd4cb59 100644 --- a/payloads/libpayload/drivers/usb/dwc2.c +++ b/payloads/libpayload/drivers/usb/dwc2.c @@ -152,13 +152,13 @@ static int dwc2_disconnected(hci_t *controller) * or an error code if the transfer failed */ static int -wait_for_complete(endpoint_t *ep, uint32_t ch_num) +wait_for_complete(endpoint_t *ep, uint32_t ch_num, int timeout_us) { hcint_t hcint; hcchar_t hcchar; hctsiz_t hctsiz; dwc2_reg_t *reg = DWC2_REG(ep->dev->controller); - int timeout = USB_MAX_PROCESSING_TIME_US / DWC2_SLEEP_TIME_US; + int timeout = timeout_us / DWC2_SLEEP_TIME_US; /* * TODO: We should take care of up to three times of transfer error @@ -211,12 +211,12 @@ wait_for_complete(endpoint_t *ep, uint32_t ch_num) hcint.d32 = ~0; writel(hcint.d32, ®->host.hchn[ch_num].hcintn); - return -HCSTAT_TIMEOUT; + return USB_TIMEOUT; } static int dwc2_do_xfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, - uint32_t ch_num, u8 *data_buf, int *short_pkt) + uint32_t ch_num, u8 *data_buf, int *short_pkt, int timeout_us) { uint32_t do_copy; int ret; @@ -279,7 +279,7 @@ dwc2_do_xfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, ®->host.hchn[ch_num].hcdman); writel(hcchar.d32, ®->host.hchn[ch_num].hccharn); - ret = wait_for_complete(ep, ch_num); + ret = wait_for_complete(ep, ch_num, timeout_us); if (ret >= 0) { /* Calculate actual transferred length */ @@ -307,7 +307,7 @@ dwc2_do_xfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, static int dwc2_split_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, u8 *data_buf, split_info_t *split, - int *short_pkt) + int *short_pkt, int timeout_us) { dwc2_reg_t *reg = DWC2_REG(ep->dev->controller); hfnum_t hfnum; @@ -331,7 +331,7 @@ dwc2_split_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, /* Handle Start-Split */ ret = dwc2_do_xfer(ep, dir == EPDIR_IN ? 0 : size, pid, dir, ch_num, - data_buf, NULL); + data_buf, NULL, timeout_us); if (ret < 0) goto out; @@ -346,7 +346,7 @@ dwc2_split_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, /* Handle Complete-Split */ do { ret = dwc2_do_xfer(ep, dir == EPDIR_OUT ? 0 : size, ep->toggle, - dir, ch_num, data_buf, short_pkt); + dir, ch_num, data_buf, short_pkt, timeout_us); } while (ret == -HCSTAT_NYET); if (dir == EPDIR_IN) @@ -379,11 +379,11 @@ static int dwc2_need_split(usbdev_t *dev, split_info_t *split) static int dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, - u8 *src, uint8_t skip_nak) + u8 *src, uint8_t skip_nak, int timeout_us) { split_info_t split; int ret, short_pkt, transferred = 0; - int timeout = USB_MAX_PROCESSING_TIME_US / USB_FULL_LOW_SPEED_FRAME_US; + int timeout = timeout_us / USB_FULL_LOW_SPEED_FRAME_US; ep->toggle = pid; @@ -393,7 +393,7 @@ dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, nak_retry: ret = dwc2_split_transfer(ep, MIN(ep->maxpacketsize, size), ep->toggle, dir, 0, src, &split, - &short_pkt); + &short_pkt, timeout_us); /* * dwc2_split_transfer() waits for the next FullSpeed @@ -403,10 +403,12 @@ dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, if (ret == -HCSTAT_NAK && !skip_nak && --timeout) { udelay(USB_FULL_LOW_SPEED_FRAME_US / 2); goto nak_retry; + } else if (timeout <= 0 && ret < 0) { + return USB_TIMEOUT; } } else { ret = dwc2_do_xfer(ep, MIN(DMA_SIZE, size), pid, dir, 0, - src, &short_pkt); + src, &short_pkt, timeout_us); } if (ret < 0) @@ -422,7 +424,7 @@ dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, } static int -dwc2_bulk(endpoint_t *ep, int size, u8 *src, int finalize) +dwc2_bulk_timeout(endpoint_t *ep, int size, u8 *src, int timeout_us) { ep_dir_t data_dir; @@ -433,7 +435,13 @@ dwc2_bulk(endpoint_t *ep, int size, u8 *src, int finalize) else return -1; - return dwc2_transfer(ep, size, ep->toggle, data_dir, 0, src, 0); + return dwc2_transfer(ep, size, ep->toggle, data_dir, 0, src, 0, timeout_us); +} + +static int +dwc2_bulk(endpoint_t *ep, int size, u8 *src, int finalize) +{ + return dwc2_bulk_timeout(ep, size, src, USB_MAX_PROCESSING_TIME_US); } static int @@ -452,19 +460,22 @@ dwc2_control(usbdev_t *dev, direction_t dir, int drlen, void *setup, return -1; /* Setup Phase */ - if (dwc2_transfer(ep, drlen, PID_SETUP, EPDIR_OUT, 0, setup, 0) < 0) + if (dwc2_transfer(ep, drlen, PID_SETUP, EPDIR_OUT, 0, setup, 0, + USB_MAX_PROCESSING_TIME_US) < 0) return -1; /* Data Phase */ ep->toggle = PID_DATA1; if (dalen > 0) { - ret = dwc2_transfer(ep, dalen, ep->toggle, data_dir, 0, src, 0); + ret = dwc2_transfer(ep, dalen, ep->toggle, data_dir, 0, src, 0, + USB_MAX_PROCESSING_TIME_US); if (ret < 0) return -1; } /* Status Phase */ - if (dwc2_transfer(ep, 0, PID_DATA1, !data_dir, 0, NULL, 0) < 0) + if (dwc2_transfer(ep, 0, PID_DATA1, !data_dir, 0, NULL, 0, + USB_MAX_PROCESSING_TIME_US) < 0) return -1; return ret; @@ -482,7 +493,8 @@ dwc2_intr(endpoint_t *ep, int size, u8 *src) else return -1; - return dwc2_transfer(ep, size, ep->toggle, data_dir, 0, src, 1); + return dwc2_transfer(ep, size, ep->toggle, data_dir, 0, src, 1, + USB_MAX_PROCESSING_TIME_US); } static u32 dwc2_intr_get_timestamp(intr_queue_t *q) @@ -583,6 +595,7 @@ hci_t *dwc2_init(void *bar) controller->init = dwc2_reinit; controller->shutdown = dwc2_shutdown; controller->bulk = dwc2_bulk; + controller->bulk_timeout = dwc2_bulk_timeout; controller->control = dwc2_control; controller->set_address = generic_set_address; controller->finish_device_config = NULL; diff --git a/payloads/libpayload/drivers/usb/dwc2_private.h b/payloads/libpayload/drivers/usb/dwc2_private.h index 3616ff3d10..86c9da2fa8 100644 --- a/payloads/libpayload/drivers/usb/dwc2_private.h +++ b/payloads/libpayload/drivers/usb/dwc2_private.h @@ -48,7 +48,6 @@ typedef enum { HCSTAT_NAK, HCSTAT_NYET, HCSTAT_UNKNOW, - HCSTAT_TIMEOUT, HCSTAT_DISCONNECTED, } hcstat_t; #endif diff --git a/payloads/libpayload/drivers/usb/ehci.c b/payloads/libpayload/drivers/usb/ehci.c index 822fdb19a9..fe3186d5ca 100644 --- a/payloads/libpayload/drivers/usb/ehci.c +++ b/payloads/libpayload/drivers/usb/ehci.c @@ -249,23 +249,25 @@ static void free_qh_and_tds(ehci_qh_t *qh, qtd_t *cur) #define EHCI_SLEEP_TIME_US 50 -static int wait_for_tds(qtd_t *head) +static int wait_for_tds(qtd_t *head, int timeout_us) { - /* returns the amount of bytes *not* transmitted, or -1 for error */ + /* returns the amount of bytes *not* transmitted, USB_TIMEOUT on timeout, + * or -1 for error + */ int result = 0; qtd_t *cur = head; while (1) { if (0) dump_td(virt_to_phys(cur)); /* wait for results */ - int timeout = USB_MAX_PROCESSING_TIME_US / EHCI_SLEEP_TIME_US; + int timeout = timeout_us / EHCI_SLEEP_TIME_US; while ((cur->token & QTD_ACTIVE) && !(cur->token & QTD_HALTED) && timeout--) udelay(EHCI_SLEEP_TIME_US); if (timeout < 0) { usb_debug("Error: ehci: queue transfer " "processing timed out.\n"); - return -1; + return USB_TIMEOUT; } if (cur->token & QTD_HALTED) { usb_debug("ERROR with packet\n"); @@ -319,7 +321,7 @@ static int ehci_set_async_schedule(ehci_t *ehcic, int enable) } static int ehci_process_async_schedule( - ehci_t *ehcic, ehci_qh_t *qhead, qtd_t *head) + ehci_t *ehcic, ehci_qh_t *qhead, qtd_t *head, int timeout_us) { int result; @@ -333,7 +335,7 @@ static int ehci_process_async_schedule( if (ehci_set_async_schedule(ehcic, 1)) return -1; /* wait for result */ - result = wait_for_tds(head); + result = wait_for_tds(head, timeout_us); /* disable async schedule */ ehci_set_async_schedule(ehcic, 0); @@ -341,7 +343,7 @@ static int ehci_process_async_schedule( return result; } -static int ehci_bulk(endpoint_t *ep, int size, u8 *src, int finalize) +static int ehci_bulk_timeout(endpoint_t *ep, int size, u8 *src, int timeout_us) { int result = 0; u8 *end = src + size; @@ -410,7 +412,7 @@ static int ehci_bulk(endpoint_t *ep, int size, u8 *src, int finalize) head->token |= (ep->toggle?QTD_TOGGLE_DATA1:0); result = ehci_process_async_schedule( - EHCI_INST(ep->dev->controller), qh, head); + EHCI_INST(ep->dev->controller), qh, head, timeout_us); if (result >= 0) { result = size - result; if (pid == EHCI_IN && end != src + size) @@ -429,6 +431,11 @@ static int ehci_bulk(endpoint_t *ep, int size, u8 *src, int finalize) return -1; } +static int ehci_bulk(endpoint_t *ep, int size, u8 *src, int finalize) +{ + return ehci_bulk_timeout(ep, size, src, USB_MAX_PROCESSING_TIME_US); +} + /* FIXME: Handle control transfers as 3 QHs, so the 2nd stage can be >0x4000 bytes */ static int ehci_control(usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen, u8 *src) @@ -530,7 +537,7 @@ static int ehci_control(usbdev_t *dev, direction_t dir, int drlen, void *setup, qh->td.next_qtd = virt_to_phys(head); result = ehci_process_async_schedule( - EHCI_INST(dev->controller), qh, head); + EHCI_INST(dev->controller), qh, head, USB_MAX_PROCESSING_TIME_US); if (result >= 0) { result = dalen - result; if (dir == IN && data != src) @@ -784,6 +791,7 @@ ehci_init(unsigned long physical_bar) controller->init = ehci_reinit; controller->shutdown = ehci_shutdown; controller->bulk = ehci_bulk; + controller->bulk_timeout = ehci_bulk_timeout; controller->control = ehci_control; controller->set_address = generic_set_address; controller->finish_device_config = NULL; diff --git a/payloads/libpayload/drivers/usb/ohci.c b/payloads/libpayload/drivers/usb/ohci.c index 79add33fe7..55bdf66826 100644 --- a/payloads/libpayload/drivers/usb/ohci.c +++ b/payloads/libpayload/drivers/usb/ohci.c @@ -39,6 +39,7 @@ static void ohci_stop(hci_t *controller); static void ohci_reset(hci_t *controller); static void ohci_shutdown(hci_t *controller); static int ohci_bulk(endpoint_t *ep, int size, u8 *data, int finalize); +static int ohci_bulk_timeout(endpoint_t *ep, int size, u8 *data, int timeout_us); static int ohci_control(usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen, u8 *data); static void* ohci_create_intr_queue(endpoint_t *ep, int reqsize, int reqcount, int reqtiming); @@ -181,6 +182,7 @@ ohci_init(unsigned long physical_bar) controller->init = ohci_reinit; controller->shutdown = ohci_shutdown; controller->bulk = ohci_bulk; + controller->bulk_timeout = ohci_bulk_timeout; controller->control = ohci_control; controller->set_address = generic_set_address; controller->finish_device_config = NULL; @@ -295,10 +297,10 @@ ohci_stop(hci_t *controller) #define OHCI_SLEEP_TIME_US 1000 static int -wait_for_ed(usbdev_t *dev, ed_t *head, int pages) +wait_for_ed(usbdev_t *dev, ed_t *head, int pages, int timeout_us) { /* wait for results */ - int timeout = USB_MAX_PROCESSING_TIME_US / OHCI_SLEEP_TIME_US; + int timeout = timeout_us / OHCI_SLEEP_TIME_US; while (((head->head_pointer & ~3) != head->tail_pointer) && !(head->head_pointer & 1) && ((((td_t*)phys_to_virt(head->head_pointer & ~3))->config @@ -326,7 +328,7 @@ wait_for_ed(usbdev_t *dev, ed_t *head, int pages) usb_debug("HALTED!\n"); return -1; } - return result; + return timeout <= 0 ? USB_TIMEOUT : result; } static void @@ -481,7 +483,8 @@ ohci_control(usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen, OHCI_INST(dev->controller)->opreg->HcCommandStatus = ControlListFilled; int result = wait_for_ed(dev, head, - (dalen == 0)?0:(last_page - first_page + 1)); + (dalen == 0)?0:(last_page - first_page + 1), + USB_MAX_PROCESSING_TIME_US); /* Wait some frames before and one after disabling list access. */ mdelay(4); OHCI_INST(dev->controller)->opreg->HcControl &= ~ControlListEnable; @@ -501,7 +504,7 @@ ohci_control(usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen, /* finalize == 1: if data is of packet aligned size, add a zero length packet */ static int -ohci_bulk(endpoint_t *ep, int dalen, u8 *src, int finalize) +ohci_bulk_finalize_timeout(endpoint_t *ep, int dalen, u8 *src, int finalize, int timeout_us) { int i; td_t *cur, *next; @@ -608,7 +611,7 @@ ohci_bulk(endpoint_t *ep, int dalen, u8 *src, int finalize) OHCI_INST(ep->dev->controller)->opreg->HcCommandStatus = BulkListFilled; int result = wait_for_ed(ep->dev, head, - (dalen == 0)?0:(last_page - first_page + 1)); + (dalen == 0)?0:(last_page - first_page + 1), timeout_us); /* Wait some frames before and one after disabling list access. */ mdelay(4); OHCI_INST(ep->dev->controller)->opreg->HcControl &= ~BulkListEnable; @@ -628,6 +631,19 @@ ohci_bulk(endpoint_t *ep, int dalen, u8 *src, int finalize) return result; } +static int +ohci_bulk_timeout(endpoint_t *ep, int dalen, u8 *src, int timeout_us) +{ + /* usbdev_hc bulk_timeout API doesn't have finalize argument. Assume it should be 0. */ + return ohci_bulk_finalize_timeout(ep, dalen, src, 0, timeout_us); +} + +static int +ohci_bulk(endpoint_t *ep, int dalen, u8 *src, int finalize) +{ + return ohci_bulk_finalize_timeout(ep, dalen, src, finalize, USB_MAX_PROCESSING_TIME_US); +} + struct _intr_queue; struct _intrq_td { diff --git a/payloads/libpayload/drivers/usb/uhci.c b/payloads/libpayload/drivers/usb/uhci.c index 7590ab3c85..53fb123c8c 100644 --- a/payloads/libpayload/drivers/usb/uhci.c +++ b/payloads/libpayload/drivers/usb/uhci.c @@ -39,6 +39,7 @@ static void uhci_stop(hci_t *controller); static void uhci_reset(hci_t *controller); static void uhci_shutdown(hci_t *controller); static int uhci_bulk(endpoint_t *ep, int size, u8 *data, int finalize); +static int uhci_bulk_timeout(endpoint_t *ep, int size, u8 *data, int timeout_us); static int uhci_control(usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen, u8 *data); static void* uhci_create_intr_queue(endpoint_t *ep, int reqsize, int reqcount, int reqtiming); @@ -162,6 +163,7 @@ uhci_pci_init(pcidev_t addr) controller->init = uhci_reinit; controller->shutdown = uhci_shutdown; controller->bulk = uhci_bulk; + controller->bulk_timeout = uhci_bulk_timeout; controller->control = uhci_control; controller->set_address = generic_set_address; controller->finish_device_config = NULL; @@ -273,23 +275,23 @@ uhci_stop(hci_t *controller) } #define UHCI_SLEEP_TIME_US 30 -#define UHCI_TIMEOUT (USB_MAX_PROCESSING_TIME_US / UHCI_SLEEP_TIME_US) #define GET_TD(x) ((void *)(((unsigned long)(x))&~0xf)) static td_t * -wait_for_completed_qh(hci_t *controller, qh_t *qh) +wait_for_completed_qh(hci_t *controller, qh_t *qh, int *timeout_us) { - int timeout = UHCI_TIMEOUT; + int timeout = *timeout_us / UHCI_SLEEP_TIME_US; void *current = GET_TD(qh->elementlinkptr); while (((qh->elementlinkptr & FLISTP_TERMINATE) == 0) && (timeout-- > 0)) { if (current != GET_TD(qh->elementlinkptr)) { current = GET_TD(qh->elementlinkptr); - timeout = UHCI_TIMEOUT; + timeout = *timeout_us / UHCI_SLEEP_TIME_US; } uhci_reg_write16(controller, USBSTS, uhci_reg_read16(controller, USBSTS) | 0); // clear resettable registers udelay(UHCI_SLEEP_TIME_US); } + *timeout_us = timeout * UHCI_SLEEP_TIME_US; return (GET_TD(qh->elementlinkptr) == 0) ? 0 : GET_TD(phys_to_virt(qh->elementlinkptr)); } @@ -370,9 +372,10 @@ uhci_control(usbdev_t *dev, direction_t dir, int drlen, void *devreq, const int TD_STATUS_ACTIVE; UHCI_INST(dev->controller)->qh_data->elementlinkptr = virt_to_phys(tds) & ~(FLISTP_QH | FLISTP_TERMINATE); + int timeout_us = USB_MAX_PROCESSING_TIME_US; td_t *td = wait_for_completed_qh(dev->controller, UHCI_INST(dev->controller)-> - qh_data); + qh_data, &timeout_us); int result; if (td == 0) { result = dalen; /* TODO: We should return the actually transferred length. */ @@ -423,23 +426,24 @@ fill_schedule(td_t *td, endpoint_t *ep, int length, unsigned char *data, } static int -run_schedule(usbdev_t *dev, td_t *td) +run_schedule(usbdev_t *dev, td_t *td, int timeout_us) { UHCI_INST(dev->controller)->qh_data->elementlinkptr = virt_to_phys(td) & ~(FLISTP_QH | FLISTP_TERMINATE); td = wait_for_completed_qh(dev->controller, - UHCI_INST(dev->controller)->qh_data); + UHCI_INST(dev->controller)->qh_data, &timeout_us); if (td == 0) { return 0; } else { td_dump(td); - return 1; + return timeout_us <= 0 ? USB_TIMEOUT : -2; } } /* finalize == 1: if data is of packet aligned size, add a zero length packet */ static int -uhci_bulk(endpoint_t *ep, const int dalen, u8 *data, int finalize) +uhci_bulk_finalize_timeout(endpoint_t *ep, const int dalen, u8 *data, int finalize, + int timeout_us) { int maxpsize = ep->maxpacketsize; if (maxpsize == 0) @@ -460,15 +464,29 @@ uhci_bulk(endpoint_t *ep, const int dalen, u8 *data, int finalize) data += maxpsize; len_left -= maxpsize; } - if (run_schedule(ep->dev, tds) == 1) { + int ret = run_schedule(ep->dev, tds, timeout_us); + if (ret) { free(tds); - return -1; + return ret; } ep->toggle = toggle; free(tds); return dalen; /* TODO: We should return the actually transferred length. */ } +static int +uhci_bulk_timeout(endpoint_t *ep, int dalen, u8 *src, int timeout_us) +{ + /* usbdev_hc bulk_timeout API doesn't have finalize argument. Assume it should be 0. */ + return uhci_bulk_finalize_timeout(ep, dalen, src, 0, timeout_us); +} + +static int +uhci_bulk(endpoint_t *ep, const int dalen, u8 *data, int finalize) +{ + return uhci_bulk_finalize_timeout(ep, dalen, data, finalize, USB_MAX_PROCESSING_TIME_US); +} + typedef struct { qh_t *qh; td_t *tds; diff --git a/payloads/libpayload/drivers/usb/xhci.c b/payloads/libpayload/drivers/usb/xhci.c index e9a7ead18b..2f9206efd5 100644 --- a/payloads/libpayload/drivers/usb/xhci.c +++ b/payloads/libpayload/drivers/usb/xhci.c @@ -40,6 +40,7 @@ static void xhci_reset(hci_t *controller); static void xhci_reinit(hci_t *controller); static void xhci_shutdown(hci_t *controller); static int xhci_bulk(endpoint_t *ep, int size, u8 *data, int finalize); +static int xhci_bulk_timeout(endpoint_t *ep, int size, u8 *data, int timeout_us); static int xhci_control(usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen, u8 *data); static void* xhci_create_intr_queue(endpoint_t *ep, int reqsize, int reqcount, int reqtiming); @@ -168,6 +169,7 @@ xhci_init(unsigned long physical_bar) controller->init = xhci_reinit; controller->shutdown = xhci_shutdown; controller->bulk = xhci_bulk; + controller->bulk_timeout = xhci_bulk_timeout; controller->control = xhci_control; controller->set_address = xhci_set_address; controller->finish_device_config = xhci_finish_device_config; @@ -705,10 +707,11 @@ xhci_control(usbdev_t *const dev, const direction_t dir, int i, transferred = 0; const int n_stages = 2 + !!dalen; for (i = 0; i < n_stages; ++i) { - const int ret = xhci_wait_for_transfer(xhci, dev->address, 1); + const int ret = xhci_wait_for_transfer(xhci, dev->address, 1, + USB_MAX_PROCESSING_TIME_US); transferred += ret; if (ret < 0) { - if (ret == TIMEOUT) { + if (ret == USB_TIMEOUT) { xhci_debug("Stopping ID %d EP 1\n", dev->address); xhci_cmd_stop_endpoint(xhci, dev->address, 1); @@ -732,14 +735,10 @@ xhci_control(usbdev_t *const dev, const direction_t dir, return transferred; } -/* finalize == 1: if data is of packet aligned size, add a zero length packet */ static int -xhci_bulk(endpoint_t *const ep, const int size, u8 *const src, - const int finalize) +xhci_bulk_timeout(endpoint_t *const ep, const int size, u8 *const src, + int timeout_us) { - /* finalize: Hopefully the xHCI controller always does this. - We have no control over the packets. */ - u8 *data = src; xhci_t *const xhci = XHCI_INST(ep->dev->controller); const int slot_id = ep->dev->address; @@ -777,9 +776,9 @@ xhci_bulk(endpoint_t *const ep, const int size, u8 *const src, xhci_ring_doorbell(ep); /* Wait for transfer event */ - const int ret = xhci_wait_for_transfer(xhci, ep->dev->address, ep_id); + const int ret = xhci_wait_for_transfer(xhci, ep->dev->address, ep_id, timeout_us); if (ret < 0) { - if (ret == TIMEOUT) { + if (ret == USB_TIMEOUT) { xhci_debug("Stopping ID %d EP %d\n", ep->dev->address, ep_id); xhci_cmd_stop_endpoint(xhci, ep->dev->address, ep_id); @@ -798,6 +797,11 @@ xhci_bulk(endpoint_t *const ep, const int size, u8 *const src, return ret; } +static int xhci_bulk(endpoint_t *ep, int size, u8 *data, int finalize) +{ + return xhci_bulk_timeout(ep, size, data, USB_MAX_PROCESSING_TIME_US); +} + static trb_t * xhci_next_trb(trb_t *cur, int *const pcs) { diff --git a/payloads/libpayload/drivers/usb/xhci_commands.c b/payloads/libpayload/drivers/usb/xhci_commands.c index a4078030c6..1cebb5432a 100644 --- a/payloads/libpayload/drivers/usb/xhci_commands.c +++ b/payloads/libpayload/drivers/usb/xhci_commands.c @@ -69,7 +69,7 @@ xhci_wait_for_command(xhci_t *const xhci, int cc; cc = xhci_wait_for_command_done(xhci, cmd_trb, clear_event); - if (cc != TIMEOUT) + if (cc != USB_TIMEOUT) return cc; /* Abort command on timeout */ diff --git a/payloads/libpayload/drivers/usb/xhci_events.c b/payloads/libpayload/drivers/usb/xhci_events.c index 139ea59619..3c36a31355 100644 --- a/payloads/libpayload/drivers/usb/xhci_events.c +++ b/payloads/libpayload/drivers/usb/xhci_events.c @@ -232,7 +232,7 @@ xhci_wait_for_event_type(xhci_t *const xhci, * * Process events from xHCI Abort command. * - * Returns CC_COMMAND_RING_STOPPED on success and TIMEOUT on failure. + * Returns CC_COMMAND_RING_STOPPED on success and USB_TIMEOUT on failure. */ int @@ -244,7 +244,7 @@ xhci_wait_for_command_aborted(xhci_t *const xhci, const trb_t *const address) * what to do then. */ unsigned long timeout_us = USB_MAX_PROCESSING_TIME_US; /* 5s */ - int cc = TIMEOUT; + int cc = USB_TIMEOUT; /* * Expects two command completion events: * The first with CC == COMMAND_ABORTED should point to address @@ -292,7 +292,7 @@ xhci_wait_for_command_aborted(xhci_t *const xhci, const trb_t *const address) /* * returns cc of command in question (pointed to by `address`) - * caller should abort command if cc is TIMEOUT + * caller should abort command if cc is USB_TIMEOUT */ int xhci_wait_for_command_done(xhci_t *const xhci, @@ -300,7 +300,7 @@ xhci_wait_for_command_done(xhci_t *const xhci, const int clear_event) { unsigned long timeout_us = USB_MAX_PROCESSING_TIME_US; /* 5s */ - int cc = TIMEOUT; + int cc = USB_TIMEOUT; while (xhci_wait_for_event_type(xhci, TRB_EV_CMD_CMPL, &timeout_us)) { if ((xhci->er.cur->ptr_low == virt_to_phys(address)) && (xhci->er.cur->ptr_high == 0)) { @@ -321,12 +321,11 @@ xhci_wait_for_command_done(xhci_t *const xhci, /* returns amount of bytes transferred on success, negative CC on error */ int -xhci_wait_for_transfer(xhci_t *const xhci, const int slot_id, const int ep_id) +xhci_wait_for_transfer(xhci_t *const xhci, const int slot_id, const int ep_id, + unsigned long timeout_us) { xhci_spew("Waiting for transfer on ID %d EP %d\n", slot_id, ep_id); - /* 5s for all types of transfers */ - unsigned long timeout_us = USB_MAX_PROCESSING_TIME_US; - int ret = TIMEOUT; + int ret = USB_TIMEOUT; while (xhci_wait_for_event_type(xhci, TRB_EV_TRANSFER, &timeout_us)) { if (TRB_GET(ID, xhci->er.cur) == slot_id && TRB_GET(EP, xhci->er.cur) == ep_id) { diff --git a/payloads/libpayload/drivers/usb/xhci_private.h b/payloads/libpayload/drivers/usb/xhci_private.h index 45c301391e..c9464ce423 100644 --- a/payloads/libpayload/drivers/usb/xhci_private.h +++ b/payloads/libpayload/drivers/usb/xhci_private.h @@ -45,8 +45,7 @@ #define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit)) -/* Make these high enough to not collide with negative XHCI CCs */ -#define TIMEOUT -65 +/* Make these high enough to not collide with negative XHCI CCs and generic USB_TIMEOUT */ #define CONTROLLER_ERROR -66 #define COMMUNICATION_ERROR -67 #define OUT_OF_MEMORY -68 @@ -496,7 +495,8 @@ void xhci_update_event_dq(xhci_t *); void xhci_handle_events(xhci_t *); int xhci_wait_for_command_aborted(xhci_t *, const trb_t *); int xhci_wait_for_command_done(xhci_t *, const trb_t *, int clear_event); -int xhci_wait_for_transfer(xhci_t *, const int slot_id, const int ep_id); +int xhci_wait_for_transfer(xhci_t *, const int slot_id, const int ep_id, + unsigned long timeout_us); void xhci_clear_trb(trb_t *, int pcs); diff --git a/payloads/libpayload/include/usb/usb.h b/payloads/libpayload/include/usb/usb.h index 43c7b4279d..f36bb5c5be 100644 --- a/payloads/libpayload/include/usb/usb.h +++ b/payloads/libpayload/include/usb/usb.h @@ -231,6 +231,12 @@ struct usbdev { typedef enum { OHCI = 0, UHCI = 1, EHCI = 2, XHCI = 3, DWC2 = 4} hc_type; +/* + * Use higher value so it is less likely to conflict with error codes that + * controller drivers may already use. + */ +#define USB_TIMEOUT -65 + struct usbdev_hc { hci_t *next; uintptr_t reg_base; @@ -255,6 +261,10 @@ struct usbdev_hc { void (*shutdown) (hci_t *controller); int (*bulk) (endpoint_t *ep, int size, u8 *data, int finalize); + /* bulk_timeout(): Perform bulk transfer, but timeout after + specified time in us. Returns + USB_TIMEOUT in that case. */ + int (*bulk_timeout) (endpoint_t *ep, int size, u8 *data, int timeout_us); int (*control) (usbdev_t *dev, direction_t pid, int dr_length, void *devreq, int data_length, u8 *data); void* (*create_intr_queue) (endpoint_t *ep, int reqsize, int reqcount, int reqtiming); From 524ad684afd0ffc9c6cdf05d0806d61e75769f40 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 20 Dec 2025 17:21:08 -0600 Subject: [PATCH 121/789] mb/google/brya/var/taeko: Fix SOF speaker topology selection taeko/taeko4es use max98357a-tdm, not max98357a. TEST=build/boot Win11 on taeko, verify speaker output functional. Change-Id: I854a9c75ded94474ad440013dad64ee03c40d6e5 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90581 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- src/mainboard/google/brya/variants/taeko/overridetree.cb | 2 +- src/mainboard/google/brya/variants/taeko4es/overridetree.cb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/brya/variants/taeko/overridetree.cb b/src/mainboard/google/brya/variants/taeko/overridetree.cb index ff25f7b638..0e1290f873 100644 --- a/src/mainboard/google/brya/variants/taeko/overridetree.cb +++ b/src/mainboard/google/brya/variants/taeko/overridetree.cb @@ -530,7 +530,7 @@ chip soc/intel/alderlake end end chip drivers/sof - register "spkr_tplg" = "max98357a" + register "spkr_tplg" = "max98357a_tdm" register "jack_tplg" = "rt5682" register "mic_tplg" = "_2ch_pdm0" device generic 0 on end diff --git a/src/mainboard/google/brya/variants/taeko4es/overridetree.cb b/src/mainboard/google/brya/variants/taeko4es/overridetree.cb index 2dc3287a05..3e978f1e00 100644 --- a/src/mainboard/google/brya/variants/taeko4es/overridetree.cb +++ b/src/mainboard/google/brya/variants/taeko4es/overridetree.cb @@ -390,7 +390,7 @@ chip soc/intel/alderlake end end chip drivers/sof - register "spkr_tplg" = "max98357a" + register "spkr_tplg" = "max98357a_tdm" register "jack_tplg" = "rt5682" register "mic_tplg" = "_2ch_pdm0" device generic 0 on end From 2aca802e85201d6da75ffa6e7a26454770154fc8 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 20 Dec 2025 19:16:49 -0600 Subject: [PATCH 122/789] mb/google/brya/acpi/cnvi_bt_reset: Fix BT re-enumeration under Windows The previous implementation violated ACPI spec by attempting to implement a reset via _ON/_OFF, which are to be used exclusively for device power management/power state transitions. As a result, under Windows the CNVi BT device was continually re-enumerating and unable to be used. Fix this by moving the reset logic out of _ON/_OFF and into _RST, where it belongs. TEST=build/boot Win11 on google/taeko, verify BT device is functional. Change-Id: I1627fefbf7747129344291cc8855c15dda50cf5f Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90582 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- .../google/brya/acpi/cnvi_bt_reset.asl | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/mainboard/google/brya/acpi/cnvi_bt_reset.asl b/src/mainboard/google/brya/acpi/cnvi_bt_reset.asl index 6e84522145..4fd2ad7449 100644 --- a/src/mainboard/google/brya/acpi/cnvi_bt_reset.asl +++ b/src/mainboard/google/brya/acpi/cnvi_bt_reset.asl @@ -22,7 +22,7 @@ External (\_SB.PCI0.GTXS, MethodObj) Scope (\_SB.PCI0.XHCI.RHUB.HS10) { - PowerResource (CTTR, 0x00, 0x0000) + PowerResource (CTTR, 0x05, 0x0000) { Method (_STA, 0, NotSerialized) // _STA: Status { @@ -31,32 +31,30 @@ Scope (\_SB.PCI0.XHCI.RHUB.HS10) Method (_ON, 0, NotSerialized) // _ON_: Power On { - If (LEqual (\_SB.PCI0.GTXS(BT_RESET_GPIO), 0)) { - \_SB.PCI0.STXS(CNV_BTEN) - \_SB.PCI0.STXS(CNV_BT_IF_SELECT) - \_SB.PCI0.STXS(BT_RESET_GPIO) - } } Method (_OFF, 0, NotSerialized) // _OFF: Power Off { - If (LEqual (\_SB.PCI0.GTXS(BT_RESET_GPIO), 1)) { - \_SB.PCI0.CTXS(CNV_BTEN) - \_SB.PCI0.CTXS(CNV_BT_IF_SELECT) - \_SB.PCI0.CTXS(BT_RESET_GPIO) - Sleep (BT_RESET_DELAY_MS) - } } + Method (_RST, 0, NotSerialized) // _RST: Device Reset + { + \_SB.PCI0.CTXS(CNV_BTEN) + \_SB.PCI0.CTXS(CNV_BT_IF_SELECT) + \_SB.PCI0.CTXS(BT_RESET_GPIO) + Sleep (BT_RESET_DELAY_MS) + \_SB.PCI0.STXS(CNV_BTEN) + \_SB.PCI0.STXS(CNV_BT_IF_SELECT) + \_SB.PCI0.STXS(BT_RESET_GPIO) + Sleep (BT_RESET_DELAY_MS) + } } - Name (_PRR, Package (0x01) // _PRR: Power Resource for Reset - { - CTTR - }) - - Name (_PR0, Package (0x01) // _PR0: Power Resources for D0 + Method (_PRR, 0, NotSerialized) // _PRR: Power Resource for Reset { - CTTR - }) + Return (Package (0x01) + { + CTTR + }) + } } From 65cbf312af928fde6260db0a5cc12ad6df4642fe Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 20 Dec 2025 11:18:21 -0600 Subject: [PATCH 123/789] mb/google/volteer: Convert MIPI camera cfg from static ASL to devicetree Convert MIPI camera configurations from static ASL files to devicetree- based runtime ACPI generation using the mipi_camera driver. This moves the camera IPU and device definitions from static ASL includes to devicetree overridetree files. Changes: - Convert baseboard, voema, volteer, and volteer2 from static mipi_camera.asl files to devicetree configuration - Move IPU0 configuration with CAM0 and CAM1 to volteer/volteer2 variant overridetree files (baseboard devicetree not used directly) - Remove all static ASL camera definition files (mipi_camera.asl) - Simplify voema variant to use only 1 IPU port (CAM1 only) instead of 2 ports, removing unused CAM0 port definition - Add SSDB config based on sensor name/type and CIO2 config This, along with follow-on patches, will allow volteer variants to be properly supported under Windows/Linux as well as ChromeOS. Change-Id: I7bd4ef2812a3d21b6541469bc3a126498d72f5ef Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90579 Tested-by: build bot (Jenkins) Reviewed-by: Eric Lai Reviewed-by: Sean Rhodes --- src/mainboard/google/volteer/Kconfig | 12 +- src/mainboard/google/volteer/dsdt.asl | 8 - .../include/baseboard/acpi/mipi_camera.asl | 650 ------------------ .../include/variant/acpi/mipi_camera.asl | 340 --------- .../volteer/variants/voema/overridetree.cb | 74 +- .../include/variant/acpi/mipi_camera.asl | 3 - .../volteer/variants/volteer/overridetree.cb | 139 +++- .../include/variant/acpi/mipi_camera.asl | 3 - .../volteer/variants/volteer2/overridetree.cb | 139 +++- 9 files changed, 353 insertions(+), 1015 deletions(-) delete mode 100644 src/mainboard/google/volteer/variants/baseboard/include/baseboard/acpi/mipi_camera.asl delete mode 100644 src/mainboard/google/volteer/variants/voema/include/variant/acpi/mipi_camera.asl delete mode 100644 src/mainboard/google/volteer/variants/volteer/include/variant/acpi/mipi_camera.asl delete mode 100644 src/mainboard/google/volteer/variants/volteer2/include/variant/acpi/mipi_camera.asl diff --git a/src/mainboard/google/volteer/Kconfig b/src/mainboard/google/volteer/Kconfig index a7537c0fd2..a32681d811 100644 --- a/src/mainboard/google/volteer/Kconfig +++ b/src/mainboard/google/volteer/Kconfig @@ -105,8 +105,8 @@ config BOARD_GOOGLE_TRONDO config BOARD_GOOGLE_VOEMA select BOARD_GOOGLE_BASEBOARD_VOLTEER + select DRIVERS_INTEL_MIPI_CAMERA select INTEL_GMA_HAVE_VBT - select VARIANT_HAS_MIPI_CAMERA config BOARD_GOOGLE_VOLET select BOARD_GOOGLE_BASEBOARD_VOLTEER @@ -114,24 +114,24 @@ config BOARD_GOOGLE_VOLET config BOARD_GOOGLE_VOLTEER select BOARD_GOOGLE_BASEBOARD_VOLTEER + select DRIVERS_INTEL_MIPI_CAMERA select INTEL_CAR_NEM select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES - select VARIANT_HAS_MIPI_CAMERA config BOARD_GOOGLE_VOLTEER2 select BOARD_GOOGLE_BASEBOARD_VOLTEER select DRIVER_I2C_TPM_ACPI select DRIVERS_GENESYSLOGIC_GL9755 + select DRIVERS_INTEL_MIPI_CAMERA select INTEL_GMA_HAVE_VBT select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES - select VARIANT_HAS_MIPI_CAMERA config BOARD_GOOGLE_VOLTEER2_TI50 select BOARD_GOOGLE_BASEBOARD_VOLTEER select DRIVER_I2C_TPM_ACPI select DRIVERS_GENESYSLOGIC_GL9755 + select DRIVERS_INTEL_MIPI_CAMERA select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES - select VARIANT_HAS_MIPI_CAMERA config BOARD_GOOGLE_VOXEL select BOARD_GOOGLE_BASEBOARD_VOLTEER @@ -241,10 +241,6 @@ config VARIANT_DIR default "volteer2" if BOARD_GOOGLE_VOLTEER2_TI50 default "voxel" if BOARD_GOOGLE_VOXEL -config VARIANT_HAS_MIPI_CAMERA - bool - default n - config USE_PM_ACPI_TIMER default n diff --git a/src/mainboard/google/volteer/dsdt.asl b/src/mainboard/google/volteer/dsdt.asl index c200294e74..dbd36043aa 100644 --- a/src/mainboard/google/volteer/dsdt.asl +++ b/src/mainboard/google/volteer/dsdt.asl @@ -30,9 +30,6 @@ DefinitionBlock( #include #include #include -#if CONFIG(VARIANT_HAS_MIPI_CAMERA) - #include -#endif } /* Mainboard hooks */ #include "mainboard.asl" @@ -48,9 +45,4 @@ DefinitionBlock( } #include - -#if CONFIG(VARIANT_HAS_MIPI_CAMERA) - /* Camera */ - #include -#endif /* VARIANT_HAS_MIPI_CAMERA */ } diff --git a/src/mainboard/google/volteer/variants/baseboard/include/baseboard/acpi/mipi_camera.asl b/src/mainboard/google/volteer/variants/baseboard/include/baseboard/acpi/mipi_camera.asl deleted file mode 100644 index f22b402865..0000000000 --- a/src/mainboard/google/volteer/variants/baseboard/include/baseboard/acpi/mipi_camera.asl +++ /dev/null @@ -1,650 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -Scope (\_SB.PCI0.IPU0) -{ - Name (_DSD, Package (0x02) /* _DSD: Device-Specific Data */ - { - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x02) - { - Package (0x02) - { - "port0", - "PRT0" - }, - Package (0x02) - { - "port1", - "PRT1" - } - } - }) - - Name (PRT0, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 5 - } - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP00" - } - } - }) - - Name (PRT1, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 1 - } - }, - - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP10" - } - } - }) -} - -Scope (\_SB.PCI0.IPU0) -{ - Name (EP00, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x04) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x04) - { - 1, - 0x02, - 0x03, - 0x04 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - ^I2C3.CAM0, - 0, - 0 - } - } - } - }) - Name (EP10, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x04) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x02) - { - 1, - 0x02 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - ^I2C2.CAM1, - 0, - 0 - } - } - } - }) -} - -Scope (\_SB.PCI0.I2C3) -{ - /* Reference counter to track power control by RCAM and VCM */ - Name (REFC, 0) - PowerResource (RCPR, 0x00, 0x0000) - { - Name (STA, 0) - Method (_ON, 0, Serialized) /* Rear camera_ON_: Power On */ - { - /* Enable IMG_CLK */ - MCON(3,1) /* Clock 3, 19.2MHz */ - - /* Pull RST low */ - CTXS(GPP_F15) - - /* Pull SNRPWR_EN high */ - STXS(GPP_H14) - - If (REFC == 0) - { - /* Pull PWREN high */ - STXS(GPP_H20) - } - Sleep(2) /* reset pulse width */ - - REFC++ - - /* Pull RST high */ - STXS(GPP_F15) - - Sleep(1) /* t2 */ - - STA = 1 - } - Method (_OFF, 0, Serialized) /* Rear camera _OFF: Power Off */ - { - /* Disable IMG_CLK */ - Sleep(1) /* t0+t1 */ - MCOF(3) /* Clock 3 */ - - /* Pull RST low */ - CTXS(GPP_F15) - - If (REFC == 1) - { - /* Pull PWREN low */ - CTXS(GPP_H20) - } - REFC-- - - /* Pull SNRPWR_EN low */ - CTXS(GPP_H14) - - STA = 0 - } - Method (_STA, 0, NotSerialized) - { - Return (STA) - } - } - - Device (CAM0) - { - Name (_HID, "OVTI8856") - Name (_UID, 0) - Name (_DDN, "Ov 8856 Camera") /* _DDN: DOS Device Name */ - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () /* _CRS: Current Resource Settings */ - { - I2cSerialBus (0x0010, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C3", - 0x00, ResourceConsumer, , - ) - }) - Name (_PR0, Package (0x01) /* _PR0: Power Resources for D0 */ - { - RCPR - }) - Name (_PR3, Package (0x01) /* _PR3: Power Resources for D3hot */ - { - RCPR - }) - Name (_DSD, Package (0x04) /* _DSD: Device-Specific Data */ - { - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "port0", - "PRT0" - } - }, - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x03) - { - Package (0x02) - { - "clock-frequency", - 0x0124F800 - }, - Package (0x02) - { - "lens-focus", - Package (0x01) - { - VCM0 - } - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - Name (PRT0, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 0 - } - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP00" - } - } - }) - Name (EP00, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x05) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x04) - { - 1, - 0x02, - 0x03, - 0x04 - } - }, - Package (0x02) - { - "link-frequencies", - Package (0x02) - { - 0x15752A00, - 0xABA9500 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - IPU0, - 0, - 0 - } - } - } - }) - } - - PowerResource (VCPR, 0x00, 0x0000) - { - Name (STA, 0) - Method (_ON, 0, Serialized) /* VCPR_ON_: VCM Power On */ - { - If (REFC == 0) - { - /* Pull PWREN high */ - STXS(GPP_H20) - } - REFC++ - STA = 1 - } - Method (_OFF, 0, Serialized) /* VCPR_OFF: VCM Power Off */ - { - If (REFC == 1) - { - /* Pull PWREN low */ - CTXS(GPP_H20) - } - REFC-- - STA = 0 - } - Method (_STA, 0, NotSerialized) - { - Return (STA) - } - } - - Device (VCM0) - { - Name (_HID, "PRP0001") - Name (_UID, 0x00) - Name (_DDN, "DW9768 VCM") /* _DDN: DOS Device Name */ - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () /* _CRS: Current Resource Settings */ - { - I2cSerialBus (0x000C, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C3", - 0x00, ResourceConsumer, , - ) - }) - Name (_DEP, Package (0x01) /* _DEP: Dependencies */ - { - CAM0 - }) - Name (_PR0, Package (0x01) /* _PR0: Power Resources for D0 */ - { - VCPR - }) - Name (_PR3, Package (0x01) /* _PR3: Power Resources for D3hot */ - { - VCPR - }) - Name (_DSD, Package (0x02) /* _DSD: Device-Specific Data */ - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x02) - { - Package (0x02) - { - "compatible", - "dongwoon,dw9768" - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - } - Device (NVM0) - { - Name (_HID, "PRP0001") - Name (_UID, 0x01) - Name (_DDN, "AT24 EEPROM") // _DDN: DOS Device Name - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings - { - I2cSerialBusV2 (0x0058, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C3", - 0x00, ResourceConsumer, , Exclusive, - ) - }) - Name (_DEP, Package (0x01) // _DEP: Dependencies - { - CAM0 - }) - Name (_PR0, Package (0x01) // _PR0: Power Resources for D0 - { - RCPR - }) - Name (_PR3, Package (0x01) // _PR3: Power Resources for D3hot - { - RCPR - }) - Name (_DSD, Package (0x02) // _DSD: Device-Specific Data - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */, - Package (0x06) - { - Package (0x02) - { - "size", - 0x2800 - }, - Package (0x02) - { - "pagesize", - 1 - }, - Package (0x02) - { - "read-only", - 1 - }, - Package (0x02) - { - "address-width", - 0x10 - }, - Package (0x02) - { - "compatible", - "atmel,24c1024" - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - } -} - -Scope (\_SB.PCI0.I2C2) -{ - Name (STA, 0) - PowerResource (FCPR, 0x00, 0x0000) - { - Method (_ON, 0, Serialized) /* Front camera_ON_: Power On */ - { - If (STA == 0) - { - /* Enable IMG_CLK */ - MCON(2,1) /* Clock 2, 19.2MHz */ - - /* Pull RST low */ - CTXS(GPP_D4) - - /* Pull SNRPWR_EN high */ - STXS(GPP_D18) - - /* Pull PWREN high */ - STXS(GPP_D17) - Sleep(10) /* t9 */ - - /* Pull RST high */ - STXS(GPP_D4) - Sleep(1) /* t2 */ - - STA = 1 - } - } - Method (_OFF, 0, Serialized) /* Front camera_OFF_: Power Off */ - { - If (STA == 1) - { - /* Disable IMG_CLK */ - Sleep(1) /* t0+t1 */ - MCOF(2) /* Clock 2 */ - - /* Pull RST low */ - CTXS(GPP_D4) - - /* Pull PWREN low */ - CTXS(GPP_D17) - - /* Pull SNRPWR_EN low */ - CTXS(GPP_D18) - - STA = 0 - } - } - Method (_STA, 0, NotSerialized) - { - Return (STA) - } - } - - Device (CAM1) - { - Name (_HID, "INT3474") - Name (_UID, 0) - Name (_DDN, "Ov 2740 Camera") /* _DDN: DOS Device Name */ - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () /* _CRS: Current Resource Settings */ - { - I2cSerialBus (0x0010, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C2", - 0x00, ResourceConsumer, , - ) - }) - Name (_PR0, Package (0x01) /* _PR0: Power Resources for D0 */ - { - FCPR - }) - Name (_PR3, Package (0x01) /* _PR3: Power Resources for D3hot */ - { - FCPR - }) - Name (_DSD, Package (0x04) /* _DSD: Device-Specific Data */ - { - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "port0", - "PRT0" - } - }, - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x02) - { - Package (0x02) - { - "clock-frequency", - 0x0124F800 - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - Name (PRT0, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 0 - } - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP00" - } - } - }) - Name (EP00, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x05) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x02) - { - 1, - 0x02 - } - }, - Package (0x02) - { - "link-frequencies", - Package (0x01) - { - 0x15752A00 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - IPU0, - 1, - 0 - } - } - } - }) - } -} diff --git a/src/mainboard/google/volteer/variants/voema/include/variant/acpi/mipi_camera.asl b/src/mainboard/google/volteer/variants/voema/include/variant/acpi/mipi_camera.asl deleted file mode 100644 index e35c3bba8a..0000000000 --- a/src/mainboard/google/volteer/variants/voema/include/variant/acpi/mipi_camera.asl +++ /dev/null @@ -1,340 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -Scope (\_SB.PCI0.IPU0) -{ - Name (_DSD, Package (0x02) /* _DSD: Device-Specific Data */ - { - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x02) - { - Package (0x02) - { - "port0", - "PRT0" - }, - Package (0x02) - { - "port1", - "PRT1" - } - } - }) - - Name (PRT0, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 5 - } - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP00" - } - } - }) - - Name (PRT1, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 1 - } - }, - - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP10" - } - } - }) -} - -Scope (\_SB.PCI0.IPU0) -{ - Name (EP10, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x04) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x02) - { - 1, - 0x02 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - ^I2C2.CAM1, - 0, - 0 - } - } - } - }) -} - -Scope (\_SB.PCI0.I2C2) -{ - Name (STA, 0) - PowerResource (FCPR, 0x00, 0x0000) - { - Method (_ON, 0, Serialized) /* Front camera_ON_: Power On */ - { - If (STA == 0) - { - /* Enable IMG_CLK */ - MCON(2,1) /* Clock 2, 19.2MHz */ - - /* Pull RST low */ - CTXS(GPP_D4) - - /* Pull PWREN high */ - STXS(GPP_D17) - Sleep(10) /* t9 */ - - /* Pull RST high */ - STXS(GPP_D4) - Sleep(1) /* t2 */ - - STA = 1 - } - } - Method (_OFF, 0, Serialized) /* Front camera_OFF_: Power Off */ - { - If (STA == 1) - { - /* Disable IMG_CLK */ - Sleep(1) /* t0+t1 */ - MCOF(2) /* Clock 2 */ - - /* Pull RST low */ - CTXS(GPP_D4) - - /* Pull PWREN low */ - CTXS(GPP_D17) - - STA = 0 - } - } - Method (_STA, 0, NotSerialized) - { - Return (STA) - } - } - - Device (CAM1) - { - Name (_HID, "INT3474") - Name (_UID, 0) - Name (_DDN, "Ov 2740 Camera") /* _DDN: DOS Device Name */ - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () /* _CRS: Current Resource Settings */ - { - I2cSerialBus (0x0036, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C2", - 0x00, ResourceConsumer, , - ) - }) - Name (_PR0, Package (0x01) /* _PR0: Power Resources for D0 */ - { - FCPR - }) - Name (_PR3, Package (0x01) /* _PR3: Power Resources for D3hot */ - { - FCPR - }) - Name (_DSD, Package (0x04) /* _DSD: Device-Specific Data */ - { - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "port0", - "PRT0" - } - }, - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x02) - { - Package (0x02) - { - "clock-frequency", - 0x0124F800 - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - Name (PRT0, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 0 - } - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP00" - } - } - }) - Name (EP00, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x05) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x02) - { - 1, - 0x02 - } - }, - Package (0x02) - { - "link-frequencies", - Package (0x01) - { - 0x15752A00 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - IPU0, - 1, - 0 - } - } - } - }) - } - Device (NVM0) - { - Name (_HID, "PRP0001") - Name (_UID, 0x01) - Name (_DDN, "AT24 EEPROM") // _DDN: DOS Device Name - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings - { - I2cSerialBusV2 (0x0050, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C2", - 0x00, ResourceConsumer, , Exclusive, - ) - }) - Name (_DEP, Package (0x01) // _DEP: Dependencies - { - CAM1 - }) - Name (_PR0, Package (0x01) // _PR0: Power Resources for D0 - { - FCPR - }) - Name (_PR3, Package (0x01) // _PR3: Power Resources for D3hot - { - FCPR - }) - Name (_DSD, Package (0x02) // _DSD: Device-Specific Data - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */, - Package (0x06) - { - Package (0x02) - { - "size", - 0x2000 - }, - Package (0x02) - { - "pagesize", - 1 - }, - Package (0x02) - { - "read-only", - 1 - }, - Package (0x02) - { - "address-width", - 0x10 - }, - Package (0x02) - { - "compatible", - "atmel,24c64" - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - } -} diff --git a/src/mainboard/google/volteer/variants/voema/overridetree.cb b/src/mainboard/google/volteer/variants/voema/overridetree.cb index e4b2616807..ecb37987c7 100644 --- a/src/mainboard/google/volteer/variants/voema/overridetree.cb +++ b/src/mainboard/google/volteer/variants/voema/overridetree.cb @@ -9,7 +9,19 @@ chip soc/intel/tigerlake register "typec_aux_bias_pads[0]" = "{.pad_auxp_dc = GPP_E10, .pad_auxn_dc = GPP_E13}" device domain 0 on - device ref ipu on end # IPU + device ref ipu on + chip drivers/intel/mipi_camera + register "acpi_uid" = "0x50000" + register "acpi_name" = ""IPU0"" + register "device_type" = "INTEL_ACPI_CAMERA_CIO2" + + register "cio2_num_ports" = "1" + register "cio2_lanes_used" = "{2}" # 2 CSI Camera lanes are used + register "cio2_lane_endpoint[0]" = ""^I2C2.CAM1"" + register "cio2_prt[0]" = "1" + device generic 0 on end + end + end device ref i2c0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" @@ -62,6 +74,66 @@ chip soc/intel/tigerlake device i2c 10 on end end end + device ref i2c2 on + chip drivers/intel/mipi_camera + register "acpi_hid" = ""INT3474"" + register "acpi_uid" = "0" + register "acpi_name" = ""CAM1"" + register "chip_name" = ""Ov 2740 Camera"" + register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "has_power_resource" = "true" + + register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" + register "ssdb.platform" = "PLAT_TGL" + register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" + register "rom_address" = "0x50" + register "num_freq_entries" = "1" + register "link_freq[0]" = "360 * MHz" + register "remote_name" = ""IPU0"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" + + #Controls + register "clk_panel.clks[0].clknum" = "2" + register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ" + + register "gpio_panel.gpio[0].gpio_num" = "GPP_D4" #reset + register "gpio_panel.gpio[1].gpio_num" = "GPP_D17" #power enable + + #_ON + register "on_seq.ops_cnt" = "4" + register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)" + register "on_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(1, 10)" # PWREN high, sleep 10ms + register "on_seq.ops[3]" = "SEQ_OPS_GPIO_ENABLE(0, 1)" # RST high, sleep 1ms + + #_OFF + register "off_seq.ops_cnt" = "3" + register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 1)" # Disable clock, delay 1ms + register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)" # PWREN low + + device i2c 36 on end + end + chip drivers/intel/mipi_camera + register "acpi_hid" = "ACPI_DT_NAMESPACE_HID" + register "acpi_uid" = "1" + register "acpi_name" = ""NVM0"" + register "chip_name" = ""AT24 EEPROM"" + register "device_type" = "INTEL_ACPI_CAMERA_NVM" + register "pr0" = ""\\_SB.PCI0.I2C2.CAM1.PRIC"" + + register "nvm_size" = "0x2000" + register "nvm_pagesize" = "1" + register "nvm_readonly" = "1" + register "nvm_width" = "0x10" + register "nvm_compat" = ""atmel,24c64"" + + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D0" + + device i2c 50 on end + end + end device ref i2c5 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" diff --git a/src/mainboard/google/volteer/variants/volteer/include/variant/acpi/mipi_camera.asl b/src/mainboard/google/volteer/variants/volteer/include/variant/acpi/mipi_camera.asl deleted file mode 100644 index 418f2e04ba..0000000000 --- a/src/mainboard/google/volteer/variants/volteer/include/variant/acpi/mipi_camera.asl +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include diff --git a/src/mainboard/google/volteer/variants/volteer/overridetree.cb b/src/mainboard/google/volteer/variants/volteer/overridetree.cb index c489c2dc91..21e6c63e55 100644 --- a/src/mainboard/google/volteer/variants/volteer/overridetree.cb +++ b/src/mainboard/google/volteer/variants/volteer/overridetree.cb @@ -63,7 +63,21 @@ chip soc/intel/tigerlake probe DB_USB USB4_GEN3 end - device ref ipu on end + device ref ipu on + chip drivers/intel/mipi_camera + register "acpi_uid" = "0x50000" + register "acpi_name" = ""IPU0"" + register "device_type" = "INTEL_ACPI_CAMERA_CIO2" + + register "cio2_num_ports" = "2" + register "cio2_lanes_used" = "{4,2}" # 4 and 2 CSI Camera lanes are used + register "cio2_lane_endpoint[0]" = ""^I2C3.CAM0"" + register "cio2_lane_endpoint[1]" = ""^I2C2.CAM1"" + register "cio2_prt[0]" = "5" + register "cio2_prt[1]" = "1" + device generic 0 on end + end + end device ref i2c0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" @@ -166,6 +180,129 @@ chip soc/intel/tigerlake register "proxraw_strength" = "0" device i2c 28 on end end + chip drivers/intel/mipi_camera + register "acpi_hid" = ""INT3474"" + register "acpi_uid" = "0" + register "acpi_name" = ""CAM1"" + register "chip_name" = ""Ov 2740 Camera"" + register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "has_power_resource" = "true" + register "low_power_probe" = "1" + + register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" + register "ssdb.platform" = "PLAT_TGL" + register "num_freq_entries" = "1" + register "link_freq[0]" = "360 * MHz" + register "remote_name" = ""IPU0"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" + + #Controls + register "clk_panel.clks[0].clknum" = "2" + register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ" + + register "gpio_panel.gpio[0].gpio_num" = "GPP_D4" #reset + register "gpio_panel.gpio[1].gpio_num" = "GPP_D17" #power enable + register "gpio_panel.gpio[2].gpio_num" = "GPP_D18" #SNRPWR_EN + + #_ON + register "on_seq.ops_cnt" = "5" + register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)" + register "on_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(2, 0)" # SNRPWR_EN high + register "on_seq.ops[3]" = "SEQ_OPS_GPIO_ENABLE(1, 10)" # PWREN high, sleep 10ms + register "on_seq.ops[4]" = "SEQ_OPS_GPIO_ENABLE(0, 1)" # RST high, sleep 1ms + + #_OFF + register "off_seq.ops_cnt" = "4" + register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 1)" # Disable clock, delay 1ms + register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)" # PWREN low + register "off_seq.ops[3]" = "SEQ_OPS_GPIO_DISABLE(2, 0)" # SNRPWR_EN low + + device i2c 10 on end + end + end + device ref i2c3 on + chip drivers/intel/mipi_camera + register "acpi_hid" = ""OVTI8856"" + register "acpi_uid" = "0" + register "acpi_name" = ""CAM0"" + register "chip_name" = ""Ov 8856 Camera"" + register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "has_power_resource" = "true" + register "low_power_probe" = "1" + + register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" + register "ssdb.platform" = "PLAT_TGL" + register "ssdb.vcm_type" = "VCM_DW9808" + register "vcm_address" = "0x0C" + register "vcm_name" = ""VCM0"" + # placeholder; ROM type 24C1024 currently unsupported + # register "ssdb.rom_type" = "ROM_EEPROM_24C1024" + # register "rom_address" = "0x50" + register "num_freq_entries" = "2" + register "link_freq[0]" = "360 * MHz" # 360 MHz + register "link_freq[1]" = "180 * MHz" # 180 MHz + register "remote_name" = ""IPU0"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" + + #Controls + register "clk_panel.clks[0].clknum" = "3" + register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ" + + register "gpio_panel.gpio[0].gpio_num" = "GPP_F15" #reset + register "gpio_panel.gpio[1].gpio_num" = "GPP_H20" #power enable + register "gpio_panel.gpio[2].gpio_num" = "GPP_H14" #SNRPWR_EN + + #_ON + register "on_seq.ops_cnt" = "5" + register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)" + register "on_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(2, 0)" # SNRPWR_EN high + register "on_seq.ops[3]" = "SEQ_OPS_GPIO_ENABLE(1, 2)" # PWREN high, sleep 2ms + register "on_seq.ops[4]" = "SEQ_OPS_GPIO_ENABLE(0, 1)" # RST high, sleep 1ms + + #_OFF + register "off_seq.ops_cnt" = "4" + register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 1)" # Disable clock, delay 1ms + register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)" # PWREN low + register "off_seq.ops[3]" = "SEQ_OPS_GPIO_DISABLE(2, 0)" # SNRPWR_EN low + + device i2c 10 on end + end + chip drivers/intel/mipi_camera + register "acpi_uid" = "2" + register "acpi_name" = ""VCM0"" + register "chip_name" = ""DW9768 VCM"" + register "device_type" = "INTEL_ACPI_CAMERA_VCM" + + register "pr0" = ""\\_SB.PCI0.I2C3.CAM0.PRIC"" + register "vcm_compat" = ""dongwoon,dw9768"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D0" + + device i2c 0C on end + end + chip drivers/intel/mipi_camera + register "acpi_hid" = "ACPI_DT_NAMESPACE_HID" + register "acpi_uid" = "1" + register "acpi_name" = ""NVM0"" + register "chip_name" = ""AT24 EEPROM"" + register "device_type" = "INTEL_ACPI_CAMERA_NVM" + register "pr0" = ""\\_SB.PCI0.I2C3.CAM0.PRIC"" + + register "nvm_size" = "0x2800" + register "nvm_pagesize" = "1" + register "nvm_readonly" = "1" + register "nvm_width" = "0x10" + register "nvm_compat" = ""atmel,24c1024"" + + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D0" + + device i2c 58 on end + end end device ref i2c5 on chip drivers/i2c/generic diff --git a/src/mainboard/google/volteer/variants/volteer2/include/variant/acpi/mipi_camera.asl b/src/mainboard/google/volteer/variants/volteer2/include/variant/acpi/mipi_camera.asl deleted file mode 100644 index 418f2e04ba..0000000000 --- a/src/mainboard/google/volteer/variants/volteer2/include/variant/acpi/mipi_camera.asl +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include diff --git a/src/mainboard/google/volteer/variants/volteer2/overridetree.cb b/src/mainboard/google/volteer/variants/volteer2/overridetree.cb index ee181c86e0..f27bb77f98 100644 --- a/src/mainboard/google/volteer/variants/volteer2/overridetree.cb +++ b/src/mainboard/google/volteer/variants/volteer2/overridetree.cb @@ -117,7 +117,21 @@ chip soc/intel/tigerlake probe DB_USB USB4_GEN3 end - device ref ipu on end # IPU 0x9A19 + device ref ipu on + chip drivers/intel/mipi_camera + register "acpi_uid" = "0x50000" + register "acpi_name" = ""IPU0"" + register "device_type" = "INTEL_ACPI_CAMERA_CIO2" + + register "cio2_num_ports" = "2" + register "cio2_lanes_used" = "{4,2}" # 4 and 2 CSI Camera lanes are used + register "cio2_lane_endpoint[0]" = ""^I2C3.CAM0"" + register "cio2_lane_endpoint[1]" = ""^I2C2.CAM1"" + register "cio2_prt[0]" = "5" + register "cio2_prt[1]" = "1" + device generic 0 on end + end + end device ref i2c0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" @@ -225,6 +239,129 @@ chip soc/intel/tigerlake register "proxraw_strength" = "0" device i2c 28 on end end + chip drivers/intel/mipi_camera + register "acpi_hid" = ""INT3474"" + register "acpi_uid" = "0" + register "acpi_name" = ""CAM1"" + register "chip_name" = ""Ov 2740 Camera"" + register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "has_power_resource" = "true" + register "low_power_probe" = "1" + + register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" + register "ssdb.platform" = "PLAT_TGL" + register "num_freq_entries" = "1" + register "link_freq[0]" = "360 * MHz" + register "remote_name" = ""IPU0"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" + + #Controls + register "clk_panel.clks[0].clknum" = "2" + register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ" + + register "gpio_panel.gpio[0].gpio_num" = "GPP_D4" #reset + register "gpio_panel.gpio[1].gpio_num" = "GPP_D17" #power enable + register "gpio_panel.gpio[2].gpio_num" = "GPP_D18" #SNRPWR_EN + + #_ON + register "on_seq.ops_cnt" = "5" + register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)" + register "on_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(2, 0)" # SNRPWR_EN high + register "on_seq.ops[3]" = "SEQ_OPS_GPIO_ENABLE(1, 10)" # PWREN high, sleep 10ms + register "on_seq.ops[4]" = "SEQ_OPS_GPIO_ENABLE(0, 1)" # RST high, sleep 1ms + + #_OFF + register "off_seq.ops_cnt" = "4" + register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 1)" # Disable clock, delay 1ms + register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)" # PWREN low + register "off_seq.ops[3]" = "SEQ_OPS_GPIO_DISABLE(2, 0)" # SNRPWR_EN low + + device i2c 10 on end + end + end + device ref i2c3 on + chip drivers/intel/mipi_camera + register "acpi_hid" = ""OVTI8856"" + register "acpi_uid" = "0" + register "acpi_name" = ""CAM0"" + register "chip_name" = ""Ov 8856 Camera"" + register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "has_power_resource" = "true" + register "low_power_probe" = "1" + + register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" + register "ssdb.platform" = "PLAT_TGL" + register "ssdb.vcm_type" = "VCM_DW9808" + register "vcm_address" = "0x0C" + register "vcm_name" = ""VCM0"" + # placeholder; ROM type 24C1024 currently unsupported + # register "ssdb.rom_type" = "ROM_EEPROM_24C1024" + # register "rom_address" = "0x50" + register "num_freq_entries" = "2" + register "link_freq[0]" = "360 * MHz" # 360 MHz + register "link_freq[1]" = "180 * MHz" # 180 MHz + register "remote_name" = ""IPU0"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" + + #Controls + register "clk_panel.clks[0].clknum" = "3" + register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ" + + register "gpio_panel.gpio[0].gpio_num" = "GPP_F15" #reset + register "gpio_panel.gpio[1].gpio_num" = "GPP_H20" #power enable + register "gpio_panel.gpio[2].gpio_num" = "GPP_H14" #SNRPWR_EN + + #_ON + register "on_seq.ops_cnt" = "5" + register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)" + register "on_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(2, 0)" # SNRPWR_EN high + register "on_seq.ops[3]" = "SEQ_OPS_GPIO_ENABLE(1, 2)" # PWREN high, sleep 2ms + register "on_seq.ops[4]" = "SEQ_OPS_GPIO_ENABLE(0, 1)" # RST high, sleep 1ms + + #_OFF + register "off_seq.ops_cnt" = "4" + register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 1)" # Disable clock, delay 1ms + register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)" # PWREN low + register "off_seq.ops[3]" = "SEQ_OPS_GPIO_DISABLE(2, 0)" # SNRPWR_EN low + + device i2c 10 on end + end + chip drivers/intel/mipi_camera + register "acpi_uid" = "2" + register "acpi_name" = ""VCM0"" + register "chip_name" = ""DW9768 VCM"" + register "device_type" = "INTEL_ACPI_CAMERA_VCM" + + register "pr0" = ""\\_SB.PCI0.I2C3.CAM0.PRIC"" + register "vcm_compat" = ""dongwoon,dw9768"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D0" + + device i2c 0C on end + end + chip drivers/intel/mipi_camera + register "acpi_hid" = "ACPI_DT_NAMESPACE_HID" + register "acpi_uid" = "1" + register "acpi_name" = ""NVM0"" + register "chip_name" = ""AT24 EEPROM"" + register "device_type" = "INTEL_ACPI_CAMERA_NVM" + register "pr0" = ""\\_SB.PCI0.I2C3.CAM0.PRIC"" + + register "nvm_size" = "0x2800" + register "nvm_pagesize" = "1" + register "nvm_readonly" = "1" + register "nvm_width" = "0x10" + register "nvm_compat" = ""atmel,24c1024"" + + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D0" + + device i2c 58 on end + end end device ref i2c5 on chip drivers/i2c/generic From ede97ef9da9b34ed6d30bc57d4efa94bb3738676 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 20 Dec 2025 15:50:50 -0600 Subject: [PATCH 124/789] mb/google/volteer: Add IPUA device and sensor names Add missing configuration items for volteer variants to have functional MIPI cameras under Windows/mainline Linux: - Add IPUA device to graphics device configuration - Add sensor_name register to sensor device configurations Change-Id: Icd80ccc09b9c0436978d781fefb6ab85fbe71484 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90580 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) Reviewed-by: Eric Lai --- src/mainboard/google/volteer/Kconfig | 4 ++++ .../volteer/variants/voema/overridetree.cb | 15 +++++++++++++++ .../volteer/variants/volteer/overridetree.cb | 16 ++++++++++++++++ .../volteer/variants/volteer2/overridetree.cb | 16 ++++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/src/mainboard/google/volteer/Kconfig b/src/mainboard/google/volteer/Kconfig index a32681d811..872d28540e 100644 --- a/src/mainboard/google/volteer/Kconfig +++ b/src/mainboard/google/volteer/Kconfig @@ -105,6 +105,7 @@ config BOARD_GOOGLE_TRONDO config BOARD_GOOGLE_VOEMA select BOARD_GOOGLE_BASEBOARD_VOLTEER + select DRIVERS_GFX_GENERIC select DRIVERS_INTEL_MIPI_CAMERA select INTEL_GMA_HAVE_VBT @@ -114,6 +115,7 @@ config BOARD_GOOGLE_VOLET config BOARD_GOOGLE_VOLTEER select BOARD_GOOGLE_BASEBOARD_VOLTEER + select DRIVERS_GFX_GENERIC select DRIVERS_INTEL_MIPI_CAMERA select INTEL_CAR_NEM select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES @@ -122,6 +124,7 @@ config BOARD_GOOGLE_VOLTEER2 select BOARD_GOOGLE_BASEBOARD_VOLTEER select DRIVER_I2C_TPM_ACPI select DRIVERS_GENESYSLOGIC_GL9755 + select DRIVERS_GFX_GENERIC select DRIVERS_INTEL_MIPI_CAMERA select INTEL_GMA_HAVE_VBT select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES @@ -130,6 +133,7 @@ config BOARD_GOOGLE_VOLTEER2_TI50 select BOARD_GOOGLE_BASEBOARD_VOLTEER select DRIVER_I2C_TPM_ACPI select DRIVERS_GENESYSLOGIC_GL9755 + select DRIVERS_GFX_GENERIC select DRIVERS_INTEL_MIPI_CAMERA select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES diff --git a/src/mainboard/google/volteer/variants/voema/overridetree.cb b/src/mainboard/google/volteer/variants/voema/overridetree.cb index ecb37987c7..6dce086fdc 100644 --- a/src/mainboard/google/volteer/variants/voema/overridetree.cb +++ b/src/mainboard/google/volteer/variants/voema/overridetree.cb @@ -9,6 +9,20 @@ chip soc/intel/tigerlake register "typec_aux_bias_pads[0]" = "{.pad_auxp_dc = GPP_E10, .pad_auxn_dc = GPP_E13}" device domain 0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + register "device[0].type" = "panel" + # IPUA for IPU camera + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + device generic 0 on end + end + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" @@ -80,6 +94,7 @@ chip soc/intel/tigerlake register "acpi_uid" = "0" register "acpi_name" = ""CAM1"" register "chip_name" = ""Ov 2740 Camera"" + register "sensor_name" = ""CJFLE23"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" diff --git a/src/mainboard/google/volteer/variants/volteer/overridetree.cb b/src/mainboard/google/volteer/variants/volteer/overridetree.cb index 21e6c63e55..9ffe08aa48 100644 --- a/src/mainboard/google/volteer/variants/volteer/overridetree.cb +++ b/src/mainboard/google/volteer/variants/volteer/overridetree.cb @@ -63,6 +63,20 @@ chip soc/intel/tigerlake probe DB_USB USB4_GEN3 end + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + register "device[0].type" = "panel" + # IPUA for IPU cameras + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + device generic 0 on end + end + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" @@ -185,6 +199,7 @@ chip soc/intel/tigerlake register "acpi_uid" = "0" register "acpi_name" = ""CAM1"" register "chip_name" = ""Ov 2740 Camera"" + register "sensor_name" = ""CJFLE23"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" register "low_power_probe" = "1" @@ -229,6 +244,7 @@ chip soc/intel/tigerlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" register "low_power_probe" = "1" diff --git a/src/mainboard/google/volteer/variants/volteer2/overridetree.cb b/src/mainboard/google/volteer/variants/volteer2/overridetree.cb index f27bb77f98..782ebcb4c1 100644 --- a/src/mainboard/google/volteer/variants/volteer2/overridetree.cb +++ b/src/mainboard/google/volteer/variants/volteer2/overridetree.cb @@ -117,6 +117,20 @@ chip soc/intel/tigerlake probe DB_USB USB4_GEN3 end + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + register "device[0].type" = "panel" + # IPUA for IPU cameras + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + device generic 0 on end + end + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" @@ -244,6 +258,7 @@ chip soc/intel/tigerlake register "acpi_uid" = "0" register "acpi_name" = ""CAM1"" register "chip_name" = ""Ov 2740 Camera"" + register "sensor_name" = ""CJFLE23"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" register "low_power_probe" = "1" @@ -288,6 +303,7 @@ chip soc/intel/tigerlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" register "low_power_probe" = "1" From ceaa41c9e47cc43278af2f0c6ba7612c204f5de1 Mon Sep 17 00:00:00 2001 From: Pranava Y N Date: Thu, 8 Jan 2026 13:15:23 +0530 Subject: [PATCH 125/789] drv/intel/mipi_camera: Verify SSDB only for camera sensors The MIPI camera driver currently validates SSDB parameters for all devices using the driver. However, some devices (VCM/NVM) does not have these parameters configured. Wrap the SSDB verification logic in a check for `INTEL_ACPI_CAMERA_SENSOR`. This prevents the driver from throwing "Parameters not set" errors and failing to create ACPI devices for non-sensor devices. BUG=b:474223827 TEST=Build and boot fatcat, verify that MIPI initialization no longer fails for non-sensor MIPI devices while still enforcing validation for actual camera sensors. Change-Id: I34ef416cdc9fa35fdca21e9fecaa8d7fc2914338 Signed-off-by: Pranava Y N Reviewed-on: https://review.coreboot.org/c/coreboot/+/90697 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/drivers/intel/mipi_camera/camera.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/drivers/intel/mipi_camera/camera.c b/src/drivers/intel/mipi_camera/camera.c index 1b2fc692d8..79c0616ccf 100644 --- a/src/drivers/intel/mipi_camera/camera.c +++ b/src/drivers/intel/mipi_camera/camera.c @@ -1219,10 +1219,19 @@ static struct device_operations camera_ops = { static void camera_enable(struct device *dev) { - //Validate Camera Parameters + /* Validate Camera Parameters */ struct drivers_intel_mipi_camera_config *config = dev->chip_info; bool params_error = false; + /* + * Non-sensor devices (like an aggregator) don't need + * SSDB validation, just assign ops and return. + */ + if (config->device_type != INTEL_ACPI_CAMERA_SENSOR) { + dev->ops = &camera_ops; + return; + } + if (!config->ssdb.lanes_used) { printk(BIOS_ERR, "MIPI camera: SSDB lanes_used not set\n"); params_error = true; From 5034f8629f646f713528a30353f96b83bd4b2a3e Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 29 Nov 2025 15:03:34 -0600 Subject: [PATCH 126/789] soc/intel/common: Add spinlock protection to fast SPI flash operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add spinlock synchronization to prevent concurrent SPI flash controller access from multiple CPUs in SMP environments. The spinlock serializes access to the SPI controller hardware in exec_sync_hwseq_xfer(). If SMP is not enabled, spinlock functions are no-ops, so this change is safe for both SMP and non-SMP configurations. This resolves an issue seen on the Starlabs Starfighter MTL where multiple SPI transaction errors occurred when reading option variables stored in SMMSTORE: [ERROR] SPI Transaction Error at Flash Offset 103002a HSFSTS = 0x01016022 [ERROR] SPI Transaction Error at Flash Offset 1030004 HSFSTS = 0x01006022 [ERROR] SPI Transaction Error at Flash Offset 1030000 HSFSTS = 0x3f006022 ... Change-Id: Ic3003b0a986b587622102b6f36714bcb16c3d976 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90283 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes Reviewed-by: Jérémy Compostella --- .../common/block/fast_spi/fast_spi_flash.c | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c index a7762711fa..89ae6d2cd3 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c +++ b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c @@ -9,6 +9,7 @@ #include #include #include +#include /* Helper to create a FAST_SPI context on API entry. */ #define BOILERPLATE_CREATE_CTX(ctx) \ @@ -32,6 +33,9 @@ struct fast_spi_flash_ctx { uintptr_t mmio_base; }; +/* Spinlock to protect concurrent SPI flash controller access from multiple CPUs */ +DECLARE_SPIN_LOCK(fast_spi_lock); + static void _fast_spi_flash_get_ctx(struct fast_spi_flash_ctx *ctx) { ctx->mmio_base = (uintptr_t)fast_spi_get_bar(); @@ -160,15 +164,28 @@ static int exec_sync_hwseq_xfer(struct fast_spi_flash_ctx *ctx, uint32_t hsfsts_cycle, uint32_t flash_addr, size_t len) { + int ret; + + /* Protect SPI flash controller from concurrent access by multiple CPUs. + * The spinlock serializes access to the SPI controller hardware. + * If SMP is not enabled, spinlock functions are no-ops. + */ + spin_lock(&fast_spi_lock); + if (wait_for_hwseq_spi_cycle_complete(ctx) != SUCCESS) { printk(BIOS_ERR, "SPI Transaction Timeout (Exceeded %d ms) due to prior" " operation at Flash Offset %x\n", SPIBAR_HWSEQ_XFER_TIMEOUT_MS, flash_addr); - return E_TIMEOUT; + ret = E_TIMEOUT; + goto unlock; } start_hwseq_xfer(ctx, hsfsts_cycle, flash_addr, len); - return wait_for_hwseq_xfer(ctx, flash_addr); + ret = wait_for_hwseq_xfer(ctx, flash_addr); + +unlock: + spin_unlock(&fast_spi_lock); + return ret; } int fast_spi_cycle_in_progress(void) From 16cb8d0d0c9b29322f646755c62a14ce29473a04 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Thu, 8 Jan 2026 16:41:02 +0530 Subject: [PATCH 127/789] mb/google/bluey: Add power sequencing for USB-C1 retimer This patch implements the power-on and reset sequence for the USB-C1 retimer on the Bluey mainboard. Sequence Details: - romstage: Added early_setup_usb_typec to ensure all power rails (3.3V, 1.8V, 0.9V) are disabled and the retimer is held in reset early in the boot process. - ramstage (mainboard): Added setup_usb_typec to perform the power-up sequence with the required 1ms delays between rails to ensure hardware stability: BUG=b:473489095 TEST=Able to detect USB devices in HS mode. Change-Id: Ia93c0078aecdec98f3af28e73e7af5af7a3b20d8 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90699 Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N Reviewed-by: Jayvik Desai Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/board.h | 6 ++++++ src/mainboard/google/bluey/mainboard.c | 14 ++++++++++++++ src/mainboard/google/bluey/romstage.c | 16 ++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/mainboard/google/bluey/board.h b/src/mainboard/google/bluey/board.h index 3260b283c7..3d42d89a48 100644 --- a/src/mainboard/google/bluey/board.h +++ b/src/mainboard/google/bluey/board.h @@ -44,6 +44,12 @@ #define GPIO_USB_CAM_RESET_L GPIO(10) #define GPIO_USB_CAM_ENABLE GPIO(206) +/* USB-C1 port specific GPIOs */ +#define GPIO_USB_C1_EN_PP3300 GPIO(186) +#define GPIO_USB_C1_EN_PP1800 GPIO(175) +#define GPIO_USB_C1_EN_PP0900 GPIO(188) +#define GPIO_USB_C1_RETIMER_RESET_L GPIO(176) + void setup_chromeos_gpios(void); bool is_off_mode(void); void configure_parallel_charging(void); diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index b93b4188db..b37c0b1e8a 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -50,8 +51,21 @@ static void enable_usb_camera(void) gpio_output(GPIO_USB_CAM_ENABLE, 1); } +static void setup_usb_typec(void) +{ + gpio_output(GPIO_USB_C1_EN_PP3300, 1); + mdelay(1); + gpio_output(GPIO_USB_C1_EN_PP1800, 1); + mdelay(1); + gpio_output(GPIO_USB_C1_EN_PP0900, 1); + mdelay(1); + gpio_output(GPIO_USB_C1_RETIMER_RESET_L, 1); +} + static void setup_usb(void) { + setup_usb_typec(); + enable_usb_camera(); setup_usb_host0(); } diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index 1c6660112e..e0f1f05743 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -86,6 +86,19 @@ static void platform_dump_battery_soc_information(void) printk(BIOS_INFO, "Battery state-of-charge %d%%\n", batt_pct); } +static void early_setup_usb_typec(void) +{ + gpio_output(GPIO_USB_C1_RETIMER_RESET_L, 0); + gpio_output(GPIO_USB_C1_EN_PP3300, 0); + gpio_output(GPIO_USB_C1_EN_PP1800, 0); + gpio_output(GPIO_USB_C1_EN_PP0900, 0); +} + +static void early_setup_usb(void) +{ + early_setup_usb_typec(); +} + void platform_romstage_main(void) { /* Watchdog must be checked first to avoid erasing watchdog info later. */ @@ -107,6 +120,9 @@ void platform_romstage_main(void) qclib_rerun(); + /* Setup early USB related config */ + early_setup_usb(); + /* * Enable this power rail now for FPMCU stability prior to * its reset being deasserted in ramstage. This applies From 17a52ce94e3c4878c38fbf4d1368a7954e1a07ad Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Fri, 9 Jan 2026 13:23:01 +0530 Subject: [PATCH 128/789] soc/qualcomm/x1p42100: Add mainboard USB Type-C config hook Add a function declaration for mainboard_usb_typec_configure. This allows mainboards to implement custom logic for external components, such as retimers or muxes, that need orientation-aware configuration. BUG=b:473489095 TEST=Verify USB SS detection on Quartz. Change-Id: I20d9a23da5b855a413f8358b8783f44c1632ccdf Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90709 Reviewed-by: Pranava Y N Reviewed-by: Subrata Banik Reviewed-by: Jayvik Desai Tested-by: build bot (Jenkins) --- src/soc/qualcomm/x1p42100/include/soc/usb/usb.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h b/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h index 250ae55c70..8284656cb8 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h +++ b/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h @@ -155,3 +155,5 @@ void usb_update_refclk_for_core(u32 core_num, bool enable); void enable_vbus_ss(const struct dwc3_controller_config *config); /* Reads comprehensive Type-C status from PMIC */ void usb_typec_status_check(const struct dwc3_controller_config *config); +/* Performs mainboard-specific USB Type-C configuration */ +void mainboard_usb_typec_configure(uint8_t port_num, bool inverse_polarity); From 657bcd32d9bfbb85cd55d2dec63f213de4cca303 Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Fri, 9 Jan 2026 13:25:22 +0530 Subject: [PATCH 129/789] mb/google/bluey: Add Kconfig for PS8820 retimer support Introduce the MAINBOARD_HAS_PS8820_RETIMER Kconfig option. This will be used to conditionally enable I2C initialization and retimer configuration logic on Bluey variants. BUG=b:473489095 TEST=Verify USB SS detection on Quartz. Change-Id: I949fb16f8c46a8375b50d2b108b8edde3231f4e9 Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90710 Reviewed-by: Subrata Banik Reviewed-by: Jayvik Desai Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N --- src/mainboard/google/bluey/Kconfig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mainboard/google/bluey/Kconfig b/src/mainboard/google/bluey/Kconfig index e5665ea752..7e21106cbc 100644 --- a/src/mainboard/google/bluey/Kconfig +++ b/src/mainboard/google/bluey/Kconfig @@ -91,6 +91,12 @@ config MAINBOARD_HAS_SD_CONTROLLER help Enable this option if your mainboard is equipped with SD card controller. +config MAINBOARD_HAS_PS8820_RETIMER + bool + default n + help + Enable this option if your mainboard is equipped with a PS8820 retimer. + config MAINBOARD_NO_USB_A_PORT bool default n From f9efe53cb0966e2b103c0a1d2e84893bf3a02233 Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Fri, 9 Jan 2026 13:27:03 +0530 Subject: [PATCH 130/789] mb/google/bluey: Implement PS8820 retimer configuration Implement mainboard_usb_typec_configure to program the Parade PS8820 retimers over I2C. The function sets the USB3 mode registers for either normal or flipped orientation based on the polarity reported by the SoC. Additionally, update mainboard_init to perform standard I2C initialization for the retimer buses when this feature is enabled, ensuring the buses are ready for transactions during the USB sequencing. BUG=b:473489095 TEST=Verify USB SS detection on Quartz. Sample output: ``` firmware-shell: md 0x0a800420 8 0a800420: 000002a0 00000000 00000000 00000000 ................ 0a800430: 00001203 00000000 00000000 00000000 ................ firmware-shell: md 0x0a600420 8 0a600420: 000002a0 00000000 00000000 00000000 ................ 0a600430: 00001203 00000000 00000000 00000000 ................ ``` Change-Id: I14f86945aeea9b83a9433edd53f5023231ca859d Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90707 Reviewed-by: Jayvik Desai Reviewed-by: Subrata Banik Reviewed-by: Pranava Y N Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/mainboard.c | 37 +++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index b37c0b1e8a..91c0f3dfad 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -8,16 +8,42 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include "board.h" #include #include +#define C0_RETIMER_I2C_BUS 0x03 +#define C1_RETIMER_I2C_BUS 0x07 +#define PS8820_SLAVE_ADDR 0x08 + +#define PS8820_USB_PORT_CONN_STATUS_REG 0x00 +#define USB3_MODE_NORMAL_VAL 0x21 +#define USB3_MODE_FLIP_VAL 0x23 + +void mainboard_usb_typec_configure(uint8_t port_num, bool inverse_polarity) +{ + if (!CONFIG(MAINBOARD_HAS_PS8820_RETIMER)) + return; + + /* There are only two ports (0 and 1) */ + if (port_num > 1) { + printk(BIOS_WARNING, "Invalid USB Type-C port number (%d)!\n", port_num); + return; + } + + uint8_t bus = port_num ? C1_RETIMER_I2C_BUS : C0_RETIMER_I2C_BUS; + uint8_t mode_value = inverse_polarity ? USB3_MODE_FLIP_VAL : USB3_MODE_NORMAL_VAL; + i2c_writeb(bus, PS8820_SLAVE_ADDR, PS8820_USB_PORT_CONN_STATUS_REG, mode_value); +} + /* * This function calls the underlying PMIC/EC function only once during the * first execution and caches the result for all subsequent calls. @@ -136,11 +162,14 @@ static void mainboard_init(struct device *dev) /* ADSP I2C (Charger/Fuel gauge) */ qupv3_se_fw_load_and_init(QUPV3_2_SE4, SE_PROTOCOL_I2C, GSI); - /* USB-C0 Re-Timer I2C */ - qupv3_se_fw_load_and_init(QUPV3_0_SE3, SE_PROTOCOL_I2C, MIXED); - /* USB-C1 Re-Timer I2C */ - qupv3_se_fw_load_and_init(QUPV3_0_SE7, SE_PROTOCOL_I2C, MIXED); + if (CONFIG(MAINBOARD_HAS_PS8820_RETIMER)) { + i2c_init(QUPV3_0_SE3, I2C_SPEED_FAST); /* USB-C0 Re-Timer I2C */ + i2c_init(QUPV3_0_SE7, I2C_SPEED_FAST); /* USB-C1 Re-Timer I2C */ + } else { + qupv3_se_fw_load_and_init(QUPV3_0_SE3, SE_PROTOCOL_I2C, MIXED); /* USB-C0 Re-Timer I2C */ + qupv3_se_fw_load_and_init(QUPV3_0_SE7, SE_PROTOCOL_I2C, MIXED); /* USB-C1 Re-Timer I2C */ + } if (!CONFIG(MAINBOARD_NO_USB_A_PORT)) qupv3_se_fw_load_and_init(QUPV3_0_SE1, SE_PROTOCOL_I2C, MIXED); /* USB-A retimer */ From e303357cb9ccba52d07d670970b3750186fe8033 Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Fri, 9 Jan 2026 13:28:53 +0530 Subject: [PATCH 131/789] soc/qualcomm/x1p42100: Call mainboard Type-C config hook Update the SoC USB driver to invoke mainboard_usb_typec_configure for both primary and secondary ports. This is called after the QMP PHY initialization to ensure the external signal path is correctly muxed for the detected orientation. BUG=b:473489095 TEST=Verify USB SS detection on Quartz. Sample output: ``` firmware-shell: md 0x0a800420 8 0a800420: 000002a0 00000000 00000000 00000000 ................ 0a800430: 00001203 00000000 00000000 00000000 ................ firmware-shell: md 0x0a600420 8 0a600420: 000002a0 00000000 00000000 00000000 ................ 0a600430: 00001203 00000000 00000000 00000000 ................ ``` Change-Id: Ic90a62b1f6ad62a8870c6d5333d06b6a11d26d4f Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90711 Reviewed-by: Pranava Y N Reviewed-by: Jayvik Desai Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/soc/qualcomm/x1p42100/usb/usb.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/soc/qualcomm/x1p42100/usb/usb.c b/src/soc/qualcomm/x1p42100/usb/usb.c index ec61ebd5be..5865a35d01 100644 --- a/src/soc/qualcomm/x1p42100/usb/usb.c +++ b/src/soc/qualcomm/x1p42100/usb/usb.c @@ -581,7 +581,8 @@ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) clock_reset_bcr(dwc3->gcc_usb4_0_dp0_phy_prim_bcr, 0); udelay(10); /* Initialize USB4/USB3 EDP_DP_Con PHY Configuration */ - int ss0_ret = qmp_usb4_dp_phy_ss_init(0, get_usb_typec_polarity(&prim_config)); + bool polarity_prim = get_usb_typec_polarity(&prim_config); + int ss0_ret = qmp_usb4_dp_phy_ss_init(0, polarity_prim); if (ss0_ret != CB_SUCCESS) { printk(BIOS_ERR, "SS0 QMP PHY initialization failed\n"); high_speed_only_primary = true; @@ -590,6 +591,7 @@ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) enable_vbus_ss(&prim_config); udelay(50); usb_typec_status_check(&prim_config); + mainboard_usb_typec_configure(0, polarity_prim); /* Type C port 1 - C1 */ /* Reset USB secondary[C1] PHY BCRs */ @@ -610,7 +612,8 @@ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) clock_reset_bcr(dwc3->gcc_usb4_1_dp0_phy_sec_bcr, 0); udelay(10); /* Initialize USB4/USB3 EDP_DP_Con PHY Configuration (secondary) */ - int ss1_ret = qmp_usb4_dp_phy_ss_init(1, get_usb_typec_polarity(&sec_config)); + bool polarity_sec = get_usb_typec_polarity(&sec_config); + int ss1_ret = qmp_usb4_dp_phy_ss_init(1, polarity_sec); if (ss1_ret != CB_SUCCESS) { printk(BIOS_ERR, "SS1 QMP PHY initialization failed\n"); high_speed_only_secondary = true; @@ -619,6 +622,7 @@ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) enable_vbus_ss(&sec_config); udelay(50); usb_typec_status_check(&sec_config); + mainboard_usb_typec_configure(1, polarity_sec); /* Initialize USB Controller for Type A */ setup_dwc3(dwc3->usb_host_dwc3); From c45e153dfbf3638816d257208d1a3f5bc4dba8f4 Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Fri, 9 Jan 2026 13:30:00 +0530 Subject: [PATCH 132/789] mb/google/bluey/var/quartz: Enable PS8820 support Select MAINBOARD_HAS_PS8820_RETIMER for the Quartz board variant. Quartz uses external PS8820 retimers that require explicit configuration to achieve SuperSpeed data rates. BUG=b:473489095 TEST=Verify USB SS detection on Quartz. Sample xHCI PORTSC register output: ``` firmware-shell: md 0x0a800420 8 0a800420: 000002a0 00000000 00000000 00000000 ................ 0a800430: 00001203 00000000 00000000 00000000 ................ firmware-shell: md 0x0a600420 8 0a600420: 000002a0 00000000 00000000 00000000 ................ 0a600430: 00001203 00000000 00000000 00000000 ................ ``` Change-Id: Ibb801adc5f7e874a403c644a5c1b3aa592a3d067 Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90712 Reviewed-by: Jayvik Desai Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N Reviewed-by: Subrata Banik --- src/mainboard/google/bluey/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/google/bluey/Kconfig b/src/mainboard/google/bluey/Kconfig index 7e21106cbc..163650702f 100644 --- a/src/mainboard/google/bluey/Kconfig +++ b/src/mainboard/google/bluey/Kconfig @@ -56,6 +56,7 @@ config BOARD_GOOGLE_QUENBIH config BOARD_GOOGLE_QUARTZ select BOARD_GOOGLE_MODEL_QUARTZ select SOC_QUALCOMM_HAMOA + select MAINBOARD_HAS_PS8820_RETIMER select MAINBOARD_NO_USB_A_PORT select MAINBOARD_SUPPORTS_PARALLEL_CHARGING From 18a986c5fe63a5e801e9cdd493a903d588312a0a Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Tue, 26 Aug 2025 02:17:56 +0200 Subject: [PATCH 133/789] soc/amd/cmn/block/cpu/mca: Support MCA_SYND1 and MCA_SYND2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The number of MCAX register used inside an MCA BANK changed from phoenix onwards. Since phoenix all 16 MCAX register are used inside an MCA bank. According to spec: The MCA_SYND register stores a syndrome associated with the error logged in MCA_STATUS or MCA_DESTAT. The “syndrome” may include syndrome values associated with an error correcting code or other information about the error. The contents of this register are valid if MCA_STATUS[SYNDV] bit is set to 1 or MCA_DESTAT[SYNDV] bit is set to 1. source: AMD64 Architecture Programmers Manual Rev 3.42 Change-Id: I20a31776d4b031c810ef0dc6502c421ade6f4315 Signed-off-by: Maximilian Brune Reviewed-on: https://review.coreboot.org/c/coreboot/+/90640 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/soc/amd/common/block/cpu/mca/mcax.c | 10 ++++++++-- src/soc/amd/common/block/cpu/mca/mcax_bert.c | 15 +++++++-------- .../amd/common/block/include/amdblocks/msr_zen.h | 5 +++++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/soc/amd/common/block/cpu/mca/mcax.c b/src/soc/amd/common/block/cpu/mca/mcax.c index 46c72f00a8..ad4f67e47d 100644 --- a/src/soc/amd/common/block/cpu/mca/mcax.c +++ b/src/soc/amd/common/block/cpu/mca/mcax.c @@ -20,14 +20,14 @@ bool mca_skip_check(void) /* Print the contents of the MCAX registers for a given bank */ void mca_print_error(unsigned int bank) { - msr_t msr; + msr_t msr, mca_status; printk(BIOS_WARNING, "#MC Error: core %u, bank %u %s\n", initial_lapicid(), bank, mca_get_bank_name(bank)); msr = rdmsr(MCAX_CTL_MSR(bank)); printk(BIOS_WARNING, " MC%u_CTL = %08x_%08x\n", bank, msr.hi, msr.lo); - msr = rdmsr(MCAX_STATUS_MSR(bank)); + msr = mca_status = rdmsr(MCAX_STATUS_MSR(bank)); printk(BIOS_WARNING, " MC%u_STATUS = %08x_%08x\n", bank, msr.hi, msr.lo); msr = rdmsr(MCAX_ADDR_MSR(bank)); printk(BIOS_WARNING, " MC%u_ADDR = %08x_%08x\n", bank, msr.hi, msr.lo); @@ -51,6 +51,12 @@ void mca_print_error(unsigned int bank) printk(BIOS_WARNING, " MC%u_MISC3 = %08x_%08x\n", bank, msr.hi, msr.lo); msr = rdmsr(MCAX_MISC4_MSR(bank)); printk(BIOS_WARNING, " MC%u_MISC4 = %08x_%08x\n", bank, msr.hi, msr.lo); + if (mca_syndv(mca_status)) { + msr = rdmsr(MCAX_SYND1_MSR(bank)); + printk(BIOS_WARNING, " MC%u_SYND1 = %08x_%08x\n", bank, msr.hi, msr.lo); + msr = rdmsr(MCAX_SYND2_MSR(bank)); + printk(BIOS_WARNING, " MC%u_SYND2 = %08x_%08x\n", bank, msr.hi, msr.lo); + } msr = rdmsr(MCA_CTL_MASK_MSR(bank)); printk(BIOS_WARNING, " MC%u_CTL_MASK = %08x_%08x\n", bank, msr.hi, msr.lo); } diff --git a/src/soc/amd/common/block/cpu/mca/mcax_bert.c b/src/soc/amd/common/block/cpu/mca/mcax_bert.c index af2bee407d..80ee534f45 100644 --- a/src/soc/amd/common/block/cpu/mca/mcax_bert.c +++ b/src/soc/amd/common/block/cpu/mca/mcax_bert.c @@ -10,10 +10,7 @@ #include #include "mca_common_defs.h" -/* MISC4 is the last used register in the MCAX banks of Picasso */ -#define MCAX_USED_REGISTERS_PER_BANK (MCAX_MISC4_OFFSET + 1) - -static inline size_t mca_report_size_reqd(void) +static inline size_t mca_report_size_reqd(int used_registers_per_bank) { size_t size; @@ -32,8 +29,8 @@ static inline size_t mca_report_size_reqd(void) size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, 3); /* Context of CTL, STATUS, ADDR, MISC0, CONFIG, IPID, SYND, RESERVED, DESTAT, DEADDR, - MISC1, MISC2, MISC3, MISC4 */ - size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, MCAX_USED_REGISTERS_PER_BANK); + MISC1, MISC2, MISC3, MISC4, SYND0, SYND1 */ + size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, used_registers_per_bank); /* Context of CTL_MASK */ size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, 1); @@ -57,7 +54,9 @@ void build_bert_mca_error(struct mca_bank_status *mci) cper_ia32x64_proc_error_info_t *chk; cper_ia32x64_context_t *ctx; - if (mca_report_size_reqd() > bert_storage_remaining()) + int used_registers_per_bank = mca_syndv(mci->sts) ? 16 : 14; + + if (mca_report_size_reqd(used_registers_per_bank) > bert_storage_remaining()) goto failed; status = bert_new_event(&CPER_SEC_PROC_GENERIC_GUID); @@ -80,7 +79,7 @@ void build_bert_mca_error(struct mca_bank_status *mci) if (!ctx) goto failed; ctx = cper_new_ia32x64_context_msr(status, x86_sec, MCAX_CTL_MSR(mci->bank), - MCAX_USED_REGISTERS_PER_BANK); + used_registers_per_bank); if (!ctx) goto failed; ctx = cper_new_ia32x64_context_msr(status, x86_sec, MCA_CTL_MASK_MSR(mci->bank), 1); diff --git a/src/soc/amd/common/block/include/amdblocks/msr_zen.h b/src/soc/amd/common/block/include/amdblocks/msr_zen.h index 0e2d2c8fec..cde4d7bdda 100644 --- a/src/soc/amd/common/block/include/amdblocks/msr_zen.h +++ b/src/soc/amd/common/block/include/amdblocks/msr_zen.h @@ -24,6 +24,9 @@ #define MCAX_MISC2_OFFSET 0xb #define MCAX_MISC3_OFFSET 0xc #define MCAX_MISC4_OFFSET 0xd +#define MCAX_SYND1_OFFSET 0xe +#define MCAX_SYND2_OFFSET 0xf + #define MCAX_MSR(bank, offset) (MCAX_MSR_BASE + (bank) * MCAX_BANK_SIZE + (offset)) #define MCAX_CTL_MSR(bank) MCAX_MSR(bank, MCAX_CTL_OFFSET) #define MCAX_STATUS_MSR(bank) MCAX_MSR(bank, MCAX_STATUS_OFFSET) @@ -38,6 +41,8 @@ #define MCAX_MISC2_MSR(bank) MCAX_MSR(bank, MCAX_MISC2_OFFSET) #define MCAX_MISC3_MSR(bank) MCAX_MSR(bank, MCAX_MISC3_OFFSET) #define MCAX_MISC4_MSR(bank) MCAX_MSR(bank, MCAX_MISC4_OFFSET) +#define MCAX_SYND1_MSR(bank) MCAX_MSR(bank, MCAX_SYND1_OFFSET) +#define MCAX_SYND2_MSR(bank) MCAX_MSR(bank, MCAX_SYND2_OFFSET) /* * The MCA CTL_MASK moved to a new location in the fam 17h+ CPUs and accessing the legacy From e705c3900967713cb315d720056506028bb1542d Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Thu, 8 Jan 2026 22:23:24 +0800 Subject: [PATCH 134/789] libpayload/arch/arm64/mmu: Add CB_MEM_TAG to usedmem_ranges CB_MEM_TAG is considered as an reserved memory. But we want to mange this region in the payload and release this region when MTE is inactive. Add CB_MEM_TAG memory range to usedmem_ranges to get a page table mapping and mark it as used. BUG=b:438666196,b:474306129 TEST=Check the tag region is wiped out in DEV mode. Change-Id: I498407cbd44b1cc70ef769a63b8e40665ea67b28 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90702 Reviewed-by: Julius Werner Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- payloads/libpayload/arch/arm64/mmu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/payloads/libpayload/arch/arm64/mmu.c b/payloads/libpayload/arch/arm64/mmu.c index e99fa37c5d..0b7d206a58 100644 --- a/payloads/libpayload/arch/arm64/mmu.c +++ b/payloads/libpayload/arch/arm64/mmu.c @@ -611,6 +611,7 @@ static void mmu_extract_ranges(struct memrange *cb_ranges, switch (cb_ranges[i].type) { case CB_MEM_TABLE: + case CB_MEM_TAG: /* Mark this memrange as used memory */ if (mmu_add_memrange(&usedmem_ranges, base, size, TYPE_NORMAL_MEM) == NULL) From 292d7b9d3d4ccf852a9c20b8fafb5663bff7ff56 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Thu, 8 Jan 2026 15:08:32 +0000 Subject: [PATCH 135/789] Revert "soc/mediatek/mt8196: Call fsp_init via boot state" This reverts commit 14a7a2315e722ef83b567d1918d7990eb83a451c. Reason for revert: The change causes DUT failed to resume from S3. BUG=b:474254985 TEST=Wake up DUT by power key. Change-Id: I2f2291a12d9b440d000a28e38bb590bc77a02c8a Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90703 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu Reviewed-by: Chen-Tsung Hsieh --- src/soc/mediatek/mt8196/soc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/soc/mediatek/mt8196/soc.c b/src/soc/mediatek/mt8196/soc.c index e988a76926..24077a0fbc 100644 --- a/src/soc/mediatek/mt8196/soc.c +++ b/src/soc/mediatek/mt8196/soc.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include -#include #include #include #include @@ -57,7 +56,7 @@ static void mte_setup(void) booker_mte_init(mte_start); } -static void fsp_init(void *arg) +static void fsp_init(void) { uint32_t storage_type = mainboard_get_storage_type(); @@ -68,8 +67,6 @@ static void fsp_init(void *arg) mtk_fsp_load_and_run(); } -BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, fsp_init, NULL); - static void soc_init(struct device *dev) { mtk_mmu_disable_l2c_sram(); @@ -79,6 +76,7 @@ static void soc_init(struct device *dev) if (spm_init()) printk(BIOS_ERR, "spm init failed, Suspend may not work\n"); + fsp_init(); sspm_init(); gpueb_init(); mcupm_init(); From c421847fe2fef61586eb313206a4be0f2e491974 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 29 Dec 2025 10:12:17 -0600 Subject: [PATCH 136/789] util/crossgcc: Fix GNAT detection for gnat-15 GCC's configure script requires gnat1, gnatbind, and gnatmake to be available as unversioned executables in PATH when building with Ada support. The previous detection logic only checked for gnat1 and used a lenient searchtool check for gnatbind, which could incorrectly enable Ada support when gnatmake was missing, causing configure to fail with "GNAT is required to build ada". In GNAT 15+, tools may only be available as versioned executables (e.g., gnatbind-15, gnatmake-15), but GCC configure still requires unversioned names. This change: 1. Adds explicit checks for gnatbind and gnatmake (unversioned) 2. Updates have_gnat() to require all three tools 3. Detects GNAT 15+ versioned tools and provides helpful error messages with instructions to create symlinks 4. Falls back to generic installation instructions if no GNAT tools are found This prevents the configure error and provides clear guidance for users with GNAT 15+ installations. Change-Id: Idc16ec48612e88fc9bdd16b343ae267aa20490f3 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90635 Tested-by: build bot (Jenkins) Reviewed-by: David Hendricks --- util/crossgcc/buildgcc | 93 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc index cf4a8d6bce..be5493d16f 100755 --- a/util/crossgcc/buildgcc +++ b/util/crossgcc/buildgcc @@ -331,9 +331,38 @@ hostcc_has_gnat1() { [ -x "$(${CC} -print-prog-name=gnat1)" ] } +hostcc_has_gnatbind() { + # GCC configure requires unversioned gnatbind in PATH + # In GNAT 15+, tools may only be available as versioned (e.g., gnatbind-15) + # Check for unversioned first (required by configure) + if command -v gnatbind >/dev/null 2>&1; then + return 0 + fi + + # If only versioned tools exist, configure will fail + # So we return false to prevent Ada from being enabled + return 1 +} + +hostcc_has_gnatmake() { + # GCC configure requires unversioned gnatmake in PATH + # In GNAT 15+, tools may only be available as versioned (e.g., gnatmake-15) + # Check for unversioned first (required by configure) + if command -v gnatmake >/dev/null 2>&1; then + return 0 + fi + + # If only versioned tools exist, configure will fail + # So we return false to prevent Ada from being enabled + return 1 +} + have_gnat() { - hostcc_has_gnat1 && \ - searchtool gnatbind "Free Software Foundation" nofail > /dev/null + # Require all GNAT tools that configure needs + # Configure checks for gnatbind and gnatmake (unversioned names) + # Even though GNAT 15+ may only provide versioned tools or use gcc -b, + # the configure script still requires the unversioned names + hostcc_has_gnat1 && hostcc_has_gnatbind && hostcc_has_gnatmake } ada_requested() { @@ -1235,23 +1264,51 @@ if [ -z "${LANGUAGES}" ]; then printf "\nFound compatible Ada compiler, enabling Ada support by default.\n\n" LANGUAGES="ada,${DEFAULT_LANGUAGES}" else + # Check if versioned tools exist (GNAT 15+) + gcc_version=$(${CC} -dumpversion 2>/dev/null | cut -d. -f1) + gnatbind_ver="" + gnatmake_ver="" + gnatbind_path="" + gnatmake_path="" + if [ -n "$gcc_version" ]; then + gnatbind_ver="gnatbind-${gcc_version}" + gnatmake_ver="gnatmake-${gcc_version}" + gnatbind_path=$(command -v "$gnatbind_ver" 2>/dev/null) + gnatmake_path=$(command -v "$gnatmake_ver" 2>/dev/null) + fi + printf "\n${red}WARNING${NC}\n" - printf "No compatible Ada compiler (GNAT) found. You can continue without\n" - printf "Ada support, but this will limit the features of ${blue}coreboot${NC} (e.g.\n" - printf "native graphics initialization won't be available on most Intel\n" - printf "boards).\n\n" - - printf "Usually, you can install GNAT with your package management system\n" - printf "(the package is called \`gnat\` or \`gcc-ada\`). It has to match the\n" - printf "\`gcc\` package in version. If there are multiple versions of GCC in-\n" - printf "stalled, you can point this script to the matching version through\n" - printf "the \`CC\` and \`CXX\` environment variables.\n\n" - - printf "e.g. on Ubuntu 14.04, if \`gcc\` is \`gcc-4.8\`:\n" - printf " apt-get install gnat-4.8 && make crossgcc\n\n" - - printf "on Ubuntu 16.04, if \`gcc\` is \`gcc-5\`:\n" - printf " apt-get install gnat-5 && make crossgcc\n" + if [ -n "$gnatbind_path" ] || [ -n "$gnatmake_path" ]; then + printf "GNAT tools are only available as versioned executables (e.g., %s, %s),\n" \ + "${gnatbind_ver:-gnatbind-N}" "${gnatmake_ver:-gnatmake-N}" + printf "but GCC configure requires unversioned names (gnatbind, gnatmake).\n\n" + printf "To enable Ada support, create symlinks or install the unversioned tools:\n" + if [ -n "$gnatbind_path" ]; then + printf " sudo ln -s %s /usr/local/bin/gnatbind\n" "$gnatbind_path" + fi + if [ -n "$gnatmake_path" ]; then + printf " sudo ln -s %s /usr/local/bin/gnatmake\n" "$gnatmake_path" + fi + printf "\nAlternatively, disable Ada support by setting BUILD_LANGUAGES=c:\n" + printf " make crossgcc-i386 BUILD_LANGUAGES=c\n\n" + else + printf "No compatible Ada compiler (GNAT) found. You can continue without\n" + printf "Ada support, but this will limit the features of ${blue}coreboot${NC} (e.g.\n" + printf "native graphics initialization won't be available on most Intel\n" + printf "boards).\n\n" + + printf "Usually, you can install GNAT with your package management system\n" + printf "(the package is called \`gnat\` or \`gcc-ada\`). It has to match the\n" + printf "\`gcc\` package in version. If there are multiple versions of GCC in-\n" + printf "stalled, you can point this script to the matching version through\n" + printf "the \`CC\` and \`CXX\` environment variables.\n\n" + + printf "e.g. on Ubuntu 14.04, if \`gcc\` is \`gcc-4.8\`:\n" + printf " apt-get install gnat-4.8 && make crossgcc\n\n" + + printf "on Ubuntu 16.04, if \`gcc\` is \`gcc-5\`:\n" + printf " apt-get install gnat-5 && make crossgcc\n" + fi timeout 30 LANGUAGES="${DEFAULT_LANGUAGES}" fi From 95ad0282740ea01983e623b4d2e4a882375e0942 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 9 Jan 2026 09:59:31 -0600 Subject: [PATCH 137/789] drivers/smmstore: Use lookup_store() for memory-mapped reads The smmstore_lookup_region() function was using fmap_locate_area_as_rdev_rw() directly, which only provides direct SPI access. This bypassed the optimized lookup_store() function that uses incoherent_rdev to enable memory-mapped reads via the read-only device while keeping direct SPI writes via the read-write device. Change smmstore_lookup_region() to call lookup_store() instead, enabling memory-mapped reads for the public API and matching the behavior of the internal implementation. This improves read performance for EFI options and other consumers of the SMMSTORE region device. It also fixes an issue where direct SPI reads were crossing 4k page boundaries on older platforms (Broadwell and earlier) causing them to fail and the fallback option to be used, leading to a disconnect between the user-selected option and device beahvior. TEST=build/boot google/guado, verify all CFR options work properly and no errors in cbmem. Change-Id: I34947be932ede19a3fe896fe0da6373035fe6db7 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90717 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/drivers/smmstore/store.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/smmstore/store.c b/src/drivers/smmstore/store.c index 35887b3c7f..fa4c1e1b51 100644 --- a/src/drivers/smmstore/store.c +++ b/src/drivers/smmstore/store.c @@ -134,7 +134,7 @@ int smmstore_lookup_region(struct region_device *rstore) if (!done) { done = 1; - if (fmap_locate_area_as_rdev_rw(SMMSTORE_REGION, &rdev)) { + if (lookup_store(&rdev)) { printk(BIOS_WARNING, "smm store: Unable to find SMM store FMAP region '%s'\n", SMMSTORE_REGION); From 8bc1372f72dc9ee83bf37e3a31377462ba8aa66d Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Tue, 6 Jan 2026 15:55:59 -0600 Subject: [PATCH 138/789] sb/intel/common/spi: Prevent transfers across 4KiB boundaries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ICH SPI controller fails when a single transfer spans a 4KiB boundary. Limit data_length in spi_ctrlr_xfer() to stay within the current 4KiB page when with_address is true, avoiding the hardware limitation at the platform driver level. This fixes SPI read errors observed on SandyBridge, IvyBridge, Haswell, and Broadwell when reading option variables stored in SMMSTORE. When scanning the store to locate a given variable, reads would often cross into the next 4KiB page (eg, reading 60 bytes from 0x313ff0). TEST=build/boot stumpy, link, beltino, jecht boards, verify no SPI read errors in cbmem, CFR options work properly. Change-Id: I73d9c0acdbbb2faf5caff1f73049bff900774156 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90689 Reviewed-by: Patrick Rudolph Reviewed-by: Angel Pons Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) --- src/southbridge/intel/common/spi.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index 068062bae0..bcdcaa9158 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -619,14 +619,28 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, */ while (trans.bytesout || trans.bytesin) { uint32_t data_length; + uint32_t max_length; /* SPI addresses are 24 bit only */ writel_(trans.offset & 0x00FFFFFF, cntlr.addr); if (trans.bytesout) - data_length = MIN(trans.bytesout, cntlr.databytes); + max_length = MIN(trans.bytesout, cntlr.databytes); else - data_length = MIN(trans.bytesin, cntlr.databytes); + max_length = MIN(trans.bytesin, cntlr.databytes); + + /* + * Avoid transfers that cross 4KiB boundaries. The ICH SPI controller + * has been observed to fail on some platforms when a single transfer + * spans a 4KiB boundary (e.g., offset 0x...3ff0, len 0x3c crosses 0x...4000). + */ + if (with_address) { + uint32_t off_in_4k = trans.offset & 0xfff; + uint32_t max_to_boundary = 0x1000 - off_in_4k; + data_length = MIN(max_length, max_to_boundary); + } else { + data_length = max_length; + } /* Program data into FDATA0 to N */ if (trans.bytesout) { From a3a556f05d3005b73871b196f6cb9c837d43095b Mon Sep 17 00:00:00 2001 From: Luca Lai Date: Fri, 5 Dec 2025 10:05:37 +0800 Subject: [PATCH 139/789] mb/google/fatcat/var/ruby: Add wifi SAR table Based on the WiFi firmware configuration to add function for getting WiFi SAR cbfs filename. BUG=b:460231264 TEST=Build and check the system could boot to OS, and check the SAR table could work fine. Change-Id: Ieec65debdc9f506e779352fcf8e54daa9296c0f7 Signed-off-by: Luca Lai Reviewed-on: https://review.coreboot.org/c/coreboot/+/90376 Reviewed-by: Derek Huang Reviewed-by: Subrata Banik Reviewed-by: YH Lin Tested-by: build bot (Jenkins) --- src/mainboard/google/fatcat/variants/ruby/Makefile.mk | 3 ++- .../google/fatcat/variants/ruby/overridetree.cb | 4 ++++ src/mainboard/google/fatcat/variants/ruby/variant.c | 11 +++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/mainboard/google/fatcat/variants/ruby/variant.c diff --git a/src/mainboard/google/fatcat/variants/ruby/Makefile.mk b/src/mainboard/google/fatcat/variants/ruby/Makefile.mk index 6c0a1ae6fb..36616963a3 100644 --- a/src/mainboard/google/fatcat/variants/ruby/Makefile.mk +++ b/src/mainboard/google/fatcat/variants/ruby/Makefile.mk @@ -1,8 +1,9 @@ -## SPDX-License-Identifier: GPL-2.0-only +/* SPDX-License-Identifier: GPL-2.0-only */ bootblock-y += gpio.c romstage-y += gpio.c romstage-y += memory.c romstage-$(CONFIG_FW_CONFIG) += fw_config.c ramstage-y += gpio.c +ramstage-$(CONFIG_FW_CONFIG) += variant.c ramstage-$(CONFIG_FW_CONFIG) += fw_config.c diff --git a/src/mainboard/google/fatcat/variants/ruby/overridetree.cb b/src/mainboard/google/fatcat/variants/ruby/overridetree.cb index c85b2b13c5..e643ee9fae 100644 --- a/src/mainboard/google/fatcat/variants/ruby/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/ruby/overridetree.cb @@ -39,6 +39,10 @@ fw_config option KB_BACKLIGHT_ABSENT 0 option KB_BACKLIGHT_PRESENT 1 end + field AP_OEM_3BIT_FIELD0 56 58 + option WIFI_SAR_ID0 0 + option WIFI_SAR_ID1 1 + end end chip soc/intel/pantherlake diff --git a/src/mainboard/google/fatcat/variants/ruby/variant.c b/src/mainboard/google/fatcat/variants/ruby/variant.c new file mode 100644 index 0000000000..8fdfd4b812 --- /dev/null +++ b/src/mainboard/google/fatcat/variants/ruby/variant.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +const char *get_wifi_sar_cbfs_filename(void) +{ + return get_wifi_sar_fw_config_filename(FW_CONFIG_FIELD(AP_OEM_3BIT_FIELD0)); +} From a5c0307e9c8aeb613028c0790c4c10aa8e48fb4c Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Fri, 9 Jan 2026 14:35:42 +0530 Subject: [PATCH 140/789] commonlib/device_tree: Add dt_add_reserved_memory_region helper Introduce a centralized helper function, dt_add_reserved_memory_region, to simplify the creation of sub-nodes under /reserved-memory. Currently, various features (such as pKVM, ramoops, and platform- specific firmware reservations) manually handle the creation of reserved memory nodes. This involves repetitive logic for: - Navigating or creating the /reserved-memory parent path. - Calculating cell sizes for 'reg' properties. - Manually adding 'no-map' or 'compatible' properties. This helper abstracts those steps into a single call, reducing boilerplate and the risk of cell-size mismatches across the codebase. The function handles: - Node creation if the path doesn't exist. - Optional 'compatible' string assignment. - Automatic 'reg' property generation using appropriate address/size cells. - Optional 'no-map' property assignment via a boolean flag. Change-Id: Ie58f5fdcfd1863b41c177b63ed9fc25d6d220e3a Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90713 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/commonlib/device_tree.c | 29 +++++++++++++++++++ src/commonlib/include/commonlib/device_tree.h | 15 ++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/commonlib/device_tree.c b/src/commonlib/device_tree.c index b51f9fc31d..7d5161db23 100644 --- a/src/commonlib/device_tree.c +++ b/src/commonlib/device_tree.c @@ -2166,3 +2166,32 @@ bool dt_is_overlay(struct device_tree *tree) return false; } + +struct device_tree_node *dt_add_reserved_memory_region(struct device_tree *tree, + const char *name, const char *compatible, uint64_t addr, uint64_t size, + bool nomap) +{ + uint32_t addr_cells, size_cells; + const char *path[] = { "reserved-memory", name, NULL }; + + /* Find or create the node. Using 1 for the 'create' argument. */ + struct device_tree_node *node = dt_find_node(tree->root, path, + &addr_cells, &size_cells, 1); + if (!node) { + printk(BIOS_ERR, "Failed to create reserved-memory node: %s\n", name); + return NULL; + } + + /* Add the compatible string if provided */ + if (compatible) + dt_add_string_prop(node, "compatible", compatible); + + /* Always add the reg property */ + dt_add_reg_prop(node, &addr, &size, 1, addr_cells, size_cells); + + /* Add no-map if requested */ + if (nomap) + dt_add_bin_prop(node, "no-map", NULL, 0); + + return node; +} diff --git a/src/commonlib/include/commonlib/device_tree.h b/src/commonlib/include/commonlib/device_tree.h index b6004fe8c4..ec4b4ffd29 100644 --- a/src/commonlib/include/commonlib/device_tree.h +++ b/src/commonlib/include/commonlib/device_tree.h @@ -237,4 +237,19 @@ struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree); /* Check whether a devicetree is an overlay device tree */ bool dt_is_overlay(struct device_tree *tree); +/* + * dt_add_reserved_memory_region - Helper to add a node under `/reserved-memory` + * @tree: The device tree structure + * @name: Name of the child node (e.g., "ramoops", "pkvm-drng-seed") + * @compatible: Compatible string (optional, pass NULL if not needed) + * @addr: Physical start address + * @size: Size of the region + * @nomap: Boolean, if true adds the "no-map" property + * + * Returns the created node on success, NULL on failure. + */ +struct device_tree_node *dt_add_reserved_memory_region(struct device_tree *tree, + const char *name, const char *compatible, uint64_t addr, uint64_t size, + bool nomap); + #endif /* __COMMONLIB_DEVICE_TREE_H__ */ From 9f4132712f2ab22011837a4cc5c4f26a4ba9ddb3 Mon Sep 17 00:00:00 2001 From: Jamie Chen Date: Tue, 6 Jan 2026 16:20:57 +0800 Subject: [PATCH 141/789] soc/intel/alderlake: add chipsetinit support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Intel chipsetinit.bin is for PCH modphy initialize. Add code to read chipsetinit.bin from CBFS and fill UPD params. BUG=b:447290550 TEST=1. build coreboot 2. check log to confirm load chipsetinit.bin successfully. Change-Id: I65740f52c779daeea1a27a9e078336daee29cf3b Signed-off-by: Jamie Chen Reviewed-on: https://review.coreboot.org/c/coreboot/+/90687 Reviewed-by: Simon Yang Tested-by: build bot (Jenkins) Reviewed-by: Kao, Ben Reviewed-by: Jérémy Compostella --- src/soc/intel/alderlake/Kconfig | 13 +++++++++++++ src/soc/intel/alderlake/fsp_params.c | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 97c2ecca70..34c9baf544 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -396,6 +396,19 @@ config CONSOLE_CBMEM_BUFFER_SIZE default 0x100000 if BUILDING_WITH_DEBUG_FSP default 0x40000 +config CHIPSETINIT_CBFS_FILE + string + depends on HAVE_CHIPSETINIT_BINARY + default "chipsetinit.bin" + help + Name of the Chipset Initialization binary on the CBFS + +config HAVE_CHIPSETINIT_BINARY + bool + default n + help + Select this option if you want to load the Chipset Initialization binary + config FSP_TYPE_IOT bool default n diff --git a/src/soc/intel/alderlake/fsp_params.c b/src/soc/intel/alderlake/fsp_params.c index bd6f1d548a..396ea53c5a 100644 --- a/src/soc/intel/alderlake/fsp_params.c +++ b/src/soc/intel/alderlake/fsp_params.c @@ -664,6 +664,22 @@ static void fill_fsps_tcss_params(FSP_S_CONFIG *s_cfg, s_cfg->Usb4CmMode = CONFIG(SOFTWARE_CONNECTION_MANAGER); } +#if CONFIG(HAVE_CHIPSETINIT_BINARY) +static void fill_fsps_chipsetinit_params(FSP_S_CONFIG *s_cfg, + const struct soc_intel_alderlake_config *config) +{ + void *data; + size_t size; + + data = cbfs_map(CONFIG_CHIPSETINIT_CBFS_FILE, &size); + if (!data || size == 0) + return; + + s_cfg->ChipsetInitBinPtr = (uint32_t)(uintptr_t)data; + s_cfg->ChipsetInitBinLen = (uint32_t)size; +} +#endif + static void fill_fsps_chipset_lockdown_params(FSP_S_CONFIG *s_cfg, const struct soc_intel_alderlake_config *config) { @@ -1284,6 +1300,9 @@ static void soc_silicon_init_params(FSP_S_CONFIG *s_cfg, fill_fsps_cpu_params, fill_fsps_igd_params, fill_fsps_tcss_params, +#if CONFIG(HAVE_CHIPSETINIT_BINARY) + fill_fsps_chipsetinit_params, +#endif fill_fsps_chipset_lockdown_params, fill_fsps_xhci_params, fill_fsps_xdci_params, From 3c3fbbaabf68781ef6422b846928601f07580aee Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Mon, 29 Dec 2025 22:10:13 +0100 Subject: [PATCH 142/789] arch/x86/acpi_bert_storage.c: Remove unused variable Signed-off-by: Maximilian Brune Change-Id: I7fb8486f265be071fd59267ce120256c183d8dd6 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90693 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Felix Held --- src/arch/x86/acpi_bert_storage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/acpi_bert_storage.c b/src/arch/x86/acpi_bert_storage.c index 321f66ac54..902ddb7da5 100644 --- a/src/arch/x86/acpi_bert_storage.c +++ b/src/arch/x86/acpi_bert_storage.c @@ -513,10 +513,10 @@ acpi_generic_error_status_t *bert_new_event(guid_t *guid) { size_t size; acpi_generic_error_status_t *status; - acpi_hest_generic_data_v300_t *entry, *r; + acpi_hest_generic_data_v300_t *r; size = sizeof(*status); - size += sizeof(*entry); + size += sizeof(*r); size += sizeof_error_section(guid); if (size > bert_storage_remaining()) { From f00a2ff7b88eacc86b1c0015e806cb846887daa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 6 Oct 2025 10:45:59 +0200 Subject: [PATCH 143/789] arch/x86/ioapic.c: Support 8-bit IOAPIC IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AMD systems support 8-bit IOAPIC IDs. Some silicon initialization code modules, like OpenSIL, may allocate an 8-bit ID by default. To respect that configuration or set ID properly in coreboot, whole 8-bit ID field has to be cleared and set. Add new IOAPIC_8BIT_ID Kconfig option to allow setting 8-bit long IOAPIC IDs. TEST=Set IOAPIC IDs starting with 240 on Gigabyte MZ33-AR1. Change-Id: Ie85b2272b0bc64a95d76c5677816941f1334901d Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/89476 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/Kconfig | 7 +++++++ src/arch/x86/ioapic.c | 12 ++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Kconfig b/src/Kconfig index 6c59e4fa5b..ec7dde2e53 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -919,6 +919,13 @@ config IOAPIC default y if SMP default n +config IOAPIC_8BIT_ID + bool + default n + depends on IOAPIC + help + Select this option if the hardware support 8bit long IOAPIC IDs. + config USE_WATCHDOG_ON_BOOT bool default n diff --git a/src/arch/x86/ioapic.c b/src/arch/x86/ioapic.c index 4cde7c7f51..792ba3e65e 100644 --- a/src/arch/x86/ioapic.c +++ b/src/arch/x86/ioapic.c @@ -129,13 +129,21 @@ static void route_i8259_irq0(uintptr_t ioapic_base) static void set_ioapic_id(uintptr_t ioapic_base, u8 ioapic_id) { int i; + u32 reg; printk(BIOS_DEBUG, "IOAPIC: Initializing IOAPIC at %" PRIxPTR "\n", ioapic_base); printk(BIOS_DEBUG, "IOAPIC: ID = 0x%02x\n", ioapic_id); - io_apic_write(ioapic_base, 0x00, - (io_apic_read(ioapic_base, 0x00) & 0xf0ffffff) | (ioapic_id << 24)); + reg = io_apic_read(ioapic_base, 0x00); + + if (CONFIG(IOAPIC_8BIT_ID)) + reg &= 0x00ffffff; + else + reg &= 0xf0ffffff; + + reg |= (ioapic_id << 24); + io_apic_write(ioapic_base, 0x00, reg); printk(BIOS_SPEW, "IOAPIC: Dumping registers\n"); for (i = 0; i < 3; i++) From 5f86aba4b3795d632a3da9769eaa24a4ea0fd039 Mon Sep 17 00:00:00 2001 From: Wonkyu Kim Date: Mon, 29 Dec 2025 13:35:33 -0800 Subject: [PATCH 144/789] soc/intel/common: Enable high address support for MCHBAR in ACPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Increased MHBR field width in ACPI northbridge.asl from 17 to 27 bits, allowing MCHBAR to be set above 4GB (up to 42 bits). Reference: Section 10.3 in 850519 BUG=none TEST=boot to OS with ACPI debug enabled and check GMHB log Signed-off-by: Wonkyu Kim Change-Id: I885ff64598367ddadcec05926af3556024b61250 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90729 Reviewed-by: Kapil Porwal Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/soc/intel/common/block/acpi/acpi/northbridge.asl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/soc/intel/common/block/acpi/acpi/northbridge.asl b/src/soc/intel/common/block/acpi/acpi/northbridge.asl index 3b2fb85933..90c90027d0 100644 --- a/src/soc/intel/common/block/acpi/acpi/northbridge.asl +++ b/src/soc/intel/common/block/acpi/acpi/northbridge.asl @@ -24,7 +24,7 @@ Device (MCHC) Offset(0x48), /* MCHBAR (0:0:0:48) */ MHEN, 1, /* Enable */ , 14, - MHBR, 17, /* MCHBAR [31:15] */ + MHBR, 27, /* MCHBAR [41:15] */ Offset(0x60), /* PCIEXBAR (0:0:0:60) */ PXEN, 1, /* Enable */ @@ -246,6 +246,7 @@ Method (_CRS, 0, Serialized) Method (GMHB, 0, Serialized) { Local0 = \_SB.PCI0.MCHC.MHBR << 15 + Printf ("GMHB: %o", ToHexString(Local0)) Return (Local0) } From 1d2b399fd76b0804d07e22da047eaaa9e5e692e2 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Mon, 12 Jan 2026 15:01:12 +0800 Subject: [PATCH 145/789] lib: Rename `fill_lb_framebuffer` to `get_lb_framebuffer` Rename `fill_lb_framebuffer` to `get_lb_framebuffer` to better reflect that it returns framebuffer information. The new `get_lb_framebuffer` returns a constant pointer to the framebuffer structure instead of filling a provided structure. This simplifies the API and avoids an unnecessary memory copy. The file `edid_fill_fb.c` is renamed to `framebuffer_info.c` to better match the function it now contains. Call sites in `coreboot_table.c` and `render_bmp.c` are updated to use the new API. TEST=emerge-tanjiro coreboot; check the FW logo is correctly drawn. BUG=b:319511268 Change-Id: I8d7b20a0524b6bc9fff9e6461fa0c253345df790 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90725 Reviewed-by: Yu-Ping Wu Reviewed-by: Chen-Tsung Hsieh Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/include/boot/coreboot_tables.h | 6 +++--- src/lib/Makefile.mk | 2 +- src/lib/coreboot_table.c | 6 +++--- src/lib/{edid_fill_fb.c => framebuffer_info.c} | 7 +++---- src/lib/render_bmp.c | 14 ++++++-------- 5 files changed, 16 insertions(+), 19 deletions(-) rename src/lib/{edid_fill_fb.c => framebuffer_info.c} (97%) diff --git a/src/include/boot/coreboot_tables.h b/src/include/boot/coreboot_tables.h index be737b0bb9..3a5e31651c 100644 --- a/src/include/boot/coreboot_tables.h +++ b/src/include/boot/coreboot_tables.h @@ -33,9 +33,9 @@ void lb_efi_fw_info(struct lb_header *header); /* Adds LB_TAG_CAPSULE table entries. */ void lb_efi_capsules(struct lb_header *header); -/* Define this function to fill in the frame buffer returning 0 on success and - < 0 on error. */ -int fill_lb_framebuffer(struct lb_framebuffer *framebuffer); +/* Define this function to get the frame buffer returning lb_framebuffer object + on success and NULL on error. */ +const struct lb_framebuffer *get_lb_framebuffer(void); /* Allow arch to add records. */ void lb_arch_add_records(struct lb_header *header); diff --git a/src/lib/Makefile.mk b/src/lib/Makefile.mk index 9deefaf95b..d7cf8455b1 100644 --- a/src/lib/Makefile.mk +++ b/src/lib/Makefile.mk @@ -154,8 +154,8 @@ ramstage-$(CONFIG_BOOTSPLASH) += jpeg.c ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c ramstage-$(CONFIG_COVERAGE) += libgcov.c ramstage-y += dp_aux.c +ramstage-y += framebuffer_info.c ramstage-y += edid.c -ramstage-y += edid_fill_fb.c ramstage-y += memrange.c ramstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c ramstage-$(CONFIG_GENERIC_UDELAY) += timer.c diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index 85c5675507..6218784adc 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -142,13 +142,13 @@ static void lb_pcie(struct lb_header *header) static void lb_framebuffer(struct lb_header *header) { struct lb_framebuffer *framebuffer; - struct lb_framebuffer fb = {0}; + const struct lb_framebuffer *fb; - if (!CONFIG(LINEAR_FRAMEBUFFER) || fill_lb_framebuffer(&fb)) + if (!CONFIG(LINEAR_FRAMEBUFFER) || !(fb = get_lb_framebuffer())) return; framebuffer = (struct lb_framebuffer *)lb_new_record(header); - memcpy(framebuffer, &fb, sizeof(*framebuffer)); + memcpy(framebuffer, fb, sizeof(*framebuffer)); framebuffer->tag = LB_TAG_FRAMEBUFFER; framebuffer->size = sizeof(*framebuffer); diff --git a/src/lib/edid_fill_fb.c b/src/lib/framebuffer_info.c similarity index 97% rename from src/lib/edid_fill_fb.c rename to src/lib/framebuffer_info.c index a9ff31f5ca..f706377caa 100644 --- a/src/lib/edid_fill_fb.c +++ b/src/lib/framebuffer_info.c @@ -181,14 +181,13 @@ struct fb_info *fb_new_framebuffer_info_from_edid(const struct edid *edid, edid->bytes_per_line, edid->framebuffer_bits_per_pixel); } -int fill_lb_framebuffer(struct lb_framebuffer *framebuffer) +const struct lb_framebuffer *get_lb_framebuffer(void) { struct fb_info *i; list_for_each(i, list, node) { //TODO: Add support for advertising all framebuffers in this list - *framebuffer = i->fb; - return 0; + return &i->fb; } - return -1; + return NULL; } diff --git a/src/lib/render_bmp.c b/src/lib/render_bmp.c index 3a7e245eca..b91015bf89 100644 --- a/src/lib/render_bmp.c +++ b/src/lib/render_bmp.c @@ -689,16 +689,14 @@ void render_logo_to_framebuffer(struct logo_config *config) if (config->framebuffer_base == 0) { /* Try to load from already populated framebuffer information */ - struct lb_framebuffer framebuffer; - memset(&framebuffer, 0, sizeof(struct lb_framebuffer)); - fill_lb_framebuffer(&framebuffer); + const struct lb_framebuffer *fb = get_lb_framebuffer(); /* Exit if framebuffer is still not available */ - if (framebuffer.physical_address == 0) + if (!fb) return; - config->framebuffer_base = framebuffer.physical_address; - config->horizontal_resolution = framebuffer.x_resolution; - config->vertical_resolution = framebuffer.y_resolution; - config->bytes_per_scanline = framebuffer.bytes_per_line; + config->framebuffer_base = fb->physical_address; + config->horizontal_resolution = fb->x_resolution; + config->vertical_resolution = fb->y_resolution; + config->bytes_per_scanline = fb->bytes_per_line; } /* From b4fbc59c6f85b9e9899b2312efe73fdfee86ebbf Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Tue, 13 Jan 2026 11:42:18 +0800 Subject: [PATCH 146/789] treewide: Move mipi_panel_parse_commands() to commonlib Move the MIPI panel init command parsing function mipi_panel_parse_init_commands() and related macros and structs from drivers/mipi/ to commonlib/mipi/, so that the function can be shared with payloads. In a follow-up patch, a 'poweroff' field will be added to the panel_serializable_data struct and then passed to payloads, so that payloads can utilize mipi_panel_parse_init_commands() to run the panel poweroff commands. BUG=b:474187570 TEST=emerge-jedi coreboot libpayload BRANCH=skywalker Change-Id: I19011669f03d060e9f030b673687cbe5965d7e2f Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90736 Reviewed-by: Subrata Banik Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Alicja Michalska Reviewed-by: Julius Werner Reviewed-by: Yidi Lin --- src/commonlib/Makefile.mk | 1 + src/commonlib/include/commonlib/mipi/cmd.h | 55 +++++++++++++++++++ .../include/commonlib}/mipi/dsi.h | 6 +- src/commonlib/mipi/Makefile.mk | 3 + .../mipi/panel.c => commonlib/mipi/cmd.c} | 6 +- src/drivers/mipi/Makefile.mk | 2 - src/include/mipi/panel.h | 47 +--------------- .../mediatek/common/include/soc/dsi_common.h | 2 +- .../tegra210/include/soc/mipi_display.h | 2 +- src/soc/qualcomm/sc7180/display/dsi.c | 1 - src/soc/rockchip/rk3399/include/soc/mipi.h | 2 +- 11 files changed, 69 insertions(+), 58 deletions(-) create mode 100644 src/commonlib/include/commonlib/mipi/cmd.h rename src/{include => commonlib/include/commonlib}/mipi/dsi.h (97%) create mode 100644 src/commonlib/mipi/Makefile.mk rename src/{drivers/mipi/panel.c => commonlib/mipi/cmd.c} (94%) diff --git a/src/commonlib/Makefile.mk b/src/commonlib/Makefile.mk index b4bc1b8fae..f71fff4892 100644 --- a/src/commonlib/Makefile.mk +++ b/src/commonlib/Makefile.mk @@ -1,5 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only +subdirs-y += mipi subdirs-y += storage subdirs-y += bsd/zstd diff --git a/src/commonlib/include/commonlib/mipi/cmd.h b/src/commonlib/include/commonlib/mipi/cmd.h new file mode 100644 index 0000000000..ebbc36ba47 --- /dev/null +++ b/src/commonlib/include/commonlib/mipi/cmd.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __COMMONLIB_MIPI_CMD_H__ +#define __COMMONLIB_MIPI_CMD_H__ + +#include +#include +#include + +/* Definitions for cmd in panel_init_command */ +enum panel_init_cmd { + PANEL_CMD_END = 0, + PANEL_CMD_DELAY = 1, + PANEL_CMD_GENERIC = 2, + PANEL_CMD_DCS = 3, +}; + +struct panel_init_command { + u8 cmd; + u8 len; + u8 data[]; +}; + +#define PANEL_DELAY(delay) \ + PANEL_CMD_DELAY, \ + delay + +#define PANEL_GENERIC(...) \ + PANEL_CMD_GENERIC, \ + sizeof((u8[]){__VA_ARGS__}), \ + __VA_ARGS__ + +#define PANEL_DCS(...) \ + PANEL_CMD_DCS, \ + sizeof((u8[]){__VA_ARGS__}), \ + __VA_ARGS__ + +#define PANEL_END \ + PANEL_CMD_END + +/* + * Callback function type for mipi_panel_parse_init_commands(). + * @param type MIPI DSI transaction type. + * @param data panel_init_command data. + * @param len panel_init_command len. + * @param user_data Arbitrary user data passed from mipi_panel_parse_init_commands(). + */ +typedef enum cb_err (*mipi_cmd_func_t)(enum mipi_dsi_transaction type, const u8 *data, u8 len, + void *user_data); + +/* Parse a command array and call cmd_func() for each entry. Delays get handled internally. */ +enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func, + void *user_data); + +#endif /* __COMMONLIB_MIPI_CMD_H__ */ diff --git a/src/include/mipi/dsi.h b/src/commonlib/include/commonlib/mipi/dsi.h similarity index 97% rename from src/include/mipi/dsi.h rename to src/commonlib/include/commonlib/mipi/dsi.h index 9f11490f69..b55fd9dc70 100644 --- a/src/include/mipi/dsi.h +++ b/src/commonlib/include/commonlib/mipi/dsi.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef __MIPI_DSI_H__ -#define __MIPI_DSI_H__ +#ifndef __COMMONLIB_MIPI_DSI_H__ +#define __COMMONLIB_MIPI_DSI_H__ /* MIPI DSI Processor-to-Peripheral transaction types */ enum mipi_dsi_transaction { @@ -109,4 +109,4 @@ enum { MIPI_DCS_READ_DDB_CONTINUE = 0xA8, }; -#endif /* __MIPI_DSI_H__ */ +#endif /* __COMMONLIB_MIPI_DSI_H__ */ diff --git a/src/commonlib/mipi/Makefile.mk b/src/commonlib/mipi/Makefile.mk new file mode 100644 index 0000000000..e5df26b2c5 --- /dev/null +++ b/src/commonlib/mipi/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-y += cmd.c diff --git a/src/drivers/mipi/panel.c b/src/commonlib/mipi/cmd.c similarity index 94% rename from src/drivers/mipi/panel.c rename to src/commonlib/mipi/cmd.c index 0182a8594a..be8c5e6412 100644 --- a/src/drivers/mipi/panel.c +++ b/src/commonlib/mipi/cmd.c @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include +#include +#include +#include #include -#include -#include enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func, void *user_data) diff --git a/src/drivers/mipi/Makefile.mk b/src/drivers/mipi/Makefile.mk index 92d5ebe987..e814414d82 100644 --- a/src/drivers/mipi/Makefile.mk +++ b/src/drivers/mipi/Makefile.mk @@ -1,7 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -ramstage-y += panel.c - panel-params-y := panel-params-$(CONFIG_MIPI_PANEL_AUO_B101UAN08_3) += panel-AUO_B101UAN08_3 diff --git a/src/include/mipi/panel.h b/src/include/mipi/panel.h index e2123a6e22..ae45684ecb 100644 --- a/src/include/mipi/panel.h +++ b/src/include/mipi/panel.h @@ -3,29 +3,15 @@ #ifndef __MIPI_PANEL_H__ #define __MIPI_PANEL_H__ +#include #include -#include #include -/* Definitions for cmd in panel_init_command */ -enum panel_init_cmd { - PANEL_CMD_END = 0, - PANEL_CMD_DELAY = 1, - PANEL_CMD_GENERIC = 2, - PANEL_CMD_DCS = 3, -}; - /* Definitions for flags in panel_serializable_data */ enum panel_flag { PANEL_FLAG_CPHY = BIT(0), }; -struct panel_init_command { - u8 cmd; - u8 len; - u8 data[]; -}; - /* VESA Display Stream Compression DSC 1.2 constants */ #define DSC_NUM_BUF_RANGES 15 @@ -215,35 +201,4 @@ struct panel_serializable_data { u8 init[]; /* A packed array of panel_init_command */ }; -/* - * Callback function type for mipi_panel_parse_init_commands(). - * @param type MIPI DSI transaction type. - * @param data panel_init_command data. - * @param len panel_init_command len. - * @param user_data Arbitrary user data passed from mipi_panel_parse_init_commands(). - */ -typedef enum cb_err (*mipi_cmd_func_t)(enum mipi_dsi_transaction type, const u8 *data, u8 len, - void *user_data); - -/* Parse a command array and call cmd_func() for each entry. Delays get handled internally. */ -enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func, - void *user_data); - -#define PANEL_DCS(...) \ - PANEL_CMD_DCS, \ - sizeof((u8[]){__VA_ARGS__}), \ - __VA_ARGS__ - -#define PANEL_GENERIC(...) \ - PANEL_CMD_GENERIC, \ - sizeof((u8[]){__VA_ARGS__}), \ - __VA_ARGS__ - -#define PANEL_DELAY(delay) \ - PANEL_CMD_DELAY, \ - delay - -#define PANEL_END \ - PANEL_CMD_END - #endif /* __MIPI_PANEL_H__ */ diff --git a/src/soc/mediatek/common/include/soc/dsi_common.h b/src/soc/mediatek/common/include/soc/dsi_common.h index 626e8414b6..62bff790a9 100644 --- a/src/soc/mediatek/common/include/soc/dsi_common.h +++ b/src/soc/mediatek/common/include/soc/dsi_common.h @@ -4,8 +4,8 @@ #define SOC_MEDIATEK_DSI_COMMON_H #include +#include #include -#include #include #include #include diff --git a/src/soc/nvidia/tegra210/include/soc/mipi_display.h b/src/soc/nvidia/tegra210/include/soc/mipi_display.h index e5c7596b97..87591878c8 100644 --- a/src/soc/nvidia/tegra210/include/soc/mipi_display.h +++ b/src/soc/nvidia/tegra210/include/soc/mipi_display.h @@ -8,7 +8,7 @@ #ifndef __SOC_MIPI_DISPLAY_H__ #define __SOC_MIPI_DISPLAY_H__ -#include +#include /* MIPI DCS pixel formats */ #define MIPI_DCS_PIXEL_FMT_24BIT 7 diff --git a/src/soc/qualcomm/sc7180/display/dsi.c b/src/soc/qualcomm/sc7180/display/dsi.c index c1e75e1090..e5b09805c3 100644 --- a/src/soc/qualcomm/sc7180/display/dsi.c +++ b/src/soc/qualcomm/sc7180/display/dsi.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include #include #include #include diff --git a/src/soc/rockchip/rk3399/include/soc/mipi.h b/src/soc/rockchip/rk3399/include/soc/mipi.h index f5bd797850..839eb5185c 100644 --- a/src/soc/rockchip/rk3399/include/soc/mipi.h +++ b/src/soc/rockchip/rk3399/include/soc/mipi.h @@ -3,7 +3,7 @@ #ifndef __RK_MIPI_H #define __RK_MIPI_H -#include +#include #include struct rk_mipi_regs { From a6407000f1fefb064cf0953d80e256626aee7248 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Tue, 13 Jan 2026 14:49:47 +0800 Subject: [PATCH 147/789] mipi/panel: Add 'poweroff' field to panel_serializable_data Some payloads such as depthcharge need to run MIPI panel power-off commands before booting to the kernel. Otherwise, the abnormal power-off timing would prevent the pixel charge from being cleared before power-off, leading to the risk of LCD overpotential hence resulting in image stickiness or flicker upon restarting. Therefore, add a 'poweroff' field to the panel_serializable_data struct, which, in a follow-up patch, will be passed to payloads for running the power-off commands. Each MIPI panel can define the power-off commands in that field. As both init and power-off commands are supported, remove "_init" from related structs and enums. BUG=b:474187570 TEST=emerge-jedi coreboot libpayload BRANCH=skywalker Change-Id: I1a7c0a14d5c197a0887a26269e4c36e498e8b7ae Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90737 Reviewed-by: Yidi Lin Reviewed-by: Alicja Michalska Reviewed-by: Subrata Banik Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner Reviewed-by: Chen-Tsung Hsieh --- src/commonlib/include/commonlib/mipi/cmd.h | 18 +++++++++--------- src/commonlib/mipi/cmd.c | 18 +++++++++--------- src/include/mipi/panel.h | 6 +++++- src/soc/mediatek/common/dsi_common.c | 2 +- src/soc/qualcomm/sc7180/display/dsi.c | 3 +-- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/commonlib/include/commonlib/mipi/cmd.h b/src/commonlib/include/commonlib/mipi/cmd.h index ebbc36ba47..17e0aeda89 100644 --- a/src/commonlib/include/commonlib/mipi/cmd.h +++ b/src/commonlib/include/commonlib/mipi/cmd.h @@ -7,15 +7,15 @@ #include #include -/* Definitions for cmd in panel_init_command */ -enum panel_init_cmd { +/* Definitions for cmd in panel_command */ +enum panel_cmd { PANEL_CMD_END = 0, PANEL_CMD_DELAY = 1, PANEL_CMD_GENERIC = 2, PANEL_CMD_DCS = 3, }; -struct panel_init_command { +struct panel_command { u8 cmd; u8 len; u8 data[]; @@ -39,17 +39,17 @@ struct panel_init_command { PANEL_CMD_END /* - * Callback function type for mipi_panel_parse_init_commands(). + * Callback function type for mipi_panel_parse_commands(). * @param type MIPI DSI transaction type. - * @param data panel_init_command data. - * @param len panel_init_command len. - * @param user_data Arbitrary user data passed from mipi_panel_parse_init_commands(). + * @param data panel_command data. + * @param len panel_command len. + * @param user_data Arbitrary user data passed from mipi_panel_parse_commands(). */ typedef enum cb_err (*mipi_cmd_func_t)(enum mipi_dsi_transaction type, const u8 *data, u8 len, void *user_data); /* Parse a command array and call cmd_func() for each entry. Delays get handled internally. */ -enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func, - void *user_data); +enum cb_err mipi_panel_parse_commands(const void *buf, mipi_cmd_func_t cmd_func, + void *user_data); #endif /* __COMMONLIB_MIPI_CMD_H__ */ diff --git a/src/commonlib/mipi/cmd.c b/src/commonlib/mipi/cmd.c index be8c5e6412..4e5a638d9b 100644 --- a/src/commonlib/mipi/cmd.c +++ b/src/commonlib/mipi/cmd.c @@ -5,26 +5,26 @@ #include #include -enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func, - void *user_data) +enum cb_err mipi_panel_parse_commands(const void *buf, mipi_cmd_func_t cmd_func, + void *user_data) { - const struct panel_init_command *init = buf; + const struct panel_command *command = buf; enum mipi_dsi_transaction type; /* * The given commands should be in a buffer containing a packed array of - * panel_init_command and each element may be in variable size so we have + * panel_command and each element may be in variable size so we have * to parse and scan. */ - for (; init->cmd != PANEL_CMD_END; init = (const void *)buf) { + for (; command->cmd != PANEL_CMD_END; command = (const void *)buf) { /* - * For some commands like DELAY, the init->len should not be + * For some commands like DELAY, the command->len should not be * counted for buf. */ - buf += sizeof(*init); + buf += sizeof(*command); - u32 cmd = init->cmd, len = init->len; + u32 cmd = command->cmd, len = command->len; if (cmd == PANEL_CMD_DELAY) { mdelay(len); @@ -70,7 +70,7 @@ enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_ return CB_ERR; } - enum cb_err ret = cmd_func(type, init->data, len, user_data); + enum cb_err ret = cmd_func(type, command->data, len, user_data); if (ret != CB_SUCCESS) return ret; buf += len; diff --git a/src/include/mipi/panel.h b/src/include/mipi/panel.h index ae45684ecb..432b43090b 100644 --- a/src/include/mipi/panel.h +++ b/src/include/mipi/panel.h @@ -189,6 +189,8 @@ struct dsc_config { u8 dsc_version_major; }; +#define PANEL_POWEROFF_CMD_MAX_LEN 16 + /* * The data to be serialized and put into CBFS. * Note some fields, for example edid.mode.name, were actually pointers and @@ -198,7 +200,9 @@ struct panel_serializable_data { u32 flags; /* flags of panel_flag */ struct edid edid; /* edid info of this panel */ struct dsc_config dsc_config; /* dsc config of this panel */ - u8 init[]; /* A packed array of panel_init_command */ + /* Packed arrays of panel_command */ + u8 poweroff[PANEL_POWEROFF_CMD_MAX_LEN]; + u8 init[]; }; #endif /* __MIPI_PANEL_H__ */ diff --git a/src/soc/mediatek/common/dsi_common.c b/src/soc/mediatek/common/dsi_common.c index 3ff8c5b049..b2df010a48 100644 --- a/src/soc/mediatek/common/dsi_common.c +++ b/src/soc/mediatek/common/dsi_common.c @@ -494,7 +494,7 @@ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, } if (init_commands) - mipi_panel_parse_init_commands(init_commands, mtk_dsi_cmdq, &mode_flags); + mipi_panel_parse_commands(init_commands, mtk_dsi_cmdq, &mode_flags); for (unsigned int i = 0; i < num_dsi; i++) mtk_dsi_set_mode(dsi_mipi_regs[i].dsi_reg, mode_flags); diff --git a/src/soc/qualcomm/sc7180/display/dsi.c b/src/soc/qualcomm/sc7180/display/dsi.c index e5b09805c3..ef219777b3 100644 --- a/src/soc/qualcomm/sc7180/display/dsi.c +++ b/src/soc/qualcomm/sc7180/display/dsi.c @@ -286,8 +286,7 @@ enum cb_err mdss_dsi_panel_initialize(const u8 *init_cmds) /* Enable command mode before sending the commands */ write32(&dsi0->ctrl, ctrl_mode | 0x04); - enum cb_err ret = mipi_panel_parse_init_commands(init_cmds, mdss_dsi_send_init_cmd, - NULL); + enum cb_err ret = mipi_panel_parse_commands(init_cmds, mdss_dsi_send_init_cmd, NULL); write32(&dsi0->ctrl, ctrl_mode); mdss_dsi_clear_intr(); From e01baafbe27692882b83a14b07b7b0f991f61a09 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Wed, 27 Aug 2025 21:29:25 +0200 Subject: [PATCH 148/789] include/cper.h: Add check information structures It is needed in a later commit that is not upstream yet. Signed-off-by: Maximilian Brune Change-Id: I260dcf199178d28387e7af06c6fb0b03c97c4bb8 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90692 Reviewed-by: Felix Held Tested-by: build bot (Jenkins) --- src/include/cper.h | 47 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/include/cper.h b/src/include/cper.h index 4dec2a2247..1bddaa78ef 100644 --- a/src/include/cper.h +++ b/src/include/cper.h @@ -172,16 +172,61 @@ typedef struct cper_ia32x64_proc_error_section { (I32X64SEC_VALID_CTXNUM_MAX \ << I32X64SEC_VALID_CTXNUM_SH) +#define I32X64_ERRTYPE_INTERNAL_UNCLASSIFIED 5 + +struct cper_ia32x64_check_ms { + uint64_t validation_bits:16; + uint64_t err_type:3; + uint64_t proc_context_corrupt:1; + uint64_t uncorrected:1; + uint64_t precise_ip:1; + uint64_t restartable_ip:1; + uint64_t overflow:1; + uint64_t :40; +}; + +struct cper_ia32x64_check_tlb { + uint64_t validation_bits:16; + uint64_t transaction_type:2; + uint64_t operation:4; + uint64_t level:3; + uint64_t proc_context_corrupt:1; + uint64_t uncorrected:1; + uint64_t precise_ip:1; + uint64_t restartable_ip:1; + uint64_t overflow:1; + uint64_t :34; +}; + +struct cper_ia32x64_check_cache { + uint64_t validation_bits:16; + uint64_t transaction_type:2; + uint64_t operation:4; + uint64_t level:3; + uint64_t proc_context_corrupt:1; + uint64_t uncorrected:1; + uint64_t precise_ip:1; + uint64_t restartable_ip:1; + uint64_t overflow:1; + uint64_t :34; +}; + /* IA32/X64 Processor Error Information Structure (Table N.8) */ typedef struct cper_ia32x64_proc_error_info { guid_t type; /* cache, tlb, bus, micro-architecture specific */ u64 validation; - u64 check_info; + union { + struct cper_ia32x64_check_ms ms; + struct cper_ia32x64_check_tlb tlb; + struct cper_ia32x64_check_cache cache; + uint64_t raw; + }; u64 target_id; u64 requestor_id; u64 responder_id; u64 instruction_ip; } __packed cper_ia32x64_proc_error_info_t; +_Static_assert(sizeof(struct cper_ia32x64_proc_error_info) == 64, "cper_ia32x64_proc_error_info size wrong"); /* IA32/X64 Processor Error Information Structs, Err Struct Types (Table N.8) */ #define X86_PROCESSOR_CACHE_CHK_ERROR_GUID \ From f2788e963ff5668ecb642782a6f6e64adca8a58a Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Wed, 17 Sep 2025 14:37:01 +0200 Subject: [PATCH 149/789] device: Rename PCI_EXP_SEC_CAP_ID -> PCI_CAP_ID_SEC_PCIE Rename the define for "Secondary PCI Express Extended Capability" and move it close to the other existing defines. Cosmetic change. No functionality was changed. Signed-off-by: Maximilian Brune Change-Id: I3b1ce6820f508661d3241c36c90febe0c73b7a5a Reviewed-on: https://review.coreboot.org/c/coreboot/+/90694 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/device/pciexp_device.c | 2 +- src/include/device/pci_def.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/pciexp_device.c b/src/device/pciexp_device.c index a5f162e8ac..1b8f8ad79b 100644 --- a/src/device/pciexp_device.c +++ b/src/device/pciexp_device.c @@ -692,7 +692,7 @@ static void clear_lane_error_status(struct device *dev) u32 reg32; u16 pos; - pos = pciexp_find_extended_cap(dev, PCI_EXP_SEC_CAP_ID, 0); + pos = pciexp_find_extended_cap(dev, PCI_CAP_ID_SEC_PCIE, 0); if (pos == 0) return; diff --git a/src/include/device/pci_def.h b/src/include/device/pci_def.h index 6748b356b7..0838128057 100644 --- a/src/include/device/pci_def.h +++ b/src/include/device/pci_def.h @@ -204,6 +204,7 @@ #define PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */ #define PCI_CAP_ID_PCIE 0x10 /* PCI Express */ #define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ +#define PCI_CAP_ID_SEC_PCIE 0x19 /* Secondary PCI Express Extended Capability */ #define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ #define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ @@ -481,7 +482,6 @@ #define PCIE_EXT_CAP_SRIOV_ID 0x0010 /* Secondary PCI Express Extended Capability Structure */ -#define PCI_EXP_SEC_CAP_ID 0x19 #define PCI_EXP_SEC_LNK_CTL3 4 /* Link Control 3 */ #define PCI_EXP_SEC_LANE_ERR_STATUS 8 /* Lane Error Status */ From fbf0087918dff2cd1b914cf6ae84027428888f51 Mon Sep 17 00:00:00 2001 From: Pierce Chou Date: Fri, 9 Jan 2026 13:53:19 +0800 Subject: [PATCH 150/789] mb/google/ocelot/var/ocicat: Use GPP_F10 for ISH Currently, Linux is unable to load the ISH firmware, as GPP_F10 define lost Update gpio pins GPP_F10 for ISH bug=b:465776760 TEST=Flash and boot to OS on ocicat, Verified ISH fw load in cpu console using below command. ~ # dmesg | grep ish output: intel_ish_ipc 0000:00:12.0: ISH loader: load firmware: intel/ish/ish_wcl.bin Change-Id: I4642560d3b14560e93158d1d19b496e22811600c Signed-off-by: Pierce Chou Reviewed-on: https://review.coreboot.org/c/coreboot/+/90708 Reviewed-by: Paul Menzel Reviewed-by: Pranava Y N Tested-by: build bot (Jenkins) --- src/mainboard/google/ocelot/variants/ocicat/gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/ocelot/variants/ocicat/gpio.c b/src/mainboard/google/ocelot/variants/ocicat/gpio.c index 3a9a7b4ed2..25aa28c73b 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/gpio.c +++ b/src/mainboard/google/ocelot/variants/ocicat/gpio.c @@ -242,7 +242,7 @@ static const struct pad_config gpio_table[] = { /* GPP_F09: M2_UFS_RST_N */ PAD_CFG_GPO(GPP_F09, 1, DEEP), /* GPP_F10: ISH_ACCEL_MB_INT_L */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_F05, NONE, DEEP, NF8), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_F10, NONE, DEEP, NF8), /* GPP_F11: NC */ PAD_NC(GPP_F11, NONE), /* GPP_F12: THC_I2C1_SCL_TCH_PAD */ From 94e6e5cd0d9b2df46a4c9188957c72c8cebc68a9 Mon Sep 17 00:00:00 2001 From: Avi Uday Date: Tue, 13 Jan 2026 13:40:06 +0530 Subject: [PATCH 151/789] mb/google/ocelot: Add option to enable VGA mode 12 This commit adds a new Kconfig option to the ocelot mainboard to enable VGA mode 12 support for early Sign of Life (eSOL). - This option, `OCELOT_VGA_MODE12_SUPPORT`, is dependent on `FSP_UGOP_EARLY_SIGN_OF_LIFE`. - It selects `ROMSTAGE_VGA` and `FSP_VGA_MODE12` to enable the necessary VGA components. BUG=None TEST=Verify VGA text rotation on ocelot RVP. Change-Id: I71dff6e58c3e4487079c0090848ecde9da5153d7 Signed-off-by: Avi Uday Reviewed-on: https://review.coreboot.org/c/coreboot/+/90731 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/mainboard/google/ocelot/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/mainboard/google/ocelot/Kconfig b/src/mainboard/google/ocelot/Kconfig index f83e19aa6a..d2a2e189e4 100644 --- a/src/mainboard/google/ocelot/Kconfig +++ b/src/mainboard/google/ocelot/Kconfig @@ -227,4 +227,13 @@ config OVERRIDE_DEVICETREE config VBOOT select VBOOT_LID_SWITCH +config OCELOT_VGA_MODE12_SUPPORT + bool "Enable VGA Mode 12 support for eSOL" + default n + depends on FSP_UGOP_EARLY_SIGN_OF_LIFE + select ROMSTAGE_VGA + select FSP_VGA_MODE12 + help + Select this if the FSP supports VGA mode 12 for eSOL. + endif # BOARD_GOOGLE_OCELOT_COMMON From e8ac9ffcd9a8e56667d18b12ad859851ad9de1a8 Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Fri, 9 Jan 2026 08:35:59 +0100 Subject: [PATCH 152/789] mb/siemens/mc_ehl7: Add new board variant based on mc_ehl6 This new mainboard variant for the Siemens mc_ehl6 is initially based on a direct copy of the mc_ehl6 configuration. This commit contains the basic board setup with only minimal changes to enable the new variant. Further specific adaptations for the mc_ehl7 hardware will be handled in subsequent commits. TEST=Build and boot to OS on mc_ehl7. Change-Id: I46148492f65630175abb3ce884261d098314f2bc Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/90714 Reviewed-by: Mario Scheithauer Tested-by: build bot (Jenkins) --- src/mainboard/siemens/mc_ehl/Kconfig | 5 + src/mainboard/siemens/mc_ehl/Kconfig.name | 3 + .../siemens/mc_ehl/variants/mc_ehl7/Kconfig | 43 +++ .../mc_ehl/variants/mc_ehl7/Makefile.mk | 8 + .../mc_ehl/variants/mc_ehl7/devicetree.cb | 260 ++++++++++++++++++ .../siemens/mc_ehl/variants/mc_ehl7/gpio.c | 137 +++++++++ .../mc_ehl/variants/mc_ehl7/mainboard.c | 69 +++++ .../siemens/mc_ehl/variants/mc_ehl7/memory.c | 48 ++++ .../siemens/mc_ehl/variants/mc_ehl7/post.c | 10 + 9 files changed, 583 insertions(+) create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Makefile.mk create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl7/mainboard.c create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl7/memory.c create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl7/post.c diff --git a/src/mainboard/siemens/mc_ehl/Kconfig b/src/mainboard/siemens/mc_ehl/Kconfig index 5aff0be1b5..3db9ad0d52 100644 --- a/src/mainboard/siemens/mc_ehl/Kconfig +++ b/src/mainboard/siemens/mc_ehl/Kconfig @@ -29,6 +29,9 @@ config BOARD_SIEMENS_MC_EHL5 config BOARD_SIEMENS_MC_EHL6 select BOARD_SIEMENS_BASEBOARD_MC_EHL +config BOARD_SIEMENS_MC_EHL7 + select BOARD_SIEMENS_BASEBOARD_MC_EHL + source "src/mainboard/siemens/mc_ehl/variants/*/Kconfig" if BOARD_SIEMENS_BASEBOARD_MC_EHL @@ -43,6 +46,7 @@ config VARIANT_DIR default "mc_ehl4" if BOARD_SIEMENS_MC_EHL4 default "mc_ehl5" if BOARD_SIEMENS_MC_EHL5 default "mc_ehl6" if BOARD_SIEMENS_MC_EHL6 + default "mc_ehl7" if BOARD_SIEMENS_MC_EHL7 config MAINBOARD_PART_NUMBER default "MC EHL1" if BOARD_SIEMENS_MC_EHL1 @@ -51,6 +55,7 @@ config MAINBOARD_PART_NUMBER default "MC EHL4" if BOARD_SIEMENS_MC_EHL4 default "MC EHL5" if BOARD_SIEMENS_MC_EHL5 default "MC EHL6" if BOARD_SIEMENS_MC_EHL6 + default "MC EHL7" if BOARD_SIEMENS_MC_EHL7 config DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" diff --git a/src/mainboard/siemens/mc_ehl/Kconfig.name b/src/mainboard/siemens/mc_ehl/Kconfig.name index 50233cea9c..ffbfc9d124 100644 --- a/src/mainboard/siemens/mc_ehl/Kconfig.name +++ b/src/mainboard/siemens/mc_ehl/Kconfig.name @@ -19,3 +19,6 @@ config BOARD_SIEMENS_MC_EHL5 config BOARD_SIEMENS_MC_EHL6 bool "-> MC EHL6" + +config BOARD_SIEMENS_MC_EHL7 + bool "-> MC EHL7" diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig new file mode 100644 index 0000000000..7cc7c5abee --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig @@ -0,0 +1,43 @@ +## SPDX-License-Identifier: GPL-2.0-only + +if BOARD_SIEMENS_MC_EHL7 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select DRIVER_INTEL_I210 + select DRIVERS_ETH_PHY_M88E1512 + select DRIVERS_I2C_RV3028C7 + select EHL_TSN_DRIVER + select MAINBOARD_HAS_TPM2 + select MEMORY_MAPPED_TPM + select NC_FPGA_POST_CODE + select SOC_INTEL_COMMON_BLOCK_LPC_COMB_ENABLE + select TPM_MEASURED_BOOT + select TPM_MEASURED_BOOT_INIT_BOOTBLOCK + +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/mc_ehl.fmd" + +config UART_FOR_CONSOLE + int + default 0 + +config EARLY_PCI_BRIDGE_DEVICE + hex + depends on NC_FPGA_POST_CODE + default 0x1c + +config EARLY_PCI_BRIDGE_FUNCTION + hex + depends on NC_FPGA_POST_CODE + default 0x0 + +config EARLY_PCI_MMIO_BASE + hex + depends on NC_FPGA_POST_CODE + default 0xfe800000 + +config SOC_INTEL_ELKHARTLAKE_TCO_NO_REBOOT_EN + default y + +endif # BOARD_SIEMENS_MC_EHL7 diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Makefile.mk b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Makefile.mk new file mode 100644 index 0000000000..d9050f098d --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Makefile.mk @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += gpio.c +romstage-y += memory.c +ramstage-y += gpio.c +ramstage-y += mainboard.c + +all-$(CONFIG_NC_FPGA_POST_CODE) += post.c diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb new file mode 100644 index 0000000000..5180770908 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb @@ -0,0 +1,260 @@ +chip soc/intel/elkhartlake + + device cpu_cluster 0 on end + + # GPE configuration + # Note that GPE events called out in ASL code rely on this + # route. i.e. If this route changes then the affected GPE + # offset bits also need to be changed. + register "pmc_gpe0_dw0" = "GPP_B" + register "pmc_gpe0_dw1" = "GPP_F" + register "pmc_gpe0_dw2" = "GPP_E" + + # FSP configuration + register "SaGv" = "SaGv_Disabled" + + # Enable IBECC for the complete memory + register "ibecc" = "{ + .enable = 1, + .mode = IBECC_ALL + }" + + # USB related UPDs + register "usb2_ports[0]" = "USB2_PORT_MID(OC2)" # X125/X135 + register "usb2_ports[1]" = "USB2_PORT_MID(OC2)" # X125/X135 + register "usb2_ports[2]" = "USB2_PORT_MID(OC0)" # X145/X155 + register "usb2_ports[3]" = "USB2_PORT_MID(OC0)" # X145/X155 + register "usb2_ports[4]" = "USB2_PORT_MID(OC3)" # USB Panel + register "usb2_ports[5]" = "USB2_PORT_MID(OC3)" # USB Panel + register "usb2_ports[6]" = "USB2_PORT_EMPTY" + register "usb2_ports[7]" = "USB2_PORT_EMPTY" + register "usb2_ports[8]" = "USB2_PORT_EMPTY" + register "usb2_ports[9]" = "USB2_PORT_EMPTY" + + register "usb3_ports[0]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/2 Type A port1 + register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/2 Type A port2 + register "usb3_ports[2]" = "USB3_PORT_EMPTY" # UNUSED + register "usb3_ports[3]" = "USB3_PORT_EMPTY" # UNUSED + + # Skip the CPU replacement check + register "SkipCpuReplacementCheck" = "1" + + # PCIe root ports related UPDs + register "PcieClkSrcUsage[0]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[1]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[2]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[3]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcUsage[4]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[5]" = "PCIE_CLK_FREE" + + register "PcieClkSrcClkReq[0]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[1]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[2]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[3]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[4]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[5]" = "PCIE_CLK_NOTUSED" + + # Disable all L1 substates for PCIe root ports + register "PcieRpL1Substates[0]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[1]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[2]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[4]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[6]" = "L1_SS_DISABLED" + + # Disable LTR for all PCIe root ports + register "PcieRpLtrDisable[0]" = "true" + register "PcieRpLtrDisable[1]" = "true" + register "PcieRpLtrDisable[2]" = "true" + register "PcieRpLtrDisable[4]" = "true" + register "PcieRpLtrDisable[6]" = "true" + + # Enable PCIe PTM (Precision Time Measurement) for all PCIe root ports + register "PciePtm[0]" = "true" + register "PciePtm[1]" = "true" + register "PciePtm[2]" = "true" + register "PciePtm[4]" = "true" + register "PciePtm[6]" = "true" + + # Determine PCIe root port speed + register "PcieRpPcieSpeed[6]" = "2" + + # Storage (SATA/SDCARD/EMMC) related UPDs + register "SataSalpSupport" = "0" + register "SataPortsEnable[1]" = "1" + register "SataPortsDevSlp[1]" = "0" + register "SataPortsSSD[1]" = "1" + register "SataSpeed" = "SATA_GEN2" + + register "ScsEmmcHs400Enabled" = "0" + register "ScsEmmcDdr50Enabled" = "1" + register "SdCardPowerEnableActiveHigh" = "1" + + # GPIO for SD card detect + register "sdcard_cd_gpio" = "GPP_G5" + + # LPSS Serial IO (I2C/UART/GSPI) related UPDs + register "SerialIoI2cMode" = "{ + [PchSerialIoIndexI2C0] = PchSerialIoDisabled, + [PchSerialIoIndexI2C1] = PchSerialIoPci, + [PchSerialIoIndexI2C2] = PchSerialIoPci, + [PchSerialIoIndexI2C3] = PchSerialIoDisabled, + [PchSerialIoIndexI2C4] = PchSerialIoPci, + [PchSerialIoIndexI2C5] = PchSerialIoDisabled, + [PchSerialIoIndexI2C6] = PchSerialIoPci, + [PchSerialIoIndexI2C7] = PchSerialIoDisabled, + }" + + register "SerialIoI2cPadsTermination" = "{ + [PchSerialIoIndexI2C1] = 1, + [PchSerialIoIndexI2C2] = 1, + [PchSerialIoIndexI2C4] = 1, + [PchSerialIoIndexI2C6] = 1, + }" + + register "SerialIoUartMode" = "{ + [PchSerialIoIndexUART0] = PchSerialIoPci, + [PchSerialIoIndexUART1] = PchSerialIoPci, + [PchSerialIoIndexUART2] = PchSerialIoPci, + }" + + register "SerialIoUartDmaEnable" = "{ + [PchSerialIoIndexUART0] = 1, + [PchSerialIoIndexUART1] = 1, + [PchSerialIoIndexUART2] = 1, + }" + + # TSN GBE related UPDs + register "PchTsnGbeLinkSpeed" = "Tsn_1_Gbps" + register "PchTsnGbeSgmiiEnable" = "1" + register "PseDmaOwn[0]" = "Host_Owned" + + # FIVR related settings + register "fivr" = "{ + .fivr_config_en = true, + .vcc_low_high_us = 50, + }" + + # Disable L1 prefetcher for real-time demands + register "L1_prefetcher_disable" = "true" + + # Enable real-time tuning + register "realtime_tuning_enable" = "true" + + device domain 0 on + device pci 00.0 on end # Host Bridge + device pci 02.0 on end # Integrated Graphics Device + + device pci 10.0 on # I2C6 + # Add dummy I2C device to limit BUS speed to 100 kHz in OS + chip drivers/i2c/generic + register "hid" = ""PRP0001"" + register "speed" = "I2C_SPEED_STANDARD" + device i2c 0x7f on end + end + end + + device pci 14.0 on end # USB3.1 xHCI + + device pci 15.1 on # I2C1 + # Enable external RTC chip + chip drivers/i2c/rv3028c7 + register "bus_speed" = "I2C_SPEED_STANDARD" + register "set_user_date" = "1" + register "user_year" = "04" + register "user_month" = "07" + register "user_day" = "01" + register "user_weekday" = "4" + register "bckup_sw_mode" = "BACKUP_SW_LEVEL" + register "cap_charge" = "CHARGE_OFF" + device i2c 0x52 on end # RTC RV3028-C7 + end + # Add dummy I2C device to limit BUS speed to 100 kHz in OS + chip drivers/i2c/generic + register "hid" = ""PRP0001"" + register "speed" = "I2C_SPEED_STANDARD" + device i2c 0x7f on end + end + end + device pci 15.2 on # I2C2 + # Add dummy I2C device to limit BUS speed to 100 kHz in OS + chip drivers/i2c/generic + register "hid" = ""PRP0001"" + register "speed" = "I2C_SPEED_STANDARD" + device i2c 0x7f on end + end + end + + device pci 16.0 hidden end # Management Engine Interface 1 + + device pci 17.0 on end # SATA + + device pci 19.0 on # I2C4 + # Add dummy I2C device to limit BUS speed to 100 kHz in OS + chip drivers/i2c/generic + register "hid" = ""PRP0001"" + register "speed" = "I2C_SPEED_STANDARD" + device i2c 0x7f on end + end + end + device pci 19.2 on end # UART2 + + device pci 1a.0 on end # eMMC + device pci 1a.1 on end # SD + + device pci 1c.0 on end # RP1 (pcie0 single VC) + device pci 1c.1 on end # RP2 (pcie0 single VC) + device pci 1c.2 on end # RP3 (pcie0 single VC) + device pci 1c.4 on end # RP5 (pcie1 multi VC) + device pci 1c.6 on end # RP7 (pcie3 multi VC) + + device pci 1d.0 off end # Intel PSE IPC (local host to PSE) + device pci 1d.1 on # Intel PSE Time-Sensitive Networking GbE 0 + # Enable external Marvell PHY 88E1512 + chip drivers/net/phy/m88e1512 + register "configure_leds" = "true" + # LED[0]: On - 1000 Mbps Link, Off - Else + register "led_0_ctrl" = "7" + # LED[1]: On - 100 Mbps Link, Off - Else + register "led_1_ctrl" = "7" + # LED[2]: Blink - Activity, Off - No Activity + register "led_2_ctrl" = "4" + # INTn is not routed to LED[2] pin + register "enable_int" = "false" + register "downshift_cnt" = "2" + device mdio 0 on # PHY address + ops m88e1512_ops + end + end + end + + device pci 1e.0 on end # UART0 + device pci 1e.1 on end # UART1 + device pci 1e.4 on # PCH Time-Sensitive Networking GbE + # Enable external Marvell PHY 88E1512 + chip drivers/net/phy/m88e1512 + register "configure_leds" = "true" + # LED[0]: On - 1000 Mbps Link, Off - Else + register "led_0_ctrl" = "7" + # LED[1]: On - 100 Mbps Link, Off - Else + register "led_1_ctrl" = "7" + # LED[2]: Blink - Activity, Off - No Activity + register "led_2_ctrl" = "4" + # INTn is not routed to LED[2] pin + register "enable_int" = "false" + register "downshift_cnt" = "2" + device mdio 1 on # PHY address + ops m88e1512_ops + end + end + end + + device pci 1f.0 on # eSPI Interface + chip drivers/pc80/tpm + device pnp 0c31.0 on end + end + end + device pci 1f.2 hidden end # Power Management Controller + device pci 1f.4 on end # SMBus + device pci 1f.5 on end # PCH SPI (flash & TPM) + end +end diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c new file mode 100644 index 0000000000..49f737b868 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +/* Pad configuration in ramstage */ +static const struct pad_config gpio_table[] = { + /* Community 0 - GpioGroup GPP_B */ + PAD_CFG_NF(GPP_B2, NONE, PLTRST, NF1), /* PMC_VRALERT_N */ + PAD_CFG_NF(GPP_B3, NONE, PLTRST, NF4), /* ESPI_ALERT0_N */ + PAD_NC(GPP_B4, NONE), /* Not connected */ + PAD_NC(GPP_B9, NONE), /* Not connected */ + PAD_NC(GPP_B10, NONE), /* Not connected */ + PAD_CFG_NF(GPP_B11, NONE, PLTRST, NF1), /* PMC_ALERT_N */ + PAD_NC(GPP_B14, NONE), /* Not connected */ + PAD_NC(GPP_B15, NONE), /* Not connected */ + PAD_NC(GPP_B18, NONE), /* Not connected */ + PAD_NC(GPP_B19, NONE), /* Not connected */ + PAD_CFG_NF(GPP_B23, NONE, PLTRST, NF2), /* PCHHOT_N */ + + /* Community 0 - GpioGroup GPP_T */ + PAD_CFG_NF(GPP_T4, NONE, DEEP, NF1), /* PSE_GBE0_INT */ + PAD_CFG_GPO(GPP_T5, 1, DEEP), /* PSE_GBE0_RST_N */ + PAD_CFG_NF(GPP_T6, NONE, DEEP, NF1), /* PSE_GBE0_AUXTS */ + PAD_CFG_NF(GPP_T7, NONE, DEEP, NF1), /* PSE_GBE0_PPS */ + PAD_CFG_NF(GPP_T12, NONE, DEEP, NF2), /* SIO_UART0_RXD */ + PAD_CFG_NF(GPP_T13, NONE, DEEP, NF2), /* SIO_UART0_TXD */ + + /* Community 0 - GpioGroup GPP_G */ + PAD_NC(GPP_G8, NONE), /* Not connected */ + PAD_NC(GPP_G9, NONE), /* Not connected */ + PAD_CFG_GPI(GPP_G19, UP_20K, PLTRST), /* TPM_IRQ_N */ + + /* Community 1 - GpioGroup GPP_V */ + PAD_CFG_NF(GPP_V0, UP_20K, DEEP, NF1), /* EMMC_CMD */ + PAD_CFG_NF(GPP_V1, UP_20K, DEEP, NF1), /* EMMC_DATA0 */ + PAD_CFG_NF(GPP_V2, UP_20K, DEEP, NF1), /* EMMC_DATA1 */ + PAD_CFG_NF(GPP_V3, UP_20K, DEEP, NF1), /* EMMC_DATA2 */ + PAD_CFG_NF(GPP_V4, UP_20K, DEEP, NF1), /* EMMC_DATA3 */ + PAD_CFG_NF(GPP_V5, UP_20K, DEEP, NF1), /* EMMC_DATA4 */ + PAD_CFG_NF(GPP_V6, UP_20K, DEEP, NF1), /* EMMC_DATA5 */ + PAD_CFG_NF(GPP_V7, UP_20K, DEEP, NF1), /* EMMC_DATA6 */ + PAD_CFG_NF(GPP_V8, UP_20K, DEEP, NF1), /* EMMC_DATA7 */ + PAD_CFG_NF(GPP_V9, DN_20K, DEEP, NF1), /* EMMC_RCLK */ + PAD_CFG_NF(GPP_V10, DN_20K, DEEP, NF1), /* EMMC_CLK */ + PAD_CFG_NF(GPP_V11, NONE, DEEP, NF1), /* EMMC_RESET */ + + /* Community 1 - GpioGroup GPP_H */ + PAD_CFG_NF(GPP_H10, NONE, DEEP, NF1), /* PCIE_CLKREQ4_N */ + PAD_CFG_NF(GPP_H11, NONE, DEEP, NF1), /* PCIE_CLKREQ5_N */ + + /* Community 1 - GpioGroup GPP_D */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* PCIE_CLKREQ0_N */ + PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* PCIE_CLKREQ1_N */ + PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* PCIE_CLKREQ2_N */ + PAD_CFG_NF(GPP_D8, NONE, DEEP, NF1), /* PCIE_CLKREQ3_N */ + + /* Community 1 - GpioGroup GPP_U */ + PAD_CFG_NF(GPP_U0, NONE, DEEP, NF1), /* GBE_INT */ + PAD_CFG_GPO(GPP_U1, 1, DEEP), /* GBE_RST_N */ + PAD_NC(GPP_U12, NONE), /* Not connected */ + PAD_NC(GPP_U13, NONE), /* Not connected */ + PAD_NC(GPP_U16, NONE), /* Not connected */ + PAD_NC(GPP_U17, NONE), /* Not connected */ + PAD_NC(GPP_U18, NONE), /* Not connected */ + + /* Community 2 - GpioGroup DSW */ + PAD_CFG_NF(GPD1, NONE, PLTRST, NF1), /* ACPRESENT */ + PAD_NC(GPD9, NONE), /* Not connected */ + PAD_NC(GPD11, NONE), /* Not connected */ + + /* Community 3 - GpioGroup GPP_S */ + PAD_NC(GPP_S0, NONE), /* Not connected */ + PAD_NC(GPP_S1, NONE), /* Not connected */ + + /* Community 3 - GpioGroup GPP_A */ + PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD3 */ + PAD_CFG_NF(GPP_A1, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD2 */ + PAD_CFG_NF(GPP_A2, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD1 */ + PAD_CFG_NF(GPP_A3, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD0 */ + PAD_CFG_NF(GPP_A4, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXCLK */ + PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXCTL */ + PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXCLK */ + PAD_CFG_NF(GPP_A7, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD3 */ + PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD2 */ + PAD_CFG_NF(GPP_A9, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD1 */ + PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD0 */ + PAD_CFG_NF(GPP_A23, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXCTL */ + + /* Community 4 - GpioGroup GPP_C */ + PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1), /* PSE_GBE0_MDC */ + PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1), /* PSE_GBE0_MDIO */ + PAD_NC(GPP_C8, NONE), /* Not connected */ + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF4), /* SIO_UART1_RXD */ + PAD_CFG_NF(GPP_C13, NONE, DEEP, NF4), /* SIO_UART1_TXD */ + PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), /* GBE_MDIO */ + PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), /* GBE_MDC */ + + /* Community 4 - GpioGroup GPP_F */ + PAD_NC(GPP_F1, NONE), /* Not connected */ + PAD_NC(GPP_F3, NONE), /* Not connected */ + PAD_NC(GPP_F8, NONE), /* Not connected */ + PAD_NC(GPP_F11, NONE), /* Not connected */ + PAD_NC(GPP_F12, NONE), /* Not connected */ + PAD_NC(GPP_F13, NONE), /* Not connected */ + PAD_NC(GPP_F14, NONE), /* Not connected */ + PAD_NC(GPP_F15, NONE), /* Not connected */ + PAD_NC(GPP_F16, NONE), /* Not connected */ + PAD_NC(GPP_F17, NONE), /* Not connected */ + PAD_CFG_GPO(GPP_F20, 0, DEEP), /* LED_BIOS_DONE */ + + /* Community 4 - GpioGroup GPP_E */ + PAD_NC(GPP_E15, NONE), /* Not connected */ + PAD_NC(GPP_E16, NONE), /* Not connected */ + PAD_NC(GPP_E18, NONE), /* Not connected */ + PAD_NC(GPP_E19, NONE), /* Not connected */ + PAD_NC(GPP_E23, NONE), /* Not connected */ + + /* Community 5 - GpioGroup GPP_R */ + PAD_NC(GPP_R1, NONE), /* Not connected */ + PAD_NC(GPP_R3, NONE), /* Not connected */ +}; + +/* Early pad configuration in bootblock */ +static const struct pad_config early_gpio_table[] = {}; + +const struct pad_config *variant_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(gpio_table); + return gpio_table; +} + +const struct pad_config *variant_early_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(early_gpio_table); + return early_gpio_table; +} diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/mainboard.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/mainboard.c new file mode 100644 index 0000000000..b3846196fc --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/mainboard.c @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include + +#define HOSTCTRL2 0x3E +#define HOSTCTRL2_PRESET (1 << 15) +#define MMC_CAP_BYP 0x810 +#define MMC_CAP_BYP_EN 0x5A +#define MMC_CAP_BYP_REG1 0x814 +#define MMC_CAP_BYP_SDR50 (1 << 13) +#define MMC_CAP_BYP_SDR104 (1 << 14) +#define MMC_CAP_BYP_DDR50 (1 << 15) + +/* Disable SDR104 and SDR50 mode while keeping DDR50 mode enabled. */ +static void disable_sdr_modes(struct resource *res) +{ + write32(res2mmio(res, MMC_CAP_BYP, 0), MMC_CAP_BYP_EN); + clrsetbits32(res2mmio(res, MMC_CAP_BYP_REG1, 0), + MMC_CAP_BYP_SDR104 | MMC_CAP_BYP_SDR50, + MMC_CAP_BYP_DDR50); +} + +void variant_mainboard_final(void) +{ + struct device *dev; + + /* PIR8 register mapping for PCIe root ports + INTA#->PIRQC#, INTB#->PIRQD#, INTC#->PIRQA#, INTD#-> PIRQB# */ + pcr_write16(PID_ITSS, 0x3150, 0x1032); + + /* Disable clock outputs 1-5 (CLKOUT) for XIO2001 PCIe to PCI Bridge. */ + dev = dev_find_device(PCI_VID_TI, PCI_DID_TI_XIO2001, 0); + if (dev) + pci_write_config8(dev, 0xd8, 0x3e); + + dev = pcidev_path_on_root(PCH_DEVFN_SDCARD); + if (dev) { + struct resource *res = probe_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + disable_sdr_modes(res); + + /* Use preset driver strength from preset value + registers. */ + clrsetbits16(res2mmio(res, HOSTCTRL2, 0), 0, + HOSTCTRL2_PRESET); + } + } + + dev = pcidev_path_on_root(PCH_DEVFN_EMMC); + if (dev) { + struct resource *res = probe_resource(dev, PCI_BASE_ADDRESS_0); + if (res) + disable_sdr_modes(res); + } +} + +static void finalize_boot(void *unused) +{ + /* Set coreboot ready LED. */ + gpio_output(GPP_F20, 1); +} + +BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, finalize_boot, NULL); diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/memory.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/memory.c new file mode 100644 index 0000000000..551583394b --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/memory.c @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +static const struct mb_cfg mc_ehl_lpddr4x_memcfg_cfg = { + .dq_map[DDR_CH0] = { + {0xf, 0xf0}, {0xf, 0xf0}, {0xff, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0} + }, + + .dq_map[DDR_CH1] = { + {0xf, 0xf0}, {0xf, 0xf0}, {0xff, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0} + }, + + /* + * The dqs_map arrays map the ddr4 pins to the SoC pins + * for both channels. + * + * the index = pin number on ddr4 part + * the value = pin number on SoC + */ + .dqs_map[DDR_CH0] = {3, 0, 1, 2, 7, 4, 5, 6}, + .dqs_map[DDR_CH1] = {3, 0, 1, 2, 7, 4, 5, 6}, + + /* Baseboard uses 100, 100 and 100 rcomp resistors */ + .rcomp_resistor = {100, 100, 100}, + + .rcomp_targets = {60, 40, 30, 20, 30}, + + /* LPDDR4x does not allow interleaved memory */ + .dq_pins_interleaved = 0, + + /* Baseboard is using config 2 for vref_ca */ + .vref_ca_config = 2, + + /* Enable Early Command Training */ + .ect = 1, + + /* Set Board Type */ + .UserBd = BOARD_TYPE_MOBILE, +}; + +const struct mb_cfg *variant_memcfg_config(void) +{ + return &mc_ehl_lpddr4x_memcfg_cfg; +} diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/post.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/post.c new file mode 100644 index 0000000000..c34e2539bc --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/post.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void mainboard_post(uint8_t value) +{ + nc_fpga_post(value); +} From ddf4748c221e2d11ee186193bdd81cb65551a93e Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Fri, 9 Jan 2026 12:27:16 +0100 Subject: [PATCH 153/789] mb/siemens/mc_ehl7: Deactivate RTC On this mainboard no RTC is assembled. Therefore, it is deactivated. TEST=Boot into OS and verify if relevant I2C Controller is disabled and no error in coreboot log is shown. Change-Id: I23b4a735a09686fa2636280d7b410db59d884c49 Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/90715 Tested-by: build bot (Jenkins) Reviewed-by: Mario Scheithauer --- .../siemens/mc_ehl/variants/mc_ehl7/Kconfig | 1 - .../mc_ehl/variants/mc_ehl7/devicetree.cb | 23 +------------------ 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig index 7cc7c5abee..6ce0b48052 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig @@ -6,7 +6,6 @@ config BOARD_SPECIFIC_OPTIONS def_bool y select DRIVER_INTEL_I210 select DRIVERS_ETH_PHY_M88E1512 - select DRIVERS_I2C_RV3028C7 select EHL_TSN_DRIVER select MAINBOARD_HAS_TPM2 select MEMORY_MAPPED_TPM diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb index 5180770908..776eab22e3 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb @@ -95,7 +95,7 @@ chip soc/intel/elkhartlake # LPSS Serial IO (I2C/UART/GSPI) related UPDs register "SerialIoI2cMode" = "{ [PchSerialIoIndexI2C0] = PchSerialIoDisabled, - [PchSerialIoIndexI2C1] = PchSerialIoPci, + [PchSerialIoIndexI2C1] = PchSerialIoDisabled, [PchSerialIoIndexI2C2] = PchSerialIoPci, [PchSerialIoIndexI2C3] = PchSerialIoDisabled, [PchSerialIoIndexI2C4] = PchSerialIoPci, @@ -105,7 +105,6 @@ chip soc/intel/elkhartlake }" register "SerialIoI2cPadsTermination" = "{ - [PchSerialIoIndexI2C1] = 1, [PchSerialIoIndexI2C2] = 1, [PchSerialIoIndexI2C4] = 1, [PchSerialIoIndexI2C6] = 1, @@ -155,26 +154,6 @@ chip soc/intel/elkhartlake device pci 14.0 on end # USB3.1 xHCI - device pci 15.1 on # I2C1 - # Enable external RTC chip - chip drivers/i2c/rv3028c7 - register "bus_speed" = "I2C_SPEED_STANDARD" - register "set_user_date" = "1" - register "user_year" = "04" - register "user_month" = "07" - register "user_day" = "01" - register "user_weekday" = "4" - register "bckup_sw_mode" = "BACKUP_SW_LEVEL" - register "cap_charge" = "CHARGE_OFF" - device i2c 0x52 on end # RTC RV3028-C7 - end - # Add dummy I2C device to limit BUS speed to 100 kHz in OS - chip drivers/i2c/generic - register "hid" = ""PRP0001"" - register "speed" = "I2C_SPEED_STANDARD" - device i2c 0x7f on end - end - end device pci 15.2 on # I2C2 # Add dummy I2C device to limit BUS speed to 100 kHz in OS chip drivers/i2c/generic From 093ae8eeaa9c67aa2b275daffb527efe4b2c825a Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Fri, 9 Jan 2026 13:47:05 +0100 Subject: [PATCH 154/789] mb/siemens/mc_ehl7: Enable reboot after HW Watchdog expiry Configure the board to perform a hardware reboot when the TCO watchdog expires. This is achieved by using the default Kconfig option SOC_INTEL_ELKHARTLAKE_TCO_NO_REBOOT_EN with 'n'. TEST=Verified in the OS on mc_ehl7: Checked IO-mapped register 0x408 Bit 0. Without this patch, the bit is 1 (No Reboot enabled). With this patch, the bit is 0 (Reboot on expiry enabled). Change-Id: If3bee9db84c92480762f8a802031d2b01541dbdb Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/90716 Tested-by: build bot (Jenkins) Reviewed-by: Mario Scheithauer --- src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig index 6ce0b48052..6524f4855d 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig @@ -36,7 +36,4 @@ config EARLY_PCI_MMIO_BASE depends on NC_FPGA_POST_CODE default 0xfe800000 -config SOC_INTEL_ELKHARTLAKE_TCO_NO_REBOOT_EN - default y - endif # BOARD_SIEMENS_MC_EHL7 From c09352d58d4d815735ae76594633f0ba62e327c3 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 12 Jan 2026 10:40:02 -0800 Subject: [PATCH 155/789] soc/intel/pantherlake: Update PS1 threshold to the latest recommendations Update the PS1 threshold values for VR_DOMAIN_IA, VR_DOMAIN_GT, and VR_DOMAIN_SA from 20 A to 15 A, following the recommendations in the Panther Lake H Platform Design Guide (Draft > 2.1). This change ensures that power state thresholds are consistent with the most recent platform specifications, improving accuracy and system behavior under varying power conditions. TEST=Fatcat device boots to OS. Change-Id: I358d4d94c3800ff5b658cb875c90ee7409d86377 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/90727 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/chipset_ptl.cb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index ccd727d6cd..fb78b88659 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -82,11 +82,11 @@ chip soc/intel/pantherlake register "tdc_time_window_ms[VR_DOMAIN_IA]" = "28000" # Set the power state thresholds according to document 813278 - # Panther Lake H Platform - Design Guide - Rev 2.0 + # Panther Lake H Platform - Design Guide - Draft > 2.1 register "ps1_threshold" = "{ - [VR_DOMAIN_IA] = 20 * 4, - [VR_DOMAIN_GT] = 20 * 4, - [VR_DOMAIN_SA] = 20 * 4 + [VR_DOMAIN_IA] = 15 * 4, + [VR_DOMAIN_GT] = 15 * 4, + [VR_DOMAIN_SA] = 15 * 4 }" register "ps2_threshold" = "{ [VR_DOMAIN_IA] = 5 * 4, From 6fd865f40946fef72a600002e3168295ca884107 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 30 Jun 2025 13:02:03 +0200 Subject: [PATCH 156/789] drivers/amd/ftpm: Add fTPM driver for PSP emulated CRB TPMs The AMD fTPM uses the CRB interface, but doesn't implement all registers defined in the TCG specification. Add a new driver that deals with the reduced register set. The reduced CRB MMIO register space has: - A START register to ring the doorbell - An error STATUS register with only one bit - DMA address and size register for the CRB - No other status or control registers - No way to read current locality (assumption is locality 0) - No interface ID register - No read only registers The TPM interface also assumes that the DRTM is always using locality 0. The fTPM needs to access the SPI flash and this is currently done using the PSP SMI handler. Thus the fTPM will only operate after SMM has been set up. The fTPM needs the PSP directory files type 0x04 and type 0x54. When the regions are missing or corrupted the fTPM won't be operational. Based off https://github.com/teslamotors/coreboot/tree/tesla-4.12-amd TEST=Works on AMD glinda (Fam 1Ah). This adds the following new log messages: [DEBUG] PSP: Querying PSP capabilities...OK [DEBUG] PSP: Querying fTPM capabilities... OK [DEBUG] PSP: Querying fTPM capabilities... OK [DEBUG] TPM: CRB buffer created at 0x7b5ee000 [SPEW ] fTPM: CRB TPM initialized successfully [INFO ] Initialized TPM device fTPM ... [DEBUG] PSP: Querying fTPM capabilities... OK [DEBUG] TPM2 log created at 0x7b5b1000 [DEBUG] PSP: Querying fTPM capabilities... OK [DEBUG] ACPI: * TPM2 [DEBUG] ACPI: added table 4/32, length now 68 Change-Id: I780bdab621228e12b37f3a89868e16bc62a05e7b Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/88247 Reviewed-by: Maximilian Brune Tested-by: build bot (Jenkins) Reviewed-by: Felix Held Reviewed-by: Alicja Michalska --- src/acpi/acpi.c | 13 +- .../bsd/include/commonlib/bsd/cbmem_id.h | 2 + src/drivers/amd/ftpm/Kconfig | 14 + src/drivers/amd/ftpm/Makefile.mk | 7 + src/drivers/amd/ftpm/chip.h | 9 + src/drivers/amd/ftpm/tis.c | 206 ++++++++++++ src/drivers/amd/ftpm/tpm.c | 307 ++++++++++++++++++ src/drivers/amd/ftpm/tpm.h | 31 ++ src/security/tpm/Kconfig | 2 +- src/security/tpm/tss/tss.c | 2 +- src/soc/amd/common/block/psp/psp.c | 4 +- 11 files changed, 591 insertions(+), 6 deletions(-) create mode 100644 src/drivers/amd/ftpm/Kconfig create mode 100644 src/drivers/amd/ftpm/Makefile.mk create mode 100644 src/drivers/amd/ftpm/chip.h create mode 100644 src/drivers/amd/ftpm/tis.c create mode 100644 src/drivers/amd/ftpm/tpm.c create mode 100644 src/drivers/amd/ftpm/tpm.h diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index abdcf26160..13728c904d 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -27,7 +27,11 @@ #include #include #include +#if CONFIG(AMD_CRB_FTPM) +#include +#else #include +#endif #include #include #include @@ -260,7 +264,7 @@ static void acpi_create_tpm2(acpi_header_t *header, void *unused) if (tlcl_get_family() != TPM_2) return; - if (CONFIG(CRB_TPM) && !(CONFIG(SPI_TPM) || CONFIG(I2C_TPM) || CONFIG(MEMORY_MAPPED_TPM))) + if ((CONFIG(CRB_TPM) || CONFIG(AMD_CRB_FTPM)) && !(CONFIG(SPI_TPM) || CONFIG(I2C_TPM) || CONFIG(MEMORY_MAPPED_TPM))) if (!crb_tpm_is_active()) return; @@ -281,7 +285,12 @@ static void acpi_create_tpm2(acpi_header_t *header, void *unused) /* Hard to detect for coreboot. Just set it to 0 */ tpm2->platform_class = 0; - if (CONFIG(CRB_TPM)) { + + if (CONFIG(AMD_CRB_FTPM) && crb_tpm_is_active()) { + /* Must be set to 2 for AMD fTPM Support */ + tpm2->control_area = crb_tpm_base_address() + 0x40; + tpm2->start_method = 2; + } else if (CONFIG(CRB_TPM) && crb_tpm_is_active()) { /* Must be set to 7 for CRB Support */ tpm2->control_area = crb_tpm_base_address() + 0x40; tpm2->start_method = 7; diff --git a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h index a5cb0a7f8a..0431626f2c 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h +++ b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h @@ -67,6 +67,7 @@ #define CBMEM_ID_TIMESTAMP 0x54494d45 #define CBMEM_ID_TPM2_TCG_LOG 0x54504d32 /* TPM log per TPM 2.0 specification */ #define CBMEM_ID_TPM_PPI 0x54505049 +#define CBMEM_ID_TPM2_CRB 0x43524220 #define CBMEM_ID_VBOOT_HANDOFF 0x780074f0 /* deprecated */ #define CBMEM_ID_VBOOT_SEL_REG 0x780074f1 /* deprecated */ #define CBMEM_ID_VBOOT_WORKBUF 0x78007343 @@ -153,6 +154,7 @@ { CBMEM_ID_TIMESTAMP, "TIME STAMP " }, \ { CBMEM_ID_TPM2_TCG_LOG, "TPM2 TCGLOG" }, \ { CBMEM_ID_TPM_PPI, "TPM PPI " }, \ + { CBMEM_ID_TPM2_CRB, "TPM CRB " }, \ { CBMEM_ID_VBOOT_HANDOFF, "VBOOT " }, \ { CBMEM_ID_VBOOT_SEL_REG, "VBOOT SEL " }, \ { CBMEM_ID_VBOOT_WORKBUF, "VBOOT WORK " }, \ diff --git a/src/drivers/amd/ftpm/Kconfig b/src/drivers/amd/ftpm/Kconfig new file mode 100644 index 0000000000..9e9c382572 --- /dev/null +++ b/src/drivers/amd/ftpm/Kconfig @@ -0,0 +1,14 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config AMD_CRB_FTPM + bool + default n + depends on !CRB_TPM + depends on SOC_AMD_COMMON_BLOCK_PSP_GEN2 + # The fTPM needs to access the SPI flash when ROM Armor + # is not being used, thus select SOC_AMD_COMMON_BLOCK_PSP_SMI. + select SOC_AMD_COMMON_BLOCK_PSP_SMI + help + Mainboard has AMD fTPM with Command Response Buffer support. + The fTPM is based on the CRB interface as defined by TCG, + but with reduced set of registers being implemented. diff --git a/src/drivers/amd/ftpm/Makefile.mk b/src/drivers/amd/ftpm/Makefile.mk new file mode 100644 index 0000000000..87f649b67c --- /dev/null +++ b/src/drivers/amd/ftpm/Makefile.mk @@ -0,0 +1,7 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ifeq ($(CONFIG_AMD_CRB_FTPM),y) +# Currently depends on SOC_AMD_COMMON_BLOCK_PSP_SMI, that means +# fTPM is only accepting commands after SMM has been set up. +ramstage-y += tis.c tpm.c +endif diff --git a/src/drivers/amd/ftpm/chip.h b/src/drivers/amd/ftpm/chip.h new file mode 100644 index 0000000000..7e69509269 --- /dev/null +++ b/src/drivers/amd/ftpm/chip.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef DRIVERS_AMD_FTPM_CHIP_H +#define DRIVERS_AMD_FTPM_CHIP_H + +struct drivers_amd_ftpm_config { +}; + +#endif /* DRIVERS_AMD_FTPM_CHIP_H */ diff --git a/src/drivers/amd/ftpm/tis.c b/src/drivers/amd/ftpm/tis.c new file mode 100644 index 0000000000..0f0dd5c899 --- /dev/null +++ b/src/drivers/amd/ftpm/tis.c @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tpm.h" +#include "chip.h" + +static const char *tis_get_dev_name(void) +{ + return "fTPM"; +} + +static tpm_result_t crb_tpm_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, uint8_t *recvbuf, + size_t *rbuf_len) +{ + int len = crb_tpm_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len); + + if (len <= 0) + return TPM_CB_FAIL; + + *rbuf_len = len; + + return TPM_SUCCESS; +} + +tis_sendrecv_fn crb_tis_probe(enum tpm_family *family) +{ + /* Wake TPM up (if necessary) */ + if (crb_tpm_init()) + return NULL; + + /* CRB interface exists only in TPM2 */ + if (family != NULL) + *family = TPM_2; + + printk(BIOS_INFO, "Initialized TPM device %s\n", tis_get_dev_name()); + + return &crb_tpm_sendrecv; +} + +static void tpm_start_func0_cb(void *arg) +{ + /* Function 1. */ + acpigen_write_return_singleton_buffer(0x3); +} +static void tpm_start_func1_cb(void *arg) +{ + /* Just return success. fTPM is already operational. */ + acpigen_write_return_byte(0); +} + +static void (*tpm_start_callbacks[])(void *) = { + tpm_start_func0_cb, + tpm_start_func1_cb, +}; + +#define TPM_START_UUID "6bbf6cab-5463-4714-b7cd-f0203c0368d4" + +static void crb_tpm_fill_ssdt(const struct device *dev) +{ + assert(dev->path.type == DEVICE_PATH_MMIO); + assert(dev->path.mmio.addr == crb_tpm_base_address()); + + /* Device */ + acpigen_write_scope("\\_SB"); + acpigen_write_device(acpi_device_name(dev)); + + acpigen_write_name_string("_HID", "MSFT0101"); + acpigen_write_name_string("_CID", "MSFT0101"); + + acpi_device_write_uid(dev); + + if (crb_tpm_is_active()) + acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON); + else + acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_OFF); + + /* Resources */ + acpigen_write_name("_CRS"); + acpigen_write_resourcetemplate_header(); + acpigen_write_mem32fixed(1, read32(CRB_REG(CRB_REG_CMD_ADDR)), + read32(CRB_REG(CRB_REG_CMD_SIZE))); + acpigen_write_mem32fixed(1, read32(CRB_REG(CRB_REG_RESP_ADDR)), + read32(CRB_REG(CRB_REG_RESP_SIZE))); + acpigen_write_resourcetemplate_footer(); + + /* + * _DSM method + */ + struct dsm_uuid ids[] = { + DSM_UUID(TPM_START_UUID, tpm_start_callbacks, + ARRAY_SIZE(tpm_start_callbacks), NULL), + }; + + acpigen_write_dsm_uuid_arr(ids, ARRAY_SIZE(ids)); + + acpigen_pop_len(); /* Device */ + acpigen_pop_len(); /* Scope */ +} + +static const char *crb_tpm_acpi_name(const struct device *dev) +{ + return "TPM2"; +} + +#if CONFIG(GENERATE_SMBIOS_TABLES) +static tpm_result_t tpm_get_cap(uint32_t property, uint32_t *value) +{ + TPMS_CAPABILITY_DATA cap_data; + int i; + tpm_result_t rc; + + if (!value) + return TPM_CB_INVALID_ARG; + + rc = tlcl2_get_capability(TPM_CAP_TPM_PROPERTIES, property, 1, &cap_data); + + if (rc) + return rc; + + for (i = 0; i < cap_data.data.tpmProperties.count; i++) { + if (cap_data.data.tpmProperties.tpmProperty[i].property == property) { + *value = cap_data.data.tpmProperties.tpmProperty[i].value; + return TPM_SUCCESS; + } + } + + return TPM_CB_FAIL; +} + +static int smbios_write_type43_tpm(struct device *dev, int *handle, unsigned long *current) +{ + uint32_t tpm_manuf, tpm_family; + uint32_t fw_ver1, fw_ver2; + uint8_t major_spec_ver, minor_spec_ver; + + /* Vendor ID is the value returned by TPM2_GetCapabiltiy TPM_PT_MANUFACTURER */ + if (tpm_get_cap(TPM_PT_MANUFACTURER, &tpm_manuf)) { + printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_MANUFACTURER failed\n"); + return 0; + } + + tpm_manuf = be32toh(tpm_manuf); + + if (tpm_get_cap(TPM_PT_FIRMWARE_VERSION_1, &fw_ver1)) { + printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_FIRMWARE_VERSION_1 failed\n"); + return 0; + } + + if (tpm_get_cap(TPM_PT_FIRMWARE_VERSION_2, &fw_ver2)) { + printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_FIRMWARE_VERSION_2 failed\n"); + return 0; + } + + if (tpm_get_cap(TPM_PT_FAMILY_INDICATOR, &tpm_family)) { + printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_FAMILY_INDICATOR failed\n"); + return 0; + } + + tpm_family = be32toh(tpm_family); + + if (!strncmp((char *)&tpm_family, "2.0", 4)) { + major_spec_ver = 2; + minor_spec_ver = 0; + } else { + printk(BIOS_ERR, "%s: Invalid TPM family\n", __func__); + return 0; + } + + return smbios_write_type43(current, handle, tpm_manuf, major_spec_ver, minor_spec_ver, + fw_ver1, fw_ver2, tis_get_dev_name(), + SMBIOS_TPM_DEVICE_CHARACTERISTICS_NOT_SUPPORTED, 0); +} +#endif + +static struct device_operations __maybe_unused amd_crb_ops = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_name = crb_tpm_acpi_name, + .acpi_fill_ssdt = crb_tpm_fill_ssdt, +#endif +#if CONFIG(GENERATE_SMBIOS_TABLES) + .get_smbios_data = smbios_write_type43_tpm, +#endif +}; + +static void enable_dev(struct device *dev) +{ +#if !DEVTREE_EARLY + dev->ops = &amd_crb_ops; +#endif +} + +struct chip_operations drivers_amd_ftpm_ops = { + .name = "AMD CRB fTPM", + .enable_dev = enable_dev +}; diff --git a/src/drivers/amd/ftpm/tpm.c b/src/drivers/amd/ftpm/tpm.c new file mode 100644 index 0000000000..e5ab0dea39 --- /dev/null +++ b/src/drivers/amd/ftpm/tpm.c @@ -0,0 +1,307 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * This is a driver for the AMD fTPM CRB Interface. + * + * The AMD fTPM uses the CRB interface, but doesn't implement all registers + * defined in the TCG specification. + * + * The reduced CRB MMIO register space has: + * - A START register to ring the doorbell + * - An error STATUS register with only one bit + * - DMA address and size register for the CRB + * - No other status or control registers + * - No way to read current locality (assumption is locality 0) + * - No interface ID register + * - No read only registers + * + * The TPM interface also assumes that the DRTM is always using locality 0. + * + * The fTPM needs to access the SPI flash and this is currently done using + * the PSP SMI handler. Thus the fTPM will only operate after SMM has been + * set up. + * + * The fTPM needs the PSP directory files type 0x04 and type 0x54. When + * the regions are missing or corrupted the fTPM won't be operational. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tpm.h" + +/* FMAP regions used */ +#define FMAP_NAME_PSP_NVRAM "PSP_NVRAM" +#define FMAP_NAME_PSP_RPMC_NVRAM "PSP_RPMC_NVRAM" + +/* Size of DMA buffer in DRAM */ +#define FTPM_CRB_SIZE (4 * 4096) + +/* Index of Count field in TPM response buffer */ +#define TPM_RSP_SIZE_BYTE 2 + +static struct control_area { + uint32_t start; + uint32_t command_size; + void *command_bfr; + uint32_t response_size; + void *response_bfr; +} control_area; + +/* Read Control Area Structure back */ +static void crb_read_control_area(void) +{ + control_area.command_size = read32(CRB_REG(CRB_REG_CMD_SIZE)); + control_area.command_bfr = + (void *)(uintptr_t)read64(CRB_REG(CRB_REG_CMD_ADDR)); + control_area.response_size = read32(CRB_REG(CRB_REG_RESP_SIZE)); + control_area.response_bfr = + (void *)(uintptr_t)read64(CRB_REG(CRB_REG_RESP_ADDR)); +} + +/* Wait for reg to be expected value */ +static tpm_result_t crb_wait_for_reg32(const void *addr, + uint32_t timeout_ms, + uint32_t mask, + uint32_t expected_value) +{ + uint32_t reg_value; + struct stopwatch sw; + + // Set up a timer which breaks the loop after timeout + stopwatch_init_msecs_expire(&sw, timeout_ms); + + while (1) { + // Now check if the TPM is in IDLE mode + reg_value = read32(addr); + + if ((reg_value & mask) == expected_value) + return TPM_SUCCESS; + + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, + "fTPM: Timed out with reg_value: %08x, mask: %08x, expected: %08x\n", + reg_value, mask, expected_value); + return TPM_CB_TIMEOUT; + } + } +} + +static int erase_region(const char *name) +{ + struct region_device store; + + if (fmap_locate_area_as_rdev_rw(name, &store)) { + printk(BIOS_ERR, "fTPM: Unable to find FMAP region %s\n", name); + return -1; + } + + if (rdev_eraseat(&store, 0, region_device_sz(&store)) + != region_device_sz(&store)) + return -1; + + printk(BIOS_NOTICE, "fTPM: Erased FMAP region %s\n", name); + + return 0; +} + +/* + * crb_tpm_init + * + * Even though the TPM does not need an initialization we check + * if the TPM responds and is in IDLE mode, which should be the + * normal bring up mode. + */ +tpm_result_t crb_tpm_init(void) +{ + bool psp_rpmc_nvram, psp_nvram, psp_dir; + + /* + * When recovery is required psp_ftpm_is_active() always returns false. + * Thus handle recovery before checking if fTPM is usable. + */ + psp_ftpm_needs_recovery(&psp_rpmc_nvram, &psp_nvram, &psp_dir); + + if (psp_rpmc_nvram) { + if (erase_region(FMAP_NAME_PSP_RPMC_NVRAM)) + psp_rpmc_nvram = false; /* Skip reset if erase failed */ + } + + if (psp_nvram) { + if (erase_region(FMAP_NAME_PSP_NVRAM)) + psp_nvram = false; /* Skip reset if erase failed */ + } + + if (psp_rpmc_nvram || psp_nvram) { + printk(BIOS_DEBUG, "fTPM: Reset to recover fTPM...\n"); + cold_reset(); + } + + if (psp_dir) { + printk(BIOS_ERR, "fTPM: fTPM driver corrupted. Need FW update.\n"); + return CB_ERR; + } + + if (!psp_ftpm_is_active()) + return CB_ERR_NOT_IMPLEMENTED; + + if (ENV_HAS_CBMEM) { + /* setting up fTPM communication buffers in cbmem */ + const struct cbmem_entry *entry; + void *buf; + uint32_t length = 2 * FTPM_CRB_SIZE; + + /* Only allocate once */ + entry = cbmem_entry_find(CBMEM_ID_TPM2_CRB); + if (entry) { + buf = cbmem_entry_start(entry); + length = cbmem_entry_size(entry); + } else { + buf = cbmem_add(CBMEM_ID_TPM2_CRB, length); + if (!buf) { + printk(BIOS_ERR, "fTPM: CBMEM CRB buffer allocation failed\n"); + return CB_ERR; + } + printk(BIOS_DEBUG, "fTPM: CRB buffer created at %p\n", buf); + memset(buf, 0, length); + } + + /* Set command/response buffers in control area */ + write32(CRB_REG(CRB_REG_CMD_SIZE), FTPM_CRB_SIZE); + write64(CRB_REG(CRB_REG_CMD_ADDR), (uintptr_t)buf); + write32(CRB_REG(CRB_REG_RESP_SIZE), FTPM_CRB_SIZE); + write64(CRB_REG(CRB_REG_RESP_ADDR), (uintptr_t)buf + FTPM_CRB_SIZE); + + /* + * The OS will read the CRB registers to find the communication + * buffers. No need to advertise it in ACPI. + */ + } + + /* Read back control area structure */ + crb_read_control_area(); + + /* Opt out when CRB hasn't been set up yet */ + if (!control_area.command_size || !control_area.response_size) + return CB_ERR_NOT_IMPLEMENTED; + + /* Good to go. */ + printk(BIOS_SPEW, "fTPM: CRB TPM initialized successfully\n"); + + return TPM_SUCCESS; +} + +/* + * crb_tpm_process_command + * + * Transfers data to and from the fTPM. + * + */ +size_t crb_tpm_process_command(const void *tpm2_command, size_t command_size, + void *tpm2_response, size_t max_response) +{ + uint32_t rsp_size; + tpm_result_t rc; + + if (!control_area.response_size || !control_area.command_size) { + printk(BIOS_ERR, "%s: Control area wasn't set up yet\n", __func__); + return -1; + } + if (command_size > control_area.command_size) { + printk(BIOS_ERR, "%s: Command size is too big: %zu > %u.\n", + __func__, command_size, control_area.command_size); + return -1; + } + + /* Check if CMD bit is cleared. */ + rc = crb_wait_for_reg32(CRB_REG(CRB_REG_START), 250, CRB_REG_START_START, 0x0); + if (rc) { + printk(BIOS_ERR, "%s: Cmd Bit didn't clear\n", __func__); + return -1; + } + + /* Write to Command Buffer */ + memcpy(control_area.command_bfr, tpm2_command, command_size); + + /* Clear Response buffer */ + memset(control_area.response_bfr, 0, control_area.response_size); + + /* Set Response size */ + write32(CRB_REG(CRB_REG_RESP_SIZE), control_area.response_size); + + /* Write Start Bit */ + write8(CRB_REG(CRB_REG_START), CRB_REG_START_START); + + /* Poll for Response */ + rc = crb_wait_for_reg32(CRB_REG(CRB_REG_START), 3500, CRB_REG_START_START, 0); + if (rc) { + printk(BIOS_DEBUG, "%s: Timeout waiting for CMD processing\n", __func__); + return -1; + } + + /* Check for errors */ + rc = read32(CRB_REG(CRB_REG_STATUS)); + if (rc & CRB_REG_STATUS_ERROR) { + printk(BIOS_DEBUG, "fTPM Error (%#x): Command errored.\n", rc); + return -1; + } + + /* Get Response Length. Seems to be static on some platforms. */ + uint32_t length = read32(CRB_REG(CRB_REG_RESP_SIZE)); + assert(length <= control_area.response_size); + + /* Response has to have at least 6 bytes */ + if (length < 6) { + printk(BIOS_DEBUG, "fTPM Error: Invalid response length: %u\n", length); + return -1; + } + + /* Get actual size from TPM packet */ + memcpy(&rsp_size, control_area.response_bfr + TPM_RSP_SIZE_BYTE, sizeof(rsp_size)); + rsp_size = be32_to_cpu(rsp_size); + if ((size_t)rsp_size > max_response) { + printk(BIOS_DEBUG, "fTPM Error: Response wouldn't fit into target buffer: %u > %zu\n", + rsp_size, max_response); + return -1; + } + + /* Copy Response */ + length = MIN(length, MIN(max_response, rsp_size)); + memcpy(tpm2_response, control_area.response_bfr, length); + + return length; +} + +/* + * crb_tpm_is_active + * + * Checks that CRB interface is available and active. + */ +bool crb_tpm_is_active(void) +{ + if (!psp_ftpm_is_active()) + return false; + + /* Read back control area structure */ + crb_read_control_area(); + + /* Validate fields */ + if (!control_area.command_size || !control_area.response_size || + !control_area.command_bfr || !control_area.response_bfr || + (control_area.command_bfr == (void *)-1) || + (control_area.response_bfr == (void *)-1)) + return false; + + return true; +} + +uintptr_t crb_tpm_base_address(void) +{ + return psp_ftpm_base_address(); +} diff --git a/src/drivers/amd/ftpm/tpm.h b/src/drivers/amd/ftpm/tpm.h new file mode 100644 index 0000000000..aaae99eb34 --- /dev/null +++ b/src/drivers/amd/ftpm/tpm.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* This is a driver for a Command Response Buffer Interface + * as found on AMD fTPMs. It only implements a small subset + * of the registers defined in the TCG specification. + */ + +#include +#include +#include + +/* CRB hardware registers */ +#define CRB_REG_STATUS 0x44 +#define CRB_REG_STATUS_ERROR 0x01 +#define CRB_REG_START 0x4C +#define CRB_REG_START_START 0x01 +#define CRB_REG_CMD_SIZE 0x58 +#define CRB_REG_CMD_ADDR 0x5C +#define CRB_REG_RESP_SIZE 0x64 +#define CRB_REG_RESP_ADDR 0x68 + +/* address of locality 0 (CRB) */ +#define CRB_REG(REG) ((void *)(uintptr_t)(psp_ftpm_base_address() + (REG))) + +tpm_result_t crb_tpm_init(void); +size_t crb_tpm_process_command(const void *tpm2_command, size_t command_size, + void *tpm2_response, size_t max_response); +bool crb_tpm_is_active(void); + +tis_sendrecv_fn crb_tis_probe(enum tpm_family *family); + +uintptr_t crb_tpm_base_address(void); diff --git a/src/security/tpm/Kconfig b/src/security/tpm/Kconfig index c8eb446839..a53163dd05 100644 --- a/src/security/tpm/Kconfig +++ b/src/security/tpm/Kconfig @@ -22,7 +22,7 @@ config TPM1 config TPM2 bool "TPM 2.0" - depends on I2C_TPM || MEMORY_MAPPED_TPM || SPI_TPM || CRB_TPM + depends on I2C_TPM || MEMORY_MAPPED_TPM || SPI_TPM || CRB_TPM || AMD_CRB_FTPM default y if MAINBOARD_HAS_TPM2 help Select this option if your TPM uses the newer TPM 2.0 protocol. diff --git a/src/security/tpm/tss/tss.c b/src/security/tpm/tss/tss.c index 8e52de73e9..f4deb2d633 100644 --- a/src/security/tpm/tss/tss.c +++ b/src/security/tpm/tss/tss.c @@ -29,7 +29,7 @@ tpm_result_t tlcl_lib_init(void) init_done = true; tlcl_tis_sendrecv = NULL; - if (CONFIG(CRB_TPM)) + if (CONFIG(CRB_TPM) || CONFIG(AMD_CRB_FTPM)) tlcl_tis_sendrecv = crb_tis_probe(&tlcl_tpm_family); if (CONFIG(MEMORY_MAPPED_TPM) && tlcl_tis_sendrecv == NULL) tlcl_tis_sendrecv = pc80_tis_probe(&tlcl_tpm_family); diff --git a/src/soc/amd/common/block/psp/psp.c b/src/soc/amd/common/block/psp/psp.c index 9ad04e1ce6..98eb0f9e84 100644 --- a/src/soc/amd/common/block/psp/psp.c +++ b/src/soc/amd/common/block/psp/psp.c @@ -64,7 +64,7 @@ enum cb_err psp_get_ftpm_capabilties(uint32_t *capabilities) }, }; - printk(BIOS_DEBUG, "PSP: Querying fTPM capabilities..."); + printk(BIOS_DEBUG, "PSP: Querying fTPM capabilities... "); cmd_status = send_psp_command(MBOX_BIOS_CMD_PSP_FTPM_QUERY, &buffer); @@ -87,7 +87,7 @@ enum cb_err psp_get_hsti_state(uint32_t *state) }, }; - printk(BIOS_DEBUG, "PSP: Querying HSTI state..."); + printk(BIOS_DEBUG, "PSP: Querying HSTI state... "); cmd_status = send_psp_command(MBOX_BIOS_CMD_HSTI_QUERY, &buffer); From b741e2274e4b3dd677ee55c4875c420cc8d3a71a Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Wed, 8 Oct 2025 12:36:30 +0200 Subject: [PATCH 157/789] acpi: Add enums for TPM2 start method Based on the "TCG ACPI Specification" Version 1.3 published 2021. Add an enum for the ACPI start methods and use it instead of hardcoding various numbers in plain code. Change-Id: I8b66527ee7417e231fe52e0a609b8c100de522b0 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/89458 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/acpi/acpi.c | 9 +++------ src/include/acpi/acpi.h | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index 13728c904d..94b6309261 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -287,17 +287,14 @@ static void acpi_create_tpm2(acpi_header_t *header, void *unused) tpm2->platform_class = 0; if (CONFIG(AMD_CRB_FTPM) && crb_tpm_is_active()) { - /* Must be set to 2 for AMD fTPM Support */ tpm2->control_area = crb_tpm_base_address() + 0x40; - tpm2->start_method = 2; + tpm2->start_method = ACPI_TPM2_SM_ACPI_START; } else if (CONFIG(CRB_TPM) && crb_tpm_is_active()) { - /* Must be set to 7 for CRB Support */ tpm2->control_area = crb_tpm_base_address() + 0x40; - tpm2->start_method = 7; + tpm2->start_method = ACPI_TPM2_SM_CRB; } else { - /* Must be set to 0 for FIFO interface support */ tpm2->control_area = 0; - tpm2->start_method = 6; + tpm2->start_method = ACPI_TPM2_SM_MMIO_TIS; } memset(tpm2->msp, 0, sizeof(tpm2->msp)); diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h index 87c99a1eb3..ac00050031 100644 --- a/src/include/acpi/acpi.h +++ b/src/include/acpi/acpi.h @@ -243,6 +243,20 @@ typedef struct acpi_tcpa { u64 lasa; } __packed acpi_tcpa_t; +/* TCG ACPI Specification "Table 8: Start Method values for ACPI table for TPM 2.0" */ +enum acpi_tpm2_start_methods { + ACPI_TPM2_SM_NOT_ALLOWED = 0, + ACPI_TPM2_SM_LEGACY, + ACPI_TPM2_SM_ACPI_START, + ACPI_TPM2_SM_MMIO_TIS = 6, + ACPI_TPM2_SM_CRB, + ACPI_TPM2_SM_CRB_AND_ACPI_START, + ACPI_TPM2_SM_CRB_AND_ARM_SECURE_MONITOR = 11, + ACPI_TPM2_SM_FIFO_I2C, + ACPI_TPM2_SM_RESERVED_MMIO0, + ACPI_TPM2_SM_RESERVED_MMIO1, +}; + typedef struct acpi_tpm2 { acpi_header_t header; u16 platform_class; From 96b4754c35b2478602feef1df01069935726dc51 Mon Sep 17 00:00:00 2001 From: Bora Guvendik Date: Wed, 7 Jan 2026 13:29:10 -0800 Subject: [PATCH 158/789] soc/intel: Add CPU ID support for Nova Lake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add CPUID definition and CPU table entry for Intel Nova Lake processor (CPUID 0x300f30). This enables basic CPU initialization and multiprocessor support for Nova Lake platforms Reference: - Nova Lake External Design Specification (EDS) Volume 1 (#844316) BUG=none Change-Id: Iea89ebfa8bae3448edfb3b757443ec9902cede5e Signed-off-by: Bora Guvendik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90695 Tested-by: build bot (Jenkins) Reviewed-by: Jérémy Compostella Reviewed-by: Kim, Wonkyu --- src/include/cpu/intel/cpu_ids.h | 1 + src/soc/intel/common/block/cpu/mp_init.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/include/cpu/intel/cpu_ids.h b/src/include/cpu/intel/cpu_ids.h index ada3bfd216..f43287226a 100644 --- a/src/include/cpu/intel/cpu_ids.h +++ b/src/include/cpu/intel/cpu_ids.h @@ -95,5 +95,6 @@ #define CPUID_SNOWRIDGE_B1 0x80665 #define CPUID_SNOWRIDGE_C0 0x80667 #define CPUID_WILDCATLAKE 0xd0650 +#define CPUID_NOVALAKE 0x300f30 #endif /* CPU_INTEL_CPU_IDS_H */ diff --git a/src/soc/intel/common/block/cpu/mp_init.c b/src/soc/intel/common/block/cpu/mp_init.c index fdee38d254..dd8a31592e 100644 --- a/src/soc/intel/common/block/cpu/mp_init.c +++ b/src/soc/intel/common/block/cpu/mp_init.c @@ -32,6 +32,7 @@ static struct device_operations cpu_dev_ops = { }; static const struct cpu_device_id cpu_table[] = { + { X86_VENDOR_INTEL, CPUID_NOVALAKE, CPUID_ALL_STEPPINGS_MASK }, { X86_VENDOR_INTEL, CPUID_WILDCATLAKE, CPUID_ALL_STEPPINGS_MASK }, { X86_VENDOR_INTEL, CPUID_PANTHERLAKE, CPUID_ALL_STEPPINGS_MASK }, { X86_VENDOR_INTEL, CPUID_LUNARLAKE_A0_1, CPUID_EXACT_MATCH_MASK }, From d62764df8779abd2a7158659849a27b4e22bcd4a Mon Sep 17 00:00:00 2001 From: Cliff Huang Date: Wed, 7 Jan 2026 09:54:21 -0800 Subject: [PATCH 159/789] soc/intel/common/block/p2sb: Add SSDT function for SoC-specific features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add weak function to fill SSDT for SoC-specific P2SB extensions. SoCs can implement this function to fill additional P2SB-related ACPI objects. For instance, a SoC might include the IOST ACPI interface that uses P2SB and enable it via SSDT for debug purposes at the OS level. BUG=none TEST=This change cannot be tested in isolation as it only adds an empty weak function. Testing requires SoCs to implement the function. Add the necessary code with the same function name in the SoC to generate ACPI objects and examine the SSDT for changes after boot. Signed-off-by: Cliff Huang Change-Id: I352f13b9b05dc4b61608a33c76946883bf0d3de3 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90691 Tested-by: build bot (Jenkins) Reviewed-by: Jérémy Compostella Reviewed-by: Alicja Michalska --- src/soc/intel/common/block/include/intelblocks/p2sb.h | 8 ++++++++ src/soc/intel/common/block/p2sb/p2sb.c | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/soc/intel/common/block/include/intelblocks/p2sb.h b/src/soc/intel/common/block/include/intelblocks/p2sb.h index e587a4d25e..a431f617c7 100644 --- a/src/soc/intel/common/block/include/intelblocks/p2sb.h +++ b/src/soc/intel/common/block/include/intelblocks/p2sb.h @@ -3,6 +3,7 @@ #ifndef SOC_INTEL_COMMON_BLOCK_P2SB_H #define SOC_INTEL_COMMON_BLOCK_P2SB_H +#include #include #include @@ -68,4 +69,11 @@ void p2sb_set_ioapic_bdf(union p2sb_bdf bdf); */ void p2sb_soc_get_sb_mask(uint32_t *ep_mask, size_t count); +/* + * SoC might define this function to fill additional P2SB-related ACPI objects. + * For instance, the SoC might include the IOST ACPI interface to use P2SB and + * enable it via SSDT for debug purposes at the OS level. + */ +void soc_fill_p2sb_ssdt(const struct device *dev); + #endif /* SOC_INTEL_COMMON_BLOCK_P2SB_H */ diff --git a/src/soc/intel/common/block/p2sb/p2sb.c b/src/soc/intel/common/block/p2sb/p2sb.c index fea3103026..194c18f86a 100644 --- a/src/soc/intel/common/block/p2sb/p2sb.c +++ b/src/soc/intel/common/block/p2sb/p2sb.c @@ -130,10 +130,18 @@ static void read_resources(struct device *dev) mmio_range(dev, PCI_BASE_ADDRESS_0, P2SB_BAR, P2SB_SIZE); } +__weak void soc_fill_p2sb_ssdt(const struct device *dev) +{ + /* no-op */ +} + const struct device_operations p2sb_ops = { .read_resources = read_resources, .set_resources = noop_set_resources, .ops_pci = &pci_dev_ops_pci, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_fill_ssdt = soc_fill_p2sb_ssdt, +#endif }; static const unsigned short pci_device_ids[] = { From 52aeb078ce69479c0efa852ba9ee7c97a09dfbc7 Mon Sep 17 00:00:00 2001 From: Cliff Huang Date: Wed, 19 Nov 2025 17:50:39 -0800 Subject: [PATCH 160/789] soc/intel/common/acpi: Add IOST device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ACPI device for Intel's IO Self-Testing Software (IOST), which is an OS tool for performing electrical margining analysis on USB4 Host and Device Routers, DP2.1 displays, memory, UFS, and PCIe Gen4+ devices. This ACPI device provides the necessary P2SB access interface to enable IOST to interact with hardware registers for comprehensive IO testing and validation. The ASL file should be included in the SoC's southbridge.asl. BUG=none TEST=Build coreboot with this ASL file included in the SoC's southbridge.asl. Boot to OS and verify IOST objects appear correctly in the DSDT tables. Signed-off-by: Cliff Huang Change-Id: I9417da8322931c2afbf75aa9062bceb52b8320d6 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90128 Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) Reviewed-by: Alicja Michalska --- src/soc/intel/common/acpi/iost.asl | 81 ++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/soc/intel/common/acpi/iost.asl diff --git a/src/soc/intel/common/acpi/iost.asl b/src/soc/intel/common/acpi/iost.asl new file mode 100644 index 0000000000..51d934ca7a --- /dev/null +++ b/src/soc/intel/common/acpi/iost.asl @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Device: Intel's IO Self-Testing Software (IOST) + * NOTE: The IOSE Name object is used to enable IOST. It is set to 0 by default, + * and its value can be updated in the SSDT. + */ +Device (IOST) +{ + // + // Intel IO Self Testing Device + // + Name (_UID, "IOST") + Name (_HID, "IOS0001") + Name (IVER, 0x00010000) + Name (IOSE, 0x00) + Method (_STA, 0, NotSerialized) + { + If (IOSE > Zero) { + Return (0xf) + } + Return (Zero) + } + + /* + * _DSM Device Specific Method + * + * Arg0: UUID : 893f00a6-660c-494e-bcfd-3043f4fb67c0 + * Arg1: Integer Revision Level + * Arg2: Integer Function Index (0 = Return Supported Functions) + * Arg3: Package Parameters + */ + Method (_DSM, 4, Serialized) + { + If ( (IOSE > Zero) && LEqual (Arg0, ToUUID ("893f00a6-660c-494e-bcfd-3043f4fb67c0"))) + { + If (LEqual (0, ToInteger (Arg1))) + { + Switch (ToInteger (Arg2)) + { + /* Function 0: returns a buffer containing one bit for each function index, starting with zero. + * Bit 0 indicates whether there is support for any function other than function 0 + */ + Case (0) + { + Return (Buffer(){0x07}) + } + /* Function 1: P2SB Read + * Package Details + * Idx0 = PortID + * Idx1 = Offset + */ + Case (1) + { + Local0 = DeRefOf (Index (Arg3, 0)) /* PordID */ + Local1 = DeRefOf (Index (Arg3, 1)) /* offset */ + + Local3 = PCRR(Local0, Local1) + Printf ("[IOST] P2B Read: PortID: %o Offset: %o read = %o", ToHexString(Local0), ToHexString(Local1), ToHexString(Local3)) + Return(Local3) + } + /* Function 2: P2SB Write + * Package Details + * Idx0 = PortID + * Idx1 = Offset + * Idx2 = DataToWrite + */ + Case (2) + { + Local0 = DeRefOf (Index (Arg3, 0)) /* PordID */ + Local1 = DeRefOf (Index (Arg3, 1)) /* offset */ + Local2 = DeRefOf (Index (Arg3, 2)) /* data to Write */ + Printf ("[IOST] P2B Write: PortID: %o Offset: %o with %o", ToHexString(Local0), ToHexString(Local1), ToHexString(Local2)) + PCRW(Local0, Local1, Local2) + Return (0x00) + } + } + } + } + Return (Buffer () {0x00}) + } +} From 2c58e525e8d7f07ae1a8124dd731abe0329c5b2c Mon Sep 17 00:00:00 2001 From: Cliff Huang Date: Fri, 14 Nov 2025 14:27:00 -0800 Subject: [PATCH 161/789] soc/intel/ptl: Add ACPI IOST support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add and enable IOST feature to support Intel's IO Self-Testing Software (IOST), which is an OS tool for performing electrical margining analysis on USB4 Host and Device Routers, DP2.1 displays, memory, UFS, and PCIe Gen4+ devices. This change includes the IOST ACPI device in the SoC's southbridge ASL and implements the SoC-specific soc_fill_p2sb_ssdt function used by the common P2SB code to generate ACPI code for enabling IOST in the DSDT. Additionally, the CBFS option "iost_enable" is required to enable IOST. Command to add this option to the image: cbfstool add-int -r COREBOOT -i 1 -n option/iost_enable Note that this cbfstool command is an example, for its syntax format could be changed in the future versions. BUG=none TEST=Build coreboot and add the CBFS option flag to the built image. Boot to OS and verify IOST can access P2SB registers through the ACPI interface for electrical margining tests. Signed-off-by: Cliff Huang Change-Id: I6929fa3a44646c5385199a8b1e3d0b681d36c9cc Reviewed-on: https://review.coreboot.org/c/coreboot/+/90045 Tested-by: build bot (Jenkins) Reviewed-by: Alicja Michalska Reviewed-by: Jérémy Compostella --- .../intel/pantherlake/acpi/southbridge.asl | 3 ++ src/soc/intel/pantherlake/chip.c | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/soc/intel/pantherlake/acpi/southbridge.asl b/src/soc/intel/pantherlake/acpi/southbridge.asl index f2ad16b36b..fc74ce00b2 100644 --- a/src/soc/intel/pantherlake/acpi/southbridge.asl +++ b/src/soc/intel/pantherlake/acpi/southbridge.asl @@ -57,3 +57,6 @@ #if CONFIG(SOC_INTEL_WILDCATLAKE) #include #endif + +/* P2B access for IOST */ +#include diff --git a/src/soc/intel/pantherlake/chip.c b/src/soc/intel/pantherlake/chip.c index 8005240475..739cd9452a 100644 --- a/src/soc/intel/pantherlake/chip.c +++ b/src/soc/intel/pantherlake/chip.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -221,6 +223,40 @@ static void cpu_fill_ssdt(const struct device *dev) generate_cpu_entries(dev); } +/* + * This implements SoC-specific function used in common P2SB code to generate + * additional P2SB-related ACPI code. + */ +void soc_fill_p2sb_ssdt(const struct device *dev) +{ + /* + * Enable IOST for debug via P2SB at OS level. The associated IOST ASL file + * (i.e., src/soc/intel/common/acpi/iost.asl) is included in the SoC's + * southbridge.asl. The CBFS option "iost_enable" is used to expose this + * IOST interface to the OS. + * Use cbfstool command to add this option to the image. + */ + if (!get_uint_option("iost_enable", 0)) + return; + + printk(BIOS_INFO, "IOST is enabled\n"); + /* + * The following generates: + * Scope (\_SB.PCI0.IOST) + * { + * If (CondRefOf (IOSE)) + * { + * IOSE = 0x0F + * } + * } + */ + acpigen_write_scope("\\_SB.PCI0.IOST"); + acpigen_write_if_cond_ref_of("IOSE"); + acpigen_write_store_int_to_namestr(0xf, "IOSE"); + acpigen_write_if_end(); + acpigen_write_scope_end(); +} + static void cpu_set_north_irqs(struct device *dev) { irq_program_non_pch(); From 5db16ea6fc8e3a45a5500876465b49d24c1068f5 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 14 Jan 2026 09:08:18 -0800 Subject: [PATCH 162/789] soc/intel/pantherlake: Fix incorrect use of logical OR for TDP selection The previous implementation used the logical OR (||) operator to select between config->tdp and get_cpu_tdp(). In C, the || operator returns a boolean value (0 or 1), not the value of the first true operand. This caused the function to return incorrect TDP values. This commit replaces the logical OR with the ternary operator (?:), ensuring that config->tdp is returned if it is non-zero; otherwise, get_cpu_tdp() is used. This change restores the intended behavior of selecting the correct TDP value. TEST=The power map is properly found and applied on a Panther Lake B005 SoC. Change-Id: I3a02f804510f87cb4d28bd929869570c355c5242 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/90759 Reviewed-by: Guvendik, Bora Reviewed-by: Kim, Wonkyu Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/tdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/intel/pantherlake/tdp.c b/src/soc/intel/pantherlake/tdp.c index 63b3072499..30b03366fe 100644 --- a/src/soc/intel/pantherlake/tdp.c +++ b/src/soc/intel/pantherlake/tdp.c @@ -21,5 +21,5 @@ enum soc_intel_pantherlake_cpu_tdps soc_get_cpu_tdp(void) } const struct soc_intel_pantherlake_config *config = config_of_soc(); - return config->tdp || get_cpu_tdp(); + return config->tdp ? : get_cpu_tdp(); } From 72af15f1de8278d46a74becb2eb63d4e28948a79 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Tue, 13 Jan 2026 07:16:40 -0600 Subject: [PATCH 163/789] mb/google/zork: Fix missing comma in CFR object list When CFR support was added in commit c1f0be39dae4 ("mb/google/zork: Add CFR option menu support"), a comma was inadvertently left off the end the first CFR object in the list, which breaks compilation. Fix this by adding the missing comma. TEST=build/boot zork Change-Id: I5f13d87cbc81f440b0c14d253a6334adab45631e Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90732 Reviewed-by: Alicja Michalska Reviewed-by: Felix Singer Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/mainboard/google/zork/cfr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/zork/cfr.c b/src/mainboard/google/zork/cfr.c index 5565d31cd8..dbf38c0dc7 100644 --- a/src/mainboard/google/zork/cfr.c +++ b/src/mainboard/google/zork/cfr.c @@ -7,7 +7,7 @@ static struct sm_obj_form ec = { .ui_name = "ChromeEC Embedded Controller", .obj_list = (const struct sm_object *[]) { - &auto_fan_control + &auto_fan_control, &ec_kb_backlight, NULL }, From a8737c5f868dd99b8a7c594f9b4ef3358c61131d Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 12 Jan 2026 14:43:24 -0600 Subject: [PATCH 164/789] mb/google/cyan: Set CBFS_SIZE default to match IFD BIOS size All cyan-based boards define the size of the BIOS region in their IFD as 6MB in size; it is likewise defined as such in chromeos.fmd. To avoid having to override this in the board's config file when building with a modern payload like edk2, set the default CBFS_SIZE to 6MB as well to avoid issues with the payload not fitting. TEST=build/boot google/edgar w/edk2 payload and default CBFS_SIZE Change-Id: I17122aa2eb9848799c284d13d8c903ad125092b9 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90733 Reviewed-by: Felix Singer Tested-by: build bot (Jenkins) --- src/mainboard/google/cyan/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/cyan/Kconfig b/src/mainboard/google/cyan/Kconfig index eacc8ef87d..fe4d2a1067 100644 --- a/src/mainboard/google/cyan/Kconfig +++ b/src/mainboard/google/cyan/Kconfig @@ -107,7 +107,7 @@ config OVERRIDE_DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" config CBFS_SIZE - default 0x200000 + default 0x600000 config MAINBOARD_SMBIOS_MANUFACTURER string From b890ca0648cbed6853624294af43bf687f60db0b Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 12 Jan 2026 12:45:04 -0600 Subject: [PATCH 165/789] mb/google/brya/var/yaviks: select USE_MTCL only if CHROMEOS There is no wifi_mtcl.bin file publicly available, nor can it be extracted from the stock Google firmware for YAVIKS, so restrict USE_MTCL to downstream ChromeOS builds since validate_mtcl() fails when no file is present in CBFS. TEST=build/boot yaviks, verify no MTCL error in cbmem Change-Id: I450db6fd8c460109aa4e491d88ec874c5f6429d0 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90734 Reviewed-by: Eric Lai Tested-by: build bot (Jenkins) Reviewed-by: Alicja Michalska Reviewed-by: Paul Menzel --- src/mainboard/google/brya/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/brya/Kconfig b/src/mainboard/google/brya/Kconfig index b871d32fa6..27f78c269b 100644 --- a/src/mainboard/google/brya/Kconfig +++ b/src/mainboard/google/brya/Kconfig @@ -771,7 +771,7 @@ config BOARD_GOOGLE_YAVIKS select EC_GOOGLE_CHROMEEC_INCLUDE_SSFC_IN_FW_CONFIG select HAVE_WWAN_POWER_SEQUENCE select INTEL_GMA_HAVE_VBT - select USE_MTCL + select USE_MTCL if CHROMEOS config BOARD_GOOGLE_YAVILLA select BOARD_GOOGLE_BASEBOARD_NISSA From e6c5ee6450338071aa214957d68c37524abc8a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E9=A2=97=E5=B0=8F=E5=9C=9F=E8=B1=86?= <72010312+potatoone@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:32:36 +0800 Subject: [PATCH 166/789] mb/google/hatch/var/kohaku: Add Samsung S-pen driver support Modify the Wacom digitizer HID to support the Samsung S-pen. This allows a different driver to attach under Windows, which adds support for the side buttons as eraser function and air command. TEST=build/boot kahaku, verify S-pen works under Windows/Linux Change-Id: I60b75f7f16f6bb028ad1747e78cc49cac810fc92 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90735 Reviewed-by: Alicja Michalska Tested-by: build bot (Jenkins) --- src/mainboard/google/hatch/variants/kohaku/overridetree.cb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/hatch/variants/kohaku/overridetree.cb b/src/mainboard/google/hatch/variants/kohaku/overridetree.cb index 59704cafa1..d8c268d706 100644 --- a/src/mainboard/google/hatch/variants/kohaku/overridetree.cb +++ b/src/mainboard/google/hatch/variants/kohaku/overridetree.cb @@ -164,7 +164,7 @@ chip soc/intel/cannonlake end # I2C #1 device ref i2c2 on chip drivers/i2c/hid - register "generic.hid" = ""WCOM50C1"" + register "generic.hid" = ""WCOM006C"" register "generic.desc" = ""WCOM Digitizer"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_C7_IRQ)" register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_C15)" From 00fbc08b769613d9e0daba3dc972ee5468500629 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Tue, 13 Jan 2026 18:29:23 +0800 Subject: [PATCH 167/789] Reapply "soc/mediatek/mt8196: Call fsp_init via boot state" This reverts commit 292d7b9d3d4ccf852a9c20b8fafb5663bff7ff56. The resume failure is caused by the improper DEVAPC setting in fsp_init for DM/PM and SPM. If fsp_init runs prior to dpm_init and spm_init, it requires AP to grant the access to DM/PM and SPM from DEVAPC. The fix is done in CB:90756. BUG=b:474254985 TEST=Run suspend/resume test Change-Id: Id21327f6d65d31659cdb8b4bda3b0a0510c438e8 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90757 Tested-by: build bot (Jenkins) Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Yu-Ping Wu --- src/soc/mediatek/mt8196/soc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/soc/mediatek/mt8196/soc.c b/src/soc/mediatek/mt8196/soc.c index 24077a0fbc..e988a76926 100644 --- a/src/soc/mediatek/mt8196/soc.c +++ b/src/soc/mediatek/mt8196/soc.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include #include @@ -56,7 +57,7 @@ static void mte_setup(void) booker_mte_init(mte_start); } -static void fsp_init(void) +static void fsp_init(void *arg) { uint32_t storage_type = mainboard_get_storage_type(); @@ -67,6 +68,8 @@ static void fsp_init(void) mtk_fsp_load_and_run(); } +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, fsp_init, NULL); + static void soc_init(struct device *dev) { mtk_mmu_disable_l2c_sram(); @@ -76,7 +79,6 @@ static void soc_init(struct device *dev) if (spm_init()) printk(BIOS_ERR, "spm init failed, Suspend may not work\n"); - fsp_init(); sspm_init(); gpueb_init(); mcupm_init(); From 282c27c95c993af054b2d13ccc489e7cc77ea081 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 15 Sep 2025 16:33:10 +0200 Subject: [PATCH 168/789] arch/x86/acpi_bert_storage.c: Allow vendor specific BERT entries Add a Kconfg option to allow the SoC to add vendor specific BERT entries, not yet defined in the ACPI spec. The function only has to return the size of payload data and the generic code will allocate space on the BERT table. The caller must fill in all BERT fields since the generic code doesn't know anything about the BERT entry. Change-Id: I361700098ce1a3cc6acae991456a1901d2f07fb6 Signed-off-by: Maximilian Brune Reviewed-on: https://review.coreboot.org/c/coreboot/+/90639 Reviewed-by: Felix Held Tested-by: build bot (Jenkins) --- src/arch/x86/Kconfig | 7 +++++++ src/arch/x86/acpi_bert_storage.c | 8 ++++++-- src/arch/x86/include/arch/bert_storage.h | 3 +++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig index d78aa8fa30..b58907e230 100644 --- a/src/arch/x86/Kconfig +++ b/src/arch/x86/Kconfig @@ -459,4 +459,11 @@ config SOC_FILL_CPU_CACHE_INFO default n help SoC selects this if it implements soc_fill_cpu_cache_info. + +config SOC_BERT_SIZEOF_ERROR_SECTION + bool + default n + help + SoC selects this if it implements soc_bert_sizeof_error_section. + endif diff --git a/src/arch/x86/acpi_bert_storage.c b/src/arch/x86/acpi_bert_storage.c index 902ddb7da5..efa1d07849 100644 --- a/src/arch/x86/acpi_bert_storage.c +++ b/src/arch/x86/acpi_bert_storage.c @@ -192,6 +192,11 @@ static size_t sizeof_error_section(guid_t *guid) else if (!guidcmp(guid, &CPER_SEC_FW_ERR_REC_REF_GUID)) return sizeof(cper_fw_err_rec_section_t); /* else if ... sizeof(structures not yet defined) */ + else if (CONFIG(SOC_BERT_SIZEOF_ERROR_SECTION)) { + size_t size = soc_bert_sizeof_error_section(guid); + if (size) + return size; + } printk(BIOS_ERR, "Requested size of unrecognized CPER GUID\n"); return 0; @@ -535,9 +540,8 @@ acpi_generic_error_status_t *bert_new_event(guid_t *guid) r = bert_append_ia32x64(status); else if (!guidcmp(guid, &CPER_SEC_FW_ERR_REC_REF_GUID)) r = bert_append_fw_err(status); - /* else if other types not implemented */ else - r = NULL; + r = bert_append_error_datasection(status, guid); if (r) return status; diff --git a/src/arch/x86/include/arch/bert_storage.h b/src/arch/x86/include/arch/bert_storage.h index eb5db7f9cb..41c4f1c6e5 100644 --- a/src/arch/x86/include/arch/bert_storage.h +++ b/src/arch/x86/include/arch/bert_storage.h @@ -50,6 +50,9 @@ */ void bert_errors_region(void **start, size_t *size); +/* Returns the size for SoC specific GUIDs */ +size_t soc_bert_sizeof_error_section(guid_t *guid); + /* Get amount of available storage left for error info */ size_t bert_storage_remaining(void); /* Find if errors were added, a BERT region is present, and ACPI table needed */ From b4917ed44d049b3aa5eb865c5922e62e9394a51a Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 10 Jan 2026 08:51:56 -0600 Subject: [PATCH 169/789] payloads/edk2: rework serial output configuration Make EDK2_DEBUG automatically select CONSOLE_SERIAL, require EDK2_CBMEM_LOGGING to depend on EDK2_RELEASE, and make serial console mutually exclusive with CBMEM logging. Revise the Kconfig text to indicate the option is for the serial console, not serial debug output. This prevents users from selecting options which conflict or will result in a different result than expected. It simplifes the build options into 4 clear choices: - Release build - Release build with cbmem logging - Release build with serial console support - Debug build with serial debugging + serial console support TEST=build/boot google/drobit with above 4 build configurations. Change-Id: I15bbbcfcb2d9d0b1d4c2074f2c33012ec94f6c01 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90719 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- payloads/external/edk2/Kconfig | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/payloads/external/edk2/Kconfig b/payloads/external/edk2/Kconfig index 7bfd486f7a..226e82d434 100644 --- a/payloads/external/edk2/Kconfig +++ b/payloads/external/edk2/Kconfig @@ -128,8 +128,9 @@ choice config EDK2_DEBUG bool "Generate edk2 debug build" + select CONSOLE_SERIAL help - Generate a debug build. + Generate a debug build. Select this if you want to enable serial debugging output. config EDK2_RELEASE bool "Generate edk2 release build" @@ -190,11 +191,12 @@ config EDK2_BOOT_TIMEOUT config EDK2_CBMEM_LOGGING bool "Enable edk2 logging to CBMEM" + depends on EDK2_RELEASE help Select this option if you want to enable edk2 logging to CBMEM. - You may want to increase the default cbmem buffer size when selecting - this option, especially if using a debug (vs release) build. - Selecting this option will increase the payload size in CBFS by 0x10000. + You will want to increase the default cbmem buffer size when selecting + this option, as it will increase logging output significantly. + Selecting this option will increase the payload size in CBFS by ~1MB. config EDK2_CPU_TIMER_LIB bool @@ -262,12 +264,14 @@ config EDK2_SD_MMC_TIMEOUT Most only require 10ms, but certain readers can take 1s. config EDK2_SERIAL_SUPPORT - bool "Support serial output" + bool "Enable serial console" default y if EDK2_DEBUG default n + depends on !EDK2_CBMEM_LOGGING + select CONSOLE_SERIAL help - Enable serial port output in edk2. Serial output limits the performance of edk2's - FrontPage. + Enable serial consule support in edk2. Serial output limits the performance of edk2's + FrontPage. This option does not enable debugging output over serial. For that, use EDK2_DEBUG. config EDK2_SECURE_BOOT_SUPPORT bool "Enable UEFI Secure Boot support" From f712c965e4ce4af469d5538813685b3a93d2cc9e Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Tue, 13 Jan 2026 14:07:06 -0600 Subject: [PATCH 170/789] payloads/edk2: Update default MrChromebox branch from 2508 to 2511 Update the default MrChromebox branch to uefipayload_2511. This branch is rebased on the latest upstream edk tag 'edk2-stable202511', and includes a number of other improvements, such as setup menu password protection. TEST=tested on multiple ChromeOS devices from Sandybridge through Meteorlake. Change-Id: I5addbcf37e0b1a1afbd731163b4419d4bd9a3747 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90747 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- payloads/external/edk2/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payloads/external/edk2/Kconfig b/payloads/external/edk2/Kconfig index 226e82d434..2f4cab5efe 100644 --- a/payloads/external/edk2/Kconfig +++ b/payloads/external/edk2/Kconfig @@ -86,7 +86,7 @@ config EDK2_REPOSITORY config EDK2_TAG_OR_REV string "Insert a commit's SHA-1 or a branch name" - default "origin/uefipayload_2508" if EDK2_REPO_MRCHROMEBOX + default "origin/uefipayload_2511" if EDK2_REPO_MRCHROMEBOX default "origin/universalpayload" if EDK2_UNIVERSAL_PAYLOAD default "origin/master" if EDK2_REPO_OFFICIAL default "" if EDK2_REPO_CUSTOM From 23f0b0b313928b3740318cda500239b12b7390a0 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Tue, 30 Dec 2025 00:13:11 +0100 Subject: [PATCH 171/789] util/xcompile/xcompile: Fix clang target parameter It updates the target variable that is used for `clang -target`. Simply because the format was wrong. According to the documentation the format of the so called "target triple" is: --- with: arch = x86_64, i386, arm, thumb, mips, etc. sub = for ex. on ARM: v5, v6m, v7a, v7m, etc. vendor = pc, apple, nvidia, ibm, etc. (can be omitted) sys = none, linux, win32, darwin, cuda, etc. env = eabi, gnu, android, macho, elf, etc. In case of powerpc that causes an issue when trying to update clang to version 21. The target parameter for clang ends up being "powerpc64-none-unknown-linux-gnu". After testing, it turns out that in clang version 18 that is actually a valid target parameter, although not according to the documentation. In clang 21 however its not valid so fix it accordingly. Signed-off-by: Maximilian Brune Change-Id: I958416e6c56459766794830fbeac57ac827ffdd9 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90643 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- util/xcompile/xcompile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/xcompile/xcompile b/util/xcompile/xcompile index 8f0d19a6a6..f88da69306 100755 --- a/util/xcompile/xcompile +++ b/util/xcompile/xcompile @@ -526,7 +526,7 @@ test_architecture() { for clang_arch in $TCLIST invalid; do for clang_prefix in $search $XGCCPATH "$GENERIC_COMPILER_PREFIX"; do - testcc "${clang_prefix}clang" "-target ${clang_arch}-none-unknown-${TABI} -c" && break 2 + testcc "${clang_prefix}clang" "-target ${clang_arch}-none-${TABI} -c" && break 2 done done @@ -535,7 +535,7 @@ test_architecture() { # but that's more of a clang limitation. Let's be optimistic # that this will change in the future. CLANG="${clang_prefix}clang" - CLANG_TARGET="-target ${clang_arch}-none-unknown-${TABI}" + CLANG_TARGET="-target ${clang_arch}-none-${TABI}" CFLAGS_CLANG="$CLANG_TARGET $CFLAGS_CLANG" CPPFLAGS_CLANG="$CLANG_TARGET $CPPFLAGS_CLANG" fi From 763911872967cb1703ad71cb93b1fcb4b5cd43cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 6 Oct 2025 11:41:21 +0200 Subject: [PATCH 172/789] drivers/amd/opensil: Add hooks to populate CBMEM_ID_MEMINFO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a hooks that will populate mem_info structure with DIMM data obtained from OpenSIL. As the memory population may be SoC-specific, call a SoC-specific hook to fill the data. Change-Id: I0b489c685877ac56f45e0e3abd0bd1b64549585b Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/89484 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/drivers/amd/opensil/Makefile.mk | 1 + src/drivers/amd/opensil/dmi.c | 13 +++++++++++++ src/drivers/amd/opensil/opensil.h | 5 +++++ 3 files changed, 19 insertions(+) create mode 100644 src/drivers/amd/opensil/dmi.c diff --git a/src/drivers/amd/opensil/Makefile.mk b/src/drivers/amd/opensil/Makefile.mk index 6ed46d1f81..08918bc36d 100644 --- a/src/drivers/amd/opensil/Makefile.mk +++ b/src/drivers/amd/opensil/Makefile.mk @@ -7,6 +7,7 @@ subdirs-y += mpio romstage-y += romstage.c ramstage-y += acpi.c +ramstage-y += dmi.c ramstage-y += ramstage.c ramstage-y += memmap.c diff --git a/src/drivers/amd/opensil/dmi.c b/src/drivers/amd/opensil/dmi.c new file mode 100644 index 0000000000..0cedb74c9b --- /dev/null +++ b/src/drivers/amd/opensil/dmi.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include "opensil.h" + +__weak void opensil_smbios_fill_cbmem_meminfo(void) { } + +static void prepare_dmi_17(void *unused) +{ + opensil_smbios_fill_cbmem_meminfo(); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_ENTRY, prepare_dmi_17, NULL); diff --git a/src/drivers/amd/opensil/opensil.h b/src/drivers/amd/opensil/opensil.h index e6efbdc80a..7cc7ad80c9 100644 --- a/src/drivers/amd/opensil/opensil.h +++ b/src/drivers/amd/opensil/opensil.h @@ -5,6 +5,7 @@ #include #include +#include /* Set up openSIL env and call TP1 */ void amd_opensil_silicon_init(void); @@ -14,5 +15,9 @@ void configure_mpio(void); void amd_opensil_add_memmap(struct device *dev, unsigned long *idx); /* Fill in FADT from openSIL */ void amd_opensil_fill_fadt_io_ports(acpi_fadt_t *fadt); +/* Marshalls dimm info from SIL_DMI_INFO into CBMEM_ID_MEMINFO */ +void opensil_smbios_fill_cbmem_meminfo(void); +/* Fill DIMM locators using OpenSIL DMI info, returns 0 on success */ +int opensil_smbios_fill_dimm_locator(const struct dimm_info *dimm, struct smbios_type17 *t); #endif /* OPENSIL_DRIVER_H */ From ae7b75fb0df5b3206a452d65c1bf5cd1565814fa Mon Sep 17 00:00:00 2001 From: Nicholas Chin Date: Fri, 2 Jan 2026 07:23:08 -0700 Subject: [PATCH 173/789] mb/lenovo/sklkbl_thinkpad/cfr.c: Fix X280 build error As there is no model of the X280 with a dGPU, its devicetree does not declare a device with a dgpu alias like the other Skylake/Kaby Lake Thinkpad ports. This breaks the DEV_PTR(dgpu) reference in cfr.c, causing the following build error if CONFIG_DRIVERS_OPTION_CFR is set: In file included from src/mainboard/lenovo/sklkbl_thinkpad/cfr.c:9: src/mainboard/lenovo/sklkbl_thinkpad/cfr.c: In function 'update_dgpu': build/static.h:11:33: error: '_dev_dgpu_ptr' undeclared (first use in this function); did you mean '_dev_igpu_ptr'? 11 | #define DEV_PTR(_alias) _dev_##_alias##_ptr | ^~~~~ src/mainboard/lenovo/sklkbl_thinkpad/cfr.c:14:31: note: in expansion of macro 'DEV_PTR' 14 | struct device *dgpu = DEV_PTR(dgpu); | ^~~~~~~ build/static.h:11:33: note: each undeclared identifier is reported only once for each function it appears in 11 | #define DEV_PTR(_alias) _dev_##_alias##_ptr | ^~~~~ src/mainboard/lenovo/sklkbl_thinkpad/cfr.c:14:31: note: in expansion of macro 'DEV_PTR' 14 | struct device *dgpu = DEV_PTR(dgpu); | ^~~~~~~ make: *** [Makefile:431: build/ramstage/mainboard/lenovo/sklkbl_thinkpad/cfr.o] Error 1 Fix this by declaring a WEAK_DEV_PTR for the dgpu device, which will be overridden by the compiled devicetree if the board variant declares a dgpu device in its overridetree. TEST=X280 builds successfully with the following defconfig: CONFIG_VENDOR_LENOVO=y CONFIG_BOARD_LENOVO_X280=y CONFIG_DRIVERS_OPTION_CFR=y Change-Id: I18cc18a88851bb943de8ab6d2d1fdcbf0f4aea86 Signed-off-by: Nicholas Chin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90674 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel --- src/mainboard/lenovo/sklkbl_thinkpad/cfr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/cfr.c b/src/mainboard/lenovo/sklkbl_thinkpad/cfr.c index 8f282facdd..b5d979806d 100644 --- a/src/mainboard/lenovo/sklkbl_thinkpad/cfr.c +++ b/src/mainboard/lenovo/sklkbl_thinkpad/cfr.c @@ -8,6 +8,8 @@ #include #include +WEAK_DEV_PTR(dgpu); + /* Hide the dGPU CFR entry if dGPU not present */ static void update_dgpu(struct sm_object *new) { From 3883118ed9a2306cb942414f62587202a58c7dd5 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 23 Nov 2025 17:28:40 -0800 Subject: [PATCH 174/789] mb/google/brya/var/kano: Configure cameras for Windows/Linux ACPI mode Update device tree configuration to work with the newly-added Windows/ Linux ACPI device type mode (MIPI_ACPI_TYPE_WINDOWS_LINUX): - Add IPUA device to GFX generic driver as non-VGA device (required for IPU enumeration in Windows/Linux mode where IPU is attached to iGPU) - Add sensor_name ("CJFLE23" and "CJFLE25") for device identification TEST=build/boot Win11/Linux (Arch) on google/kano, verify MIPI camera functional under both OSes using the Intel IPU6 driver stack. Change-Id: I9232318c30ba0eee6dcd54f7199f6995a8ffa48b Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90743 Reviewed-by: Alicja Michalska Reviewed-by: Eric Lai Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/mainboard/google/brya/variants/kano/overridetree.cb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/brya/variants/kano/overridetree.cb b/src/mainboard/google/brya/variants/kano/overridetree.cb index 73065130e6..89cb331799 100644 --- a/src/mainboard/google/brya/variants/kano/overridetree.cb +++ b/src/mainboard/google/brya/variants/kano/overridetree.cb @@ -98,7 +98,7 @@ chip soc/intel/alderlake device domain 0 on device ref igpu on chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" # Internal panel on the first port of the graphics chip @@ -117,6 +117,10 @@ chip soc/intel/alderlake register "device[4].pld" = "ACPI_PLD_TYPE_C(RIGHT, RIGHT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel, so GFX device is added for TCP3 register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" device generic 0 on end end end # Integrated Graphics Device @@ -322,6 +326,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 2740 Camera"" + register "sensor_name" = ""CJFLE23"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" @@ -365,6 +370,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" From 139f6c3e64924daaed65145dacb0a31bf3b752d8 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 23 Nov 2025 20:21:29 -0800 Subject: [PATCH 175/789] mb/google/brya/var/redrix: Configure cameras for Windows/Linux ACPI mode Update device tree configuration to work with the newly-added Windows/ Linux ACPI device type mode (MIPI_ACPI_TYPE_WINDOWS_LINUX): - Add IPUA device to GFX generic driver as non-VGA device (required for IPU enumeration in Windows/Linux mode where IPU is attached to iGPU) - Add sensor_name ("S5VM17" and "CJFLE25") for device identification TEST=build/boot Win11/Linux (Ubuntu 25.10) on google/redrix, verify MIPI camera functional under both OSes using the Intel IPU6 driver stack. Change-Id: Ic72a96e93706c096b3839ab4c951e1d0a725b5ce Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90744 Reviewed-by: Eric Lai Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Alicja Michalska --- .../google/brya/variants/redrix/overridetree.cb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/brya/variants/redrix/overridetree.cb b/src/mainboard/google/brya/variants/redrix/overridetree.cb index 822babaead..3bc331129a 100644 --- a/src/mainboard/google/brya/variants/redrix/overridetree.cb +++ b/src/mainboard/google/brya/variants/redrix/overridetree.cb @@ -102,7 +102,7 @@ chip soc/intel/alderlake device domain 0 on device ref igpu on chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" # Use ChromeOS privacy screen _HID @@ -125,12 +125,16 @@ chip soc/intel/alderlake register "device[4].pld" = "ACPI_PLD_TYPE_C(RIGHT, LEFT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel, so GFX device is added for TCP3 register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" device generic 0 on probe EPS PRIVACY_SCREEN end end chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" # Internal panel on the first port of the graphics chip @@ -149,6 +153,10 @@ chip soc/intel/alderlake register "device[4].pld" = "ACPI_PLD_TYPE_C(RIGHT, LEFT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel, so GFX device is added for TCP3 register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" device generic 0 on probe EPS PRIVACY_SCREEN_ABSENT end @@ -417,6 +425,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 5675 Camera"" + register "sensor_name" = ""S5VM17"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" @@ -459,6 +468,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" From a306987ae44f658cea9911c3f168db38ad5fbfac Mon Sep 17 00:00:00 2001 From: Keith Hui Date: Thu, 23 May 2024 10:38:18 -0400 Subject: [PATCH 176/789] util/superiotool: Add experimental Nuvoton NPCD378 support I use this to dump SIO config on an HP Z210 CMT workstation. It's a shotgun blast into the dark, although based on what was done for Z220, already in tree. Change-Id: I83184f29c11c92384f6a09b671ed9e24956e9e57 Signed-off-by: Keith Hui Reviewed-on: https://review.coreboot.org/c/coreboot/+/82627 Reviewed-by: Walter Sonius Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- util/superiotool/nuvoton.c | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/util/superiotool/nuvoton.c b/util/superiotool/nuvoton.c index 80ba12ecdd..5f249e7463 100644 --- a/util/superiotool/nuvoton.c +++ b/util/superiotool/nuvoton.c @@ -907,6 +907,50 @@ static const struct superio_registers reg_table[] = { {0x30,0xe0,0xe1,0xe2,0xe3,EOT}, {0xa0,0x20,0x04,0x05,0x01,EOT}}, {EOT}}}, + {0x1c11, "NPCD378 (experimental)", { + {NOLDN, NULL, + {0x10,0x11,0x13,0x14,0x1a,0x1b,0x1c,0x1d,0x20,0x21,0x22,0x24,0x25,0x26,0x27,0x28,0x2a,0x2b,0x2c,0x2d,0x2f,EOT}, + {NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {0x00, "FDC", + {0x30,0x60,0x61,0x70,0x74,0xf0,0xf1,0xf2,0xf4,0xf5,EOT}, + {0x01,0x03,0xf0,0x06,0x02,0x0e,0x00,0xff,0x00,0x00,EOT}}, + {0x01, "Parallel Port", + {0x30,0x60,0x61,0x70,0x74,0xf0,EOT}, + {0x01,0x03,0x78,0x07,0x04,0x3f,EOT}}, + {0x02, "UART A", + {0x30,0x60,0x61,0x70,0xf0,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,EOT}, + {0x01,0x03,0xf8,0x04,0x00,0x00,0x00,0xff,0xff,0x02,0x00,0x00,EOT}}, + {0x03, "UART B", + {0x30,0x60,0x61,0x70,0xf0,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,EOT}, + {0x01,0x02,0xf8,0x03,0x00,0x00,0x00,0xff,0xff,0x02,0x00,0x00,EOT}}, + {0x04, "LED Control", + {0x30,0x60,0x61,0x62,0x63,0x70,0xf0,0xf1,0xf2,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,NANA,NANA,NANA,EOT}}, + {0x05, "?", + {0x30,0x60,0x61,0x62,0x63,0x70,0xf0,0xf1,0xf2,0xf3,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x09,0x32,0x00,EOT}}, + {0x06, "Keyboard Controller", + {0x30,0x60,0x61,0x62,0x63,0x70,0x72,0xf0,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,EOT}}, + {0x07, "?", + {0x30,0x60,0x61,0x70,0x72,0xf0,EOT}, + {0x00,0x00,0x00,0x00,0x00,NANA,EOT}}, + {0x08, "Hardware Monitor", + {0x30,0x60,0x61,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,EOT}, + {0x00,0x00,0x00,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {0x0f, "?", + {0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe9,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,EOT}, + {NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {0x15, "?", + {0x30,0x60,0x61,0x62,0x63,0x70,0x72,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {0x1c, "?", + {0x30,0x60,0x61,0x62,0x63,0x70,0x72,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {0x1e, "?", + {0x30,0x60,0x61,0x62,0x63,0x70,0x72,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {EOT}}}, {EOT} }; From f9b917d3913685419c8615b38440962cb27781a6 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 14 Jan 2026 18:25:27 +0000 Subject: [PATCH 177/789] soc/qualcomm/x1p42100: Relocate CBMEM top below XBL log Relocate the CBMEM top address from a hardcoded 0xC7800000 to the start of the XBL log region (_dram_xbl_log). This change moves the CBMEM region from the high Linux Kernel Reserve block down into the lower DRAM Space 0, adjacent to other firmware reserved regions. This consolidation prevents marking CBMEM range as `reserved` and ensures CBMEM is placed in a more stable memory location (marked available aka System RAM). - Remove CBMEM_TOP define from addressmap.h. - Update cbmem_top_chipset() to return (uintptr_t)_dram_xbl_log. - Update memlayout.ld documentation to reflect the new memory map. BUG=none TEST=Boot on X1P42100 platform, verify CBMEM console and tables are accessible and correctly located via 'cbmem -l'. w/o this patch: ``` c7800000-cb7fffff : reserved ``` w/ this patch: ``` 815a0000-819fffff : System RAM ``` Change-Id: I7392bb7a62d50640696301931940a7baa00351e3 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90760 Reviewed-by: Derek Huang Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal Reviewed-by: Jayvik Desai --- src/soc/qualcomm/x1p42100/cbmem.c | 2 +- src/soc/qualcomm/x1p42100/include/soc/addressmap.h | 1 - src/soc/qualcomm/x1p42100/memlayout.ld | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/soc/qualcomm/x1p42100/cbmem.c b/src/soc/qualcomm/x1p42100/cbmem.c index 6836a3ca84..0524c67f03 100644 --- a/src/soc/qualcomm/x1p42100/cbmem.c +++ b/src/soc/qualcomm/x1p42100/cbmem.c @@ -6,5 +6,5 @@ uintptr_t cbmem_top_chipset(void) { - return (uintptr_t)CBMEM_TOP; + return (uintptr_t)_dram_xbl_log; } diff --git a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h index 8b22662e92..60649835d6 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h +++ b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h @@ -24,7 +24,6 @@ #define AOP_BOOT_COOKIE_ADDR 0xC3F0040 -#define CBMEM_TOP 0xC7800000 /* X1P42100 NCC0 PLL CONFIG ADDRESSES */ #define NCC0_NCC_CMU_NCC_PLL_CFG 0x199A2010 #define NCC0_NCC_CMU_NCC_CLK_CFG 0x199A2030 diff --git a/src/soc/qualcomm/x1p42100/memlayout.ld b/src/soc/qualcomm/x1p42100/memlayout.ld index 110444a87a..1c2865a5c8 100644 --- a/src/soc/qualcomm/x1p42100/memlayout.ld +++ b/src/soc/qualcomm/x1p42100/memlayout.ld @@ -41,8 +41,6 @@ * 0xD7800000 +----------------------------------------------------------+ | | * | Linux Kernel Reserve | | | * 0xC7800000 +----------------------------------------------------------+ | | - * | CBMEM | | | - * +----------------------------------------------------------+ | | * | ... Usable memory ... | | | * 0xA1800000 +----------------------------------------------------------+ | | * | RAMSTAGE | DRAM Space 0 | @@ -83,6 +81,8 @@ * 0x81A40000 +----------------------------------------------------------+ | | * | dram_xbl_log | | | * 0x81A00000 +----------------------------------------------------------+ | | + * | CBMEM | | | + * +----------------------------------------------------------+ | | * | ... Usable memory ... | | | * 0x815A0000 +----------------------------------------------------------+ | | * | dram_cpucp | | | From 7351e663d2848877a243707370c34f1d8a16b688 Mon Sep 17 00:00:00 2001 From: Yunlong Jia Date: Thu, 15 Jan 2026 07:18:43 +0000 Subject: [PATCH 178/789] mb/google/nissa: Enable early EC SW sync & eSOL for gothrax/epic `VBOOT_EARLY_EC_SYNC` enables EC software sync in romstage. This is useful to achieve full USB-PD negotiation early in the boot flow. It eliminates a problem where PMC is wrongly configured in depthcharge during the EC-sync scenario which prevents USB devices from getting detected when connected via a self-powered USB hub. `VBOOT_EC_SYNC_ESOL` displays early sign-of-life (eSOL) during EC firmware updates. BUG=b:386920751,b:467506959,b:468885646 TEST=Verify detection and booting to OS from USB drive connected to the Servo v4 debugger (self-powered hub) during the EC-sync scenario. Verify that eSOL is displayed during EC firmware update. Signed-off-by: Yunlong Jia Change-Id: I612b4dc13be2efaee863e6cacf8fc4c432edc313 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90762 Reviewed-by: Eric Lai Tested-by: build bot (Jenkins) Reviewed-by: Derek Huang Reviewed-by: Subrata Banik --- src/mainboard/google/brya/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/brya/Kconfig b/src/mainboard/google/brya/Kconfig index 27f78c269b..dca1ea2201 100644 --- a/src/mainboard/google/brya/Kconfig +++ b/src/mainboard/google/brya/Kconfig @@ -1174,8 +1174,8 @@ config VARIANT_DIR default "pujjolo" if BOARD_GOOGLE_PUJJOLO config VBOOT - select VBOOT_EARLY_EC_SYNC if !(BOARD_GOOGLE_BASEBOARD_NISSA || BOARD_GOOGLE_BASEBOARD_TRULO) || BOARD_GOOGLE_RULL - select VBOOT_EC_SYNC_ESOL if BOARD_GOOGLE_RULL + select VBOOT_EARLY_EC_SYNC if !(BOARD_GOOGLE_BASEBOARD_NISSA || BOARD_GOOGLE_BASEBOARD_TRULO) || BOARD_GOOGLE_RULL || BOARD_GOOGLE_GOTHRAX || BOARD_GOOGLE_EPIC + select VBOOT_EC_SYNC_ESOL if BOARD_GOOGLE_RULL || BOARD_GOOGLE_GOTHRAX || BOARD_GOOGLE_EPIC select VBOOT_LID_SWITCH config UART_FOR_CONSOLE From b5ad97a2688bd734d352a9c2ec447c3e360e118a Mon Sep 17 00:00:00 2001 From: Yunlong Jia Date: Thu, 15 Jan 2026 07:46:25 +0000 Subject: [PATCH 179/789] mb/google/nissa/var/gothrax: Add wifi sar table Add AX211 wifi sar table for gothrax wifi sar config. Use fw_config to separate different wifi card settings. WLAN_AX211_Intel: 1 BUG=b:454207611 Test=emerge-nissa coreboot Signed-off-by: Yunlong Jia Change-Id: I11cf6cd61a13f5365530fc07b589d749c9459d26 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90763 Tested-by: build bot (Jenkins) Reviewed-by: Eric Lai --- src/mainboard/google/brya/Kconfig | 1 + src/mainboard/google/brya/variants/gothrax/variant.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/mainboard/google/brya/Kconfig b/src/mainboard/google/brya/Kconfig index dca1ea2201..e1d64876c5 100644 --- a/src/mainboard/google/brya/Kconfig +++ b/src/mainboard/google/brya/Kconfig @@ -303,6 +303,7 @@ config BOARD_GOOGLE_GOTHRAX select DRIVERS_I2C_SX9324 select DRIVERS_I2C_SX9324_SUPPORT_LEGACY_LINUX_DRIVER select HAVE_WWAN_POWER_SEQUENCE + select CHROMEOS_WIFI_SAR if CHROMEOS config BOARD_GOOGLE_GUREN select BOARD_GOOGLE_BASEBOARD_NISSA diff --git a/src/mainboard/google/brya/variants/gothrax/variant.c b/src/mainboard/google/brya/variants/gothrax/variant.c index 8b8822bf4f..ab134c2ba7 100644 --- a/src/mainboard/google/brya/variants/gothrax/variant.c +++ b/src/mainboard/google/brya/variants/gothrax/variant.c @@ -4,6 +4,7 @@ #include #include #include +#include void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config) { @@ -40,3 +41,8 @@ void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config) config->typec_aux_bias_pads[1].pad_auxn_dc = 0x00; } } + +const char *get_wifi_sar_cbfs_filename(void) +{ + return get_wifi_sar_fw_config_filename(FW_CONFIG_FIELD(WLAN)); +} From 5f76f78383c5bed3f96138a5d7156d6926ba9afd Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Mon, 12 Jan 2026 09:47:44 +0100 Subject: [PATCH 180/789] mb/siemens/mc_ehl7: Deactivate GbE and PSE GbE 0 Remove the unused GbE and PSE TSN GbE device 0. These devices are not required for the current board functionality. Removing them simplifies the configuration. Also PSE is not used for any other functionality, the local host interface is deacitivated as well. TEST=Check if all other GbE ports of mainboard still work. Change-Id: I83c7e9731d3684a0b0a7f16b533ee3ea2989f3c6 Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/90726 Reviewed-by: Mario Scheithauer Tested-by: build bot (Jenkins) --- .../siemens/mc_ehl/variants/mc_ehl7/Kconfig | 2 - .../mc_ehl/variants/mc_ehl7/devicetree.cb | 38 ------------------- 2 files changed, 40 deletions(-) diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig index 6524f4855d..c1c3bb2a98 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig @@ -5,8 +5,6 @@ if BOARD_SIEMENS_MC_EHL7 config BOARD_SPECIFIC_OPTIONS def_bool y select DRIVER_INTEL_I210 - select DRIVERS_ETH_PHY_M88E1512 - select EHL_TSN_DRIVER select MAINBOARD_HAS_TPM2 select MEMORY_MAPPED_TPM select NC_FPGA_POST_CODE diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb index 776eab22e3..da0ce4e292 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb @@ -186,46 +186,8 @@ chip soc/intel/elkhartlake device pci 1c.4 on end # RP5 (pcie1 multi VC) device pci 1c.6 on end # RP7 (pcie3 multi VC) - device pci 1d.0 off end # Intel PSE IPC (local host to PSE) - device pci 1d.1 on # Intel PSE Time-Sensitive Networking GbE 0 - # Enable external Marvell PHY 88E1512 - chip drivers/net/phy/m88e1512 - register "configure_leds" = "true" - # LED[0]: On - 1000 Mbps Link, Off - Else - register "led_0_ctrl" = "7" - # LED[1]: On - 100 Mbps Link, Off - Else - register "led_1_ctrl" = "7" - # LED[2]: Blink - Activity, Off - No Activity - register "led_2_ctrl" = "4" - # INTn is not routed to LED[2] pin - register "enable_int" = "false" - register "downshift_cnt" = "2" - device mdio 0 on # PHY address - ops m88e1512_ops - end - end - end - device pci 1e.0 on end # UART0 device pci 1e.1 on end # UART1 - device pci 1e.4 on # PCH Time-Sensitive Networking GbE - # Enable external Marvell PHY 88E1512 - chip drivers/net/phy/m88e1512 - register "configure_leds" = "true" - # LED[0]: On - 1000 Mbps Link, Off - Else - register "led_0_ctrl" = "7" - # LED[1]: On - 100 Mbps Link, Off - Else - register "led_1_ctrl" = "7" - # LED[2]: Blink - Activity, Off - No Activity - register "led_2_ctrl" = "4" - # INTn is not routed to LED[2] pin - register "enable_int" = "false" - register "downshift_cnt" = "2" - device mdio 1 on # PHY address - ops m88e1512_ops - end - end - end device pci 1f.0 on # eSPI Interface chip drivers/pc80/tpm From 3f5807ce101cabe88ac528690653fd4901c333cf Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Mon, 12 Jan 2026 16:05:25 +0100 Subject: [PATCH 181/789] mb/siemens/mc_ehl7: Deactivate SATA interface On this mainboard no SATA interface is assembled. Therefore, it is deactivated. TEST=Boot into OS and verify via lspci if relevant SATA Controller is deactivated and no error in coreboot log is shown. Change-Id: Iea01c30d18d81e67087ac8abef5cece0040087e5 Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/90730 Reviewed-by: Mario Scheithauer Tested-by: build bot (Jenkins) --- .../siemens/mc_ehl/variants/mc_ehl7/devicetree.cb | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb index da0ce4e292..fcd6de5463 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb @@ -78,13 +78,7 @@ chip soc/intel/elkhartlake # Determine PCIe root port speed register "PcieRpPcieSpeed[6]" = "2" - # Storage (SATA/SDCARD/EMMC) related UPDs - register "SataSalpSupport" = "0" - register "SataPortsEnable[1]" = "1" - register "SataPortsDevSlp[1]" = "0" - register "SataPortsSSD[1]" = "1" - register "SataSpeed" = "SATA_GEN2" - + # Storage (SDCARD/EMMC) related UPDs register "ScsEmmcHs400Enabled" = "0" register "ScsEmmcDdr50Enabled" = "1" register "SdCardPowerEnableActiveHigh" = "1" @@ -165,8 +159,6 @@ chip soc/intel/elkhartlake device pci 16.0 hidden end # Management Engine Interface 1 - device pci 17.0 on end # SATA - device pci 19.0 on # I2C4 # Add dummy I2C device to limit BUS speed to 100 kHz in OS chip drivers/i2c/generic From b7763a59735d233e47343a00c83e5f8d8b9cf36c Mon Sep 17 00:00:00 2001 From: Cliff Huang Date: Sun, 14 Sep 2025 23:10:47 -0700 Subject: [PATCH 182/789] mb/google/fatcat: Implement Google Rex touchscreen integration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This update introduces support for Google touchscreen devices to the existing framework, enhancing compatibility with Google's hardware interfaces. It extends the fw_config field with new options to accommodate different connection types used by Google touchscreens. Specifically, it adds: - TOUCHSCREEN_LPSS_I2C_ELAN_REX for ELAN9006 interfaced via LPSS-I2C. - TOUCHSCREEN_THC_SPI_ELAN_REX for ELAN6918 interfaced via THC-SPI. - TOUCHSCREEN_THC_I2C_ELAN_REX for ELAN9006 interfaced via THC-I2C. BUG=none TEST=Connect Google's REX touchscreen with the conversion cables. Boot to OS with fw_config setting for Google's touchscreen and verify device enumeration in /sys/bus/hid/devices directory. Signed-off-by: Cliff Huang Change-Id: I3fda0e4587d8484881c844674053a0badfc23a11 Reviewed-on: https://review.coreboot.org/c/coreboot/+/89181 Reviewed-by: Kim, Kyoung Il Reviewed-by: Subrata Banik Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) --- .../google/fatcat/variants/fatcat/fw_config.c | 12 ++-- .../fatcat/variants/fatcat/overridetree.cb | 63 +++++++++++++++++++ .../google/fatcat/variants/fatcat/variant.c | 6 +- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/mainboard/google/fatcat/variants/fatcat/fw_config.c b/src/mainboard/google/fatcat/variants/fatcat/fw_config.c index d1f40ec06d..e0a59219a4 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/fw_config.c +++ b/src/mainboard/google/fatcat/variants/fatcat/fw_config.c @@ -669,15 +669,18 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table) GPIO_PADBASED_OVERRIDE(padbased_table, touchpad_i2c_disable_pads); } - if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_LPSS_I2C))) { + if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_LPSS_I2C)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_LPSS_I2C_ELAN_REX))) { GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_lpss_i2c_enable_pads); - } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C))) { + } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C_ELAN_REX))) { GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_thc_i2c_enable_pads); if (config->thc_wake_on_touch[0]) GPIO_PADBASED_OVERRIDE(padbased_table, thc0_enable_wake); } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_GSPI))) { GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_gspi_enable_pads); - } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI))) { + } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI_ELAN_REX))) { GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_thc_spi_enable_pads); if (config->thc_wake_on_touch[0]) GPIO_PADBASED_OVERRIDE(padbased_table, thc0_enable_wake); @@ -708,7 +711,8 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table) * 2. CBI selecting TS THC-SPI or TS GSPI with FSP present is invalid case. */ if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_GSPI)) || - fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI))) { + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI_ELAN_REX))) { /* board has TS SPI rework and not FPS support */ } else if (fw_config_probe(FW_CONFIG(FP, FP_PRESENT))) { GPIO_PADBASED_OVERRIDE(padbased_table, fp_enable_pads); diff --git a/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb b/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb index f95d9e8255..dc744d0cd1 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb @@ -24,6 +24,10 @@ fw_config option TOUCHSCREEN_GSPI 2 option TOUCHSCREEN_THC_SPI 3 option TOUCHSCREEN_THC_I2C 4 + # NOTE: conversion cables are required to connect with Google touch screen + option TOUCHSCREEN_LPSS_I2C_ELAN_REX 5 + option TOUCHSCREEN_THC_SPI_ELAN_REX 6 + option TOUCHSCREEN_THC_I2C_ELAN_REX 7 end field TOUCHPAD 11 12 option TOUCHPAD_NONE 0 @@ -326,6 +330,8 @@ chip soc/intel/pantherlake register "thc_wake_on_touch[0]" = "true" probe TOUCHSCREEN TOUCHSCREEN_THC_SPI probe TOUCHSCREEN TOUCHSCREEN_THC_I2C + probe TOUCHSCREEN TOUCHSCREEN_THC_SPI_ELAN_REX + probe TOUCHSCREEN TOUCHSCREEN_THC_I2C_ELAN_REX # THC0 is function 0; hence it needs to be enabled when THC1 is to be enabled. probe TOUCHPAD TOUCHPAD_THC_I2C chip drivers/intel/touch @@ -345,6 +351,23 @@ chip soc/intel/pantherlake probe TOUCHSCREEN TOUCHSCREEN_THC_I2C end end + chip drivers/intel/touch + register "name" = "INTEL_THC0_NAME" + register "mode" = "THC_HID_I2C_MODE" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F08)" + register "enable_delay_ms" = "2" + register "enable_off_delay_ms" = "2" + register "wake_on_touch" = "true" + # NOTE: Use GpioInt() in _CRS and does not use GPE. + register "wake_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(GPP_VGPIO3_THC0)" + register "active_ltr" = "1" + register "idle_ltr" = "0" + register "connected_device" = "TH_SENSOR_ELAN_REX" + register "add_acpi_dma_property" = "true" + device generic 0 alias touch_0_i2c_google on + probe TOUCHSCREEN TOUCHSCREEN_THC_I2C_ELAN_REX + end + end chip drivers/intel/touch register "name" = "INTEL_THC0_NAME" register "mode" = "THC_HID_SPI_MODE" @@ -367,6 +390,28 @@ chip soc/intel/pantherlake probe TOUCHSCREEN TOUCHSCREEN_THC_SPI end end + chip drivers/intel/touch + register "name" = "INTEL_THC0_NAME" + register "mode" = "THC_HID_SPI_MODE" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F08)" + register "enable_delay_ms" = "2" + register "enable_off_delay_ms" = "2" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E16)" + register "reset_delay_ms" = "10" + register "reset_off_delay_ms" = "2" + register "wake_on_touch" = "true" + # NOTE: Use GpioInt() in _CRS and does not use GPE. + register "wake_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(GPP_VGPIO3_THC0)" + register "active_ltr" = "1" + register "idle_ltr" = "0" + register "connected_device" = "TH_SENSOR_ELAN_REX" + register "soc_hidspi.write_mode" = "HIDSPI_WRITE_MODE_SINGLE" + register "soc_hidspi.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E16)" + register "add_acpi_dma_property" = "true" + device generic 0 alias touch_0_spi_google on + probe TOUCHSCREEN TOUCHSCREEN_THC_SPI_ELAN_REX + end + end end device ref thc1 on register "thc_wake_on_touch[1]" = "true" @@ -902,6 +947,24 @@ chip soc/intel/pantherlake probe TOUCHSCREEN TOUCHSCREEN_LPSS_I2C end end + chip drivers/i2c/hid + register "generic.hid" = ""ELAN9006"" + register "generic.desc" = ""ELAN Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E18_IRQ)" + # NOTE: pmc_gpe0_dw2 is GPP_E in baseboard devicetree.cb. + register "generic.wake" = "GPE0_DW2_18" + register "generic.probed" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E16)" + register "generic.reset_delay_ms" = "20" + register "generic.reset_off_delay_ms" = "2" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F08)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 10 on + probe TOUCHSCREEN TOUCHSCREEN_LPSS_I2C_ELAN_REX + end + end end # I2C4 device ref i2c5 on chip drivers/i2c/hid diff --git a/src/mainboard/google/fatcat/variants/fatcat/variant.c b/src/mainboard/google/fatcat/variants/fatcat/variant.c index a3d7e79e65..a8b5b4146d 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/variant.c +++ b/src/mainboard/google/fatcat/variants/fatcat/variant.c @@ -51,9 +51,11 @@ void variant_update_soc_chip_config(struct soc_intel_pantherlake_config *config) * | with WOT disabled | with WOT disabled| | | * +===================+==================+=================+============================+ */ - if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C))) { + if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C_ELAN_REX))) { config->thc_mode[0] = THC_HID_I2C_MODE; - } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI))) { + } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI_ELAN_REX))) { config->thc_mode[0] = THC_HID_SPI_MODE; } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_GSPI))) { config->serial_io_gspi_mode[PchSerialIoIndexGSPI0] = PchSerialIoPci; From 01d82febb2f7d784d3ac918740045772e94e777e Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sun, 21 Dec 2025 20:03:36 +0100 Subject: [PATCH 183/789] util/autoport: Separate handling of Kconfig selects Previously, `KconfigBool` was used to generate selects (if the option value is true) or bool option overrides (if the option value is false). This approach is not particularly flexible: one cannot have conditions for selects, and bool option overrides can only disable options. Introduce a new `KconfigStatement` map of Kconfig names to conditions. An empty condition string means that no condition is to be added. Also update uses of `KconfigBool` to `KconfigSelect` to preserve autoport's current behaviour. TEST=Generated files for HP ProBook 4740s (Sandy Bridge) do not change. Change-Id: I88666ce0d761c1d393ac602196229ec0878fed42 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/90585 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- util/autoport/azalia.go | 2 +- util/autoport/bd82x6x.go | 4 ++-- util/autoport/ec_fixme.go | 2 +- util/autoport/ec_lenovo.go | 4 ++-- util/autoport/haswell.go | 6 +++--- util/autoport/lynxpoint.go | 6 +++--- util/autoport/main.go | 36 +++++++++++++++++++++--------------- util/autoport/rce823.go | 2 +- util/autoport/sandybridge.go | 10 +++++----- 9 files changed, 39 insertions(+), 33 deletions(-) diff --git a/util/autoport/azalia.go b/util/autoport/azalia.go index a7c8b7253b..eb28a7c2dc 100644 --- a/util/autoport/azalia.go +++ b/util/autoport/azalia.go @@ -11,7 +11,7 @@ type azalia struct { func (i azalia) Scan(ctx Context, addr PCIDevData) { /* FIXME: Rework to output new verb table format, or better yet use hda-decoder to avoid duplicating functionality */ - KconfigBool["AZALIA_USE_LEGACY_VERB_TABLE"] = true + KconfigSelect["AZALIA_USE_LEGACY_VERB_TABLE"] = "" az := Create(ctx, "hda_verb.c") defer az.Close() diff --git a/util/autoport/bd82x6x.go b/util/autoport/bd82x6x.go index a94b359b51..919c043d07 100644 --- a/util/autoport/bd82x6x.go +++ b/util/autoport/bd82x6x.go @@ -62,8 +62,8 @@ func (b bd82x6x) Scan(ctx Context, addr PCIDevData) { inteltool := ctx.InfoSource.GetInteltool() GPIO(ctx, inteltool) - KconfigBool["SOUTHBRIDGE_INTEL_"+b.variant] = true - KconfigBool["SERIRQ_CONTINUOUS_MODE"] = true + KconfigSelect["SOUTHBRIDGE_INTEL_"+b.variant] = "" + KconfigSelect["SERIRQ_CONTINUOUS_MODE"] = "" KconfigInt["USBDEBUG_HCD_INDEX"] = 2 KconfigComment["USBDEBUG_HCD_INDEX"] = "FIXME: check this" dmi := ctx.InfoSource.GetDMI() diff --git a/util/autoport/ec_fixme.go b/util/autoport/ec_fixme.go index 17c431c65e..bdb2966077 100644 --- a/util/autoport/ec_fixme.go +++ b/util/autoport/ec_fixme.go @@ -60,7 +60,7 @@ Method(_PTS,1) } ` - KconfigBool["EC_ACPI"] = true + KconfigSelect["EC_ACPI"] = "" si := Create(ctx, "acpi/superio.asl") defer si.Close() diff --git a/util/autoport/ec_lenovo.go b/util/autoport/ec_lenovo.go index 38257d0eda..267b64f6f5 100644 --- a/util/autoport/ec_lenovo.go +++ b/util/autoport/ec_lenovo.go @@ -149,8 +149,8 @@ void mainboard_smi_sleep(u8 slp_typ) Add_SPDX(ec, ASL, GPL2_only) ec.WriteString("#include \n") - KconfigBool["EC_LENOVO_PMH7"] = true - KconfigBool["EC_LENOVO_H8"] = true + KconfigSelect["EC_LENOVO_PMH7"] = "" + KconfigSelect["EC_LENOVO_H8"] = "" pmh := DevTreeNode{ Chip: "ec/lenovo/pmh7", diff --git a/util/autoport/haswell.go b/util/autoport/haswell.go index 668771b754..f4f331e036 100644 --- a/util/autoport/haswell.go +++ b/util/autoport/haswell.go @@ -101,9 +101,9 @@ func (i haswellmc) Scan(ctx Context, addr PCIDevData) { PutPCIDev(addr, "Host bridge") - KconfigBool["NORTHBRIDGE_INTEL_HASWELL"] = true - KconfigBool["HAVE_ACPI_TABLES"] = true - KconfigBool["HAVE_ACPI_RESUME"] = true + KconfigSelect["NORTHBRIDGE_INTEL_HASWELL"] = "" + KconfigSelect["HAVE_ACPI_TABLES"] = "" + KconfigSelect["HAVE_ACPI_RESUME"] = "" DSDTIncludes = append(DSDTIncludes, DSDTInclude{ File: "cpu/intel/common/acpi/cpu.asl", diff --git a/util/autoport/lynxpoint.go b/util/autoport/lynxpoint.go index 899736ef22..681072c6b4 100644 --- a/util/autoport/lynxpoint.go +++ b/util/autoport/lynxpoint.go @@ -143,11 +143,11 @@ func (b lynxpoint) Scan(ctx Context, addr PCIDevData) { GPIO(ctx, inteltool) } - KconfigBool["SOUTHBRIDGE_INTEL_LYNXPOINT"] = true + KconfigSelect["SOUTHBRIDGE_INTEL_LYNXPOINT"] = "" if isULT { - KconfigBool["INTEL_LYNXPOINT_LP"] = true + KconfigSelect["INTEL_LYNXPOINT_LP"] = "" } - KconfigBool["SERIRQ_CONTINUOUS_MODE"] = true + KconfigSelect["SERIRQ_CONTINUOUS_MODE"] = "" if isULT { KconfigInt["USBDEBUG_HCD_INDEX"] = 1 } else { diff --git a/util/autoport/main.go b/util/autoport/main.go index 1246e3277c..896a81f869 100644 --- a/util/autoport/main.go +++ b/util/autoport/main.go @@ -130,6 +130,7 @@ var KconfigComment map[string]string = map[string]string{} var KconfigString map[string]string = map[string]string{} var KconfigHex map[string]uint32 = map[string]uint32{} var KconfigInt map[string]int = map[string]int{} +var KconfigSelect map[string]string = map[string]string{} var ROMSizeKB = 0 var ROMProtocol = "" var FlashROMSupport = "" @@ -572,6 +573,14 @@ func makeComment(name string) string { return " # " + cmt } +func makeSelect(name string) string { + condition, ok := KconfigSelect[name] + if !ok || condition == "" { + return name + makeComment(name) + } + return name + " if " + condition + makeComment(name) +} + func makeKconfig(ctx Context) { kc := Create(ctx, "Kconfig") defer kc.Close() @@ -581,33 +590,30 @@ func makeKconfig(ctx Context) { fmt.Fprintf(kc, "config BOARD_SPECIFIC_OPTIONS\n\tdef_bool y\n") keys := []string{} - for name, val := range KconfigBool { - if val { - keys = append(keys, name) - } + for name, _ := range KconfigSelect { + keys = append(keys, name) } sort.Strings(keys) for _, name := range keys { - fmt.Fprintf(kc, "\tselect %s%s\n", name, makeComment(name)) + fmt.Fprintf(kc, "\tselect %s\n", makeSelect(name)) } keys = nil - for name, val := range KconfigBool { - if !val { - keys = append(keys, name) - } + for name, _ := range KconfigBool { + keys = append(keys, name) } sort.Strings(keys) for _, name := range keys { + var mapper map[bool]rune = map[bool]rune{false: 'n', true: 'y'} fmt.Fprintf(kc, ` config %s%s bool - default n -`, name, makeComment(name)) + default %c +`, name, makeComment(name), mapper[KconfigBool[name]]) } keys = nil @@ -742,7 +748,7 @@ func main() { } if dmi.IsLaptop { - KconfigBool["SYSTEM_TYPE_LAPTOP"] = true + KconfigSelect["SYSTEM_TYPE_LAPTOP"] = "" } ctx.SaneVendor = sanitize(ctx.Vendor) for { @@ -767,7 +773,7 @@ func main() { ScanRoot(ctx) if IGDEnabled { - KconfigBool["MAINBOARD_HAS_LIBGFXINIT"] = true + KconfigSelect["MAINBOARD_HAS_LIBGFXINIT"] = "" KconfigComment["MAINBOARD_HAS_LIBGFXINIT"] = "FIXME: check this" AddRAMStageFile("gma-mainboard.ads", "CONFIG_MAINBOARD_USE_LIBGFXINIT") } @@ -851,10 +857,10 @@ func main() { } if ROMSizeKB == 0 { - KconfigBool["BOARD_ROMSIZE_KB_2048"] = true + KconfigSelect["BOARD_ROMSIZE_KB_2048"] = "" KconfigComment["BOARD_ROMSIZE_KB_2048"] = "FIXME: correct this" } else { - KconfigBool[fmt.Sprintf("BOARD_ROMSIZE_KB_%d", ROMSizeKB)] = true + KconfigSelect[fmt.Sprintf("BOARD_ROMSIZE_KB_%d", ROMSizeKB)] = "" } makeKconfig(ctx) diff --git a/util/autoport/rce823.go b/util/autoport/rce823.go index 7c921093f4..20fab4a33d 100644 --- a/util/autoport/rce823.go +++ b/util/autoport/rce823.go @@ -30,7 +30,7 @@ func (r rce823) Scan(ctx Context, addr PCIDevData) { PutPCIChip(addr, cur) } PutPCIDev(addr, "Ricoh SD card reader") - KconfigBool["DRIVERS_RICOH_RCE822"] = true + KconfigSelect["DRIVERS_RICOH_RCE822"] = "" } func init() { diff --git a/util/autoport/sandybridge.go b/util/autoport/sandybridge.go index 552bd66d48..b479bfe739 100644 --- a/util/autoport/sandybridge.go +++ b/util/autoport/sandybridge.go @@ -62,11 +62,11 @@ func (i sandybridgemc) Scan(ctx Context, addr PCIDevData) { PutPCIDev(addr, "") /* FIXME:XX some configs are unsupported. */ - KconfigBool["NORTHBRIDGE_INTEL_SANDYBRIDGE"] = true - KconfigBool["USE_NATIVE_RAMINIT"] = true - KconfigBool["INTEL_INT15"] = true - KconfigBool["HAVE_ACPI_TABLES"] = true - KconfigBool["HAVE_ACPI_RESUME"] = true + KconfigSelect["NORTHBRIDGE_INTEL_SANDYBRIDGE"] = "" + KconfigSelect["USE_NATIVE_RAMINIT"] = "" + KconfigSelect["INTEL_INT15"] = "" + KconfigSelect["HAVE_ACPI_TABLES"] = "" + KconfigSelect["HAVE_ACPI_RESUME"] = "" DSDTIncludes = append(DSDTIncludes, DSDTInclude{ File: "cpu/intel/common/acpi/cpu.asl", From 2fc8051679320c4cb00ad54f39d5b18097d0da94 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sun, 21 Dec 2025 20:22:47 +0100 Subject: [PATCH 184/789] util/autoport: Factor out getting sorted Kconfig option names Using generics (introduced in go 1.18) we can avoid repeating the same code multiple times by encapsulating it into a generic function. Change-Id: I5dc6696f8802d3fe57290121e22b2c27c545d3ef Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/90586 Tested-by: build bot (Jenkins) Reviewed-by: Nicholas Reviewed-by: Matt DeVillier --- util/autoport/go.mod | 1 + util/autoport/main.go | 53 ++++++++++++------------------------------- 2 files changed, 15 insertions(+), 39 deletions(-) diff --git a/util/autoport/go.mod b/util/autoport/go.mod index 55a89cc9e1..dac59c1285 100644 --- a/util/autoport/go.mod +++ b/util/autoport/go.mod @@ -1 +1,2 @@ module autoport +go 1.18 diff --git a/util/autoport/main.go b/util/autoport/main.go index 896a81f869..1718b4f24d 100644 --- a/util/autoport/main.go +++ b/util/autoport/main.go @@ -581,6 +581,15 @@ func makeSelect(name string) string { return name + " if " + condition + makeComment(name) } +func getSortedKeys[T any](strMap map[string]T) []string { + keys := []string{} + for k, _ := range strMap { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + func makeKconfig(ctx Context) { kc := Create(ctx, "Kconfig") defer kc.Close() @@ -589,25 +598,12 @@ func makeKconfig(ctx Context) { fmt.Fprintf(kc, "if %s\n\n", ctx.KconfigName) fmt.Fprintf(kc, "config BOARD_SPECIFIC_OPTIONS\n\tdef_bool y\n") - keys := []string{} - for name, _ := range KconfigSelect { - keys = append(keys, name) - } - sort.Strings(keys) - - for _, name := range keys { + for _, name := range getSortedKeys(KconfigSelect) { fmt.Fprintf(kc, "\tselect %s\n", makeSelect(name)) } - keys = nil - for name, _ := range KconfigBool { - keys = append(keys, name) - } - - sort.Strings(keys) - - for _, name := range keys { + for _, name := range getSortedKeys(KconfigBool) { var mapper map[bool]rune = map[bool]rune{false: 'n', true: 'y'} fmt.Fprintf(kc, ` config %s%s @@ -616,14 +612,7 @@ config %s%s `, name, makeComment(name), mapper[KconfigBool[name]]) } - keys = nil - for name, _ := range KconfigString { - keys = append(keys, name) - } - - sort.Strings(keys) - - for _, name := range keys { + for _, name := range getSortedKeys(KconfigString) { fmt.Fprintf(kc, ` config %s%s string @@ -631,14 +620,7 @@ config %s%s `, name, makeComment(name), KconfigString[name]) } - keys = nil - for name, _ := range KconfigHex { - keys = append(keys, name) - } - - sort.Strings(keys) - - for _, name := range keys { + for _, name := range getSortedKeys(KconfigHex) { fmt.Fprintf(kc, ` config %s%s hex @@ -646,14 +628,7 @@ config %s%s `, name, makeComment(name), KconfigHex[name]) } - keys = nil - for name, _ := range KconfigInt { - keys = append(keys, name) - } - - sort.Strings(keys) - - for _, name := range keys { + for _, name := range getSortedKeys(KconfigInt) { fmt.Fprintf(kc, ` config %s%s int From 94672e2b45b61729afbfb990a4b7efb80f4b79a2 Mon Sep 17 00:00:00 2001 From: Nicholas Sudsgaard Date: Tue, 14 Oct 2025 21:43:16 +0900 Subject: [PATCH 185/789] sb/intel/ibexpeak: Remove 6/7 series chipset PCI IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support for the Ibex Peak chipset was added in commit 888d559b0373 ("Support for Ibexpeak southbridge") by copy-pasting the bd82x6x implementation and making appropriate changes. This resulted in some of the PCI IDs for 6/7 series chipsets being left behind. While some of these PCI IDs were removed in a commit b7d878888013 ("ibexpeak/lpc: Fix PCIIDs."), there are still some that remain, we remove those in this commit. Change-Id: I5dc0e4fb2694eec9ef6246e0ae9211dff604d5b9 Signed-off-by: Nicholas Sudsgaard Reviewed-on: https://review.coreboot.org/c/coreboot/+/89569 Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Matt DeVillier --- src/southbridge/intel/ibexpeak/azalia.c | 2 -- src/southbridge/intel/ibexpeak/me.c | 1 - src/southbridge/intel/ibexpeak/smbus.c | 2 -- 3 files changed, 5 deletions(-) diff --git a/src/southbridge/intel/ibexpeak/azalia.c b/src/southbridge/intel/ibexpeak/azalia.c index 6196096a14..6a738f356d 100644 --- a/src/southbridge/intel/ibexpeak/azalia.c +++ b/src/southbridge/intel/ibexpeak/azalia.c @@ -117,8 +117,6 @@ static struct device_operations azalia_ops = { }; static const unsigned short pci_device_ids[] = { - 0x1c20, - 0x1e20, PCI_DID_INTEL_IBEXPEAK_AUDIO, 0 }; diff --git a/src/southbridge/intel/ibexpeak/me.c b/src/southbridge/intel/ibexpeak/me.c index fbcb01dc3a..68a0ca5b3a 100644 --- a/src/southbridge/intel/ibexpeak/me.c +++ b/src/southbridge/intel/ibexpeak/me.c @@ -515,7 +515,6 @@ static struct device_operations device_ops = { }; static const unsigned short pci_device_ids[] = { - 0x1c3a, PCI_DID_INTEL_IBEXPEAK_HECI1, 0 }; diff --git a/src/southbridge/intel/ibexpeak/smbus.c b/src/southbridge/intel/ibexpeak/smbus.c index 6bbd1e44f8..13886131bb 100644 --- a/src/southbridge/intel/ibexpeak/smbus.c +++ b/src/southbridge/intel/ibexpeak/smbus.c @@ -33,8 +33,6 @@ static struct device_operations smbus_ops = { }; static const unsigned short pci_device_ids[] = { - 0x1c22, - 0x1e22, PCI_DID_INTEL_IBEXPEAK_SMBUS, 0 }; From 0f450a8d9cc986da99968a1854c28f07f7d9b77f Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Thu, 15 Jan 2026 20:04:01 +0000 Subject: [PATCH 186/789] mb/starlabs/starlite: Set card_reader fallback value to 0 The `card_reader` option is only available on specific boards, so to avoid enabling a USB port that isn't connected, set the fallback value to 0 instead of 1. Change-Id: Ied540d6242758663db7a7a11fbefb5c4a84b942d Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90770 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c b/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c index 35d289c7ad..cc8dd4a7b9 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c +++ b/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c @@ -78,6 +78,6 @@ void devtree_update(void) gna_dev->enabled = 0; /* Enable/Disable Card Reader based on CMOS Settings */ - if (get_uint_option("card_reader", 1) == 0) + if (get_uint_option("card_reader", 0) == 0) cfg->usb2_ports[3].enable = 0; } From d94d4b8a2500d96685b2bd94e9e16887072fbd79 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Fri, 2 Jan 2026 16:40:02 +0000 Subject: [PATCH 187/789] mb/starlabs/starlite_adl: Add trace length for the card reader Add the trace length for the card reader USB port, and based on this value adjust the macro used accordingly. Change-Id: I1c7661f492b9193b75ed39abb2f5d14614cfc213 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90675 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- .../starlabs/starlite_adl/variants/mk_v/devicetree.cb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devicetree.cb b/src/mainboard/starlabs/starlite_adl/variants/mk_v/devicetree.cb index 10680827c6..b0080bd292 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devicetree.cb +++ b/src/mainboard/starlabs/starlite_adl/variants/mk_v/devicetree.cb @@ -85,8 +85,8 @@ chip soc/intel/alderlake # Internal Bluetooth 1874 mil register "usb2_ports[9]" = "USB2_PORT_SHORT(OC_SKIP)" - # Card Reader - register "usb2_ports[3]" = "USB2_PORT_MID(OC_SKIP)" + # Card Reader 3926 mil + register "usb2_ports[3]" = "USB2_PORT_SHORT(OC_SKIP)" chip drivers/usb/acpi device ref xhci_root_hub on From 8cfc71d9e07e79d9be262e35a97e2bd204324e90 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Tue, 13 Jan 2026 11:48:42 +0800 Subject: [PATCH 188/789] libpayload: Pass panel power-off commands to payloads Introduce the lb_panel_poweroff/cb_panel_poweroff structs to pass the panel power-off commands from coreboot to payloads. Also add mipi_panel_parse_commands() to libpayload libc, so that payloads can utilize it to parse the power-off commands. BUG=b:474187570 TEST=emerge-jedi coreboot libpayload BRANCH=skywalker Change-Id: I652178c8075a1f3aee356502e682ef9a4f3d1cf8 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90738 Tested-by: build bot (Jenkins) Reviewed-by: Yidi Lin Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Julius Werner --- payloads/libpayload/include/coreboot_tables.h | 9 +++++++++ payloads/libpayload/include/libpayload.h | 1 + payloads/libpayload/include/sysinfo.h | 1 + payloads/libpayload/libc/Makefile.mk | 1 + payloads/libpayload/libc/coreboot.c | 8 ++++++++ src/commonlib/include/commonlib/coreboot_tables.h | 9 +++++++++ 6 files changed, 29 insertions(+) diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h index 01d86c272c..36ec6e9125 100644 --- a/payloads/libpayload/include/coreboot_tables.h +++ b/payloads/libpayload/include/coreboot_tables.h @@ -85,6 +85,7 @@ enum { CB_TAG_TYPE_C_INFO = 0x0042, CB_TAG_ACPI_RSDP = 0x0043, CB_TAG_PCIE = 0x0044, + CB_TAG_PANEL_POWEROFF = 0x0049, CB_TAG_CMOS_OPTION_TABLE = 0x00c8, CB_TAG_OPTION = 0x00c9, CB_TAG_OPTION_ENUM = 0x00ca, @@ -446,6 +447,14 @@ struct cb_acpi_rsdp { cb_uint64_t rsdp_pointer; /* Address of the ACPI RSDP */ }; +struct cb_panel_poweroff { + uint32_t tag; + uint32_t size; + + /* MIPI DSI poweroff commands from panel_serializable_data. */ + uint8_t cmd[]; +}; + enum boot_mode_t { CB_BOOT_MODE_NORMAL, CB_BOOT_MODE_LOW_BATTERY, diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h index 86429144ec..6125fe0285 100644 --- a/payloads/libpayload/include/libpayload.h +++ b/payloads/libpayload/include/libpayload.h @@ -47,6 +47,7 @@ #include #if CONFIG(LP_GPL) #include +#include #else #include #endif diff --git a/payloads/libpayload/include/sysinfo.h b/payloads/libpayload/include/sysinfo.h index 23e2d55409..324233170e 100644 --- a/payloads/libpayload/include/sysinfo.h +++ b/payloads/libpayload/include/sysinfo.h @@ -180,6 +180,7 @@ struct sysinfo_t { enum boot_mode_t boot_mode; uintptr_t memory_info; + uintptr_t cb_panel_poweroff; }; extern struct sysinfo_t lib_sysinfo; diff --git a/payloads/libpayload/libc/Makefile.mk b/payloads/libpayload/libc/Makefile.mk index 063118a925..45152f135c 100644 --- a/payloads/libpayload/libc/Makefile.mk +++ b/payloads/libpayload/libc/Makefile.mk @@ -52,5 +52,6 @@ libc-srcs += $(coreboottop)/src/commonlib/bsd/string.c ifeq ($(CONFIG_LP_GPL),y) libc-srcs += $(coreboottop)/src/commonlib/device_tree.c libc-srcs += $(coreboottop)/src/commonlib/list.c +libc-srcs += $(coreboottop)/src/commonlib/mipi/cmd.c endif endif diff --git a/payloads/libpayload/libc/coreboot.c b/payloads/libpayload/libc/coreboot.c index b1be37c19e..bd05d7c04a 100644 --- a/payloads/libpayload/libc/coreboot.c +++ b/payloads/libpayload/libc/coreboot.c @@ -301,6 +301,11 @@ static void cb_parse_rsdp(void *ptr, struct sysinfo_t *info) info->acpi_rsdp = cb_acpi_rsdp->rsdp_pointer; } +static void cb_parse_panel_poweroff(unsigned char *ptr, struct sysinfo_t *info) +{ + info->cb_panel_poweroff = virt_to_phys(ptr); +} + int cb_parse_header(void *addr, int len, struct sysinfo_t *info) { struct cb_header *header; @@ -447,6 +452,9 @@ int cb_parse_header(void *addr, int len, struct sysinfo_t *info) case CB_TAG_PCIE: cb_parse_pcie(ptr, info); break; + case CB_TAG_PANEL_POWEROFF: + cb_parse_panel_poweroff(ptr, info); + break; case CB_TAG_BOOT_MODE: cb_parse_boot_mode(ptr, info); break; diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index fcc7761044..ed5d52f0b5 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -91,6 +91,7 @@ enum { LB_TAG_CAPSULE = 0x0046, LB_TAG_CFR_ROOT = 0x0047, LB_TAG_ROOT_BRIDGE_INFO = 0x0048, + LB_TAG_PANEL_POWEROFF = 0x0049, /* The following options are CMOS-related */ LB_TAG_CMOS_OPTION_TABLE = 0x00c8, LB_TAG_OPTION = 0x00c9, @@ -629,6 +630,14 @@ struct lb_cfr { /* struct lb_cfr_option_form forms[] */ }; +struct lb_panel_poweroff { + uint32_t tag; + uint32_t size; + + /* MIPI DSI poweroff commands from panel_serializable_data. */ + uint8_t cmd[]; +}; + enum boot_mode_t { LB_BOOT_MODE_NORMAL, LB_BOOT_MODE_LOW_BATTERY, From 03b47f947fef5e584c5e0ec4cb739934cffd8d47 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Tue, 13 Jan 2026 16:29:10 +0800 Subject: [PATCH 189/789] soc/mediatek: Add mtk_get_mipi_panel_data() API Introduce mtk_get_mipi_panel_data() API for the mainboard code to get the MIPI panel data. BUG=b:474187570 TEST=emerge-jedi coreboot BRANCH=skywalker Change-Id: Ibd3bccb7ce164a4ad3d6cb36345514240495e62f Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90739 Reviewed-by: Yidi Lin Reviewed-by: Chen-Tsung Hsieh Tested-by: build bot (Jenkins) --- src/soc/mediatek/common/display.c | 9 +++++++-- src/soc/mediatek/common/include/soc/display.h | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c index 08139dfc3d..9d2c873838 100644 --- a/src/soc/mediatek/common/display.c +++ b/src/soc/mediatek/common/display.c @@ -16,6 +16,8 @@ #include #include +static struct panel_serializable_data *mipi_data; + static struct panel_serializable_data *get_mipi_cmd_from_cbfs(struct panel_description *desc) { /* @@ -136,8 +138,6 @@ int mtk_display_init(void) return -1; } } else { - struct panel_serializable_data *mipi_data = NULL; - if (panel->get_edid) { if (panel->get_edid(&edid) < 0) return -1; @@ -239,3 +239,8 @@ u32 mtk_get_vrefresh(const struct edid *edid) return vrefresh; } + +const struct panel_serializable_data *mtk_get_mipi_panel_data(void) +{ + return mipi_data; +} diff --git a/src/soc/mediatek/common/include/soc/display.h b/src/soc/mediatek/common/include/soc/display.h index 62ea9b0c23..3e3b4a2164 100644 --- a/src/soc/mediatek/common/include/soc/display.h +++ b/src/soc/mediatek/common/include/soc/display.h @@ -40,4 +40,6 @@ void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, void mtk_ddp_ovlsys_start(uintptr_t fb_addr, const struct edid *edid, enum disp_path_sel path); +const struct panel_serializable_data *mtk_get_mipi_panel_data(void); + #endif From c0998983d0002741aaa2e3068e75fba189ed754a Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 14 Jan 2026 13:49:47 -0600 Subject: [PATCH 190/789] ec/google/chromeec: Fix uninitialized buffer in cbi_get_uint32() Commit e59c5abd13e6 ("ec/google/chromeec: Add EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC") refactored cbi_get_uint32() to write directly to the caller's buffer instead of using a local variable. This caused uninitialized memory (containing garbage addresses) to be passed to the EC as the return buffer during CBI reads. In the case of google/zork, the call to google_chromeec_cbi_get_board_version() returned garbage data (e.g., 0xae6ccd05 vs 0x5) which caused incorrect code paths to be taken: - variant_override_gpio_table() selected wrong GPIO tables based on invalid board version comparisons - variant_touchscreen_update() skipped touchscreen GPIO configuration because variant_uses_v3_6_schematics() returned true for garbage values - variant_uses_codec_gpi() returned wrong value, preventing headphone jack interrupt setup These misconfigurations caused input devices (touchpad, touchscreen, trackpoint) to be non-functional, despite being detected by the OS. The fix restores the original behavior by using a local variable initialized to 0, ensuring a clean buffer is always passed to the EC. TEST=build/boot google/zork, verify board version is read correctly, all input devices functional under Linux/Windows. Change-Id: Ia7be0bcc588075ab5c994edc3d68e979cc01ac79 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90761 Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- src/ec/google/chromeec/ec.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index f4da831006..ee04d4a669 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -841,7 +841,12 @@ static int cbi_read(void *buf, size_t bufsize, uint32_t tag, bool check_size) static int cbi_get_uint32(uint32_t *id, uint32_t tag) { - return cbi_read(id, sizeof(*id), tag, true); + uint32_t r = 0; + int rv = cbi_read(&r, sizeof(r), tag, true); + if (rv) + return rv; + *id = r; + return 0; } int google_chromeec_cbi_get_sku_id(uint32_t *id) From 4374bbd37b026972c24c000f3fdce73410b98d0b Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 14 Jan 2026 16:44:10 -0600 Subject: [PATCH 191/789] payloads/ipxe: Update and use the stable version Recent changes to iPXE related to UEFI SecureBoot handling are causing builds to break, so update the "stable" tag to the last commit in December 2025 and use that by default until things are sorted out in the master branch. TEST=build samsung/stumpy with iPXE for edk2 Change-Id: I5ccdbbf35273cf1e963b913327ffa94df46a1497 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90771 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- payloads/external/iPXE/Kconfig | 6 +++--- payloads/external/iPXE/Makefile | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/payloads/external/iPXE/Kconfig b/payloads/external/iPXE/Kconfig index 14f8898f4e..31686c8916 100644 --- a/payloads/external/iPXE/Kconfig +++ b/payloads/external/iPXE/Kconfig @@ -53,15 +53,15 @@ if BUILD_IPXE choice prompt "iPXE version" - default IPXE_MASTER + default IPXE_STABLE config IPXE_STABLE - bool "2022.1" + bool "2025.12" help iPXE uses a rolling release with no stable version, for reproducibility, use the last commit of a given month as the 'stable' version. - This is iPXE from the end of January, 2022. + This is iPXE from the end of December, 2025. config IPXE_MASTER bool "master" diff --git a/payloads/external/iPXE/Makefile b/payloads/external/iPXE/Makefile index a58d5f79ce..284d4275b4 100644 --- a/payloads/external/iPXE/Makefile +++ b/payloads/external/iPXE/Makefile @@ -2,7 +2,7 @@ # 2022.1 - Last commit of January 2022 # When updating, change the name both here and in payloads/external/iPXE/Kconfig -STABLE_COMMIT_ID=6ba671acd922ee046b257c5119b8a0f64d275473 +STABLE_COMMIT_ID=7c39c04a537ce29dccc6f2bae9749d1d371429c1 TAG-$(CONFIG_IPXE_MASTER)=origin/master TAG-$(CONFIG_IPXE_STABLE)=$(STABLE_COMMIT_ID) From 3b18467e8a91a1b8e1d612da0b602c87665806e5 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 14 Jan 2026 17:04:41 -0600 Subject: [PATCH 192/789] payloads/ipxe: Unconditionally restore config files post-build Replace backup file mechanism with git restore to fix restoration bugs and simplify the build system. Files are now always restored after build completion, ensuring a clean git state regardless of which configuration options modify the config files. TEST=build samsung/stumpy with iPXE for edk2 twice in a row without failure due to dirty repo state. Change-Id: I9c88f5ca5e5a0172f7c0a94e4edfe0192340d1e2 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90772 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- payloads/external/iPXE/Makefile | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/payloads/external/iPXE/Makefile b/payloads/external/iPXE/Makefile index 284d4275b4..a9fb43f846 100644 --- a/payloads/external/iPXE/Makefile +++ b/payloads/external/iPXE/Makefile @@ -42,15 +42,10 @@ checkout: fetch config: checkout ifeq ($(CONSOLE_SERIAL),yy) - cp "$(project_dir)/src/config/console.h" "$(project_dir)/src/config/console.h.cb" - cp "$(project_dir)/src/config/serial.h" "$(project_dir)/src/config/serial.h.cb" sed -i'' 's|//#define\s*CONSOLE_SERIAL.*|#define CONSOLE_SERIAL|' "$(project_dir)/src/config/console.h" sed -i'' 's|#define\s*COMCONSOLE.*|#define COMCONSOLE $(IPXE_UART)|' "$(project_dir)/src/config/serial.h" sed -i'' 's|#define\s*COMSPEED.*|#define COMSPEED $(CONFIG_TTYS0_BAUD)|' "$(project_dir)/src/config/serial.h" endif -ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_IPXE_NO_PROMPT)),) - cp "$(project_dir)/src/config/general.h" "$(project_dir)/src/config/general.h.cb" -endif ifeq ($(CONFIG_HAS_SCRIPT),y) sed -i'' 's|//#define\s*IMAGE_SCRIPT.*|#define IMAGE_SCRIPT|' "$(project_dir)/src/config/general.h" endif @@ -73,13 +68,7 @@ else $(MAKE) -C $(project_dir)/src $(IPXE_BUILD_TARGET) $(PXE_MAKE_OPTS) endif cp $(project_dir)/src/$(IPXE_BUILD_TARGET) $(project_dir)/ipxe.rom -ifeq ($(CONSOLE_SERIAL),yy) - cp "$(project_dir)/src/config/console.h.cb" "$(project_dir)/src/config/console.h" - cp "$(project_dir)/src/config/serial.h.cb" "$(project_dir)/src/config/serial.h" -endif -ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_IPXE_NO_PROMPT)),) - cp "$(project_dir)/src/config/general.h.cb" "$(project_dir)/src/config/general.h" -endif + cd $(project_dir) && git restore src/config/console.h src/config/serial.h src/config/general.h clean: test -d $(project_dir) && $(MAKE) -C $(project_dir)/src veryclean || exit 0 From d5fb4becd5890ad584e7488948c4ad84a192907b Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Fri, 16 Jan 2026 15:18:29 +0800 Subject: [PATCH 193/789] mb/google/nissa/var/yavilla: Update DTT parameters This CL update max TDP from 6W to 7W as requested by thermal team. Increase tdp_pl1_override value from 6 W to 7 W. Increase PL1 max power value from 6 W to 7 W. The settings has been verified by thermal team. BUG=b:476292154, b:476292156 TEST=emerge-nissa coreboot chromeos-bootimage verified test result by thermal team Change-Id: Iaedfb2caec589dd5f5be5cc872e302d55fa51dd6 Signed-off-by: Tony Huang Reviewed-on: https://review.coreboot.org/c/coreboot/+/90774 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- .../google/brya/variants/yavilla/overridetree.cb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/brya/variants/yavilla/overridetree.cb b/src/mainboard/google/brya/variants/yavilla/overridetree.cb index 588919da54..8ed08cc0d3 100644 --- a/src/mainboard/google/brya/variants/yavilla/overridetree.cb +++ b/src/mainboard/google/brya/variants/yavilla/overridetree.cb @@ -113,6 +113,12 @@ chip soc/intel/alderlake .configure_ext_fivr = 1, }" + register "power_limits_config[ADL_N_041_6W_CORE]" = "{ + .tdp_pl1_override = 7, + .tdp_pl2_override = 25, + .tdp_pl4 = 78, + }" + # Intel Common SoC Config #+-------------------+---------------------------+ #| Field | Value | @@ -202,7 +208,7 @@ chip soc/intel/alderlake register "controls.power_limits" = "{ .pl1 = { .min_power = 3000, - .max_power = 6000, + .max_power = 7000, .time_window_min = 28 * MSECS_PER_SEC, .time_window_max = 32 * MSECS_PER_SEC, .granularity = 200 From cacc11de4f8ca1f5c65b9cfa53fe042e05c6e88b Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Wed, 7 Jan 2026 22:12:09 +0100 Subject: [PATCH 194/789] include/cpu/x86/msr.h: Update return types from int -> bool For all functions which check flags, return a bool type instead of an int type. Signed-off-by: Maximilian Brune Change-Id: I39f0e2f392ec999f7622ed28c5755dd4d0eecf42 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90776 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/include/cpu/x86/msr.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/include/cpu/x86/msr.h b/src/include/cpu/x86/msr.h index 2fdb064608..f4f33b40f6 100644 --- a/src/include/cpu/x86/msr.h +++ b/src/include/cpu/x86/msr.h @@ -142,77 +142,77 @@ static inline void mca_clear_status(void) /* Helpers for interpreting MC[i]_STATUS */ -static inline int mca_valid(msr_t msr) +static inline bool mca_valid(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_VAL); } -static inline int mca_over(msr_t msr) +static inline bool mca_over(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_OVERFLOW); } -static inline int mca_uc(msr_t msr) +static inline bool mca_uc(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_UC); } -static inline int mca_en(msr_t msr) +static inline bool mca_en(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_EN); } -static inline int mca_miscv(msr_t msr) +static inline bool mca_miscv(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_MISCV); } -static inline int mca_addrv(msr_t msr) +static inline bool mca_addrv(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_ADDRV); } -static inline int mca_pcc(msr_t msr) +static inline bool mca_pcc(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_PCC); } -static inline int mca_tcc(msr_t msr) +static inline bool mca_tcc(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_TCC); } -static inline int mca_syndv(msr_t msr) +static inline bool mca_syndv(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_SYNDV); } -static inline int mca_idv(msr_t msr) +static inline bool mca_idv(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_COREID_VAL); } -static inline int mca_cecc(msr_t msr) +static inline bool mca_cecc(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_CECC); } -static inline int mca_uecc(msr_t msr) +static inline bool mca_uecc(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_UECC); } -static inline int mca_defd(msr_t msr) +static inline bool mca_defd(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_DEFERRED); } -static inline int mca_poison(msr_t msr) +static inline bool mca_poison(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_POISON); } -static inline int mca_sublink(msr_t msr) +static inline bool mca_sublink(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_SUBLINK); } From a12663fd88c04f4afceb20ee06bb5416747d082c Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Tue, 30 Sep 2025 15:11:01 +0200 Subject: [PATCH 195/789] drivers/spi: Allow SoC to provide the SPI flash CS index On AMD platforms the PSP can boot from different SPI CS lines and do a recovery boot in case the default CS0 isn't usable. Allow the SoC to provide the current boot_device CS line by adding a new weak function. Signed-off-by: Patrick Rudolph Signed-off-by: Maximilian Brune Change-Id: Ic9ed54b7979405d433f22458265f09701cda842e Reviewed-on: https://review.coreboot.org/c/coreboot/+/90777 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/drivers/spi/boot_device_rw_nommap.c | 7 ++++++- src/drivers/spi/cbfs_spi.c | 7 ++++++- src/include/boot_device.h | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/drivers/spi/boot_device_rw_nommap.c b/src/drivers/spi/boot_device_rw_nommap.c index 58efc87fe9..86581600d1 100644 --- a/src/drivers/spi/boot_device_rw_nommap.c +++ b/src/drivers/spi/boot_device_rw_nommap.c @@ -8,6 +8,11 @@ static struct spi_flash sfg; static bool sfg_init_done; +__weak int boot_device_spi_cs(void) +{ + return 0; /* Default to chip select 0 */ +} + static ssize_t spi_readat(const struct region_device *rd, void *b, size_t offset, size_t size) { @@ -47,7 +52,7 @@ static const struct region_device spi_rw = static void boot_device_rw_init(void) { const int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS; - const int cs = 0; + const int cs = boot_device_spi_cs(); if (sfg_init_done == true) return; diff --git a/src/drivers/spi/cbfs_spi.c b/src/drivers/spi/cbfs_spi.c index 15a18b72e4..5f3b5ca40a 100644 --- a/src/drivers/spi/cbfs_spi.c +++ b/src/drivers/spi/cbfs_spi.c @@ -17,6 +17,11 @@ static struct spi_flash spi_flash_info; static bool spi_flash_init_done; +__weak int boot_device_spi_cs(void) +{ + return 0; /* Default to chip select 0 */ +} + /* * SPI speed logging for big transfers available with BIOS_DEBUG. The format is: * @@ -82,7 +87,7 @@ static struct mmap_helper_region_device mdev = void boot_device_init(void) { int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS; - int cs = 0; + int cs = boot_device_spi_cs(); if (spi_flash_init_done == true) return; diff --git a/src/include/boot_device.h b/src/include/boot_device.h index 883f37c8c8..1a44aefc03 100644 --- a/src/include/boot_device.h +++ b/src/include/boot_device.h @@ -27,6 +27,9 @@ enum bootdev_prot_type { * most likely not to work so don't rely on such semantics. */ +/* Return the chip select index used for probing the SPI flash. */ +int boot_device_spi_cs(void); + /* Return the region_device for the read-only boot device. This is the root device for all CBFS boot devices. */ const struct region_device *boot_device_ro(void); From cf2c2555f45fa1982de01bc74b759922be6a3e1b Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Wed, 1 Oct 2025 10:21:59 +0200 Subject: [PATCH 196/789] mb/siemens/mc_ehl8: Add new board variant based on mc_ehl1 This mainboard is based on mc_ehl1. As a first step, it contains a copy of the mc_ehl1 directory with minimal changes. Special adaptations for mc_ehl8 mainboard will follow in separate commits. TEST=Built siemens/mc_ehl8 successfully. Change-Id: Icf8e90e7d3ed58ea4500cb6132fef37e32c5a4c2 Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/90764 Reviewed-by: Mario Scheithauer Tested-by: build bot (Jenkins) --- src/mainboard/siemens/mc_ehl/Kconfig | 5 + src/mainboard/siemens/mc_ehl/Kconfig.name | 3 + .../siemens/mc_ehl/variants/mc_ehl8/Kconfig | 42 ++++ .../mc_ehl/variants/mc_ehl8/Makefile.mk | 7 + .../mc_ehl/variants/mc_ehl8/devicetree.cb | 191 ++++++++++++++++++ .../siemens/mc_ehl/variants/mc_ehl8/gpio.c | 178 ++++++++++++++++ .../siemens/mc_ehl/variants/mc_ehl8/memory.c | 58 ++++++ .../siemens/mc_ehl/variants/mc_ehl8/post.c | 10 + 8 files changed, 494 insertions(+) create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Makefile.mk create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl8/gpio.c create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl8/memory.c create mode 100644 src/mainboard/siemens/mc_ehl/variants/mc_ehl8/post.c diff --git a/src/mainboard/siemens/mc_ehl/Kconfig b/src/mainboard/siemens/mc_ehl/Kconfig index 3db9ad0d52..25715ad9f8 100644 --- a/src/mainboard/siemens/mc_ehl/Kconfig +++ b/src/mainboard/siemens/mc_ehl/Kconfig @@ -32,6 +32,9 @@ config BOARD_SIEMENS_MC_EHL6 config BOARD_SIEMENS_MC_EHL7 select BOARD_SIEMENS_BASEBOARD_MC_EHL +config BOARD_SIEMENS_MC_EHL8 + select BOARD_SIEMENS_BASEBOARD_MC_EHL + source "src/mainboard/siemens/mc_ehl/variants/*/Kconfig" if BOARD_SIEMENS_BASEBOARD_MC_EHL @@ -47,6 +50,7 @@ config VARIANT_DIR default "mc_ehl5" if BOARD_SIEMENS_MC_EHL5 default "mc_ehl6" if BOARD_SIEMENS_MC_EHL6 default "mc_ehl7" if BOARD_SIEMENS_MC_EHL7 + default "mc_ehl8" if BOARD_SIEMENS_MC_EHL8 config MAINBOARD_PART_NUMBER default "MC EHL1" if BOARD_SIEMENS_MC_EHL1 @@ -56,6 +60,7 @@ config MAINBOARD_PART_NUMBER default "MC EHL5" if BOARD_SIEMENS_MC_EHL5 default "MC EHL6" if BOARD_SIEMENS_MC_EHL6 default "MC EHL7" if BOARD_SIEMENS_MC_EHL7 + default "MC EHL8" if BOARD_SIEMENS_MC_EHL8 config DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" diff --git a/src/mainboard/siemens/mc_ehl/Kconfig.name b/src/mainboard/siemens/mc_ehl/Kconfig.name index ffbfc9d124..57eba04f0a 100644 --- a/src/mainboard/siemens/mc_ehl/Kconfig.name +++ b/src/mainboard/siemens/mc_ehl/Kconfig.name @@ -22,3 +22,6 @@ config BOARD_SIEMENS_MC_EHL6 config BOARD_SIEMENS_MC_EHL7 bool "-> MC EHL7" + +config BOARD_SIEMENS_MC_EHL8 + bool "-> MC EHL8" diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig new file mode 100644 index 0000000000..d07cd32ef8 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig @@ -0,0 +1,42 @@ +## SPDX-License-Identifier: GPL-2.0-only + +if BOARD_SIEMENS_MC_EHL8 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select DRIVERS_I2C_RX6110SA + select DRIVERS_I2C_PI608GP + select DRIVER_INTEL_I210 + select INTEL_LPSS_UART_FOR_CONSOLE + select NC_FPGA_POST_CODE + select MAINBOARD_HAS_TPM2 + select MEMORY_MAPPED_TPM + select TPM_MEASURED_BOOT + select TPM_MEASURED_BOOT_INIT_BOOTBLOCK + +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/mc_ehl.fmd" + +config UART_FOR_CONSOLE + int + default 2 + +config EARLY_PCI_BRIDGE_DEVICE + hex + depends on NC_FPGA_POST_CODE + default 0x1c + +config EARLY_PCI_BRIDGE_FUNCTION + hex + depends on NC_FPGA_POST_CODE + default 0x2 + +config EARLY_PCI_MMIO_BASE + hex + depends on NC_FPGA_POST_CODE + default 0xfe800000 + +config SOC_INTEL_ELKHARTLAKE_TCO_NO_REBOOT_EN + default y + +endif # BOARD_SIEMENS_MC_EHL8 diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Makefile.mk b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Makefile.mk new file mode 100644 index 0000000000..2b78a7a75f --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Makefile.mk @@ -0,0 +1,7 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += gpio.c +romstage-y += memory.c +ramstage-y += gpio.c + +all-$(CONFIG_NC_FPGA_POST_CODE) += post.c diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb new file mode 100644 index 0000000000..6e85734887 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb @@ -0,0 +1,191 @@ +chip soc/intel/elkhartlake + + device cpu_cluster 0 on end + + # GPE configuration + # Note that GPE events called out in ASL code rely on this + # route. i.e. If this route changes then the affected GPE + # offset bits also need to be changed. + register "pmc_gpe0_dw0" = "GPP_B" + register "pmc_gpe0_dw1" = "GPP_F" + register "pmc_gpe0_dw2" = "GPP_E" + + # FSP configuration + register "SaGv" = "SaGv_Disabled" + + # Enable IBECC for the complete memory + register "ibecc" = "{ + .enable = 1, + .mode = IBECC_ALL + }" + + # USB related UPDs + register "usb2_ports[0]" = "USB2_PORT_SHORT(OC_SKIP)" # USB3/2 Type A port 1 + register "usb2_ports[1]" = "USB2_PORT_SHORT(OC_SKIP)" # USB3/2 Type A Port 2 + register "usb2_ports[2]" = "USB2_PORT_MID(OC_SKIP)" # Onboard USB + register "usb2_ports[3]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[4]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[5]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[6]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[7]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[8]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[9]" = "USB2_PORT_EMPTY" # Port is unused + + register "usb3_ports[0]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/2 Type A port1 + register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/2 Type A port2 + register "usb3_ports[2]" = "USB3_PORT_EMPTY" # Port is not used + register "usb3_ports[3]" = "USB3_PORT_EMPTY" # Port is not used + + # Skip the CPU replacement check + register "SkipCpuReplacementCheck" = "1" + + # PCIe root ports related UPDs + register "PcieClkSrcUsage[0]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[1]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[2]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[3]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcUsage[4]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcUsage[5]" = "PCIE_CLK_NOTUSED" + + register "PcieClkSrcClkReq[0]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[1]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[2]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[3]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[4]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[5]" = "PCIE_CLK_NOTUSED" + + # Disable all L1 substates for PCIe root ports + register "PcieRpL1Substates[0]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[1]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[2]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[3]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[6]" = "L1_SS_DISABLED" + + # Disable LTR for all PCIe root ports + register "PcieRpLtrDisable[0]" = "true" + register "PcieRpLtrDisable[1]" = "true" + register "PcieRpLtrDisable[2]" = "true" + register "PcieRpLtrDisable[3]" = "true" + register "PcieRpLtrDisable[6]" = "true" + + # Storage (SATA/SDCARD/EMMC) related UPDs + register "SataSalpSupport" = "0" + register "SataPortsEnable[0]" = "1" + register "SataPortsEnable[1]" = "1" + register "SataPortsDevSlp[0]" = "0" + register "SataPortsDevSlp[1]" = "0" + register "SataPortsSSD[0]" = "1" + register "SataPortsSSD[1]" = "1" + register "SataSpeed" = "SATA_GEN2" + + register "ScsEmmcHs400Enabled" = "0" + register "ScsEmmcDdr50Enabled" = "1" + register "SdCardPowerEnableActiveHigh" = "1" + + # LPSS Serial IO (I2C/UART/GSPI) related UPDs + register "SerialIoI2cMode" = "{ + [PchSerialIoIndexI2C0] = PchSerialIoDisabled, + [PchSerialIoIndexI2C1] = PchSerialIoPci, + [PchSerialIoIndexI2C2] = PchSerialIoDisabled, + [PchSerialIoIndexI2C3] = PchSerialIoDisabled, + [PchSerialIoIndexI2C4] = PchSerialIoPci, + [PchSerialIoIndexI2C5] = PchSerialIoDisabled, + [PchSerialIoIndexI2C6] = PchSerialIoDisabled, + [PchSerialIoIndexI2C7] = PchSerialIoDisabled, + }" + + register "SerialIoI2cPadsTermination" = "{ + [PchSerialIoIndexI2C1] = 1, + [PchSerialIoIndexI2C4] = 1, + }" + + register "SerialIoUartMode" = "{ + [PchSerialIoIndexUART0] = PchSerialIoPci, + [PchSerialIoIndexUART1] = PchSerialIoPci, + [PchSerialIoIndexUART2] = PchSerialIoSkipInit, + }" + + register "SerialIoUartDmaEnable" = "{ + [PchSerialIoIndexUART0] = 1, + [PchSerialIoIndexUART1] = 1, + [PchSerialIoIndexUART2] = 1, + }" + + # TSN GBE related UPDs + register "PchTsnGbeLinkSpeed" = "Tsn_2_5_Gbps" + register "PchTsnGbeSgmiiEnable" = "1" + + # FIVR related settings + register "fivr" = "{ + .fivr_config_en = true, + .vcc_low_high_us = 50, + }" + + # Disable L1 prefetcher + register "L1_prefetcher_disable" = "true" + + # Enable real-time tuning + register "realtime_tuning_enable" = "true" + + device domain 0 on + device pci 00.0 on end # Host Bridge + device pci 02.0 on end # Integrated Graphics Device + + device pci 14.0 on end # USB3.1 xHCI + + device pci 15.0 off end # I2C0 + device pci 15.1 on end # I2C1 + + device pci 16.0 hidden end # Management Engine Interface 1 + + device pci 17.0 on end # SATA + + device pci 19.0 on end # I2C4 + device pci 19.2 on end # UART2 + + device pci 1a.0 on end # eMMC + + device pci 1c.0 on end # RP1 (pcie0 single VC) + device pci 1c.1 on end # RP2 (pcie0 single VC) + device pci 1c.2 on end # RP3 (pcie0 single VC) + device pci 1c.3 on end # RP4 (pcie0 single VC) + device pci 1c.6 on end # RP7 (pcie3 multi VC) + + device pci 1e.0 on end # UART0 + device pci 1e.1 on end # UART1 + + + device pci 1f.0 on # eSPI Interface + chip drivers/pc80/tpm + device pnp 0c31.0 on end + end + end + device pci 1f.2 hidden end # Power Management Controller + device pci 1f.4 on # SMBus + # Enable external RTC chip + chip drivers/i2c/rx6110sa + register "bus_speed" = "I2C_SPEED_STANDARD" + register "pmon_sampling" = "PMON_SAMPL_256_MS" + register "bks_on" = "0" + register "bks_off" = "1" + register "iocut_en" = "1" + register "set_user_date" = "1" + register "user_year" = "04" + register "user_month" = "07" + register "user_day" = "01" + register "user_weekday" = "4" + device i2c 0x32 on end # RTC RX6110 SA + end + # PI7C9X2G608GP PCIe switch configuration + chip drivers/i2c/pi608gp + register "gen2_3p5_enable" = "true" + register "gen2_3p5_amp" = "AMP_LVL_MV(425)" + register "gen2_3p5_deemph" = "DEEMPH_LVL_MV(6, 0)" + device i2c 0x6f on + ops pi608gp_ops + end + end + end + device pci 1f.5 on end # PCH SPI (flash & TPM) + end +end diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/gpio.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/gpio.c new file mode 100644 index 0000000000..ea814a09ac --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/gpio.c @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +/* Pad configuration in ramstage */ +static const struct pad_config gpio_table[] = { + /* Community 0 - GpioGroup GPP_B */ + PAD_CFG_NF(GPP_B2, NONE, PLTRST, NF1), /* PMC_VRALERT_N */ + PAD_CFG_NF(GPP_B3, NONE, PLTRST, NF4), /* ESPI_ALERT0_N */ + PAD_CFG_NF(GPP_B4, NONE, PLTRST, NF4), /* ESPI_ALERT1_N */ + PAD_NC(GPP_B9, NONE), /* Not connected */ + PAD_NC(GPP_B10, NONE), /* Not connected */ + PAD_CFG_NF(GPP_B11, NONE, PLTRST, NF1), /* PMC_ALERT_N */ + PAD_NC(GPP_B14, NONE), /* Not connected */ + PAD_CFG_NF(GPP_B15, NONE, PLTRST, NF5), /* ESPI_CS1_N */ + PAD_NC(GPP_B18, NONE), /* Not connected */ + PAD_NC(GPP_B19, NONE), /* Not connected */ + PAD_NC(GPP_B20, NONE), /* Not connected */ + PAD_NC(GPP_B21, NONE), /* Not connected */ + PAD_NC(GPP_B22, NONE), /* Not connected */ + PAD_NC(GPP_B23, NONE), /* Not connected */ + + /* Community 0 - GpioGroup GPP_T */ + PAD_CFG_NF(GPP_T4, UP_20K, DEEP, NF1), /* PSE_GBE0_INT */ + PAD_CFG_NF(GPP_T5, DN_20K, DEEP, NF1), /* PSE_GBE0_RST_N */ + PAD_CFG_NF(GPP_T6, NONE, DEEP, NF1), /* PSE_GBE0_AUXTS */ + PAD_CFG_NF(GPP_T7, NONE, DEEP, NF1), /* PSE_GBE0_PPS */ + PAD_CFG_NF(GPP_T12, NONE, DEEP, NF2), /* SIO_UART0_RXD */ + PAD_CFG_NF(GPP_T13, NONE, DEEP, NF2), /* SIO_UART0_TXD */ + + /* Community 0 - GpioGroup GPP_G */ + PAD_NC(GPP_G8, NONE), /* Not connected */ + PAD_NC(GPP_G9, NONE), /* Not connected */ + PAD_NC(GPP_G12, NONE), /* Not connected */ + PAD_CFG_NF(GPP_G15, NONE, DEEP, NF1), /* ESPI_IO_0 */ + PAD_CFG_NF(GPP_G16, NONE, DEEP, NF1), /* ESPI_IO_1 */ + PAD_CFG_NF(GPP_G17, NONE, DEEP, NF1), /* ESPI_IO_2 */ + PAD_CFG_NF(GPP_G18, NONE, DEEP, NF1), /* ESPI_IO_3 */ + PAD_CFG_GPI(GPP_G19, UP_20K, PLTRST), /* TPM_IRQ_N */ + PAD_CFG_NF(GPP_G20, NONE, DEEP, NF1), /* ESPI_CSO_N */ + PAD_CFG_NF(GPP_G21, NONE, DEEP, NF1), /* ESPI_CLK */ + PAD_CFG_NF(GPP_G22, NONE, DEEP, NF1), /* ESPI_RST0_N */ + + /* Community 1 - GpioGroup GPP_V */ + PAD_CFG_NF(GPP_V0, UP_20K, DEEP, NF1), /* EMMC_CMD */ + PAD_CFG_NF(GPP_V1, UP_20K, DEEP, NF1), /* EMMC_DATA0 */ + PAD_CFG_NF(GPP_V2, UP_20K, DEEP, NF1), /* EMMC_DATA1 */ + PAD_CFG_NF(GPP_V3, UP_20K, DEEP, NF1), /* EMMC_DATA2 */ + PAD_CFG_NF(GPP_V4, UP_20K, DEEP, NF1), /* EMMC_DATA3 */ + PAD_CFG_NF(GPP_V5, UP_20K, DEEP, NF1), /* EMMC_DATA4 */ + PAD_CFG_NF(GPP_V6, UP_20K, DEEP, NF1), /* EMMC_DATA5 */ + PAD_CFG_NF(GPP_V7, UP_20K, DEEP, NF1), /* EMMC_DATA6 */ + PAD_CFG_NF(GPP_V8, UP_20K, DEEP, NF1), /* EMMC_DATA7 */ + PAD_CFG_NF(GPP_V9, DN_20K, DEEP, NF1), /* EMMC_RCLK */ + PAD_CFG_NF(GPP_V10, DN_20K, DEEP, NF1), /* EMMC_CLK */ + PAD_CFG_NF(GPP_V11, NONE, DEEP, NF1), /* EMMC_RESET_N */ + + /* Community 1 - GpioGroup GPP_H */ + PAD_CFG_NF(GPP_H0, DN_20K, DEEP, NF1), /* PSE_GBE1_INT */ + PAD_CFG_NF(GPP_H1, DN_20K, DEEP, NF1), /* PSE_GBE1_RST_N */ + PAD_CFG_NF(GPP_H2, NONE, DEEP, NF1), /* PSE_GBE1_AUXTS */ + PAD_CFG_NF(GPP_H3, NONE, DEEP, NF1), /* PSE_GBE1_PPS */ + PAD_CFG_NF(GPP_H8, UP_20K, DEEP, NF1), /* SIO_I2C4_SDA */ + PAD_CFG_NF(GPP_H9, UP_20K, DEEP, NF1), /* SIO_I2C4_SCL */ + + /* Community 1 - GpioGroup GPP_D */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* EMMC_PWR_EN_N */ + + /* Community 1 - GpioGroup GPP_U */ + PAD_CFG_NF(GPP_U0, DN_20K, DEEP, NF1), /* GBE_INT */ + PAD_CFG_NF(GPP_U1, DN_20K, DEEP, NF1), /* GBE_RST_N */ + PAD_CFG_NF(GPP_U2, NONE, DEEP, NF1), /* GBE_PPS */ + PAD_CFG_NF(GPP_U3, NONE, DEEP, NF1), /* GBE_AUXTS */ + PAD_NC(GPP_U12, NONE), /* Not connected */ + PAD_NC(GPP_U13, NONE), /* Not connected */ + PAD_NC(GPP_U16, NONE), /* Not connected */ + PAD_NC(GPP_U17, NONE), /* Not connected */ + PAD_NC(GPP_U18, NONE), /* Not connected */ + PAD_CFG_GPO(GPP_U19, 1, DEEP), /* UPD_REQ_N */ + + /* Community 2 - GpioGroup DSW */ + PAD_CFG_NF(GPD4, NONE, PLTRST, NF1), /* SLP_S3 */ + PAD_CFG_NF(GPD5, NONE, PLTRST, NF1), /* SLP_S4 */ + PAD_NC(GPD7, NONE), /* Not connected */ + PAD_CFG_NF(GPD10, NONE, PLTRST, NF1), /* SLP_S5 */ + + /* Community 3 - GpioGroup GPP_S */ + PAD_NC(GPP_S0, NONE), /* Not connected */ + PAD_NC(GPP_S1, NONE), /* Not connected */ + + /* Community 3 - GpioGroup GPP_A */ + PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD3 */ + PAD_CFG_NF(GPP_A1, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD2 */ + PAD_CFG_NF(GPP_A2, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD1 */ + PAD_CFG_NF(GPP_A3, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD0 */ + PAD_CFG_NF(GPP_A4, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXCLK */ + PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXCTL */ + PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXCLK */ + PAD_CFG_NF(GPP_A7, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD3 */ + PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD2 */ + PAD_CFG_NF(GPP_A9, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD1 */ + PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD0 */ + PAD_CFG_NF(GPP_A23, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXCTL */ + + /* Community 4 - GpioGroup GPP_C */ + PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1), /* PSE_GBE0_MDC */ + PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1), /* PSE_GBE0_MDIO */ + PAD_NC(GPP_C5, NONE), /* Not connected */ + PAD_CFG_NF(GPP_C6, NONE, DEEP, NF1), /* PSE_GBE1_MDC */ + PAD_CFG_NF(GPP_C7, NONE, DEEP, NF1), /* PSE_GBE1_MDIO */ + PAD_NC(GPP_C8, NONE), /* Not connected */ + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF4), /* SIO_UART1_RXD */ + PAD_CFG_NF(GPP_C13, NONE, DEEP, NF4), /* SIO_UART1_TXD */ + PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), /* GBE_MDIO */ + PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), /* GBE_MDC */ + PAD_CFG_NF(GPP_C18, NONE, DEEP, NF4), /* SIO_I2C1_SDA */ + PAD_CFG_NF(GPP_C19, NONE, DEEP, NF4), /* SIO_I2C1_SCL */ + + /* Community 4 - GpioGroup GPP_F */ + PAD_NC(GPP_F0, NONE), /* Not connected */ + PAD_NC(GPP_F1, NONE), /* Not connected */ + PAD_NC(GPP_F2, NONE), /* Not connected */ + PAD_NC(GPP_F3, NONE), /* Not connected */ + PAD_NC(GPP_F4, NONE), /* Not connected */ + PAD_NC(GPP_F5, NONE), /* Not connected */ + PAD_NC(GPP_F7, NONE), /* Not connected */ + PAD_NC(GPP_F8, NONE), /* Not connected */ + PAD_NC(GPP_F10, NONE), /* Not connected */ + PAD_NC(GPP_F11, NONE), /* Not connected */ + PAD_NC(GPP_F12, NONE), /* Not connected */ + PAD_NC(GPP_F13, NONE), /* Not connected */ + PAD_NC(GPP_F14, NONE), /* Not connected */ + PAD_NC(GPP_F15, NONE), /* Not connected */ + PAD_NC(GPP_F16, NONE), /* Not connected */ + PAD_NC(GPP_F17, NONE), /* Not connected */ + PAD_NC(GPP_F20, NONE), /* Not connected */ + PAD_NC(GPP_F21, NONE), /* Not connected */ + + /* Community 4 - GpioGroup GPP_E */ + PAD_CFG_NF(GPP_E0, NONE, DEEP, NF1), /* SATA_LED_N */ + PAD_CFG_NF(GPP_E3, NONE, DEEP, NF1), /* DDI1_HPD */ + PAD_CFG_NF(GPP_E5, NONE, DEEP, NF1), /* DDI1_DDC_SDA */ + PAD_NC(GPP_E6, NONE), /* Not connected */ + PAD_CFG_NF(GPP_E7, NONE, DEEP, NF1), /* DDI1_DDC_SCL */ + PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* DDI0_HPD */ + PAD_NC(GPP_E15, NONE), /* Not connected */ + PAD_NC(GPP_E16, NONE), /* Not connected */ + PAD_CFG_NF(GPP_E18, NONE, DEEP, NF1), /* DDI0_DDC_SDA */ + PAD_CFG_NF(GPP_E19, NONE, DEEP, NF1), /* DDI0_DDC_SCL */ + PAD_NC(GPP_E23, NONE), /* Not connected */ + + /* Community 5 - GpioGroup GPP_R */ + PAD_NC(GPP_R1, NONE), /* Not connected */ + PAD_NC(GPP_R2, NONE), /* Not connected */ + PAD_NC(GPP_R3, NONE), /* Not connected */ +}; + +/* Early pad configuration in bootblock */ +static const struct pad_config early_gpio_table[] = { + PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* SMB_CLK */ + PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* SMB_DATA */ + PAD_CFG_NF(GPP_C2, NONE, DEEP, NF2), /* SMB_ALERT_N */ + PAD_CFG_NF(GPP_C20, NONE, DEEP, NF4), /* SIO_UART2_RXD */ + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF4), /* SIO_UART2_TXD */ +}; + +const struct pad_config *variant_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(gpio_table); + return gpio_table; +} + +const struct pad_config *variant_early_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(early_gpio_table); + return early_gpio_table; +} diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/memory.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/memory.c new file mode 100644 index 0000000000..a800d30ef1 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/memory.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +static const struct mb_cfg mc_ehl_lpddr4x_memcfg_cfg = { + .dq_map[DDR_CH0] = { + {0xf, 0xf0}, + {0xf, 0xf0}, + {0xff, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0} + }, + + .dq_map[DDR_CH1] = { + {0xf, 0xf0}, + {0xf, 0xf0}, + {0xff, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0} + }, + + /* + * The dqs_map arrays map the ddr4 pins to the SoC pins + * for both channels. + * + * the index = pin number on ddr4 part + * the value = pin number on SoC + */ + .dqs_map[DDR_CH0] = {3, 0, 1, 2, 7, 4, 5, 6}, + .dqs_map[DDR_CH1] = {3, 0, 1, 2, 7, 4, 5, 6}, + + /* Baseboard uses 100, 100 and 100 rcomp resistors */ + .rcomp_resistor = {100, 100, 100}, + + .rcomp_targets = {60, 40, 30, 20, 30}, + + /* LPDDR4x does not allow interleaved memory */ + .dq_pins_interleaved = 0, + + /* Baseboard is using config 2 for vref_ca */ + .vref_ca_config = 2, + + /* Enable Early Command Training */ + .ect = 1, + + /* Set Board Type */ + .UserBd = BOARD_TYPE_MOBILE, +}; + +const struct mb_cfg *variant_memcfg_config(void) +{ + return &mc_ehl_lpddr4x_memcfg_cfg; +} diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/post.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/post.c new file mode 100644 index 0000000000..c34e2539bc --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/post.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void mainboard_post(uint8_t value) +{ + nc_fpga_post(value); +} From d81025700805831b4cc36f6b34a3e63c6dc9a501 Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Tue, 7 Oct 2025 08:26:16 +0200 Subject: [PATCH 197/789] mb/siemens/mc_ehl8: Configure PCIe root ports This patch updates the PCIe root port settings, as the PCIe topology differs from the mc_ehl1 mainboard. TEST=Booted into OS and verifed that all relevant PCIe devices are detected. Change-Id: I0953a139b63080489128cc0a0dc865b65632b575 Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/90765 Reviewed-by: Mario Scheithauer Tested-by: build bot (Jenkins) --- .../mc_ehl/variants/mc_ehl8/devicetree.cb | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb index 6e85734887..b4fca918f0 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb @@ -55,19 +55,29 @@ chip soc/intel/elkhartlake register "PcieClkSrcClkReq[5]" = "PCIE_CLK_NOTUSED" # Disable all L1 substates for PCIe root ports - register "PcieRpL1Substates[0]" = "L1_SS_DISABLED" - register "PcieRpL1Substates[1]" = "L1_SS_DISABLED" register "PcieRpL1Substates[2]" = "L1_SS_DISABLED" register "PcieRpL1Substates[3]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[4]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[5]" = "L1_SS_DISABLED" register "PcieRpL1Substates[6]" = "L1_SS_DISABLED" # Disable LTR for all PCIe root ports - register "PcieRpLtrDisable[0]" = "true" - register "PcieRpLtrDisable[1]" = "true" register "PcieRpLtrDisable[2]" = "true" register "PcieRpLtrDisable[3]" = "true" + register "PcieRpLtrDisable[4]" = "true" + register "PcieRpLtrDisable[5]" = "true" register "PcieRpLtrDisable[6]" = "true" + # Enable PCIe PTM (Precision Time Measurement) for all PCIe root ports + register "PciePtm[2]" = "true" + register "PciePtm[3]" = "true" + register "PciePtm[4]" = "true" + register "PciePtm[5]" = "true" + register "PciePtm[6]" = "true" + + # Determine PCIe root port speed + register "PcieRpPcieSpeed[5]" = "2" + # Storage (SATA/SDCARD/EMMC) related UPDs register "SataSalpSupport" = "0" register "SataPortsEnable[0]" = "1" @@ -145,10 +155,10 @@ chip soc/intel/elkhartlake device pci 1a.0 on end # eMMC - device pci 1c.0 on end # RP1 (pcie0 single VC) - device pci 1c.1 on end # RP2 (pcie0 single VC) device pci 1c.2 on end # RP3 (pcie0 single VC) device pci 1c.3 on end # RP4 (pcie0 single VC) + device pci 1c.4 on end # RP5 (pcie1 multi VC) + device pci 1c.5 on end # RP6 (pcie2 multi VC) device pci 1c.6 on end # RP7 (pcie3 multi VC) device pci 1e.0 on end # UART0 From 483c3e51ae4eaabf844033f01c045ddfe1a16da4 Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Thu, 9 Oct 2025 13:13:34 +0200 Subject: [PATCH 198/789] mb/siemens/mc_ehl8: Configure I2C and SMB devices On this board, different I2C controllers must be activated and a different RTC chip is used compared to mc_ehl1. TEST=Booted into OS and verified that all relevant devices are detected. Change-Id: If2990b7d8d599c6e5f5841d8018d2a3f00dbc515 Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/90766 Reviewed-by: Mario Scheithauer Tested-by: build bot (Jenkins) --- .../siemens/mc_ehl/variants/mc_ehl8/Kconfig | 2 +- .../mc_ehl/variants/mc_ehl8/devicetree.cb | 23 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig index d07cd32ef8..b0941d7ed1 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig @@ -4,7 +4,7 @@ if BOARD_SIEMENS_MC_EHL8 config BOARD_SPECIFIC_OPTIONS def_bool y - select DRIVERS_I2C_RX6110SA + select DRIVERS_I2C_RV3028C7 select DRIVERS_I2C_PI608GP select DRIVER_INTEL_I210 select INTEL_LPSS_UART_FOR_CONSOLE diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb index b4fca918f0..34cf91baa2 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb @@ -95,18 +95,19 @@ chip soc/intel/elkhartlake # LPSS Serial IO (I2C/UART/GSPI) related UPDs register "SerialIoI2cMode" = "{ [PchSerialIoIndexI2C0] = PchSerialIoDisabled, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoDisabled, + [PchSerialIoIndexI2C1] = PchSerialIoDisabled, + [PchSerialIoIndexI2C2] = PchSerialIoPci, [PchSerialIoIndexI2C3] = PchSerialIoDisabled, [PchSerialIoIndexI2C4] = PchSerialIoPci, [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - [PchSerialIoIndexI2C6] = PchSerialIoDisabled, + [PchSerialIoIndexI2C6] = PchSerialIoPci, [PchSerialIoIndexI2C7] = PchSerialIoDisabled, }" register "SerialIoI2cPadsTermination" = "{ - [PchSerialIoIndexI2C1] = 1, + [PchSerialIoIndexI2C2] = 1, [PchSerialIoIndexI2C4] = 1, + [PchSerialIoIndexI2C6] = 1, }" register "SerialIoUartMode" = "{ @@ -141,10 +142,12 @@ chip soc/intel/elkhartlake device pci 00.0 on end # Host Bridge device pci 02.0 on end # Integrated Graphics Device + device pci 10.0 on end # I2C6 + device pci 14.0 on end # USB3.1 xHCI device pci 15.0 off end # I2C0 - device pci 15.1 on end # I2C1 + device pci 15.2 on end # I2C2 device pci 16.0 hidden end # Management Engine Interface 1 @@ -173,18 +176,16 @@ chip soc/intel/elkhartlake device pci 1f.2 hidden end # Power Management Controller device pci 1f.4 on # SMBus # Enable external RTC chip - chip drivers/i2c/rx6110sa + chip drivers/i2c/rv3028c7 register "bus_speed" = "I2C_SPEED_STANDARD" - register "pmon_sampling" = "PMON_SAMPL_256_MS" - register "bks_on" = "0" - register "bks_off" = "1" - register "iocut_en" = "1" register "set_user_date" = "1" register "user_year" = "04" register "user_month" = "07" register "user_day" = "01" register "user_weekday" = "4" - device i2c 0x32 on end # RTC RX6110 SA + register "bckup_sw_mode" = "BACKUP_SW_LEVEL" + register "cap_charge" = "CHARGE_OFF" + device i2c 0x52 on end # RTC RV3028-C7 end # PI7C9X2G608GP PCIe switch configuration chip drivers/i2c/pi608gp From d420e1fb8735a08592cb80c07889ad323c6dc380 Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Thu, 13 Nov 2025 10:57:45 +0100 Subject: [PATCH 199/789] mb/siemens/mc_ehl8: Switch from LPSS UART to legacy 8250 I/O UART Replace the memory-mapped LPSS UART2 with I/O port-mapped legacy 8250 UART for the serial console which is placed on mainboard. - Removing INTEL_LPSS_UART_FOR_CONSOLE activates the DRIVERS_UART_8250IO switch by default. - Change UART_FOR_CONSOLE from 2 to 0 (COM1 at I/O 0x3F8). - Add SOC_INTEL_COMMON_BLOCK_LPC_COMB_ENABLE (to enable COM2 at I/O 0x2F8). - Sort Kconfig switches alphabetically. TEST=Built and booted on mc_ehl8 - Verifed boot log on COM1. - Verifed functionality in OS via: 1) stty -F /dev/ttySx 115200 cs8 -cstopb -parenb 2) sending: echo "teststring" > /dev/ttySx 3) receiving: cat /dev/ttySx Change-Id: I72b2c0e745b40beab862ee3b68fdb6bfc54ed9ed Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/90767 Tested-by: build bot (Jenkins) Reviewed-by: Mario Scheithauer --- src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig index b0941d7ed1..4160e7bc22 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig @@ -4,13 +4,13 @@ if BOARD_SIEMENS_MC_EHL8 config BOARD_SPECIFIC_OPTIONS def_bool y - select DRIVERS_I2C_RV3028C7 - select DRIVERS_I2C_PI608GP select DRIVER_INTEL_I210 - select INTEL_LPSS_UART_FOR_CONSOLE + select DRIVERS_I2C_PI608GP + select DRIVERS_I2C_RV3028C7 select NC_FPGA_POST_CODE select MAINBOARD_HAS_TPM2 select MEMORY_MAPPED_TPM + select SOC_INTEL_COMMON_BLOCK_LPC_COMB_ENABLE select TPM_MEASURED_BOOT select TPM_MEASURED_BOOT_INIT_BOOTBLOCK @@ -19,7 +19,7 @@ config FMDFILE config UART_FOR_CONSOLE int - default 2 + default 0 config EARLY_PCI_BRIDGE_DEVICE hex From 532543027ae43ec2b7f4a74d44b1017f194332a4 Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Thu, 15 Jan 2026 14:03:03 +0100 Subject: [PATCH 200/789] mb/siemens/{mc_ehl6,mc_ehl7}: Configure GPIO GPP_G5 (SD CD) pull-up On mc_ehl6/7 mainboards, the internal GPIO pull-up is required for the SD card "Card Detect" signal to function properly. This patch updates the GPIO configuration accordingly. TEST=Booted mc_ehl6 and verified the voltage level at the relevant pin before and after the patch. Change-Id: I96a381f100dd9886ced030434316125d60a13a72 Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/90769 Reviewed-by: Mario Scheithauer Tested-by: build bot (Jenkins) --- src/mainboard/siemens/mc_ehl/variants/mc_ehl6/gpio.c | 1 + src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/gpio.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/gpio.c index 49f737b868..4ec42c02cf 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/gpio.c +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/gpio.c @@ -27,6 +27,7 @@ static const struct pad_config gpio_table[] = { PAD_CFG_NF(GPP_T13, NONE, DEEP, NF2), /* SIO_UART0_TXD */ /* Community 0 - GpioGroup GPP_G */ + PAD_CFG_NF(GPP_G5, UP_20K, DEEP, NF1), /* SD Card Detect */ PAD_NC(GPP_G8, NONE), /* Not connected */ PAD_NC(GPP_G9, NONE), /* Not connected */ PAD_CFG_GPI(GPP_G19, UP_20K, PLTRST), /* TPM_IRQ_N */ diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c index 49f737b868..18997f7c0f 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c @@ -27,6 +27,7 @@ static const struct pad_config gpio_table[] = { PAD_CFG_NF(GPP_T13, NONE, DEEP, NF2), /* SIO_UART0_TXD */ /* Community 0 - GpioGroup GPP_G */ + PAD_CFG_NF(GPP_G5, UP_20K, DEEP, NF1), /* SD Card Detect */ PAD_NC(GPP_G8, NONE), /* Not connected */ PAD_NC(GPP_G9, NONE), /* Not connected */ PAD_CFG_GPI(GPP_G19, UP_20K, PLTRST), /* TPM_IRQ_N */ From 18ffcafa61727955dd11a7fc1d5c8d76db8fccf4 Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Wed, 14 Jan 2026 17:50:26 +0530 Subject: [PATCH 201/789] mb/google/bluey/quartz: Adjust PS8820 init sequence List of changes: - Increase the delay between romstage and ramstage GPIO init sequence. - Delay the USB host initialization to meet the timing requirements. BUG=b:475214332 TEST=Verify USB 3.0 storage key detection on Google/Quartz. Change-Id: Ib6044b1e65fe0fe2fde5b688a9491d6e3fc75727 Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90758 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/mainboard.c | 11 +++++++++++ src/mainboard/google/bluey/romstage.c | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 91c0f3dfad..6551976f55 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -93,9 +94,19 @@ static void setup_usb(void) setup_usb_typec(); enable_usb_camera(); +} + +static void setup_usb_late(void *unused) +{ + /* Skip USB initialization if boot mode is "low-battery" or "off-mode charging"*/ + if (is_low_power_boot()) + return; + setup_usb_host0(); } +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, setup_usb_late, NULL); + void lb_add_boot_mode(struct lb_header *header) { if (!CONFIG(EC_GOOGLE_CHROMEEC)) diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index e0f1f05743..aeb1eeda6b 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -101,6 +101,9 @@ static void early_setup_usb(void) void platform_romstage_main(void) { + /* Setup early USB related config */ + early_setup_usb(); + /* Watchdog must be checked first to avoid erasing watchdog info later. */ check_wdog(); @@ -120,9 +123,6 @@ void platform_romstage_main(void) qclib_rerun(); - /* Setup early USB related config */ - early_setup_usb(); - /* * Enable this power rail now for FPMCU stability prior to * its reset being deasserted in ramstage. This applies From a974b7668e21d138a3103f903a59e4504d98dd3b Mon Sep 17 00:00:00 2001 From: Ulysse Ballesteros Date: Thu, 30 Oct 2025 11:14:04 +0100 Subject: [PATCH 202/789] soc/intel/*: Disable InternalGfx w/o iGPU to prevent FSP-M/S crash Add verification to ensure that the integrated GPU is available, avoiding crashes in FSP-M and FSP-S. The problem was first identified on Skylake systems where the iGPU is missing or disabled, particularly when VT-D is enabled, which can cause FSP-S to hang during boot. Enabling SGX hides the issue, but it also leads to unstable virtualization. Apply the fix to Alderlake, Cannonlake, and Tigerlake SoCs in addition to Skylake. TEST=Build and boot to OS (Windows, Proxmox). Check to verify functions work. (Skylake H110 + Xeon E3-1245 V5, E3-1260L V5, i7-6700K, i3-7100) Change-Id: I394f46ed5a277218a8dd587705eaecabe59fd110 Signed-off-by: Ulysse Ballesteros Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/89821 Reviewed-by: Walter Sonius Tested-by: build bot (Jenkins) Reviewed-by: Alicja Michalska --- src/soc/intel/alderlake/romstage/fsp_params.c | 16 ++++++++++++++-- src/soc/intel/cannonlake/romstage/fsp_params.c | 16 ++++++++++------ src/soc/intel/skylake/chip.c | 14 +++++++++++++- src/soc/intel/skylake/romstage/fsp_params.c | 17 +++++++++++++---- src/soc/intel/tigerlake/romstage/fsp_params.c | 14 ++++++++++++-- 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/soc/intel/alderlake/romstage/fsp_params.c b/src/soc/intel/alderlake/romstage/fsp_params.c index 730b1f82b2..4bb2980b2b 100644 --- a/src/soc/intel/alderlake/romstage/fsp_params.c +++ b/src/soc/intel/alderlake/romstage/fsp_params.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -152,9 +153,19 @@ static void fill_fspm_igd_params(FSP_M_CONFIG *m_cfg, [DDI_PORT_3] = {&m_cfg->DdiPort3Ddc, &m_cfg->DdiPort3Hpd}, [DDI_PORT_4] = {&m_cfg->DdiPort4Ddc, &m_cfg->DdiPort4Hpd}, }; - m_cfg->InternalGfx = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); - if (m_cfg->InternalGfx) { + + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); + + /* Probe for no IGD and disable InternalGfx to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } + + if (igd_enabled) { /* IGD is enabled, set IGD stolen size to 60MB. */ + m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_60MB); m_cfg->ApertureSize = get_uint_option("igd_aperture_size", IGD_AP_SZ_256MB); /* DP port config */ @@ -168,6 +179,7 @@ static void fill_fspm_igd_params(FSP_M_CONFIG *m_cfg, } } else { /* IGD is disabled, skip IGD init in FSP. */ + m_cfg->InternalGfx = 0; m_cfg->IgdDvmt50PreAlloc = 0; /* DP port config */ m_cfg->DdiPortAConfig = 0; diff --git a/src/soc/intel/cannonlake/romstage/fsp_params.c b/src/soc/intel/cannonlake/romstage/fsp_params.c index 38dfdd8922..c86da261d2 100644 --- a/src/soc/intel/cannonlake/romstage/fsp_params.c +++ b/src/soc/intel/cannonlake/romstage/fsp_params.c @@ -30,12 +30,16 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) m_cfg->HyperThreading = get_uint_option("hyper_threading", CONFIG(FSP_HYPERTHREADING)); - /* - * Probe for no IGD and disable InternalGfx and panel power to prevent a - * crash in FSP-M. - */ - const bool igd_on = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); - if (igd_on && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) != 0xffff) { + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); + + /* Probe for no IGD and disable InternalGfx and panel power to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } + + if (igd_enabled) { /* Set IGD stolen size to 64MB. */ m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_64MB); diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c index 0061c10ae8..a884035f59 100644 --- a/src/soc/intel/skylake/chip.c +++ b/src/soc/intel/skylake/chip.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -491,7 +492,18 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) /* Enable VT-d and X2APIC */ if (soc_vtd_enabled()) { - params->VtdBaseAddress[0] = GFXVT_BASE_ADDRESS; + /* + * Probe for no IGD and set VtdBaseAddress accordingly to prevent a + * crash in FSP-S. + */ + const struct device *igd_dev = pcidev_path_on_root(SA_DEVFN_IGD); + if (igd_dev && pci_read_config16(igd_dev, PCI_VENDOR_ID) != 0xffff) { + printk(BIOS_DEBUG, "iGPU present - GFXVT_BASE_ADDRESS set\n"); + params->VtdBaseAddress[0] = GFXVT_BASE_ADDRESS; + } else { + printk(BIOS_DEBUG, "No iGPU - GFXVT_BASE_ADDRESS disabled\n"); + params->VtdBaseAddress[0] = 0; + } params->VtdBaseAddress[1] = VTVC0_BASE_ADDRESS; params->X2ApicOptOut = 0; tconfig->VtdDisable = 0; diff --git a/src/soc/intel/skylake/romstage/fsp_params.c b/src/soc/intel/skylake/romstage/fsp_params.c index 3ca8a48472..5d59ff18c3 100644 --- a/src/soc/intel/skylake/romstage/fsp_params.c +++ b/src/soc/intel/skylake/romstage/fsp_params.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include #include @@ -104,7 +105,14 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, static void soc_primary_gfx_config_params(FSP_M_CONFIG *m_cfg, const struct soc_intel_skylake_config *config) { - m_cfg->InternalGfx = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); + + /* Probe for no IGD and disable InternalGfx to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } /* * If iGPU is enabled, set IGD stolen size to 64MB. The FBC @@ -116,12 +124,13 @@ static void soc_primary_gfx_config_params(FSP_M_CONFIG *m_cfg, * * If disabled, don't reserve memory for it. */ - if (m_cfg->InternalGfx) { - /* IGD is enabled, set IGD stolen size to 64MB. */ + if (igd_enabled) { + /* Set IGD stolen size to 64MB. */ + m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_64MB); m_cfg->ApertureSize = get_uint_option("igd_aperture_size", IGD_AP_SZ_256MB); } else { - /* IGD is disabled, skip IGD init in FSP. */ + m_cfg->InternalGfx = 0; m_cfg->IgdDvmt50PreAlloc = 0; } diff --git a/src/soc/intel/tigerlake/romstage/fsp_params.c b/src/soc/intel/tigerlake/romstage/fsp_params.c index 3e171b198a..0f6c80cfec 100644 --- a/src/soc/intel/tigerlake/romstage/fsp_params.c +++ b/src/soc/intel/tigerlake/romstage/fsp_params.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -27,14 +28,23 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, m_cfg->HyperThreading = get_uint_option("hyper_threading", CONFIG(FSP_HYPERTHREADING)); - m_cfg->InternalGfx = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); - if (m_cfg->InternalGfx) { + /* Probe for no IGD and disable InternalGfx to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } + + if (igd_enabled) { /* IGD is enabled, set IGD stolen size to 60MB. */ + m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_60MB); m_cfg->ApertureSize = get_uint_option("igd_aperture_size", IGD_AP_SZ_256MB); } else { /* IGD is disabled, skip IGD init in FSP. */ + m_cfg->InternalGfx = 0; m_cfg->IgdDvmt50PreAlloc = 0; } From 0ee48a475c8da08fc8e42faefc00a249015b8890 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Tue, 13 Jan 2026 14:50:14 +0800 Subject: [PATCH 203/789] drivers/mipi: Add power-off commands for TM_TL121BVMS07_00C Add DSI power-off commands for TM_TL121BVMS07_00C, so that payloads can run it to properly disable the display. Also refactor the init commands using MIPI_DCS_* macros to improve readability. BUG=b:474187570 TEST=emerge-jedi coreboot libpayload BRANCH=skywalker Change-Id: I0e7da1d23c658d7f3594cbb651c229057810319c Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90740 Reviewed-by: Yidi Lin Reviewed-by: Chen-Tsung Hsieh Tested-by: build bot (Jenkins) --- src/drivers/mipi/panel-TM_TL121BVMS07_00C.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/drivers/mipi/panel-TM_TL121BVMS07_00C.c b/src/drivers/mipi/panel-TM_TL121BVMS07_00C.c index e69d8ebc54..cbc93804c8 100644 --- a/src/drivers/mipi/panel-TM_TL121BVMS07_00C.c +++ b/src/drivers/mipi/panel-TM_TL121BVMS07_00C.c @@ -29,11 +29,18 @@ struct panel_serializable_data TM_TL121BVMS07_00C = { PANEL_DCS(0xFF, 0x5A, 0xA5, 0x07), PANEL_DCS(0X29, 0x00), PANEL_DCS(0xFF, 0x5A, 0xA5, 0x00), - PANEL_DCS(0x11), + PANEL_DCS(MIPI_DCS_EXIT_SLEEP_MODE), PANEL_DELAY(120), - PANEL_DCS(0x29), + PANEL_DCS(MIPI_DCS_SET_DISPLAY_ON), PANEL_DELAY(20), PANEL_END, }, + .poweroff = { + PANEL_DCS(MIPI_DCS_SET_DISPLAY_OFF), + PANEL_DELAY(20), + PANEL_DCS(MIPI_DCS_ENTER_SLEEP_MODE), + PANEL_DELAY(120), + PANEL_END, + }, .flags = PANEL_FLAG_CPHY, }; From d110cf46697fddfe953a3a7ad4b01b4ea39ce009 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Fri, 16 Jan 2026 08:38:02 +0800 Subject: [PATCH 204/789] commonlib/mipi/cmd: Add mipi_panel_get_commands_len() Introduce a helper function mipi_panel_get_commands_len() to calculate the MIPI panel commands array length. BUG=b:474187570 TEST=emerge-jedi coreboot BRANCH=skywalker Change-Id: I3fef37144f6856057b44415caf578629a35fe573 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90773 Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Yidi Lin Tested-by: build bot (Jenkins) --- src/commonlib/include/commonlib/mipi/cmd.h | 7 +++++ src/commonlib/mipi/cmd.c | 33 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/commonlib/include/commonlib/mipi/cmd.h b/src/commonlib/include/commonlib/mipi/cmd.h index 17e0aeda89..ad3c5a7fb4 100644 --- a/src/commonlib/include/commonlib/mipi/cmd.h +++ b/src/commonlib/include/commonlib/mipi/cmd.h @@ -5,6 +5,7 @@ #include #include +#include #include /* Definitions for cmd in panel_command */ @@ -52,4 +53,10 @@ typedef enum cb_err (*mipi_cmd_func_t)(enum mipi_dsi_transaction type, const u8 enum cb_err mipi_panel_parse_commands(const void *buf, mipi_cmd_func_t cmd_func, void *user_data); +/* + * Parse a command array and calculate the array length, including the trailing + * PANEL_CMD_END. If the array begins with PANEL_CMD_END, 0 will be returned. + */ +size_t mipi_panel_get_commands_len(const void *buf); + #endif /* __COMMONLIB_MIPI_CMD_H__ */ diff --git a/src/commonlib/mipi/cmd.c b/src/commonlib/mipi/cmd.c index 4e5a638d9b..fa52d21c08 100644 --- a/src/commonlib/mipi/cmd.c +++ b/src/commonlib/mipi/cmd.c @@ -78,3 +78,36 @@ enum cb_err mipi_panel_parse_commands(const void *buf, mipi_cmd_func_t cmd_func, return CB_SUCCESS; } + +size_t mipi_panel_get_commands_len(const void *buf) +{ + const void *const buf_start = buf; + const struct panel_command *command = buf; + + if (command->cmd == PANEL_CMD_END) + return 0; + + for (; command->cmd != PANEL_CMD_END; command = buf) { + buf += sizeof(*command); + + switch (command->cmd) { + case PANEL_CMD_DELAY: + /* + * For PANEL_CMD_DELAY, the command->len should not be + * counted for buf. + */ + break; + case PANEL_CMD_GENERIC: + case PANEL_CMD_DCS: + buf += command->len; + break; + default: + printk(BIOS_ERR, "%s: Unknown command code: %d.\n", + __func__, command->cmd); + return 0; + } + } + + /* Add 1 byte for PANEL_CMD_END. */ + return buf - buf_start + 1; +} From 5af56ddf92766c42402f00c9f21a04a72c8bf4a7 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Thu, 15 Jan 2026 16:59:06 +0800 Subject: [PATCH 205/789] mb/google/skywalker: Implement lb_board() to pass LB_TAG_PANEL_POWEROFF To allow payloads to run MIPI panel power-off commands, create a new LB_TAG_PANEL_POWEROFF record and pass it to payloads. BUG=b:474187570 TEST=emerge-jedi coreboot BRANCH=skywalker Change-Id: Ie11e1e78129188cc26d56764449fbafafa8fa316 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90768 Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Julius Werner Reviewed-by: Yidi Lin Tested-by: build bot (Jenkins) --- src/mainboard/google/skywalker/mainboard.c | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/mainboard/google/skywalker/mainboard.c b/src/mainboard/google/skywalker/mainboard.c index a0a89fc215..a36e3fa7a2 100644 --- a/src/mainboard/google/skywalker/mainboard.c +++ b/src/mainboard/google/skywalker/mainboard.c @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +#include #include +#include +#include +#include #include #include #include @@ -166,3 +170,23 @@ struct chip_operations mainboard_ops = { .name = CONFIG_MAINBOARD_PART_NUMBER, .enable_dev = mainboard_enable, }; + +void lb_board(struct lb_header *header) +{ + const struct panel_serializable_data *mipi_data = mtk_get_mipi_panel_data(); + + if (!mipi_data) + return; + + size_t cmd_len = mipi_panel_get_commands_len(mipi_data->poweroff); + + if (!cmd_len) + return; + + struct lb_panel_poweroff *panel_poweroff = + (struct lb_panel_poweroff *)lb_new_record(header); + panel_poweroff->tag = LB_TAG_PANEL_POWEROFF; + panel_poweroff->size = ALIGN_UP(sizeof(*panel_poweroff) + cmd_len, + LB_ENTRY_ALIGN); + memcpy(panel_poweroff->cmd, mipi_data->poweroff, cmd_len); +} From d7d4b67c6a7ec4e904abe0f1234cff494414d427 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Mon, 19 Jan 2026 14:37:29 +0800 Subject: [PATCH 206/789] commonlib/mipi/cmd: Remove unnecessary 'const void *' cast The 'buf' variable is already 'const void *'. Change-Id: I0d52f7386853bf353df637085be0f38f787bf6d5 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90797 Tested-by: build bot (Jenkins) Reviewed-by: Yidi Lin Reviewed-by: Chen-Tsung Hsieh --- src/commonlib/mipi/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commonlib/mipi/cmd.c b/src/commonlib/mipi/cmd.c index fa52d21c08..8c59a83b6e 100644 --- a/src/commonlib/mipi/cmd.c +++ b/src/commonlib/mipi/cmd.c @@ -17,7 +17,7 @@ enum cb_err mipi_panel_parse_commands(const void *buf, mipi_cmd_func_t cmd_func, * to parse and scan. */ - for (; command->cmd != PANEL_CMD_END; command = (const void *)buf) { + for (; command->cmd != PANEL_CMD_END; command = buf) { /* * For some commands like DELAY, the command->len should not be * counted for buf. From b9bd92484715f4deaf31ca451e8a25c6960f218d Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Wed, 7 Jan 2026 00:43:39 +0100 Subject: [PATCH 207/789] soc/amd/common/block/spi: Implement boot_device_spi_cs() The PSP can choose the SPI flash to boot from. One such case would be a corrupted EFS or invalid PSP directory tables. Read the active SPI CS index from register SPI_ALT_CS_REG and use it in boot_device_spi_cs(). Register name is taken from Linux kernel. TEST=Booted on AMD/glinda with EFS on SPI CS0 corrupted. Will boot from SPI CS2 and log shows: spi_init: Booting from SPI CS2 Signed-off-by: Maximilian Brune Change-Id: I2c806d4d1563aa2403e84dec9f8768081e5e208a Reviewed-on: https://review.coreboot.org/c/coreboot/+/90778 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/soc/amd/common/block/spi/fch_spi_ctrl.c | 23 ++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/soc/amd/common/block/spi/fch_spi_ctrl.c b/src/soc/amd/common/block/spi/fch_spi_ctrl.c index c4ec4cc9b8..79c916ff34 100644 --- a/src/soc/amd/common/block/spi/fch_spi_ctrl.c +++ b/src/soc/amd/common/block/spi/fch_spi_ctrl.c @@ -1,16 +1,24 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include -#include #include #include #include +#include +#include #include #include +#include +#include #include #include +/* + * Default SPI CS line. When PSP fails to boot from CS0 it will + * attempt to boot from other CS lines as well. Keep track of the + * boot source for DUAL SPI access support. + */ +static uint8_t default_cs; + #define GRANULARITY_TEST_4k 0x0000f000 /* bits 15-12 */ #define WORD_TO_DWORD_UPPER(x) ((x << 16) & 0xffff0000) @@ -18,6 +26,8 @@ #define SPI_RESTRICTED_CMD1 0x04 #define SPI_RESTRICTED_CMD2 0x08 #define SPI_CNTRL1 0x0c +#define SPI_ALT_CS_REG 0x1d +#define SPI_ALT_CS_REG_MASK 0x03 #define SPI_CMD_CODE 0x45 #define SPI_CMD_TRIGGER 0x47 #define SPI_CMD_TRIGGER_EXECUTE BIT(7) @@ -114,6 +124,13 @@ static int execute_command(void) void spi_init(void) { printk(BIOS_DEBUG, "%s: SPI BAR at 0x%08lx\n", __func__, spi_get_bar()); + default_cs = spi_read8(SPI_ALT_CS_REG) & SPI_ALT_CS_REG_MASK; + printk(BIOS_DEBUG, "%s: Booting from SPI CS%d\n", __func__, default_cs); +} + +int boot_device_spi_cs(void) +{ + return default_cs; } static uint8_t cmd_code; From 225e635ea1739468af7c84fbedb6ff288c37dd39 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 21 Jul 2025 15:26:15 +0200 Subject: [PATCH 208/789] soc/amd/common/block/spi: Operate on multiple SPI flashes On AMD glinda up to 3 CS# lines are available. Drive the correct SPI flash chip select using register 0x1d when necessary. This allows to modifiy the contents of the "backup" SPI flash when booting from the primary SPI flash. TEST=Can access backup SPI flash on AMD Glinda SoC. Signed-off-by: Maximilian Brune Change-Id: I446ef54a27c7a29155948cef9219cdef7b52b776 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90779 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/soc/amd/common/block/spi/fch_spi_ctrl.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/soc/amd/common/block/spi/fch_spi_ctrl.c b/src/soc/amd/common/block/spi/fch_spi_ctrl.c index 79c916ff34..114c733244 100644 --- a/src/soc/amd/common/block/spi/fch_spi_ctrl.c +++ b/src/soc/amd/common/block/spi/fch_spi_ctrl.c @@ -134,6 +134,7 @@ int boot_device_spi_cs(void) } static uint8_t cmd_code; +static uint8_t alt_cs; static uint8_t tx_byte_count; static uint8_t rx_byte_count; static uint8_t fifo[SPI_FIFO_DEPTH]; @@ -144,6 +145,7 @@ void fch_spi_backup_registers(void) if (ENV_SMM && (spi_read8(SPI_MISC_CNTRL) & SPI_SEMAPHORE_BIOS_LOCKED)) return; + alt_cs = spi_read8(SPI_ALT_CS_REG); cmd_code = spi_read8(SPI_CMD_CODE); tx_byte_count = spi_read8(SPI_TX_BYTE_COUNT); rx_byte_count = spi_read8(SPI_RX_BYTE_COUNT); @@ -158,6 +160,7 @@ void fch_spi_restore_registers(void) if (ENV_SMM && (spi_read8(SPI_MISC_CNTRL) & SPI_SEMAPHORE_BIOS_LOCKED)) return; + spi_write8(SPI_ALT_CS_REG, alt_cs); spi_write8(SPI_CMD_CODE, cmd_code); spi_write8(SPI_TX_BYTE_COUNT, tx_byte_count); spi_write8(SPI_RX_BYTE_COUNT, rx_byte_count); @@ -350,6 +353,16 @@ static int spi_ctrlr_claim_bus(const struct spi_slave *slave) spi_write8(SPI_MISC_CNTRL, reg8 | SPI_SEMAPHORE_BIOS_LOCKED); } + /* Set chip select line */ + if (slave->cs <= 3) { + reg8 = spi_read8(SPI_ALT_CS_REG); + if ((reg8 & SPI_ALT_CS_REG_MASK) != slave->cs) { + reg8 &= ~SPI_ALT_CS_REG_MASK; + reg8 |= slave->cs; + spi_write8(SPI_ALT_CS_REG, reg8); + } + } + return 0; } @@ -358,6 +371,14 @@ static void spi_ctrlr_release_bus(const struct spi_slave *slave) { uint8_t reg8; + /* Reset chip select line */ + reg8 = spi_read8(SPI_ALT_CS_REG); + if ((reg8 & SPI_ALT_CS_REG_MASK) != default_cs) { + reg8 &= ~SPI_ALT_CS_REG_MASK; + reg8 |= default_cs; + spi_write8(SPI_ALT_CS_REG, reg8); + } + if (ENV_RAMSTAGE && CONFIG(SOC_AMD_COMMON_BLOCK_PSP_SMI)) { reg8 = spi_read8(SPI_MISC_CNTRL); spi_write8(SPI_MISC_CNTRL, reg8 & ~SPI_SEMAPHORE_BIOS_LOCKED); From fc20f238f678b9c157a4aa96aefab63de13c737b Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Sun, 18 Jan 2026 20:06:16 +0000 Subject: [PATCH 209/789] mb/starlabs/*: Select DRIVERS_EFI_FW_INFO Select DRIVERS_EFI_FW_INFO as to allow updating with EFI capsules. Change-Id: I6f0198cea69397be58693c8d48cf7855a1179771 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90790 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/common/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mainboard/starlabs/common/Kconfig b/src/mainboard/starlabs/common/Kconfig index 07239c8904..a59bc86dcf 100644 --- a/src/mainboard/starlabs/common/Kconfig +++ b/src/mainboard/starlabs/common/Kconfig @@ -4,6 +4,9 @@ if VENDOR_STARLABS menu "Star Labs Settings" +config DRIVERS_EFI_FW_INFO + default y + config MB_COMMON_DIR string default "starlabs/common" From f070e0add87f9a8bfaafecba2e62ad7d513caf36 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Sun, 18 Jan 2026 20:21:10 +0000 Subject: [PATCH 210/789] mb/starlabs/byte_adl: Fix WOL The GPIO used for WOL was not configured to support WOL, so configure this and adjust devicetree accordingly. Also, set the supported state to S3, as coreboot disables this in S5. Change-Id: Iaaac1aac3319473fe9e04f44043bf300620915cc Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90791 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- .../starlabs/byte_adl/variants/mk_ii/devicetree.cb | 6 ++++-- src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb b/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb index 40635bde30..ec5d3c03e9 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb +++ b/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb @@ -155,7 +155,8 @@ chip soc/intel/alderlake }" chip drivers/pcie/generic - register "wake_gpe" = "GPE0_PME_B0" + register "wake_gpe" = "GPE0_LAN_WAK" + register "wake_deepest" = "ACPI_S3" device generic 0 on end end smbios_slot_desc "SlotTypePciExpressGen4x1" @@ -172,7 +173,8 @@ chip soc/intel/alderlake .PcieRpL1Substates = L1_SS_L1_2, }" chip drivers/pcie/generic - register "wake_gpe" = "GPE0_PME_B0" + register "wake_gpe" = "GPE0_LAN_WAK" + register "wake_deepest" = "ACPI_S3" device generic 0 on end end smbios_slot_desc "SlotTypePciExpressGen3X4" diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c b/src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c index bddabb14db..0c0173cb40 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c +++ b/src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c @@ -20,6 +20,7 @@ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ PAD_CFG_NF(GPD1, NONE, DEEP, NF1), /* Charger Connected */ + PAD_CFG_NF(GPD2, NATIVE, PWROK, NF1), /* LAN Wake */ PAD_CFG_NF(GPD3, UP_20K, DEEP, NF1), /* Power Button */ PAD_CFG_NF(GPD4, NONE, DEEP, NF1), /* Sleep S3 */ PAD_CFG_NF(GPD5, NONE, DEEP, NF1), /* Sleep S4 */ @@ -99,7 +100,6 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPO(GPP_F7, 0, PLTRST), /* MCRO LDO [ Disabled / Bypass ] */ PAD_CFG_GPO(GPD7, 0, PLTRST), /* RTC Clock Delay [ Disabled / 95ms ] */ - PAD_NC(GPD2, NONE), PAD_NC(GPD6, NONE), PAD_NC(GPD9, NONE), PAD_NC(GPD11, NONE), From 40dbe0807da361951c567cec8192061743ae5a75 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Fri, 19 Dec 2025 20:38:31 +0000 Subject: [PATCH 211/789] Documentation/mb: Add missing entry for starfighter_mtl Change-Id: I6d7dfe2ab0eb1f4c79dfc5f87ddb8666b79a535b Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90569 Reviewed-by: Nicholas Tested-by: build bot (Jenkins) --- Documentation/mainboard/index.md | 1 + .../mainboard/starlabs/starfighter_mtl.md | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 Documentation/mainboard/starlabs/starfighter_mtl.md diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index bbfe831fc9..de731f3048 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -360,6 +360,7 @@ StarBook Mk VII (N200) StarBook Mk VII (165H) Byte Mk II StarFighter Mk I +StarFighter Mk II Building coreboot Flashing devices diff --git a/Documentation/mainboard/starlabs/starfighter_mtl.md b/Documentation/mainboard/starlabs/starfighter_mtl.md new file mode 100644 index 0000000000..2164b698c5 --- /dev/null +++ b/Documentation/mainboard/starlabs/starfighter_mtl.md @@ -0,0 +1,92 @@ +# StarFighter Mk I + +## Specs + +- CPU (full processor specs available at ) + - Intel 125H (Meteor Lake) + - Intel 285H (Arrow Lake) +- EC + - ITE IT5570E + - Backlit keyboard, with standard PS/2 keycodes and SCI hotkeys + - Battery + - USB-C PD Charger + - Suspend / resume +- GPU + - Intel® Iris® Xe Graphics + - GOP driver is recommended, VBT is provided + - eDP 16-inch 3840x2400 or 2560x1600 LCD + - HDMI video + - USB-C DisplayPort video +- Memory + - 32 or 64GB LPDDR5 on-board memory +- Networking + - AX210 2230 WiFi / Bluetooth +- Sound + - Realtek ALC235 + - Internal speakers + - Removable microphone + - Combined headphone / microphone 3.5-mm jack + - HDMI audio + - USB-C DisplayPort audio +- Storage + - 2 x M.2 PCIe SSD + - RTS5129 MicroSD card reader +- USB + - 1920x1080 removable CCD camera + - 2 x Thunderbolt 4.0 (left) + - USB 3.1 Gen 2 Type-A (left) + - USB 3.1 Gen 2 Type-A (right) + - USB 3.1 Gen 1 Type-A (right) + +## Building coreboot + +Please follow the [Star Labs build instructions](common/building.md) to build +coreboot, using `config.starlabs_starfighter_mtl` as config file. + +### Preliminaries + +Prior to building coreboot the following files are required: +* Intel Flash Descriptor file (descriptor.bin) +* Intel Management Engine firmware (me.bin) +* ITE Embedded Controller firmware (ec.bin) + +The files listed below are optional: +- Splash screen image in Windows 3.1 BMP format (Logo.bmp) + +These files exist in the correct location in the StarLabsLtd/blobs repo on +GitHub which is used in place of the standard 3rdparty/blobs repo. + +### Build + +The following commands will build a working image: + + +```bash +make distclean +make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_starfighter_mtl +make +``` + +## Flashing coreboot + +```{eval-rst} ++---------------------+------------+ +| Type | Value | ++=====================+============+ +| Socketed flash | no | ++---------------------+------------+ +| Vendor | Winbond | ++---------------------+------------+ +| Model | W25Q256.V | ++---------------------+------------+ +| Size | 32 MiB | ++---------------------+------------+ +| Package | SOIC-8 | ++---------------------+------------+ +| Internal flashing | yes | ++---------------------+------------+ +| External flashing | yes | ++---------------------+------------+ +``` + +Please see [here](common/flashing.md) for instructions on how to flash with fwupd. From 4427a34b6bcfc7f812edf19b9cdba566e98bc691 Mon Sep 17 00:00:00 2001 From: Pranava Y N Date: Sun, 18 Jan 2026 21:35:57 +0530 Subject: [PATCH 212/789] drivers/intel/fsp2_0: Fix string length handling in timestamp printing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation uses '%*s' which treats the calculated str_len as a minimum field width. If the underlying string buffer is not null-terminated, printk will continue reading past the buffer until it encounters a null byte. Switch to '%.*s' to correctly use the precision field, which specifies the maximum number of characters to be printed from the string. BUG=None TEST=Able to dump FSP performance data with `DISPLAY_FSP_TIMESTAMPS` Kconfig selected and meeting the FSP prerequisites. Verify that the performance data table is printed correctly. ``` [INFO ] +---------------------------------------------------+ [INFO ] |------ FSP Performance Timestamp Table Dump -------| [INFO ] +---------------------------------------------------+ [INFO ] | Perf-ID Timestamp(us) String/GUID | [INFO ] +---------------------------------------------------+ [INFO ] 0 1242275 SEC/52c05b14-0b98-496c-bc3b04b50211d680 [INFO ] 50 1242282 PEI/52c05b14-0b98-496c-bc3b04b50211d680 [INFO ] 40 1242284 PreMem/52c05b14-0b98-496c-bc3b04b50211d680 ``` Change-Id: Id95bd34b9c7d45d2c363339eb18adc5ac731c72b Signed-off-by: Pranava Y N Reviewed-on: https://review.coreboot.org/c/coreboot/+/90788 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Kapil Porwal Reviewed-by: Subrata Banik Reviewed-by: Jérémy Compostella --- src/drivers/intel/fsp2_0/fsp_timestamp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/intel/fsp2_0/fsp_timestamp.c b/src/drivers/intel/fsp2_0/fsp_timestamp.c index 872cf9149e..65a6060f57 100644 --- a/src/drivers/intel/fsp2_0/fsp_timestamp.c +++ b/src/drivers/intel/fsp2_0/fsp_timestamp.c @@ -51,7 +51,7 @@ static void print_guid_record(const struct generic_event_record *rec) static void print_string_record(const struct generic_event_record *rec) { size_t str_len = rec->header.length - offsetof(struct generic_event_record, string); - printk(BIOS_INFO, "%5x\t%16llu\t\t%*s/", + printk(BIOS_INFO, "%5x\t%16llu\t\t%.*s/", rec->progress_id, TIMESTAMP_TO_MICRO(rec->timestamp), (int)str_len, rec->string); fsp_print_guid(BIOS_INFO, rec->guid); printk(BIOS_INFO, "\n"); From e64507638e5cb88132bfc9beed269095f4feff62 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Mon, 19 Jan 2026 23:26:53 +0800 Subject: [PATCH 213/789] tests/lib/ux_locales-test: Avoid double quotes in CMUnitTest.name From the Jenkins result of CB:90798, it appears that the generated junit-tests_lib_ux_locales-test(tests).xml is not a valid XML file possibly due to incorrect quotes handling by cmocka. Therefore, in the UX_LOCALES_GET_TEXT_TEST macro definition, replace `#_expect` with `_expect`, so that the `name` field of the CMUnitTest struct won't contain double quotes. Change-Id: Idfec437ae627208031854694e66ca79e22132385 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90801 Reviewed-by: Jakub "Kuba" Czapiga Tested-by: build bot (Jenkins) --- tests/lib/ux_locales-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/ux_locales-test.c b/tests/lib/ux_locales-test.c index 4edac5c9d2..8d643e6e11 100644 --- a/tests/lib/ux_locales-test.c +++ b/tests/lib/ux_locales-test.c @@ -191,7 +191,7 @@ static void test_ux_locales_null_terminated(void **state) #define UX_LOCALES_GET_TEXT_TEST(_msg_id, _lang_id, _expect) \ ((struct CMUnitTest) { \ .name = "test_ux_locales_get_text(msg_id=" #_msg_id ", lang_id=" #_lang_id \ - ", expect=" #_expect ")", \ + ", expect=" _expect ")", \ .test_func = test_ux_locales_get_text, \ .setup_func = setup_default, \ .teardown_func = teardown_unmap, \ From d246e2ca7e7ae4bb04bfec204f20b785dcb3da0a Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Fri, 9 Jan 2026 17:31:59 +0800 Subject: [PATCH 214/789] tests/Makefile.common: Fix inverted USE_SYSTEM_CMOCKA condition "-I$(cmockasrc)/include" should be added to TEST_CFLAGS if we are building cmocka from source (i.e., USE_SYSTEM_CMOCKA is NOT 1). Fix the condition in Makefile.common. Change-Id: I957066fb24f03712a5b4b396aa9e04f3861940ee Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90798 Reviewed-by: Hsuan-ting Chen Reviewed-by: Jakub "Kuba" Czapiga Tested-by: build bot (Jenkins) --- tests/Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile.common b/tests/Makefile.common index a8bb19c4f1..cfb6fe945e 100644 --- a/tests/Makefile.common +++ b/tests/Makefile.common @@ -157,7 +157,7 @@ $($(1)-sysobjs): $(testobj)/$(1)/%.o: $$$$*.c $$($(1)-config-file) # Link against Cmocka if not disabled ifeq ($(strip $(filter-out 0 n no,$($(1)-no_test_framework))),) -ifneq ($(USE_SYSTEM_CMOCKA),) +ifneq ($(USE_SYSTEM_CMOCKA),1) $($(1)-objs): TEST_CFLAGS += -I$(cmockasrc)/include $($(1)-bin): TEST_LDFLAGS += -L$(cmockaobj)/src -Wl,-rpath=$(cmockaobj)/src $($(1)-bin): TEST_CFLAGS += -I$(cmockasrc)/include From fcd716d9a272461da1fdbaf1c048eb5a52c7896b Mon Sep 17 00:00:00 2001 From: Sowmya Aralguppe Date: Wed, 14 Jan 2026 13:58:56 +0530 Subject: [PATCH 215/789] mb/google/ocelot: Limit Power Limit when battery is missing Ensure the board can boot by limiting the power limits if the battery is missing. This addresses the factory use case for Wildcat Lake processors. BUG=b:None TEST= Use cutoff at-shutdown and reboot The device should boot with reduced power limits value and the log is as shown below [INFO ] Battery not connected, booting with reduced PL values [INFO ] Overriding power limits PL1 (mW) (10000, 15000) PL2 (mW) (35000, 35000) PL4 (W) (45) Change-Id: Iadb9c4c8450e6a55dd9fc644785742cc7aafd671 Signed-off-by: Sowmya Aralguppe Reviewed-on: https://review.coreboot.org/c/coreboot/+/90755 Reviewed-by: Pranava Y N Reviewed-by: Avi Uday Tested-by: build bot (Jenkins) --- .../variants/baseboard/ocelot/ramstage.c | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/src/mainboard/google/ocelot/variants/baseboard/ocelot/ramstage.c b/src/mainboard/google/ocelot/variants/baseboard/ocelot/ramstage.c index 43a82d12c3..e68010d3b7 100644 --- a/src/mainboard/google/ocelot/variants/baseboard/ocelot/ramstage.c +++ b/src/mainboard/google/ocelot/variants/baseboard/ocelot/ramstage.c @@ -3,6 +3,51 @@ #include #include +/* + * SKU_ID, TDP (Watts), pl1_min (milliWatts), pl1_max (milliWatts), + * pl2_min (milliWatts), pl2_max (milliWatts), pl4 (milliWatts) + */ +/* Define a macro for the common power limit values for WCL */ +#define COMMON_WCL_POWER_LIMITS \ + .pl1_min_power = 10000, \ + .pl1_max_power = 15000, \ + .pl2_min_power = 35000, \ + .pl2_max_power = 35000, \ + .pl4_power = 45000 + +const struct cpu_tdp_power_limits power_optimized_limits[] = { + { + .mch_id = PCI_DID_INTEL_WCL_ID_1, + .cpu_tdp = TDP_15W, + .power_limits_index = WCL_CORE, + COMMON_WCL_POWER_LIMITS + }, + { + .mch_id = PCI_DID_INTEL_WCL_ID_2, + .cpu_tdp = TDP_15W, + .power_limits_index = WCL_CORE, + COMMON_WCL_POWER_LIMITS + }, + { + .mch_id = PCI_DID_INTEL_WCL_ID_3, + .cpu_tdp = TDP_15W, + .power_limits_index = WCL_CORE, + COMMON_WCL_POWER_LIMITS + }, + { + .mch_id = PCI_DID_INTEL_WCL_ID_4, + .cpu_tdp = TDP_15W, + .power_limits_index = WCL_CORE, + COMMON_WCL_POWER_LIMITS + }, + { + .mch_id = PCI_DID_INTEL_WCL_ID_5, + .cpu_tdp = TDP_15W, + .power_limits_index = WCL_CORE, + COMMON_WCL_POWER_LIMITS + }, +}; + /* * Placeholder to check if variant has support for barrel jack for powering * on the device. @@ -21,7 +66,9 @@ void baseboard_devtree_update(void) if (variant_is_barrel_charger_present()) return; - /* TODO: Add power limit override code for Wildcat Lake */ - if (!google_chromeec_is_battery_present()) - printk(BIOS_DEBUG, "TODO: Add support for power optimized boot configuration limits\n"); + if (!google_chromeec_is_battery_present()) { + printk(BIOS_INFO, "Battery not connected, booting with reduced PL values\n"); + variant_update_cpu_power_limits(power_optimized_limits, + ARRAY_SIZE(power_optimized_limits)); + } } From 9f8094575e1ed24e9003a03202006a83f511b688 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 11:44:22 +0000 Subject: [PATCH 216/789] soc/intel/meteorlake: Include Arrow Lake microcode binaries Include the ARL-U A1 and ARL-S/HX B0 microode binaries. Change-Id: I6ba458892f89b956cd8a1f1b8600c1ce1bc72a65 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90809 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/soc/intel/meteorlake/Makefile.mk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index ab4e8a7f56..2ef53f5395 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -62,7 +62,10 @@ CPPFLAGS_common += -I$(src)/soc/intel/meteorlake CPPFLAGS_common += -I$(src)/soc/intel/meteorlake/include ifeq ($(CONFIG_SOC_INTEL_METEORLAKE_U_H),y) -cpu_microcode_bins += 3rdparty/intel-microcode/intel-ucode/06-aa-04 +cpu_microcode_bins += \ + 3rdparty/intel-microcode/intel-ucode/06-aa-04 \ + 3rdparty/intel-microcode/intel-ucode/06-b5-00 \ + 3rdparty/intel-microcode/intel-ucode/06-c6-02 endif endif From a198e7b8d63fbd3735cdb7093dee6473d3821db6 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 13:21:13 +0000 Subject: [PATCH 217/789] mb/starlabs/*: Use inline DEV_PTR calls Remove the intermediate struct device's, and replace with the DEV_PTR macro. This isn't a functional change, just cleaner. Change-Id: I1a6a596a4d4215f6b670a8a7f7749a4f9bd391b0 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90820 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- .../starlabs/byte_adl/variants/mk_ii/devtree.c | 7 ++----- .../starlabs/starbook/variants/adl/devtree.c | 4 +--- .../starlabs/starbook/variants/adl_n/devtree.c | 4 +--- .../starlabs/starbook/variants/cml/devtree.c | 4 +--- .../starlabs/starbook/variants/kbl/devtree.c | 4 +--- .../starlabs/starbook/variants/mtl/devtree.c | 7 ++----- .../starlabs/starbook/variants/rpl/devtree.c | 10 +++------- .../starlabs/starbook/variants/tgl/devtree.c | 13 ++++--------- .../starlabs/starfighter/variants/rpl/devtree.c | 13 ++++--------- .../starlabs/starlite_adl/variants/mk_v/devtree.c | 13 ++++--------- 10 files changed, 23 insertions(+), 56 deletions(-) diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c b/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c index b9746623fe..0e8d04df79 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c +++ b/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c @@ -22,9 +22,6 @@ void devtree_update(void) struct soc_power_limits_config *soc_conf_8core = &cfg->power_limits_config[ADL_N_041_15W_CORE]; - struct device *wifi_dev = pcidev_on_root(0x14, 3); - struct device *gna_dev = pcidev_on_root(0x08, 0); - uint8_t performance_scale = 100; /* Set PL4 to 1.0C */ @@ -59,7 +56,7 @@ void devtree_update(void) /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) - wifi_dev->enabled = 0; + DEV_PTR(cnvi_wifi)->enabled = 0; /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) @@ -67,5 +64,5 @@ void devtree_update(void) /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starbook/variants/adl/devtree.c b/src/mainboard/starlabs/starbook/variants/adl/devtree.c index 22b66d0d9f..2deb69f8e6 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/adl/devtree.c @@ -23,8 +23,6 @@ void devtree_update(void) struct soc_power_limits_config *soc_conf_12core = &cfg->power_limits_config[ADL_P_682_28W_CORE]; - struct device *gna_dev = pcidev_on_root(0x08, 0); - uint8_t performance_scale = 100; /* Set PL4 to 1.0C */ @@ -75,5 +73,5 @@ void devtree_update(void) /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c b/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c index 437a73c1bb..bd90e07c07 100644 --- a/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c @@ -20,8 +20,6 @@ void devtree_update(void) struct soc_power_limits_config *soc_conf_4core = &cfg->power_limits_config[ADL_N_041_6W_CORE]; - struct device *gna_dev = pcidev_on_root(0x08, 0); - uint8_t performance_scale = 100; /* Set PL4 to 1.0C */ @@ -63,5 +61,5 @@ void devtree_update(void) /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starbook/variants/cml/devtree.c b/src/mainboard/starlabs/starbook/variants/cml/devtree.c index d9bafcabd5..990b3c6143 100644 --- a/src/mainboard/starlabs/starbook/variants/cml/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/cml/devtree.c @@ -19,8 +19,6 @@ void devtree_update(void) struct soc_power_limits_config *soc_conf = &cfg->power_limits_config; - struct device *wifi_dev = pcidev_on_root(0x14, 3); - uint8_t performance_scale = 100; /* Set PL4 to 1.0C */ @@ -50,7 +48,7 @@ void devtree_update(void) /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) - wifi_dev->enabled = 0; + DEV_PTR(cnvi_wifi)->enabled = 0; /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/variants/kbl/devtree.c b/src/mainboard/starlabs/starbook/variants/kbl/devtree.c index c648be9da7..56978fff11 100644 --- a/src/mainboard/starlabs/starbook/variants/kbl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/kbl/devtree.c @@ -19,8 +19,6 @@ void devtree_update(void) struct soc_power_limits_config *soc_conf = &cfg->power_limits_config; - struct device *wifi_dev = pcidev_on_root(0x1c, 5); - uint8_t performance_scale = 100; /* Set PL4 to 1.0C */ @@ -50,7 +48,7 @@ void devtree_update(void) /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) - wifi_dev->enabled = 0; + DEV_PTR(pcie_rp5)->enabled = 0; /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/variants/mtl/devtree.c b/src/mainboard/starlabs/starbook/variants/mtl/devtree.c index 296027e9e8..66c8179810 100644 --- a/src/mainboard/starlabs/starbook/variants/mtl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/mtl/devtree.c @@ -20,9 +20,6 @@ void devtree_update(void) struct soc_power_limits_config *soc_conf_20core = &cfg->power_limits_config[MTL_P_682_482_CORE]; - struct device *gna_dev = pcidev_on_root(0x08, 0); - struct device *vpu_dev = pcidev_on_root(0x0b, 0); - uint8_t performance_scale = 100; /* Set PL4 to 1.0C */ @@ -64,9 +61,9 @@ void devtree_update(void) /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; /* Enable/Disable VPU based on CMOS settings */ if (get_uint_option("vpu", 0) == 0) - vpu_dev->enabled = 0; + DEV_PTR(vpu)->enabled = 0; } diff --git a/src/mainboard/starlabs/starbook/variants/rpl/devtree.c b/src/mainboard/starlabs/starbook/variants/rpl/devtree.c index 32ba845ba8..3485fdbb31 100644 --- a/src/mainboard/starlabs/starbook/variants/rpl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/rpl/devtree.c @@ -23,10 +23,6 @@ void devtree_update(void) struct soc_power_limits_config *soc_conf_12core = &cfg->power_limits_config[RPL_P_682_482_282_28W_CORE]; - struct device *tbt_pci_dev = pcidev_on_root(0x07, 0); - struct device *tbt_dma_dev = pcidev_on_root(0x0d, 2); - struct device *gna_dev = pcidev_on_root(0x08, 0); - uint8_t performance_scale = 100; /* Set PL4 to 1.0C */ @@ -77,11 +73,11 @@ void devtree_update(void) /* Enable/Disable Thunderbolt based on CMOS settings */ if (get_uint_option("thunderbolt", 1) == 0) { - tbt_pci_dev->enabled = 0; - tbt_dma_dev->enabled = 0; + DEV_PTR(tbt_pcie_rp0)->enabled = 0; + DEV_PTR(tcss_dma0)->enabled = 0; } /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starbook/variants/tgl/devtree.c b/src/mainboard/starlabs/starbook/variants/tgl/devtree.c index d83c2b55a7..7bfd6a560b 100644 --- a/src/mainboard/starlabs/starbook/variants/tgl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/tgl/devtree.c @@ -23,11 +23,6 @@ void devtree_update(void) struct soc_power_limits_config *soc_conf_4core = &cfg->power_limits_config[POWER_LIMITS_U_4_CORE]; - struct device *wifi_dev = pcidev_on_root(0x14, 3); - struct device *tbt_pci_dev = pcidev_on_root(0x07, 0); - struct device *tbt_dma_dev = pcidev_on_root(0x0d, 2); - struct device *gna_dev = pcidev_on_root(0x08, 0); - uint8_t performance_scale = 100; /* Set PL4 to 1.0C */ @@ -62,7 +57,7 @@ void devtree_update(void) /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) - wifi_dev->enabled = 0; + DEV_PTR(cnvi_wifi)->enabled = 0; /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) @@ -79,11 +74,11 @@ void devtree_update(void) if (get_uint_option("thunderbolt", 1) == 0) { cfg->UsbTcPortEn = 0; cfg->TcssXhciEn = 0; - tbt_pci_dev->enabled = 0; - tbt_dma_dev->enabled = 0; + DEV_PTR(tbt_pcie_rp0)->enabled = 0; + DEV_PTR(tbt_dma0)->enabled = 0; } /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c b/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c index fe9d9117dc..b094c7c2fb 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c +++ b/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c @@ -23,11 +23,6 @@ void devtree_update(void) struct soc_power_limits_config *soc_conf_14core = &cfg->power_limits_config[RPL_P_682_642_482_45W_CORE]; - struct device *tbt_pci_dev_0 = pcidev_on_root(0x07, 0); - struct device *tbt_pci_dev_1 = pcidev_on_root(0x07, 1); - struct device *tbt_dma_dev = pcidev_on_root(0x0d, 2); - struct device *gna_dev = pcidev_on_root(0x08, 0); - uint8_t performance_scale = 100; /* Set PL4 to 1.0C */ @@ -70,12 +65,12 @@ void devtree_update(void) /* Enable/Disable Thunderbolt based on CMOS settings */ if (get_uint_option("thunderbolt", 1) == 0) { - tbt_pci_dev_0->enabled = 0; - tbt_pci_dev_1->enabled = 0; - tbt_dma_dev->enabled = 0; + DEV_PTR(tbt_pcie_rp0)->enabled = 0; + DEV_PTR(tbt_pcie_rp1)->enabled = 0; + DEV_PTR(tcss_dma0)->enabled = 0; } /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c b/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c index cc8dd4a7b9..1f1dd8fd28 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c +++ b/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c @@ -20,11 +20,6 @@ void devtree_update(void) struct soc_power_limits_config *soc_conf_4core = &cfg->power_limits_config[ADL_N_041_6W_CORE]; - struct device *wifi_dev = pcidev_on_root(0x14, 3); - struct device *touchscreen_dev = pcidev_on_root(0x15, 2); - struct device *accelerometer_dev = pcidev_on_root(0x15, 0); - struct device *gna_dev = pcidev_on_root(0x08, 0); - uint8_t performance_scale = 100; /* Set PL4 to 1.0C */ @@ -55,7 +50,7 @@ void devtree_update(void) /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) - wifi_dev->enabled = 0; + DEV_PTR(cnvi_wifi)->enabled = 0; /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) @@ -67,15 +62,15 @@ void devtree_update(void) /* Enable/Disable Touchscreen based on CMOS settings */ if (get_uint_option("touchscreen", 1) == 0) - touchscreen_dev->enabled = 0; + DEV_PTR(i2c2)->enabled = 0; /* Enable/Disable Accelerometer based on CMOS settings */ if (get_uint_option("accelerometer", 1) == 0) - accelerometer_dev->enabled = 0; + DEV_PTR(i2c0)->enabled = 0; /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; /* Enable/Disable Card Reader based on CMOS Settings */ if (get_uint_option("card_reader", 0) == 0) From cb08e29ba79b1f935f43375d13d6983327de1b79 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Mon, 27 Oct 2025 19:45:07 +0000 Subject: [PATCH 218/789] mb/starlabs/*: Move powercap configuration to common dir Move the code that configures power limits, tcc and other power related settings into common code. The end result is the same, but the PL4 is set by reading the battery capacity, rather than being hardcoded. This patch also appends `_group` to each form group, to avoid conflicts with objects now visible with the extra headers. Change-Id: I41235039bc984686fa43f5c712e836d0b8d5d24a Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/89775 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/byte_adl/Kconfig | 7 ++- src/mainboard/starlabs/byte_adl/cfr.c | 24 +++++----- .../byte_adl/variants/mk_ii/devtree.c | 41 +--------------- .../starlabs/common/include/common/cfr.h | 1 + .../starlabs/common/include/common/powercap.h | 6 ++- .../starlabs/common/powercap/powercap.c | 48 ++++++++++++++++++- src/mainboard/starlabs/lite/Kconfig | 8 ++++ src/mainboard/starlabs/lite/cfr.c | 28 +++++------ src/mainboard/starlabs/lite/devtree.c | 31 +----------- src/mainboard/starlabs/starbook/Kconfig | 11 +++++ src/mainboard/starlabs/starbook/cfr.c | 28 +++++------ .../starlabs/starbook/variants/adl/devtree.c | 42 +--------------- .../starbook/variants/adl_n/devtree.c | 34 +------------ .../starlabs/starbook/variants/cml/devtree.c | 33 +------------ .../starlabs/starbook/variants/kbl/devtree.c | 33 +------------ .../starlabs/starbook/variants/mtl/devtree.c | 34 +------------ .../starlabs/starbook/variants/rpl/devtree.c | 42 +--------------- .../starlabs/starbook/variants/tgl/devtree.c | 42 +--------------- src/mainboard/starlabs/starfighter/Kconfig | 8 ++++ src/mainboard/starlabs/starfighter/cfr.c | 28 +++++------ .../starfighter/variants/mtl/devtree.c | 34 +------------ .../starfighter/variants/rpl/devtree.c | 42 +--------------- src/mainboard/starlabs/starlite_adl/Kconfig | 8 ++++ src/mainboard/starlabs/starlite_adl/cfr.c | 24 +++++----- .../starlite_adl/variants/mk_v/devtree.c | 35 +------------- 25 files changed, 171 insertions(+), 501 deletions(-) diff --git a/src/mainboard/starlabs/byte_adl/Kconfig b/src/mainboard/starlabs/byte_adl/Kconfig index 04bdcc8ee2..d8524a9ceb 100644 --- a/src/mainboard/starlabs/byte_adl/Kconfig +++ b/src/mainboard/starlabs/byte_adl/Kconfig @@ -85,8 +85,7 @@ config ME_BIN_PATH config PL4_WATTS int - default 65 if BOARD_STARLABS_BYTE_TWL - default 36 + default 65 config POWER_STATE_DEFAULT_ON_AFTER_FAILURE default n @@ -98,6 +97,10 @@ config EDK2_BOOTSPLASH_FILE config SOC_INTEL_CSE_SEND_EOP_EARLY default n +config TJ_MAX + int + default 105 + config UART_FOR_CONSOLE default 0 diff --git a/src/mainboard/starlabs/byte_adl/cfr.c b/src/mainboard/starlabs/byte_adl/cfr.c index 5a29170778..3a9162d1cb 100644 --- a/src/mainboard/starlabs/byte_adl/cfr.c +++ b/src/mainboard/starlabs/byte_adl/cfr.c @@ -8,7 +8,7 @@ #include #include -static struct sm_obj_form performance = { +static struct sm_obj_form performance_group = { .ui_name = "Performance", .obj_list = (const struct sm_object *[]) { &bluetooth_rtd3, @@ -18,7 +18,7 @@ static struct sm_obj_form performance = { }, }; -static struct sm_obj_form processor = { +static struct sm_obj_form processor_group = { .ui_name = "Processor", .obj_list = (const struct sm_object *[]) { &me_state, @@ -29,7 +29,7 @@ static struct sm_obj_form processor = { }, }; -static struct sm_obj_form power = { +static struct sm_obj_form power_group = { .ui_name = "Power", .obj_list = (const struct sm_object *[]) { &power_on_after_fail_bool, @@ -37,7 +37,7 @@ static struct sm_obj_form power = { }, }; -static struct sm_obj_form devices = { +static struct sm_obj_form devices_group = { .ui_name = "Devices", .obj_list = (const struct sm_object *[]) { &bluetooth, @@ -47,7 +47,7 @@ static struct sm_obj_form devices = { }, }; -static struct sm_obj_form pci = { +static struct sm_obj_form pci_group = { .ui_name = "PCI", .obj_list = (const struct sm_object *[]) { &pciexp_clk_pm, @@ -57,7 +57,7 @@ static struct sm_obj_form pci = { }, }; -static struct sm_obj_form coreboot = { +static struct sm_obj_form coreboot_group = { .ui_name = "coreboot", .obj_list = (const struct sm_object *[]) { &debug_level, @@ -66,12 +66,12 @@ static struct sm_obj_form coreboot = { }; static struct sm_obj_form *sm_root[] = { - &performance, - &processor, - &power, - &devices, - &pci, - &coreboot, + &performance_group, + &processor_group, + &power_group, + &devices_group, + &pci_group, + &coreboot_group, NULL }; diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c b/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c index 0e8d04df79..aaa5fdafae 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c +++ b/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c @@ -10,49 +10,10 @@ #include #include -#define TJ_MAX 105 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_4core = - &cfg->power_limits_config[ADL_N_041_6W_CORE]; - struct soc_power_limits_config *soc_conf_8core = - &cfg->power_limits_config[ADL_N_041_15W_CORE]; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_4core->tdp_pl4 = CONFIG_PL4_WATTS; - - /* Set PL1 to 50% of PL2 */ - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl2_override / 2) & ~1; - soc_conf_8core->tdp_pl1_override = (soc_conf_8core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(70); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(80); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(90); - break; - } - - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl1_override * performance_scale) / 100; - soc_conf_4core->tdp_pl2_override = (soc_conf_4core->tdp_pl2_override * performance_scale) / 100; - - soc_conf_8core->tdp_pl1_override = (soc_conf_8core->tdp_pl1_override * performance_scale) / 100; - soc_conf_8core->tdp_pl2_override = (soc_conf_8core->tdp_pl2_override * performance_scale) / 100; - + update_power_limits(cfg); /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) diff --git a/src/mainboard/starlabs/common/include/common/cfr.h b/src/mainboard/starlabs/common/include/common/cfr.h index 4a081c3c31..faf9887b1f 100644 --- a/src/mainboard/starlabs/common/include/common/cfr.h +++ b/src/mainboard/starlabs/common/include/common/cfr.h @@ -4,6 +4,7 @@ #define _STARLABS_CMN_CFR_H_ #include +#include #include void cfr_card_reader_update(struct sm_object *new_obj); diff --git a/src/mainboard/starlabs/common/include/common/powercap.h b/src/mainboard/starlabs/common/include/common/powercap.h index aa1d68f418..a9ea99916c 100644 --- a/src/mainboard/starlabs/common/include/common/powercap.h +++ b/src/mainboard/starlabs/common/include/common/powercap.h @@ -3,6 +3,10 @@ #ifndef _STARLABS_CMN_POWERCAP_H_ #define _STARLABS_CMN_POWERCAP_H_ +#include + +#define TCC(temp) (CONFIG_TJ_MAX - temp) + enum cmos_power_profile { PP_POWER_SAVER = 0, PP_BALANCED = 1, @@ -10,6 +14,6 @@ enum cmos_power_profile { }; #define NUM_POWER_PROFILES 3 -enum cmos_power_profile get_power_profile(enum cmos_power_profile fallback); +void update_power_limits(config_t *cfg); #endif diff --git a/src/mainboard/starlabs/common/powercap/powercap.c b/src/mainboard/starlabs/common/powercap/powercap.c index e19e6ec403..a1eeb019cf 100644 --- a/src/mainboard/starlabs/common/powercap/powercap.c +++ b/src/mainboard/starlabs/common/powercap/powercap.c @@ -1,10 +1,56 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include -enum cmos_power_profile get_power_profile(enum cmos_power_profile fallback) +static enum cmos_power_profile get_power_profile(enum cmos_power_profile fallback) { const unsigned int power_profile = get_uint_option("power_profile", fallback); return power_profile < NUM_POWER_PROFILES ? power_profile : fallback; } + + +void update_power_limits(config_t *cfg) +{ + uint8_t performance_scale = 100; + + /* Scale PL1 & PL2 based on CMOS settings */ + switch (get_power_profile(PP_POWER_SAVER)) { + case PP_POWER_SAVER: + performance_scale -= 50; + cfg->tcc_offset = TCC(80); + break; + case PP_BALANCED: + performance_scale -= 25; + cfg->tcc_offset = TCC(90); + break; + case PP_PERFORMANCE: + /* Use the Intel defaults */ + cfg->tcc_offset = TCC(100); + break; + } + + struct soc_power_limits_config *limits = + (struct soc_power_limits_config *)&cfg->power_limits_config; + size_t limit_count = sizeof(cfg->power_limits_config) / + sizeof(struct soc_power_limits_config); + + for (size_t i = 0; i < limit_count; i++) { + struct soc_power_limits_config *entry = &limits[i]; + + entry->tdp_pl4 = (uint16_t)CONFIG_PL4_WATTS; + + if (!entry->tdp_pl2_override) + continue; + + /* Set PL1 to 50% of PL2 */ + entry->tdp_pl1_override = (entry->tdp_pl2_override / 2) & ~1; + + if (performance_scale == 100) + continue; + + entry->tdp_pl1_override = ((entry->tdp_pl1_override * performance_scale) / 100); + entry->tdp_pl2_override = ((entry->tdp_pl2_override * performance_scale) / 100); + } +} diff --git a/src/mainboard/starlabs/lite/Kconfig b/src/mainboard/starlabs/lite/Kconfig index 8ea2101f69..e68e84b397 100644 --- a/src/mainboard/starlabs/lite/Kconfig +++ b/src/mainboard/starlabs/lite/Kconfig @@ -83,6 +83,14 @@ config MAINBOARD_SMBIOS_PRODUCT_NAME config POWER_STATE_DEFAULT_ON_AFTER_FAILURE default n +config TJ_MAX + int + default 100 + +config PL4_WATTS + int + default 45 + config TRACKPAD_INTERRUPT hex default 0x1 if BOARD_STARLABS_LITE_GLK diff --git a/src/mainboard/starlabs/lite/cfr.c b/src/mainboard/starlabs/lite/cfr.c index f9e42146cf..db3702fb79 100644 --- a/src/mainboard/starlabs/lite/cfr.c +++ b/src/mainboard/starlabs/lite/cfr.c @@ -8,7 +8,7 @@ #include #include -static struct sm_obj_form performance = { +static struct sm_obj_form performance_group = { .ui_name = "Performance", .obj_list = (const struct sm_object *[]) { &power_profile, @@ -16,7 +16,7 @@ static struct sm_obj_form performance = { }, }; -static struct sm_obj_form processor = { +static struct sm_obj_form processor_group = { .ui_name = "Processor", .obj_list = (const struct sm_object *[]) { &s0ix_enable, @@ -25,7 +25,7 @@ static struct sm_obj_form processor = { }, }; -static struct sm_obj_form power = { +static struct sm_obj_form power_group = { .ui_name = "Power", .obj_list = (const struct sm_object *[]) { &power_on_after_fail_bool, @@ -33,7 +33,7 @@ static struct sm_obj_form power = { }, }; -static struct sm_obj_form keyboard = { +static struct sm_obj_form keyboard_group = { .ui_name = "Keyboard", .obj_list = (const struct sm_object *[]) { &kbl_timeout, @@ -42,7 +42,7 @@ static struct sm_obj_form keyboard = { }, }; -static struct sm_obj_form devices = { +static struct sm_obj_form devices_group = { .ui_name = "Devices", .obj_list = (const struct sm_object *[]) { &bluetooth, @@ -54,7 +54,7 @@ static struct sm_obj_form devices = { }, }; -static struct sm_obj_form pci = { +static struct sm_obj_form pci_group = { .ui_name = "PCI", .obj_list = (const struct sm_object *[]) { #if CONFIG(SOC_INTEL_ALDERLAKE) @@ -66,7 +66,7 @@ static struct sm_obj_form pci = { }, }; -static struct sm_obj_form coreboot = { +static struct sm_obj_form coreboot_group = { .ui_name = "coreboot", .obj_list = (const struct sm_object *[]) { &debug_level, @@ -75,13 +75,13 @@ static struct sm_obj_form coreboot = { }; static struct sm_obj_form *sm_root[] = { - &performance, - &processor, - &power, - &keyboard, - &devices, - &pci, - &coreboot, + &performance_group, + &processor_group, + &power_group, + &keyboard_group, + &devices_group, + &pci_group, + &coreboot_group, NULL }; diff --git a/src/mainboard/starlabs/lite/devtree.c b/src/mainboard/starlabs/lite/devtree.c index b86c38b208..afbd1bba11 100644 --- a/src/mainboard/starlabs/lite/devtree.c +++ b/src/mainboard/starlabs/lite/devtree.c @@ -15,38 +15,9 @@ void devtree_update(void) { config_t *cfg = config_of_soc(); - struct soc_power_limits_config *soc_conf = - &cfg->power_limits_config; - struct device *wifi_dev = pcidev_on_root(0x0c, 0); - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf->tdp_pl4 = 31; - - /* Set PL1 to 50% of PL2 */ - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 25; - cfg->tcc_offset = 15; - break; - case PP_BALANCED: - /* Use the Intel defaults */ - cfg->tcc_offset = 10; - break; - case PP_PERFORMANCE: - performance_scale += 25; - cfg->tcc_offset = 5; - break; - } - - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl1_override * performance_scale) / 100; - soc_conf->tdp_pl2_override = (soc_conf->tdp_pl2_override * performance_scale) / 100; - + update_power_limits(cfg); /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/Kconfig b/src/mainboard/starlabs/starbook/Kconfig index 7a7ac3919e..063a7c6410 100644 --- a/src/mainboard/starlabs/starbook/Kconfig +++ b/src/mainboard/starlabs/starbook/Kconfig @@ -197,6 +197,17 @@ config POWER_STATE_DEFAULT_ON_AFTER_FAILURE config SOC_INTEL_CSE_SEND_EOP_EARLY default n +config TJ_MAX + int + default 100 if BOARD_STARLABS_LABTOP_KBL || BOARD_STARLABS_LABTOP_CML || BOARD_STARLABS_STARBOOK_TGL + default 105 if BOARD_STARLABS_STARBOOK_ADL_N + default 110 + +config PL4_WATTS + int + default 45 if BOARD_STARLABS_LABTOP_KBL || BOARD_STARLABS_LABTOP_CML + default 65 + config TME_KEY_REGENERATION_ON_WARM_BOOT default n diff --git a/src/mainboard/starlabs/starbook/cfr.c b/src/mainboard/starlabs/starbook/cfr.c index 69e48d1023..a499d3ed08 100644 --- a/src/mainboard/starlabs/starbook/cfr.c +++ b/src/mainboard/starlabs/starbook/cfr.c @@ -7,7 +7,7 @@ #include #include -static struct sm_obj_form performance = { +static struct sm_obj_form performance_group = { .ui_name = "Performance", .obj_list = (const struct sm_object *[]) { &bluetooth_rtd3, @@ -17,7 +17,7 @@ static struct sm_obj_form performance = { }, }; -static struct sm_obj_form processor = { +static struct sm_obj_form processor_group = { .ui_name = "Processor", .obj_list = (const struct sm_object *[]) { &me_state, @@ -31,7 +31,7 @@ static struct sm_obj_form processor = { }, }; -static struct sm_obj_form power = { +static struct sm_obj_form power_group = { .ui_name = "Power", .obj_list = (const struct sm_object *[]) { &max_charge, @@ -45,7 +45,7 @@ static struct sm_obj_form power = { }, }; -static struct sm_obj_form keyboard = { +static struct sm_obj_form keyboard_group = { .ui_name = "Keyboard", .obj_list = (const struct sm_object *[]) { &kbl_timeout, @@ -54,7 +54,7 @@ static struct sm_obj_form keyboard = { }, }; -static struct sm_obj_form devices = { +static struct sm_obj_form devices_group = { .ui_name = "Devices", .obj_list = (const struct sm_object *[]) { &bluetooth, @@ -84,7 +84,7 @@ static struct sm_obj_form devices = { }, }; -static struct sm_obj_form pci = { +static struct sm_obj_form pci_group = { .ui_name = "PCI", .obj_list = (const struct sm_object *[]) { #if CONFIG(BOARD_STARLABS_STARBOOK_ADL) @@ -103,7 +103,7 @@ static struct sm_obj_form pci = { }, }; -static struct sm_obj_form coreboot = { +static struct sm_obj_form coreboot_group = { .ui_name = "coreboot", .obj_list = (const struct sm_object *[]) { &debug_level, @@ -112,13 +112,13 @@ static struct sm_obj_form coreboot = { }; static struct sm_obj_form *sm_root[] = { - &performance, - &processor, - &power, - &keyboard, - &devices, - &pci, - &coreboot, + &performance_group, + &processor_group, + &power_group, + &keyboard_group, + &devices_group, + &pci_group, + &coreboot_group, NULL }; diff --git a/src/mainboard/starlabs/starbook/variants/adl/devtree.c b/src/mainboard/starlabs/starbook/variants/adl/devtree.c index 2deb69f8e6..3379e02dae 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/adl/devtree.c @@ -10,50 +10,10 @@ #include #include -#define TJ_MAX 110 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_10core = - &cfg->power_limits_config[ADL_P_282_442_482_28W_CORE]; - - struct soc_power_limits_config *soc_conf_12core = - &cfg->power_limits_config[ADL_P_682_28W_CORE]; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_10core->tdp_pl4 = 65; - soc_conf_12core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_10core->tdp_pl1_override = (soc_conf_10core->tdp_pl2_override / 2) & ~1; - soc_conf_12core->tdp_pl1_override = (soc_conf_12core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_10core->tdp_pl1_override = (soc_conf_10core->tdp_pl1_override * performance_scale) / 100; - soc_conf_10core->tdp_pl2_override = (soc_conf_10core->tdp_pl2_override * performance_scale) / 100; - - soc_conf_12core->tdp_pl1_override = (soc_conf_12core->tdp_pl1_override * performance_scale) / 100; - soc_conf_12core->tdp_pl2_override = (soc_conf_12core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c b/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c index bd90e07c07..1b01e25cb0 100644 --- a/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c @@ -10,42 +10,10 @@ #include #include -#define TJ_MAX 105 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_4core = - &cfg->power_limits_config[ADL_N_041_6W_CORE]; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_4core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl1_override * performance_scale) / 100; - soc_conf_4core->tdp_pl2_override = (soc_conf_4core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/variants/cml/devtree.c b/src/mainboard/starlabs/starbook/variants/cml/devtree.c index 990b3c6143..980a472abc 100644 --- a/src/mainboard/starlabs/starbook/variants/cml/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/cml/devtree.c @@ -10,41 +10,10 @@ #include #include -#define TJ_MAX 100 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf = &cfg->power_limits_config; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf->tdp_pl4 = 45; - - /* Set PL1 to 50% of PL2 */ - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl1_override * performance_scale) / 100; - soc_conf->tdp_pl2_override = (soc_conf->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/variants/kbl/devtree.c b/src/mainboard/starlabs/starbook/variants/kbl/devtree.c index 56978fff11..2dd0f995ab 100644 --- a/src/mainboard/starlabs/starbook/variants/kbl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/kbl/devtree.c @@ -10,41 +10,10 @@ #include #include -#define TJ_MAX 100 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf = &cfg->power_limits_config; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf->tdp_pl4 = 45; - - /* Set PL1 to 50% of PL2 */ - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl1_override * performance_scale) / 100; - soc_conf->tdp_pl2_override = (soc_conf->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/variants/mtl/devtree.c b/src/mainboard/starlabs/starbook/variants/mtl/devtree.c index 66c8179810..0b2cd1b959 100644 --- a/src/mainboard/starlabs/starbook/variants/mtl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/mtl/devtree.c @@ -10,42 +10,10 @@ #include #include -#define TJ_MAX 110 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_20core = - &cfg->power_limits_config[MTL_P_682_482_CORE]; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_20core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_20core->tdp_pl1_override = (soc_conf_20core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_20core->tdp_pl1_override = (soc_conf_20core->tdp_pl1_override * performance_scale) / 100; - soc_conf_20core->tdp_pl2_override = (soc_conf_20core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/variants/rpl/devtree.c b/src/mainboard/starlabs/starbook/variants/rpl/devtree.c index 3485fdbb31..fe9ec1b3e2 100644 --- a/src/mainboard/starlabs/starbook/variants/rpl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/rpl/devtree.c @@ -10,50 +10,10 @@ #include #include -#define TJ_MAX 110 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_6core = - &cfg->power_limits_config[RPL_P_282_242_142_15W_CORE]; - - struct soc_power_limits_config *soc_conf_12core = - &cfg->power_limits_config[RPL_P_682_482_282_28W_CORE]; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_6core->tdp_pl4 = 65; - soc_conf_12core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_6core->tdp_pl1_override = (soc_conf_6core->tdp_pl2_override / 2) & ~1; - soc_conf_12core->tdp_pl1_override = (soc_conf_12core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_6core->tdp_pl1_override = (soc_conf_6core->tdp_pl1_override * performance_scale) / 100; - soc_conf_6core->tdp_pl2_override = (soc_conf_6core->tdp_pl2_override * performance_scale) / 100; - - soc_conf_12core->tdp_pl1_override = (soc_conf_12core->tdp_pl1_override * performance_scale) / 100; - soc_conf_12core->tdp_pl2_override = (soc_conf_12core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/variants/tgl/devtree.c b/src/mainboard/starlabs/starbook/variants/tgl/devtree.c index 7bfd6a560b..796624e1c6 100644 --- a/src/mainboard/starlabs/starbook/variants/tgl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/tgl/devtree.c @@ -10,50 +10,10 @@ #include #include -#define TJ_MAX 100 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_2core = - &cfg->power_limits_config[POWER_LIMITS_U_2_CORE]; - - struct soc_power_limits_config *soc_conf_4core = - &cfg->power_limits_config[POWER_LIMITS_U_4_CORE]; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_2core->tdp_pl4 = 65; - soc_conf_4core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_2core->tdp_pl1_override = (soc_conf_2core->tdp_pl2_override / 2) & ~1; - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_2core->tdp_pl1_override = (soc_conf_2core->tdp_pl1_override * performance_scale) / 100; - soc_conf_2core->tdp_pl2_override = (soc_conf_2core->tdp_pl2_override * performance_scale) / 100; - - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl1_override * performance_scale) / 100; - soc_conf_4core->tdp_pl2_override = (soc_conf_4core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) diff --git a/src/mainboard/starlabs/starfighter/Kconfig b/src/mainboard/starlabs/starfighter/Kconfig index 1e12366501..5709ced88c 100644 --- a/src/mainboard/starlabs/starfighter/Kconfig +++ b/src/mainboard/starlabs/starfighter/Kconfig @@ -122,6 +122,14 @@ config SOC_INTEL_CSE_SEND_EOP_EARLY config TME_KEY_REGENERATION_ON_WARM_BOOT default n +config TJ_MAX + int + default 110 + +config PL4_WATTS + int + default 80 + config TPM_PIRQ depends on MAINBOARD_HAS_TPM2 default 0x3d if BOARD_STARLABS_STARFIGHTER_MTL diff --git a/src/mainboard/starlabs/starfighter/cfr.c b/src/mainboard/starlabs/starfighter/cfr.c index ff3567f860..146ffd6913 100644 --- a/src/mainboard/starlabs/starfighter/cfr.c +++ b/src/mainboard/starlabs/starfighter/cfr.c @@ -8,7 +8,7 @@ #include #include -static struct sm_obj_form performance = { +static struct sm_obj_form performance_group = { .ui_name = "Performance", .obj_list = (const struct sm_object *[]) { &bluetooth_rtd3, @@ -18,7 +18,7 @@ static struct sm_obj_form performance = { }, }; -static struct sm_obj_form processor = { +static struct sm_obj_form processor_group = { .ui_name = "Processor", .obj_list = (const struct sm_object *[]) { &me_state, @@ -30,7 +30,7 @@ static struct sm_obj_form processor = { }, }; -static struct sm_obj_form power = { +static struct sm_obj_form power_group = { .ui_name = "Power", .obj_list = (const struct sm_object *[]) { &max_charge, @@ -44,7 +44,7 @@ static struct sm_obj_form power = { }, }; -static struct sm_obj_form keyboard = { +static struct sm_obj_form keyboard_group = { .ui_name = "Keyboard", .obj_list = (const struct sm_object *[]) { &kbl_timeout, @@ -53,7 +53,7 @@ static struct sm_obj_form keyboard = { }, }; -static struct sm_obj_form devices = { +static struct sm_obj_form devices_group = { .ui_name = "Devices", .obj_list = (const struct sm_object *[]) { #if CONFIG(SOC_INTEL_TIGERLAKE) || CONFIG(SOC_INTEL_ALDERLAKE) || CONFIG(SOC_INTEL_RAPTORLAKE) @@ -73,7 +73,7 @@ static struct sm_obj_form devices = { }, }; -static struct sm_obj_form pci = { +static struct sm_obj_form pci_group = { .ui_name = "PCI", .obj_list = (const struct sm_object *[]) { #if CONFIG(SOC_INTEL_COMMON_BLOCK_ASPM) @@ -88,7 +88,7 @@ static struct sm_obj_form pci = { }, }; -static struct sm_obj_form coreboot = { +static struct sm_obj_form coreboot_group = { .ui_name = "coreboot", .obj_list = (const struct sm_object *[]) { &debug_level, @@ -97,13 +97,13 @@ static struct sm_obj_form coreboot = { }; static struct sm_obj_form *sm_root[] = { - &performance, - &processor, - &power, - &keyboard, - &devices, - &pci, - &coreboot, + &performance_group, + &processor_group, + &power_group, + &keyboard_group, + &devices_group, + &pci_group, + &coreboot_group, NULL }; diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c b/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c index a983bba747..c4b0da67fd 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c +++ b/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c @@ -10,42 +10,10 @@ #include #include -#define TJ_MAX 110 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_20core = - &cfg->power_limits_config[MTL_P_682_482_CORE]; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_20core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_20core->tdp_pl1_override = (soc_conf_20core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_20core->tdp_pl1_override = (soc_conf_20core->tdp_pl1_override * performance_scale) / 100; - soc_conf_20core->tdp_pl2_override = (soc_conf_20core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Webcam based on CMOS settings */ if (get_uint_option("webcam", 1) == 0) diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c b/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c index b094c7c2fb..aea5d89b40 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c +++ b/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c @@ -10,50 +10,10 @@ #include #include -#define TJ_MAX 110 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_6core = - &cfg->power_limits_config[RPL_P_282_242_142_15W_CORE]; - - struct soc_power_limits_config *soc_conf_14core = - &cfg->power_limits_config[RPL_P_682_642_482_45W_CORE]; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_6core->tdp_pl4 = 65; - soc_conf_14core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_6core->tdp_pl1_override = (soc_conf_6core->tdp_pl2_override / 2) & ~1; - soc_conf_14core->tdp_pl1_override = (soc_conf_14core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_6core->tdp_pl1_override = (soc_conf_6core->tdp_pl1_override * performance_scale) / 100; - soc_conf_6core->tdp_pl2_override = (soc_conf_6core->tdp_pl2_override * performance_scale) / 100; - - soc_conf_14core->tdp_pl1_override = (soc_conf_14core->tdp_pl1_override * performance_scale) / 100; - soc_conf_14core->tdp_pl2_override = (soc_conf_14core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) diff --git a/src/mainboard/starlabs/starlite_adl/Kconfig b/src/mainboard/starlabs/starlite_adl/Kconfig index 6e66d653b0..00c2a4ecb5 100644 --- a/src/mainboard/starlabs/starlite_adl/Kconfig +++ b/src/mainboard/starlabs/starlite_adl/Kconfig @@ -100,6 +100,14 @@ config EDK2_BOOTSPLASH_FILE config SOC_INTEL_CSE_SEND_EOP_EARLY default n +config TJ_MAX + int + default 105 + +config PL4_WATTS + int + default 37 + config UART_FOR_CONSOLE default 0 diff --git a/src/mainboard/starlabs/starlite_adl/cfr.c b/src/mainboard/starlabs/starlite_adl/cfr.c index da0b77bd94..7bbe25d61f 100644 --- a/src/mainboard/starlabs/starlite_adl/cfr.c +++ b/src/mainboard/starlabs/starlite_adl/cfr.c @@ -19,7 +19,7 @@ void cfr_card_reader_update(struct sm_object *new_obj) new_obj->sm_bool.flags = CFR_OPTFLAG_SUPPRESS; } -static struct sm_obj_form performance = { +static struct sm_obj_form performance_group = { .ui_name = "Performance", .obj_list = (const struct sm_object *[]) { &bluetooth_rtd3, @@ -29,7 +29,7 @@ static struct sm_obj_form performance = { }, }; -static struct sm_obj_form processor = { +static struct sm_obj_form processor_group = { .ui_name = "Processor", .obj_list = (const struct sm_object *[]) { &me_state, @@ -40,7 +40,7 @@ static struct sm_obj_form processor = { }, }; -static struct sm_obj_form power = { +static struct sm_obj_form power_group = { .ui_name = "Power", .obj_list = (const struct sm_object *[]) { &max_charge, @@ -54,7 +54,7 @@ static struct sm_obj_form power = { }, }; -static struct sm_obj_form devices = { +static struct sm_obj_form devices_group = { .ui_name = "Devices", .obj_list = (const struct sm_object *[]) { &accelerometer, @@ -75,7 +75,7 @@ static struct sm_obj_form devices = { }, }; -static struct sm_obj_form pci = { +static struct sm_obj_form pci_group = { .ui_name = "PCI", .obj_list = (const struct sm_object *[]) { #if CONFIG(SOC_INTEL_COMMON_BLOCK_ASPM) @@ -87,7 +87,7 @@ static struct sm_obj_form pci = { }, }; -static struct sm_obj_form coreboot = { +static struct sm_obj_form coreboot_group = { .ui_name = "coreboot", .obj_list = (const struct sm_object *[]) { &debug_level, @@ -96,12 +96,12 @@ static struct sm_obj_form coreboot = { }; static struct sm_obj_form *sm_root[] = { - &performance, - &processor, - &power, - &devices, - &pci, - &coreboot, + &performance_group, + &processor_group, + &power_group, + &devices_group, + &pci_group, + &coreboot_group, NULL }; diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c b/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c index 1f1dd8fd28..4a13543bf6 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c +++ b/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c @@ -10,43 +10,10 @@ #include #include -#define TJ_MAX 105 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_4core = - &cfg->power_limits_config[ADL_N_041_6W_CORE]; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_4core->tdp_pl4 = 37; - - /* Set PL1 to 50% of PL2 */ - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(70); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(80); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(90); - break; - } - - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl1_override * performance_scale) / 100; - soc_conf_4core->tdp_pl2_override = (soc_conf_4core->tdp_pl2_override * performance_scale) / 100; - + update_power_limits(cfg); /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) From 9c19c973f6e5fd20dcc2a6474fb9dbcb966d92a4 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 14:05:28 +0000 Subject: [PATCH 219/789] mb/starlabs/starlite_adl: Adjust FMAP to match descriptor Adjust the FMAP to match a newer version of the descriptor generated with mFIT. Change-Id: Id2eeec5269e8988e425e497f797645fa940922b3 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90822 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd b/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd index 9cf12adf81..2197262237 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd +++ b/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd @@ -1,7 +1,7 @@ FLASH 0x1000000 { SI_ALL 0x600000 { SI_DESC 0x1000 - SI_ME 0x412000 + SI_ME 0x411000 } SI_BIOS 0xa00000 { EC@0x0 0x20000 From b2c24afcf55853bdede7d7bf7832978258db2493 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 14:06:30 +0000 Subject: [PATCH 220/789] mb/starlabs/starfighter/mtl: Adjust FMAP to match descriptor Adjust the FMAP to match a newer version of the descriptor generated with mFIT. Change-Id: I546697f5c3352358a715f8783a7eda650c771c78 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90823 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/starfighter/variants/mtl/board.fmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd b/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd index ad7674988f..e88eaf2d0e 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd +++ b/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd @@ -1,7 +1,7 @@ FLASH 0x2000000 { SI_ALL 0x1000000 { SI_DESC 0x4000 - SI_ME 0x80f000 + SI_ME 0xbb1000 } SI_BIOS 0x1000000 { EC@0x0 0x20000 From 60c8496afe6e43901c774ac180965125c805fbc4 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 9 Jan 2026 18:33:32 -0600 Subject: [PATCH 221/789] ec/starlabs/merlin: Add retry to get_ec_version() Occasionally when reading the EC version from ECRAM, the major version fails to read and returns zero. To avoid having an incorrect version reported, retry up to 10x with a 10ms delay between retries. TEST=build/boot various Starlabs hardware, update the EC firmware, verify the EC version is reported correctly every time. Change-Id: I78d921e7230e8e180041097672661e744f70dde2 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90834 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- src/ec/starlabs/merlin/ite.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ec/starlabs/merlin/ite.c b/src/ec/starlabs/merlin/ite.c index 953c9e3de6..ec4c9a65ab 100644 --- a/src/ec/starlabs/merlin/ite.c +++ b/src/ec/starlabs/merlin/ite.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include #include @@ -17,6 +18,9 @@ uint16_t ec_get_version(void) { + for (int i = 0; i < 10 && ec_read(ECRAM_MAJOR_VERSION) == 0; i++) + mdelay(10); + return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION); } From 6118dbe0a3fcc775090698fc961b865a7f93d355 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 14:26:12 +0000 Subject: [PATCH 222/789] mb/starlabs/*: Set bluetooth_rdt3 to disabled by default Change-Id: I78e526722446110821256698922c2a39eab24c9f Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90835 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/common/include/common/cfr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/starlabs/common/include/common/cfr.h b/src/mainboard/starlabs/common/include/common/cfr.h index faf9887b1f..1b89642133 100644 --- a/src/mainboard/starlabs/common/include/common/cfr.h +++ b/src/mainboard/starlabs/common/include/common/cfr.h @@ -28,7 +28,7 @@ static const struct sm_object bluetooth_rtd3 = SM_DECLARE_BOOL({ .ui_name = "Bluetooth Runtime-D3", .ui_helptext = "Enable or disable Bluetooth power optimization.\n" "Recommended to disable when booting Windows.", - .default_value = true, + .default_value = false, }); static const struct sm_object card_reader = SM_DECLARE_BOOL({ From 80d48a628843535fdcb56a5cae03f40b76c9566b Mon Sep 17 00:00:00 2001 From: alokagarwal Date: Thu, 8 Jan 2026 21:05:16 +0530 Subject: [PATCH 223/789] vc/intel/fsp/fsp2_0/ptl: Expose all the UPDs As Panther Lake code is moving to a new phase, the full FSP headers, including all the UPDs, can now be published. This CL is not tied to the FSP update; it only provides the full list of UPDs for the current FSP version 3442.07. Details: - FspmUpd.h : Expose all UPDs - FspsUpd.h : Expose all UPDs BUG=b:474393325 TEST=Build fatcat without any errors. Change-Id: If02f9bf8d920497b0dcb52f5652839fae7fd0919 Signed-off-by: Alok Agarwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90704 Reviewed-by: Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora Reviewed-by: Kim, Wonkyu Reviewed-by: Alicja Michalska Reviewed-by: Pranava Y N Reviewed-by: Sowmya, V Reviewed-by: Zhixing Ma Reviewed-by: Subrata Banik --- .../intel/fsp/fsp2_0/pantherlake/FspmUpd.h | 1849 +++++++++++++-- .../intel/fsp/fsp2_0/pantherlake/FspsUpd.h | 2021 ++++++++++++++--- 2 files changed, 3426 insertions(+), 444 deletions(-) diff --git a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h index ac166e6ccf..cb221b9e14 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h @@ -93,9 +93,11 @@ typedef struct { **/ UINT32 SerialIoUartDebugCtsPinMux; -/** Offset 0x0074 - Reserved +/** Offset 0x0074 - SerialIo Uart PowerGating + Select SerialIo Uart Powergating mode + 0:Disabled, 1:Enabled, 2:Auto **/ - UINT8 Reserved1; + UINT8 SerialIoUartPowerGating; /** Offset 0x0075 - DCI Enable Determine if to enable DCI debug from host @@ -110,9 +112,28 @@ typedef struct { **/ UINT8 DciDbcMode; -/** Offset 0x0077 - Reserved +/** Offset 0x0077 - DCI Clock Enable + Enable/Disable DCI clock in lowest power state + $EN_DIS +**/ + UINT8 DciClkEnable; + +/** Offset 0x0078 - Keep Early Trace + Trace is activated by default. When enable, keep early trace data and keep tracing, + may block s0ix.\n + When disabled will abandon trace data and stop tracing which allows enter s0ix\n + \n + noted:enable this option will not enable TraceHub; When probe is connected, keep + early trace will then be configured by tool, this option will not take effect. + $EN_DIS +**/ + UINT8 KeepEarlyTrace; + +/** Offset 0x0079 - Enable/Disable MemoryOverlap check + Enable(Default): Enable MemoryOverlap check, Disable: Disable MemoryOverlap check + $EN_DIS **/ - UINT8 Reserved2[3]; + UINT8 MemMapOverlapCheckSupport; /** Offset 0x007A - Memory Test on Warm Boot Run Base Memory Test on Warm Boot @@ -122,7 +143,7 @@ typedef struct { /** Offset 0x007B - Reserved **/ - UINT8 Reserved3[5]; + UINT8 Reserved1[5]; /** Offset 0x0080 - Platform Reserved Memory Size The minimum platform memory size required to pass control into DXE @@ -137,7 +158,7 @@ typedef struct { /** Offset 0x008A - Reserved **/ - UINT8 Reserved4[6]; + UINT8 Reserved2[6]; /** Offset 0x0090 - Memory SPD Pointer Controller 0 Channel 0 Dimm 0 Pointer to SPD data, will be used only when SpdAddressTable SPD Address are marked as 00 @@ -316,9 +337,19 @@ typedef struct { **/ UINT8 LowerBasicMemTestSize; -/** Offset 0x01AD - Reserved +/** Offset 0x01AD - EccGranularity32BEn + Reduce BasicMemTest size. 0: Disabled (default), regular BasicMemTest. 1: Enabled, + shorter BasicMemTest (faster boot) + $EN_DIS +**/ + UINT8 EccGranularity32BEn; + +/** Offset 0x01AE - EccCorrectionMode + Reduce BasicMemTest size. 0: Disabled (default), regular BasicMemTest. 1: Enabled, + shorter BasicMemTest (faster boot) + $EN_DIS **/ - UINT8 Reserved5[2]; + UINT8 EccCorrectionMode; /** Offset 0x01AF - CaVrefHigh DDR5 CA Sweep High Vref Value for DDR5 OC @@ -350,9 +381,13 @@ typedef struct { **/ UINT8 DFETap2StepSize; -/** Offset 0x01B5 - Reserved +/** Offset 0x01B5 - IbeccEccInjControl + IBECC Error Injection Control + 0: No Error Injection, 1:Inject Correctable Error Address match, 3:Inject Correctable + Error on insertion counter, 5: Inject Uncorrectable Error Address match, 7:Inject + Uncorrectable Error on insertion counter **/ - UINT8 Reserved6; + UINT8 IbeccEccInjControl; /** Offset 0x01B6 - VDD2 override VDD2 override for DDR5 OC; 0 - Auto @@ -473,9 +508,17 @@ typedef struct { **/ UINT16 tCCD_L_WR; -/** Offset 0x01E2 - Reserved +/** Offset 0x01E2 - Periodic COMP + Enable/disable Periodic Compensation + $EN_DIS **/ - UINT8 Reserved7[2]; + UINT8 EnPeriodicComp; + +/** Offset 0x01E3 - LPMode4 Support + LPMode4 Options + 0: Disable, 1:Enable, 2:Dynamic Threshold 2, 3:Dynamic Threshold 3 +**/ + UINT8 LpMode4; /** Offset 0x01E4 - LPMode Support Bit[0]: Enable Lpmode0p5 (Idle_enable), Bit[1]: Enable Lpmode2 (Powerdown_enable), @@ -483,9 +526,17 @@ typedef struct { **/ UINT8 LpMode; -/** Offset 0x01E5 - Reserved +/** Offset 0x01E5 - Opportunistic Read + Enables/Disable Opportunistic Read (Def= Enable) + $EN_DIS +**/ + UINT8 OpportunisticRead; + +/** Offset 0x01E6 - Cycle Bypass Support + Enables/Disable Cycle Bypass Support(Def=Disable) + $EN_DIS **/ - UINT8 Reserved8[2]; + UINT8 Disable2CycleBypass; /** Offset 0x01E7 - MRC OCSafeMode OverClocking Safe Mode for tCL @@ -493,9 +544,13 @@ typedef struct { **/ UINT8 OCSafeMode; -/** Offset 0x01E8 - Reserved +/** Offset 0x01E8 - DQ Vref Ctrl Offset + Offset to be applied to DDRDATA7CH1_CR_DDRCRVREFADJUST1.Ch0VrefCtl + 0xF4:-12,0xF5:-11, 0xF6:-10, 0xF7:-9, 0xF8:-8, 0xF9:-7, 0xFA:-6, 0xFB:-5, 0xFC:-4, + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3, 4:+4, 5:+5, 6:+6, 7:+7, 8:+8, + 9:+9, 10:+10, 11:+11, 12:+12 **/ - UINT8 Reserved9; + UINT8 VrefCtlOffset; /** Offset 0x01E9 - Dqs Pins Interleaved Setting Indicates DqPinsInterleaved setting: board-dependent @@ -536,9 +591,10 @@ typedef struct { **/ UINT8 ProbelessTrace; -/** Offset 0x01EF - Reserved +/** Offset 0x01EF - IbeccEccInjCount + Number of memory transactions between ECC error injection **/ - UINT8 Reserved10; + UINT8 IbeccEccInjCount; /** Offset 0x01F0 - DDR Frequency Limit Maximum Memory Frequency Selections in Mhz. Options are 1067, 1333, 1600, 1867, @@ -676,9 +732,11 @@ typedef struct { **/ UINT8 TXDQSDCC; -/** Offset 0x0213 - Reserved +/** Offset 0x0213 - Rx DQS Duty Cycle Correction + Enables/Disable Rx DQS Duty Cycle Correction + $EN_DIS **/ - UINT8 Reserved11; + UINT8 RXDQSDCC; /** Offset 0x0214 - Ch Hash Override Select if Channel Hash setting values will be taken from input parameters or automatically @@ -687,9 +745,17 @@ typedef struct { **/ UINT8 ChHashOverride; -/** Offset 0x0215 - Reserved +/** Offset 0x0215 - Voltage Readout + Enables/Disable Voltage Readout for VCCClk and PBias + $EN_DIS +**/ + UINT8 VoltageReadout; + +/** Offset 0x0216 - DQS Rise/Fall + Enables/Disable DQS Rise/Fall + $EN_DIS **/ - UINT8 Reserved12[2]; + UINT8 DQSRF; /** Offset 0x0217 - DQS Rise/Fall Enables/Disable DQS Rise/Fall @@ -697,9 +763,17 @@ typedef struct { **/ UINT8 RDDQSODTT; -/** Offset 0x0218 - Reserved +/** Offset 0x0218 - PreTraining + Enables/Disable PreTraining + $EN_DIS +**/ + UINT8 PRETRAIN; + +/** Offset 0x0219 - DUNIT Configuration + Enables/Disable Dunit Configuration + $EN_DIS **/ - UINT8 Reserved13[2]; + UINT8 DUNITC; /** Offset 0x021A - Functional Duty Cycle Correction for DDR5 CLK Enable/Disable Functional Duty Cycle Correction for DDR5 CLK @@ -729,9 +803,11 @@ typedef struct { **/ UINT8 DQDQSSWZ; -/** Offset 0x021F - Reserved +/** Offset 0x021F - LP5 Dca Training + Enable/Disable LP5 Dca Training + $EN_DIS **/ - UINT8 Reserved14; + UINT8 DCCLP5READDCA; /** Offset 0x0220 - Functional Duty Cycle Correction for Data DQ Enable/Disable Functional Duty Cycle Correction for Data DQ @@ -739,9 +815,39 @@ typedef struct { **/ UINT8 FUNCDCCDQ; -/** Offset 0x0221 - Reserved +/** Offset 0x0221 - SubCh Hash Override + Select if SubChannel Hash setting values will be taken from input parameters or + automatically taken from POR values depending on DRAM type detected. NOTE: ONLY + if Memory interleaved Mode + $EN_DIS +**/ + UINT8 SubChHashOverride; + +/** Offset 0x0222 - DDR5 Auto Precharge Enable + Auto Precharge Enable for DDR5: O=Auto, 1=Disable, 2=Enable + $EN_DIS +**/ + UINT8 Ddr5AutoPrechargeEnable; + +/** Offset 0x0223 - Lp5 SplitACT Enable + SplitACT enable for LP5 + 0:Auto, 1:Disable, 2:Enable +**/ + UINT8 Lp5SplitACTEnable; + +/** Offset 0x0224 - CCC Half Frequency + CCC Half Frequency (CccGear4) Mode: 0 = Auto (Default), 1 = Disable, 2 = GroupGv0 + (SaGv0 only), 3 = GroupGv1 (Up to SaGv1), 4 = GroupGv2 (Up to SaGv2), 5 = GroupGv3 + (Up to SaGv3) + 0: Auto, 1: Disable, 2: GroupGv0, 3: GroupGv1, 4: GroupGv2, 5: GroupGv3 **/ - UINT8 Reserved15[5]; + UINT8 CccHalfFrequency; + +/** Offset 0x0225 - DIMM Non-Target ODT Training + Enables/Disable DIMM Non-Target ODT Training + $EN_DIS +**/ + UINT8 DIMMNTODT; /** Offset 0x0226 - Unmatched Rx Calibration Enable/Disable Rx Unmatched Calibration @@ -749,9 +855,60 @@ typedef struct { **/ UINT8 RXUNMATCHEDCAL; -/** Offset 0x0227 - Reserved +/** Offset 0x0227 - Hard Post Package Repair + Deprecated + $EN_DIS +**/ + UINT8 PPR; + +/** Offset 0x0228 - PPR Test Type + Deprecated +**/ + UINT8 PprTestType; + +/** Offset 0x0229 - PPR Run Once + When Eanble, PPR will run only once and then is disabled at next training cycle + $EN_DIS +**/ + UINT8 PprRunOnce; + +/** Offset 0x022A - PPR Run During Fastboot + Deprecated + $EN_DIS +**/ + UINT8 PprRunAtFastboot; + +/** Offset 0x022B - PPR Repair Type + PPR Repair Type: 0:Do not Repair (Default), 1:Soft Repair, 2:Hard Repair + 0:Do not Repair (Default), 1:Soft Repair, 2:Hard Repair +**/ + UINT8 PprRepairType; + +/** Offset 0x022C - PPR Error Injection + When Eanble, PPR will inject bad rows during testing + $EN_DIS +**/ + UINT8 PprErrorInjection; + +/** Offset 0x022D - PPR Repair Controller + Deprecated +**/ + UINT8 PprRepairController; + +/** Offset 0x022E - PPR Repair Channel + Deprecated +**/ + UINT8 PprRepairChannel; + +/** Offset 0x022F - PPR Repair Dimm + Deprecated +**/ + UINT8 PprRepairDimm; + +/** Offset 0x0230 - PPR Repair Rank + Deprecated **/ - UINT8 Reserved16[10]; + UINT8 PprRepairRank; /** Offset 0x0231 - Memory Slice Hash LSB Bit Memory Slice (Controller) Hash LSB bit. Valid values are 0..7 for BITS 6..13; used @@ -766,9 +923,25 @@ typedef struct { **/ UINT16 MsHashMask; -/** Offset 0x0234 - Reserved +/** Offset 0x0234 - PPR Repair Row + Deprecated +**/ + UINT32 PprRepairRow; + +/** Offset 0x0238 - PPR Repair Physical Address Low + Deprecated +**/ + UINT32 PprRepairPhysicalAddrLow; + +/** Offset 0x023C - PPR Repair Physical Address High + Deprecated +**/ + UINT32 PprRepairPhysicalAddrHigh; + +/** Offset 0x0240 - PPR Repair BankGroup + Deprecated **/ - UINT8 Reserved17[13]; + UINT8 PprRepairBankGroup; /** Offset 0x0241 - LVR Auto Trim Enable/disable LVR Auto Trim @@ -788,9 +961,23 @@ typedef struct { **/ UINT8 WRTRETRAIN; -/** Offset 0x0244 - Reserved +/** Offset 0x0244 - DCC Phase Clk Calibration + Enable/disable DCC Phase Clk Calibration + $EN_DIS +**/ + UINT8 PHASECLKCAL; + +/** Offset 0x0245 - DCC Tline Clk Calibration + Enable/disable DCC Tline Clk Calibration + $EN_DIS +**/ + UINT8 TLINECLKCAL; + +/** Offset 0x0246 - DCC Tline Serializer Calibration + Enable/disable DCC PI Serializer Calibratio + $EN_DIS **/ - UINT8 Reserved18[3]; + UINT8 DCCPISERIALCAL; /** Offset 0x0247 - RDDQODTT Enable/disable Read DQ ODT Training @@ -1000,9 +1187,11 @@ typedef struct { **/ UINT8 TAT; -/** Offset 0x026A - Reserved +/** Offset 0x026A - Rmt Even Odd + Enables/Disable Rmt Even Odd + $EN_DIS **/ - UINT8 Reserved19; + UINT8 RMTEVENODD; /** Offset 0x026B - DIMM SPD Alias Test Enables/Disable DIMM SPD Alias Test @@ -1028,9 +1217,17 @@ typedef struct { **/ UINT8 EccSupport; -/** Offset 0x026F - Reserved +/** Offset 0x026F - DLL DCC Calibration + Enables/Disable DLL DCC Calibration + $EN_DIS +**/ + UINT8 DLLDCC; + +/** Offset 0x0270 - DLL BW Select Calibration + Enables/Disable DLL BW Select Calibration + $EN_DIS **/ - UINT8 Reserved20[2]; + UINT8 DLLBWSEL; /** Offset 0x0271 - Ibecc In-Band ECC Support @@ -1044,9 +1241,11 @@ typedef struct { **/ UINT8 IbeccParity; -/** Offset 0x0273 - Reserved +/** Offset 0x0273 - MsHashEnable + Controller Hash Enable: 0=Disable, 1=Enable + $EN_DIS **/ - UINT8 Reserved21; + UINT8 MsHashEnable; /** Offset 0x0274 - IbeccOperationMode In-Band ECC Operation Mode @@ -1062,7 +1261,7 @@ typedef struct { /** Offset 0x027D - Reserved **/ - UINT8 Reserved22; + UINT8 Reserved3; /** Offset 0x027E - IbeccProtectedRegionBases IBECC Protected Region Bases per IBECC instance @@ -1135,9 +1334,17 @@ typedef struct { **/ UINT8 ExitOnFailure; -/** Offset 0x02A8 - Reserved +/** Offset 0x02A8 - Wck Pad DCC Calibration + Enable/disable Wck Pad DCC Calibration + $EN_DIS +**/ + UINT8 WCKPADDCCCAL; + +/** Offset 0x02A9 - DCC PI Code LUT Calibration + Enable/Disable DCC PI Code LUT Calibration + $EN_DIS **/ - UINT8 Reserved23[2]; + UINT8 DCCPICODELUT; /** Offset 0x02AA - Read Voltage Centering 1D Enable/Disable Read Voltage Centering 1D @@ -1223,9 +1430,11 @@ typedef struct { **/ UINT8 RowPressEn; -/** Offset 0x02B8 - Reserved +/** Offset 0x02B8 - DBI feature + Enables/Disable DBI feature + $EN_DIS **/ - UINT8 Reserved24; + UINT8 DBI; /** Offset 0x02B9 - DDR5 MR7 WICA support Enable if DDR5 DRAM Device supports MR7 WICA 0.5 tCK offset alignment @@ -1252,9 +1461,10 @@ typedef struct { **/ UINT16 ChHashMask; -/** Offset 0x02BE - Reserved +/** Offset 0x02BE - CccPinsInterleaved + Interleaving mode of CCC pins which depends on board routing: 0=Disable, 1=Enable **/ - UINT8 Reserved25; + UINT8 CccPinsInterleaved; /** Offset 0x02BF - Throttler CKEMin Timer Timer value for CKEMin, range[255;0]. Req'd min of SC_ROUND_T + BYTE_LENGTH (4). @@ -1333,7 +1543,12 @@ typedef struct { /** Offset 0x02CB - Reserved **/ - UINT8 Reserved26[5]; + UINT8 Reserved4; + +/** Offset 0x02CC - IbeccEccInjAddrBase + Address to match against for ECC error injection. Example: 1 = 32MB, 2 = 64MB +**/ + UINT32 IbeccEccInjAddrBase; /** Offset 0x02D0 - DDR Phy Safe Mode Support DdrSafeMode[0]: Basic PM Features, DdrSafeMode[1]: Spine Gating, DdrSafeMode[2]: @@ -1353,9 +1568,56 @@ typedef struct { **/ UINT8 CleanMemory; -/** Offset 0x02D6 - Reserved +/** Offset 0x02D6 - Tseg Retry Count + Tseg Retry count will increase based on TSEG Region Fail count + 0: Default, 1:3 +**/ + UINT8 RetryCount; + +/** Offset 0x02D7 - Mrc Ppr Status + Get Mrc PPR Status after PPR Recovery flow will get Trigger + 0: PASS, 1: FAIL(Default) +**/ + UINT8 MrcPprStatus; + +/** Offset 0x02D8 - Tseg Memory Test Status + If enabled, PPR Recovery flow will get Trigger + 0: PASS, 1: FAIL(Default) +**/ + UINT8 TsegMemoryTestStatus; + +/** Offset 0x02D9 - Ppr Recovery Status Enable + 0: Disabled(Default), 1: Enabled. If enabled, PPR Recovery flow will get Trigger. + $EN_DIS +**/ + UINT8 PprRecoveryStatusEnable; + +/** Offset 0x02DA - Safe Loading Bios Enable State + 0: Disabled(Default), 1: Enabled. If enabled, Memory diagnostic will perform for + TSEG Region. + $EN_DIS +**/ + UINT8 SafeLoadingBiosEnableState; + +/** Offset 0x02DB - BDAT test type + When BdatEnable is set to TRUE, this option selects the type of data which will + be populated in the BIOS Data ACPI Tables: 0=RMT, 1=RMT Per Bit, 2=Margin 2D. + 0:RMT per Rank, 1:RMT per Bit, 2:Margin2D +**/ + UINT8 MrcBdatTestType; + +/** Offset 0x02DC - MrcBdatEnable + 0: Disabled(Default), 1: Enabled. This field enables the generation of the BIOS + DATA ACPI Tables: 0=FALSE, 1=TRUE. + $EN_DIS +**/ + UINT8 MrcBdatEnable; + +/** Offset 0x02DD - DisableMrcRetraining + 0: Disabled(Default), 1: Enabled. Enable/Disable DisableMrcRetraining + $EN_DIS **/ - UINT8 Reserved27[8]; + UINT8 DisableMrcRetraining; /** Offset 0x02DE - RMTLoopCount Specifies the Loop Count to be used during Rank Margin Tool Testing. 0 - AUTO @@ -1391,7 +1653,7 @@ typedef struct { /** Offset 0x02E7 - Reserved **/ - UINT8 Reserved28; + UINT8 Reserved5; /** Offset 0x02E8 - Margin limit check L2 Margin limit check L2 threshold: 100=Default @@ -1404,9 +1666,12 @@ typedef struct { **/ UINT8 ExtendedBankHashing; -/** Offset 0x02EB - Reserved +/** Offset 0x02EB - DRFM Blast Radius Configuration + Row Hammer DRFM Blast Radius Configuration determines number of victim rows around + aggressor row targeted to send the DRFM sequence to: 2=BlastRadius 2, 3=BlastRadius + 3, 4=BlastRadius 4 **/ - UINT8 Reserved29; + UINT8 DrfmBrc; /** Offset 0x02EC - LP5 Command Pins Mapping BitMask where bits [3:0] are Controller 0 Channel [3:0] and bits [7:4] are Controller @@ -1426,9 +1691,73 @@ typedef struct { **/ UINT8 MrcTimeMeasure; -/** Offset 0x02EF - Reserved +/** Offset 0x02EF - DVFSQ Enabled + Enable/Disable DVFSQ + $EN_DIS +**/ + UINT8 DvfsqEnabled; + +/** Offset 0x02F0 - E-DVFSC Enabled + Eanble/Disable DVFSC + $EN_DIS +**/ + UINT8 DvfscEnabled; + +/** Offset 0x02F1 - Ddr5 Dca Training + Enable/Disable DDR5 Dca Training + $EN_DIS +**/ + UINT8 DCCDDR5READDCA; + +/** Offset 0x02F2 - PPR Run WCHMATS8 + Run WCHMATS8 in Post Package Repair flow +**/ + UINT8 PprRunWCHMATS8; + +/** Offset 0x02F3 - PPR Run Retention + Run Data Retention in Post Package Repair flow +**/ + UINT8 PprRunRetention; + +/** Offset 0x02F4 - PPR Run XMarch + Run XMarch in Post Package Repair flow +**/ + UINT8 PprRunXMarch; + +/** Offset 0x02F5 - PPR Run XMarchG + Run XMarchG in Post Package Repair flow +**/ + UINT8 PprRunXMarchG; + +/** Offset 0x02F6 - PPR Run YMarchShort + Run YMarchShort in Post Package Repair flow +**/ + UINT8 PprRunYMarchShort; + +/** Offset 0x02F7 - PPR Run YMarchLong + Run YMarchLong in Post Package Repair flow +**/ + UINT8 PprRunYMarchLong; + +/** Offset 0x02F8 - PPR Run Mmrw + Run Mmrw in Post Package Repair flow +**/ + UINT8 PprRunMmrw; + +/** Offset 0x02F9 - PPR Test Disabled + Don't run any test in Post Package Repair flow +**/ + UINT8 PprTestDisabled; + +/** Offset 0x02FA - PPR Entry Info + PPR Repair Info +**/ + UINT8 PprEntryInfo[16]; + +/** Offset 0x030A - PPR Entry Address + PPR Repair Memory Address **/ - UINT8 Reserved30[43]; + UINT8 PprEntryAddress[16]; /** Offset 0x031A - Read Vref Decap Training* Enable/Disable Read Timing Centering Training with SR stress* @@ -1454,9 +1783,15 @@ typedef struct { **/ UINT8 IsWckIdleExitEnabled; -/** Offset 0x031E - Reserved +/** Offset 0x031E - LP5 Safe Speed + Enable / Disable LP5 Safe Speed feature + $EN_DIS +**/ + UINT8 Lp5SafeSpeed; + +/** Offset 0x031F - Reserved **/ - UINT8 Reserved31[17]; + UINT8 Reserved6[16]; /** Offset 0x032F - Board Type MrcBoardType, Options are 0=Mobile/Mobile Halo, 1=Desktop/DT Halo, 5=ULT/ULX/Mobile @@ -1478,9 +1813,11 @@ typedef struct { **/ UINT8 TxtImplemented; -/** Offset 0x0341 - Reserved +/** Offset 0x0341 - PCIE Resizable BAR Support + Enable/Disable PCIE Resizable BAR Support.0: Disable; 1: Enable; 2: Auto(Default). + $EN_DIS **/ - UINT8 Reserved32; + UINT8 PcieResizableBarSupport; /** Offset 0x0342 - Skip external display device scanning Enable: Do not scan for external display device, Disable (Default): Scan external @@ -1608,7 +1945,7 @@ typedef struct { /** Offset 0x04D6 - Reserved **/ - UINT8 Reserved33[2]; + UINT8 Reserved7[2]; /** Offset 0x04D8 - DMIC ClkA Pin Muxing (N - DMIC number) Determines DMIC ClkA Pin muxing. See GPIO_*_MUXING_DMIC_CLKA_* @@ -1623,7 +1960,7 @@ typedef struct { /** Offset 0x04E1 - Reserved **/ - UINT8 Reserved34[3]; + UINT8 Reserved8[3]; /** Offset 0x04E4 - DMIC Data Pin Muxing Determines DMIC Data Pin muxing. See GPIO_*_MUXING_DMIC_DATA_* @@ -1635,9 +1972,35 @@ typedef struct { **/ UINT8 PchHdaAudioLinkSspEnable[7]; -/** Offset 0x04F3 - Reserved +/** Offset 0x04F3 - PCH Hda Disc Bt Off Enabled + Hda Disc Bt Off Enabled +**/ + UINT8 PchHdaDiscBtOffEnabled; + +/** Offset 0x04F4 - PCH HDA Discrete BT Offload Ssp Link + Discrete BT Offload Ssp Link +**/ + UINT32 PchHdaDiscBtOffSspLink; + +/** Offset 0x04F8 - SSP Sclk Pin Muxing (N - SSP Number) + Determines SSP Sclk Pin muxing. See GPIOV2_*_MUXING_I2S*_SCLK +**/ + UINT32 PchHdaAudioLinkSspSclkPinMux[7]; + +/** Offset 0x0514 - SSP Sfmr Pin Muxing (N - SSP Number) + Determines SSP Sfmr Pin muxing. See GPIOV2_*_MUXING_I2S*_SFMR +**/ + UINT32 PchHdaAudioLinkSspSfmrPinMux[7]; + +/** Offset 0x0530 - SSP Txd Pin Muxing (N - SSP Number) + Determines SSP Txd Pin muxing. See GPIOV2_*_MUXING_I2S*_TXD +**/ + UINT32 PchHdaAudioLinkSspTxdPinMux[7]; + +/** Offset 0x054C - SSP Rxd Pin Muxing (N - SSP Number) + Determines SSP Rxd Pin muxing. See GPIOV2_*_MUXING_I2S*_RXD **/ - UINT8 Reserved35[117]; + UINT32 PchHdaAudioLinkSspRxdPinMux[7]; /** Offset 0x0568 - Enable HD Audio SoundWire#N Link Enable/disable HD Audio SNDW#N link. Muxed with HDA. @@ -1656,9 +2019,41 @@ typedef struct { **/ UINT8 PchHdaIDispLinkTmode; -/** Offset 0x056F - Reserved +/** Offset 0x056F - Sndw Multilane enablement + SoundWire Multiline enablement. Default is DISABLE. 0: DISABLE, 1: Two lines enabled, + 2: Three lines enabled, 3: Four Lines enabled. + $EN_DIS +**/ + UINT8 PchHdAudioSndwMultilaneEnable[2]; + +/** Offset 0x0571 - Reserved +**/ + UINT8 Reserved9[3]; + +/** Offset 0x0574 - SoundWire Clk Pin Muxing (N - SoundWire number) + Determines SoundWire Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_CLK* +**/ + UINT32 PchHdaAudioLinkMultilaneClkPinMux[2]; + +/** Offset 0x057C - SoundWire Multilane Data0 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA0* +**/ + UINT32 PchHdaAudioLinkMultilaneData0PinMux[2]; + +/** Offset 0x0584 - SoundWire Multilane Data1 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA1* +**/ + UINT32 PchHdaAudioLinkMultilaneData1PinMux[2]; + +/** Offset 0x058C - SoundWire Multilane Data2 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA2* +**/ + UINT32 PchHdaAudioLinkMultilaneData2PinMux[2]; + +/** Offset 0x0594 - SoundWire Multilane Data3 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA3* **/ - UINT8 Reserved36[45]; + UINT32 PchHdaAudioLinkMultilaneData3PinMux[2]; /** Offset 0x059C - iDisplay Audio Codec disconnection 0: Not disconnected, enumerable, 1: Disconnected SDI, not enumerable. @@ -1666,9 +2061,20 @@ typedef struct { **/ UINT8 PchHdaIDispCodecDisconnect; -/** Offset 0x059D - Reserved +/** Offset 0x059D - Sndw Interface for Multilanes (N - SoundWire number) + 0: Not disconnected, enumerable, 1: Disconnected SDI, not enumerable. + 0: Sndw0, 1: Sndw1, 2: Sndw2, 3: Sndw3, 4: Sndw4, 5: Sndw5 +**/ + UINT8 PchHdAudioSndwMultilaneSndwInterface[2]; + +/** Offset 0x059F - Reserved **/ - UINT8 Reserved37[5]; + UINT8 Reserved10; + +/** Offset 0x05A0 - Audio Sub System IDs + Set default Audio Sub System IDs. If its set to 0 then value from Strap is used. +**/ + UINT16 ResetWaitTimer; /** Offset 0x05A2 - HDA Power/Clock Gating (PGD/CGD) Enable/Disable HD Audio Power and Clock Gating(POR: Enable). 0: PLATFORM_POR, 1: @@ -1677,18 +2083,22 @@ typedef struct { **/ UINT8 PchHdaTestPowerClockGating; -/** Offset 0x05A3 - Reserved +/** Offset 0x05A3 - Low Frequency Link Clock Source (LFLCS) + 0: POR (Enable), 1: Enable (XTAL), 2: Disable (Audio PLL). + 0: POR (Enable), 1: Enable (XTAL), 2: Disable (Audio PLL) **/ - UINT8 Reserved38; + UINT8 PchHdaTestLowFreqLinkClkSrc; /** Offset 0x05A4 - Audio Sub System IDs Set default Audio Sub System IDs. If its set to 0 then value from Strap is used. **/ UINT32 PchHdaSubSystemIds; -/** Offset 0x05A8 - Reserved +/** Offset 0x05A8 - SoundWire clock source select + Select clock source for the SoundWire controllers. 0: XTAL, 1: Audio PLL. + $EN_DIS **/ - UINT8 Reserved39; + UINT8 PchHdaSndwClockSourceSelect; /** Offset 0x05A9 - PCH LPC Enhance the port 8xh decoding Original LPC only decodes one byte of port 80h. @@ -1708,7 +2118,12 @@ typedef struct { /** Offset 0x05CE - Reserved **/ - UINT8 Reserved40[46]; + UINT8 Reserved11[14]; + +/** Offset 0x05DC - Clk Req GPIO Pin + Select Clk Req Pin. Refer to GPIO_*_MUXING_SRC_CLKREQ_x* for possible values. +**/ + UINT32 PcieClkReqGpioMux[8]; /** Offset 0x05FC - Enable PCIE RP Mask Enable/disable PCIE Root Ports. 0: disable, 1: enable. One bit for each port, bit0 @@ -1724,7 +2139,7 @@ typedef struct { /** Offset 0x0601 - Reserved **/ - UINT8 Reserved41[3]; + UINT8 Reserved12[3]; /** Offset 0x0604 - Serial Io Uart Debug Mmio Base Select SerialIo Uart default MMIO resource in SEC/PEI phase when PcdLpssUartMode @@ -1799,9 +2214,13 @@ typedef struct { **/ UINT8 WdtDisableAndLock; -/** Offset 0x061A - Reserved +/** Offset 0x061A **/ - UINT8 Reserved42[2]; + UINT8 FabricGVDisable; + +/** Offset 0x061B - Reserved +**/ + UINT8 Reserved13; /** Offset 0x061C - HECI Timeouts 0: Disable, 1: Enable (Default) timeout check for HECI @@ -1852,9 +2271,18 @@ typedef struct { **/ UINT8 SkipMbpHob; -/** Offset 0x0624 - Reserved +/** Offset 0x0624 - HECI Communication + Test, 0: POR, 1: enable, 2: disable, Disables HECI communication causing ME to enter + error state. + $EN_DIS +**/ + UINT8 HeciCommunication; + +/** Offset 0x0625 - HECI3 Interface Communication + Test, 0: POR, 1: enable, 2: disable, Adds or Removes HECI3 Device from PCI space. + $EN_DIS **/ - UINT8 Reserved43[2]; + UINT8 HeciCommunication3; /** Offset 0x0626 - ISA Serial Base selection Select ISA Serial Base address. Default is 0x3F8. @@ -1873,9 +2301,47 @@ typedef struct { **/ UINT16 PostCodeOutputPort; -/** Offset 0x062A - Reserved +/** Offset 0x062A - Enable/Disable I2cPostcode + Enable (Default): Postcode via I2C, Disable: Postcode via Port80 + $EN_DIS +**/ + UINT8 I2cPostCodeEnable; + +/** Offset 0x062B - Reserved +**/ + UINT8 Reserved14[5]; + +/** Offset 0x0630 - FSPM Validation Pointer + Point to FSPM Validation configuration structure +**/ + UINT64 FspmValidationPtr; + +/** Offset 0x0638 - Extended BIOS Support + Enable/Disable Extended BIOS Region Support. Default is DISABLE. 0: DISABLE, 1: ENABLE + $EN_DIS +**/ + UINT8 ExtendedBiosDecodeRange; + +/** Offset 0x0639 - Extented BIOS Direct Read Decode enable + Enable/Disable access to bigger than 16MB BIOS Region through Direct Memory Reads. + 0: disabled (default), 1: enabled + $EN_DIS +**/ + UINT8 PchSpiExtendedBiosDecodeRangeEnable; + +/** Offset 0x063A - Reserved +**/ + UINT8 Reserved15[2]; + +/** Offset 0x063C - Extended BIOS Direct Read Decode Range base + Bits of 31:16 of a memory address that'll be a base for Extended BIOS Direct Read Decode. +**/ + UINT32 PchSpiExtendedBiosDecodeRangeBase; + +/** Offset 0x0640 - Extended BIOS Direct Read Decode Range limit + Bits of 31:16 of a memory address that'll be a limit for Extended BIOS Direct Read Decode. **/ - UINT8 Reserved44[26]; + UINT32 PchSpiExtendedBiosDecodeRangeLimit; /** Offset 0x0644 - Enable SMBus Enable/disable SMBus controller. @@ -1896,7 +2362,7 @@ typedef struct { /** Offset 0x0647 - Reserved **/ - UINT8 Reserved45; + UINT8 Reserved16; /** Offset 0x0648 - SMBUS Base Address SMBUS Base Address (IO space). @@ -1911,7 +2377,7 @@ typedef struct { /** Offset 0x064B - Reserved **/ - UINT8 Reserved46[13]; + UINT8 Reserved17[13]; /** Offset 0x0658 - Smbus dynamic power gating Disable or Enable Smbus dynamic power gating. @@ -1932,9 +2398,51 @@ typedef struct { **/ UINT8 SaOcSupport; -/** Offset 0x065B - Reserved +/** Offset 0x065B - VF Point Count + Number of supported Voltage & Frequency Point Offset +**/ + UINT8 VfPointCount[10]; + +/** Offset 0x0665 - ProcessVmaxLimit + Disabling Process Vmax Limit will allow user to set any voltage +**/ + UINT8 ProcessVmaxLimit; + +/** Offset 0x0666 - CorePllCurrentRefTuningOffset + Core PLL Current Reference Tuning Offset. 0: No offset. Range 0-15 +**/ + UINT8 CorePllCurrentRefTuningOffset; + +/** Offset 0x0667 - RingPllCurrentRefTuningOffset + Ring PLL Current Reference Tuning Offset. 0: No offset. Range 0-15 +**/ + UINT8 RingPllCurrentRefTuningOffset; + +/** Offset 0x0668 - IaAtomPllCurrentRefTuningOffset + IaAtom PLL Current Reference Tuning Offset. 0: No offset. Range 0-15 +**/ + UINT8 IaAtomPllCurrentRefTuningOffset; + +/** Offset 0x0669 - CoreMinRatio + equest Core Min Ratio. Limit Core minimum ratio for extreme overclocking. Default + 0 indicates no request +**/ + UINT8 CoreMinRatio; + +/** Offset 0x066A - CoreMiNegativeTemperatureReportingnRatio + Negative Temperature Reporting Enable. 0: Disable, 1: enable +**/ + UINT8 NegativeTemperatureReporting; + +/** Offset 0x066B - PcorePowerDensityThrottle + Power Density Throttle control allows user to disable P-core +**/ + UINT8 PcorePowerDensityThrottle; + +/** Offset 0x066C - EcorePowerDensityThrottle + Power Density Throttle control allows user to disable P-core **/ - UINT8 Reserved47[18]; + UINT8 EcorePowerDensityThrottle; /** Offset 0x066D - Over clocking support Over clocking support; 0: Disable; 1: Enable @@ -1942,9 +2450,12 @@ typedef struct { **/ UINT8 OcSupport; -/** Offset 0x066E - Reserved +/** Offset 0x066E - UnderVolt Protection + When UnderVolt Protection is enabled, user will be not be able to program under + voltage in OS runtime. 0: Disabled; 1: Enabled + $EN_DIS **/ - UINT8 Reserved48; + UINT8 UnderVoltProtection; /** Offset 0x066F - Realtime Memory Timing 0(Default): Disabled, 1: Enabled. When enabled, it will allow the system to perform @@ -2005,9 +2516,18 @@ typedef struct { **/ UINT8 Lfsr1Mask; -/** Offset 0x067B - Reserved +/** Offset 0x067B - Row Hammer DRAM Refresh Management Mode + Row Hammer Adaptive Refresh Management Level: 0-RFM (default), 1-ARFMLevel A, 2-ARFMLevel + B, 3-ARFMLevel C, 4-Disable ARFM and RFM + 0: RFM, 1: ARFM Level A, 2: ARFM Level B, 3: ARFM Level C, 4: ARFM and RFM Disabled +**/ + UINT8 DramRfmMode; + +/** Offset 0x067C - Row Hammer Targeted Row Refresh Mode + Row Hammer Targeted Row Refresh: 0-DRFM, 1-pTRR (default), 2-Disable DRFM and pTRR + 0: DRFM, 1: pTRR, 2: Targeted Row Refresh Disabled **/ - UINT8 Reserved49[2]; + UINT8 TargetedRowRefreshMode; /** Offset 0x067D - TjMax Offset TjMax offset.Specified value here is clipped by pCode (125 - TjMax Offset) to support @@ -2015,9 +2535,27 @@ typedef struct { **/ UINT8 TjMaxOffset; -/** Offset 0x067E - Reserved +/** Offset 0x067E - Per-Atom-Cluster VF Offset + Array used to specifies the selected Atom Core Cluster Offset Voltage. This voltage + is specified in millivolts. +**/ + UINT16 PerAtomClusterVoltageOffset[8]; + +/** Offset 0x068E - Per-Atom-Cluster VF Offset Prefix + Sets the PerAtomCLusterVoltageOffset value as positive or negative for the selected + Core; 0: Positive ; 1: Negative. +**/ + UINT8 PerAtomClusterVoltageOffsetPrefix[8]; + +/** Offset 0x0696 - Per-Atom-Cluster Voltage Mode + Array used to specifies the selected Atom Core ClusterVoltage Mode. +**/ + UINT8 PerAtomClusterVoltageMode[8]; + +/** Offset 0x069E - Per-Atom-Cluster Voltage Override + Array used to specifies the selected Atom Core Cluster Voltage Override. **/ - UINT8 Reserved50[48]; + UINT16 PerAtomClusterVoltageOverride[8]; /** Offset 0x06AE - Core VF Point Offset Array used to specifies the Core Voltage Offset applied to the each selected VF @@ -2037,9 +2575,28 @@ typedef struct { **/ UINT8 CoreVfPointRatio[15]; -/** Offset 0x06EA - Reserved +/** Offset 0x06EA - Core VF Configuration Scope + Allows both all-core VF curve or per-core VF curve configuration; 0: All-core; + 1: Per-core. + 0:All-core, 1:Per-core +**/ + UINT8 CoreVfConfigScope; + +/** Offset 0x06EB - Reserved +**/ + UINT8 Reserved18; + +/** Offset 0x06EC - Per-core VF Offset + Array used to specifies the selected Core Offset Voltage. This voltage is specified + in millivolts. +**/ + UINT16 PerCoreVoltageOffset[8]; + +/** Offset 0x06FC - Per-core VF Offset Prefix + Sets the PerCoreVoltageOffset value as positive or negative for the selected Core; + 0: Positive ; 1: Negative. **/ - UINT8 Reserved51[26]; + UINT8 PerCoreVoltageOffsetPrefix[8]; /** Offset 0x0704 - Per Core Max Ratio override Enable or disable Per Core PState OC supported by writing OCMB 0x1D to program new @@ -2048,18 +2605,30 @@ typedef struct { **/ UINT8 PerCoreRatioOverride; -/** Offset 0x0705 - Reserved +/** Offset 0x0705 - Per-core Voltage Mode + Array used to specifies the selected Core Voltage Mode. +**/ + UINT8 PerCoreVoltageMode[8]; + +/** Offset 0x070D - Reserved +**/ + UINT8 Reserved19; + +/** Offset 0x070E - Per-core Voltage Override + Array used to specifies the selected Core Voltage Override. **/ - UINT8 Reserved52[25]; + UINT16 PerCoreVoltageOverride[8]; /** Offset 0x071E - Per Core Current Max Ratio Array for the Per Core Max Ratio **/ UINT8 PerCoreRatio[8]; -/** Offset 0x0726 - Reserved +/** Offset 0x0726 - Atom Cluster Max Ratio + Array for Atom Cluster Max Ratio, 4 ATOM cores are in the same Cluster and their + max core ratio will be aligned. **/ - UINT8 Reserved53[8]; + UINT8 AtomClusterRatio[8]; /** Offset 0x072E - Pvd Ratio Threshold for SOC/CPU die Array of Pvd Ratio Threshold for SOC/CPU die is the threshold value for input ratio @@ -2070,34 +2639,92 @@ typedef struct { **/ UINT8 PvdRatioThreshold; -/** Offset 0x072F - Reserved +/** Offset 0x072F - Pvd Mode SOC/CPU die + Array of PVD Mode. Value from 0 to 3 for SOC/CPU. 0x0 = div-1 (VCO = Output clock), + 0x1 = div-2 (VCO = 2x Output clock), 0x2 = div-4 (VCO = 4x Output clock), 0x3 = + div-8 (VCO = 8x Output clock). **/ - UINT8 Reserved54[65]; + UINT8 PvdMode; -/** Offset 0x0770 - CPU BCLK OC Frequency - CPU BCLK OC Frequency in KHz units. 98000000Hz = 98MHz 0 - Auto. Range is - 40Mhz-1000Mhz. +/** Offset 0x0730 - FLL Overclock Mode + Select FLL Mode Value from 0 to 3. 0x0 = no overclocking, 0x1 = ratio overclocking + with nominal (0.5-1x) reference clock frequency, 0x2 = BCLK overclocking with elevated + (1-3x) reference clock frequency, 0x3 = BCLK overclocking with extreme elevated + (3-5x) reference clock frequency and ratio limited to 63. **/ - UINT32 CpuBclkOcFrequency; + UINT8 FllOverclockMode; -/** Offset 0x0774 - Reserved +/** Offset 0x0731 - Reserved **/ - UINT8 Reserved55[13]; + UINT8 Reserved20; -/** Offset 0x0781 - Avx2 Voltage Guardband Scaling Factor - AVX2 Voltage Guardband Scale factor applied to AVX2 workloads. Range is 0-200 in - 1/100 units, where a value of 125 would apply a 1.25 scale factor. +/** Offset 0x0732 - Ring VF Point Offset + Array used to specifies the Ring Voltage Offset applied to the each selected VF + Point. This voltage is specified in millivolts. **/ - UINT8 Avx2VoltageScaleFactor; + UINT16 RingVfPointOffset[15]; -/** Offset 0x0782 - Ring PLL voltage offset - Core PLL voltage offset. 0: No offset. Range 0-15 +/** Offset 0x0750 - Ring VF Point Offset Prefix + Sets the RingVfPointOffset value as positive or negative for corresponding core + VF Point; 0: Positive ; 1: Negative. +**/ + UINT8 RingVfPointOffsetPrefix[15]; + +/** Offset 0x075F - Ring VF Point Ratio + Array for the each selected Ring VF Point to display the ration. +**/ + UINT8 RingVfPointRatio[15]; + +/** Offset 0x076E - Soc Die SSC enable + Enable/Disable Soc-Die SSC Configuration. 0(Default)=Disable, 1=Enable + $EN_DIS +**/ + UINT8 SocDieSscEnable; + +/** Offset 0x076F - Core Operating Point Reporting + Enables Core Operating point reporting. 0: Disable; 1: Enable + 0:Disable, 1:Enable +**/ + UINT8 CoreOpPointReportingEn; + +/** Offset 0x0770 - CPU BCLK OC Frequency + CPU BCLK OC Frequency in KHz units. 98000000Hz = 98MHz 0 - Auto. Range is + 40Mhz-1000Mhz. +**/ + UINT32 CpuBclkOcFrequency; + +/** Offset 0x0774 - SOC BCLK OC Frequency + SOC BCLK OC Frequency in KHz units. 98000000Hz = 98MHz 0 - Auto. Range is + 40Mhz-1000Mhz. +**/ + UINT32 SocBclkOcFrequency; + +/** Offset 0x0778 - Bitmask of disable cores + Core mask is a bitwise indication of which core should be disabled. 0x00=Default; + Bit 0 - core 0, bit 7 - core 7. +**/ + UINT64 DisablePerCoreMask; + +/** Offset 0x0780 - Granular Ratio Override + Enable or disable OC Granular Ratio Override. 0: Disable, 1: enable + $EN_DIS +**/ + UINT8 GranularRatioOverride; + +/** Offset 0x0781 - Avx2 Voltage Guardband Scaling Factor + AVX2 Voltage Guardband Scale factor applied to AVX2 workloads. Range is 0-200 in + 1/100 units, where a value of 125 would apply a 1.25 scale factor. +**/ + UINT8 Avx2VoltageScaleFactor; + +/** Offset 0x0782 - Ring PLL voltage offset + Core PLL voltage offset. 0: No offset. Range 0-15 **/ UINT8 RingPllVoltageOffset; /** Offset 0x0783 - Reserved **/ - UINT8 Reserved56[5]; + UINT8 Reserved21[5]; /** Offset 0x0788 - Enable PCH ISH Controller 0: Disable, 1: Enable (Default) ISH Controller @@ -2107,7 +2734,7 @@ typedef struct { /** Offset 0x0789 - Reserved **/ - UINT8 Reserved57; + UINT8 Reserved22; /** Offset 0x078A - BiosSize The size of the BIOS region of the IFWI. Used if FspmUpd->FspmConfig.BiosGuard != @@ -2140,9 +2767,24 @@ typedef struct { **/ UINT8 SkipStopPbet; -/** Offset 0x0790 - Reserved +/** Offset 0x0790 - Reset Auxiliary content + Reset Auxiliary content, 0: Disabled, 1: Enabled + $EN_DIS **/ - UINT8 Reserved58[3]; + UINT8 ResetAux; + +/** Offset 0x0791 - TseEnable + Enable/Disable. 0: Disable, Enable/Disable Tse feature, 1: enable + $EN_DIS +**/ + UINT8 TseEnable; + +/** Offset 0x0792 - Enable or Disable TDX + Configure Trust Domain Extension (TDX) to isolate VMs from Virtual-Machine Manager + (VMM)/hypervisor 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 TdxEnable; /** Offset 0x0793 - MKTME Key-Id Bits Override Enable Configure Trust Domain Extension (TDX) to isolate VMs from Virtual-Machine Manager @@ -2153,7 +2795,7 @@ typedef struct { /** Offset 0x0794 - Reserved **/ - UINT8 Reserved59[4]; + UINT8 Reserved23[4]; /** Offset 0x0798 - TME Exclude Base Address TME Exclude Base Address. @@ -2165,9 +2807,26 @@ typedef struct { **/ UINT64 TmeExcludeSize; -/** Offset 0x07A8 - Reserved +/** Offset 0x07A8 - TdxActmModuleAddr + Base address of Tdx Actm module, used for launching the Actm +**/ + UINT64 TdxActmModuleAddr; + +/** Offset 0x07B0 - TdxActmModuleSize + size of Tdx Actm module, used for launching the Actm +**/ + UINT32 TdxActmModuleSize; + +/** Offset 0x07B4 - TdxSeamldrSvn + TdxSeamldrSvn +**/ + UINT8 TdxSeamldrSvn; + +/** Offset 0x07B5 - Boot max frequency + Enable Boot Maximum Frequency in CPU strap. 0: Disable; 1: Enable + $EN_DIS **/ - UINT8 Reserved60[14]; + UINT8 BootMaxFrequency; /** Offset 0x07B6 - BIST on Reset Enable/Disable BIST (Built-In Self Test) on reset. 0: Disable; 1: Enable. @@ -2175,9 +2834,11 @@ typedef struct { **/ UINT8 BistOnReset; -/** Offset 0x07B7 - Reserved +/** Offset 0x07B7 - Reduce XeCores + Enable/Disable Reduce XeCores. 0: Disable(strap=1) ; 1: Enable(strap=0. + $EN_DIS **/ - UINT8 Reserved61; + UINT8 ReduceXecores; /** Offset 0x07B8 - Enable or Disable VMX Enable or Disable VMX, When enabled, a VMM can utilize the additional hardware capabilities @@ -2245,9 +2906,29 @@ typedef struct { **/ UINT8 ActiveCoreCount; -/** Offset 0x07C2 - Reserved +/** Offset 0x07C2 - Number of active small cores + Number of E-cores to enable in each processor package. Note: Number of P-Cores and + E-Cores are looked at together. When both are {0,0 + 0:Disable all small cores, 1:1, 2:2, 3:3, 0xFF:Active all small cores +**/ + UINT8 ActiveSmallCoreCount; + +/** Offset 0x07C3 - Number of LP Atom cores + Number of LP E-cores to enable in LP. 0: Disable all LP Atom cores; 1: 1; 2: 2; + 0xFF: Active all LP Atom cores + 0:Disable all LP Atom cores, 1:1, 2:2, 0xFF:Active all cores **/ - UINT8 Reserved62[6]; + UINT8 ActiveLpAtomCoreCount; + +/** Offset 0x07C4 - DFD Enable + Enable or Disable DFD. 0: Disable, 1:Enable + $EN_DIS +**/ + UINT8 DfdEnable; + +/** Offset 0x07C5 - Reserved +**/ + UINT8 Reserved24[3]; /** Offset 0x07C8 - PrmrrSize Enable/Disable. 0: Disable, define default value of PrmrrSize , 1: enable @@ -2275,7 +2956,351 @@ typedef struct { /** Offset 0x07D2 - Reserved **/ - UINT8 Reserved63[98]; + UINT8 Reserved25[2]; + +/** Offset 0x07D4 - Platform PL1 power + Platform Power Limit 1 Power in Milli Watts. BIOS will round to the nearest 1/8W + when programming. Value set 120 = 15W. Any value can be programmed between Max + and Min Power Limits. This setting will act as the new PL1 value for the Package + RAPL algorithm. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. Valid Range + 0 to 32767. +**/ + UINT32 PsysPowerLimit1Power; + +/** Offset 0x07D8 - PlatformAtxTelemetryUnit Mode + Enable/Disable PlatformAtxTelemetryUnit Mode. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT32 PlatformAtxTelemetryUnit; + +/** Offset 0x07DC - Platform PL1 power + Short term Power Limit value for custom cTDP level. Units are 125 milliwatt. +**/ + UINT16 CustomPowerLimit1; + +/** Offset 0x07DE - Platform PL1 power + Short term Power Limit value for custom cTDP level. Units are 125 milliwatt. +**/ + UINT16 CustomPowerLimit2; + +/** Offset 0x07E0 - Platform PL2 power + Platform Power Limit 2 Power in Milli Watts. BIOS will round to the nearest 1/8W + when programming. Value set 120 = 15W. Any value can be programmed between Max + and Min Power Limits. This setting will act as the new Max Turbo Power (PL2) value + for the Package RAPL algorithm. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 PsysPowerLimit2Power; + +/** Offset 0x07E4 - Vsys Max System battery volatge + Vsys Max defined in 1/1000 increments. Range is 0-65535. For a 1.25 voltage, enter + 1250. Default =0xFF. +**/ + UINT16 VsysMax; + +/** Offset 0x07E6 - ThETA Ibatt Feature + Enable or Disable ThETA Ibatt Feature. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 ThETAIbattEnable; + +/** Offset 0x07E7 - Reserved +**/ + UINT8 Reserved26; + +/** Offset 0x07E8 - ISYS Current Limit L1 + This field indicated the current limitiation of L1. Indicate current limit for which + dependency is on AC/DC mode before PSYS.Units of measurements are 1/8 A +**/ + UINT16 IsysCurrentLimitL1; + +/** Offset 0x07EA - ISYS Current Limit L1 Tau + This Specifies the time window used to calculate average current for ISYS_L1. The + units of measuremnts are specified in PACKAGE_POWER_SKU[TIME_UNIT] +**/ + UINT8 IsysCurrentL1Tau; + +/** Offset 0x07EB - Reserved +**/ + UINT8 Reserved27; + +/** Offset 0x07EC - ISYS Current Limit L2 + This bits enables disables ISYS_CURRENT_LIMIT_L2 algorithm.Indicate current limit + for which dependency is on AC/DC mode before PSYS. Units of measurements are 1/8 A +**/ + UINT16 IsysCurrentLimitL2; + +/** Offset 0x07EE - ISYS Current Limit L1 Enable + This bits enables disables ISYS_CURRENT_LIMIT_L1 algorithm. It control loop based + on the system power source AC or DC mode. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 IsysCurrentLimitL1Enable; + +/** Offset 0x07EF - ISYS Current Limit L2 Enable + This bits enables disables ISYS_CURRENT_LIMIT_L2 algorithm. It control loop based + on the system power source AC or DC mode. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 IsysCurrentLimitL2Enable; + +/** Offset 0x07F0 - Package PL4 boost configuration + Configure Power Limit 4 Boost in Watts. Valid Range 0 to 63000 in step size of 125 + mWatt. The value 0 means disable. +**/ + UINT16 PowerLimit4Boost; + +/** Offset 0x07F2 - Skin Temperature Target + Target temperature is limit to which the control mechanism is regulating.It is defined + in 1/2 C increments.Range is 0-255. Temperature Range is 0-122.5 C.0: Auto. +**/ + UINT8 SkinTargetTemp[3]; + +/** Offset 0x07F5 - Skin Control Temperature Enable MMIO + Enables the skin temperature control for MMIO register. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 SkinTempControlEnable[3]; + +/** Offset 0x07F8 - Skin Temperature Loop Gain + Sets the aggressiveness of control loop where 0 is graceful, favors performance + on expense of temperature overshoots and 7 is for aggressive, favors tight regulation + over performance. Range is 0-7.0: Auto. +**/ + UINT8 SkinControlLoopGain[3]; + +/** Offset 0x07FB - Skin Temperature Override Enable + When set, Pcode will use TEMPERATURE_OVERRIDE values instead of reading from corresponding + sensor.. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 SkinTempOverrideEnable[3]; + +/** Offset 0x07FE - Skin Temperature Minimum Performance Level + Minimum Performance level below which the STC limit will not throttle. 0 - all levels + of throttling allowed incl. survivability actions. 256 - no throttling allowed.0: Auto. +**/ + UINT8 SkinMinPerformanceLevel[3]; + +/** Offset 0x0801 - Skin Temperature Override + Allows SW to override the input temperature. Pcode will use this value instead of + the sensor temperature. EC control is not impacted. Units: 0.5C. Values are 0 to + 255 which represents 0C-122.5C range.0: Auto. +**/ + UINT8 SkinTempOverride[3]; + +/** Offset 0x0804 - Skin Temperature Control Enable + Enables Skin Temperature Control Sensors Feature. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 SkinTempControl; + +/** Offset 0x0805 - AC or DC Power State + AC or DC power State; 0: DC; 1: AC + 0:DC, 1:AC +**/ + UINT8 AcDcPowerState; + +/** Offset 0x0806 - Enable or Disable VR Thermal Alert + Enable or Disable VR Thermal Alert; 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 DisableVrThermalAlert; + +/** Offset 0x0807 - Enable or Disable Thermal Monitor + Enable or Disable Thermal Monitor; 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 ThermalMonitor; + +/** Offset 0x0808 - Configuration for boot TDP selection + Assured Power (cTDP) Mode as Nominal/Level1/Level2/Deactivate Base Power (TDP) selection. + Deactivate option will set MSR to Nominal and MMIO to Zero. 0: Base Power (TDP) + Nominal; 1: Base Power (TDP) Down; 2: Base Power (TDP) Up;0xFF : Deactivate +**/ + UINT8 ConfigTdpLevel; + +/** Offset 0x0809 - ConfigTdp mode settings Lock + Assured Power (cTDP) Mode Lock sets the Lock bits on TURBO_ACTIVATION_RATIO and + CONFIG_TDP_CONTROL. Note: When CTDP (Assured Power) Lock is enabled Custom ConfigTDP + Count will be forced to 1 and Custom ConfigTDP Boot Index will be forced to 0. + 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 ConfigTdpLock; + +/** Offset 0x080A - Load Configurable TDP SSDT + Enables Assured Power (cTDP) control via runtime ACPI BIOS methods. This 'BIOS only' + feature does not require EC or driver support. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 ConfigTdpBios; + +/** Offset 0x080B - CustomTurboActivationRatio + Turbo Activation Ratio for custom cTDP level + $EN_DIS +**/ + UINT8 CustomTurboActivationRatio; + +/** Offset 0x080C - CustomPowerLimit1Time + Short term Power Limit time window value for custom cTDP level. + $EN_DIS +**/ + UINT8 CustomPowerLimit1Time; + +/** Offset 0x080D - PL1 Enable value + Enable/Disable Platform Power Limit 1 programming. If this option is enabled, it + activates the PL1 value to be used by the processor to limit the average power + of given time window. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 PsysPowerLimit1; + +/** Offset 0x080E - PL1 timewindow + Platform Power Limit 1 Time Window value in seconds. The value may vary from 0 to + 128. 0 = default values. Indicates the time window over which Platform Processor + Base Power (TDP) value should be maintained. Valid values(Unit in seconds) 0 to + 8 , 10 , 12 ,14 , 16 , 20 , 24 , 28 , 32 , 40 , 48 , 56 , 64 , 80 , 96 , 112 , 128 +**/ + UINT8 PsysPowerLimit1Time; + +/** Offset 0x080F - PL2 Enable Value + Enable/Disable Platform Power Limit 2 programming. If this option is disabled, BIOS + will program the default values for Platform Power Limit 2. 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 PsysPowerLimit2; + +/** Offset 0x0810 - Package PL3 time window + Power Limit 3 Time Window value in Milli seconds. Indicates the time window over + which Power Limit 3 value should be maintained. If the value is 0, BIOS leaves + the hardware default value. Valid value: 0, 3-8, 10, 12, 14, 16, 20, 24, + 28, 32, 40, 48, 56, 64. +**/ + UINT8 PowerLimit3Time; + +/** Offset 0x0811 - Package Long duration turbo mode time + Power Limit 1 Time Window value in seconds. The value may vary from 0 to 128. 0 + = default value (28 sec for Mobile and 8 sec for Desktop). Defines time window + which Processor Base Power (TDP) value should be maintained. Valid values(Unit + in seconds) 0 to 8 , 10 , 12 ,14 , 16 , 20 , 24 , 28 , 32 , 40 , 48 , 56 , 64 , + 80 , 96 , 112 , 128 +**/ + UINT8 PowerLimit1Time; + +/** Offset 0x0812 - Reserved +**/ + UINT8 Reserved28[2]; + +/** Offset 0x0814 - Package Long duration turbo mode power limit + Power Limit 1 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. 0 = no custom override. Overclocking SKU: Value must be between + Max and Min Power Limits. Other SKUs: This value must be between Min Power Limit + and Processor Base Power (TDP) Limit. If value is 0, BIOS will program Processor + Base Power (TDP) value. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. Valid + Range 0 to 32767. +**/ + UINT32 PowerLimit1; + +/** Offset 0x0818 - Package Short duration turbo mode power limit + Power Limit 2 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. If the value is 0, BIOS will program this value as 1.25*Processor + Base Power (TDP). Processor applies control policies such that the package power + does not exceed this limit. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 PowerLimit2Power; + +/** Offset 0x081C - Package PL3 power limit + Power Limit 3 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. XE SKU: Any value can be programmed. Overclocking SKU: Value + must be between Max and Min Power Limits. Other SKUs: This value must be between + Min Power Limit and Processor Base Power (TDP) Limit. If the value is 0, BIOS leaves + the hardware default value. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 PowerLimit3; + +/** Offset 0x0820 - Package PL4 power limit + Power Limit 4 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. If the value is 0, BIOS leaves default value. Units are based + on POWER_MGMT_CONFIG.CustomPowerUnit. Valid Range 0 to 32767. +**/ + UINT32 PowerLimit4; + +/** Offset 0x0824 - Short term Power Limit value for custom cTDP level 1 + Power Limit 1 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. 0 = no custom override. Overclocking SKU: Value must be between + Max and Min Power Limits. Other SKUs: This value must be between Min Power Limit + and Processor Base Power (TDP) Limit. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 Custom1PowerLimit1; + +/** Offset 0x0828 - Long term Power Limit value for custom cTDP level 1 + Power Limit 2 value in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. 0 = no custom override. Processor applies control policies + such that the package power does not exceed this limit. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 Custom1PowerLimit2; + +/** Offset 0x082C - Enable Configurable TDP + Applies Assured Power (cTDP) initialization settings based on non-Assured Power + (cTDP) or Assured Power (cTDP). Default is 1: Applies to Assured Power (cTDP) ; + if 0 then applies non-Assured Power (cTDP) and BIOS will bypass Assured Power (cTDP) + initialization flow + $EN_DIS +**/ + UINT8 ApplyConfigTdp; + +/** Offset 0x082D - Dual Tau Boost + Enable Dual Tau Boost feature. This is only applicable for Desktop 35W/65W/125W + sku. When DPTF is enabled this feature is ignored. 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 DualTauBoost; + +/** Offset 0x082E - Tcc Offset Lock + Tcc Offset Lock for Runtime Average Temperature Limit (RATL) to lock temperature + target; 1:Enabled ; 0: Disabled. + $EN_DIS +**/ + UINT8 TccOffsetLock; + +/** Offset 0x082F - Package PL3 Duty Cycle + Specify the duty cycle in percentage that the CPU is required to maintain over the + configured time window. Range is 0-100. +**/ + UINT8 PowerLimit3DutyCycle; + +/** Offset 0x0830 - Package PL3 Lock + Power Limit 3 Lock. When enabled PL3 configurations are locked during OS. When disabled + PL3 configuration can be changed during OS. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT8 PowerLimit3Lock; + +/** Offset 0x0831 - Package PL4 Lock + Power Limit 4 Lock. When enabled PL4 configurations are locked during OS. When disabled + PL4 configuration can be changed during OS. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT8 PowerLimit4Lock; + +/** Offset 0x0832 - Short Duration Turbo Mode + Enable/Disable Power Limit 2 override. If this option is disabled, BIOS will program + the default values for Power Limit 2. 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 PowerLimit2; + +/** Offset 0x0833 - Response Mode + Enable/Disable Response Mode. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT8 ResponseMode; /** Offset 0x0834 - SinitMemorySize Enable/Disable. 0: Disable, define default value of SinitMemorySize , 1: enable @@ -2340,9 +3365,18 @@ typedef struct { **/ UINT8 AcousticNoiseMitigation; -/** Offset 0x086E - Reserved +/** Offset 0x086E - RfiMitigation + Enable or Disable RFI Mitigation. 0: Disable - DCM is the IO_N default; 1: + Enable - Enable IO_N DCM/CCM switching as RFI mitigation. + $EN_DIS +**/ + UINT8 RfiMitigation; + +/** Offset 0x086F - Platform Psys slope correction + PSYS Slope defined in 1/100 increments. 0 - Auto Specified in 1/100 increment + values. Range is 0-200. 125 = 1.25 **/ - UINT8 Reserved64[2]; + UINT8 PsysSlope; /** Offset 0x0870 - Platform Power Pmax PSYS PMax power, defined in 1/8 Watt increments. 0 - Auto Specified in 1/8 @@ -2394,7 +3428,14 @@ typedef struct { /** Offset 0x08BA - Reserved **/ - UINT8 Reserved65[26]; + UINT8 Reserved29[2]; + +/** Offset 0x08BC - Imon offset correction + IMON Offset is an 32-bit signed value (2's complement). Units 1/1000, Range is [-128000, + 127999]. For an offset of 25.348, enter 25348. 0: Auto. [0] for IA, [1] + for GT, [2] for SA, [3] through [5] are Reserved. +**/ + UINT32 ImonOffset[6]; /** Offset 0x08D4 - Icc Max limit Voltage Regulator Current Limit (Icc Max). This value represents the Maximum instantaneous @@ -2404,9 +3445,34 @@ typedef struct { **/ UINT16 IccMax[6]; -/** Offset 0x08E0 - Reserved +/** Offset 0x08E0 - VR Fast Vmode VoltageLimit support + Voltage Regulator Fast VoltageLimit . **/ - UINT8 Reserved66[42]; + UINT16 VrVoltageLimit[6]; + +/** Offset 0x08EC - Imon slope correction + IMON Slope defined in 1/100 increments. Range is 0-200. For a 1.25 slope, enter + 125. 0: Auto. [0] for IA, [1] for GT, [2] for SA, [3] through [5] are Reserved. +**/ + UINT16 ImonSlope[6]; + +/** Offset 0x08F8 - Power State 3 enable/disable + PS3 Enable/Disable. 0 - Disabled, 1 - Enabled. [0] for IA, [1] for GT, [2] for SA, + [3] through [5] are Reserved. +**/ + UINT8 Ps3Enable[6]; + +/** Offset 0x08FE - Power State 4 enable/disable + PS4 Enable/Disable. 0 - Disabled, 1 - Enabled. [0] for IA, [1] for GT, [2] for SA, + [3] through [5] are Reserved. +**/ + UINT8 Ps4Enable[6]; + +/** Offset 0x0904 - Enable/Disable BIOS configuration of VR + VR Config Enable. [0] for IA, [1] for GT, [2] for SA, [3] through [5] are Reserved. + 0: Disable; 1: Enable. +**/ + UINT8 VrConfigEnable[6]; /** Offset 0x090A - Thermal Design Current enable/disable Thermal Design Current enable/disable; 0: Disable; 1: Enable. [0] for IA, @@ -2414,9 +3480,11 @@ typedef struct { **/ UINT8 TdcEnable[6]; -/** Offset 0x0910 - Reserved +/** Offset 0x0910 - Thermal Design Current Lock + Thermal Design Current Lock; 0: Disable; 1: Enable. [0] for IA, [1] for GT, + [2] for SA, [3] for atom, [4]-[5] are Reserved. **/ - UINT8 Reserved67[6]; + UINT8 TdcLock[6]; /** Offset 0x0916 - Disable Fast Slew Rate for Deep Package C States for VR domains This option needs to be configured to reduce acoustic noise during deeper C states. @@ -2438,7 +3506,14 @@ typedef struct { /** Offset 0x0922 - Reserved **/ - UINT8 Reserved68[6]; + UINT8 Reserved30[2]; + +/** Offset 0x0924 - Platform Psys offset correction + PSYS Offset defined in 1/1000 increments. 0 - Auto This is an 32-bit signed + value (2's complement). Units 1/1000, Range is [-128000, 127999]. For an offset + of 25.348, enter 25348. +**/ + UINT32 PsysOffset; /** Offset 0x0928 - Thermal Design Current time window Auto = 0 is default. Range is from 1ms to 448s. 0: Auto. [0] for IA, [1] @@ -2452,9 +3527,17 @@ typedef struct { **/ UINT8 TdcMode[6]; -/** Offset 0x0946 - Reserved +/** Offset 0x0946 - DLVR RFI Enable + Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 FivrSpectrumEnable; + +/** Offset 0x0947 - DLVR RFI Spread Spectrum Percentage + DLVR SSC in percentage with multiple of 0.25%. 0 = 0%, 10 = 4%. 0x00: 0% , 0x02: + 0.5%, 0x04: 1% , 0x08: 2% ,0x10: 4%; u3.2 value from 0% - 4%. **/ - UINT8 Reserved69[2]; + UINT8 DlvrSpreadSpectrumPercentage; /** Offset 0x0948 - DLVR RFI Enable Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. @@ -2474,7 +3557,53 @@ typedef struct { /** Offset 0x094B - Reserved **/ - UINT8 Reserved70[11]; + UINT8 Reserved31; + +/** Offset 0x094C - DLVR RFI Frequency + DLVR RFI Frequency in MHz. 0: 2227 MHz , 1: 2140MHZ. +**/ + UINT16 DlvrRfiFrequency; + +/** Offset 0x094E - DLVR PHASE_SSC Enable + Enable/Disable DLVR PHASE_SSC. 0: Disable. 1:Enable. + $EN_DIS +**/ + UINT8 VrPowerDeliveryDesign; + +/** Offset 0x094F - DLVR PHASE_SSC Enable + Enable/Disable DLVR PHASE_SSC. 0: Disable. 1:Enable. + $EN_DIS +**/ + UINT8 DlvrPhaseSsc; + +/** Offset 0x0950 - Vsys Critical + PCODE MMIO Mailbox: Vsys Critical. 0: Disable; 1: Enable Range is 0-255. +**/ + UINT8 EnableVsysCritical; + +/** Offset 0x0951 - Assertion Deglitch Mantissa + Assertion Deglitch Mantissa, Range is 0-255 +**/ + UINT8 VsysAssertionDeglitchMantissa; + +/** Offset 0x0952 - Assertion Deglitch Exponent + Assertion Deglitch Exponent, Range is 0-255 +**/ + UINT8 VsysAssertionDeglitchExponent; + +/** Offset 0x0953 - De assertion Deglitch Mantissa + De assertion Deglitch Mantissa, Range is 0-255 +**/ + UINT8 VsysDeassertionDeglitchMantissa; + +/** Offset 0x0954 - De assertion Deglitch Exponent + De assertion Deglitch Exponent, Range is 0-255 +**/ + UINT8 VsysDeassertionDeglitchExponent; + +/** Offset 0x0955 - Reserved +**/ + UINT8 Reserved32; /** Offset 0x0956 - VR Fast Vmode ICC Limit support Voltage Regulator Fast Vmode ICC Limit. A value of 400 = 100A. A value of 0 corresponds @@ -2499,7 +3628,44 @@ typedef struct { /** Offset 0x096E - Reserved **/ - UINT8 Reserved71[28]; + UINT8 Reserved33[2]; + +/** Offset 0x0970 - Vsys Full Scale + Vsys Full Scale, Range is 0-255000mV +**/ + UINT32 VsysFullScale; + +/** Offset 0x0974 - Vsys Critical Threshold + Vsys Critical Threshold, Range is 0-255000mV +**/ + UINT32 VsysCriticalThreshold; + +/** Offset 0x0978 - Psys Full Scale + Psys Full Scale, Range is 0-255000mV +**/ + UINT32 PsysFullScale; + +/** Offset 0x097C - Psys Critical Threshold + Psys Critical Threshold, Range is 0-255000mV +**/ + UINT32 PsysCriticalThreshold; + +/** Offset 0x0980 - Reserved +**/ + UINT8 Reserved34[8]; + +/** Offset 0x0988 - IOE Debug Enable + Enable/Disable IOE Debug. When enabled, IOE D2D Dfx link will keep up and clock + is enabled + $EN_DIS +**/ + UINT8 IoeDebugEn; + +/** Offset 0x0989 - Pmode Clock Enable + Enable/Disable PMODE clock. When enabled, Pmode clock will toggle for XDP use + $EN_DIS +**/ + UINT8 PmodeClkEn; /** Offset 0x098A - PCH Port80 Route Control where the Port 80h cycles are sent, 0: LPC; 1: PCI. @@ -2514,9 +3680,21 @@ typedef struct { **/ UINT8 GpioOverride; -/** Offset 0x098C - Reserved +/** Offset 0x098C - Pmc Privacy Consent + Enable/Disable Pmc Privacy Consent + $EN_DIS +**/ + UINT8 PmcPrivacyConsent; + +/** Offset 0x098D - DMI ME UMA Root Space Check + DMI IOSF Root Space attribute check for RS3 for cycles targeting MEUMA. + 0: POR, 1: enable, 2: disable **/ - UINT8 Reserved72[4]; + UINT8 PchTestDmiMeUmaRootSpaceCheck; + +/** Offset 0x098E - Reserved +**/ + UINT8 Reserved35[2]; /** Offset 0x0990 - PMR Size Size of PMR memory buffer. 0x400000 for normal boot and 0x200000 for S3 boot @@ -2540,9 +3718,11 @@ typedef struct { **/ UINT8 VtdDisable; -/** Offset 0x0997 - Reserved +/** Offset 0x0997 - State of Vtd Capabilities + 0x0=(No operation), BIT0 = 1 (Defeature Nested Support), BIT1 = 1 (Defeature Posted + Interrupt Support) **/ - UINT8 Reserved73; + UINT8 VtdCapabilityControl; /** Offset 0x0998 - Base addresses for VT-d function MMIO access Base addresses for VT-d MMIO access per VT-d engine @@ -2551,7 +3731,17 @@ typedef struct { /** Offset 0x09BC - Reserved **/ - UINT8 Reserved74[20]; + UINT8 Reserved36[4]; + +/** Offset 0x09C0 - MMIO Size + Size of MMIO space reserved for devices. 0(Default)=Auto, non-Zero=size in MB +**/ + UINT64 MchBar; + +/** Offset 0x09C8 - MMIO Size + Size of MMIO space reserved for devices. 0(Default)=Auto, non-Zero=size in MB +**/ + UINT64 RegBar; /** Offset 0x09D0 - MMIO Size Size of MMIO space reserved for devices. 0(Default)=Auto, non-Zero=size in MB @@ -2564,9 +3754,50 @@ typedef struct { **/ UINT16 MmioSizeAdjustment; -/** Offset 0x09D4 - Reserved +/** Offset 0x09D4 - Temporary address for ApicLocalAddress + The reference code will use this as Temporary address space +**/ + UINT32 ApicLocalAddress; + +/** Offset 0x09D8 - Temporary address for NvmeHcPeiMmioBase + The reference code will use this as Temporary address space +**/ + UINT32 NvmeHcPeiMmioBase; + +/** Offset 0x09DC - Temporary address for NvmeHcPeiMmioLimit + The reference code will use this as Temporary address space **/ - UINT8 Reserved75[36]; + UINT32 NvmeHcPeiMmioLimit; + +/** Offset 0x09E0 - Temporary address for AhciPeiMmioBase + The reference code will use this as Temporary address space +**/ + UINT32 AhciPeiMmioBase; + +/** Offset 0x09E4 - Temporary address for AhciPeiMmioLimit + The reference code will use this as Temporary address space +**/ + UINT32 AhciPeiMmioLimit; + +/** Offset 0x09E8 - Temporary address for EcExtraIoBase + The reference code will use this as Temporary address space +**/ + UINT16 EcExtraIoBase; + +/** Offset 0x09EA - Temporary address for SioBaseAddress + The reference code will use this as Temporary address space +**/ + UINT16 SioBaseAddress; + +/** Offset 0x09EC - Temporary CfgBar address for VMD + The reference code will use this as Temporary address space +**/ + UINT32 VmdCfgBarBar; + +/** Offset 0x09F0 - System Agent SafBar + Address of System Agent SafBar +**/ + UINT64 SafBar; /** Offset 0x09F8 - Enable above 4GB MMIO resource support Enable/disable above 4GB MMIO resource support @@ -2582,7 +3813,20 @@ typedef struct { /** Offset 0x09FA - Reserved **/ - UINT8 Reserved76[10]; + UINT8 Reserved37[2]; + +/** Offset 0x09FC - StreamTracer Mode + Disable: Disable StreamTracer, Advanced Tracing: StreamTracer size 512MB - Recommended + when all groups in high verbosity are traced in 'red', Auto: StreamTracer size + 8MB - Recommended when using up to 8 groups red or up to 16 groups in green in + med verbosity, User input: Allow User to enter a size in the range of 64KB-512MB + 0: Disable (Default), 524288: Advanced Tracing , 8192: Auto , 3: User input +**/ + UINT32 StreamTracerMode; + +/** Offset 0x0A00 +**/ + UINT32 StreamTracerSize; /** Offset 0x0A04 - Enable/Disable CrashLog Device Enable or Disable CrashLog/Telemetry Device 0- Disable, 1- Enable @@ -2590,9 +3834,39 @@ typedef struct { **/ UINT32 CpuCrashLogDevice; -/** Offset 0x0A08 - Reserved +/** Offset 0x0A08 - StreamTracer physical address + StreamTracer physical address +**/ + UINT64 StreamTracerBase; + +/** Offset 0x0A10 - Temporary MemBar1 address for VMD + StreamTracer physical address **/ - UINT8 Reserved77[20]; + UINT32 VmdMemBar1Bar; + +/** Offset 0x0A14 - Temporary MemBar2 address for VMD + StreamTracer physical address +**/ + UINT32 VmdMemBar2Bar; + +/** Offset 0x0A18 - Skip override boot mode When Fw Update. + When set to TRUE and boot mode is BOOT_ON_FLASH_UPDATE, skip setting boot mode to + BOOT_WITH_FULL_CONFIGURATION in PEI memory init. + $EN_DIS +**/ + UINT8 SiSkipOverrideBootModeWhenFwUpdate; + +/** Offset 0x0A19 - Reserved +**/ + UINT8 Reserved38; + +/** Offset 0x0A1A - Static Content at 4GB Location + 0 (Default): No Allocation, 0x20:32MB, 0x40:64MB, 0x80:128MB, 0x100:256MB, 0x200:512MB, + 0x400:1GB, 0x800:2GB, 0xC00:3GB, 0x1000:4GB, 0x2000:8GB + 0: No Allocation, 0x20:32MB, 0x40:64MB, 0x80:128MB, 0x100:256MB, 0x200:512MB, 0x400:1GB, + 0x800:2GB, 0xC00:3GB, 0x1000:4GB, 0x2000:8GB +**/ + UINT16 StaticContentSizeAt4Gb; /** Offset 0x0A1C - Platform Debug Option Enabled Trace active: TraceHub is enabled and trace is active, blocks s0ix.\n @@ -2607,9 +3881,14 @@ typedef struct { **/ UINT8 PlatformDebugOption; -/** Offset 0x0A1D - Reserved +/** Offset 0x0A1D - TXT CMOS Offset + CMOS Offset for TXT policy data. Default 0x2A +**/ + UINT8 CmosTxtOffset; + +/** Offset 0x0A1E - Reserved **/ - UINT8 Reserved78[14]; + UINT8 Reserved39[13]; /** Offset 0x0A2B - Program GPIOs for LFP on DDI port-A device 0=Disabled,1(Default)=eDP, 2=MIPI DSI @@ -2617,9 +3896,10 @@ typedef struct { **/ UINT8 DdiPortAConfig; -/** Offset 0x0A2C - Reserved +/** Offset 0x0A2C - HgSubSystemId + Hybrid Graphics SubSystemId **/ - UINT8 Reserved79[2]; + UINT16 HgSubSystemId; /** Offset 0x0A2E - Program GPIOs for LFP on DDI port-B device 0(Default)=Disabled,1=eDP, 2=MIPI DSI @@ -2711,9 +3991,15 @@ typedef struct { **/ UINT8 DdiPort4Ddc; -/** Offset 0x0A3D - Reserved +/** Offset 0x0A3D - Oem T12 Dealy Override + Oem T12 Dealy Override. 0(Default)=Disable 1=Enable + $EN_DIS +**/ + UINT8 OemT12DelayOverride; + +/** Offset 0x0A3E - Reserved **/ - UINT8 Reserved80[3]; + UINT8 Reserved40[2]; /** Offset 0x0A40 - Temporary MMIO address for GMADR The reference code will use this as Temporary MMIO address space to access GMADR @@ -2730,9 +4016,12 @@ typedef struct { **/ UINT64 GttMmAdr; -/** Offset 0x0A50 - Reserved +/** Offset 0x0A50 - Delta T12 Power Cycle Delay required in ms + Select the value for delay required. 0= No delay, 0xFFFF(Default) = Auto calculate + T12 Delay to max 500ms + 0 : No Delay, 0xFFFF : Auto Calulate T12 Delay **/ - UINT8 Reserved81[2]; + UINT16 DeltaT12PowerCycleDelay; /** Offset 0x0A52 - Enable/Disable Memory Bandwidth Compression 0=Disable, 1(Default)=Enable @@ -2762,7 +4051,7 @@ typedef struct { /** Offset 0x0A56 - Reserved **/ - UINT8 Reserved82[2]; + UINT8 Reserved41[2]; /** Offset 0x0A58 - Intel Graphics VBT (Video BIOS Table) Size Size of Internal Graphics VBT Image @@ -2771,7 +4060,7 @@ typedef struct { /** Offset 0x0A5C - Reserved **/ - UINT8 Reserved83[4]; + UINT8 Reserved42[4]; /** Offset 0x0A60 - Graphics Configuration Ptr Points to VBT @@ -2831,9 +4120,11 @@ typedef struct { **/ UINT8 TcssXhciEn; -/** Offset 0x0A83 - Reserved +/** Offset 0x0A83 - IomUsbCDpConfig + Set IomUsbCDpConfig expect 4 values from 0 to 3 + 0:Disabled, 1:IOM_DP, 2:IOM_HDMI, 3: IOM_EDP **/ - UINT8 Reserved84[4]; + UINT8 IomUsbCDpConfig[4]; /** Offset 0x0A87 - TCSS Type C Port 0 Set TCSS Type C Port 0 Type, Options are 0=DISABLE, 1=DP_ONLY, 2=NO_TBT, 3=NO_PCIE, @@ -2863,9 +4154,11 @@ typedef struct { **/ UINT8 TcssPort3; -/** Offset 0x0A8B - Reserved +/** Offset 0x0A8B - TCSS Platform Configuration + Set TCSS Platform Configuration - Retimer Map, TCP0 - Bits[1:0], TCP1 - Bits[3:2], + TCP2 - Bits[5:4], TCP3 - Bits[7:6]; 0=Retimerless, 1=Retimer **/ - UINT8 Reserved85; + UINT8 TcssPlatConf; /** Offset 0x0A8C - TypeC port GPIO setting GPIO Pin number for Type C Aux orientation setting, use the GpioPad that is defined @@ -2931,9 +4224,11 @@ typedef struct { **/ UINT8 InternalGraphics; -/** Offset 0x0AC9 - Reserved +/** Offset 0x0AC9 - Asynchronous ODT + This option configures the Memory Controler Asynchronous ODT control + 0:Enabled, 1:Disabled **/ - UINT8 Reserved86; + UINT8 AsyncOdtDis; /** Offset 0x0ACA - DLL Weak Lock Support Enables/Disable DLL Weak Lock Support @@ -2943,7 +4238,7 @@ typedef struct { /** Offset 0x0ACB - Reserved **/ - UINT8 Reserved87; + UINT8 Reserved43; /** Offset 0x0ACC - Rx DQS Delay Comp Support Enables/Disable Rx DQS Delay Comp Support @@ -2953,7 +4248,7 @@ typedef struct { /** Offset 0x0ACD - Reserved **/ - UINT8 Reserved88[2]; + UINT8 Reserved44[2]; /** Offset 0x0ACF - Mrc Failure On Unsupported Dimm Enables/Disable Mrc Failure On Unsupported Dimm @@ -2961,9 +4256,11 @@ typedef struct { **/ UINT8 MrcFailureOnUnsupportedDimm; -/** Offset 0x0AD0 - Reserved +/** Offset 0x0AD0 - Fore Single Rank config + Enables/Disable Fore Single Rank config + $EN_DIS **/ - UINT8 Reserved89[4]; + UINT32 ForceSingleRank; /** Offset 0x0AD4 - DynamicMemoryBoost Enable/Disable Dynamic Memory Boost Feature. Only valid if SpdProfileSelected is @@ -2979,9 +4276,55 @@ typedef struct { **/ UINT32 RealtimeMemoryFrequency; -/** Offset 0x0ADC - Reserved +/** Offset 0x0ADC - SelfRefresh IdleTimer + SelfRefresh IdleTimer, Default is 256 +**/ + UINT16 SrefCfgIdleTmr; + +/** Offset 0x0ADE - MC Register Offset + Apply user offsets to select MC registers(Def=Disable) + $EN_DIS +**/ + UINT8 MCREGOFFSET; + +/** Offset 0x0ADF - CA Vref Ctl Offset + Offset to be applied to DDRDATA7CH1_CR_DDRCRVREFADJUST1.CAVref + 0xF4:-12,0xF5:-11, 0xF6:-10, 0xF7:-9, 0xF8:-8, 0xF9:-7, 0xFA:-6, 0xFB:-5, 0xFC:-4, + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3, 4:+4, 5:+5, 6:+6, 7:+7, 8:+8, + 9:+9, 10:+10, 11:+11, 12:+12 +**/ + UINT8 CAVrefCtlOffset; + +/** Offset 0x0AE0 - Clk PI Code Offset + Offset to be applied to DDRCLKCH0_CR_DDRCRCLKPICODE.PiSettingRank[0-3] + 0xFA:-6, 0xFB:-5, 0xFC:-4, 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3, 4:+4, + 5:+5, 6:+6 +**/ + UINT8 ClkPiCodeOffset; + +/** Offset 0x0AE1 - RcvEn Offset + Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.RcvEn + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 +**/ + UINT8 RcvEnOffset; + +/** Offset 0x0AE2 - Rx Dqs Offset + Offset to be applied to DDRDATACHX_CR_DDRCRDATAOFFSETTRAIN.RxDqsOffset + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 +**/ + UINT8 RxDqsOffset; + +/** Offset 0x0AE3 - Tx Dq Offset + Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.TxDqOffset + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 **/ - UINT8 Reserved90[9]; + UINT8 TxDqOffset; + +/** Offset 0x0AE4 - Tx Dqs Offset + Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.TxDqsOffset + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 +**/ + UINT8 TxDqsOffset; /** Offset 0x0AE5 - Vref Offset Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.VrefOffset @@ -2990,9 +4333,15 @@ typedef struct { **/ UINT8 VrefOffset; -/** Offset 0x0AE6 - Reserved +/** Offset 0x0AE6 - Controller mask + Controller mask to apply on parameter offset +**/ + UINT8 CntrlrMask; + +/** Offset 0x0AE7 - Channel mask + Channel mask to apply on parameter offset **/ - UINT8 Reserved91[2]; + UINT8 ChMask; /** Offset 0x0AE8 - tRRSG Delta Delay between Read-to-Read commands in the same Bank Group. 0 - Auto. Signed TAT @@ -3106,9 +4455,158 @@ typedef struct { **/ UINT8 tRWDD; -/** Offset 0x0AF8 - Reserved +/** Offset 0x0AF8 - MRC Interpreter + Select CMOS location match of DD01 or Ctrl-Break key or force entry + 0:CMOS, 1:Break, 2:Force +**/ + UINT8 Interpreter; + +/** Offset 0x0AF9 - ODT mode + ODT mode + 0:Default, 1:Vtt, 2:Vddq, 3:Vss, 4:Max +**/ + UINT8 IoOdtMode; + +/** Offset 0x0AFA - PerBankRefresh + Control of Per Bank Refresh feature for LPDDR DRAMs + $EN_DIS +**/ + UINT8 PerBankRefresh; + +/** Offset 0x0AFB - Mimic WC display pattern in IPQ + Using for Disable/Enable Mimic WC display pattern in IPQ: 0:Disable, 1:Enable 1 + ACT resources usage, 3:Enable 2 ACT resources usage, 3:Enable 3 ACT resources usage,0xf: + Enable 4 ACT resources usage + 1:1, 3:3, 0xf:0xf, 0:Auto +**/ + UINT8 MimicWcDisaplayInIpq; + +/** Offset 0x0AFC - Fake SAGV + Fake SAGV: 0:Disabled, 1:Enabled + $EN_DIS +**/ + UINT32 FakeSagv; + +/** Offset 0x0B00 - Lock DPR register + Lock DPR register. 0: Platform POR ; 1: Enable; 2: Disable + 0:Platform POR, 1: Enable, 2: Disable +**/ + UINT32 DprLock; + +/** Offset 0x0B04 - Board Stack Up + Board Stack Up: 0=Typical, 1=Freq Limited + 0:Typical, 1:Freq Limited +**/ + UINT8 BoardStackUp; + +/** Offset 0x0B05 - PPR ForceRepair + When Eanble, PPR will force repair some rows many times (90) + $EN_DIS +**/ + UINT8 PprForceRepair; + +/** Offset 0x0B06 - PPR Repair Bank + Deprecated **/ - UINT8 Reserved92[41]; + UINT8 PprRepairBank; + +/** Offset 0x0B07 - Board Topology + Board Topology: 0=Daisy Chain, 1=Tee. + 0:Daisy Chain, 1:Tee +**/ + UINT8 BoardTopology; + +/** Offset 0x0B08 - SubCh Hash Interleaved Bit + Select the MC Enhanced Channel interleave bit, to set different address bit for + sub channel selection than bit-6 + 0:BIT6, 1:BIT7, 2:BIT8, 3:BIT9, 4:BIT10, 5:BIT11, 6:BIT12, 7:BIT13 +**/ + UINT8 SubChHashInterleaveBit; + +/** Offset 0x0B09 - Reserved +**/ + UINT8 Reserved45; + +/** Offset 0x0B0A - SubCh Hash Mask + Set the BIT(s) to be included in the XOR function. NOTE BIT mask corresponds to + BITS [19:6] Default is 0x834 +**/ + UINT16 SubChHashMask; + +/** Offset 0x0B0C - Force CKD in Bypass Mode + Enable/Disable Force CKD in Bypass Mode + $EN_DIS +**/ + UINT8 ForceCkdBypass; + +/** Offset 0x0B0D - Reserved +**/ + UINT8 Reserved46[3]; + +/** Offset 0x0B10 - Disable Zq + Enable/Disable Zq Calibration: 0:Enabled, 1:Disabled + $EN_DIS +**/ + UINT32 DisableZq; + +/** Offset 0x0B14 - Replicate SAGV + Replicate SAGV: 0:Disabled, 1:Enabled + $EN_DIS +**/ + UINT32 ReplicateSagv; + +/** Offset 0x0B18 - Adjust wck mode + Adjust wck mode: 0:safe mode, 1:manual mode, 2:dynamic mode, 3:Default + 0:safe mode, 1:manual mode, 2:dynamic mode, 3:Default +**/ + UINT8 AdjustWckMode; + +/** Offset 0x0B19 - Control MC/PMA telemetry + Control MC/PMA telemetry: 0: Default, 1: Enable, 2: Disable + 0: Default, 1: Enable, 2: Disable +**/ + UINT8 TelemetryControl; + +/** Offset 0x0B1A - PHclk\Qclk SPINE gating Control + PHclk\Qclk SPINE gating Control: 0:Disabled, 1:Enabled + $EN_DIS +**/ + UINT8 SpineAndPhclkGateControl; + +/** Offset 0x0B1B - SpineGating per lpmode + SpineGatePerLpmode[0]:Lpmode0.5, SpineGatePerLpmode[1]:Lpmode2, SpineGatePerLpmode[2]:Lpmode3, + SpineGatePerLpmode[3]:Lpmode4 +**/ + UINT8 SpineGatePerLpmode; + +/** Offset 0x0B1C - PhClkGating control per lpmode + PhclkGatePerLpmode[0]:Lpmode0.5, PhclkGatePerLpmode[1]:Lpmode1, PhclkGatePerLpmode[2]:Lpmode2, + PhclkGatePerLpmode[3]:Lpmode3, PhclkGatePerLpmode[4]:Lpmode4 +**/ + UINT8 PhclkGatePerLpmode; + +/** Offset 0x0B1D - DFI Control after cold boot + Disable Switch DFI Control to MC after cold boot: 0(Default)=switch DFI to MC, 1=Keep + with PHY/MPTU + $EN_DIS +**/ + UINT8 DisableSwitchDfiToMc; + +/** Offset 0x0B1E - Enable/Disable SmbusPostcode + Disable (Default): Postcode via Port80, Enable: Postcode via Smbus + $EN_DIS +**/ + UINT8 SmbusPostCodeEnable; + +/** Offset 0x0B1F - SmbusPostcode Address + Slave address for Smbus postcode device +**/ + UINT8 SmbusPostCodeAddress; + +/** Offset 0x0B20 - SmbusPostcode Command + Command value for Smbus postcode device +**/ + UINT8 SmbusPostCodeCommand; /** Offset 0x0B21 - Channel to CKD QCK Mapping Specify Channel to CKD QCK Mapping for CH0D0/CH0D1/CH1D0&CH1D1 @@ -3120,9 +4618,16 @@ typedef struct { **/ UINT8 PhyClockToCkdDimm[8]; -/** Offset 0x0B31 - Reserved +/** Offset 0x0B31 - CKD Address Table + Specify CKD Address table for all DIMMs +**/ + UINT8 CkdAddressTable[16]; + +/** Offset 0x0B41 - Single VDD2 Rail + LP5x VDD2 rail: 0: Dual rail (E-DVFSC is possible), 1: Single rail(No E-DVFSC; VDD2L == VDD2H) + $EN_DIS **/ - UINT8 Reserved93[17]; + UINT8 SingleVdd2Rail; /** Offset 0x0B42 - VDD2 Voltage Voltage is multiple of 5mV where 0 means Auto. @@ -3146,7 +4651,7 @@ typedef struct { /** Offset 0x0B4A - Reserved **/ - UINT8 Reserved94[30]; + UINT8 Reserved47[30]; } FSP_M_CONFIG; /** Fsp M UPD Configuration diff --git a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h index ae0ffe29dd..be67c19c80 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h @@ -104,9 +104,24 @@ typedef struct { **/ UINT64 BiosGuardModulePtr; -/** Offset 0x0080 - Reserved +/** Offset 0x0080 - EcProvisionEav + EcProvisionEav function pointer. \n + @code typedef EFI_STATUS (EFIAPI *EC_PROVISION_EAV) (IN UINT32 Eav, OUT UINT8 + *ReturnValue); @endcode **/ - UINT8 Reserved1[17]; + UINT64 EcProvisionEav; + +/** Offset 0x0088 - EcBiosGuardCmdLock + EcBiosGuardCmdLock function pointer. \n + @code typedef EFI_STATUS (EFIAPI *EC_CMD_LOCK) (OUT UINT8 *ReturnValue); @endcode +**/ + UINT64 EcBiosGuardCmdLock; + +/** Offset 0x0090 - PCH eSPI Host and Device BME enabled + PCH eSPI Host and Device BME enabled + $EN_DIS +**/ + UINT8 PchEspiBmeHostDeviceEnabled; /** Offset 0x0091 - PCH eSPI Link Configuration Lock (SBLCL) Enable/Disable lock of communication through SET_CONFIG/GET_CONFIG to eSPI target @@ -127,9 +142,27 @@ typedef struct { **/ UINT8 PchEspiLgmrEnable; -/** Offset 0x0094 - Reserved +/** Offset 0x0094 - PCH eSPI PmHAE + This option enables or disables espi lgmr + $EN_DIS +**/ + UINT8 PchEspiPmHAE; + +/** Offset 0x0095 - PCH eSPI HideNonFatalErrors + This option enables or disables espi lgmr + $EN_DIS +**/ + UINT8 PchEspiHideNonFatalErrors; + +/** Offset 0x0096 - PCH eSPI NmiEnableCs1 + Set this bit to enable eSPI NMI VW events to be processed by the SOC + $EN_DIS +**/ + UINT8 PchEspiNmiEnableCs1; + +/** Offset 0x0097 - Reserved **/ - UINT8 Reserved2[4]; + UINT8 Reserved1; /** Offset 0x0098 - CpuBistData Pointer CPU BIST Data @@ -151,7 +184,16 @@ typedef struct { /** Offset 0x00A9 - Reserved **/ - UINT8 Reserved3[7]; + UINT8 Reserved2[3]; + +/** Offset 0x00AC - StreamTracer Mode + Disable: Disable StreamTracer, Advanced Tracing: StreamTracer size 512MB - Recommended + when all groups in high verbosity are traced in 'red', Auto: StreamTracer size + 8MB - Recommended when using up to 8 groups red or up to 16 groups in green in + med verbosity, User input: Allow User to enter a size in the range of 64KB-512MB + 0: Disable (Default), 524288: Advanced Tracing , 8192: Auto , 3: User input +**/ + UINT32 StreamTracerMode; /** Offset 0x00B0 - MicrocodeRegionBase Memory Base of Microcode Updates @@ -192,9 +234,12 @@ typedef struct { **/ UINT8 AvxDisable; -/** Offset 0x00C4 - Reserved +/** Offset 0x00C4 - X2ApicEnable + Enable/Disable X2APIC Operating Mode. When this option is configured as 'Enabled', + 'VT-d' option must be 'Enabled'. + $EN_DIS **/ - UINT8 Reserved4; + UINT8 X2ApicEnable; /** Offset 0x00C5 - P-state ratios for max 16 version of custom P-state table P-state ratios for max 16 version of custom P-state table. This table is used for @@ -287,9 +332,17 @@ typedef struct { **/ UINT8 PkgCStateLimit; -/** Offset 0x00E1 - Reserved +/** Offset 0x00E1 - ForcePr Demotion Algorithm configuration + ForcePr Demotion Algorithm configuration. 0: Disable; 1: Enable + 0: Disable, 1: Enable +**/ + UINT8 ForcePrDemotion; + +/** Offset 0x00E2 - VrAlert Demotion Algorithm configuration + VrAlert Demotion Algorithm configuration. 0: Disable; 1: Enable + 0: Disable, 1: Enable **/ - UINT8 Reserved5[2]; + UINT8 VrAlertDemotion; /** Offset 0x00E3 - Interrupt Redirection Mode Select Interrupt Redirection Mode Select for Logical Interrupts. 0: Fixed priority; 1: @@ -303,9 +356,12 @@ typedef struct { **/ UINT8 TurboMode; -/** Offset 0x00E5 - Reserved +/** Offset 0x00E5 - Power Floor PCIe Gen Downgrade + SoC can downgrade PCIe gen speed to lower SoC floor power (Default enabled). 0: + Disable: Reduction in PCIe gen speed will not be used by SoC., 1: Enable + $EN_DIS **/ - UINT8 Reserved6; + UINT8 PowerFloorPcieGenDowngrade; /** Offset 0x00E6 - P-state ratios for custom P-state table P-state ratios for custom P-state table. NumberOfEntries has valid range between @@ -325,9 +381,12 @@ typedef struct { **/ UINT8 MaxRatio; -/** Offset 0x0110 - Reserved +/** Offset 0x0110 - Boot frequency + Select the performance state that the BIOS will set starting from reset vector. + 0: Maximum battery performance. 1: Maximum non-turbo performance. 2: Turbo performance + 0:0, 1:1, 2:2 **/ - UINT8 Reserved7; + UINT8 BootFrequency; /** Offset 0x0111 - Turbo settings Lock Enable/Disable locking of Package Power Limit settings. When enabled, PACKAGE_POWER_LIMIT @@ -337,9 +396,41 @@ typedef struct { **/ UINT8 TurboPowerLimitLock; -/** Offset 0x0112 - Reserved +/** Offset 0x0112 - FastMsrHwpReq + 0: Disable; 1: Enable; + $EN_DIS +**/ + UINT8 EnableFastMsrHwpReq; + +/** Offset 0x0113 - Turbo Ratio Limit Ratio array + Performance-core Turbo Ratio Limit Ratio0-7 (TRLR) defines the turbo ratio (max + is 85 in normal mode and 120 in core extension mode). Ratio[0]: This Turbo Ratio + Limit Ratio0 must be greater than or equal all other ratio values. If this value + is invalid, thn set all other active cores to minimum. Otherwise, align the Ratio + Limit to 0. Please check each active cores. Ratio[1~7]: This Turbo Ratio Limit + Ratio1 must be <= to Turbo Ratio Limit Ratio0~6. +**/ + UINT8 TurboRatioLimitRatio[8]; + +/** Offset 0x011B - Turbo Ratio Limit Num Core array + Performance-core Turbo Ratio Limit Core0~7 defines the core range, the turbo ratio + is defined in Turbo Ratio Limit Ratio0~7. If value is zero, this entry is ignored. +**/ + UINT8 TurboRatioLimitNumCore[8]; + +/** Offset 0x0123 - ATOM Turbo Ratio Limit Ratio array + Efficient-core Turbo Ratio Limit Ratio0-7 defines the turbo ratio (max is 85 irrespective + of the core extension mode), the core range is defined in E-core Turbo Ratio Limit + CoreCount0-7. +**/ + UINT8 AtomTurboRatioLimitRatio[8]; + +/** Offset 0x012B - ATOM Turbo Ratio Limit Num Core array + Efficient-core Turbo Ratio Limit CoreCount0-7 defines the core range, the turbo + ratio is defined in E-core Turbo Ratio Limit Ratio0-7. If value is zero, this entry + is ignored. **/ - UINT8 Reserved8[33]; + UINT8 AtomTurboRatioLimitNumCore[8]; /** Offset 0x0133 - Race To Halt Enable/Disable Race To Halt feature. RTH will dynamically increase CPU frequency @@ -373,9 +464,11 @@ typedef struct { **/ UINT8 MaxRingRatioLimit; -/** Offset 0x0138 - Reserved +/** Offset 0x0138 - Resource Priority Feature + Enable/Disable Resource Priority Feature. Enable/Disable; 0: Disable, 1: Enable + $EN_DIS **/ - UINT8 Reserved9; + UINT8 EnableRp; /** Offset 0x0139 - Enable or Disable HWP Enable/Disable Intel(R) Speed Shift Technology support. Enabling will expose the @@ -406,9 +499,42 @@ typedef struct { **/ UINT8 EnableHwpAutoEppGrouping; -/** Offset 0x013D - Reserved +/** Offset 0x013D - Dynamic Efficiency Control + Enable or Disable SoC to control energy efficiency targets autonomously, regardless + of EPP, EPB and other SW inputs. 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 EnableDynamicEfficiencyControl; + +/** Offset 0x013E - Misc Power Management MSR Lock + Enable/Disable HWP Lock support in Misc Power Management MSR. 0: Disable, 1: + Enable + $EN_DIS +**/ + UINT8 HwpLock; + +/** Offset 0x013F - Power Floor Managment for SOC + Option to disable Power Floor Managment for SOC. Disabling this might effectively + raise power floor of the SoC and may lead to stability issues. 0: Disable, 1: + Enable + $EN_DIS +**/ + UINT8 PowerFloorManagement; + +/** Offset 0x0140 - Power Floor Disaplay Disconnect + SoC can disconnect secondary/external display to lower SoC floor power (Default + disabled). 0: Disable: Display disconnect will not be used by SoC., 1: Enable + $EN_DIS +**/ + UINT8 PowerFloorDisplayDisconnect; + +/** Offset 0x0141 - Memory size per thread allocated for Processor Trace + Memory size per thread for Processor Trace. Processor Trace requires 2^N alignment + and size in bytes per thread, from 4KB to 128MB.\n + 0xff:none , 0:4k, 0x1:8k, 0x2:16k, 0x3:32k, 0x4:64k, 0x5:128k, 0x6:256k, + 0x7:512k, 0x8:1M, 0x9:2M, 0xa:4M. 0xb:8M, 0xc:16M, 0xd:32M, 0xe:64M, 0xf:128M **/ - UINT8 Reserved10[5]; + UINT8 ProcessorTraceMemSize; /** Offset 0x0142 - Enable or Disable MLC Streamer Prefetcher Enable or Disable MLC Streamer Prefetcher; 0: Disable; 1: Enable. @@ -447,9 +573,25 @@ typedef struct { **/ UINT8 ProcessorTraceEnable; -/** Offset 0x0148 - Reserved +/** Offset 0x0148 - Processor trace enabled for Bsp only or all cores + Processor trace enabled for Bsp only or all cores; 0: all cores; 1: Bsp only. + 0: all cores, 1: Bsp only +**/ + UINT8 ProcessorTraceBspOnly; + +/** Offset 0x0149 - Enable/Disable processor trace Timing Packet + Enable/Disable collocting processor trace performance (CYC, TSC); 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 ProcessorTraceTimingPacket; + +/** Offset 0x014A - Enable or Disable Three Strike Counter + Enable (default): Three Strike counter will be incremented. Disable: Prevents Three + Strike counter from incrementing; 0: Disable; 1: Enable + $EN_DIS **/ - UINT8 Reserved11[3]; + UINT8 ThreeStrikeCounter; /** Offset 0x014B - UFS enable/disable Enable/Disable UFS controller, One byte for each Controller - (1,0) to enable controller @@ -466,9 +608,12 @@ typedef struct { **/ UINT8 UfsInlineEncryption[2]; -/** Offset 0x014F - Reserved +/** Offset 0x014F - UFS Connection Status + UFS Connection Status, One byte for each Controller - (1,0) to UFS connected to + controller 0 and (0,1) to UFS connected to controller 1 + $EN_DIS **/ - UINT8 Reserved12[2]; + UINT8 UfsDeviceConnected[2]; /** Offset 0x0151 - Enable/Disable PCIe tunneling for USB4 Enable/Disable PCIe tunneling for USB4, default is enable @@ -478,7 +623,7 @@ typedef struct { /** Offset 0x0152 - Reserved **/ - UINT8 Reserved13[2]; + UINT8 Reserved3[2]; /** Offset 0x0154 - ITBTForcePowerOn Timeout value ITBTForcePowerOn value. Specified increment values in miliseconds. Range is 0-1000. @@ -504,7 +649,12 @@ typedef struct { /** Offset 0x015D - Reserved **/ - UINT8 Reserved14[19]; + UINT8 Reserved4[11]; + +/** Offset 0x0168 - FSPS Validation + Point to FSPS Validation configuration structure +**/ + UINT64 FspsValidationPtr; /** Offset 0x0170 - IEH Mode Integrated Error Handler Mode, 0: Bypass, 1: Enable @@ -563,7 +713,7 @@ typedef struct { /** Offset 0x017B - Reserved **/ - UINT8 Reserved15; + UINT8 Reserved5; /** Offset 0x017C - ISH GP GPIO Pin Muxing Determines ISH GP GPIO Pin muxing. See GPIO_*_MUXING_ISH_GP_x_GPIO_*. 'x' are GP_NUMBER @@ -746,9 +896,11 @@ typedef struct { **/ UINT8 PchIshPdtUnlock; -/** Offset 0x025C - Reserved +/** Offset 0x025C - PCH ISH MSI Interrupts + 0: False; 1: True. + $EN_DIS **/ - UINT8 Reserved16; + UINT8 PchIshMsiInterrupt; /** Offset 0x025D - End of Post message Test, Send End of Post message. Disable(0x0): Disable EOP message, Send in PEI(0x1): @@ -778,9 +930,44 @@ typedef struct { **/ UINT8 MeUnconfigOnRtcClear; -/** Offset 0x0261 - Reserved +/** Offset 0x0261 - CSE Data Resilience Support + 0: Disable CSE Data Resilience Support. 1: Enable CSE Data Resilience Support. + 2: Enable CSE Data Resilience but defer to DXE. + $EN_DIS +**/ + UINT8 CseDataResilience; + +/** Offset 0x0262 - PSE EOM Flow Control + 0: Disable PSE EOM Flow. 1: Enable PSE EOM Flow. + $EN_DIS +**/ + UINT8 PseEomFlowEnable; + +/** Offset 0x0263 - ISH I3C SDA Pin Muxing + Select ISH I3C SDA Pin muxing. Refer to GPIO_*_MUXING_ISH_I3Cx_SDA_* for possible values. **/ - UINT8 Reserved17[22]; + UINT8 IshI3cSdaPinMuxing[8]; + +/** Offset 0x026B - ISH I3C SCL Pin Muxing + Select ISH I3C SCL Pin muxing. Refer to GPIO_*_MUXING_ISH_I3Cx_SCL_* for possible values. +**/ + UINT8 IshI3cSclPinMuxing[8]; + +/** Offset 0x0273 - ISH I3C SDA Pad termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C#N Sda pads termination + respectively. #N-byte for each controller, byte0 for I2C0 Sda, byte1 for I2C1 Sda, + and so on. +**/ + UINT8 IshI3cSdaPadTermination[2]; + +/** Offset 0x0275 - ISH I3C SCL Pad termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C#N Scl pads termination + respectively. #N-byte for each controller, byte0 for I2C0 Scl, byte1 for I2C1 Scl, + and so on. +**/ + UINT8 IshI3cSclPadTermination[2]; /** Offset 0x0277 - Enable PCH ISH I3C pins assigned Set if ISH I3C native pins are to be enabled by BIOS. 0: Disable; 1: Enable. @@ -789,7 +976,7 @@ typedef struct { /** Offset 0x0279 - Reserved **/ - UINT8 Reserved18[3]; + UINT8 Reserved6[3]; /** Offset 0x027C - Power button debounce configuration Debounce time for PWRBTN in microseconds. For values not supported by HW, they will @@ -972,9 +1159,11 @@ typedef struct { **/ UINT8 PmcLpmS0ixSubStateEnableMask; -/** Offset 0x029C - Reserved +/** Offset 0x029C - PCH PMC ER Debug mode + Disable/Enable Energy Reporting Debug Mode. + $EN_DIS **/ - UINT8 Reserved19; + UINT8 PchPmErDebugMode; /** Offset 0x029D - PMC C10 dynamic threshold dajustment enable Set if you want to enable PMC C10 dynamic threshold adjustment. Only works on supported SKUs @@ -1143,9 +1332,11 @@ typedef struct { **/ UINT8 PcieRpAspm[28]; -/** Offset 0x053C - Reserved +/** Offset 0x053C - HostL0sTxDis + Disable Host L0 transmission state + $EN_DIS **/ - UINT8 Reserved20[28]; + UINT8 HostL0sTxDis[28]; /** Offset 0x0558 - PCIE RP L1 Substates The L1 Substates configuration of the root port (see: PCH_PCIE_L1SUBSTATES_CONTROL). @@ -1169,321 +1360,1121 @@ typedef struct { **/ UINT8 PcieEqOverrideDefault[12]; -/** Offset 0x05B8 - Reserved +/** Offset 0x05B8 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq **/ - UINT8 Reserved21[1525]; + UINT8 PcieGen3EqMethod[12]; -/** Offset 0x0BAD - PCIE RP Enable Peer Memory Write - This member describes whether Peer Memory Writes are enabled on the platform. +/** Offset 0x05C4 - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq +**/ + UINT8 PcieGen3EqMode[12]; + +/** Offset 0x05D0 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override $EN_DIS **/ - UINT8 PcieEnablePeerMemoryWrite[12]; + UINT8 PcieGen3EqLocalTxOverrideEn[12]; -/** Offset 0x0BB9 - Assertion on Link Down GPIOs - GPIO Assertion on Link Down. Disabled(0x0)(Default): Disable assertion on Link Down - GPIOs, Enabled(0x1): Enable assertion on Link Down GPIOs - 0:Disable, 1:Enable +/** Offset 0x05DC - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode **/ - UINT8 PcieRpLinkDownGpios[12]; + UINT8 PcieGen3EqPh3NoOfPresetOrCoeff[12]; -/** Offset 0x0BC5 - PCIE Compliance Test Mode - Compliance Test Mode shall be enabled when using Compliance Load Board. - $EN_DIS +/** Offset 0x05E8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieComplianceTestMode; + UINT8 PcieGen3EqPh3PreCursor0List[12]; -/** Offset 0x0BC6 - PCIE Rp Function Swap - Allows BIOS to use root port function number swapping when root port of function - 0 is disabled. - $EN_DIS +/** Offset 0x05F4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpFunctionSwap; + UINT8 PcieGen3EqPh3PostCursor0List[12]; -/** Offset 0x0BC7 - Reserved +/** Offset 0x0600 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved22[12]; + UINT8 PcieGen3EqPh3PreCursor1List[12]; -/** Offset 0x0BD3 - PCIe RootPort Power Gating - Describes whether the PCI Express Power Gating for each root port is enabled by - platform modules. 0: Disable; 1: Enable(Default). - $EN_DIS +/** Offset 0x060C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PciePowerGating[12]; + UINT8 PcieGen3EqPh3PostCursor1List[12]; -/** Offset 0x0BDF - Reserved +/** Offset 0x0618 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved23[49]; + UINT8 PcieGen3EqPh3PreCursor2List[12]; -/** Offset 0x0C10 - PCIE RP Ltr Max Snoop Latency - Latency Tolerance Reporting, Max Snoop Latency. +/** Offset 0x0624 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpLtrMaxSnoopLatency[24]; + UINT8 PcieGen3EqPh3PostCursor2List[12]; -/** Offset 0x0C40 - PCIE RP Ltr Max No Snoop Latency - Latency Tolerance Reporting, Max Non-Snoop Latency. +/** Offset 0x0630 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpLtrMaxNoSnoopLatency[24]; + UINT8 PcieGen3EqPh3PreCursor3List[12]; -/** Offset 0x0C70 - PCIE RP Snoop Latency Override Mode - Latency Tolerance Reporting, Snoop Latency Override Mode. +/** Offset 0x063C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSnoopLatencyOverrideMode[28]; + UINT8 PcieGen3EqPh3PostCursor3List[12]; -/** Offset 0x0C8C - PCIE RP Snoop Latency Override Multiplier - Latency Tolerance Reporting, Snoop Latency Override Multiplier. +/** Offset 0x0648 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSnoopLatencyOverrideMultiplier[28]; + UINT8 PcieGen3EqPh3PreCursor4List[12]; -/** Offset 0x0CA8 - PCIE RP Snoop Latency Override Value - Latency Tolerance Reporting, Snoop Latency Override Value. +/** Offset 0x0654 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpSnoopLatencyOverrideValue[24]; + UINT8 PcieGen3EqPh3PostCursor4List[12]; -/** Offset 0x0CD8 - PCIE RP Non Snoop Latency Override Mode - Latency Tolerance Reporting, Non-Snoop Latency Override Mode. +/** Offset 0x0660 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpNonSnoopLatencyOverrideMode[28]; + UINT8 PcieGen3EqPh3PreCursor5List[12]; -/** Offset 0x0CF4 - PCIE RP Non Snoop Latency Override Multiplier - Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier. +/** Offset 0x066C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpNonSnoopLatencyOverrideMultiplier[28]; + UINT8 PcieGen3EqPh3PostCursor5List[12]; -/** Offset 0x0D10 - PCIE RP Non Snoop Latency Override Value - Latency Tolerance Reporting, Non-Snoop Latency Override Value. +/** Offset 0x0678 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpNonSnoopLatencyOverrideValue[24]; + UINT8 PcieGen3EqPh3PreCursor6List[12]; -/** Offset 0x0D40 - PCIE RP Slot Power Limit Scale - Specifies scale used for slot power limit value. Leave as 0 to set to default. +/** Offset 0x0684 - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSlotPowerLimitScale[28]; + UINT8 PcieGen3EqPh3PostCursor6List[12]; -/** Offset 0x0D5C - PCIE RP Slot Power Limit Value - Specifies upper limit on power supplie by slot. Leave as 0 to set to default. +/** Offset 0x0690 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpSlotPowerLimitValue[24]; + UINT8 PcieGen3EqPh3PreCursor7List[12]; -/** Offset 0x0D8C - PCIE RP Enable Port8xh Decode - This member describes whether PCIE root port Port 8xh Decode is enabled. 0: Disable; - 1: Enable. - $EN_DIS +/** Offset 0x069C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieEnablePort8xhDecode; + UINT8 PcieGen3EqPh3PostCursor7List[12]; -/** Offset 0x0D8D - PCIE Port8xh Decode Port Index - The Index of PCIe Port that is selected for Port8xh Decode (1 Based). +/** Offset 0x06A8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PchPciePort8xhDecodePortIndex; + UINT8 PcieGen3EqPh3PreCursor8List[12]; -/** Offset 0x0D8E - Reserved +/** Offset 0x06B4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved24[114]; + UINT8 PcieGen3EqPh3PostCursor8List[12]; -/** Offset 0x0E00 - SPIn Device Mode - Selects SPI operation mode. N represents controller index: SPI0, SPI1, ... Available - modes: 0:LpssSpiDisabled, 1:LpssSpiPci, 2:LpssSpiHidden +/** Offset 0x06C0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiMode[7]; + UINT8 PcieGen3EqPh3PreCursor9List[12]; -/** Offset 0x0E07 - Reserved +/** Offset 0x06CC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved25[85]; + UINT8 PcieGen3EqPh3PostCursor9List[12]; -/** Offset 0x0E5C - SPIn Default Chip Select Mode HW/SW - Sets Default CS Mode Hardware or Software. N represents controller index: SPI0, - SPI1, ... Available options: 0:HW, 1:SW +/** Offset 0x06D8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiCsMode[7]; + UINT8 PcieGen3EqPh3Preset0List[12]; -/** Offset 0x0E63 - SPIn Default Chip Select State Low/High - Sets Default CS State Low or High. N represents controller index: SPI0, SPI1, ... - Available options: 0:Low, 1:High +/** Offset 0x06E4 - PCIe preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiCsState[7]; + UINT8 PcieGen3EqPh3Preset1List[12]; -/** Offset 0x0E6A - UARTn Device Mode - Selects Uart operation mode. N represents controller index: Uart0, Uart1, ... Available - modes: 0:SerialIoUartDisabled, 1:SerialIoUartPci, 2:SerialIoUartHidden, 3:SerialIoUartCom, - 4:SerialIoUartSkipInit +/** Offset 0x06F0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartMode[7]; + UINT8 PcieGen3EqPh3Preset2List[12]; -/** Offset 0x0E71 - Reserved +/** Offset 0x06FC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 Reserved26[3]; + UINT8 PcieGen3EqPh3Preset3List[12]; -/** Offset 0x0E74 - Default BaudRate for each Serial IO UART - Set default BaudRate Supported from 0 - default to 6000000 +/** Offset 0x0708 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT32 SerialIoUartBaudRate[7]; + UINT8 PcieGen3EqPh3Preset4List[12]; -/** Offset 0x0E90 - Default ParityType for each Serial IO UART - Set default Parity. 0: DefaultParity, 1: NoParity, 2: EvenParity, 3: OddParity +/** Offset 0x0714 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartParity[7]; + UINT8 PcieGen3EqPh3Preset5List[12]; -/** Offset 0x0E97 - Default DataBits for each Serial IO UART - Set default word length. 0: Default, 5,6,7,8 +/** Offset 0x0720 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartDataBits[7]; + UINT8 PcieGen3EqPh3Preset6List[12]; -/** Offset 0x0E9E - Default StopBits for each Serial IO UART - Set default stop bits. 0: DefaultStopBits, 1: OneStopBit, 2: OneFiveStopBits, 3: - TwoStopBits +/** Offset 0x072C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartStopBits[7]; + UINT8 PcieGen3EqPh3Preset7List[12]; -/** Offset 0x0EA5 - Power Gating mode for each Serial IO UART that works in COM mode - Set Power Gating. 0: Disabled, 1: Enabled, 2: Auto +/** Offset 0x0738 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartPowerGating[7]; + UINT8 PcieGen3EqPh3Preset8List[12]; -/** Offset 0x0EAC - Enable Dma for each Serial IO UART that supports it - Set DMA/PIO mode. 0: Disabled, 1: Enabled +/** Offset 0x0744 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartDmaEnable[7]; + UINT8 PcieGen3EqPh3Preset9List[12]; -/** Offset 0x0EB3 - Enables UART hardware flow control, CTS and RTS lines - Enables UART hardware flow control, CTS and RTS lines. +/** Offset 0x0750 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartAutoFlow[7]; + UINT8 PcieGen3EqPh3Preset10List[12]; -/** Offset 0x0EBA - Reserved +/** Offset 0x075C - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization **/ - UINT8 Reserved27[2]; + UINT8 PcieGen3EqPh1DpTxPreset[12]; -/** Offset 0x0EBC - SerialIoUartRtsPinMuxPolicy - Select SerialIo Uart Rts pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RTS* - for possible values. +/** Offset 0x0768 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization **/ - UINT32 SerialIoUartRtsPinMuxPolicy[7]; + UINT8 PcieGen3EqPh1UpTxPreset[12]; -/** Offset 0x0ED8 - SerialIoUartRxPinMuxPolicy - Select SerialIo Uart Rx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RX* for - possible values. +/** Offset 0x0774 - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override **/ - UINT32 SerialIoUartRxPinMuxPolicy[7]; + UINT8 PcieGen3EqPh2LocalTxOverridePreset[12]; -/** Offset 0x0EF4 - SerialIoUartTxPinMuxPolicy - Select SerialIo Uart Tx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_TX* for - possible values. +/** Offset 0x0780 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq **/ - UINT32 SerialIoUartTxPinMuxPolicy[7]; + UINT8 PcieGen4EqMethod[12]; -/** Offset 0x0F10 - Serial IO UART DBG2 table - Enable or disable Serial Io UART DBG2 table, default is Disable; 0: Disable; - 1: Enable. +/** Offset 0x078C - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq **/ - UINT8 SerialIoUartDbg2[7]; + UINT8 PcieGen4EqMode[12]; -/** Offset 0x0F17 - Reserved +/** Offset 0x0798 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override + $EN_DIS **/ - UINT8 Reserved28[7]; + UINT8 PcieGen4EqLocalTxOverrideEn[12]; -/** Offset 0x0F1E - I2Cn Device Mode - Selects I2c operation mode. N represents controller index: I2c0, I2c1, ... Available - modes: 0:SerialIoI2cDisabled, 1:SerialIoI2cPci, 2:SerialIoI2cHidden +/** Offset 0x07A4 - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode **/ - UINT8 SerialIoI2cMode[8]; + UINT8 PcieGen4EqPh3NoOfPresetOrCoeff[12]; -/** Offset 0x0F26 - Reserved +/** Offset 0x07B0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved29[2]; + UINT8 PcieGen4EqPh3PreCursor0List[12]; -/** Offset 0x0F28 - Serial IO I2C SDA Pin Muxing - Select SerialIo I2c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SDA* for - possible values. +/** Offset 0x07BC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT32 PchSerialIoI2cSdaPinMux[8]; + UINT8 PcieGen4EqPh3PostCursor0List[12]; -/** Offset 0x0F48 - Serial IO I2C SCL Pin Muxing - Select SerialIo I2c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SCL* for - possible values. +/** Offset 0x07C8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT32 PchSerialIoI2cSclPinMux[8]; + UINT8 PcieGen4EqPh3PreCursor1List[12]; -/** Offset 0x0F68 - PCH SerialIo I2C Pads Termination - 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, - 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C0,I2C1,... pads termination - respectively. One byte for each controller, byte0 for I2C0, byte1 for I2C1, and so on. +/** Offset 0x07D4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PchSerialIoI2cPadsTermination[8]; + UINT8 PcieGen4EqPh3PostCursor1List[12]; -/** Offset 0x0F70 - I3C Device Mode - Selects I3c operation mode. Available modes: 0:SerialIoI3cDisabled, 1:SerialIoI3cPci, - 2:SerialIoI3cPhantom (only applicable to I3C1, controlls GPIO enabling) +/** Offset 0x07E0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 SerialIoI3cMode[3]; + UINT8 PcieGen4EqPh3PreCursor2List[12]; -/** Offset 0x0F73 - Reserved +/** Offset 0x07EC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved30[48]; + UINT8 PcieGen4EqPh3PostCursor2List[12]; -/** Offset 0x0FA3 - Enable VMD controller - Enable/disable to VMD controller.0: Disable; 1: Enable(Default) - $EN_DIS +/** Offset 0x07F8 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdEnable; + UINT8 PcieGen4EqPh3PreCursor3List[12]; -/** Offset 0x0FA4 - Enable VMD Global Mapping - Enable/disable to VMD controller.0: Disable(Default); 1: Enable - $EN_DIS +/** Offset 0x0804 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdGlobalMapping; + UINT8 PcieGen4EqPh3PostCursor3List[12]; -/** Offset 0x0FA5 - Map port under VMD - Map/UnMap port under VMD - $EN_DIS +/** Offset 0x0810 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPort[31]; + UINT8 PcieGen4EqPh3PreCursor4List[12]; -/** Offset 0x0FC4 - Reserved +/** Offset 0x081C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved31[31]; + UINT8 PcieGen4EqPh3PostCursor4List[12]; -/** Offset 0x0FE3 - VMD Port Device - VMD Root port device number. +/** Offset 0x0828 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPortDev[31]; + UINT8 PcieGen4EqPh3PreCursor5List[12]; -/** Offset 0x1002 - VMD Port Func - VMD Root port function number. +/** Offset 0x0834 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPortFunc[31]; + UINT8 PcieGen4EqPh3PostCursor5List[12]; -/** Offset 0x1021 - Reserved +/** Offset 0x0840 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved32[7]; + UINT8 PcieGen4EqPh3PreCursor6List[12]; -/** Offset 0x1028 - VMD Variable - VMD Variable Pointer. +/** Offset 0x084C - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT64 VmdVariablePtr; + UINT8 PcieGen4EqPh3PostCursor6List[12]; -/** Offset 0x1030 - Reserved +/** Offset 0x0858 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved33[4]; + UINT8 PcieGen4EqPh3PreCursor7List[12]; -/** Offset 0x1034 - Temporary MemBar1 address for VMD - VMD Variable Pointer. +/** Offset 0x0864 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT32 VmdMemBar1Base; + UINT8 PcieGen4EqPh3PostCursor7List[12]; -/** Offset 0x1038 - Temporary MemBar2 address for VMD - VMD Variable Pointer. +/** Offset 0x0870 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT32 VmdMemBar2Base; + UINT8 PcieGen4EqPh3PreCursor8List[12]; -/** Offset 0x103C - Enable D3 Hot in TCSS +/** Offset 0x087C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PostCursor8List[12]; + +/** Offset 0x0888 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PreCursor9List[12]; + +/** Offset 0x0894 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PostCursor9List[12]; + +/** Offset 0x08A0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset0List[12]; + +/** Offset 0x08AC - PCIe preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset1List[12]; + +/** Offset 0x08B8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset2List[12]; + +/** Offset 0x08C4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset3List[12]; + +/** Offset 0x08D0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset4List[12]; + +/** Offset 0x08DC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset5List[12]; + +/** Offset 0x08E8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset6List[12]; + +/** Offset 0x08F4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset7List[12]; + +/** Offset 0x0900 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset8List[12]; + +/** Offset 0x090C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset9List[12]; + +/** Offset 0x0918 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset10List[12]; + +/** Offset 0x0924 - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization +**/ + UINT8 PcieGen4EqPh1DpTxPreset[12]; + +/** Offset 0x0930 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization +**/ + UINT8 PcieGen4EqPh1UpTxPreset[12]; + +/** Offset 0x093C - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override +**/ + UINT8 PcieGen4EqPh2LocalTxOverridePreset[12]; + +/** Offset 0x0948 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq +**/ + UINT8 PcieGen5EqMethod[12]; + +/** Offset 0x0954 - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq +**/ + UINT8 PcieGen5EqMode[12]; + +/** Offset 0x0960 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override + $EN_DIS +**/ + UINT8 PcieGen5EqLocalTxOverrideEn[12]; + +/** Offset 0x096C - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode +**/ + UINT8 PcieGen5EqPh3NoOfPresetOrCoeff[12]; + +/** Offset 0x0978 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor0List[12]; + +/** Offset 0x0984 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor0List[12]; + +/** Offset 0x0990 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor1List[12]; + +/** Offset 0x099C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor1List[12]; + +/** Offset 0x09A8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor2List[12]; + +/** Offset 0x09B4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor2List[12]; + +/** Offset 0x09C0 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor3List[12]; + +/** Offset 0x09CC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor3List[12]; + +/** Offset 0x09D8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor4List[12]; + +/** Offset 0x09E4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor4List[12]; + +/** Offset 0x09F0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor5List[12]; + +/** Offset 0x09FC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor5List[12]; + +/** Offset 0x0A08 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor6List[12]; + +/** Offset 0x0A14 - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor6List[12]; + +/** Offset 0x0A20 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor7List[12]; + +/** Offset 0x0A2C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor7List[12]; + +/** Offset 0x0A38 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor8List[12]; + +/** Offset 0x0A44 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor8List[12]; + +/** Offset 0x0A50 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor9List[12]; + +/** Offset 0x0A5C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor9List[12]; + +/** Offset 0x0A68 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset0List[12]; + +/** Offset 0x0A74 - PCIe preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset1List[12]; + +/** Offset 0x0A80 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset2List[12]; + +/** Offset 0x0A8C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset3List[12]; + +/** Offset 0x0A98 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset4List[12]; + +/** Offset 0x0AA4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset5List[12]; + +/** Offset 0x0AB0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset6List[12]; + +/** Offset 0x0ABC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset7List[12]; + +/** Offset 0x0AC8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset8List[12]; + +/** Offset 0x0AD4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset9List[12]; + +/** Offset 0x0AE0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset10List[12]; + +/** Offset 0x0AEC - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization +**/ + UINT8 PcieGen5EqPh1DpTxPreset[12]; + +/** Offset 0x0AF8 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization +**/ + UINT8 PcieGen5EqPh1UpTxPreset[12]; + +/** Offset 0x0B04 - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override +**/ + UINT8 PcieGen5EqPh2LocalTxOverridePreset[12]; + +/** Offset 0x0B10 - Phase3 RP Gen3 EQ enable + Phase3 Gen3 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen3EqPh3Bypass[12]; + +/** Offset 0x0B1C - Phase3 RP Gen4 EQ enable + Phase3 Gen4 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen4EqPh3Bypass[12]; + +/** Offset 0x0B28 - Phase3 RP Gen5 EQ enable + Phase3 Gen5 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen5EqPh3Bypass[12]; + +/** Offset 0x0B34 - Phase2-3 RP Gen3 EQ enable + Phase2-3 Gen3 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen3EqPh23Bypass[12]; + +/** Offset 0x0B40 - Phase2-3 RP Gen4 EQ enable + Phase2-3 Gen4 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen4EqPh23Bypass[12]; + +/** Offset 0x0B4C - Phase2-3 RP Gen5 EQ enable + Phase2-3 Gen5 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen5EqPh23Bypass[12]; + +/** Offset 0x0B58 - PCET Timer + Preset/Coefficient Evaluation Timeout Gen3 PCET Timer. See PCIE_GEN3_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen3PcetTimer[12]; + +/** Offset 0x0B64 - Gen4 PCET Timer + Preset/Coefficient Evaluation Timeout - Gen4 PCET Timer. See PCIE_GEN4_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen4PcetTimer[12]; + +/** Offset 0x0B70 - Gen5 PCET Timer + Preset/Coefficient Evaluation Timeout - Gen5 PCET Timer. See PCIE_GEN5_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen5PcetTimer[12]; + +/** Offset 0x0B7C - TS Lock Timer for Gen3 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen3 TS Lock + Timer. See PCIE_GEN3_TS_LOCK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen3TsLockTimer[12]; + +/** Offset 0x0B88 - PTS Lock Timer for Gen4 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen4 TS Lock + Timer. See PCIE_GEN4_TS_LCOK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen4TsLockTimer[12]; + +/** Offset 0x0B94 - PTS Lock Timer for Gen5 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen5 TS Lock + Timer. See PCIE_GEN5_TS_LCOK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen5TsLockTimer[12]; + +/** Offset 0x0BA0 - PCIE Secure Register Lock + Describes whether Secure Register Lock is enaled or disabled. When it will be enbaled, + load PcieRpSetSecuredRegisterLock recipe. 0: Disable(Default); 1: Enable + $EN_DIS +**/ + UINT8 PcieSetSecuredRegisterLock; + +/** Offset 0x0BA1 - Enable/Disable ASPM Optionality Compliance + Enable/Disable ASPM Optionality Compliance. +**/ + UINT8 PcieRpTestAspmOc[12]; + +/** Offset 0x0BAD - PCIE RP Enable Peer Memory Write + This member describes whether Peer Memory Writes are enabled on the platform. + $EN_DIS +**/ + UINT8 PcieEnablePeerMemoryWrite[12]; + +/** Offset 0x0BB9 - Assertion on Link Down GPIOs + GPIO Assertion on Link Down. Disabled(0x0)(Default): Disable assertion on Link Down + GPIOs, Enabled(0x1): Enable assertion on Link Down GPIOs + 0:Disable, 1:Enable +**/ + UINT8 PcieRpLinkDownGpios[12]; + +/** Offset 0x0BC5 - PCIE Compliance Test Mode + Compliance Test Mode shall be enabled when using Compliance Load Board. + $EN_DIS +**/ + UINT8 PcieComplianceTestMode; + +/** Offset 0x0BC6 - PCIE Rp Function Swap + Allows BIOS to use root port function number swapping when root port of function + 0 is disabled. + $EN_DIS +**/ + UINT8 PcieRpFunctionSwap; + +/** Offset 0x0BC7 - PCIe RootPort Clock Gating + Describes whether the PCI Express Clock Gating for each root port is enabled by + platform modules. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieClockGating[12]; + +/** Offset 0x0BD3 - PCIe RootPort Power Gating + Describes whether the PCI Express Power Gating for each root port is enabled by + platform modules. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PciePowerGating[12]; + +/** Offset 0x0BDF - PCIe RootPort VISA Clock Gating + Describes whether the PCI Express VISA Clock Gating. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieVisaClockGating[12]; + +/** Offset 0x0BEB - PCIe RootPort AutoPower Gating + Describes the Auto Power Gating for per controller. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieAutoPowerGating[12]; + +/** Offset 0x0BF7 - PCIe RootPort PHY AutoPower Gating + Describes the PHY Auto Power Gating for per controller. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PciePhyAutoPowerGating; + +/** Offset 0x0BF8 - FOMS Control Policy + Choose the Foms Control Policy, Default = 0 + 0: Auto, 1: Gen3 Foms, 2: Gen4 Foms, 3: Gen3 and Gen4 Foms +**/ + UINT8 PcieFomsCp[12]; + +/** Offset 0x0C04 - EqPhBypass Control Policy + PCIe Equalization Phase Enable Control, Disabled (0x0) : Disable Phase + (Default), Enabled (0x1) : Enable Phase + 0: Auto, 1: Gen3 Foms, 2: Gen4 Foms, 3: Gen3 and Gen4 Foms +**/ + UINT8 PcieEqPhBypass[12]; + +/** Offset 0x0C10 - PCIE RP Ltr Max Snoop Latency + Latency Tolerance Reporting, Max Snoop Latency. +**/ + UINT16 PcieRpLtrMaxSnoopLatency[24]; + +/** Offset 0x0C40 - PCIE RP Ltr Max No Snoop Latency + Latency Tolerance Reporting, Max Non-Snoop Latency. +**/ + UINT16 PcieRpLtrMaxNoSnoopLatency[24]; + +/** Offset 0x0C70 - PCIE RP Snoop Latency Override Mode + Latency Tolerance Reporting, Snoop Latency Override Mode. +**/ + UINT8 PcieRpSnoopLatencyOverrideMode[28]; + +/** Offset 0x0C8C - PCIE RP Snoop Latency Override Multiplier + Latency Tolerance Reporting, Snoop Latency Override Multiplier. +**/ + UINT8 PcieRpSnoopLatencyOverrideMultiplier[28]; + +/** Offset 0x0CA8 - PCIE RP Snoop Latency Override Value + Latency Tolerance Reporting, Snoop Latency Override Value. +**/ + UINT16 PcieRpSnoopLatencyOverrideValue[24]; + +/** Offset 0x0CD8 - PCIE RP Non Snoop Latency Override Mode + Latency Tolerance Reporting, Non-Snoop Latency Override Mode. +**/ + UINT8 PcieRpNonSnoopLatencyOverrideMode[28]; + +/** Offset 0x0CF4 - PCIE RP Non Snoop Latency Override Multiplier + Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier. +**/ + UINT8 PcieRpNonSnoopLatencyOverrideMultiplier[28]; + +/** Offset 0x0D10 - PCIE RP Non Snoop Latency Override Value + Latency Tolerance Reporting, Non-Snoop Latency Override Value. +**/ + UINT16 PcieRpNonSnoopLatencyOverrideValue[24]; + +/** Offset 0x0D40 - PCIE RP Slot Power Limit Scale + Specifies scale used for slot power limit value. Leave as 0 to set to default. +**/ + UINT8 PcieRpSlotPowerLimitScale[28]; + +/** Offset 0x0D5C - PCIE RP Slot Power Limit Value + Specifies upper limit on power supplie by slot. Leave as 0 to set to default. +**/ + UINT16 PcieRpSlotPowerLimitValue[24]; + +/** Offset 0x0D8C - PCIE RP Enable Port8xh Decode + This member describes whether PCIE root port Port 8xh Decode is enabled. 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 PcieEnablePort8xhDecode; + +/** Offset 0x0D8D - PCIE Port8xh Decode Port Index + The Index of PCIe Port that is selected for Port8xh Decode (1 Based). +**/ + UINT8 PchPciePort8xhDecodePortIndex; + +/** Offset 0x0D8E - PCIE RP LTR Override Spec Compliant + Override LTR based on Ep capability. +**/ + UINT8 PcieRpLtrOverrideSpecCompliant[28]; + +/** Offset 0x0DAA - PCIe AER _OSC Setting + Enable/Disable Global PCIe Advanced Error Reporting + 0:Disable, 1:Enable +**/ + UINT8 GlobalPcieAer; + +/** Offset 0x0DAB - PCIe TBT Performance Boost Bitmap + Bitmap of TBT performance boost enabled PCIe controllers to which discrete TBT controllers + connect. Bit0: PXPA, Bit1: PXPB, Bit2: PXPC, Bit3: PXPD, Bit4: PXPE +**/ + UINT8 PcieTbtPerfBoost; + +/** Offset 0x0DAC - Serial IO SPI CLK Pin Muxing + Select SerialIo LPSS SPI CS pin muxing. Refer to GPIO_*_MUXING_SERIALIO_SPIx_CLK* + for possible values. +**/ + UINT32 SerialIoLpssSpiClkPinMux[7]; + +/** Offset 0x0DC8 - Serial IO SPI CS Pin Muxing + Select SerialIo LPSS SPI CS pin muxing. Refer to GPIO_*_MUXING_SERIALIO_SPIx_CS* + for possible values. +**/ + UINT32 SerialIoLpssSpiCsPinMux[14]; + +/** Offset 0x0E00 - SPIn Device Mode + Selects SPI operation mode. N represents controller index: SPI0, SPI1, ... Available + modes: 0:LpssSpiDisabled, 1:LpssSpiPci, 2:LpssSpiHidden +**/ + UINT8 SerialIoLpssSpiMode[7]; + +/** Offset 0x0E07 - Reserved +**/ + UINT8 Reserved7; + +/** Offset 0x0E08 - LPSS SPI MOSI Pin Muxing + Select LPSS SPI MOSI pin muxing. Refer to GPIO_*_MUXING_LPSS_SPIx_MOSI* for possible values. +**/ + UINT32 SerialIoLpssSpiMosiPinMux[7]; + +/** Offset 0x0E24 - LPSS SPI MISO Pin Muxing + Select Lpss SPI MISO pin muxing. Refer to GPIO_*_MUXING_LPSS_SPIx_MISO* for possible values. +**/ + UINT32 SerialIoLpssSpiMisoPinMux[7]; + +/** Offset 0x0E40 - SPI Chip Select Polarity + Sets polarity for each chip Select. Available options: 0:LpssSpiCsActiveLow, 1:LpssSpiCsActiveHigh +**/ + UINT8 SerialIoLpssSpiCsPolarity[14]; + +/** Offset 0x0E4E - SPI Chip Select Enable + 0:Disabled, 1:Enabled. Enables GPIO for CS0 or CS1 if it is Enabled +**/ + UINT8 SerialIoLpssSpiCsEnable[14]; + +/** Offset 0x0E5C - SPIn Default Chip Select Mode HW/SW + Sets Default CS Mode Hardware or Software. N represents controller index: SPI0, + SPI1, ... Available options: 0:HW, 1:SW +**/ + UINT8 SerialIoLpssSpiCsMode[7]; + +/** Offset 0x0E63 - SPIn Default Chip Select State Low/High + Sets Default CS State Low or High. N represents controller index: SPI0, SPI1, ... + Available options: 0:Low, 1:High +**/ + UINT8 SerialIoLpssSpiCsState[7]; + +/** Offset 0x0E6A - UARTn Device Mode + Selects Uart operation mode. N represents controller index: Uart0, Uart1, ... Available + modes: 0:SerialIoUartDisabled, 1:SerialIoUartPci, 2:SerialIoUartHidden, 3:SerialIoUartCom, + 4:SerialIoUartSkipInit +**/ + UINT8 SerialIoUartMode[7]; + +/** Offset 0x0E71 - Reserved +**/ + UINT8 Reserved8[3]; + +/** Offset 0x0E74 - Default BaudRate for each Serial IO UART + Set default BaudRate Supported from 0 - default to 6000000 +**/ + UINT32 SerialIoUartBaudRate[7]; + +/** Offset 0x0E90 - Default ParityType for each Serial IO UART + Set default Parity. 0: DefaultParity, 1: NoParity, 2: EvenParity, 3: OddParity +**/ + UINT8 SerialIoUartParity[7]; + +/** Offset 0x0E97 - Default DataBits for each Serial IO UART + Set default word length. 0: Default, 5,6,7,8 +**/ + UINT8 SerialIoUartDataBits[7]; + +/** Offset 0x0E9E - Default StopBits for each Serial IO UART + Set default stop bits. 0: DefaultStopBits, 1: OneStopBit, 2: OneFiveStopBits, 3: + TwoStopBits +**/ + UINT8 SerialIoUartStopBits[7]; + +/** Offset 0x0EA5 - Power Gating mode for each Serial IO UART that works in COM mode + Set Power Gating. 0: Disabled, 1: Enabled, 2: Auto +**/ + UINT8 SerialIoUartPowerGating[7]; + +/** Offset 0x0EAC - Enable Dma for each Serial IO UART that supports it + Set DMA/PIO mode. 0: Disabled, 1: Enabled +**/ + UINT8 SerialIoUartDmaEnable[7]; + +/** Offset 0x0EB3 - Enables UART hardware flow control, CTS and RTS lines + Enables UART hardware flow control, CTS and RTS lines. +**/ + UINT8 SerialIoUartAutoFlow[7]; + +/** Offset 0x0EBA - Reserved +**/ + UINT8 Reserved9[2]; + +/** Offset 0x0EBC - SerialIoUartRtsPinMuxPolicy + Select SerialIo Uart Rts pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RTS* + for possible values. +**/ + UINT32 SerialIoUartRtsPinMuxPolicy[7]; + +/** Offset 0x0ED8 - SerialIoUartRxPinMuxPolicy + Select SerialIo Uart Rx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RX* for + possible values. +**/ + UINT32 SerialIoUartRxPinMuxPolicy[7]; + +/** Offset 0x0EF4 - SerialIoUartTxPinMuxPolicy + Select SerialIo Uart Tx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_TX* for + possible values. +**/ + UINT32 SerialIoUartTxPinMuxPolicy[7]; + +/** Offset 0x0F10 - Serial IO UART DBG2 table + Enable or disable Serial Io UART DBG2 table, default is Disable; 0: Disable; + 1: Enable. +**/ + UINT8 SerialIoUartDbg2[7]; + +/** Offset 0x0F17 - Serial IO UART PG DBG2 table + Enable or disable Serial Io UART PG DBG2 table, default is Disable; 0: Disable; + 1: Enable. +**/ + UINT8 SerialIoUartPgDbg2[7]; + +/** Offset 0x0F1E - I2Cn Device Mode + Selects I2c operation mode. N represents controller index: I2c0, I2c1, ... Available + modes: 0:SerialIoI2cDisabled, 1:SerialIoI2cPci, 2:SerialIoI2cHidden +**/ + UINT8 SerialIoI2cMode[8]; + +/** Offset 0x0F26 - Reserved +**/ + UINT8 Reserved10[2]; + +/** Offset 0x0F28 - Serial IO I2C SDA Pin Muxing + Select SerialIo I2c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SDA* for + possible values. +**/ + UINT32 PchSerialIoI2cSdaPinMux[8]; + +/** Offset 0x0F48 - Serial IO I2C SCL Pin Muxing + Select SerialIo I2c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SCL* for + possible values. +**/ + UINT32 PchSerialIoI2cSclPinMux[8]; + +/** Offset 0x0F68 - PCH SerialIo I2C Pads Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C0,I2C1,... pads termination + respectively. One byte for each controller, byte0 for I2C0, byte1 for I2C1, and so on. +**/ + UINT8 PchSerialIoI2cPadsTermination[8]; + +/** Offset 0x0F70 - I3C Device Mode + Selects I3c operation mode. Available modes: 0:SerialIoI3cDisabled, 1:SerialIoI3cPci, + 2:SerialIoI3cPhantom (only applicable to I3C1, controlls GPIO enabling) +**/ + UINT8 SerialIoI3cMode[3]; + +/** Offset 0x0F73 - Reserved +**/ + UINT8 Reserved11; + +/** Offset 0x0F74 - Serial IO I3C SDA Pin Muxing + Select SerialIo I3c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SDA* for + possible values. +**/ + UINT32 SerialIoI3cSdaPinMux[3]; + +/** Offset 0x0F80 - Serial IO I3C SDA Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSdaPadTermination[3]; + +/** Offset 0x0F83 - Reserved +**/ + UINT8 Reserved12; + +/** Offset 0x0F84 - Serial IO I3C SCL Pin Muxing + Select SerialIo I3c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SCL* for + possible values. +**/ + UINT32 SerialIoI3cSclPinMux[3]; + +/** Offset 0x0F90 - Serial IO I3C SCL Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSclPadTermination[3]; + +/** Offset 0x0F93 - Reserved +**/ + UINT8 Reserved13; + +/** Offset 0x0F94 - Serial IO I3C SCL FB Pin Muxing + Select SerialIo I3c SclFb pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SCL FB* + for possible values. +**/ + UINT32 SerialIoI3cSclFbPinMux[3]; + +/** Offset 0x0FA0 - Serial IO I3C SCL FB Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSclFbPadTermination[3]; + +/** Offset 0x0FA3 - Enable VMD controller + Enable/disable to VMD controller.0: Disable; 1: Enable(Default) + $EN_DIS +**/ + UINT8 VmdEnable; + +/** Offset 0x0FA4 - Enable VMD Global Mapping + Enable/disable to VMD controller.0: Disable(Default); 1: Enable + $EN_DIS +**/ + UINT8 VmdGlobalMapping; + +/** Offset 0x0FA5 - Map port under VMD + Map/UnMap port under VMD + $EN_DIS +**/ + UINT8 VmdPort[31]; + +/** Offset 0x0FC4 - VMD Port Bus + VMD Root port bus number. +**/ + UINT8 VmdPortBus[31]; + +/** Offset 0x0FE3 - VMD Port Device + VMD Root port device number. +**/ + UINT8 VmdPortDev[31]; + +/** Offset 0x1002 - VMD Port Func + VMD Root port function number. +**/ + UINT8 VmdPortFunc[31]; + +/** Offset 0x1021 - Reserved +**/ + UINT8 Reserved14[7]; + +/** Offset 0x1028 - VMD Variable + VMD Variable Pointer. +**/ + UINT64 VmdVariablePtr; + +/** Offset 0x1030 - Temporary CfgBar address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdCfgBarBase; + +/** Offset 0x1034 - Temporary MemBar1 address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdMemBar1Base; + +/** Offset 0x1038 - Temporary MemBar2 address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdMemBar2Base; + +/** Offset 0x103C - Enable D3 Hot in TCSS This policy will enable/disable D3 hot support in IOM $EN_DIS **/ UINT8 D3HotEnable; -/** Offset 0x103D - Reserved +/** Offset 0x103D - TCSS TBT Performance Boost Bitmap + Bitmap of TBT performance boost enabled TCSS PCIe root ports. Bit0: TCSS port0, + Bit1: TCSS port1, Bit2: TCSS port2, Bit3: TCSS port3 **/ - UINT8 Reserved34[3]; + UINT8 TcssTbtPerfBoost; + +/** Offset 0x103E - Reserved +**/ + UINT8 Reserved15[2]; /** Offset 0x1040 - TypeC port GPIO setting GPIO Ping number for Type C Aux orientation setting, use the GpioPad that is defined @@ -1508,9 +2499,17 @@ typedef struct { **/ UINT8 TcCstateLimit; -/** Offset 0x107C - Reserved +/** Offset 0x107C - TC Notify Igd + Tc Notify Igd **/ - UINT8 Reserved35[2]; + UINT8 TcNotifyIgd; + +/** Offset 0x107D - TCSS CPU USB PDO Programming + Enable/disable PDO programming for TCSS CPU USB in PEI phase. Disabling will allow + for programming during later phase. 1: enable, 0: disable + $EN_DIS +**/ + UINT8 TcssCpuUsbPdoProgramming; /** Offset 0x107E - Enable/Disable PMC-PD Solution This policy will enable/disable PMC-PD Solution vs EC-TCPC Solution @@ -1520,7 +2519,7 @@ typedef struct { /** Offset 0x107F - Reserved **/ - UINT8 Reserved36; + UINT8 Reserved16; /** Offset 0x1080 - TCSS Aux Orientation Override Enable Bits 0, 2, ... 10 control override enables, bits 1, 3, ... 11 control overrides @@ -1594,9 +2593,11 @@ typedef struct { **/ UINT8 SaPcieItbtRpLtrConfigLock[4]; -/** Offset 0x10B6 - Reserved +/** Offset 0x10B6 - Type C Port x Convert to TypeA + Enable / Disable(default) Type C Port x Convert to TypeA + $EN_DIS **/ - UINT8 Reserved37[4]; + UINT8 EnableTcssCovTypeA[4]; /** Offset 0x10BA - Touch Host Controller Assignment Assign THC 0x0:ThcAssignmentNone, 0x1:ThcAssignmentThc0, 0x2:ThcAssignmentThc1 @@ -1620,9 +2621,276 @@ typedef struct { **/ UINT8 ThcWakeOnTouch[2]; -/** Offset 0x10C8 - Reserved +/** Offset 0x10C8 - Touch Host Controller Active Ltr + Expose Active Ltr for OS driver to set +**/ + UINT32 ThcActiveLtr[2]; + +/** Offset 0x10D0 - Touch Host Controller Idle Ltr + Expose Idle Ltr for OS driver to set +**/ + UINT32 ThcIdleLtr[2]; + +/** Offset 0x10D8 - Touch Host Controller Timestamp timer behavior in D0i2 + Timestamp timer behavior in D0i2. 1 = Timer resets to 0 when entering D0i2 0 = Timer + is paused instead of reset to 0 when entering D0i2 +**/ + UINT8 TimestampTimerMode[2]; + +/** Offset 0x10DA - Reserved +**/ + UINT8 Reserved17[2]; + +/** Offset 0x10DC - Touch Host Controller Display Frame Sync Period + Period of the emulated display frame sync [ms] The minimum period is 2ms, maximum + period is 100ms +**/ + UINT32 DisplayFrameSyncPeriod[2]; + +/** Offset 0x10E4 - Touch Host Controller ResetPad + ResetPad +**/ + UINT32 ThcResetPad[2]; + +/** Offset 0x10EC - Touch Host Controller ResetPad Trigger + Hid Over Spi Reset Pad Trigger 0x0:Low, 0x1:High +**/ + UINT32 ThcResetPadTrigger[2]; + +/** Offset 0x10F4 - Touch Host Controller DYSync + Based on this setting GPIO for given THC will be in native mode +**/ + UINT8 ThcDsyncPad[2]; + +/** Offset 0x10F6 - Reserved +**/ + UINT8 Reserved18[2]; + +/** Offset 0x10F8 - Touch Host Controller Hid Over Spi Connection Speed + Hid Over Spi Connection Speed - SPI Frequency +**/ + UINT32 ThcHidSpiConnectionSpeed[2]; + +/** Offset 0x1100 - Touch Host Controller Hid Over Spi Limit PacketSize + When set, limits SPI read & write packet size to 64B. Otherwise, THC uses Max Soc + packet size for SPI Read and Write 0x0- Max Soc Packet Size, 0x11 - 64 Bytes +**/ + UINT32 ThcHidSpiLimitPacketSize[2]; + +/** Offset 0x1108 - Touch Host Controller Hid Over Spi Limit PacketSize + Minimum amount of delay the THC/QUICKSPI driver must wait between end of write operation + and begin of read operation. This value shall be in 10us multiples 0x0: Disabled, + 1-65535 (0xFFFF) - up to 655350 us +**/ + UINT32 ThcPerformanceLimitation[2]; + +/** Offset 0x1110 - Touch Host Controller Hid Over Spi Input Report Header Address + Hid Over Spi Input Report Header Address +**/ + UINT32 ThcHidSpiInputReportHeaderAddress[2]; + +/** Offset 0x1118 - Touch Host Controller Hid Over Spi Input Report Body Address + Hid Over Spi Input Report Body Address +**/ + UINT32 ThcHidSpiInputReportBodyAddress[2]; + +/** Offset 0x1120 - Touch Host Controller Hid Over Spi Output Report Address + Hid Over Spi Output Report Address +**/ + UINT32 ThcHidSpiOutputReportAddress[2]; + +/** Offset 0x1128 - Touch Host Controller Hid Over Spi Read Opcode + Hid Over Spi Read Opcode +**/ + UINT32 ThcHidSpiReadOpcode[2]; + +/** Offset 0x1130 - Touch Host Controller Hid Over Spi Write Opcode + Hid Over Spi Write Opcode +**/ + UINT32 ThcHidSpiWriteOpcode[2]; + +/** Offset 0x1138 - Touch Host Controller Hid Over Spi Flags + Hid Over Spi Flags 0x0:Single SPI Mode, 0x4000:Dual SPI Mode, 0x8000:Quad SPI Mode +**/ + UINT32 ThcHidSpiFlags[2]; + +/** Offset 0x1140 - Touch Host Controller Reset Sequencing Delay [ms] + Policy control for reset sequencing delay (ACPI _INI, _RST) default 300ms +**/ + UINT16 ThcResetSequencingDelay[2]; + +/** Offset 0x1144 - Touch Host Controller Hid Over I2c Device Address + Hid Over I2c Device Address +**/ + UINT32 ThcHidI2cDeviceAddress[2]; + +/** Offset 0x114C - Touch Host Controller Hid Over I2c Connection Speed + Hid Over I2c Connection Speed [Hz] +**/ + UINT32 ThcHidI2cConnectionSpeed[2]; + +/** Offset 0x1154 - Touch Host Controller Hid Over I2c Addressing Mode + Hid Over I2c Addressing Mode - 0x1: The connection uses 10-bit addressing. 0x0: + The connection uses 7-bit addressing. +**/ + UINT8 ThcHidI2cAddressingMode[2]; + +/** Offset 0x1156 - Reserved +**/ + UINT8 Reserved19[2]; + +/** Offset 0x1158 - Touch Host Controller Hid Over I2c Device Descriptor Address + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cDeviceDescriptorAddress[2]; + +/** Offset 0x1160 - Touch Host Controller Hid Over I2c Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialClockLineHighPeriod[2]; + +/** Offset 0x1168 - Touch Host Controller Hid Over I2c Standard Mode Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialClockLineLowPeriod[2]; + +/** Offset 0x1170 - Touch Host Controller Hid Over I2c Standard Mode Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x1178 - Touch Host Controller Hid Over I2c Standard Mode Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x1180 - Touch Host Controller Hid Over I2c Fast Mode Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialClockLineHighPeriod[2]; + +/** Offset 0x1188 - Touch Host Controller Hid Over I2c Fast Mode Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialClockLineLowPeriod[2]; + +/** Offset 0x1190 - Touch Host Controller Hid Over I2c Fast Mode Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x1198 - Touch Host Controller Hid Over I2c Fast Mode Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11A0 - Touch Host Controller Hid Over I2c Maximum Length Of Suppressed Spikes In Std Mode Fast Mode And Fast Mode Plus + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cMaxSuppressedSpikesSMFMFMP[2]; + +/** Offset 0x11A8 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialClockLineHighPeriod[2]; + +/** Offset 0x11B0 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialClockLineLowPeriod[2]; + +/** Offset 0x11B8 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x11C0 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11C8 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Clock Line High Period + Hid Over I2c Device Descriptor Address **/ - UINT8 Reserved38[337]; + UINT32 ThcHidI2cHighSpeedModePlusSerialClockLineHighPeriod[2]; + +/** Offset 0x11D0 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialClockLineLowPeriod[2]; + +/** Offset 0x11D8 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x11E0 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11E8 - Touch Host Controller Hid Over I2c Maximum Length Of Suppressed Spikes In High Speed Mode + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cMaximumLengthOfSuppressedSpikesInHighSpeedMode[2]; + +/** Offset 0x11F0 - THC Wake On Touch GPIO resource Edge or Level + Definition of GPIO resource configuration of Edge or Level +**/ + UINT8 ThcWotEdgeLevel[2]; + +/** Offset 0x11F2 - THC Wake On Touch GPIO resource of Active Level + Definition of GPIO resource configuration of Active Level +**/ + UINT8 ThcWotActiveLevel[2]; + +/** Offset 0x11F4 - THC Wake On Touch GPIO resource of pin configuration + Definition of GPIO resource configuration of pin configuration +**/ + UINT8 ThcWotPinConfig[2]; + +/** Offset 0x11F6 - THC customized SubSytem ID for Port + Definition of GPIO resource configuration of pin configuration +**/ + UINT16 ThcCustomizedSsid[2]; + +/** Offset 0x11FA - THC Sets Customized SubSytem Vendor ID for Port + Definition of GPIO resource configuration of pin configuration +**/ + UINT16 ThcCustomizedSvid[2]; + +/** Offset 0x11FE - Reserved +**/ + UINT8 Reserved20[2]; + +/** Offset 0x1200 - USB 3.1 Speed Selection + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT32 Usb31PortSpeed; + +/** Offset 0x1204 - Touch Host Controller Hid Over I2c Maximum Frame Size Enable + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT8 ThcHidI2cMaxFrameSize[2]; + +/** Offset 0x1206 - Touch Host Controller Hid Over I2c Maximum Frame Size Value + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT16 ThcHidI2cMaxFrameSizeValue[2]; + +/** Offset 0x120A - Touch Host Controller Hid Over I2c Interrupt Delay Enable + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT8 ThcHidI2cIntDelay[2]; + +/** Offset 0x120C - Touch Host Controller Hid Over I2c Interrupt Delay Value + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT16 ThcHidI2cIntDelayValue[2]; + +/** Offset 0x1210 - Reserved +**/ + UINT8 Reserved21[9]; /** Offset 0x1219 - PCHHOT# pin Enable PCHHOT# pin assertion when temperature is higher than PchHotLevel. 0: disable, 1: enable @@ -1683,7 +2951,47 @@ typedef struct { /** Offset 0x122A - Reserved **/ - UINT8 Reserved39[34]; + UINT8 Reserved22[2]; + +/** Offset 0x122C - PCH TSN MAC Address High Bits + Set TSN MAC Address High. +**/ + UINT32 PchTsn1MacAddressHigh; + +/** Offset 0x1230 - PCH TSN MAC Address Low Bits + Set TSN MAC Address Low. +**/ + UINT32 PchTsn1MacAddressLow; + +/** Offset 0x1234 - PCH TSN2 MAC Address High Bits + Set TSN2 MAC Address High. +**/ + UINT32 PchTsn2MacAddressHigh; + +/** Offset 0x1238 - PCH TSN2 MAC Address Low Bits + Set TSN2 MAC Address Low. +**/ + UINT32 PchTsn2MacAddressLow; + +/** Offset 0x123C - PCH TSN3 MAC Address High Bits + Set TSN3 MAC Address High. +**/ + UINT32 PchTsn3MacAddressHigh; + +/** Offset 0x1240 - PCH TSN3 MAC Address Low Bits + Set TSN3 MAC Address Low. +**/ + UINT32 PchTsn3MacAddressLow; + +/** Offset 0x1244 - PCH TSN4 MAC Address High Bits + Set TSN4 MAC Address High. +**/ + UINT32 PchTsn4MacAddressHigh; + +/** Offset 0x1248 - PCH TSN MAC4 Address Low Bits + Set TSN MAC4 Address Low. +**/ + UINT32 PchTsn4MacAddressLow; /** Offset 0x124C - Enable USB2 ports Enable/disable per USB2 ports. One byte for each port, byte0 for port0, byte1 for @@ -1710,9 +3018,11 @@ typedef struct { **/ UINT8 UsbPdoProgramming; -/** Offset 0x1268 - Reserved +/** Offset 0x1268 - USB Audio Offload enable + Enable/Disable USB Audio Offload capabilites. 0: disabled, 1: enabled (default) + $EN_DIS **/ - UINT8 Reserved40; + UINT8 PchXhciUaolEnable; /** Offset 0x1269 - PCH USB OverCurrent mapping enable 1: Will program USB OC pin mapping in xHCI controller memory, 0: Will clear OC pin @@ -1737,9 +3047,15 @@ typedef struct { **/ UINT8 PchUsbLtrOverrideEnable; -/** Offset 0x1285 - Reserved +/** Offset 0x1285 - USB DWB enable + Enable/Disable USB DWB. 0: disabled, 1: enabled (default) + $EN_DIS +**/ + UINT8 PchXhciDwbEnable; + +/** Offset 0x1286 - Reserved **/ - UINT8 Reserved41[3]; + UINT8 Reserved23[2]; /** Offset 0x1288 - xHCI High Idle Time LTR override Value used for overriding LTR recommendation for xHCI High Idle Time LTR setting @@ -1897,9 +3213,21 @@ typedef struct { **/ UINT8 Usb3HsioTxRate0UniqTran[10]; -/** Offset 0x13AD - Reserved +/** Offset 0x13AD - PCIe Fia Programming + Load Fia configuration if enable. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieFiaProgramming; + +/** Offset 0x13AE - Enable SSE Device + Test, 0: POR, 1: enable, 2: disable, Enable/Disable SSE/SSE++ Devices from PCI config space + $EN_DIS +**/ + UINT8 SseCommunication; + +/** Offset 0x13AF - Reserved **/ - UINT8 Reserved42[4]; + UINT8 Reserved24[2]; /** Offset 0x13B1 - Enable/Disable NPU Device Enable(Default): Enable NPU Device, Disable: Disable NPU Device @@ -1919,9 +3247,11 @@ typedef struct { **/ UINT8 PchLanLtrEnable; -/** Offset 0x13B4 - Reserved +/** Offset 0x13B4 - PCH Lan WOL Fast Support + Enables bit B_PCH_ACPI_GPE0_EN_127_96_PME_B0 during PchLanSxCallback in PchLanSxSmm. + $EN_DIS **/ - UINT8 Reserved43; + UINT8 PchLanWOLFastSupport; /** Offset 0x13B5 - Skip Ssid Programming. When set to TRUE, silicon code will not do any SSID programming and platform code @@ -1942,9 +3272,15 @@ typedef struct { **/ UINT16 SiCustomizedSsid; -/** Offset 0x13BA - Reserved +/** Offset 0x13BA - CAN Configurations + Enable/Disable CAN Controllers.0: Disable, 1: Enable + $EN_DIS +**/ + UINT8 PchCanEnable[2]; + +/** Offset 0x13BC - Reserved **/ - UINT8 Reserved44[6]; + UINT8 Reserved25[4]; /** Offset 0x13C0 - SVID SDID table Poniter. The address of the table of SVID SDID to customize each SVID SDID entry. This is @@ -1958,9 +3294,15 @@ typedef struct { **/ UINT16 SiNumberOfSsidTableEntry; -/** Offset 0x13CA - Reserved +/** Offset 0x13CA - Skip DFX. + Skip DFX. + $EN_DIS +**/ + UINT8 DfxSkipBiosDone; + +/** Offset 0x13CB - Reserved **/ - UINT8 Reserved45[10]; + UINT8 Reserved26[9]; /** Offset 0x13D4 - LogoPixelHeight Address Address of LogoPixelHeight @@ -1974,7 +3316,7 @@ typedef struct { /** Offset 0x13DC - Reserved **/ - UINT8 Reserved46[4]; + UINT8 Reserved27[4]; /** Offset 0x13E0 - Blt Buffer Address Address of Blt buffer @@ -1992,9 +3334,11 @@ typedef struct { **/ UINT8 SkipFspGop; -/** Offset 0x13F1 - Reserved +/** Offset 0x13F1 - Enable/Disable Media Configuration + Enable(Default): Configure Media for use, Disable: Skip Media Configuration + $EN_DIS **/ - UINT8 Reserved47; + UINT8 ConfigureMedia; /** Offset 0x13F2 - Enable/Disable IGFX RenderStandby Enable(Default): Enable IGFX RenderStandby, Disable: Disable IGFX RenderStandby @@ -2002,9 +3346,23 @@ typedef struct { **/ UINT8 RenderStandby; -/** Offset 0x13F3 - Reserved +/** Offset 0x13F3 - Enable/Disable GT Configuration + Enable(Default): Configure GT for use, Disable: Skip GT Configuration + $EN_DIS +**/ + UINT8 ConfigureGT; + +/** Offset 0x13F4 - Enable RC1p GT frequency request to PMA (provided all other conditions are met) + 0(Default)=Disable, 1=Enable + $EN_DIS +**/ + UINT8 RC1pGtFreqEnable; + +/** Offset 0x13F5 - Enable RC1p Media frequency request to PMA (provided all other conditions are met) + 0(Default)=Disable, 1=Enable + $EN_DIS **/ - UINT8 Reserved48[3]; + UINT8 RC1pMediaFreqEnable; /** Offset 0x13F6 - Enable/Disable PavpEnable Enable(Default): Enable PavpEnable, Disable: Disable PavpEnable @@ -2019,9 +3377,21 @@ typedef struct { **/ UINT8 PeiGraphicsPeimInit; -/** Offset 0x13F8 - Reserved +/** Offset 0x13F8 - Enable/Disable IGFX Media Standby + Enable(Default): Enable IGFX Media Standby, Disable: Disable IGFX MediaStandby + $EN_DIS +**/ + UINT8 MediaStandby; + +/** Offset 0x13F9 - Enable/Disable Gfx Workstation + Enable(Default): Is a workstation, Disable: Is not a workstation + $EN_DIS +**/ + UINT8 Dev2IsGfxWorkstation; + +/** Offset 0x13FA - Reserved **/ - UINT8 Reserved49[4]; + UINT8 Reserved28[2]; /** Offset 0x13FC - Intel Graphics VBT (Video BIOS Table) Size Size of Internal Graphics VBT Image @@ -2042,7 +3412,21 @@ typedef struct { /** Offset 0x1402 - Reserved **/ - UINT8 Reserved50[66]; + UINT8 Reserved29[2]; + +/** Offset 0x1404 - HorizontalResolution for PEI Logo + HorizontalResolution from PEIm Gfx for PEI Logo +**/ + UINT32 HorizontalResolution; + +/** Offset 0x1408 - VerticalResolution for PEI Logo + VerticalResolution from PEIm Gfx for PEI Logo +**/ + UINT32 VerticalResolution; + +/** Offset 0x140C - Reserved +**/ + UINT8 Reserved30[56]; /** Offset 0x1444 - Address of PCH_DEVICE_INTERRUPT_CONFIG table. The address of the table of PCH_DEVICE_INTERRUPT_CONFIG. @@ -2076,9 +3460,33 @@ typedef struct { **/ UINT8 TcoIrqEnable; -/** Offset 0x144D - Reserved +/** Offset 0x144D - PMC ADR enable + Enable/disable asynchronous DRAM refresh + $EN_DIS +**/ + UINT8 PmcAdrEn; + +/** Offset 0x144E - PMC ADR timer configuration enable + Enable/disable ADR timer configuration + $EN_DIS +**/ + UINT8 PmcAdrTimerEn; + +/** Offset 0x144F - PMC ADR phase 1 timer value + Enable/disable ADR timer configuration +**/ + UINT8 PmcAdrTimer1Val; + +/** Offset 0x1450 - PMC ADR phase 1 timer multiplier value + Specify the multiplier value for phase 1 ADR timer +**/ + UINT8 PmcAdrMultiplier1Val; + +/** Offset 0x1451 - PMC ADR host reset partition enable + Specify whether PMC should set ADR_RST_STS bit after receiving Reset_Warn_Ack DMI message + $EN_DIS **/ - UINT8 Reserved51[5]; + UINT8 PmcAdrHostPartitionReset; /** Offset 0x1452 - Mask to enable the usage of external V1p05 VR rail in specific S0ix or Sx states Enable External V1P05 Rail in: BIT0:S0i1/S0i2, BIT1:S0i3, BIT2:S3, BIT3:S4, BIT5:S5 @@ -2112,7 +3520,7 @@ typedef struct { /** Offset 0x1459 - Reserved **/ - UINT8 Reserved52; + UINT8 Reserved31; /** Offset 0x145A - External Vnn Voltage Value that will be used in S0ix/Sx states Value is given in 2.5mV increments (0=0mV, 1=2.5mV, 2=5mV...), Default is set to 420 @@ -2173,7 +3581,7 @@ typedef struct { /** Offset 0x1467 - Reserved **/ - UINT8 Reserved53; + UINT8 Reserved32; /** Offset 0x1468 - External V1P05 Icc Max Value Granularity of this setting is 1mA and maximal possible value is 500mA @@ -2213,9 +3621,11 @@ typedef struct { **/ UINT8 PchLegacyIoLowLatency; -/** Offset 0x1472 - Reserved +/** Offset 0x1472 - PCH P2SB + PCH P2SB + $EN_DIS **/ - UINT8 Reserved54; + UINT8 SvTestUnhideP2sb; /** Offset 0x1473 - PCH Unlock SideBand access The SideBand PortID mask for certain end point (e.g. PSFx) will be locked before @@ -2282,9 +3692,19 @@ typedef struct { **/ UINT8 CnviBtAudioOffload; -/** Offset 0x147D - Reserved +/** Offset 0x147D - WWAN Coex + WWAN Coex is getting updated from UEFI variable +**/ + UINT8 CnviWwanCoex; + +/** Offset 0x147E - Skip BtPreInit + BtPreInit can be skipped if SkipBtPreInit is enabled **/ - UINT8 Reserved55[3]; + UINT8 SkipBtPreInit; + +/** Offset 0x147F - Reserved +**/ + UINT8 Reserved33; /** Offset 0x1480 - CNVi RF_RESET pin muxing Select CNVi RF_RESET# pin depending on board routing. LP/P/M: GPP_A8 = 0x2942E408(default) @@ -2299,9 +3719,11 @@ typedef struct { **/ UINT32 CnviClkreqPinMux; -/** Offset 0x1488 - Reserved +/** Offset 0x1488 - CNVi BT Audio OffOffloadInterfaceload + Enable/Disable BT Audio OffloadInterface, Default is ENABLE. 0: DISABLE, 1: ENABLE + $EN_DIS **/ - UINT8 Reserved56; + UINT8 CnviBtAudioOffloadInterface; /** Offset 0x1489 - Enable Device 4 Enable/disable Device 4 @@ -2316,9 +3738,10 @@ typedef struct { **/ UINT8 SkipPamLock; -/** Offset 0x148B - Reserved +/** Offset 0x148B - TCSS LSx OE Enable + Bits 0, 1, ... max Type C Rettimerless port LSx OE enables **/ - UINT8 Reserved57; + UINT8 TcssLsxOe; /** Offset 0x148C - PCH HDA Verb Table Entry Number Number of Entries in Verb Table. @@ -2327,7 +3750,7 @@ typedef struct { /** Offset 0x148D - Reserved **/ - UINT8 Reserved58[3]; + UINT8 Reserved34[3]; /** Offset 0x1490 - PCH HDA Verb Table Pointer Pointer to Array of pointers to Verb Table. @@ -2359,9 +3782,11 @@ typedef struct { **/ UINT8 PchHdaMicPrivacyMode; -/** Offset 0x149C - Reserved +/** Offset 0x149C - HD Audio Microphone Privacy Deglitch + HD Audio Microphone Privacy Deglitch: 0: Disable, 1: Enable + $EN_DIS **/ - UINT8 Reserved59; + UINT8 PchHdaMicPrivacyDeglitch; /** Offset 0x149D - HD Audio Microphone Privacy applied for SoundWire Link number 0 in HW Mode HD Audio Microphone Privacy applied for SoundWire Link number 0 in HW Mode: 0: Disable, 1: Enable @@ -2401,7 +3826,17 @@ typedef struct { /** Offset 0x14A3 - Reserved **/ - UINT8 Reserved60[13]; + UINT8 Reserved35; + +/** Offset 0x14A4 - HD Audio Microphone Privacy Timeout. Indicates the time-out duration to wait before forcing the actual microphone privacy DMA data zeroing. + HD Audio Microphone Privacy Timeout. Indicates the time-out duration to wait before + forcing the actual microphone privacy DMA data zeroing. +**/ + UINT32 PchHdaMicPrivacyTimeout; + +/** Offset 0x14A8 - Reserved +**/ + UINT8 Reserved36[8]; /** Offset 0x14B0 - Pointer to ChipsetInit Binary ChipsetInit Binary Pointer. @@ -2415,7 +3850,49 @@ typedef struct { /** Offset 0x14BC - Reserved **/ - UINT8 Reserved61[36]; + UINT8 Reserved37[4]; + +/** Offset 0x14C0 - Pointer to NPHY Binary + Nphy Binary Pointer. +**/ + UINT64 NphyBinPtr; + +/** Offset 0x14C8 - Length of NPHY Binary + Nphy Binary Length. +**/ + UINT32 NphyBinLen; + +/** Offset 0x14CC - Reserved +**/ + UINT8 Reserved38[4]; + +/** Offset 0x14D0 - Pointer to SYNPS PHY Binary + Synps Binary Pointer. +**/ + UINT64 SynpsPhyBinPtr; + +/** Offset 0x14D8 - Length of SYNPS PHY Binary + Synps Binary Length. +**/ + UINT32 SynpsPhyBinLen; + +/** Offset 0x14DC - Skip setting BIOS_DONE When Fw Update. + When set to TRUE and boot mode is BOOT_ON_FLASH_UPDATE,skip setting BIOS_DONE MSR + at EndofPei. Note: BIOS_DONE MSR should be set in later phase before executing + 3rd party code if SiSkipBiosDoneWhenFwUpdate set to TRUE. + $EN_DIS +**/ + UINT8 SiSkipBiosDoneWhenFwUpdate; + +/** Offset 0x14DD - PMC WDT enable + Enable/disable PMC WDT configuration + $EN_DIS +**/ + UINT8 PmcWdtTimerEn; + +/** Offset 0x14DE - Reserved +**/ + UINT8 Reserved39[2]; } FSP_S_CONFIG; /** Fsp S UPD Configuration From 63ec633ccddd7f1600d19df274a4ef91c9be864b Mon Sep 17 00:00:00 2001 From: Appukuttan V K Date: Tue, 6 Jan 2026 22:02:23 +0530 Subject: [PATCH 224/789] mb/google/ocelot: Update sagv_freq_mhz as per platform POR config Update the SaGV frequency registers in the devicetree as per platform Plan of Record (POR) configuration: - sagv_freq_mhz[1]: 3200 MHz -> 4800 MHz - sagv_freq_mhz[2]: 6000 MHz -> 6400 MHz - sagv_freq_mhz[3]: 6400 MHz -> 7467 MHz The current frequency points were configured lower than the platform's expected specifications. BUG=None TEST=Boot ocelot and verify that the system boots and MRC training is successful for each SAGV point. [SPEW ] Requested/actual ratio 72/72, Frequency=2400, GearMode=1, RefClk=33MHz, tCK=3333333fs [SPEW ] Requested/actual ratio 144/144, Frequency=4800, GearMode=1, RefClk=33MHz, tCK=1666667fs [SPEW ] Requested/actual ratio 192/192, Frequency=6400, GearMode=1, RefClk=33MHz, tCK=1250000fs [SPEW ] Requested/actual ratio 224/224, Frequency=7467, GearMode=1, RefClk=33MHz, tCK=1071429fs Change-Id: I7beab13bd9188aa47a45bc4a265aba75f00eded8 Signed-off-by: Appukuttan V K Reviewed-on: https://review.coreboot.org/c/coreboot/+/90688 Reviewed-by: Avi Uday Reviewed-by: P, Usha Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N --- .../google/ocelot/variants/baseboard/ocelot/devicetree.cb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb b/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb index e2ea33173b..9391ac9d37 100644 --- a/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb +++ b/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb @@ -35,13 +35,13 @@ chip soc/intel/pantherlake register "sagv_freq_mhz[0]" = "2400" register "sagv_gear[0]" = "GEAR_4" - register "sagv_freq_mhz[1]" = "3200" + register "sagv_freq_mhz[1]" = "4800" register "sagv_gear[1]" = "GEAR_4" - register "sagv_freq_mhz[2]" = "6000" + register "sagv_freq_mhz[2]" = "6400" register "sagv_gear[2]" = "GEAR_4" - register "sagv_freq_mhz[3]" = "6400" + register "sagv_freq_mhz[3]" = "7467" register "sagv_gear[3]" = "GEAR_4" # Enable s0ix From edae16f6f255c7194c51481b952801ea35640112 Mon Sep 17 00:00:00 2001 From: Pierce Chou Date: Wed, 14 Jan 2026 10:13:31 +0800 Subject: [PATCH 225/789] mb/google/ocelot/var/ocicat: Add wake support for touchscreen This commit introduces support for touch functionalities on the ocicat board. Changes include: - Support for touchscreen devices in THC-I2C - Wake support from S0ix state for touchscreen - PMC GPE DW0 is reconfigured to GPP_F for Touchscreen in variant.c for wake support BUG=b:444942125 TEST= Build Ocicat and Test wake from S0ix state via touchscreen inputs. Change-Id: Icf6fb0e170a64a5aec05590450a3bd40ab95cbf3 Signed-off-by: Pierce Chou Reviewed-on: https://review.coreboot.org/c/coreboot/+/90750 Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N Reviewed-by: Avi Uday --- .../ocelot/variants/ocicat/overridetree.cb | 8 +++++++- .../google/ocelot/variants/ocicat/variant.c | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb b/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb index 52ada4b77c..61a9c72b96 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb +++ b/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb @@ -246,6 +246,7 @@ chip soc/intel/pantherlake device ref thc0 on register "thc_wake_on_touch[0]" = "true" + register "thc_mode[0]" = "THC_HID_I2C_MODE" # THC0 is function 0; hence it needs to be enabled when THC1 is to be enabled. chip drivers/intel/touch register "name" = "INTEL_THC0_NAME" @@ -265,6 +266,7 @@ chip soc/intel/pantherlake end device ref thc1 on register "thc_wake_on_touch[1]" = "true" + register "thc_mode[1]" = "THC_HID_I2C_MODE" chip drivers/intel/touch register "name" = "INTEL_THC1_NAME" register "mode" = "THC_HID_I2C_MODE" @@ -273,7 +275,7 @@ chip soc/intel/pantherlake register "wake_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(GPP_VGPIO3_THC1)" register "active_ltr" = "1" register "idle_ltr" = "0" - register "connected_device" = "TH_SENSOR_HYNITRON" + register "connected_device" = "TH_SENSOR_ELAN" register "add_acpi_dma_property" = "true" device generic 0 alias touch_1_i2c_hynitron on end end @@ -434,6 +436,8 @@ chip soc/intel/pantherlake register "generic.hid" = ""ELAN2513"" register "generic.desc" = ""ELAN Touchscreen"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" + # NOTE: pmc_gpe0_dw0 will be overridden to GPP_F in variant.c. + register "generic.wake" = "GPE0_DW0_18" register "generic.detect" = "1" register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F16)" register "generic.reset_delay_ms" = "20" @@ -454,6 +458,8 @@ chip soc/intel/pantherlake register "generic.hid" = ""ELAN2513"" register "generic.desc" = ""ELAN Touchscreen"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" + # NOTE: pmc_gpe0_dw0 will be overridden to GPP_F in variant.c. + register "generic.wake" = "GPE0_DW0_18" register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F16)" register "generic.reset_delay_ms" = "20" register "generic.reset_off_delay_ms" = "2" diff --git a/src/mainboard/google/ocelot/variants/ocicat/variant.c b/src/mainboard/google/ocelot/variants/ocicat/variant.c index 733cf6bf3b..935327f255 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/variant.c +++ b/src/mainboard/google/ocelot/variants/ocicat/variant.c @@ -15,6 +15,25 @@ const char *get_wifi_sar_cbfs_filename(void) return get_wifi_sar_fw_config_filename(FW_CONFIG_FIELD(WIFI_INTERFACE)); } +void variant_update_soc_chip_config(struct soc_intel_pantherlake_config *config) +{ + /* Touchscreen and Touchpad WOT support: + * +===================+==================+=================+========================+ + * | Touchscreen | Touchpad | PMC_GPE0_DW0 | WOT | + * +===================+==================+=================+========================+ + * | THC-SPI/THC-I2C | THC-I2C | VGPIO | TS, TP | + * +===================+==================+=================+========================+ + * | THC-SPI/THC-I2C | LPSS-I2C | GPP_F18 | TP | + * +===================+==================+=================+========================+ + */ + + config->thc_mode[0] = THC_HID_I2C_MODE; + config->thc_mode[1] = THC_HID_I2C_MODE; + + /* touchscreen: GPP_F18: GPE0_DW0_18 */ + config->pmc_gpe0_dw0 = GPP_F; +} + void variant_update_soc_memory_init_params(FSPM_UPD *memupd) { FSP_M_CONFIG *m_cfg = &memupd->FspmConfig; From 9e865fb880ec9857d90babcc2693c549a6c2b826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Tue, 9 Sep 2025 10:09:32 +0200 Subject: [PATCH 226/789] amdblocks/acpi/ivrs: Fix IVRS generation for multiple IOMMUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More complex systems, such as servers, have multiple IOMMUs. For example, Turin CPUs have a total of 4 IOMMUs per socket. Abort IVHD generation only if IOMMU is not present on domain 0. For other domains simply continue the loop, so that other domains have their IOMMUs described properly in the IVRS. To keep simple systems working as before, IVHD generation is aborted, if IOMMU is not present in domain 0. TEST=See IOMMUs on domains 1,3,4,6 being skipped during IVHD generation instead of IVHD generation being aborted on domain 1 on Gigabyte MZ33-AR1 console log. Change-Id: Icd3a51621908dc3ee5c85aa1e5814f3b3ac69007 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/89111 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/soc/amd/common/block/acpi/ivrs.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/soc/amd/common/block/acpi/ivrs.c b/src/soc/amd/common/block/acpi/ivrs.c index 48c3965926..c3af6285a6 100644 --- a/src/soc/amd/common/block/acpi/ivrs.c +++ b/src/soc/amd/common/block/acpi/ivrs.c @@ -171,7 +171,7 @@ static unsigned long acpi_ivhd_misc(unsigned long current, struct device *dev) /* * Add all possible PCI devices in the domain that can generate transactions * processed by IOMMU. Start with device :01.0 - */ + */ current = ivhd_dev_range(current, PCI_DEVFN(0, 3) | (dev->downstream->secondary << 8), 0xff | (dev->downstream->subordinate << 8), 0); @@ -311,6 +311,7 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) struct device *iommu_dev; struct device *nb_dev; struct device *dev = NULL; + unsigned int domain; if (ivrs == NULL) { printk(BIOS_WARNING, "%s: ivrs is NULL\n", __func__); @@ -322,15 +323,22 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) while ((dev = dev_find_path(dev, DEVICE_PATH_DOMAIN)) != NULL) { nb_dev = pcidev_path_behind(dev->downstream, PCI_DEVFN(0, 0)); iommu_dev = pcidev_path_behind(dev->downstream, PCI_DEVFN(0, 2)); + domain = dev_get_domain_id(dev); if (!nb_dev) { - printk(BIOS_WARNING, "%s: Northbridge device not present!\n", __func__); - printk(BIOS_WARNING, "%s: IVRS table not generated...\n", __func__); - return (unsigned long)ivrs; + printk(BIOS_WARNING, "%s: Northbridge device not present on domain %u!\n", __func__, domain); + if (domain == 0) { + printk(BIOS_WARNING, "%s: IVRS table not generated...\n", __func__); + return (unsigned long)ivrs; + } + continue; } if (!iommu_dev) { - printk(BIOS_WARNING, "%s: IOMMU device not found\n", __func__); - return (unsigned long)ivrs; + printk(BIOS_WARNING, "%s: IOMMU device not found on domain %u\n", __func__, dev_get_domain_id(dev)); + if (domain == 0) + return (unsigned long)ivrs; + + continue; } ivhd->type = IVHD_BLOCK_TYPE_LEGACY__FIXED; From 96d5c3dd54b08070e7557459c7aeb304eaf8ad21 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 14:28:15 +0000 Subject: [PATCH 227/789] ec/starlabs/merlin: Set the default changing speed to 1.0C Change-Id: I0aed42d85bbcebb2eba329d818b8e7b153a9f3b1 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90836 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/ec/starlabs/merlin/cfr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ec/starlabs/merlin/cfr.h b/src/ec/starlabs/merlin/cfr.h index 170ec7a0dd..760c41afb6 100644 --- a/src/ec/starlabs/merlin/cfr.h +++ b/src/ec/starlabs/merlin/cfr.h @@ -75,7 +75,7 @@ static const struct sm_object charging_speed = SM_DECLARE_ENUM({ .ui_name = "Charging Speed", .ui_helptext = "Set the maximum speed to charge the battery. Charging faster" " will increase heat and battery wear.", - .default_value = SPEED_0_5C, + .default_value = SPEED_1_0C, .values = (const struct sm_enum_value[]) { { "1.0C", SPEED_1_0C }, { "0.5C", SPEED_0_5C }, From 53d31a4152f16d49f63c491bf89de15790d588bd Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 14:34:27 +0000 Subject: [PATCH 228/789] mb/starlabs/*: Adjust the default power profile If the board has a fan, set the default profile to Performance. If not, use Balanced. Change-Id: I8adb22f38a8aec55ed86a3aa29e8abfde5670867 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90837 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/common/include/common/cfr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/starlabs/common/include/common/cfr.h b/src/mainboard/starlabs/common/include/common/cfr.h index 1b89642133..58c4ec2a8e 100644 --- a/src/mainboard/starlabs/common/include/common/cfr.h +++ b/src/mainboard/starlabs/common/include/common/cfr.h @@ -101,7 +101,7 @@ static const struct sm_object power_profile = SM_DECLARE_ENUM({ .opt_name = "power_profile", .ui_name = "Power Profile", .ui_helptext = "Select whether to maximize performance, battery life or both.", - .default_value = 1, + .default_value = CONFIG(EC_STARLABS_FAN) ? PP_PERFORMANCE : PP_BALANCED, .values = (const struct sm_enum_value[]) { { "Power Saver", PP_POWER_SAVER }, { "Balanced", PP_BALANCED }, From 7d4e2c6150841b3279ed10722253c31c4d43d9e4 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 14:47:57 +0000 Subject: [PATCH 229/789] mb/starlabs/*: Default to ASPM_L0S_L1 over ASPM_AUTO Set the default for ASPM to ASPM_L0S_L1 rather than ASPM_AUTO, as using AUTO won't always enable ASPM for some SSDs (Western Digital). Test=build and flash starbook/mtl; check new default is ASPM_L0S_L1 in edk2 menu. Change-Id: If66dcabe5eca717565e0378ab36db8a4cb220d43 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90838 Reviewed-by: Matt DeVillier Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/byte_adl/cfr.c | 1 + src/mainboard/starlabs/common/cfr/cfr.c | 13 +++++++++++++ src/mainboard/starlabs/common/include/common/cfr.h | 1 + src/mainboard/starlabs/lite/cfr.c | 1 + src/mainboard/starlabs/starbook/cfr.c | 1 + src/mainboard/starlabs/starfighter/cfr.c | 1 + src/mainboard/starlabs/starlite_adl/cfr.c | 1 + 7 files changed, 19 insertions(+) diff --git a/src/mainboard/starlabs/byte_adl/cfr.c b/src/mainboard/starlabs/byte_adl/cfr.c index 3a9162d1cb..9936025c25 100644 --- a/src/mainboard/starlabs/byte_adl/cfr.c +++ b/src/mainboard/starlabs/byte_adl/cfr.c @@ -77,5 +77,6 @@ static struct sm_obj_form *sm_root[] = { void mb_cfr_setup_menu(struct lb_cfr *cfr_root) { + starlabs_cfr_register_overrides(); cfr_write_setup_menu(cfr_root, sm_root); } diff --git a/src/mainboard/starlabs/common/cfr/cfr.c b/src/mainboard/starlabs/common/cfr/cfr.c index 78a41814e5..70899d21b1 100644 --- a/src/mainboard/starlabs/common/cfr/cfr.c +++ b/src/mainboard/starlabs/common/cfr/cfr.c @@ -1,9 +1,22 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include void __weak cfr_card_reader_update(struct sm_object *new_obj) { (void)new_obj; } + +static const struct cfr_default_override starlabs_cfr_overrides[] = { + CFR_OVERRIDE_ENUM("pciexp_aspm", ASPM_L0S_L1), + CFR_OVERRIDE_END +}; + +void starlabs_cfr_register_overrides(void) +{ + if (!CONFIG(DRIVERS_OPTION_CFR)) + return; + cfr_register_overrides(starlabs_cfr_overrides); +} diff --git a/src/mainboard/starlabs/common/include/common/cfr.h b/src/mainboard/starlabs/common/include/common/cfr.h index 58c4ec2a8e..4613b94fbd 100644 --- a/src/mainboard/starlabs/common/include/common/cfr.h +++ b/src/mainboard/starlabs/common/include/common/cfr.h @@ -8,6 +8,7 @@ #include void cfr_card_reader_update(struct sm_object *new_obj); +void starlabs_cfr_register_overrides(void); static const struct sm_object accelerometer = SM_DECLARE_BOOL({ .opt_name = "accelerometer", diff --git a/src/mainboard/starlabs/lite/cfr.c b/src/mainboard/starlabs/lite/cfr.c index db3702fb79..ae1cfdbbd3 100644 --- a/src/mainboard/starlabs/lite/cfr.c +++ b/src/mainboard/starlabs/lite/cfr.c @@ -87,5 +87,6 @@ static struct sm_obj_form *sm_root[] = { void mb_cfr_setup_menu(struct lb_cfr *cfr_root) { + starlabs_cfr_register_overrides(); cfr_write_setup_menu(cfr_root, sm_root); } diff --git a/src/mainboard/starlabs/starbook/cfr.c b/src/mainboard/starlabs/starbook/cfr.c index a499d3ed08..ab5f84e663 100644 --- a/src/mainboard/starlabs/starbook/cfr.c +++ b/src/mainboard/starlabs/starbook/cfr.c @@ -124,5 +124,6 @@ static struct sm_obj_form *sm_root[] = { void mb_cfr_setup_menu(struct lb_cfr *cfr_root) { + starlabs_cfr_register_overrides(); cfr_write_setup_menu(cfr_root, sm_root); } diff --git a/src/mainboard/starlabs/starfighter/cfr.c b/src/mainboard/starlabs/starfighter/cfr.c index 146ffd6913..01488d4865 100644 --- a/src/mainboard/starlabs/starfighter/cfr.c +++ b/src/mainboard/starlabs/starfighter/cfr.c @@ -109,5 +109,6 @@ static struct sm_obj_form *sm_root[] = { void mb_cfr_setup_menu(struct lb_cfr *cfr_root) { + starlabs_cfr_register_overrides(); cfr_write_setup_menu(cfr_root, sm_root); } diff --git a/src/mainboard/starlabs/starlite_adl/cfr.c b/src/mainboard/starlabs/starlite_adl/cfr.c index 7bbe25d61f..6416dc4a77 100644 --- a/src/mainboard/starlabs/starlite_adl/cfr.c +++ b/src/mainboard/starlabs/starlite_adl/cfr.c @@ -107,5 +107,6 @@ static struct sm_obj_form *sm_root[] = { void mb_cfr_setup_menu(struct lb_cfr *cfr_root) { + starlabs_cfr_register_overrides(); cfr_write_setup_menu(cfr_root, sm_root); } From 5ad87a4de9f98dd1ccf981c1dbc0abba0ec56a13 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Wed, 5 Nov 2025 09:48:45 +0000 Subject: [PATCH 230/789] soc/intel/{adl,mtl,ptl): Hook Intel TME up to the option table This makes it runtime configurable; disabling it can save around 100ms boot time. Change-Id: I9cddb07fc2e7caf754fa8d665249536c4885a4fe Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/89918 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/alderlake/cpu.c | 3 ++- src/soc/intel/alderlake/romstage/fsp_params.c | 2 +- .../common/block/include/intelblocks/cfr.h | 18 ++++++++++++++++++ src/soc/intel/meteorlake/cpu.c | 3 ++- src/soc/intel/meteorlake/romstage/fsp_params.c | 2 +- src/soc/intel/pantherlake/cpu.c | 3 ++- .../intel/pantherlake/romstage/fsp_params.c | 3 ++- src/soc/intel/tigerlake/romstage/fsp_params.c | 2 +- 8 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/soc/intel/alderlake/cpu.c b/src/soc/intel/alderlake/cpu.c index c2efff3419..615bd43c31 100644 --- a/src/soc/intel/alderlake/cpu.c +++ b/src/soc/intel/alderlake/cpu.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -140,7 +141,7 @@ void soc_core_init(struct device *cpu) /* Enable Turbo */ enable_turbo(); - if (CONFIG(INTEL_TME) && is_tme_supported()) + if (get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported()) set_tme_core_activate(); } diff --git a/src/soc/intel/alderlake/romstage/fsp_params.c b/src/soc/intel/alderlake/romstage/fsp_params.c index 4bb2980b2b..d6224658ae 100644 --- a/src/soc/intel/alderlake/romstage/fsp_params.c +++ b/src/soc/intel/alderlake/romstage/fsp_params.c @@ -226,7 +226,7 @@ static void fill_fspm_security_params(FSP_M_CONFIG *m_cfg, { /* Disable BIOS Guard */ m_cfg->BiosGuard = 0; - m_cfg->TmeEnable = CONFIG(INTEL_TME) && is_tme_supported(); + m_cfg->TmeEnable = get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported(); } static void fill_fspm_uart_params(FSP_M_CONFIG *m_cfg, diff --git a/src/soc/intel/common/block/include/intelblocks/cfr.h b/src/soc/intel/common/block/include/intelblocks/cfr.h index 7828e1f359..15dcacab23 100644 --- a/src/soc/intel/common/block/include/intelblocks/cfr.h +++ b/src/soc/intel/common/block/include/intelblocks/cfr.h @@ -8,6 +8,7 @@ #define SOC_INTEL_CMN_CFR_H #include +#include #include #include @@ -133,4 +134,21 @@ static const struct sm_object pciexp_speed = SM_DECLARE_ENUM({ SM_ENUM_VALUE_END }, }); +/* TME */ +static void update_intel_tme(struct sm_object *new) +{ + if (!is_tme_supported()) + new->sm_bool.flags |= CFR_OPTFLAG_SUPPRESS; +} + +static const struct sm_object intel_tme = SM_DECLARE_BOOL({ + .opt_name = "intel_tme", + .ui_name = "Total Memory Encryption", + .ui_helptext = "Enable TME (Total Memory Encryption). When enabled, all data stored in" + " system memory is encrypted to prevent unauthorized access or data theft." + " Disabling TME decreases boot time by around 100ms", + .default_value = CONFIG(INTEL_TME), +}, WITH_CALLBACK(update_intel_tme)); + + #endif /* SOC_INTEL_CMN_CFR_H */ diff --git a/src/soc/intel/meteorlake/cpu.c b/src/soc/intel/meteorlake/cpu.c index b4854cb6ef..05fe9a9756 100644 --- a/src/soc/intel/meteorlake/cpu.c +++ b/src/soc/intel/meteorlake/cpu.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -142,7 +143,7 @@ void soc_core_init(struct device *cpu) /* Set core type in struct cpu_info */ set_dev_core_type(); - if (CONFIG(INTEL_TME) && is_tme_supported()) + if (get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported()) set_tme_core_activate(); if (CONFIG(DROP_CPU_FEATURE_PROGRAM_IN_FSP)) { diff --git a/src/soc/intel/meteorlake/romstage/fsp_params.c b/src/soc/intel/meteorlake/romstage/fsp_params.c index cec8304281..d6c0b04782 100644 --- a/src/soc/intel/meteorlake/romstage/fsp_params.c +++ b/src/soc/intel/meteorlake/romstage/fsp_params.c @@ -198,7 +198,7 @@ static void fill_fspm_cpu_params(FSP_M_CONFIG *m_cfg, static void fill_tme_params(FSP_M_CONFIG *m_cfg) { - m_cfg->TmeEnable = CONFIG(INTEL_TME) && is_tme_supported(); + m_cfg->TmeEnable = get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported(); if (!m_cfg->TmeEnable || acpi_is_wakeup_s3()) return; m_cfg->GenerateNewTmeKey = CONFIG(TME_KEY_REGENERATION_ON_WARM_BOOT) && diff --git a/src/soc/intel/pantherlake/cpu.c b/src/soc/intel/pantherlake/cpu.c index f821507749..40b216d697 100644 --- a/src/soc/intel/pantherlake/cpu.c +++ b/src/soc/intel/pantherlake/cpu.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -141,7 +142,7 @@ void soc_core_init(struct device *cpu) /* Set core type in struct cpu_info */ set_dev_core_type(); - if (CONFIG(INTEL_TME) && is_tme_supported()) + if (get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported()) set_tme_core_activate(); if (CONFIG(DROP_CPU_FEATURE_PROGRAM_IN_FSP)) { diff --git a/src/soc/intel/pantherlake/romstage/fsp_params.c b/src/soc/intel/pantherlake/romstage/fsp_params.c index 46458af5ce..5ec92bb80f 100644 --- a/src/soc/intel/pantherlake/romstage/fsp_params.c +++ b/src/soc/intel/pantherlake/romstage/fsp_params.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -112,7 +113,7 @@ static void fill_fspm_cpu_params(FSP_M_CONFIG *m_cfg, static void fill_tme_params(FSP_M_CONFIG *m_cfg) { - m_cfg->TmeEnable = CONFIG(INTEL_TME) && is_tme_supported(); + m_cfg->TmeEnable = get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported(); if (!m_cfg->TmeEnable || acpi_is_wakeup_s3()) return; m_cfg->GenerateNewTmeKey = CONFIG(TME_KEY_REGENERATION_ON_WARM_BOOT); diff --git a/src/soc/intel/tigerlake/romstage/fsp_params.c b/src/soc/intel/tigerlake/romstage/fsp_params.c index 0f6c80cfec..6f8c5eb9e6 100644 --- a/src/soc/intel/tigerlake/romstage/fsp_params.c +++ b/src/soc/intel/tigerlake/romstage/fsp_params.c @@ -220,7 +220,7 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, m_cfg->CpuPcieRpEnableMask |= 1 << i; } - m_cfg->TmeEnable = CONFIG(INTEL_TME) && is_tme_supported(); + m_cfg->TmeEnable = get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported(); /* crashLog config */ m_cfg->CpuCrashLogDevice = CONFIG(SOC_INTEL_CRASHLOG) && is_devfn_enabled(SA_DEVFN_TMT); From 90c1d8654c4a70a5dcf1e7203ffc309f75fa4d7d Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Wed, 5 Nov 2025 10:01:42 +0000 Subject: [PATCH 231/789] mb/starlabs/*: Expose TME CFR option Change-Id: I806b8af593626dc3125435ba56ce18dfcd7f6946 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/89920 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/byte_adl/cfr.c | 10 ++++++++++ src/mainboard/starlabs/lite/cfr.c | 10 ++++++++++ src/mainboard/starlabs/starbook/cfr.c | 9 +++++++++ src/mainboard/starlabs/starfighter/cfr.c | 9 +++++++++ src/mainboard/starlabs/starlite_adl/cfr.c | 9 +++++++++ 5 files changed, 47 insertions(+) diff --git a/src/mainboard/starlabs/byte_adl/cfr.c b/src/mainboard/starlabs/byte_adl/cfr.c index 9936025c25..e80108ba42 100644 --- a/src/mainboard/starlabs/byte_adl/cfr.c +++ b/src/mainboard/starlabs/byte_adl/cfr.c @@ -47,6 +47,15 @@ static struct sm_obj_form devices_group = { }, }; +static struct sm_obj_form security_group = { + .ui_name = "Security", + .obj_list = (const struct sm_object *[]) { + &intel_tme, + NULL + }, +}; + + static struct sm_obj_form pci_group = { .ui_name = "PCI", .obj_list = (const struct sm_object *[]) { @@ -70,6 +79,7 @@ static struct sm_obj_form *sm_root[] = { &processor_group, &power_group, &devices_group, + &security_group, &pci_group, &coreboot_group, NULL diff --git a/src/mainboard/starlabs/lite/cfr.c b/src/mainboard/starlabs/lite/cfr.c index ae1cfdbbd3..81d236ea86 100644 --- a/src/mainboard/starlabs/lite/cfr.c +++ b/src/mainboard/starlabs/lite/cfr.c @@ -54,6 +54,15 @@ static struct sm_obj_form devices_group = { }, }; +static struct sm_obj_form security_group = { + .ui_name = "Security", + .obj_list = (const struct sm_object *[]) { + &intel_tme, + NULL + }, +}; + + static struct sm_obj_form pci_group = { .ui_name = "PCI", .obj_list = (const struct sm_object *[]) { @@ -80,6 +89,7 @@ static struct sm_obj_form *sm_root[] = { &power_group, &keyboard_group, &devices_group, + &security_group, &pci_group, &coreboot_group, NULL diff --git a/src/mainboard/starlabs/starbook/cfr.c b/src/mainboard/starlabs/starbook/cfr.c index ab5f84e663..d317d2e531 100644 --- a/src/mainboard/starlabs/starbook/cfr.c +++ b/src/mainboard/starlabs/starbook/cfr.c @@ -84,6 +84,14 @@ static struct sm_obj_form devices_group = { }, }; +static struct sm_obj_form security_group = { + .ui_name = "Security", + .obj_list = (const struct sm_object *[]) { + &intel_tme, + NULL + }, +}; + static struct sm_obj_form pci_group = { .ui_name = "PCI", .obj_list = (const struct sm_object *[]) { @@ -117,6 +125,7 @@ static struct sm_obj_form *sm_root[] = { &power_group, &keyboard_group, &devices_group, + &security_group, &pci_group, &coreboot_group, NULL diff --git a/src/mainboard/starlabs/starfighter/cfr.c b/src/mainboard/starlabs/starfighter/cfr.c index 01488d4865..e925fa731c 100644 --- a/src/mainboard/starlabs/starfighter/cfr.c +++ b/src/mainboard/starlabs/starfighter/cfr.c @@ -73,6 +73,14 @@ static struct sm_obj_form devices_group = { }, }; +static struct sm_obj_form security_group = { + .ui_name = "Security", + .obj_list = (const struct sm_object *[]) { + &intel_tme, + NULL + }, +}; + static struct sm_obj_form pci_group = { .ui_name = "PCI", .obj_list = (const struct sm_object *[]) { @@ -102,6 +110,7 @@ static struct sm_obj_form *sm_root[] = { &power_group, &keyboard_group, &devices_group, + &security_group, &pci_group, &coreboot_group, NULL diff --git a/src/mainboard/starlabs/starlite_adl/cfr.c b/src/mainboard/starlabs/starlite_adl/cfr.c index 6416dc4a77..62370cfc2d 100644 --- a/src/mainboard/starlabs/starlite_adl/cfr.c +++ b/src/mainboard/starlabs/starlite_adl/cfr.c @@ -75,6 +75,14 @@ static struct sm_obj_form devices_group = { }, }; +static struct sm_obj_form security_group = { + .ui_name = "Security", + .obj_list = (const struct sm_object *[]) { + &intel_tme, + NULL + }, +}; + static struct sm_obj_form pci_group = { .ui_name = "PCI", .obj_list = (const struct sm_object *[]) { @@ -100,6 +108,7 @@ static struct sm_obj_form *sm_root[] = { &processor_group, &power_group, &devices_group, + &security_group, &pci_group, &coreboot_group, NULL From d216ea151c1b14a2d7ce74dc5a65ca7895188d91 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 19 Jan 2026 10:44:30 +0530 Subject: [PATCH 232/789] mb/google/bluey: Change ADSP I2C transfer mode to MIXED Update QUPV3_2_SE4 (ADSP I2C) configuration to use MIXED mode instead of GSI. This allows the I2C controller for the charger and fuel gauge to handle both GSI (DMA) and non-GSI transfers, ensuring better compatibility during different boot stages. BUG=b:472358270 BRANCH=None TEST=TBD. Change-Id: Ie2ed3cd6991c3d98b7902c1331e68ec5a4f35d92 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90796 Tested-by: build bot (Jenkins) Reviewed-by: Jayvik Desai Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/mainboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 6551976f55..ea0e8a4851 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -171,7 +171,7 @@ static void mainboard_init(struct device *dev) qupv3_se_fw_load_and_init(QUPV3_0_SE0, SE_PROTOCOL_I2C, MIXED); /* Trackpad I2C */ /* ADSP I2C (Charger/Fuel gauge) */ - qupv3_se_fw_load_and_init(QUPV3_2_SE4, SE_PROTOCOL_I2C, GSI); + qupv3_se_fw_load_and_init(QUPV3_2_SE4, SE_PROTOCOL_I2C, MIXED); if (CONFIG(MAINBOARD_HAS_PS8820_RETIMER)) { From a7a627d8f50ac9b9428a4183377babf6ebd77289 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 20 Jan 2026 16:19:18 +0530 Subject: [PATCH 233/789] ec/google/chromeec: Add helper to set LED RGB colors This patch adds google_chromeec_set_lightbar_rgb() to allow mainboards to manually control the individual LED colors. This is useful for providing visual feedback during early boot or platform-specific events, such as low-battery warnings. TEST=Build and boot google/fatcat. Change-Id: I146006511ea727787ea496b0674b67fa950ce8f2 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90807 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/ec/google/chromeec/ec.c | 36 ++++++++++++++++++++++++++++++++++++ src/ec/google/chromeec/ec.h | 16 ++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index ee04d4a669..b9d53e7788 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -1945,3 +1945,39 @@ int google_chromeec_read_batt_state_of_charge(uint32_t *state) return ret; } + +/* + * Set the RGB color of a specific LED on the Lightbar. + * + * This function communicates with the Embedded Controller (EC) + * to update the color of an individual LED. + * + * led: The index of the LED to be updated. + * red: Red intensity value (0x00 - 0xff). + * green: Green intensity value (0x00 - 0xff). + * blue: Blue intensity value (0x00 - 0xff). + * Return: 0 on success, or a non-zero error code from the EC host command. + */ +int google_chromeec_set_lightbar_rgb(unsigned int led, int red, int green, + int blue) +{ + const struct ec_params_lightbar req = { + .cmd = LIGHTBAR_CMD_SET_RGB, + .set_rgb = { + .led = led, + .red = red, + .green = green, + .blue = blue + } + }; + + struct chromeec_command cmd = { + .cmd_code = EC_CMD_LIGHTBAR_CMD, + .cmd_size_out = 0, + .cmd_data_out = NULL, + .cmd_size_in = sizeof(req), + .cmd_data_in = &req, + }; + + return google_chromeec_command(&cmd); +} diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index e4120dabeb..e5a4b0647d 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -546,4 +546,20 @@ void chipset_ioport_range(uint16_t *base, size_t *size); */ int google_chromeec_read_batt_state_of_charge(uint32_t *state); +/* + * Set the RGB color of a specific LED on the Lightbar. + * + * This function communicates with the Embedded Controller (EC) + * to update the color of an individual LED. + * + * @param led: The index of the LED to be updated. + * @param red: Red intensity value (0x00 - 0xff). + * @param green: Green intensity value (0x00 - 0xff). + * @param blue: Blue intensity value (0x00 - 0xff). + * + * @return 0 on success, or a non-zero error code from the EC host command. + */ +int google_chromeec_set_lightbar_rgb(unsigned int led, int red, int green, + int blue); + #endif /* _EC_GOOGLE_CHROMEEC_EC_H */ From e8e3fc9cf7dcf71e9f6ffe701176167268c2aa2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 4 Dec 2025 15:36:43 +0100 Subject: [PATCH 234/789] vendorcode/amd/opensil/turin_poc: Add turin_poc as a copy of genoa_poc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a copy of genoa_poc OpenSIL directory with all genoa occurrences changed to turin. Submodule has been omitted. Adjustment for Turin OpenSIL will be made in subsequent patch. Change-Id: I71e3b85f162971d6497783d4631a33780dc0e560 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/90369 Reviewed-by: Felix Held Tested-by: build bot (Jenkins) --- .../amd/opensil/turin_poc/Makefile.mk | 18 ++ src/vendorcode/amd/opensil/turin_poc/acpi.c | 24 +++ src/vendorcode/amd/opensil/turin_poc/filter.h | 23 ++ src/vendorcode/amd/opensil/turin_poc/memmap.c | 57 +++++ .../opensil/turin_poc/meson_cross.template | 35 +++ .../amd/opensil/turin_poc/mpio/Makefile.mk | 5 + .../amd/opensil/turin_poc/mpio/chip.c | 202 ++++++++++++++++++ .../amd/opensil/turin_poc/mpio/chip.h | 71 ++++++ .../opensil/turin_poc/opensil_config.template | 5 + .../amd/opensil/turin_poc/opensil_console.c | 44 ++++ .../amd/opensil/turin_poc/opensil_console.h | 9 + .../amd/opensil/turin_poc/ramstage.c | 180 ++++++++++++++++ .../amd/opensil/turin_poc/romstage.c | 17 ++ 13 files changed, 690 insertions(+) create mode 100644 src/vendorcode/amd/opensil/turin_poc/Makefile.mk create mode 100644 src/vendorcode/amd/opensil/turin_poc/acpi.c create mode 100644 src/vendorcode/amd/opensil/turin_poc/filter.h create mode 100644 src/vendorcode/amd/opensil/turin_poc/memmap.c create mode 100644 src/vendorcode/amd/opensil/turin_poc/meson_cross.template create mode 100644 src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk create mode 100644 src/vendorcode/amd/opensil/turin_poc/mpio/chip.c create mode 100644 src/vendorcode/amd/opensil/turin_poc/mpio/chip.h create mode 100644 src/vendorcode/amd/opensil/turin_poc/opensil_config.template create mode 100644 src/vendorcode/amd/opensil/turin_poc/opensil_console.c create mode 100644 src/vendorcode/amd/opensil/turin_poc/opensil_console.h create mode 100644 src/vendorcode/amd/opensil/turin_poc/ramstage.c create mode 100644 src/vendorcode/amd/opensil/turin_poc/romstage.c diff --git a/src/vendorcode/amd/opensil/turin_poc/Makefile.mk b/src/vendorcode/amd/opensil/turin_poc/Makefile.mk new file mode 100644 index 0000000000..62bd00bf91 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/Makefile.mk @@ -0,0 +1,18 @@ +## SPDX-License-Identifier: GPL-2.0-only + +subdirs-y += mpio + +CPPFLAGS_common += -I$(opensil_dir)/Include -I$(opensil_dir)/xUSL -I$(opensil_dir)/xUSL/Include -I$(opensil_dir)/xUSL/FCH -I$(opensil_dir)/xUSL/FCH/Common -I$(opensil_dir)/xSIM -I$(opensil_dir)/xPRF + +romstage-y += opensil_console.c +romstage-y += romstage.c + +ramstage-y += acpi.c +ramstage-y += memmap.c +ramstage-y += opensil_console.c +ramstage-y += ramstage.c + +$(obj)/romstage/vendorcode/amd/opensil/turin_poc/opensil_console.o: CFLAGS_romstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas +$(obj)/romstage/vendorcode/amd/opensil/turin_poc/romstage.o: CFLAGS_romstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas + +$(obj)/ramstage/vendorcode/amd/opensil/turin_poc/opensil_console.o: CFLAGS_ramstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas diff --git a/src/vendorcode/amd/opensil/turin_poc/acpi.c b/src/vendorcode/amd/opensil/turin_poc/acpi.c new file mode 100644 index 0000000000..fcdf167c12 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/acpi.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +#include "../opensil.h" + +void opensil_fill_fadt(acpi_fadt_t *fadt) +{ + FCHHWACPI_INPUT_BLK *blk = SilFindStructure(SilId_FchHwAcpiP, 0); + + fadt->pm1a_evt_blk = blk->AcpiPm1EvtBlkAddr; + fadt->pm1a_cnt_blk = blk->AcpiPm1CntBlkAddr; + fadt->pm_tmr_blk = blk->AcpiPmTmrBlkAddr; + fadt->gpe0_blk = blk->AcpiGpe0BlkAddr; +} + +unsigned long add_opensil_acpi_table(unsigned long current, acpi_rsdp_t *rsdp) +{ + return current; +} diff --git a/src/vendorcode/amd/opensil/turin_poc/filter.h b/src/vendorcode/amd/opensil/turin_poc/filter.h new file mode 100644 index 0000000000..f0817f7502 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/filter.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Keep this in sync with openSIL SilCommon.h file */ +#define DEBUG_FILTER_APOB 0x00000001UL +#define DEBUG_FILTER_NBIO 0x00000002UL +#define DEBUG_FILTER_CCX 0x00000004UL +#define DEBUG_FILTER_SMU 0x00000008UL +#define DEBUG_FILTER_DF 0x00000010UL +#define DEBUG_FILTER_MEM 0x00000040UL +#define DEBUG_FILTER_FCH 0x00000080UL +#define DEBUG_FILTER_RAS 0x00000100UL + +#define SIL_DEBUG(topic) (CONFIG(OPENSIL_DEBUG_##topic) ? DEBUG_FILTER_##topic : 0) + +#define SIL_DEBUG_MODULE_FILTER ( \ + SIL_DEBUG(APOB) | \ + SIL_DEBUG(NBIO) | \ + SIL_DEBUG(CCX) | \ + SIL_DEBUG(SMU) | \ + SIL_DEBUG(DF) | \ + SIL_DEBUG(MEM) | \ + SIL_DEBUG(FCH) | \ + SIL_DEBUG(RAS) ) diff --git a/src/vendorcode/amd/opensil/turin_poc/memmap.c b/src/vendorcode/amd/opensil/turin_poc/memmap.c new file mode 100644 index 0000000000..eed1be7e5f --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/memmap.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include // needed above ApobCmn.h +#include +#include + +#include "../opensil.h" + +_Static_assert(sizeof(uint32_t) == sizeof(((MEMORY_HOLE_DESCRIPTOR){0}).Type), + "Unexpected size of MEMORY_HOLE_TYPES in the MEMORY_HOLE_DESCRIPTOR " + "struct which doesn't match the code in drivers/amd/opensil/memmap.c"); + +const char *opensil_get_hole_info_type(uint32_t type) +{ + const struct hole_type { + MEMORY_HOLE_TYPES type; + const char *string; + } types[] = { + {UMA, "UMA"}, + {MMIO, "MMIO"}, + {PrivilegedDRAM, "PrivilegedDRAM"}, + {Reserved1TbRemap, "Reserved1TbRemap"}, + {ReservedSLink, "ReservedSLink"}, + {ReservedSLinkAlignment, "ReservedSLinkAlignment"}, + {ReservedDrtm, "ReservedDrtm"}, + {ReservedCvip, "ReservedCvip"}, + {ReservedSmuFeatures, "ReservedSmuFeatures"}, + {ReservedFwtpm, "ReservedFwtpm"}, + {ReservedMpioC20, "ReservedMpioC20"}, + {ReservedNbif, "ReservedNbif"}, + {ReservedCxl, "ReservedCxl"}, + {ReservedCxlAlignment, "ReservedCxlAlignment"}, + {ReservedCpuTmr, "ReservedCpuTmr"}, + {ReservedRasEinj, "ReservedRasEinj"}, + {MaxMemoryHoleTypes, "MaxMemoryHoleTypes"}, + }; + + int i; + MEMORY_HOLE_TYPES enum_type = (MEMORY_HOLE_TYPES)type; // Cast int to enum + for (i = 0; i < ARRAY_SIZE(types); i++) + if (enum_type == types[i].type) + return types[i].string; + return "Unknown type"; +} + +void opensil_get_hole_info(uint32_t *n_holes, uint64_t *top_of_mem, void **hole_info) +{ + SIL_STATUS status = xPrfGetSystemMemoryMap(n_holes, top_of_mem, hole_info); + SIL_STATUS_report("xPrfGetSystemMemoryMap", status); + // Make sure hole_info does not get initialized to something odd by xPRF on failure + if (status != SilPass) { + *hole_info = NULL; + *n_holes = 0; + *top_of_mem = 0; + } +} diff --git a/src/vendorcode/amd/opensil/turin_poc/meson_cross.template b/src/vendorcode/amd/opensil/turin_poc/meson_cross.template new file mode 100644 index 0000000000..6473b65225 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/meson_cross.template @@ -0,0 +1,35 @@ +[binaries] +c = '##COMPILER##' +ar = '##AR##' +nasm = '##NASM##' + +[built-in options] +c_args = ['-nostdinc', + '-I##OBJPATH##', + '-I##COREBOOT_DIR##/src/include', + '-I##COREBOOT_DIR##/src/arch/x86/include', + '-I##COREBOOT_DIR##/src/commonlib/include', + '-I##COREBOOT_DIR##/src/commonlib/bsd/include', + '-include', '##COREBOOT_DIR##/src/include/kconfig.h', + '-include', '##OBJPATH##/config.h', + '-include', '##COREBOOT_DIR##/src/commonlib/bsd/include/commonlib/bsd/compiler.h', + '-include', '##OPENSIL_DIR##/../filter.h', + '-DHAS_STRING_H=1', + # openSIL isn't compatible with coreboot's assert implementation, so use special case + '-D_PORTING_H_=1', + '-DSIL_DEBUG_ENABLE=##SIL_DEBUG_ENABLE##', + # openSIL uses coreboot assert which uses printk which warns about unused-param + '-Wno-unused-parameter', + # ubiquitous problem in openSIL + '-Wno-missing-field-initializers', + ##CLANG_ARGS## + ] + +[host_machine] +system = 'linux' +cpu_family = '##CPU_FAMILY##' +cpu = '##CPU##' +endian = 'little' + +[properties] +is32bit = ##IS32BIT## diff --git a/src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk b/src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk new file mode 100644 index 0000000000..fafdc5935f --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-y += chip.c + +$(obj)/ramstage/vendorcode/amd/opensil/turin_poc/mpio/chip.o: CFLAGS_ramstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas diff --git a/src/vendorcode/amd/opensil/turin_poc/mpio/chip.c b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.c new file mode 100644 index 0000000000..587ab81e02 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.c @@ -0,0 +1,202 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "chip.h" + +static void mpio_params_config(void) +{ + MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0); + mpio_data->CfgDxioClockGating = 1; + mpio_data->PcieDxioTimingControlEnable = 0; + mpio_data->PCIELinkReceiverDetectionPolling = 0; + mpio_data->PCIELinkResetToTrainingTime = 0; + mpio_data->PCIELinkL0Polling = 0; + mpio_data->PCIeExactMatchEnable = 0; + mpio_data->DxioPhyValid = 1; + mpio_data->DxioPhyProgramming = 1; + mpio_data->CfgSkipPspMessage = 1; + mpio_data->DxioSaveRestoreModes = 0xff; + mpio_data->AmdAllowCompliance = 0; + mpio_data->AmdAllowCompliance = 0xff; + mpio_data->SrisEnableMode = 0xff; + mpio_data->SrisSkipInterval = 0; + mpio_data->SrisSkpIntervalSel = 1; + mpio_data->SrisCfgType = 0; + mpio_data->SrisAutoDetectMode = 0xff; + mpio_data->SrisAutodetectFactor = 0; + mpio_data->SrisLowerSkpOsGenSup = 0; + mpio_data->SrisLowerSkpOsRcvSup = 0; + mpio_data->AmdCxlOnAllPorts = 1; + mpio_data->CxlCorrectableErrorLogging = 1; + mpio_data->CxlUnCorrectableErrorLogging = 1; + // This is also available in Nbio. How to handle duplicate entries? + mpio_data->CfgAEREnable = 1; + mpio_data->CfgMcCapEnable = 0; + mpio_data->CfgRcvErrEnable = 0; + mpio_data->EarlyBmcLinkTraining = 1; + mpio_data->SurpriseDownFeature = 1; + mpio_data->LcMultAutoSpdChgOnLastRateEnable = 0; + mpio_data->AmdRxMarginEnabled = 1; + mpio_data->CfgPcieCVTestWA = 1; + mpio_data->CfgPcieAriSupport = 1; + mpio_data->CfgNbioCTOtoSC = 0; + mpio_data->CfgNbioCTOIgnoreError = 1; + mpio_data->CfgNbioSsid = 0; + mpio_data->CfgIommuSsid = 0; + mpio_data->CfgPspccpSsid = 0; + mpio_data->CfgNtbccpSsid = 0; + mpio_data->CfgNbifF0Ssid = 0; + mpio_data->CfgNtbSsid = 0; + mpio_data->AmdPcieSubsystemDeviceID = 0x1453; + mpio_data->AmdPcieSubsystemVendorID = 0x1022; + mpio_data->GppAtomicOps = 1; + mpio_data->GfxAtomicOps = 1; + mpio_data->AmdNbioReportEdbErrors = 0; + mpio_data->OpnSpare = 0; + mpio_data->AmdPreSilCtrl0 = 0; + mpio_data->MPIOAncDataSupport = 1; + mpio_data->AfterResetDelay = 0; + mpio_data->CfgEarlyLink = 0; + mpio_data->AmdCfgExposeUnusedPciePorts = 1; // Show all ports + mpio_data->CfgForcePcieGenSpeed = 0; + mpio_data->CfgSataPhyTuning = 0; + mpio_data->PcieLinkComplianceModeAllPorts = 0; + mpio_data->AmdMCTPEnable = 0; + mpio_data->SbrBrokenLaneAvoidanceSup = 1; + mpio_data->AutoFullMarginSup = 1; + // A getter and setter, both are needed for this PCD. + mpio_data->AmdPciePresetMask8GtAllPort = 0xffffffff; + // A getter and setter, both are needed for this PCD. + mpio_data->AmdPciePresetMask16GtAllPort = 0xffffffff; + // A getter and setter, both are needed for this PCD. + mpio_data->AmdPciePresetMask32GtAllPort = 0xffffffff; + mpio_data->PcieLinkAspmAllPort = 0xff; + + mpio_data->SyncHeaderByPass = 1; + mpio_data->CxlTempGen5AdvertAltPtcl = 0; + + /* TODO handle this differently on multisocket */ + mpio_data->PcieTopologyData.PlatformData[0].Flags = DESCRIPTOR_TERMINATE_LIST; + mpio_data->PcieTopologyData.PlatformData[0].PciePortList = mpio_data->PcieTopologyData.PortList; +} + +static void nbio_params_config(void) +{ + NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0); + NBIOCLASS_INPUT_BLK *input = &nbio_data->NbioInputBlk; + input->CfgHdAudioEnable = false; + input->EsmEnableAllRootPorts = false; + input->EsmTargetSpeed = 16; + input->CfgRxMarginPersistenceMode = 1; + input->CfgDxioFrequencyVetting = false; + input->CfgSkipPspMessage = 1; + input->CfgEarlyTrainTwoPcieLinks = false; + input->EarlyBmcLinkTraining = true; + input->EdpcEnable = 0; + input->PcieAerReportMechanism = 2; + input->SevSnpSupport = false; +} + +static void setup_bmc_lanes(uint8_t lane, uint8_t socket) +{ + DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0); + rc_mgr_input_block->BmcSocket = socket; + rc_mgr_input_block->EarlyBmcLinkLaneNum = lane; + + NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0); + NBIOCLASS_INPUT_BLK *nbio_input = &nbio_data->NbioInputBlk; + nbio_input->EarlyBmcLinkSocket = socket; + nbio_input->EarlyBmcLinkLaneNum = lane; + nbio_input->EarlyBmcLinkDie = 0; + + MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0); + mpio_data->EarlyBmcLinkSocket = socket; + mpio_data->EarlyBmcLinkLaneNum = lane; + mpio_data->EarlyBmcLinkDie = 0; +} + +void opensil_mpio_per_device_config(struct device *dev) +{ + /* Cache *mpio_data from SilFindStructure */ + static MPIOCLASS_INPUT_BLK *mpio_data = NULL; + if (mpio_data == NULL) { + mpio_data = SilFindStructure(SilId_MpioClass, 0); + } + + static uint32_t slot_num; + const uint32_t domain = dev_get_domain_id(dev); + const uint32_t devfn = dev->path.pci.devfn; + const struct drivers_amd_opensil_mpio_config *const config = dev->chip_info; + printk(BIOS_DEBUG, "Setting MPIO port for domain 0x%x, PCI %d:%d\n", + domain, PCI_SLOT(devfn), PCI_FUNC(devfn)); + + if (config->type == IFTYPE_UNUSED) { + if (is_dev_enabled(dev)) { + printk(BIOS_WARNING, "Unused MPIO chip, disabling PCI device.\n"); + dev->enabled = false; + } else { + printk(BIOS_DEBUG, "Unused MPIO chip, skipping.\n"); + } + return; + } + + if (config->bmc) { + setup_bmc_lanes(config->start_lane, 0); // TODO support multiple sockets + return; + } + + static int mpio_port = 0; + MPIO_PORT_DESCRIPTOR port = { .Flags = DESCRIPTOR_TERMINATE_LIST }; + if (config->type == IFTYPE_PCIE) { + const MPIO_ENGINE_DATA engine_data = + MPIO_ENGINE_DATA_INITIALIZER(MpioPcieEngine, + config->start_lane, config->end_lane, + config->hotplug == HotplugDisabled ? 0 : 1, + config->gpio_group); + port.EngineData = engine_data; + const MPIO_PORT_DATA port_data = + MPIO_PORT_DATA_INITIALIZER_PCIE(is_dev_enabled(dev) ? + MpioPortEnabled : MpioPortDisabled, + PCI_SLOT(devfn), + PCI_FUNC(devfn), + config->hotplug, + config->speed, + 0, // No backup PCIe speed + config->aspm, + config->aspm_l1_1, + config->aspm_l1_2, + config->clock_pm); + port.Port = port_data; + } else if (config->type == IFTYPE_SATA) { + const MPIO_ENGINE_DATA engine_data = + MPIO_ENGINE_DATA_INITIALIZER(MpioSATAEngine, + config->start_lane, config->end_lane, + 0, // meaningless field + config->gpio_group); + port.EngineData = engine_data; + const MPIO_PORT_DATA port_data = { .PortPresent = 1 }; + port.Port = port_data; + + } + port.Port.AlwaysExpose = 1; + port.Port.SlotNum = ++slot_num; + mpio_data->PcieTopologyData.PortList[mpio_port] = port; + /* Update TERMINATE list */ + if (mpio_port > 0) + mpio_data->PcieTopologyData.PortList[mpio_port - 1].Flags = 0; + mpio_port++; +} + +void opensil_mpio_global_config(void) +{ + mpio_params_config(); + nbio_params_config(); +} diff --git a/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h new file mode 100644 index 0000000000..ce5468cbde --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef OPENSIL_TURIN_POC_MPIO_CHIP_H +#define OPENSIL_TURIN_POC_MPIO_CHIP_H + +#include + +/* + * TURIN MPIO mapping + * P0 -> [0-15] + * G0 -> [16-31] + * P1 -> [32-47] + * G1 -> [48-63] + * P2 -> [64-79] + * G2 -> [80-95] + * P3 -> [96-111] + * G3 -> [112-127] + * P4 -> [128-131] + * P5 -> [132-136] + */ + +enum mpio_type { + IFTYPE_UNUSED, + IFTYPE_PCIE, + IFTYPE_SATA, +}; + +/* Sync with PCIE_HOTPLUG_TYPE */ +enum mpio_hotplug { + HotplugDisabled, ///< Hotplug disable + Basic, ///< Basic Hotplug + ServerExpress, ///< Server Hotplug Express Module + Enhanced, ///< Enhanced + Inboard, ///< Inboard + ServerEntSSD, ///< Server Hotplug Enterprise SSD + UBM, ///< UBM Backplane + OCP, ///< OCP NIC 3.0 +}; + +enum pcie_link_speed { + MaxSupported, + Gen1, + Gen2, + Gen3, + Gen4, + Gen5, +}; + +/* Sync with PCIE_ASPM_TYPE */ +enum pcie_aspm { + aspm_disabled, + L0s, + L1, + L0sL1, +}; + +struct drivers_amd_opensil_mpio_config { + enum mpio_type type; + uint8_t start_lane; + uint8_t end_lane; + uint8_t gpio_group; + enum mpio_hotplug hotplug; + enum pcie_link_speed speed; + enum pcie_aspm aspm; + uint8_t aspm_l1_1 : 1; + uint8_t aspm_l1_2 : 1; + uint8_t clock_pm : 1; + uint8_t bmc : 1; +}; + +#endif /* OPENSIL_TURIN_POC_MPIO_CHIP_H */ diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil_config.template b/src/vendorcode/amd/opensil/turin_poc/opensil_config.template new file mode 100644 index 0000000000..2ddd3b4ec1 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/opensil_config.template @@ -0,0 +1,5 @@ +CONFIG_PLAT_APOB_ADDRESS=##APOB_BASE## +CONFIG_PSP_BIOS_BIN_BASE=##BIOS_ENTRY_BASE## +CONFIG_PSP_BIOS_BIN_SIZE=##BIOS_ENTRY_SIZE## +CONFIG_PLAT_NUMBER_SOCKETS=1 +CONFIG_SOC_F19M10=y diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil_console.c b/src/vendorcode/amd/opensil/turin_poc/opensil_console.c new file mode 100644 index 0000000000..35e5eeb2b4 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/opensil_console.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include "opensil_console.h" +#include + +static int translate_opensil_debug_level(size_t MsgLevel) +{ + switch (MsgLevel) { + case SIL_TRACE_ERROR: + return BIOS_ERR; + case SIL_TRACE_WARNING: + return BIOS_WARNING; + case SIL_TRACE_ENTRY: + case SIL_TRACE_EXIT: + return BIOS_SPEW; + case SIL_TRACE_INFO: + return BIOS_DEBUG; + default: + return BIOS_NEVER; + } +} + +void HostDebugService(size_t MsgLevel, const char *SilPrefix, const char *Message, + const char *Function, size_t Line, ...) +{ + if (!CONFIG(OPENSIL_DEBUG_OUTPUT)) + return; + + const int loglevel = translate_opensil_debug_level(MsgLevel); + + /* print fomatted prefix */ + if (CONFIG(OPENSIL_DEBUG_PREFIX)) + printk(loglevel, "%s%s:%zu:", SilPrefix, Function, Line); + + /* print formatted message */ + va_list args; + va_start(args, Line); + vprintk(loglevel, Message, args); + va_end(args); +} diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil_console.h b/src/vendorcode/amd/opensil/turin_poc/opensil_console.h new file mode 100644 index 0000000000..d3ffb6857f --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/opensil_console.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _VENDORCODE_AND_OPENSIL_CONSOLE +#define _VENDORCODE_AND_OPENSIL_CONSOLE + +void HostDebugService(size_t MsgLevel, const char *SilPrefix, const char *Message, + const char *Function, size_t Line, ...); + +#endif diff --git a/src/vendorcode/amd/opensil/turin_poc/ramstage.c b/src/vendorcode/amd/opensil/turin_poc/ramstage.c new file mode 100644 index 0000000000..f4474f0be5 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/ramstage.c @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "opensil_console.h" +#include "../opensil.h" + +void SIL_STATUS_report(const char *function, const int status) +{ + const int log_level = status == SilPass ? BIOS_DEBUG : BIOS_ERR; + const char *error_string = "Unknown error"; + + const struct error_string_entry { + SIL_STATUS status; + const char *string; + } errors[] = { + {SilPass, "SilPass"}, + {SilUnsupportedHardware, "SilUnsupportedHardware"}, + {SilUnsupported, "SilUnsupported"}, + {SilInvalidParameter, "SilInvalidParameter"}, + {SilAborted, "SilAborted"}, + {SilOutOfResources, "SilOutOfResources"}, + {SilNotFound, "SilNotFound"}, + {SilOutOfBounds, "SilOutOfBounds"}, + {SilDeviceError, "SilDeviceError"}, + {SilResetRequestColdImm, "SilResetRequestColdImm"}, + {SilResetRequestColdDef, "SilResetRequestColdDef"}, + {SilResetRequestWarmImm, "SilResetRequestWarmImm"}, + {SilResetRequestWarmDef, "SilResetRequestWarmDef"}, + }; + + int i; + for (i = 0; i < ARRAY_SIZE(errors); i++) { + if (errors[i].status == status) + error_string = errors[i].string; + } + printk(log_level, "%s returned %d (%s)\n", function, status, error_string); +} + +static void setup_rc_manager_default(void) +{ + DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0); + /* Let openSIL distribute the resources to the different PCI roots */ + rc_mgr_input_block->SetRcBasedOnNv = false; + + /* Currently 1P is the only supported configuration */ + rc_mgr_input_block->SocketNumber = 1; + rc_mgr_input_block->RbsPerSocket = 4; /* PCI root bridges per socket */ + rc_mgr_input_block->McptEnable = true; + rc_mgr_input_block->PciExpressBaseAddress = CONFIG_ECAM_MMCONF_BASE_ADDRESS; + rc_mgr_input_block->BottomMmioReservedForPrimaryRb = 4ull * GiB - 32 * MiB; + rc_mgr_input_block->MmioSizePerRbForNonPciDevice = 16 * MiB; + /* MmioAbove4GLimit will be adjusted down in openSIL */ + rc_mgr_input_block->MmioAbove4GLimit = POWER_OF_2(cpu_phys_address_size()); + rc_mgr_input_block->Above4GMmioSizePerRbForNonPciDevice = 0; +} + +#define NUM_XHCI_CONTROLLERS 2 +static void configure_usb(void) +{ + const struct soc_amd_turin_poc_config *soc_config = config_of_soc(); + const struct soc_usb_config *usb = &soc_config->usb; + + FCHUSB_INPUT_BLK *fch_usb_data = SilFindStructure(SilId_FchUsb, 0); + fch_usb_data->Xhci0Enable = usb->xhci0_enable; + fch_usb_data->Xhci1Enable = usb->xhci1_enable; + fch_usb_data->Xhci2Enable = false; /* there's no XHCI2 on this SoC */ + for (int i = 0; i < NUM_XHCI_CONTROLLERS; i++) { + memcpy(&fch_usb_data->XhciOCpinSelect[i].Usb20OcPin, &usb->usb2_oc_pins[i], + sizeof(fch_usb_data->XhciOCpinSelect[i].Usb20OcPin)); + memcpy(&fch_usb_data->XhciOCpinSelect[i].Usb31OcPin, &usb->usb3_oc_pins[i], + sizeof(fch_usb_data->XhciOCpinSelect[i].Usb31OcPin)); + } + fch_usb_data->XhciOcPolarityCfgLow = usb->polarity_cfg_low; + fch_usb_data->Usb3PortForceGen1 = usb->usb3_force_gen1.raw; + + /* Instead of overwriting the whole OemUsbConfigurationTable, only copy the relevant + fields to the pre-populated data structure */ + fch_usb_data->OemUsbConfigurationTable.Usb31PhyEnable = usb->usb31_phy_enable; + if (usb->usb31_phy_enable) + memcpy(&fch_usb_data->OemUsbConfigurationTable.Usb31PhyPort, usb->usb31_phy, + sizeof(fch_usb_data->OemUsbConfigurationTable.Usb31PhyPort)); + fch_usb_data->OemUsbConfigurationTable.Usb31PhyEnable = usb->s1_usb31_phy_enable; + if (usb->s1_usb31_phy_enable) + memcpy(&fch_usb_data->OemUsbConfigurationTable.S1Usb31PhyPort, usb->s1_usb31_phy, + sizeof(fch_usb_data->OemUsbConfigurationTable.S1Usb31PhyPort)); +} + +#define NUM_SATA_CONTROLLERS 4 +static void configure_sata(void) +{ + FCHSATA_INPUT_BLK *fch_sata_data = SilFindStructure(SilId_FchSata, 0); + FCH_SATA2 *fch_sata_defaults = GetFchSataData(); + for (int i = 0; i < NUM_SATA_CONTROLLERS; i++) { + fch_sata_data[i] = fch_sata_defaults[i]; + fch_sata_data[i].SataSetMaxGen2 = false; + fch_sata_data[i].SataMsiEnable = true; + fch_sata_data[i].SataEspPort = 0xFF; + fch_sata_data[i].SataRasSupport = true; + fch_sata_data[i].SataDevSlpPort1Num = 1; + fch_sata_data[i].SataMsiEnable = true; + fch_sata_data[i].SataControllerAutoShutdown = true; + fch_sata_data[i].SataRxPolarity = 0xFF; + } +} + +void setup_opensil(void) +{ + const SIL_STATUS debug_ret = SilDebugSetup(HostDebugService); + SIL_STATUS_report("SilDebugSetup", debug_ret); + const size_t mem_req = xSimQueryMemoryRequirements(); + void *buf = cbmem_add(CBMEM_ID_AMD_OPENSIL, mem_req); + assert(buf); + /* We run all openSIL timepoints in the same stage so using TP1 as argument is fine. */ + const SIL_STATUS assign_mem_ret = xSimAssignMemoryTp1(buf, mem_req); + SIL_STATUS_report("xSimAssignMemory", assign_mem_ret); + + setup_rc_manager_default(); + configure_usb(); + configure_sata(); +} + +static void opensil_entry(SIL_TIMEPOINT timepoint) +{ + SIL_STATUS ret; + SIL_TIMEPOINT tp = (uintptr_t)timepoint; + + switch (tp) { + case SIL_TP1: + ret = InitializeSiTp1(); + break; + case SIL_TP2: + ret = InitializeSiTp2(); + break; + case SIL_TP3: + ret = InitializeSiTp3(); + break; + default: + printk(BIOS_ERR, "Unknown openSIL timepoint\n"); + return; + } + char opensil_function[16]; + snprintf(opensil_function, sizeof(opensil_function), "InitializeSiTp%d", tp + 1); + SIL_STATUS_report(opensil_function, ret); + if (ret == SilResetRequestColdImm || ret == SilResetRequestColdDef) { + printk(BIOS_INFO, "openSIL requested a cold reset"); + do_cold_reset(); + } else if (ret == SilResetRequestWarmImm || ret == SilResetRequestWarmDef) { + printk(BIOS_INFO, "openSIL requested a warm reset"); + do_warm_reset(); + } +} + +void opensil_xSIM_timepoint_1(void) +{ + opensil_entry(SIL_TP1); +} + +void opensil_xSIM_timepoint_2(void) +{ + opensil_entry(SIL_TP2); +} + +void opensil_xSIM_timepoint_3(void) +{ + opensil_entry(SIL_TP3); +} + +/* TODO: also call timepoints 2 and 3 from coreboot. Are they NOOP? */ diff --git a/src/vendorcode/amd/opensil/turin_poc/romstage.c b/src/vendorcode/amd/opensil/turin_poc/romstage.c new file mode 100644 index 0000000000..5b871f6025 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/romstage.c @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include "opensil_console.h" +#include +#include + +#include "../opensil.h" + +uintptr_t opensil_get_low_usable_dram_address(void) +{ + SilDebugSetup(HostDebugService); + uintptr_t low_usable_dram_addr = xPrfGetLowUsableDramAddress(0); + printk(BIOS_DEBUG, "xPrfGetLowUsableDramAddress: 0x%lx\n", low_usable_dram_addr); + + return low_usable_dram_addr; +} From 0750412241b256d653d555cdda3e51ddb49a884c Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Wed, 21 Jan 2026 17:25:06 +0800 Subject: [PATCH 235/789] soc/mediatek/mt8196: Fix missing read_resources for non-NVMe SKUs The following error will be shown on non-NVMe SKUs. [ERROR] DOMAIN: 00000000 missing read_resources That's because when mainboard_needs_pcie_init() returns false, dev->ops will be NULL, causing the '!curdev->ops || !curdev->ops->read_resources' check to fail in device/device.c read_resources(). To prevent the misleading error message from showing up, for non-NVMe SKUs, assign 'noop_domain_ops' to dev->ops. BUG=none TEST=emerge-tanjiro coreboot BRANCH=rauru Change-Id: If0f81aadda3fbde99f4df794cbdd885a607c9625 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90843 Reviewed-by: Yidi Lin Reviewed-by: Chen-Tsung Hsieh Tested-by: build bot (Jenkins) --- src/soc/mediatek/mt8196/soc.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/soc/mediatek/mt8196/soc.c b/src/soc/mediatek/mt8196/soc.c index e988a76926..c739998383 100644 --- a/src/soc/mediatek/mt8196/soc.c +++ b/src/soc/mediatek/mt8196/soc.c @@ -104,15 +104,22 @@ static struct device_operations pci_domain_ops = { .enable = &mtk_pcie_domain_enable, }; +static struct device_operations noop_domain_ops = { + .read_resources = &noop_read_resources, + .set_resources = &noop_set_resources, +}; + static void enable_soc_dev(struct device *dev) { if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) { dev->ops = &soc_ops; } else if (dev->path.type == DEVICE_PATH_DOMAIN) { - if (mainboard_needs_pcie_init()) + if (mainboard_needs_pcie_init()) { dev->ops = &pci_domain_ops; - else + } else { printk(BIOS_DEBUG, "Skip setting PCIe ops\n"); + dev->ops = &noop_domain_ops; + } } } From 87731a704ae30549575a1c3d3c7b7858971147a5 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Wed, 21 Jan 2026 17:31:39 +0800 Subject: [PATCH 236/789] soc/mediatek/common/dp: Print unexpected eDP pattern in error log BUG=none TEST=emerge-tanjiro coreboot BRANCH=rauru Change-Id: Ib7f06a8da0f6ae89fa9ac2189f6c38b35362a609 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90844 Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Yidi Lin Tested-by: build bot (Jenkins) --- src/soc/mediatek/common/dp/dptx_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/mediatek/common/dp/dptx_v2.c b/src/soc/mediatek/common/dp/dptx_v2.c index 5b917a501a..81cfa76681 100644 --- a/src/soc/mediatek/common/dp/dptx_v2.c +++ b/src/soc/mediatek/common/dp/dptx_v2.c @@ -41,7 +41,7 @@ static void mtk_edp_pattern(struct mtk_dp *mtk_dp, u8 lane_count, u8 pattern) break; case DPTX_PATTERN_UNKNOWN: default: - printk(BIOS_ERR, "Set default or unknown pattern\n"); + printk(BIOS_ERR, "Set default or unknown pattern %d\n", pattern); mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, 0x0, PATTERN_EN_DP_TRANS_4P_MASK); return; } From ee2cbba939b362d644bf8ce7c8b6adb57b1f2d14 Mon Sep 17 00:00:00 2001 From: Chen-Tsung Hsieh Date: Thu, 22 Jan 2026 05:05:32 +0000 Subject: [PATCH 237/789] soc/mediatek/mt8196: Remove unused MTE_TAG_ADDR macro The MTE_TAG_ADDR macro is no longer used after the changes in CB:90144. Remove the unused definition. BUG=b:438666196 TEST=util/abuild/abuild -x -t GOOGLE_SAPPHIRE -a --clean BRANCH=none Change-Id: Ic71fa22292793162de882d3c764e7805301250c5 Signed-off-by: Chen-Tsung Hsieh Reviewed-on: https://review.coreboot.org/c/coreboot/+/90864 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu Reviewed-by: Yidi Lin --- src/soc/mediatek/mt8196/include/soc/booker.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/soc/mediatek/mt8196/include/soc/booker.h b/src/soc/mediatek/mt8196/include/soc/booker.h index 25c2d140af..ea819429fd 100644 --- a/src/soc/mediatek/mt8196/include/soc/booker.h +++ b/src/soc/mediatek/mt8196/include/soc/booker.h @@ -5,8 +5,6 @@ #include -#define MTE_TAG_ADDR 0x460E80000 - void booker_init(void); void booker_mte_init(uint64_t mte_tag_addr); From 4222a1ffd612c12e52528aa84cf6a5289998234c Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 16 Jan 2026 17:26:58 -0600 Subject: [PATCH 238/789] util/chromeos/crosfirmware.sh: Refactor dependency checking Refactor exit_if_dependencies_are_missing() to check all dependencies in a single pass using an associative array, collect any missing ones, and report them all together before exiting. This provides better UX by showing all missing dependencies at once rather than exiting after the first one. This replaces the previous approach that would exit immediately upon finding the first missing dependency, often causing users to run the script several times to identify and install all missing dependencies. Change-Id: Ieb03756b24fd2aa1af2c0ffaed717d06c9e85cbb Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90785 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- util/chromeos/crosfirmware.sh | 45 ++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/util/chromeos/crosfirmware.sh b/util/chromeos/crosfirmware.sh index 673f3b38a5..ab17c22ad6 100755 --- a/util/chromeos/crosfirmware.sh +++ b/util/chromeos/crosfirmware.sh @@ -5,27 +5,34 @@ # On some systems, `parted` and `debugfs` are located in /sbin. export PATH="$PATH:/sbin" -exit_if_uninstalled() { - local cmd_name="$1" - local deb_pkg_name="$2" +exit_if_dependencies_are_missing() { + local missing_deps=() + local -A deps_map=( + ["uudecode"]="sharutils" + ["debugfs"]="e2fsprogs" + ["parted"]="parted" + ["curl"]="curl" + ["unzip"]="unzip" + ) + + # Check all dependencies at once + for cmd_name in "${!deps_map[@]}"; do + if ! type "$cmd_name" >/dev/null 2>&1; then + missing_deps+=("$cmd_name:${deps_map[$cmd_name]}") + fi + done - if type "$cmd_name" >/dev/null 2>&1; then - return + # Exit if any dependencies are missing + if [ ${#missing_deps[@]} -gt 0 ]; then + printf 'The following required commands were not found:\n' >&2 + for dep_info in "${missing_deps[@]}"; do + cmd_name="${dep_info%%:*}" + deb_pkg_name="${dep_info##*:}" + printf ' - `%s`\n' "$cmd_name" >&2 + printf ' On Debian-based systems, install with: `apt install %s`\n' "$deb_pkg_name" >&2 + done + exit 1 fi - - printf '`%s` was not found. ' "$cmd_name" >&2 - printf 'On Debian-based systems, it can be installed\n' >&2 - printf 'by running `apt install %s`.\n' "$deb_pkg_name" >&2 - - exit 1 -} - -exit_if_dependencies_are_missing() { - exit_if_uninstalled "uudecode" "sharutils" - exit_if_uninstalled "debugfs" "e2fsprogs" - exit_if_uninstalled "parted" "parted" - exit_if_uninstalled "curl" "curl" - exit_if_uninstalled "unzip" "unzip" } get_inventory() { From 369c47d00eaad5ff8e06d310647c9a847ce29c7b Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 16 Jan 2026 17:29:19 -0600 Subject: [PATCH 239/789] util/chromeos/crosfirmware.sh: Add 7z as a dependency Many newer ChromeOS recovery shellballs require 7z to decompress, so add it as a dependency. Change-Id: Ibe0391567736a39c31914c573b154d8ed7de617b Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90786 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- util/chromeos/crosfirmware.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/util/chromeos/crosfirmware.sh b/util/chromeos/crosfirmware.sh index ab17c22ad6..999b7c201f 100755 --- a/util/chromeos/crosfirmware.sh +++ b/util/chromeos/crosfirmware.sh @@ -13,6 +13,7 @@ exit_if_dependencies_are_missing() { ["parted"]="parted" ["curl"]="curl" ["unzip"]="unzip" + ["7z"]="p7zip" ) # Check all dependencies at once From 36f0b1257009e6acd314d319226afdc2fe7f234c Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 16 Jan 2026 17:32:22 -0600 Subject: [PATCH 240/789] util/chromeos/crosfirmware.sh: Exit if shellball extraction fails Test if shellball extraction fails, and if it does, show the output of the command and then exit, as nothing more can be done. Change-Id: I0cd7416c988d11e019bfd0b4cd52af8811e6d1e2 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90787 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- util/chromeos/crosfirmware.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/chromeos/crosfirmware.sh b/util/chromeos/crosfirmware.sh index 999b7c201f..3be613de19 100755 --- a/util/chromeos/crosfirmware.sh +++ b/util/chromeos/crosfirmware.sh @@ -103,7 +103,11 @@ extract_coreboot() { echo "Extracting coreboot image" if ! sh $_shellball --unpack $_unpacked >/dev/null 2>&1; then - sh $_shellball --sb_extract $_unpacked >/dev/null 2>&1 + if ! sh $_shellball --sb_extract $_unpacked >$_unpacked/sb_extract.log 2>&1; then + echo "Failed to extract shellball image" + cat $_unpacked/sb_extract.log + exit 1 + fi fi if [ -d $_unpacked/models/ ]; then From 82a2e328dca6ac4b5336cd282b7ddb0032ecd88a Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 14:20:41 +0000 Subject: [PATCH 241/789] mb/starlabs/starfighter/mtl: Fix 64GB spd binary This somehow lost a few bytes when initially addded, so restore the whole binary that was originally generated with spd_tools. Change-Id: I7aa828c8e358a0d40597a265a8fc54e01ff105e8 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90824 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- .../starlabs/starfighter/spd/64gb-mtl.spd.hex | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-mtl.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-mtl.spd.hex index d8a75d2182..ee280c8ca2 100644 --- a/src/mainboard/starlabs/starfighter/spd/64gb-mtl.spd.hex +++ b/src/mainboard/starlabs/starfighter/spd/64gb-mtl.spd.hex @@ -9,15 +9,24 @@ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 -20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 -20 20 20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 From 57bfc9184bcf2116c430410a84d90720153baa48 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 15:03:41 +0000 Subject: [PATCH 242/789] mb/starlabs/starfighter: Make the memory speed configurable Let the user chose between 5500, 6400 and 7500MT/s. Change-Id: I91171f252e83e409904031109ee084115f6b3708 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90825 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/starfighter/cfr.c | 1 + .../starfighter/spd/16gb-5500.spd.hex | 32 +++++++++++++++++++ .../spd/{16gb.spd.hex => 16gb-6400.spd.hex} | 0 .../starfighter/spd/16gb-7500.spd.hex | 32 +++++++++++++++++++ .../starfighter/spd/32gb-5500.spd.hex | 32 +++++++++++++++++++ .../spd/{32gb.spd.hex => 32gb-6400.spd.hex} | 0 .../starfighter/spd/32gb-7500.spd.hex | 32 +++++++++++++++++++ .../starfighter/spd/32gb-mtl-5500.spd.hex | 32 +++++++++++++++++++ ...32gb-mtl.spd.hex => 32gb-mtl-6400.spd.hex} | 0 .../starfighter/spd/32gb-mtl-7500.spd.hex | 32 +++++++++++++++++++ .../starfighter/spd/64gb-5500.spd.hex | 32 +++++++++++++++++++ .../starfighter/spd/64gb-6400.spd.hex | 32 +++++++++++++++++++ .../spd/{64gb.spd.hex => 64gb-7500.spd.hex} | 0 .../starfighter/spd/64gb-mtl-5500.spd.hex | 32 +++++++++++++++++++ .../starfighter/spd/64gb-mtl-6400.spd.hex | 32 +++++++++++++++++++ ...64gb-mtl.spd.hex => 64gb-mtl-7500.spd.hex} | 0 .../starlabs/starfighter/spd/Makefile.mk | 24 +++++++++++--- .../starfighter/variants/mtl/romstage.c | 17 +++++++--- .../starfighter/variants/rpl/romstage.c | 19 ++++++++--- 19 files changed, 367 insertions(+), 14 deletions(-) create mode 100644 src/mainboard/starlabs/starfighter/spd/16gb-5500.spd.hex rename src/mainboard/starlabs/starfighter/spd/{16gb.spd.hex => 16gb-6400.spd.hex} (100%) create mode 100644 src/mainboard/starlabs/starfighter/spd/16gb-7500.spd.hex create mode 100644 src/mainboard/starlabs/starfighter/spd/32gb-5500.spd.hex rename src/mainboard/starlabs/starfighter/spd/{32gb.spd.hex => 32gb-6400.spd.hex} (100%) create mode 100644 src/mainboard/starlabs/starfighter/spd/32gb-7500.spd.hex create mode 100644 src/mainboard/starlabs/starfighter/spd/32gb-mtl-5500.spd.hex rename src/mainboard/starlabs/starfighter/spd/{32gb-mtl.spd.hex => 32gb-mtl-6400.spd.hex} (100%) create mode 100644 src/mainboard/starlabs/starfighter/spd/32gb-mtl-7500.spd.hex create mode 100644 src/mainboard/starlabs/starfighter/spd/64gb-5500.spd.hex create mode 100644 src/mainboard/starlabs/starfighter/spd/64gb-6400.spd.hex rename src/mainboard/starlabs/starfighter/spd/{64gb.spd.hex => 64gb-7500.spd.hex} (100%) create mode 100644 src/mainboard/starlabs/starfighter/spd/64gb-mtl-5500.spd.hex create mode 100644 src/mainboard/starlabs/starfighter/spd/64gb-mtl-6400.spd.hex rename src/mainboard/starlabs/starfighter/spd/{64gb-mtl.spd.hex => 64gb-mtl-7500.spd.hex} (100%) diff --git a/src/mainboard/starlabs/starfighter/cfr.c b/src/mainboard/starlabs/starfighter/cfr.c index e925fa731c..45df94c424 100644 --- a/src/mainboard/starlabs/starfighter/cfr.c +++ b/src/mainboard/starlabs/starfighter/cfr.c @@ -12,6 +12,7 @@ static struct sm_obj_form performance_group = { .ui_name = "Performance", .obj_list = (const struct sm_object *[]) { &bluetooth_rtd3, + &memory_speed, &fan_mode, &power_profile, NULL diff --git a/src/mainboard/starlabs/starfighter/spd/16gb-5500.spd.hex b/src/mainboard/starlabs/starfighter/spd/16gb-5500.spd.hex new file mode 100644 index 0000000000..77a62517e3 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/16gb-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 15 1A B5 08 00 40 00 00 0A 01 00 00 +48 00 0B FF 92 55 05 00 AE 00 90 A8 90 90 06 C0 +03 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 4B 7F 50 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/16gb.spd.hex b/src/mainboard/starlabs/starfighter/spd/16gb-6400.spd.hex similarity index 100% rename from src/mainboard/starlabs/starfighter/spd/16gb.spd.hex rename to src/mainboard/starlabs/starfighter/spd/16gb-6400.spd.hex diff --git a/src/mainboard/starlabs/starfighter/spd/16gb-7500.spd.hex b/src/mainboard/starlabs/starfighter/spd/16gb-7500.spd.hex new file mode 100644 index 0000000000..110d974afa --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/16gb-7500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 15 1A B5 08 00 40 00 00 0A 01 00 00 +48 00 08 FF 92 55 05 00 AA 00 90 A8 90 90 06 C0 +03 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 46 7F 42 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/32gb-5500.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-5500.spd.hex new file mode 100644 index 0000000000..09f6a03464 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/32gb-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 22 B5 08 00 40 00 00 0A 01 00 00 +48 00 0B FF 92 55 05 00 AE 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 4B 7F 50 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/32gb.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-6400.spd.hex similarity index 100% rename from src/mainboard/starlabs/starfighter/spd/32gb.spd.hex rename to src/mainboard/starlabs/starfighter/spd/32gb-6400.spd.hex diff --git a/src/mainboard/starlabs/starfighter/spd/32gb-7500.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-7500.spd.hex new file mode 100644 index 0000000000..c946476aa6 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/32gb-7500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 22 B5 08 00 40 00 00 0A 01 00 00 +48 00 08 FF 92 55 05 00 AA 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 46 7F 42 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/32gb-mtl-5500.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-mtl-5500.spd.hex new file mode 100644 index 0000000000..de89ca1b80 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/32gb-mtl-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 22 B5 08 00 40 00 00 0A 01 00 00 +48 00 0B FF 92 55 05 00 AE 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 4B 7F 50 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/32gb-mtl.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-mtl-6400.spd.hex similarity index 100% rename from src/mainboard/starlabs/starfighter/spd/32gb-mtl.spd.hex rename to src/mainboard/starlabs/starfighter/spd/32gb-mtl-6400.spd.hex diff --git a/src/mainboard/starlabs/starfighter/spd/32gb-mtl-7500.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-mtl-7500.spd.hex new file mode 100644 index 0000000000..8f4c71530a --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/32gb-mtl-7500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 22 B5 08 00 40 00 00 0A 01 00 00 +48 00 08 FF 92 55 05 00 AA 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 46 7F 42 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-5500.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-5500.spd.hex new file mode 100644 index 0000000000..c0ecc15077 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/64gb-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 15 0E 16 2A F9 08 00 40 00 00 09 01 00 00 +48 00 0B FF 92 55 05 00 AE 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 4B 7F 50 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-6400.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-6400.spd.hex new file mode 100644 index 0000000000..bdeb4c2501 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/64gb-6400.spd.hex @@ -0,0 +1,32 @@ +23 10 15 0E 16 2A F9 08 00 40 00 00 09 01 00 00 +48 00 0A FF 92 55 05 00 AA 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 00 7F 00 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/64gb.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-7500.spd.hex similarity index 100% rename from src/mainboard/starlabs/starfighter/spd/64gb.spd.hex rename to src/mainboard/starlabs/starfighter/spd/64gb-7500.spd.hex diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-mtl-5500.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-5500.spd.hex new file mode 100644 index 0000000000..c2934a2c6e --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 15 0E 16 2A F9 08 00 40 00 00 09 01 00 00 +48 00 0B FF 92 55 05 00 AE 00 90 A8 90 C0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 4B 00 50 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 7F 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-mtl-6400.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-6400.spd.hex new file mode 100644 index 0000000000..a3ca8d3afd --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-6400.spd.hex @@ -0,0 +1,32 @@ +23 10 15 0E 16 2A F9 08 00 40 00 00 09 01 00 00 +48 00 0A FF 92 55 05 00 AA 00 90 A8 90 C0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 7F 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-mtl.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-7500.spd.hex similarity index 100% rename from src/mainboard/starlabs/starfighter/spd/64gb-mtl.spd.hex rename to src/mainboard/starlabs/starfighter/spd/64gb-mtl-7500.spd.hex diff --git a/src/mainboard/starlabs/starfighter/spd/Makefile.mk b/src/mainboard/starlabs/starfighter/spd/Makefile.mk index ee9a117ed2..4bce4845b9 100644 --- a/src/mainboard/starlabs/starfighter/spd/Makefile.mk +++ b/src/mainboard/starlabs/starfighter/spd/Makefile.mk @@ -1,10 +1,24 @@ ## SPDX-License-Identifier: GPL-2.0-only ifeq ($(CONFIG_BOARD_STARLABS_STARFIGHTER_RPL),y) -SPD_SOURCES = 16gb # 13 -SPD_SOURCES += 32gb # 0 -SPD_SOURCES += 64gb # 8 +# RPL memory configs (selected by straps) with runtime speed selection. +# CBFS index order is (per config): 5500, 6400, 7500. +SPD_SOURCES = 16gb-5500 +SPD_SOURCES += 16gb-6400 +SPD_SOURCES += 16gb-7500 +SPD_SOURCES += 32gb-5500 +SPD_SOURCES += 32gb-6400 +SPD_SOURCES += 32gb-7500 +SPD_SOURCES += 64gb-5500 +SPD_SOURCES += 64gb-6400 +SPD_SOURCES += 64gb-7500 else -SPD_SOURCES = 32gb-mtl # 13 -SPD_SOURCES += 64gb-mtl # 0 +# MTL memory configs (selected by straps) with runtime speed selection. +# CBFS index order is (per config): 5500, 6400, 7500. +SPD_SOURCES = 32gb-mtl-5500 +SPD_SOURCES += 32gb-mtl-6400 +SPD_SOURCES += 32gb-mtl-7500 +SPD_SOURCES += 64gb-mtl-5500 +SPD_SOURCES += 64gb-mtl-6400 +SPD_SOURCES += 64gb-mtl-7500 endif diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c b/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c index 8281dd0ebb..486912cbfe 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c +++ b/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c @@ -6,16 +6,23 @@ #include #include -static uint8_t strap_to_cbfs_index(uint8_t strap) +static uint8_t strap_to_memcfg_index(uint8_t strap) { switch (strap) { - case 13: // 32GB + case 13: /* 32GB */ return 0; - default: // 64GB + default: /* 64GB */ return 1; } } +static uint8_t memcfg_and_speed_to_cbfs_index(uint8_t memcfg, unsigned int speed) +{ + if (speed > 2) + speed = 2; + return (uint8_t)(memcfg * 3 + speed); +} + void mainboard_memory_init_params(FSPM_UPD *mupd) { const struct mb_cfg mem_config = { @@ -82,7 +89,9 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) const struct mem_spd lpddr5_spd_info = { .topo = MEM_TOPO_MEMORY_DOWN, - .cbfs_index = strap_to_cbfs_index(get_memory_config_straps()), + .cbfs_index = memcfg_and_speed_to_cbfs_index( + strap_to_memcfg_index(get_memory_config_straps()), + get_uint_option("memory_speed", 1)), }; memcfg_init(mupd, &mem_config, &lpddr5_spd_info, half_populated); diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/romstage.c b/src/mainboard/starlabs/starfighter/variants/rpl/romstage.c index 34e61728c4..4242560688 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/romstage.c +++ b/src/mainboard/starlabs/starfighter/variants/rpl/romstage.c @@ -40,18 +40,25 @@ static uint8_t get_memory_config_straps(void) return (uint8_t)gpio_base2_value(spd_id, ARRAY_SIZE(spd_id)); } -static uint8_t strap_to_cbfs_index(uint8_t strap) +static uint8_t strap_to_memcfg_index(uint8_t strap) { switch (strap) { - case 0: // 32GB + case 0: /* 32GB */ return 1; - case 8: // 64GB + case 8: /* 64GB */ return 2; - default:// 16GB + default: /* 16GB */ return 0; } } +static uint8_t memcfg_and_speed_to_cbfs_index(uint8_t memcfg, unsigned int speed) +{ + if (speed > 2) + speed = 2; + return (uint8_t)(memcfg * 3 + speed); +} + void mainboard_memory_init_params(FSPM_UPD *mupd) { const struct mb_cfg mem_config = { @@ -118,7 +125,9 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) const struct mem_spd lpddr5_spd_info = { .topo = MEM_TOPO_MEMORY_DOWN, - .cbfs_index = strap_to_cbfs_index(get_memory_config_straps()), + .cbfs_index = memcfg_and_speed_to_cbfs_index( + strap_to_memcfg_index(get_memory_config_straps()), + get_uint_option("memory_speed", 1)), }; memcfg_init(mupd, &mem_config, &lpddr5_spd_info, half_populated); From b3e8bd41254d2059f4555e7f794a7f48b617743d Mon Sep 17 00:00:00 2001 From: Swathi Tamilselvan Date: Tue, 20 Jan 2026 12:48:00 +0530 Subject: [PATCH 243/789] soc/qualcomm/x1p42100: Add API support for audio clock configuration Add API support to enable LPASS core clocks and vote for LP0 BCM resource required for LPASS. This change includes support to enable audio clocks. LPASS is Low Power Audio Subsystem that runs audio and voice processing on a dedicated DSP. This enables low-power audio operation while the main CPUs remain in low-power states. Test=1. Create an image.serial.bin and ensure it boots on X1P42100. Change-Id: If7684bee10d127866acac80e6aeefadaa177dc1f Signed-off-by: Swathi Tamilselvan Reviewed-on: https://review.coreboot.org/c/coreboot/+/90851 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/soc/qualcomm/x1p42100/Makefile.mk | 1 + .../x1p42100/include/soc/addressmap.h | 7 + src/soc/qualcomm/x1p42100/include/soc/clock.h | 187 +++++++++++++++--- src/soc/qualcomm/x1p42100/include/soc/lpass.h | 27 +++ src/soc/qualcomm/x1p42100/lpass.c | 147 ++++++++++++++ 5 files changed, 343 insertions(+), 26 deletions(-) create mode 100644 src/soc/qualcomm/x1p42100/include/soc/lpass.h create mode 100644 src/soc/qualcomm/x1p42100/lpass.c diff --git a/src/soc/qualcomm/x1p42100/Makefile.mk b/src/soc/qualcomm/x1p42100/Makefile.mk index 4a51a20dd6..2881e90350 100644 --- a/src/soc/qualcomm/x1p42100/Makefile.mk +++ b/src/soc/qualcomm/x1p42100/Makefile.mk @@ -56,6 +56,7 @@ ramstage-y += ../common/cmd_db.c ramstage-y += ../common/rpmh.c ../common/rpmh_bcm.c ../common/rpmh_regulator.c ../common/rpmh_rsc.c ramstage-y += rpmh_rsc_init.c ramstage-y += display/disp.c +ramstage-y += lpass.c ################################################################################ diff --git a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h index 60649835d6..dc45a668d6 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h +++ b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h @@ -18,6 +18,13 @@ #define DISP_PLL1_BASE 0xAF01000 #define DISP_CC_BASE 0xAF08000 +/* LPASS BASE ADDRESSES */ +#define LPASS_BASE 0x06000000 +#define LPASS_AUDIO_CC_PLL_BASE (LPASS_BASE + 0x00BC0000) +#define LPASS_AON_CC_BASE (LPASS_BASE + 0x00E08000) +#define LPASS_AON_CC_PLL_CM_BASE (LPASS_BASE + 0x00E01000) +#define LPASS_CORE_GDSC_REG_BASE (LPASS_BASE + 0x01E00000) + #define RPMH_BASE 0x17520000 #define CMD_DB_BASE_ADDR 0x81c60000 #define CMD_DB_SIZE 0x20000 diff --git a/src/soc/qualcomm/x1p42100/include/soc/clock.h b/src/soc/qualcomm/x1p42100/include/soc/clock.h index 73378ce59e..95258eaa85 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/clock.h +++ b/src/soc/qualcomm/x1p42100/include/soc/clock.h @@ -60,6 +60,14 @@ enum clk_ctl_gpll_user_ctl_x1p42100 { PLL_POST_DIV_ODD_SHFT_X1P42100 = 14, }; +enum clk_ctl_lpass_aon_cc_pll_user_ctl_x1p42100 { + AON_CC_PLL_PLLOUT_MAIN_SHFT_X1P42100 = 0, + AON_CC_PLL_PLLOUT_EVEN_SHFT_X1P42100 = 1, + AON_CC_PLL_PLLOUT_ODD_SHFT_X1P42100 = 2, + AON_CC_PLL_POST_DIV_EVEN_SHFT_X1P42100 = 10, + AON_CC_PLL_POST_DIV_ODD_SHFT_X1P42100 = 14, +}; + enum clk_pll_src { SRC_XO_19_2MHZ = 0, SRC_GPLL0_MAIN_600MHZ = 1, @@ -193,6 +201,99 @@ struct x1p42100_disp_pll_clock { u32 pll_user_ctl_u; }; +/* LPASS AON CC PLL register structure */ +struct x1p42100_lpass_aon_cc_pll_clock { + u32 pll_mode; + u32 pll_opmode; + u32 pll_state; + u32 pll_status; + u32 pll_l_val; + u32 pll_alpha_val; + u32 pll_user_ctl; + u32 pll_user_ctl_u; + u32 pll_config_ctl; + u32 pll_config_ctl_u; + u32 pll_config_ctl_u1; + u32 pll_test_ctl; + u32 pll_test_ctl_u; + u32 pll_test_ctl_u1; + u32 pll_test_ctl_u2; +}; + +/* LPASS Audio CC register structure */ +struct x1p42100_lpass_audio_cc { + u8 _res0[0x28018]; + u32 codec_ext_mclk0_cbcr; + u8 _res1[0xffc]; + u32 codec_ext_mclk1_cbcr; + u8 _res2[0x10b0]; + u32 wsa_mclk_2x_cbcr; + u8 _res3[0x4]; + u32 wsa_mclk_cbcr; + u8 _res4[0x18]; + u32 tx_mclk_2x_wsa_cbcr; + u32 tx_mclk_wsa_cbcr; + u8 _res5[0x2f08]; + u32 wsa2_mclk_2x_cbcr; + u32 wsa2_mclk_cbcr; + u32 tx_mclk_wsa2_cbcr; + u32 tx_mclk_2x_wsa2_cbcr; + u8 _res6[0xff0]; + u32 codec_mem_cbcr; + u32 codec_mem0_cbcr; + u32 codec_mem0_sregr; + u32 codec_mem0_cfg_sregr; + u32 codec_mem1_cbcr; + u32 codec_mem1_sregr; + u32 codec_mem1_cfg_sregr; + u32 codec_mem2_cbcr; + u32 codec_mem2_sregr; + u32 codec_mem2_cfg_sregr; + u32 codec_mem3_cbcr; + u32 codec_mem3_sregr; + u32 codec_mem3_cfg_sregr; +}; + +check_member(x1p42100_lpass_audio_cc, codec_ext_mclk0_cbcr, 0x28018); +check_member(x1p42100_lpass_audio_cc, codec_ext_mclk1_cbcr, 0x29018); +check_member(x1p42100_lpass_audio_cc, wsa_mclk_2x_cbcr, 0x2A0CC); +check_member(x1p42100_lpass_audio_cc, wsa_mclk_cbcr, 0x2A0D4); +check_member(x1p42100_lpass_audio_cc, tx_mclk_2x_wsa_cbcr, 0x2A0F0); +check_member(x1p42100_lpass_audio_cc, wsa2_mclk_2x_cbcr, 0x2D000); +check_member(x1p42100_lpass_audio_cc, codec_mem_cbcr, 0x2E000); + +/* LPASS Core GDSC register structure */ +struct x1p42100_lpass_core_gdsc { + u32 core_hm_gdscr; + u8 _res0[0xB4]; + u32 lpass_core_gds_hm_ready; + u8 _res1[0x8F44]; + u32 lpass_top_cc_lpass_core_sway_ahb_ls_cbcr; +}; + +check_member(x1p42100_lpass_core_gdsc, lpass_core_gds_hm_ready, 0x000B8); +check_member(x1p42100_lpass_core_gdsc, lpass_top_cc_lpass_core_sway_ahb_ls_cbcr, 0x09000); + +/* LPASS AON CC register structure */ +struct x1p42100_lpass_aon_cc { + u8 _res0[0x9060]; + u32 va_mem0_cbcr; + u8 _res1[0x2c]; + u32 lpass_audio_hm_gdscr; + u8 _res2[0x8F78]; + u32 va_2x_cbcr; + u8 _res3[0x4]; + u32 va_cbcr; + u8 _res4[0xffc]; + u32 tx_mclk_cbcr; +}; + +check_member(x1p42100_lpass_aon_cc, va_mem0_cbcr, 0x9060); +check_member(x1p42100_lpass_aon_cc, lpass_audio_hm_gdscr, 0x9090); +check_member(x1p42100_lpass_aon_cc, va_2x_cbcr, 0x1200C); +check_member(x1p42100_lpass_aon_cc, va_cbcr, 0x12014); +check_member(x1p42100_lpass_aon_cc, tx_mclk_cbcr, 0x13014); + struct x1p42100_disp_cc { uint8_t _res0[0x00C]; uint32_t mdss_mdp_cbcr; @@ -414,80 +515,82 @@ struct x1p42100_gcc { u32 gcc_aggre_usb3_prim_axi_cbcr; u8 _res36[0x42004 - 0x39094]; struct qupv3_clock qup_wrap0_s[8]; - u8 _res37[0x4b000 - 0x429c4]; + u8 _res37[0x47000 - 0x429c4]; + u32 lpass_cfg_noc_sway_cbcr; + u8 _res38[0x4b000 - 0x47004]; u32 qspi_bcr; u32 qspi_cnoc_ahb_cbcr; u32 qspi_core_cbcr; struct clock_rcg qspi_core; - u8 _res38[0x50000 - 0x4b014]; + u8 _res39[0x50000 - 0x4b014]; u32 gcc_usb3_phy_prim_bcr; u32 gcc_usb3phy_phy_prim_bcr; - u8 _res39[0x50010 - 0x50008]; + u8 _res40[0x50010 - 0x50008]; u32 gcc_usb4_0_dp0_phy_prim_bcr; - u8 _res40[0x52000 - 0x50014]; + u8 _res41[0x52000 - 0x50014]; u32 apcs_clk_br_en; - u8 _res41[0x52008 - 0x52004]; + u8 _res42[0x52008 - 0x52004]; u32 apcs_clk_br_en1; - u8 _res42[0x52010 - 0x5200c]; + u8 _res43[0x52010 - 0x5200c]; u32 apcs_clk_br_en2; - u8 _res43[0x52018 - 0x52014]; + u8 _res44[0x52018 - 0x52014]; u32 apcs_clk_br_en3; - u8 _res44[0x52020 - 0x5201c]; + u8 _res45[0x52020 - 0x5201c]; u32 apcs_clk_br_en4; - u8 _res45[0x52028 - 0x52024]; + u8 _res46[0x52028 - 0x52024]; u32 apcs_clk_br_en5; - u8 _res46[0x52030 - 0x5202c]; + u8 _res47[0x52030 - 0x5202c]; u32 apcs_pll_br_en; - u8 _res47[0x54000 - 0x52034]; + u8 _res48[0x54000 - 0x52034]; u32 usb3_uniphy_mp1_bcr; u32 usb3uniphy_phy_mp1_bcr; u32 gcc_usb3_mp_ss1_phy_bcr; u32 gcc_usb3_mp_ss1_phy_gdscr; - u8 _res48[0x8e000 - 0x54010]; + u8 _res49[0x8e000 - 0x54010]; u32 pcie_6_phy_gdscr; - u8 _res49[0xa1000 - 0x8e004]; + u8 _res50[0xa1000 - 0x8e004]; u32 gcc_usb30_sec_bcr; u32 gcc_usb30_sec_gdscr; - u8 _res50[0xa1018 - 0xa1008]; + u8 _res51[0xa1018 - 0xa1008]; u32 gcc_usb30_sec_master_cbcr; - u8 _res51[0xa1024 - 0xa101c]; + u8 _res52[0xa1024 - 0xa101c]; u32 gcc_usb30_sec_sleep_cbcr; u32 gcc_usb30_sec_mock_utmi_cbcr; struct clock_rcg usb30_sec_master_rcg; - u8 _res52[0xa1060 - 0xa1034]; + u8 _res53[0xa1060 - 0xa1034]; u32 gcc_usb3_sec_phy_aux_cbcr; u32 gcc_usb3_sec_phy_com_aux_cbcr; u32 gcc_usb3_sec_phy_pipe_cbcr; u32 gcc_usb3_sec_phy_pipe_muxr; - u8 _res53[0xa108c - 0xa1070]; + u8 _res54[0xa108c - 0xa1070]; u32 gcc_cfg_noc_usb3_sec_axi_cbcr; u32 gcc_aggre_usb3_sec_axi_cbcr; - u8 _res54[0xa2000 - 0xa1094]; + u8 _res55[0xa2000 - 0xa1094]; u32 gcc_usb30_tert_bcr; u32 gcc_usb30_tert_gdscr; - u8 _res55[0xa2018 - 0xa2008]; + u8 _res56[0xa2018 - 0xa2008]; u32 gcc_usb30_tert_master_cbcr; - u8 _res56[0xa2024 - 0xa201c]; + u8 _res57[0xa2024 - 0xa201c]; u32 gcc_usb30_tert_sleep_cbcr; u32 gcc_usb30_tert_mock_utmi_cbcr; - u8 _res57[0xa2034 - 0xa202c]; + u8 _res58[0xa2034 - 0xa202c]; u32 gcc_usb30_tert_master_m; u32 gcc_usb30_tert_master_n; u32 gcc_usb30_tert_master_d; - u8 _res58[0xa2060 - 0xa2040]; + u8 _res59[0xa2060 - 0xa2040]; u32 gcc_usb3_tert_phy_aux_cbcr; u32 gcc_usb3_tert_phy_com_aux_cbcr; u32 gcc_usb3_tert_phy_pipe_cbcr; u32 gcc_usb3_tert_phy_pipe_muxr; - u8 _res59[0xa208c - 0xa2070]; + u8 _res60[0xa208c - 0xa2070]; u32 gcc_cfg_noc_usb3_tert_axi_cbcr; u32 gcc_aggre_usb3_tert_axi_cbcr; - u8 _res60[0xa3000 - 0xa2094]; + u8 _res61[0xa3000 - 0xa2094]; u32 gcc_usb3_phy_tert_bcr; u32 gcc_usb3phy_phy_tert_bcr; - u8 _res61[0xa3010 - 0xa3008]; + u8 _res62[0xa3010 - 0xa3008]; u32 gcc_usb4_2_dp0_phy_tert_bcr; - u8 _res62[0xac01c - 0xa3014]; + u8 _res63[0xac01c - 0xa3014]; u32 pcie_6a_phy_bcr; }; @@ -536,6 +639,7 @@ check_member(x1p42100_gcc, gcc_aggre_usb_noc_axi_cbcr, 0x2d034); check_member(x1p42100_gcc, gcc_aggre_noc_usb_south_axi_cbcr, 0x2d174); check_member(x1p42100_gcc, gcc_aggre_noc_usb_north_axi_cbcr, 0x2d17c); check_member(x1p42100_gcc, qup_wrap0_s, 0x42004); +check_member(x1p42100_gcc, lpass_cfg_noc_sway_cbcr, 0x47000); check_member(x1p42100_gcc, qspi_bcr, 0x4b000); check_member(x1p42100_gcc, apcs_clk_br_en, 0x52000); check_member(x1p42100_gcc, apcs_clk_br_en1, 0x52008); @@ -735,6 +839,29 @@ enum clk_usb_phy_src_sel { USB_PHY_XO_SRC_SEL = 2, }; +enum clk_lpass { + LPASS_CODEC_MEM_CBCR, + LPASS_CODEC_MEM0_CBCR, + LPASS_CODEC_MEM1_CBCR, + LPASS_CODEC_MEM2_CBCR, + LPASS_CODEC_MEM3_CBCR, + LPASS_EXT_MCLK0_CBCR, + LPASS_EXT_MCLK1_CBCR, + LPASS_TX_MCLK_CBCR, + LPASS_TX_MCLK_2X_WSA_CBCR, + LPASS_TX_MCLK_WSA_CBCR, + LPASS_WSA_MCLK_2X_CBCR, + LPASS_WSA_MCLK_CBCR, + LPASS_TX_MCLK_2X_WSA2_CBCR, + LPASS_TX_MCLK_WSA2_CBCR, + LPASS_WSA2_MCLK_2X_CBCR, + LPASS_WSA2_MCLK_CBCR, + LPASS_VA_MEM0_CBCR, + LPASS_VA_CBCR, + LPASS_VA_2X_CBCR, + LPASS_CLK_COUNT +}; + enum subsystem_reset { AOP_RESET_SHFT, CORE_SW_RESET, @@ -760,6 +887,8 @@ enum cb_err usb_sec_clock_enable(enum clk_usb_sec clk_type); enum cb_err mdss_clock_enable(enum clk_mdss clk_type); enum cb_err disp_pll_init_and_set(struct x1p42100_disp_pll_clock *disp_pll, u32 l_val, u32 alpha_val); +enum cb_err lpass_init(void); + void clock_configure_dfsr_table_x1p42100(int qup, struct clock_freq_config *clk_cfg, uint32_t num_perfs); @@ -778,6 +907,12 @@ static struct x1p42100_qupv3_wrap *const qup_wrap0_clk = (void *)GCC_QUPV3_WRAP0 static struct x1p42100_qupv3_wrap *const qup_wrap1_clk = (void *)GCC_QUPV3_WRAP1_BASE; static struct x1p42100_qupv3_wrap *const qup_wrap2_clk = (void *)GCC_QUPV3_WRAP2_BASE; +/* Static pointers to LPASS register blocks */ +static struct x1p42100_lpass_audio_cc *const lpass_audio_cc = (void *)LPASS_AUDIO_CC_PLL_BASE; +static struct x1p42100_lpass_aon_cc *const lpass_aon_cc = (void *)LPASS_AON_CC_BASE; +static struct x1p42100_lpass_aon_cc_pll_clock *const lpass_aon_cc_pll = (void *)LPASS_AON_CC_PLL_CM_BASE; +static struct x1p42100_lpass_core_gdsc *const lpass_core_gdsc = (void *)LPASS_CORE_GDSC_REG_BASE; + /* Does nothing */ #define clock_reset_aop() do {} while (0) /* Does nothing */ diff --git a/src/soc/qualcomm/x1p42100/include/soc/lpass.h b/src/soc/qualcomm/x1p42100/include/soc/lpass.h new file mode 100644 index 0000000000..79439e4ba7 --- /dev/null +++ b/src/soc/qualcomm/x1p42100/include/soc/lpass.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_QUALCOMM_X1P42100_LPASS_H_ +#define _SOC_QUALCOMM_X1P42100_LPASS_H_ + +#include + +/* LPASS AON CC PLL Settings */ +#define HAL_CLK_LPASS_AON_CC_PLL_L_VALUE 0x00000020 +#define HAL_CLK_LPASS_AON_CC_PLL_ALPHA_VALUE 0x00000000 +#define HAL_CLK_LPASS_AON_CC_PLL_CAL_L_VALUE 0x00000044 +#define HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL 0x20485699 +#define HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL_U 0x00182261 +#define HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL_U1 0x82AA299C +#define HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL 0x00000000 +#define HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U 0x00000003 +#define HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U1 0x00009000 +#define HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U2 0x00000034 +#define HAL_CLK_LPASS_AON_CC_PLL_USER_CTL 0x00E00041 +#define HAL_CLK_LPASS_AON_CC_PLL_USER_CTL_U 0x00000105 + +#define LPASS_CORE_HM_READY BIT(0) +#define HW_CTL BIT(1) +#define GDSC_ENABLE_BIT 0 + +#define BCM_LP0_VOTE_VALUE 0x60004001 +#endif /* _SOC_QUALCOMM_X1P42100_LPASS_H_ */ diff --git a/src/soc/qualcomm/x1p42100/lpass.c b/src/soc/qualcomm/x1p42100/lpass.c new file mode 100644 index 0000000000..437a888cb0 --- /dev/null +++ b/src/soc/qualcomm/x1p42100/lpass.c @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +static enum cb_err lpass_aon_cc_pll_enable(void) +{ + struct alpha_pll_reg_val_config pll_cfg = {0}; + + pll_cfg.reg_mode = &lpass_aon_cc_pll->pll_mode; + pll_cfg.reg_l = &lpass_aon_cc_pll->pll_l_val; + pll_cfg.l_val = HAL_CLK_LPASS_AON_CC_PLL_L_VALUE; + + pll_cfg.reg_alpha = &lpass_aon_cc_pll->pll_alpha_val; + pll_cfg.alpha_val = HAL_CLK_LPASS_AON_CC_PLL_ALPHA_VALUE; + + pll_cfg.reg_cal_l = &lpass_aon_cc_pll->pll_l_val; + pll_cfg.cal_l_val = HAL_CLK_LPASS_AON_CC_PLL_CAL_L_VALUE; + + pll_cfg.reg_config_ctl = &lpass_aon_cc_pll->pll_config_ctl; + pll_cfg.config_ctl_val = HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL; + pll_cfg.reg_config_ctl_hi = &lpass_aon_cc_pll->pll_config_ctl_u; + pll_cfg.config_ctl_hi_val = HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL_U; + pll_cfg.reg_config_ctl_hi1 = &lpass_aon_cc_pll->pll_config_ctl_u1; + pll_cfg.config_ctl_hi1_val = HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL_U1; + + pll_cfg.reg_user_ctl = &lpass_aon_cc_pll->pll_user_ctl; + pll_cfg.user_ctl_val = HAL_CLK_LPASS_AON_CC_PLL_USER_CTL; + pll_cfg.reg_user_ctl_hi = &lpass_aon_cc_pll->pll_user_ctl_u; + pll_cfg.user_ctl_hi_val = HAL_CLK_LPASS_AON_CC_PLL_USER_CTL_U; + + pll_cfg.reg_opmode = &lpass_aon_cc_pll->pll_opmode; + + if (clock_configure_enable_gpll(&pll_cfg, false, 0) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: AON CC PLL configuration failed\n"); + return CB_ERR; + } + + write32(&lpass_aon_cc_pll->pll_test_ctl, HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL); + write32(&lpass_aon_cc_pll->pll_test_ctl_u, HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U); + write32(&lpass_aon_cc_pll->pll_test_ctl_u1, HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U1); + write32(&lpass_aon_cc_pll->pll_test_ctl_u2, HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U2); + + if (lucidole_pll_enable(&pll_cfg) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: AON CC PLL enable failed\n"); + return CB_ERR; + } + + setbits32(&lpass_aon_cc_pll->pll_user_ctl, (BIT(AON_CC_PLL_PLLOUT_EVEN_SHFT_X1P42100) | + BIT(AON_CC_PLL_PLLOUT_ODD_SHFT_X1P42100))); + + return CB_SUCCESS; +} + +static enum cb_err lpass_setup_core_infrastructure(void) +{ + + if (clock_enable(&gcc->lpass_cfg_noc_sway_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable CFG NOC SWAY clock\n"); + return CB_ERR; + } + + setbits32(&lpass_core_gdsc->lpass_top_cc_lpass_core_sway_ahb_ls_cbcr, HW_CTL); + + if (enable_and_poll_gdsc_status(&lpass_core_gdsc->core_hm_gdscr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable Core HM GDSC\n"); + return CB_ERR; + } + + if (!wait_us(1000000, read32(&lpass_core_gdsc->lpass_core_gds_hm_ready) & LPASS_CORE_HM_READY)) { + printk(BIOS_ERR, "LPASS: Core HM ready timeout\n"); + return CB_ERR; + } + + return CB_SUCCESS; +} + +static u32 *lpass_cbcr[LPASS_CLK_COUNT] = { + [LPASS_CODEC_MEM_CBCR] = &lpass_audio_cc->codec_mem_cbcr, + [LPASS_CODEC_MEM0_CBCR] = &lpass_audio_cc->codec_mem0_cbcr, + [LPASS_CODEC_MEM1_CBCR] = &lpass_audio_cc->codec_mem1_cbcr, + [LPASS_CODEC_MEM2_CBCR] = &lpass_audio_cc->codec_mem2_cbcr, + [LPASS_CODEC_MEM3_CBCR] = &lpass_audio_cc->codec_mem3_cbcr, + [LPASS_EXT_MCLK0_CBCR] = &lpass_audio_cc->codec_ext_mclk0_cbcr, + [LPASS_EXT_MCLK1_CBCR] = &lpass_audio_cc->codec_ext_mclk1_cbcr, + [LPASS_TX_MCLK_CBCR] = &lpass_aon_cc->tx_mclk_cbcr, + [LPASS_TX_MCLK_2X_WSA_CBCR] = &lpass_audio_cc->tx_mclk_2x_wsa_cbcr, + [LPASS_TX_MCLK_WSA_CBCR] = &lpass_audio_cc->tx_mclk_wsa_cbcr, + [LPASS_WSA_MCLK_2X_CBCR] = &lpass_audio_cc->wsa_mclk_2x_cbcr, + [LPASS_WSA_MCLK_CBCR] = &lpass_audio_cc->wsa_mclk_cbcr, + [LPASS_TX_MCLK_2X_WSA2_CBCR] = &lpass_audio_cc->tx_mclk_2x_wsa2_cbcr, + [LPASS_TX_MCLK_WSA2_CBCR] = &lpass_audio_cc->tx_mclk_wsa2_cbcr, + [LPASS_WSA2_MCLK_2X_CBCR] = &lpass_audio_cc->wsa2_mclk_2x_cbcr, + [LPASS_WSA2_MCLK_CBCR] = &lpass_audio_cc->wsa2_mclk_cbcr, + [LPASS_VA_MEM0_CBCR] = &lpass_aon_cc->va_mem0_cbcr, + [LPASS_VA_CBCR] = &lpass_aon_cc->va_cbcr, + [LPASS_VA_2X_CBCR] = &lpass_aon_cc->va_2x_cbcr, +}; + +static enum cb_err lpass_audio_clocks_enable(void) +{ + for (size_t i = 0; i < LPASS_CLK_COUNT; i++) { + if (clock_enable(lpass_cbcr[i]) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable audio clock\n"); + return CB_ERR; + } + } + + return CB_SUCCESS; +} + +enum cb_err lpass_init(void) +{ + int rc; + rc = rpmh_bcm_vote("LP0", BCM_LP0_VOTE_VALUE); + if (rc) { + printk(BIOS_ERR, "LPASS: Failed to send BCM vote for LPASS bus clock manager LP0\n"); + return CB_ERR; + } + + if (enable_and_poll_gdsc_status(&lpass_aon_cc->lpass_audio_hm_gdscr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable Core HM GDSC\n"); + return CB_ERR; + } + + if (lpass_setup_core_infrastructure() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to setup core infrastructure\n"); + return CB_ERR; + } + + if (lpass_aon_cc_pll_enable() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable AON CC PLL\n"); + return CB_ERR; + } + + if (lpass_audio_clocks_enable() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable audio clocks\n"); + return CB_ERR; + } + + printk(BIOS_INFO, "LPASS: BCM vote for LP0 and LPASS Init completed successfully\n"); + return CB_SUCCESS; +} From dec1dfe1601d26a6abc6bde0904c7fbb7ed719df Mon Sep 17 00:00:00 2001 From: Swathi Tamilselvan Date: Tue, 20 Jan 2026 16:32:00 +0530 Subject: [PATCH 244/789] mb/google/bluey: Add support to invoke LPASS Init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support in mainboard to invoke LPASS Initialization. Test=1. Create an image.serial.bin and ensure it boots on X1P42100. 2. Verified LP0 BCM vote using serial logs. Serial Log: [DEBUG] BCM: Found address 0x00050048 for resource LP0 [INFO ] BCM: Successfully voted for LP0 (addr=0x00050048, val=0x60004001) 3. Verified if the clocks are enabled by taking clock dump. Clock enablement is verified by dumping the 31st bit of the corresponding clock’s CBCR register. A value of 0 in bit 31 indicates that the clock is ON. The register details are part of HRD-X1P42100-S1 document. https://docs.qualcomm.com/bundle/resource/topics/HRD-X1P42100-S1/ Change-Id: Icdcb8176639d4c6d24ab6cd2741d7e44e2370eb0 Signed-off-by: Swathi Tamilselvan Reviewed-on: https://review.coreboot.org/c/coreboot/+/90852 Reviewed-by: Subrata Banik Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/mainboard.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index ea0e8a4851..ad02b2ea3c 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -203,6 +203,8 @@ static void mainboard_init(struct device *dev) setup_usb(); display_startup(); + + lpass_init(); } static void mainboard_enable(struct device *dev) From f84a676cc7f522c166f0ef852544784d42e6ee7d Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Wed, 21 Jan 2026 21:46:19 +0000 Subject: [PATCH 245/789] src/lib/smbios: Advertise UEFI support for EDK2 fwupd checks SMBIOS Type 0 BIOS Characteristics Extension Byte 2 bit 3 (UEFI Specification Supported) when deciding if UEFI capsule updates are supported. Set the flag when coreboot is built with the EDK2 payload. Change-Id: I4d24deeca88cde5411225f8d113704f5a04e8a34 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90860 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/include/smbios.h | 1 + src/lib/smbios.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/include/smbios.h b/src/include/smbios.h index b9dbc0bdf6..103e85b9af 100644 --- a/src/include/smbios.h +++ b/src/include/smbios.h @@ -123,6 +123,7 @@ int smbios_write_type8(unsigned long *current, int *handle, #define BIOS_EXT1_CHARACTERISTICS_ACPI (1 << 0) #define BIOS_EXT2_CHARACTERISTICS_TARGET (1 << 2) +#define BIOS_EXT2_CHARACTERISTICS_UEFI_SUPPORT (1 << 3) #define BIOS_MEMORY_ECC_SINGLE_BIT_CORRECTING (1 << 3) #define BIOS_MEMORY_ECC_DOUBLE_BIT_CORRECTING (1 << 4) diff --git a/src/lib/smbios.c b/src/lib/smbios.c index 7da3e2ad15..35b4d7765f 100644 --- a/src/lib/smbios.c +++ b/src/lib/smbios.c @@ -412,6 +412,9 @@ static int smbios_write_type0(unsigned long *current, int handle) t->bios_characteristics_ext1 = BIOS_EXT1_CHARACTERISTICS_ACPI; t->bios_characteristics_ext2 = BIOS_EXT2_CHARACTERISTICS_TARGET; + if (CONFIG(PAYLOAD_EDK2)) + t->bios_characteristics_ext2 |= BIOS_EXT2_CHARACTERISTICS_UEFI_SUPPORT; + const int len = smbios_full_table_len(&t->header, t->eos); *current += len; return len; From 56922d914ba7687fb41434b7806b4b56affb5f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 21 Jan 2026 15:19:32 +0100 Subject: [PATCH 246/789] soc/amd/common/block/lpc: Report ESPI1 MMIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ESPI1 MMIO is reported in ACPI already, but the resource allocator must also know about it to avoid the allocation of resources in that range. TEST=Boot Gigabyte MZ33-AR1 and verify that ESPI1 address (0xfec30000) is reported for PCI device 00:00.14.3 in coreboot logs: dev: PCI: 00:00:14.3, index: 0x3, base: 0xfec30000, size: 0x1000 Change-Id: Ic4024e6aa37bd7568dcecbd7cae29be9ae587a7f Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/90853 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Paul Menzel --- src/soc/amd/common/block/include/amdblocks/espi.h | 1 + src/soc/amd/common/block/lpc/lpc.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/soc/amd/common/block/include/amdblocks/espi.h b/src/soc/amd/common/block/include/amdblocks/espi.h index b7ab06ee55..5781dea3af 100644 --- a/src/soc/amd/common/block/include/amdblocks/espi.h +++ b/src/soc/amd/common/block/include/amdblocks/espi.h @@ -7,6 +7,7 @@ /* eSPI MMIO base lives at an offset of 0x10000 from the address in SPI BAR. */ #define ESPI_OFFSET_FROM_BAR 0x10000 +#define ESPI1_OFFSET_FROM_BAR 0x20000 #define ESPI_DECODE 0x40 /* more bits defined in soc/common/amd/blocks/lpc/espi_def.h */ diff --git a/src/soc/amd/common/block/lpc/lpc.c b/src/soc/amd/common/block/lpc/lpc.c index 2392d5f3e8..1aa81f66ca 100644 --- a/src/soc/amd/common/block/lpc/lpc.c +++ b/src/soc/amd/common/block/lpc/lpc.c @@ -123,6 +123,10 @@ static void lpc_read_resources(struct device *dev) /* Add a memory resource for the eSPI MMIO */ mmio_range(dev, idx++, SPI_BASE_ADDRESS + ESPI_OFFSET_FROM_BAR, 4 * KiB); + /* Add a memory resource for the eSPI1 MMIO */ + if (CONFIG(SOC_AMD_COMMON_BLOCK_HAS_ESPI1)) + mmio_range(dev, idx++, SPI_BASE_ADDRESS + ESPI1_OFFSET_FROM_BAR, 4 * KiB); + /* FCH IOAPIC */ mmio_range(dev, idx++, IO_APIC_ADDR, 4 * KiB); From 68551a79ce8fb36543664feb86c7ec1134dcfa89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Tue, 8 Jul 2025 19:13:46 +0200 Subject: [PATCH 247/789] soc/amd/turin_poc: Adjust sources for Turin SOC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the SOC code based on the PPR for C1 stepping, doc 57238. 1. Turin CPU has less USB ports than Genoa, so the chip structure has to reflect that. The number of ports has been reduced to match the hardware capabilities. 2. Added early FCH initialization: legacy ISA devices, eSPI, I/O decoding, UARTs, SMBus and SPI. 3. Updated AOAC device numbers. 4. Updated MMIO and I/O base addresses for CPU internal devices. 5. Added reserved RAM and MMIO reporting. 6. Adjusted root complex layout to match Turin IOHCs base addresses and fabric IDs. 7. Extended chipset.cb devicetree to match the layout of devices on a single socket Turin system. Change-Id: I5272c1f2cd2aa259569d0bc6fa5c4073907b1673 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/88708 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/soc/amd/turin_poc/Kconfig | 102 +++++- src/soc/amd/turin_poc/Makefile.mk | 27 +- src/soc/amd/turin_poc/acpi.c | 4 +- src/soc/amd/turin_poc/acpi/mmio.asl | 231 ++++++++++++ src/soc/amd/turin_poc/acpi/pci_int_defs.asl | 36 +- src/soc/amd/turin_poc/acpi/resources.asl | 68 ++++ src/soc/amd/turin_poc/acpi/soc.asl | 11 +- src/soc/amd/turin_poc/chip.c | 3 + src/soc/amd/turin_poc/chip.h | 19 +- src/soc/amd/turin_poc/chipset.cb | 344 ++++++++++-------- src/soc/amd/turin_poc/cpu.c | 5 +- src/soc/amd/turin_poc/domain.c | 39 +- src/soc/amd/turin_poc/early_fch.c | 77 +++- src/soc/amd/turin_poc/fch.c | 72 +++- src/soc/amd/turin_poc/gpio.c | 1 + .../turin_poc/include/soc/amd_pci_int_defs.h | 24 +- src/soc/amd/turin_poc/include/soc/aoac_defs.h | 8 +- src/soc/amd/turin_poc/include/soc/cpu.h | 5 +- .../amd/turin_poc/include/soc/data_fabric.h | 22 +- src/soc/amd/turin_poc/include/soc/gpio.h | 91 +++-- src/soc/amd/turin_poc/include/soc/iomap.h | 28 +- src/soc/amd/turin_poc/include/soc/msr.h | 4 +- src/soc/amd/turin_poc/include/soc/smi.h | 3 +- src/soc/amd/turin_poc/include/soc/smu.h | 10 +- .../amd/turin_poc/include/soc/southbridge.h | 9 +- src/soc/amd/turin_poc/include/soc/xhci.h | 17 + src/soc/amd/turin_poc/mca.c | 28 +- src/soc/amd/turin_poc/root_complex.c | 65 +++- src/soc/amd/turin_poc/smihandler.c | 1 + src/soc/amd/turin_poc/uart.c | 4 + 30 files changed, 1081 insertions(+), 277 deletions(-) create mode 100644 src/soc/amd/turin_poc/acpi/resources.asl create mode 100644 src/soc/amd/turin_poc/include/soc/xhci.h diff --git a/src/soc/amd/turin_poc/Kconfig b/src/soc/amd/turin_poc/Kconfig index 55af8c71e6..8eadb04933 100644 --- a/src/soc/amd/turin_poc/Kconfig +++ b/src/soc/amd/turin_poc/Kconfig @@ -10,23 +10,39 @@ config SOC_SPECIFIC_OPTIONS select ACPI_SOC_NVS select ARCH_X86 select DEFAULT_X2APIC + select BOOT_DEVICE_SUPPORTS_WRITES if BOOT_DEVICE_SPI_FLASH + select CACHE_MRC_SETTINGS + select DRIVERS_USB_ACPI + select DRIVERS_USB_PCI_XHCI + select GENERIC_GPIO_LIB select HAVE_ACPI_TABLES + select HAVE_CF9_RESET + select HAVE_EM100_SUPPORT select HAVE_X86_64_SUPPORT - select HAVE_SMI_HANDLER + select HAVE_SMI_HANDLER if !NO_SMM + select IDT_IN_EVERY_STAGE + select PARALLEL_MP_AP_WORK + select PROVIDES_ROM_SHARING + select RTC select SOC_AMD_COMMON select SOC_AMD_COMMON_BLOCK_ACPI select SOC_AMD_COMMON_BLOCK_ACPIMMIO + select SOC_AMD_COMMON_BLOCK_ACPIMMIO_PM_IO_ACCESS select SOC_AMD_COMMON_BLOCK_ACPI_CPU_POWER_STATE select SOC_AMD_COMMON_BLOCK_ACPI_IVRS select SOC_AMD_COMMON_BLOCK_ACPI_MADT select SOC_AMD_COMMON_BLOCK_AOAC + select SOC_AMD_COMMON_BLOCK_APOB select SOC_AMD_COMMON_BLOCK_BANKED_GPIOS - select SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM17H_19H + select SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM1AH select SOC_AMD_COMMON_BLOCK_DATA_FABRIC select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_MULTI_PCI_SEGMENT select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_EXTENDED_MMIO select SOC_AMD_COMMON_BLOCK_HAS_ESPI + select SOC_AMD_COMMON_BLOCK_HAS_ESPI_ALERT_ENABLE + select SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES + select SOC_AMD_COMMON_BLOCK_ESPI_RETAIN_PORT80_EN select SOC_AMD_COMMON_BLOCK_I2C select SOC_AMD_COMMON_BLOCK_I3C select SOC_AMD_COMMON_BLOCK_IOMMU @@ -35,8 +51,11 @@ config SOC_SPECIFIC_OPTIONS select SOC_AMD_COMMON_BLOCK_NONCAR select SOC_AMD_COMMON_BLOCK_PCI select SOC_AMD_COMMON_BLOCK_PCI_MMCONF + select SOC_AMD_COMMON_BLOCK_PM select SOC_AMD_COMMON_BLOCK_PSP_GEN2 + select SOC_AMD_COMMON_BLOCK_PSP_SMI select SOC_AMD_COMMON_BLOCK_PSP_SPL + select SOC_AMD_COMMON_BLOCK_SMBUS select SOC_AMD_COMMON_BLOCK_SMI select SOC_AMD_COMMON_BLOCK_SMM select SOC_AMD_COMMON_BLOCK_SMU @@ -47,8 +66,15 @@ config SOC_SPECIFIC_OPTIONS select SOC_AMD_COMMON_BLOCK_UART select SOC_AMD_COMMON_BLOCK_UCODE select SOC_AMD_COMMON_BLOCK_USE_ESPI + select SOC_AMD_COMMON_BLOCK_XHCI select SOC_AMD_OPENSIL select OPENSIL_DRIVER + select DRAM_SUPPORT_DDR5 + select SSE2 + select X86_AMD_FIXED_MTRRS + select X86_INIT_NEED_1_SIPI + select VBOOT_X86_SHA256_ACCELERATION if VBOOT + select UDK_2017_BINDING config USE_X86_64_SUPPORT default y @@ -73,7 +99,11 @@ config EARLY_RESERVED_DRAM_BASE config EARLYRAM_BSP_STACK_SIZE hex - default 0x1000 + default 0x10000 + +config STACK_SIZE + hex + default 0x10000 config MAX_CPUS int @@ -81,14 +111,18 @@ config MAX_CPUS config PSP_APOB_DRAM_ADDRESS hex - default 0x7001000 + default 0x7010000 help Location in DRAM where the PSP will copy the AGESA PSP Output Block. config PSP_APOB_DRAM_SIZE hex - default 0x20000 + default 0xd0000 + +config MRC_SETTINGS_CACHE_SIZE + hex + default 0xd0000 config PRERAM_CBMEM_CONSOLE_SIZE hex @@ -106,7 +140,7 @@ config C_ENV_BOOTBLOCK_SIZE config ROMSTAGE_ADDR hex - default 0x7050000 + default 0x7150000 help Sets the address in DRAM where romstage should be loaded. @@ -124,6 +158,14 @@ config ECAM_MMCONF_BUS_NUMBER int default 256 +config DISABLE_KEYBOARD_RESET_PIN + bool + help + Instruct the SoC to not use the state of GPIO_129 as keyboard reset. + +config CPU_PT_ROM_MAP_GB + default 1024 + menu "PSP Configuration Options" config AMDFW_CONFIG_FILE @@ -141,7 +183,7 @@ config PSP_INIT_ESPI Select to initialize the eSPI controller in the PSP Stage 2 Boot Loader. -config PSP_UNLOCK_SECURE_DEBUG +config PSP_UNLOCK_SECURE_DEBUG bool default y @@ -171,6 +213,11 @@ config PSP_SOFTFUSE_BITS 0=SoC MMIO UART, 1=IO port 0x3F8 See #57299 (NDA) for additional bit definitions. + +config PSPV2_MBOX_CMD_OFFSET + hex + default 0x10970 + endmenu config CONSOLE_UART_BASE_ADDRESS @@ -179,6 +226,7 @@ config CONSOLE_UART_BASE_ADDRESS default 0xfedc9000 if UART_FOR_CONSOLE = 0 default 0xfedca000 if UART_FOR_CONSOLE = 1 default 0xfedce000 if UART_FOR_CONSOLE = 2 + default 0xfedcf000 if UART_FOR_CONSOLE = 3 config SMM_TSEG_SIZE hex @@ -208,4 +256,44 @@ config ACPI_BERT_SIZE Specify the amount of DRAM reserved for gathering the data used to generate the ACPI table. +config ASYNC_FILE_LOADING + bool "Loads files from SPI asynchronously" + select COOP_MULTITASKING + select SOC_AMD_COMMON_BLOCK_LPC_SPI_DMA + select CBFS_PRELOAD + help + When enabled, the platform will use the LPC SPI DMA controller to + asynchronously load contents from the SPI ROM. This will improve + boot time because the CPUs can be performing useful work while the + SPI contents are being preloaded. + +config CBFS_CACHE_SIZE + hex + default 0x40000 if CBFS_PRELOAD + +config VBOOT + select VBOOT_STARTS_IN_BOOTBLOCK + select VBOOT_VBNV_CMOS + select VBOOT_VBNV_CMOS_BACKUP_TO_FLASH + +config RO_REGION_ONLY + string + depends on VBOOT_SLOTS_RW_AB || VBOOT_SLOTS_RW_A + default "apu/amdfw" + +config DISABLE_SPI_FLASH_ROM_SHARING + def_bool n + help + Instruct the chipset to not honor the EGPIO67_SPI_ROM_REQ pin + which indicates a board level ROM transaction request. This + removes arbitration with board and assumes the chipset controls + the SPI flash bus entirely. + +config SERIRQ_CONTINUOUS_MODE + bool + default n + help + Set this option to y for serial IRQ in continuous mode. + Otherwise it is in quiet mode. + endif # SOC_AMD_TURIN_POC diff --git a/src/soc/amd/turin_poc/Makefile.mk b/src/soc/amd/turin_poc/Makefile.mk index ab4d40f257..68144574c2 100644 --- a/src/soc/amd/turin_poc/Makefile.mk +++ b/src/soc/amd/turin_poc/Makefile.mk @@ -32,6 +32,7 @@ ifeq ($(call int-gt, $(CONFIG_ROM_SIZE) 0x1000000), 1) CBFSTOOL_ADD_CMD_OPTIONS+= --mmap 0:0xff000000:0x1000000 endif +ifneq ($(call strip_quotes, $(CONFIG_AMDFW_CONFIG_FILE)),) # # PSP Directory Table items # @@ -79,6 +80,14 @@ PSP_ELF_FILE=$(objcbfs)/bootblock_fixed_data.elf PSP_BIOSBIN_SIZE=$(shell $(READELF_bootblock) -Wl $(PSP_ELF_FILE) | grep LOAD | awk '{print $$5}') PSP_BIOSBIN_DEST=$(shell $(READELF_bootblock) -Wl $(PSP_ELF_FILE) | grep LOAD | awk '{print $$3}') +ifneq ($(CONFIG_SOC_AMD_COMMON_BLOCK_APOB_NV_DISABLE),y) +# type = 0x63 - construct APOB NV base/size from flash map +# The flashmap section used for this is expected to be named RW_MRC_CACHE +# Size should be 0xD0000 +APOB_NV_SIZE=$(call get_fmap_value,FMAP_SECTION_RW_MRC_CACHE_SIZE) +APOB_NV_BASE=$(call get_fmap_value,FMAP_SECTION_RW_MRC_CACHE_START) +endif # !CONFIG_SOC_AMD_COMMON_BLOCK_APOB_NV_DISABLE + # Helper function to return a value with given bit set # Soft Fuse type = 0xb - See #57299 (NDA) for bit definitions. set-bit=$(call int-shift-left, 1 $(call _toint,$1)) @@ -104,6 +113,9 @@ OPT_PSP_BIOSBIN_FILE=$(call add_opt_prefix, $(PSP_BIOSBIN_FILE), --bios-bin) OPT_PSP_BIOSBIN_DEST=$(call add_opt_prefix, $(PSP_BIOSBIN_DEST), --bios-bin-dest) OPT_PSP_BIOSBIN_SIZE=$(call add_opt_prefix, $(PSP_BIOSBIN_SIZE), --bios-uncomp-size) +OPT_APOB_NV_SIZE=$(call add_opt_prefix, $(APOB_NV_SIZE), --apob-nv-size) +OPT_APOB_NV_BASE=$(call add_opt_prefix, $(APOB_NV_BASE), --apob-nv-base) + OPT_EFS_SPI_READ_MODE=$(call add_opt_prefix, $(CONFIG_EFS_SPI_READ_MODE), --spi-read-mode) OPT_EFS_SPI_SPEED=$(call add_opt_prefix, $(CONFIG_EFS_SPI_SPEED), --spi-speed) OPT_EFS_SPI_MICRON_FLAG=$(call add_opt_prefix, $(CONFIG_EFS_SPI_MICRON_FLAG), --spi-micron-flag) @@ -112,14 +124,22 @@ OPT_PSP_SOFTFUSE=$(call add_opt_prefix, $(PSP_SOFTFUSE), --soft-fuse) OPT_WHITELIST_FILE=$(call add_opt_prefix, $(PSP_WHITELIST_FILE), --whitelist) OPT_SPL_TABLE_FILE=$(call add_opt_prefix, $(SPL_TABLE_FILE), --spl-table) +OPT_UCODE_FILES=$(foreach i, $(shell seq $(words $(amd_microcode_bins))), \ + $(call add_opt_prefix, $(word $(i), $(amd_microcode_bins)), \ + --instance $(shell printf "%x" $$(($(i)-1))) --ucode)) + AMDFW_COMMON_ARGS=$(OPT_PSP_APCB_FILES) \ $(OPT_APOB_ADDR) \ + $(OPT_APOB_NV_SIZE) \ + $(OPT_APOB_NV_BASE) \ + $(OPT_UCODE_FILES) \ $(OPT_DEBUG_AMDFWTOOL) \ $(OPT_PSP_BIOSBIN_FILE) \ $(OPT_PSP_BIOSBIN_DEST) \ $(OPT_PSP_BIOSBIN_SIZE) \ $(OPT_PSP_SOFTFUSE) \ --use-pspsecureos \ + --load-s0i3 \ $(OPT_TOKEN_UNLOCK) \ $(OPT_WHITELIST_FILE) \ $(OPT_SPL_TABLE_FILE) \ @@ -127,11 +147,12 @@ AMDFW_COMMON_ARGS=$(OPT_PSP_APCB_FILES) \ $(OPT_EFS_SPI_SPEED) \ $(OPT_EFS_SPI_MICRON_FLAG) \ --config $(CONFIG_AMDFW_CONFIG_FILE) \ - --flashsize 0x1000000 + --flashsize $(call strip_quotes, $(CONFIG_ROM_SIZE)) $(obj)/amdfw.rom: $(call strip_quotes, $(PSP_BIOSBIN_FILE)) \ $$(PSP_APCB_FILES) \ $(DEP_FILES) \ + $(UCODE_FILES) \ $(AMDFWTOOL) \ $(obj)/fmap_config.h \ $(objcbfs)/bootblock_fixed_data.elf # this target also creates the .map file @@ -157,4 +178,8 @@ $(PSP_BIOSBIN_FILE): $(PSP_ELF_FILE) $(AMDCOMPRESS) $(AMDCOMPRESS) --infile $(PSP_ELF_FILE) --outfile $@ --compress \ --maxsize $(PSP_BIOSBIN_SIZE) +else +# Set FIRMWARE_LOCATION to get the microcode files +FIRMWARE_LOCATION=3rdparty/amd_firmwares/Firmwares/Turin +endif # ifneq ($(call strip_quotes, $(CONFIG_AMDFW_CONFIG_FILE)),) endif diff --git a/src/soc/amd/turin_poc/acpi.c b/src/soc/amd/turin_poc/acpi.c index 9091050ba5..224f2464a9 100644 --- a/src/soc/amd/turin_poc/acpi.c +++ b/src/soc/amd/turin_poc/acpi.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -40,6 +39,7 @@ unsigned long soc_acpi_write_tables(const struct device *device, unsigned long c struct acpi_rsdp *rsdp) { /* IVRS */ + printk(BIOS_DEBUG, "ACPI: * IVRS\n"); current = acpi_add_ivrs_table(current, rsdp); return current; @@ -54,7 +54,7 @@ const acpi_cstate_t cstate_cfg_table[] = { }, [1] = { .ctype = 2, - .latency = 0x12, + .latency = 0x64, .power = 0, }, }; diff --git a/src/soc/amd/turin_poc/acpi/mmio.asl b/src/soc/amd/turin_poc/acpi/mmio.asl index 9b5e1d2d2b..6ec247f788 100644 --- a/src/soc/amd/turin_poc/acpi/mmio.asl +++ b/src/soc/amd/turin_poc/acpi/mmio.asl @@ -33,6 +33,7 @@ Device (GPIO) Shared, , , IRQR) { 0 } Memory32Fixed (ReadWrite, ACPIMMIO_GPIO0_BASE, 0x400) + Memory32Fixed (ReadWrite, ACPIMMIO_RGPIO_BASE, 0x2C) } CreateDWordField (Local0, IRQR._INT, IRQN) If (PICM) { @@ -43,6 +44,7 @@ Device (GPIO) If (IRQN == 0x1f || IRQN == 0) { Return (ResourceTemplate() { Memory32Fixed (ReadWrite, ACPIMMIO_GPIO0_BASE, 0x400) + Memory32Fixed (ReadWrite, ACPIMMIO_RGPIO_BASE, 0x2C) }) } Else { Return (Local0) @@ -68,6 +70,7 @@ Device (FUR0) Exclusive, , , IRQR) { 0 } Memory32Fixed (ReadWrite, APU_UART0_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA0_BASE, 0x1000) } CreateDWordField (Local0, IRQR._INT, IRQN) If (PICM) { @@ -78,6 +81,7 @@ Device (FUR0) If (IRQN == 0x1f) { Return (ResourceTemplate() { Memory32Fixed (ReadWrite, APU_UART0_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA0_BASE, 0x1000) }) } Else { Return (Local0) @@ -105,6 +109,7 @@ Device (FUR1) { Exclusive, , , IRQR) { 0 } Memory32Fixed (ReadWrite, APU_UART1_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA1_BASE, 0x1000) } CreateDWordField (Local0, IRQR._INT, IRQN) If (PICM) { @@ -115,6 +120,7 @@ Device (FUR1) { If (IRQN == 0x1f) { Return (ResourceTemplate() { Memory32Fixed (ReadWrite, APU_UART1_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA1_BASE, 0x1000) }) } Else { Return (Local0) @@ -142,6 +148,7 @@ Device (FUR2) { Exclusive, , , IRQR) { 0 } Memory32Fixed (ReadWrite, APU_UART2_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA2_BASE, 0x1000) } CreateDWordField (Local0, IRQR._INT, IRQN) If (PICM) { @@ -152,6 +159,7 @@ Device (FUR2) { If (IRQN == 0x1f) { Return (ResourceTemplate() { Memory32Fixed (ReadWrite, APU_UART2_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA2_BASE, 0x1000) }) } Else { Return (Local0) @@ -167,6 +175,45 @@ Device (FUR2) { AOAC_DEVICE(FCH_AOAC_DEV_UART2, 0) } +Device (FUR3) { + Name (_HID, "AMDI0020") + Name (_UID, 0x3) + Method (_CRS, 0) { + Local0 = ResourceTemplate() { + Interrupt ( + ResourceConsumer, + Edge, + ActiveHigh, + Exclusive, , , IRQR) + { 0 } + Memory32Fixed (ReadWrite, APU_UART3_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA3_BASE, 0x1000) + } + CreateDWordField (Local0, IRQR._INT, IRQN) + If (PICM) { + IRQN = IUA3 + } Else { + IRQN = PUA3 + } + If (IRQN == 0x1f) { + Return (ResourceTemplate() { + Memory32Fixed (ReadWrite, APU_UART3_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA3_BASE, 0x1000) + }) + } Else { + Return (Local0) + } + } + + Name (STAT, 0x0) + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + AOAC_DEVICE(FCH_AOAC_DEV_UART3, 0) +} + Device (I2C0) { Name (_HID, "AMDI0010") Name (_UID, 0x0) @@ -412,3 +459,187 @@ Device (MISC) Return (0x0B) } } + +Device (I3C0) +{ + Name (STAT, 0x0) + + /* Only return I3C controller HID "AMDI0015" when device is enabled in devicetree */ + Method (_HID, 0x0) { + If (STAT) { + Return ("AMDI0015") + } Else { + Return ("AMDI0016") + } + } + Name (_UID, 0x0) + Method (_CRS, 0) { + Local0 = ResourceTemplate() { + Interrupt ( + ResourceConsumer, + Edge, + ActiveHigh, + Exclusive, , , IRQR) + { 0 } + Memory32Fixed (ReadWrite, APU_I3C0_BASE, 0x1000) + } + CreateDWordField (Local0, IRQR._INT, IRQN) + If (PICM) { + IRQN = II20 + } Else { + IRQN = PI20 + } + If (IRQN == 0x1f) { + Return (ResourceTemplate() { + Memory32Fixed (ReadWrite, APU_I3C0_BASE, 0x1000) + }) + } Else { + Return (Local0) + } + } + + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + AOAC_DEVICE(FCH_AOAC_DEV_I3C0, 0) +} + +Device (I3C1) +{ + Name (STAT, 0x0) + + /* Only return I3C controller HID "AMDI0015" when device is enabled in devicetree */ + Method (_HID, 0x0) { + If (STAT) { + Return ("AMDI0015") + } Else { + Return ("AMDI0016") + } + } + Name (_UID, 0x1) + Method (_CRS, 0) { + Local0 = ResourceTemplate() { + Interrupt ( + ResourceConsumer, + Edge, + ActiveHigh, + Exclusive, , , IRQR) + { 0 } + Memory32Fixed (ReadWrite, APU_I3C1_BASE, 0x1000) + } + CreateDWordField (Local0, IRQR._INT, IRQN) + If (PICM) { + IRQN = II21 + } Else { + IRQN = PI21 + } + If (IRQN == 0x1f) { + Return (ResourceTemplate() { + Memory32Fixed (ReadWrite, APU_I3C1_BASE, 0x1000) + }) + } Else { + Return (Local0) + } + } + + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + AOAC_DEVICE(FCH_AOAC_DEV_I3C1, 0) +} + +Device (I3C2) +{ + Name (STAT, 0x0) + + /* Only return I3C controller HID "AMDI0015" when device is enabled in devicetree */ + Method (_HID, 0x0) { + If (STAT) { + Return ("AMDI0015") + } Else { + Return ("AMDI0016") + } + } + Name (_UID, 0x2) + Method (_CRS, 0) { + Local0 = ResourceTemplate() { + Interrupt ( + ResourceConsumer, + Edge, + ActiveHigh, + Exclusive, , , IRQR) + { 0 } + Memory32Fixed (ReadWrite, APU_I3C2_BASE, 0x1000) + } + CreateDWordField (Local0, IRQR._INT, IRQN) + If (PICM) { + IRQN = II22 + } Else { + IRQN = PI22 + } + If (IRQN == 0x1f) { + Return (ResourceTemplate() { + Memory32Fixed (ReadWrite, APU_I3C2_BASE, 0x1000) + }) + } Else { + Return (Local0) + } + } + + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + AOAC_DEVICE(FCH_AOAC_DEV_I3C2, 0) +} + +Device (I3C3) +{ + Name (STAT, 0x0) + + /* Only return I3C controller HID "AMDI0015" when device is enabled in devicetree */ + Method (_HID, 0x0) { + If (STAT) { + Return ("AMDI0015") + } Else { + Return ("AMDI0016") + } + } + Name (_UID, 0x3) + Method (_CRS, 0) { + Local0 = ResourceTemplate() { + Interrupt ( + ResourceConsumer, + Edge, + ActiveHigh, + Exclusive, , , IRQR) + { 0 } + Memory32Fixed (ReadWrite, APU_I3C3_BASE, 0x1000) + } + CreateDWordField (Local0, IRQR._INT, IRQN) + If (PICM) { + IRQN = II23 + } Else { + IRQN = PI23 + } + If (IRQN == 0x1f) { + Return (ResourceTemplate() { + Memory32Fixed (ReadWrite, APU_I3C3_BASE, 0x1000) + }) + } Else { + Return (Local0) + } + } + + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + AOAC_DEVICE(FCH_AOAC_DEV_I3C3, 0) +} diff --git a/src/soc/amd/turin_poc/acpi/pci_int_defs.asl b/src/soc/amd/turin_poc/acpi/pci_int_defs.asl index 22455c5cae..14b2f7db44 100644 --- a/src/soc/amd/turin_poc/acpi/pci_int_defs.asl +++ b/src/soc/amd/turin_poc/acpi/pci_int_defs.asl @@ -21,17 +21,30 @@ IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) { PIRG, 0x00000008, /* Index 6: INTG */ PIRH, 0x00000008, /* Index 7: INTH */ - Offset (0x10), + Offset (0xc), + SIRA, 0x00000008, /* Index 0xc: Serial IRQ A */ + SIRB, 0x00000008, /* Index 0xd: Serial IRQ B */ + SIRC, 0x00000008, /* Index 0xe: Serial IRQ C */ + SIRD, 0x00000008, /* Index 0xf: Serial IRQ D */ PSCI, 0x00000008, /* Index 0x10: SCI */ PSB0, 0x00000008, /* Index 0x11: SMBUS0 */ PASF, 0x00000008, /* Index 0x12: ASF */ + PHDA, 0x00000008, /* Index 0x12: HDA */ Offset (0x16), PPMN, 0x00000008, /* Index 0x16: PerMon */ + PSDC, 0x00000008, /* Index 0x17: SD */ Offset (0x1a), PSIO, 0x00000008, /* Index 0x1A: SDIO */ + Offset (0x30), + PUS1, 0x00000008, /* Index 0x30: USB EMU */ + Offset (0x34), + PUS3, 0x00000008, /* Index 0x34: XHCI0 */ + Offset (0x41), + PSAT, 0x00000008, /* Index 0x41: SATA */ + Offset (0x50), PGP0, 0x00000008, /* Index 0x50: GPP0 */ PGP1, 0x00000008, /* Index 0x51: GPP1 */ @@ -64,27 +77,40 @@ IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) { IORG, 0x00000008, /* Index 0x86: INTG */ IORH, 0x00000008, /* Index 0x87: INTH */ - Offset (0x90), + Offset (0x8c), + ISIA, 0x00000008, /* Index 0x8c: Serial IRQ A */ + ISIB, 0x00000008, /* Index 0x8d: Serial IRQ B */ + ISIC, 0x00000008, /* Index 0x8e: Serial IRQ C */ + ISID, 0x00000008, /* Index 0x8f: Serial IRQ D */ ISCI, 0x00000008, /* Index 0x90: SCI */ ISB0, 0x00000008, /* Index 0x91: SMBUS0 */ IASF, 0x00000008, /* Index 0x92: ASF */ + IHDA, 0x00000008, /* Index 0x93: HDA */ Offset (0x96), IPMN, 0x00000008, /* Index 0x96: PerMon */ + ISDC, 0x00000008, /* Index 0x97: SD */ Offset (0x9a), ISIO, 0x00000008, /* Index 0x9A: SDIO */ - Offset (0xD0), + Offset (0xb0), + IUS1, 0x00000008, /* Index 0xb0: USB EMU */ + Offset (0xb4), + IUS3, 0x00000008, /* Index 0xb4: XHCI0 */ + Offset (0xc1), + ISAT, 0x00000008, /* Index 0xc1: SATA */ + + Offset (0xd0), IGP0, 0x00000008, /* Index 0xD0: GPP0 */ IGP1, 0x00000008, /* Index 0xD1: GPP1 */ IGP2, 0x00000008, /* Index 0xD2: GPP2 */ IGP3, 0x00000008, /* Index 0xD3: GPP3 */ - Offset (0xE2), + Offset (0xe2), IGPI, 0x00000008, /* Index 0xE2: GPIO */ - Offset (0xF0), + Offset (0xf0), II20, 0x00000008, /* Index 0xF0: I2C0/I3C0 */ II21, 0x00000008, /* Index 0xF1: I2C1/I3C1 */ II22, 0x00000008, /* Index 0xF2: I2C2/I3C2 */ diff --git a/src/soc/amd/turin_poc/acpi/resources.asl b/src/soc/amd/turin_poc/acpi/resources.asl new file mode 100644 index 0000000000..98437690b5 --- /dev/null +++ b/src/soc/amd/turin_poc/acpi/resources.asl @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* PCI Device Resource Consumption */ +Device (PDRC) { + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 0x700) + Name (_STA, 0x0F) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, 0x0010, 0x0010, 0x00, 0x10, ) + IO (Decode16, 0x0022, 0x0022, 0x00, 0x1e, ) + IO (Decode16, 0x0063, 0x0063, 0x00, 0x01, ) + IO (Decode16, 0x0065, 0x0065, 0x00, 0x01, ) + IO (Decode16, 0x0067, 0x0067, 0x00, 0x09, ) + IO (Decode16, 0x0072, 0x0072, 0x00, 0x0E, ) + IO (Decode16, 0x0080, 0x0080, 0x00, 0x01, ) + IO (Decode16, 0x0084, 0x0084, 0x00, 0x03, ) + IO (Decode16, 0x0088, 0x0088, 0x00, 0x01, ) + IO (Decode16, 0x008c, 0x008c, 0x00, 0x03, ) + IO (Decode16, 0x0090, 0x0090, 0x00, 0x10, ) + IO (Decode16, 0x00a2, 0x00a2, 0x00, 0x1e, ) + IO (Decode16, 0x00b1, 0x00b1, 0x00, 0x01, ) + IO (Decode16, 0x00e0, 0x00e0, 0x00, 0x10, ) + /* ACPI */ + IO (Decode16, 0x0400, 0x0400, 0x00, 0xa0, ) + /* DMA */ + IO (Decode16, 0x040b, 0x040b, 0x00, 0x01, ) + /* INTR edge control */ + IO (Decode16, 0x04d0, 0x04d0, 0x00, 0x02, ) + /* DMA */ + IO (Decode16, 0x04d6, 0x04d6, 0x00, 0x01, ) + IO (Decode16, 0x0900, 0x0900, 0x00, 0x10, ) + IO (Decode16, 0x0910, 0x0910, 0x00, 0x10, ) + /* SMBUS */ + IO (Decode16, 0x0b00, 0x0b00, 0x00, 0x10, ) + /* SMBUS ASF */ + IO (Decode16, 0x0b20, 0x0b20, 0x00, 0x20, ) + /* PCI interrupt router */ + IO (Decode16, 0x0c00, 0x0c00, 0x00, 0x02, ) + /* PCI ERR */ + IO (Decode16, 0x0c14, 0x0c14, 0x00, 0x01, ) + IO (Decode16, 0x0c50, 0x0c50, 0x00, 0x02, ) + IO (Decode16, 0x0c52, 0x0c52, 0x00, 0x01, ) + IO (Decode16, 0x0c6c, 0x0c6c, 0x00, 0x01, ) + /* ISA MISC */ + IO (Decode16, 0x0c6f, 0x0c6f, 0x00, 0x01, ) + IO (Decode16, 0x0cd0, 0x0cd0, 0x00, 0x02, ) + /* PMIO2 */ + IO (Decode16, 0x0cd2, 0x0cd2, 0x00, 0x02, ) + /* BIOSRAM */ + IO (Decode16, 0x0cd4, 0x0cd4, 0x00, 0x02, ) + /* PMIO */ + IO (Decode16, 0x0cd6, 0x0cd6, 0x00, 0x02, ) + /* AB INDX */ + IO (Decode16, 0x0cd8, 0x0cd8, 0x00, 0x08, ) + /* ACPI PMA CNTL BLK */ + IO (Decode16, 0xfe00, 0xfe00, 0x00, 0xff, ) + Memory32Fixed (ReadWrite, 0xfee00000, 0x00001000, ) + /* Remainder of remote GPIO up to GPIO0 bank */ + Memory32Fixed (ReadWrite, 0xfed8122c, 0x000002d4, ) + /* ACPI MMIO above GPIO banks */ + Memory32Fixed (ReadWrite, 0xfed81a00, 0x0000e600, ) + /* Watchdog */ + Memory32Fixed (ReadWrite, 0xfeb00000, 0x00000010, ) + /* ROM */ + Memory32Fixed (ReadWrite, 0xff000000, 0x01000000, ) + }) +} diff --git a/src/soc/amd/turin_poc/acpi/soc.asl b/src/soc/amd/turin_poc/acpi/soc.asl index 75344dc325..5d18024705 100644 --- a/src/soc/amd/turin_poc/acpi/soc.asl +++ b/src/soc/amd/turin_poc/acpi/soc.asl @@ -19,6 +19,15 @@ Scope(\_SB) { ROOT_BRIDGE(S0B1) ROOT_BRIDGE(S0B2) ROOT_BRIDGE(S0B3) + ROOT_BRIDGE(S0B4) + ROOT_BRIDGE(S0B5) + ROOT_BRIDGE(S0B6) + ROOT_BRIDGE(S0B7) + + Scope(S0B0) { + #include "resources.asl" + #include + } /* End S0B0 scope */ } /* End \_SB scope */ #include @@ -34,6 +43,4 @@ Scope(\_SB) { */ Method (PNOT) { - /* Report AC/DC state to ALIB using WAL1() */ - \WAL1 () } diff --git a/src/soc/amd/turin_poc/chip.c b/src/soc/amd/turin_poc/chip.c index 344617d52e..ee5ad5e0a0 100644 --- a/src/soc/amd/turin_poc/chip.c +++ b/src/soc/amd/turin_poc/chip.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -10,6 +11,8 @@ static void soc_init(void *chip_info) { default_dev_ops_root.write_acpi_tables = soc_acpi_write_tables; + display_mtrrs(); + amd_opensil_silicon_init(); data_fabric_print_mmio_conf(); diff --git a/src/soc/amd/turin_poc/chip.h b/src/soc/amd/turin_poc/chip.h index f08f348f15..1bfe6e6c92 100644 --- a/src/soc/amd/turin_poc/chip.h +++ b/src/soc/amd/turin_poc/chip.h @@ -9,6 +9,11 @@ #include #include +#define MAX_DOMAINS 8 + +static const unsigned int domain_to_rb_index[MAX_DOMAINS] = { 2, 7, 3, 6, 4, 1, 5, 0 }; +static const unsigned int domain_to_logical_rb[MAX_DOMAINS] = { 4, 5, 6, 7, 3, 2, 1, 0 }; + struct usb31_phy_settings { uint8_t rx_ana_iq_phase_adjust; uint8_t rx_eq_delta_iq_ovrd_en; @@ -30,33 +35,23 @@ struct soc_usb_config { struct { uint8_t port0 : 4; uint8_t port1 : 4; - uint8_t port2 : 4; - uint8_t port3 : 4; - uint8_t port4 : 4; - uint8_t port5 : 4; - uint8_t port6 : 4; - uint8_t port7 : 4; } usb2_oc_pins[2]; struct { uint8_t port0 : 4; uint8_t port1 : 4; - uint8_t port2 : 4; - uint8_t port3 : 4; } usb3_oc_pins[2]; bool polarity_cfg_low; union { struct { uint8_t port0 : 2; uint8_t port1 : 2; - uint8_t port2 : 2; /* Broken in OpenSIL */ - uint8_t port3 : 2; /* Broken in OpenSIL */ }; uint8_t raw; } usb3_force_gen1; bool usb31_phy_enable; - struct usb31_phy_settings usb31_phy[8]; + struct usb31_phy_settings usb31_phy[2]; bool s1_usb31_phy_enable; - struct usb31_phy_settings s1_usb31_phy[8]; + struct usb31_phy_settings s1_usb31_phy[2]; }; struct soc_amd_turin_poc_config { diff --git a/src/soc/amd/turin_poc/chipset.cb b/src/soc/amd/turin_poc/chipset.cb index 399d3530fc..f8f4888658 100644 --- a/src/soc/amd/turin_poc/chipset.cb +++ b/src/soc/amd/turin_poc/chipset.cb @@ -4,14 +4,14 @@ chip soc/amd/turin_poc device cpu_cluster 0 on ops amd_cpu_bus_ops end # OC pins - register "usb.usb2_oc_pins[0]" = "{ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf }" - register "usb.usb2_oc_pins[1]" = "{ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf }" - register "usb.usb3_oc_pins[0]" = "{ 0xf, 0xf, 0xf, 0xf }" - register "usb.usb3_oc_pins[1]" = "{ 0xf, 0xf, 0xf, 0xf }" + register "usb.usb2_oc_pins[0]" = "{ 0xf, 0xf }" + register "usb.usb2_oc_pins[1]" = "{ 0xf, 0xf }" + register "usb.usb3_oc_pins[0]" = "{ 0xf, 0xf }" + register "usb.usb3_oc_pins[1]" = "{ 0xf, 0xf }" device domain 0 on ops turin_pci_domain_ops - device pci 00.0 alias gnb_0 on end + device pci 00.0 alias gnb_0 on ops turin_root_complex_operations end device pci 00.2 alias iommu_0 off ops amd_iommu_ops end device pci 00.3 alias rcec_0 off end @@ -47,69 +47,19 @@ chip soc/amd/turin_poc end device pci 03.0 on end # Dummy device function, do not disable - chip drivers/amd/opensil/mpio - device pci 03.1 alias gpp_bridge_0_0_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.2 alias gpp_bridge_0_1_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.3 alias gpp_bridge_0_2_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.4 alias gpp_bridge_0_3_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.5 alias gpp_bridge_0_4_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.6 alias gpp_bridge_0_5_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.7 alias gpp_bridge_0_6_b off end - end - device pci 04.0 on end # Dummy device function, do not disable - chip drivers/amd/opensil/mpio - device pci 04.1 alias gpp_bridge_0_7_b off end - end - chip drivers/amd/opensil/mpio - device pci 04.2 alias gpp_bridge_0_8_b off end - end - device pci 05.0 on end # Dummy device function, do not disable - chip drivers/amd/opensil/mpio - device pci 05.1 alias gpp_bridge_0_0_c off end - end - chip drivers/amd/opensil/mpio - device pci 05.2 alias gpp_bridge_0_1_c off end - end - chip drivers/amd/opensil/mpio - device pci 05.3 alias gpp_bridge_0_2_c off end - end - chip drivers/amd/opensil/mpio - device pci 05.4 alias gpp_bridge_0_3_c off end - end device pci 07.0 on end # Dummy device function, do not disable - device pci 07.1 alias gpp_bridge_0_a off # Internal GPP Bridge 0 to Bus B0 - device pci 0.0 on end # Dummy PCIe function - device pci 0.1 off end - device pci 0.2 alias primary_NTB_0 off end # Primary PCIe Non-TransparentBridge - device pci 0.3 alias secondry_NTB_0 off end # Secondary vNTB - device pci 0.4 alias xhci_0 off end # USB - device pci 0.5 alias mp0_0 off end # PSP (MP0) - device pci 0.6 alias acp_0 off end # Audio Processor (ACP) - device pci 0.7 alias hda_0 off end # Audio Processor HD Audio Controller (main AZ) - end - device pci 07.2 alias gpp_bridge_0_b off # Internal GPP Bridge 1 to Bus C0 - device pci 0.0 alias sata_0_0 off end # first SATA controller; AHCI mode - device pci 0.1 alias sata_0_1 off end # second SATA controller; AHCI mode + device pci 07.1 alias gpp_bridge_0_a on # Internal GPP Bridge 0 to Bus C0 + device pci 00.0 alias nbif_0 on end # Dummy PCIe function + device pci 00.1 alias sdxi_1 on end # Smart Data Accelerator Interface + device pci 00.2 alias primary_NTB_1 off end # Primary PCIe Non-TransparentBridge + device pci 00.3 alias secondry_NTB_1 off end # Secondary vNTB end device pci 14.0 alias smbus on end # primary FCH function device pci 14.3 alias lpc_bridge on ops amd_lpc_ops end - device pci 14.6 alias sdhci off end device pci 18.0 alias data_fabric_0 on end device pci 18.1 alias data_fabric_1 on end @@ -123,8 +73,7 @@ chip soc/amd/turin_poc device domain 1 on ops turin_pci_domain_ops - device pci 00.0 alias gnb_1 on end - device pci 00.2 alias iommu_1 off ops amd_iommu_ops end + device pci 00.0 alias gnb_1 on ops turin_root_complex_operations end device pci 00.3 alias rcec_1 off end device pci 01.0 on end # Dummy device function, do not disable @@ -157,224 +106,321 @@ chip soc/amd/turin_poc chip drivers/amd/opensil/mpio device pci 02.2 alias gpp_bridge_1_8_a off end end + end - device pci 03.0 on end # Dummy device function, do not disable + device domain 2 on + ops turin_pci_domain_ops + device pci 00.0 alias gnb_2 on ops turin_root_complex_operations end + device pci 00.2 alias iommu_2 off ops amd_iommu_ops end + + device pci 01.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 03.1 alias gpp_bridge_1_0_b off end + device pci 01.1 alias gpp_bridge_2_0_a off end end chip drivers/amd/opensil/mpio - device pci 03.2 alias gpp_bridge_1_1_b off end + device pci 01.2 alias gpp_bridge_2_1_a off end end chip drivers/amd/opensil/mpio - device pci 03.3 alias gpp_bridge_1_2_b off end + device pci 01.3 alias gpp_bridge_2_2_a off end end chip drivers/amd/opensil/mpio - device pci 03.4 alias gpp_bridge_1_3_b off end + device pci 01.4 alias gpp_bridge_2_3_a off end end chip drivers/amd/opensil/mpio - device pci 03.5 alias gpp_bridge_1_4_b off end + device pci 01.5 alias gpp_bridge_2_4_a off end end chip drivers/amd/opensil/mpio - device pci 03.6 alias gpp_bridge_1_5_b off end + device pci 01.6 alias gpp_bridge_2_5_a off end end chip drivers/amd/opensil/mpio - device pci 03.7 alias gpp_bridge_1_6_b off end + device pci 01.7 alias gpp_bridge_2_6_a off end end - device pci 04.0 on end # Dummy device function, do not disable + device pci 02.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 04.1 alias gpp_bridge_1_7_b off end + device pci 02.1 alias gpp_bridge_2_7_a off end end chip drivers/amd/opensil/mpio - device pci 04.2 alias gpp_bridge_1_8_b off end + device pci 02.2 alias gpp_bridge_2_8_a off end end + device pci 03.0 on end # Dummy device function, do not disable + device pci 04.0 on end # Dummy device function, do not disable + device pci 05.0 on end # Dummy device function, do not disable + chip drivers/amd/opensil/mpio + device pci 05.1 alias gpp_bridge_2_0_c off end + end + chip drivers/amd/opensil/mpio + device pci 05.2 alias gpp_bridge_2_1_c off end + end + chip drivers/amd/opensil/mpio + device pci 05.3 alias gpp_bridge_2_2_c off end + end device pci 07.0 on end # Dummy device function, do not disable - device pci 07.1 alias gpp_bridge_1_a off - device pci 0.0 on end # Dummy PCIe function - device pci 0.1 off end #SDXI - device pci 0.2 alias primary_NTB_1 off end # Primary PCIe Non-TransparentBridge - device pci 0.3 alias secondry_NTB_1 off end # Secondary vNTB + device pci 07.1 alias gpp_bridge_2_a on # Internal GPP Bridge 0 to Bus C1 + device pci 00.0 alias nbif_2 on end # Dummy PCIe function + device pci 00.1 alias sdxi_2 on end # Smart Data Accelerator Interface + device pci 00.3 alias secondry_NTB_2 off end # Secondary vNTB + device pci 00.4 alias xhci_0 off end # USB + device pci 00.7 alias hda off end # HD Audio Controller (AZ) + end + device pci 07.2 alias gpp_bridge_2_b on # Internal GPP Bridge 0 to Bus D1 + device pci 00.0 alias sata_2_0 off end # first SATA controller; AHCI mode + device pci 00.1 alias sata_2_1 off end # second SATA controller; AHCI mode end end - device domain 2 on + device domain 3 on ops turin_pci_domain_ops - device pci 00.0 alias gnb_2 on end - device pci 00.2 alias iommu_2 off ops amd_iommu_ops end - device pci 00.3 alias rcec_2 off end + device pci 00.0 alias gnb_3 on ops turin_root_complex_operations end device pci 01.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 01.1 alias gpp_bridge_2_0_a off end + device pci 01.1 alias gpp_bridge_3_0_a off end end chip drivers/amd/opensil/mpio - device pci 01.2 alias gpp_bridge_2_1_a off end + device pci 01.2 alias gpp_bridge_3_1_a off end end chip drivers/amd/opensil/mpio - device pci 01.3 alias gpp_bridge_2_2_a off end + device pci 01.3 alias gpp_bridge_3_2_a off end end chip drivers/amd/opensil/mpio - device pci 01.4 alias gpp_bridge_2_3_a off end + device pci 01.4 alias gpp_bridge_3_3_a off end end chip drivers/amd/opensil/mpio - device pci 01.5 alias gpp_bridge_2_4_a off end + device pci 01.5 alias gpp_bridge_3_4_a off end end chip drivers/amd/opensil/mpio - device pci 01.6 alias gpp_bridge_2_5_a off end + device pci 01.6 alias gpp_bridge_3_5_a off end end chip drivers/amd/opensil/mpio - device pci 01.7 alias gpp_bridge_2_6_a off end + device pci 01.7 alias gpp_bridge_3_6_a off end end device pci 02.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 02.1 alias gpp_bridge_2_7_a off end + device pci 02.1 alias gpp_bridge_3_7_a off end end chip drivers/amd/opensil/mpio - device pci 02.2 alias gpp_bridge_2_8_a off end + device pci 02.2 alias gpp_bridge_3_8_a off end end + end - device pci 03.0 on end # Dummy device function, do not disable + device domain 4 on + ops turin_pci_domain_ops + device pci 00.0 alias gnb_4 on ops turin_root_complex_operations end + + device pci 01.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 03.1 alias gpp_bridge_2_0_b off end + device pci 01.1 alias gpp_bridge_4_0_a off end end chip drivers/amd/opensil/mpio - device pci 03.2 alias gpp_bridge_2_1_b off end + device pci 01.2 alias gpp_bridge_4_1_a off end end chip drivers/amd/opensil/mpio - device pci 03.3 alias gpp_bridge_2_2_b off end + device pci 01.3 alias gpp_bridge_4_2_a off end end chip drivers/amd/opensil/mpio - device pci 03.4 alias gpp_bridge_2_3_b off end + device pci 01.4 alias gpp_bridge_4_3_a off end end chip drivers/amd/opensil/mpio - device pci 03.5 alias gpp_bridge_2_4_b off end + device pci 01.5 alias gpp_bridge_4_4_a off end end chip drivers/amd/opensil/mpio - device pci 03.6 alias gpp_bridge_2_5_b off end + device pci 01.6 alias gpp_bridge_4_5_a off end end chip drivers/amd/opensil/mpio - device pci 03.7 alias gpp_bridge_2_6_b off end + device pci 01.7 alias gpp_bridge_4_6_a off end end - device pci 04.0 on end # Dummy device function, do not disable + device pci 02.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 04.1 alias gpp_bridge_2_7_b off end + device pci 02.1 alias gpp_bridge_4_7_a off end end chip drivers/amd/opensil/mpio - device pci 04.2 alias gpp_bridge_2_8_b off end - end - - device pci 05.0 on end # Dummy device function, do not disable - - device pci 07.0 on end # Dummy device function, do not disable - device pci 07.1 alias gpp_bridge_2_a off - device pci 0.0 on end # Dummy PCIe function - device pci 0.1 off end - device pci 0.2 alias primary_NTB_2 off end # Primary PCIe Non-TransparentBridge - device pci 0.3 alias secondry_NTB_2 off end # Secondary vNTB + device pci 02.2 alias gpp_bridge_4_8_a off end end end - device domain 3 on + device domain 5 on ops turin_pci_domain_ops - device pci 00.0 alias gnb_3 on end - device pci 00.2 alias iommu_3 off ops amd_iommu_ops end - device pci 00.3 alias rcec_3 off end + device pci 00.0 alias gnb_5 on ops turin_root_complex_operations end + device pci 00.2 alias iommu_5 off ops amd_iommu_ops end device pci 01.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 01.1 alias gpp_bridge_3_0_a off end + device pci 01.1 alias gpp_bridge_5_0_a off end end chip drivers/amd/opensil/mpio - device pci 01.2 alias gpp_bridge_3_1_a off end + device pci 01.2 alias gpp_bridge_5_1_a off end end chip drivers/amd/opensil/mpio - device pci 01.3 alias gpp_bridge_3_2_a off end + device pci 01.3 alias gpp_bridge_5_2_a off end end chip drivers/amd/opensil/mpio - device pci 01.4 alias gpp_bridge_3_3_a off end + device pci 01.4 alias gpp_bridge_5_3_a off end end chip drivers/amd/opensil/mpio - device pci 01.5 alias gpp_bridge_3_4_a off end + device pci 01.5 alias gpp_bridge_5_4_a off end end chip drivers/amd/opensil/mpio - device pci 01.6 alias gpp_bridge_3_5_a off end + device pci 01.6 alias gpp_bridge_5_5_a off end end chip drivers/amd/opensil/mpio - device pci 01.7 alias gpp_bridge_3_6_a off end + device pci 01.7 alias gpp_bridge_5_6_a off end end device pci 02.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 02.1 alias gpp_bridge_3_7_a off end + device pci 02.1 alias gpp_bridge_5_7_a off end end chip drivers/amd/opensil/mpio - device pci 02.2 alias gpp_bridge_3_8_a off end + device pci 02.2 alias gpp_bridge_5_8_a off end end device pci 03.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 03.1 alias gpp_bridge_3_0_b off end + device pci 03.1 alias gpp_bridge_5_0_b off end end chip drivers/amd/opensil/mpio - device pci 03.2 alias gpp_bridge_3_1_b off end + device pci 03.2 alias gpp_bridge_5_1_b off end end chip drivers/amd/opensil/mpio - device pci 03.3 alias gpp_bridge_3_2_b off end + device pci 03.3 alias gpp_bridge_5_2_b off end end chip drivers/amd/opensil/mpio - device pci 03.4 alias gpp_bridge_3_3_b off end + device pci 03.4 alias gpp_bridge_5_3_b off end end chip drivers/amd/opensil/mpio - device pci 03.5 alias gpp_bridge_3_4_b off end + device pci 03.5 alias gpp_bridge_5_4_b off end end chip drivers/amd/opensil/mpio - device pci 03.6 alias gpp_bridge_3_5_b off end + device pci 03.6 alias gpp_bridge_5_5_b off end end chip drivers/amd/opensil/mpio - device pci 03.7 alias gpp_bridge_3_6_b off end + device pci 03.7 alias gpp_bridge_5_6_b off end end device pci 04.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 04.1 alias gpp_bridge_3_7_b off end + device pci 04.1 alias gpp_bridge_5_7_b off end + end + + device pci 05.0 on end # Dummy device function, do not disable + chip drivers/amd/opensil/mpio + device pci 05.1 alias gpp_bridge_5_0_c off end + end + chip drivers/amd/opensil/mpio + device pci 05.2 alias gpp_bridge_5_1_c off end end chip drivers/amd/opensil/mpio - device pci 04.2 alias gpp_bridge_3_8_b off end + device pci 05.3 alias gpp_bridge_5_2_c off end end - device pci 05.0 on end # Dummy device function, do not disable + device pci 07.0 on end # Dummy device function, do not disable + device pci 07.1 alias gpp_bridge_3_a on # Internal GPP Bridge 0 to Bus C2 + device pci 00.0 alias nbif_3 on end # Dummy PCIe function + device pci 00.1 alias sdxi_3 on end # Smart Data Accelerator Interface + device pci 00.2 alias primary_NTB_3 off end # Primary PCIe Non-TransparentBridge + device pci 00.3 alias secondry_NTB_3 off end # Secondary vNTB + device pci 00.5 alias asp off end # PSP (MP0) + end + end + + device domain 6 on + ops turin_pci_domain_ops + device pci 00.0 alias gnb_6 on ops turin_root_complex_operations end + device pci 00.3 alias rcec_6 off end + + device pci 01.0 on end # Dummy device function, do not disable + chip drivers/amd/opensil/mpio + device pci 01.1 alias gpp_bridge_6_0_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.2 alias gpp_bridge_6_1_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.3 alias gpp_bridge_6_2_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.4 alias gpp_bridge_6_3_a off end + end chip drivers/amd/opensil/mpio - device pci 05.1 alias gpp_bridge_3_0_c off end + device pci 01.5 alias gpp_bridge_6_4_a off end end chip drivers/amd/opensil/mpio - device pci 05.2 alias gpp_bridge_3_1_c off end + device pci 01.6 alias gpp_bridge_6_5_a off end end chip drivers/amd/opensil/mpio - device pci 05.3 alias gpp_bridge_3_2_c off end + device pci 01.7 alias gpp_bridge_6_6_a off end end + + device pci 02.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 05.4 alias gpp_bridge_3_3_c off end + device pci 02.1 alias gpp_bridge_6_7_a off end end + chip drivers/amd/opensil/mpio + device pci 02.2 alias gpp_bridge_6_8_a off end + end + end + + device domain 7 on + ops turin_pci_domain_ops + device pci 00.0 alias gnb_7 on ops turin_root_complex_operations end + device pci 00.2 alias iommu_7 off ops amd_iommu_ops end + device pci 00.3 alias rcec_7 off end + + device pci 01.0 on end # Dummy device function, do not disable + chip drivers/amd/opensil/mpio + device pci 01.1 alias gpp_bridge_7_0_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.2 alias gpp_bridge_7_1_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.3 alias gpp_bridge_7_2_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.4 alias gpp_bridge_7_3_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.5 alias gpp_bridge_7_4_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.6 alias gpp_bridge_7_5_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.7 alias gpp_bridge_7_6_a off end + end + + device pci 02.0 on end # Dummy device function, do not disable + chip drivers/amd/opensil/mpio + device pci 02.1 alias gpp_bridge_7_7_a off end + end + chip drivers/amd/opensil/mpio + device pci 02.2 alias gpp_bridge_7_8_a off end + end + + device pci 03.0 on end # Dummy device function, do not disable + device pci 04.0 on end # Dummy device function, do not disable + device pci 05.0 on end # Dummy device function, do not disable device pci 07.0 on end # Dummy device function, do not disable - device pci 07.1 alias gpp_bridge_3_a off - device pci 0.0 on end # Dummy PCIe function - device pci 0.1 off end #SDXI - device pci 0.2 alias primary_NTB_3 off end # Primary PCIe Non-TransparentBridge - device pci 0.3 alias secondry_NTB_3 off end # Secondary vNTB - device pci 0.4 alias xhci_3 off end # USB - device pci 0.5 alias mp0_3 off end # PSP (MP0) + device pci 07.1 alias gpp_bridge_7_a on # Internal GPP Bridge 0 to Bus C3 + device pci 00.0 alias nbif_4 on end # Dummy PCIe function + device pci 00.1 alias sdxi_4 on end # Smart Data Accelerator Interface + device pci 00.2 alias primary_NTB_4 off end # Primary PCIe Non-TransparentBridge + device pci 00.3 alias secondry_NTB_4 off end # Secondary vNTB + device pci 00.4 alias xhci_1 off end # USB end - device pci 07.2 alias gpp_bridge_3_b off - device pci 0.0 alias sata_3_0 off end # first SATA controller; AHCI mode - device pci 0.1 alias sata_3_1 off end # second SATA controller; AHCI mode + device pci 07.2 alias gpp_bridge_7_b on # Internal GPP Bridge 0 to Bus D3 + device pci 00.0 alias sata_7_0 off end # first SATA controller; AHCI mode + device pci 00.1 alias sata_7_1 off end # second SATA controller; AHCI mode end + end device mmio 0xfedc2000 alias i2c_0 off ops soc_amd_i2c_mmio_ops end diff --git a/src/soc/amd/turin_poc/cpu.c b/src/soc/amd/turin_poc/cpu.c index aedd0ac6cf..fc1ad627eb 100644 --- a/src/soc/amd/turin_poc/cpu.c +++ b/src/soc/amd/turin_poc/cpu.c @@ -10,8 +10,9 @@ static struct device_operations cpu_dev_ops = { }; static struct cpu_device_id cpu_table[] = { - { X86_VENDOR_AMD, TURIN_A0_CPUID, CPUID_ALL_STEPPINGS_MASK }, - { X86_VENDOR_AMD, TURIN_B0_CPUID, CPUID_ALL_STEPPINGS_MASK }, + { X86_VENDOR_AMD, TURIN_Ax_CPUID, CPUID_ALL_STEPPINGS_MASK }, + { X86_VENDOR_AMD, TURIN_Bx_CPUID, CPUID_ALL_STEPPINGS_MASK }, + { X86_VENDOR_AMD, TURIN_Cx_CPUID, CPUID_ALL_STEPPINGS_MASK }, CPU_TABLE_END }; diff --git a/src/soc/amd/turin_poc/domain.c b/src/soc/amd/turin_poc/domain.c index 40177d7dcc..6991fdc527 100644 --- a/src/soc/amd/turin_poc/domain.c +++ b/src/soc/amd/turin_poc/domain.c @@ -1,23 +1,56 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #define IOHC_IOAPIC_BASE_ADDR_LO 0x2f0 +/* + * 12GiB of DF reserved space at the top of physical address space. The + * address is not fixed and depends on SME state, because it can reduce the + * available physical address space. + */ +#define DATA_FABRIC_RESERVED_BASE \ + (POWER_OF_2(cpu_phys_address_size()) - DF_RESERVED_TOP_12GB_MMIO_SIZE) +#define DATA_FABRIC_RESERVED_SIZE DF_RESERVED_TOP_12GB_MMIO_SIZE + +/* + * 64KiB of ACPI EINJ buffer, reserve it. Reads return FFs and cause errors in + * memtest86 if not reserved, and needless to say, crashes in operating + * systems too. + */ +#define ACPI_EINJ_RESERVED_BASE (4ull * GiB) +#define ACPI_EINJ_RESERVED_SIZE (64 * KiB) + void read_soc_memmap_resources(struct device *domain, unsigned long *idx) { read_lower_soc_memmap_resources(domain, idx); + if (is_domain0(domain)) { + reserved_ram_range(domain, (*idx)++, ACPI_EINJ_RESERVED_BASE, + ACPI_EINJ_RESERVED_SIZE); + + mmio_range(domain, (*idx)++, IOMMU_RESERVED_MMIO_BASE, 12ULL * GiB); + mmio_range(domain, (*idx)++, DATA_FABRIC_RESERVED_BASE, + DATA_FABRIC_RESERVED_SIZE); + + mmio_range(domain, (*idx)++, AMD_SB_ACPI_MMIO_ADDR, 0x2000); + mmio_range(domain, (*idx)++, ALINK_AHB_ADDRESS, 0x20000); + } + amd_opensil_add_memmap(domain, idx); } @@ -48,11 +81,15 @@ static void turin_domain_set_resources(struct device *domain) static const char *turin_domain_acpi_name(const struct device *domain) { const unsigned int domain_id = dev_get_domain_id(domain); - const char *domain_acpi_names[4] = { + const char *domain_acpi_names[8] = { "S0B0", "S0B1", "S0B2", "S0B3", + "S0B4", + "S0B5", + "S0B6", + "S0B7", }; if (domain_id < ARRAY_SIZE(domain_acpi_names)) diff --git a/src/soc/amd/turin_poc/early_fch.c b/src/soc/amd/turin_poc/early_fch.c index d82ebcbcf8..5bcbca0834 100644 --- a/src/soc/amd/turin_poc/early_fch.c +++ b/src/soc/amd/turin_poc/early_fch.c @@ -1,19 +1,73 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#define __SIMPLE_DEVICE__ + #include #include #include #include +#include #include +#include +#include +#include #include +#include #include #include +#include + +#define SMN_D18F0_BASE 0x49000000 + +static void df_set_pci_mmconf(void) +{ + uint32_t reg; + uint64_t mmconf_base = CONFIG_ECAM_MMCONF_BASE_ADDRESS; + uint64_t mmconf_limit = mmconf_base + CONFIG_ECAM_MMCONF_LENGTH; + + mmconf_limit--; + mmconf_limit &= 0xfff00000; /* Address bits [19:0] are fixed to be FFFFF */ + mmconf_base |= 1; /* Range enable */ + + /* + * We have to use I/O PCI access to SMN index/data, because MMCONF + * will not work with our MMCONF address until this function returns. + */ + reg = smn_io_read32(SMN_D18F0_BASE + 0xc10); + reg &= ~1; /* Disable MMCONF range first */ + smn_io_write32(SMN_D18F0_BASE + 0xc10, reg); + + /* Now repeat the order in which ABL configured the MMCONF */ + reg = mmconf_limit >> 32; + smn_io_write32(SMN_D18F0_BASE + 0xc1c, reg); + reg = mmconf_limit & 0xffffffff; + smn_io_write32(SMN_D18F0_BASE + 0xc18, reg); + reg = mmconf_base >> 32; + smn_io_write32(SMN_D18F0_BASE + 0xc14, reg); + reg = mmconf_base & 0xffffffff; + smn_io_write32(SMN_D18F0_BASE + 0xc10, reg); +} /* Before console init */ void fch_pre_init(void) { + /* + * Before we can proceed with any initialization that touches PCI, we + * have to ensure our PCI MMCONF base matches the register in DF. + */ + df_set_pci_mmconf(); + /* + * Enable_acpimmio_decode_pm04 to enable the ACPIMMIO decode which is + * needed to access the GPIO registers. + */ + enable_acpimmio_decode_pm04(); + /* Setup SPI base by calling lpc_early_init before setting up eSPI. */ + lpc_early_init(); + fch_spi_early_init(); + fch_smbus_init(); fch_enable_cf9_io(); - + fch_enable_legacy_io(); + fch_disable_legacy_dma_io(); enable_aoac_devices(); /* * On reset Range_0 defaults to enabled. We want to start with a clean @@ -24,10 +78,29 @@ void fch_pre_init(void) if (CONFIG(AMD_SOC_CONSOLE_UART)) set_uart_config(CONFIG_UART_FOR_CONSOLE); - configure_espi_with_mb_hook(); + /* disable the keyboard reset function before mainboard GPIO setup */ + if (CONFIG(DISABLE_KEYBOARD_RESET_PIN)) + fch_disable_kb_rst(); + + /* + * Skip eSPI configuration. The EFS/PSP DIR already contains eSPI configuration + * so x86 does not need to configure it. Running configure_espi_with_mb_hook + * and resetting eSPI causes the slave/AST2600 to stop printing output on serial + * port. Boards may still configure I/O decodes early, if needed. + * + * configure_espi_with_mb_hook(); + */ } /* After console init */ void fch_early_init(void) { + reset_i2c_peripherals(); + pm_set_power_failure_state(); + fch_print_pmxc0_status(); + i2c_soc_early_init(); + show_spi_speeds_and_modes(); + + if (CONFIG(DISABLE_SPI_FLASH_ROM_SHARING)) + lpc_disable_spi_rom_sharing(); } diff --git a/src/soc/amd/turin_poc/fch.c b/src/soc/amd/turin_poc/fch.c index 46f97db8ea..a55abf2718 100644 --- a/src/soc/amd/turin_poc/fch.c +++ b/src/soc/amd/turin_poc/fch.c @@ -37,8 +37,23 @@ static const struct irq_idx_name irq_association[] = { { PIRQ_SCI, "SCI" }, { PIRQ_SMBUS, "SMBUS" }, { PIRQ_ASF, "ASF" }, + { PIRQ_HDA, "HDA" }, + { PIRQ_GBE0, "GBE0" }, + { PIRQ_GBE1, "GBE1" }, { PIRQ_PMON, "PerMon" }, + { PIRQ_SD, "SD" }, { PIRQ_SDIO, "SDIO" }, + { PIRQ_CIR, "CIR" }, + { PIRQ_GPIOA, "GPIOa" }, + { PIRQ_GPIOB, "GPIOb" }, + { PIRQ_GPIOC, "GPIOc" }, + { PIRQ_USB_EMU, "USB_EMU" }, + { PIRQ_USB_DR0, "USB_DR0" }, + { PIRQ_USB_DR1, "USB_DR1" }, + { PIRQ_XHCI0, "XHCI0" }, + { PIRQ_SSIC, "USB_SSIC" }, + { PIRQ_SATA, "SATA" }, + { PIRQ_UFS, "UFS" }, { PIRQ_GPP0, "GPP0" }, { PIRQ_GPP1, "GPP1" }, { PIRQ_GPP2, "GPP2" }, @@ -64,23 +79,62 @@ const struct irq_idx_name *sb_get_apic_reg_association(size_t *size) return irq_association; } -static void set_pci_irqs(void) +static void fch_init_acpi_ports(void) { - /* Write PCI_INTR regs 0xC00/0xC01 */ - write_pci_int_table(); + uint32_t reg32; + uint8_t reg8; + + if (CONFIG(HAVE_SMI_HANDLER)) { + /* Configure and enable APMC SMI Command Port */ + pm_write16(PM_ACPI_SMI_CMD, APM_CNT); + configure_smi(SMITYPE_SMI_CMD_PORT, SMI_MODE_SMI); - /* TODO: PIRQ configuration */ + /* SMI on SlpTyp requires sending SMI before completion + response of the I/O write. */ + reg32 = pm_read32(PM_PCI_CTRL); + reg32 |= FORCE_SLPSTATE_RETRY; + /* Ths bit should be cleared in case of SlpType SMI trapping */ + reg32 &= ~FORCE_STPCLK_RETRY; + pm_write32(PM_PCI_CTRL, reg32); + + /* Disable SlpTyp feature */ + reg8 = pm_read8(PM_RST_CTRL1); + reg8 &= ~SLPTYPE_CONTROL_EN; + pm_write8(PM_RST_CTRL1, reg8); + + configure_smi(SMITYPE_SLP_TYP, SMI_MODE_SMI); + } else { + pm_write16(PM_ACPI_SMI_CMD, 0); + } + + /* Decode ACPI registers and enable standard features */ + pm_write8(PM_ACPI_CONF, PM_ACPI_DECODE_STD | + PM_ACPI_GLOBAL_EN | + PM_ACPI_RTC_EN_EN | + PM_ACPI_TIMER_EN_EN); } -static void fch_init_acpi_ports(void) +static void fch_clk_output_48Mhz(void) { - /* Configure and enable APMC SMI Command Port */ - pm_write16(PM_ACPI_SMI_CMD, APM_CNT); - configure_smi(SMITYPE_SMI_CMD_PORT, SMI_MODE_SMI); + uint32_t ctrl = misc_read32(MISC_CLK_CNTL0); + /* Enable BP_X48M0 Clock Output */ + ctrl |= BP_X48M0_OUTPUT_EN; + misc_write32(MISC_CLK_CNTL0, ctrl); +} + +static void fch_pci_int_vw_mode(void) +{ + pm_write32(0xa8, 0x80ffcef8); } void fch_init(void *chip_info) { - set_pci_irqs(); fch_init_acpi_ports(); + fch_clk_output_48Mhz(); + + /* Write PCI_INTR regs 0xC00/0xC01 */ + write_pci_int_table(); + fch_pci_int_vw_mode(); + + fch_enable_ioapic_decode(); } diff --git a/src/soc/amd/turin_poc/gpio.c b/src/soc/amd/turin_poc/gpio.c index c38719bf3f..72d0b2b0a4 100644 --- a/src/soc/amd/turin_poc/gpio.c +++ b/src/soc/amd/turin_poc/gpio.c @@ -20,6 +20,7 @@ static const struct soc_amd_event gpio_event_table[] = { { GPIO_23, GEVENT_16 }, { GPIO_24, GEVENT_14 }, { GPIO_26, GEVENT_15 }, + { GPIO_28, GEVENT_18 }, { GPIO_76, GEVENT_11 }, { GPIO_86, GEVENT_9 }, { GPIO_89, GEVENT_0 }, diff --git a/src/soc/amd/turin_poc/include/soc/amd_pci_int_defs.h b/src/soc/amd/turin_poc/include/soc/amd_pci_int_defs.h index f093247735..82915109a7 100644 --- a/src/soc/amd/turin_poc/include/soc/amd_pci_int_defs.h +++ b/src/soc/amd/turin_poc/include/soc/amd_pci_int_defs.h @@ -28,11 +28,29 @@ #define PIRQ_SCI 0x10 /* SCI IRQ */ #define PIRQ_SMBUS 0x11 /* SMBUS0 */ #define PIRQ_ASF 0x12 /* ASF */ -/* 0x13-0x15 reserved */ +#define PIRQ_HDA 0x13 /* HDA */ +#define PIRQ_GBE0 0x14 /* GBE0 */ +#define PIRQ_GBE1 0x15 /* GBE1 */ #define PIRQ_PMON 0x16 /* Performance Monitor */ -/* 0x17-0x19 reserved */ +#define PIRQ_SD 0x17 /* SD */ +/* 0x18-0x19 reserved */ #define PIRQ_SDIO 0x1a /* SDIO */ -/* 0x1b-0x49 reserved */ +/* 0x1b-0x1f reserved */ +#define PIRQ_CIR 0x20 /* CIR */ +#define PIRQ_GPIOA 0x21 /* GPIOa */ +#define PIRQ_GPIOB 0x22 /* GPIOb */ +#define PIRQ_GPIOC 0x23 /* GPIOc */ +/* 0x24-0x2f reserved */ +#define PIRQ_USB_EMU 0x30 /* USB Emulation */ +#define PIRQ_USB_DR0 0x31 /* USB Dual Role 1 */ +#define PIRQ_USB_DR1 0x32 /* USB Dual Role 2 */ +/* 0x33 reserved */ +#define PIRQ_XHCI0 0x34 /* XHCI0 */ +#define PIRQ_SSIC 0x35 /* USB SSIC */ +/* 0x36-0x40 reserved */ +#define PIRQ_SATA 0x41 /* SATA */ +#define PIRQ_UFS 0x42 /* UFS */ +/* 0x43-0x4f reserved */ #define PIRQ_GPP0 0x50 /* GPPInt0 */ #define PIRQ_GPP1 0x51 /* GPPInt1 */ #define PIRQ_GPP2 0x52 /* GPPInt2 */ diff --git a/src/soc/amd/turin_poc/include/soc/aoac_defs.h b/src/soc/amd/turin_poc/include/soc/aoac_defs.h index 156ee34962..2ee168ca59 100644 --- a/src/soc/amd/turin_poc/include/soc/aoac_defs.h +++ b/src/soc/amd/turin_poc/include/soc/aoac_defs.h @@ -18,7 +18,13 @@ #define FCH_AOAC_DEV_I3C3 15 #define FCH_AOAC_DEV_UART2 16 #define FCH_AOAC_DEV_AMBA 17 +/* Bits 18-19 reserved */ +#define FCH_AOAC_DEV_UART4 20 #define FCH_AOAC_DEV_I3C0 21 -#define FCH_AOAC_DEV_ESPI 27 +#define FCH_AOAC_DEV_ESPI1 22 +/* Bits 23-25 reserved */ +#define FCH_AOAC_DEV_UART3 26 +#define FCH_AOAC_DEV_ESPI 27 /* RO */ +#define FCH_AOAC_DEV_CPU 31 #endif /* AMD_TURIN_POC_AOAC_DEFS_H */ diff --git a/src/soc/amd/turin_poc/include/soc/cpu.h b/src/soc/amd/turin_poc/include/soc/cpu.h index eada9233fa..618ecf81d6 100644 --- a/src/soc/amd/turin_poc/include/soc/cpu.h +++ b/src/soc/amd/turin_poc/include/soc/cpu.h @@ -3,7 +3,8 @@ #ifndef AMD_TURIN_POC_CPU_H #define AMD_TURIN_POC_CPU_H -#define TURIN_A0_CPUID CPUID_FROM_FMS(0x19, 0x10, 0) -#define TURIN_B0_CPUID CPUID_FROM_FMS(0x19, 0x11, 0) +#define TURIN_Ax_CPUID CPUID_FROM_FMS(0x1a, 0x0, 0) +#define TURIN_Bx_CPUID CPUID_FROM_FMS(0x1a, 0x1, 0) +#define TURIN_Cx_CPUID CPUID_FROM_FMS(0x1a, 0x2, 0) #endif /* AMD_TURIN_POC_CPU_H */ diff --git a/src/soc/amd/turin_poc/include/soc/data_fabric.h b/src/soc/amd/turin_poc/include/soc/data_fabric.h index 503dc39afb..590ada3660 100644 --- a/src/soc/amd/turin_poc/include/soc/data_fabric.h +++ b/src/soc/amd/turin_poc/include/soc/data_fabric.h @@ -23,7 +23,7 @@ union df_vga_en { #define DF_PCI_CFG_BASE0 DF_REG_ID(0, 0xc80) #define DF_PCI_CFG_LIMIT0 DF_REG_ID(0, 0xc84) -#define DF_PCI_CFG_MAP_COUNT 8 +#define DF_PCI_CFG_MAP_COUNT 16 #define DF_PCI_CFG_REG_OFFSET(instance) ((instance) * 2 * sizeof(uint32_t)) #define DF_PCI_CFG_BASE(reg) (DF_PCI_CFG_BASE0 + DF_PCI_CFG_REG_OFFSET(reg)) @@ -54,7 +54,7 @@ union df_pci_cfg_limit { #define DF_IO_BASE0 DF_REG_ID(0, 0xd00) #define DF_IO_LIMIT0 DF_REG_ID(0, 0xd04) -#define DF_IO_REG_COUNT 8 +#define DF_IO_REG_COUNT 16 #define DF_IO_REG_OFFSET(instance) ((instance) * 2 * sizeof(uint32_t)) #define DF_IO_BASE(reg) (DF_IO_BASE0 + DF_IO_REG_OFFSET(reg)) @@ -93,13 +93,13 @@ union df_io_limit { #define DF_MMIO_EXT_ADDR_SHIFT 48 #define DF_MMIO_REG_SET_SIZE 4 -#define DF_MMIO_REG_SET_COUNT 16 +#define DF_MMIO_REG_SET_COUNT 32 union df_mmio_control { struct { uint32_t re : 1; /* [ 0.. 0] */ uint32_t we : 1; /* [ 1.. 1] */ - uint32_t : 1; /* [ 2.. 2] */ + uint32_t cpu_dis : 1; /* [ 2.. 2] */ uint32_t np : 1; /* [ 3.. 3] */ uint32_t : 12; /* [ 4..15] */ uint32_t dst_fabric_id : 12; /* [16..27] */ @@ -124,13 +124,13 @@ union df_mmio_addr_ext { union df_ficaa { struct { - uint32_t cfg_inst_acc_en : 1; /* [ 0.. 0] */ - uint32_t reg_num : 10; /* [10.. 1] */ - uint32_t func_num : 3; /* [13..11] */ - uint32_t b64_en : 1; /* [14..14] */ - uint32_t : 1; /* [15..15] */ - uint32_t inst_id : 8; /* [23..16] */ - uint32_t : 8; /* [31..24] */ + uint32_t cfg_inst_acc_en : 1; /* [ 0.. 0] */ + uint32_t reg_num : 10; /* [10.. 1] */ + uint32_t func_num : 3; /* [13..11] */ + uint32_t b64_en : 1; /* [14..14] */ + uint32_t : 1; /* [15..15] */ + uint32_t inst_id : 9; /* [24..16] */ + uint32_t : 7; /* [31..25] */ }; uint32_t raw; }; diff --git a/src/soc/amd/turin_poc/include/soc/gpio.h b/src/soc/amd/turin_poc/include/soc/gpio.h index 613fea7f25..d2890aa50b 100644 --- a/src/soc/amd/turin_poc/include/soc/gpio.h +++ b/src/soc/amd/turin_poc/include/soc/gpio.h @@ -25,7 +25,6 @@ #define GPIO_4 4 #define GPIO_5 5 #define GPIO_6 6 -#define GPIO_7 7 #define GPIO_12 12 #define GPIO_13 13 #define GPIO_14 14 @@ -38,15 +37,29 @@ #define GPIO_23 23 #define GPIO_24 24 #define GPIO_26 26 +#define GPIO_27 27 +#define GPIO_28 28 +#define GPIO_29 29 +#define GPIO_30 30 +#define GPIO_31 31 +#define GPIO_32 32 +#define GPIO_40 40 +#define GPIO_42 42 +#define GPIO_70 70 /* Bank 1: GPIO_64 - GPIO_127 */ #define GPIO_74 74 #define GPIO_75 75 #define GPIO_76 76 +#define GPIO_84 84 +#define GPIO_85 85 #define GPIO_86 86 #define GPIO_87 87 #define GPIO_88 88 #define GPIO_89 89 +#define GPIO_90 90 +#define GPIO_91 91 +#define GPIO_92 92 #define GPIO_104 104 #define GPIO_105 105 #define GPIO_106 106 @@ -54,6 +67,8 @@ #define GPIO_108 108 #define GPIO_109 109 #define GPIO_110 110 +#define GPIO_113 113 +#define GPIO_114 114 #define GPIO_115 115 #define GPIO_116 116 #define GPIO_117 117 @@ -69,6 +84,7 @@ /* Bank 2: GPIO_128 - GPIO_191 */ #define GPIO_129 129 +#define GPIO_130 130 #define GPIO_131 131 #define GPIO_132 132 #define GPIO_133 133 @@ -78,8 +94,11 @@ #define GPIO_137 137 #define GPIO_138 138 #define GPIO_139 139 +#define GPIO_140 140 #define GPIO_141 141 #define GPIO_142 142 +#define GPIO_143 143 +#define GPIO_144 144 #define GPIO_145 145 #define GPIO_146 146 #define GPIO_147 147 @@ -96,16 +115,13 @@ #define GPIO_259 259 #define GPIO_260 260 #define GPIO_261 261 -#define GPIO_262 262 -#define GPIO_263 263 #define GPIO_264 264 #define GPIO_265 265 #define GPIO_266 266 /* IOMUX function names and values */ #define GPIO_0_IOMUX_PWR_BTN_L 0 -#define GPIO_0_IOMUX_GPIO_PU1PD0 1 -#define GPIO_0_IOMUX_GPIOxx 2 +#define GPIO_0_IOMUX_GPIOxx 1 #define GPIO_1_IOMUX_SYS_RESET_L 0 #define GPIO_1_IOMUX_GPIOxx 1 #define GPIO_2_IOMUX_WAKE_L 0 @@ -121,12 +137,10 @@ #define GPIO_12_IOMUX_PWRGD_OUT 0 #define GPIO_12_IOMUX_GPIOxx 1 #define GPIO_13_IOMUX_I2C4_SCL 0 -#define GPIO_13_IOMUX_CLK_48_24_0 1 -#define GPIO_13_IOMUX_GPIOxx 2 +#define GPIO_13_IOMUX_GPIOxx 1 #define GPIO_14_IOMUX_I2C4_SDA 0 -#define GPIO_14_IOMUX_S0A3 1 -#define GPIO_14_IOMUX_GPIOxx 2 -#define GPIO_16_IOMUX_USB_1O_OC_L 0 +#define GPIO_14_IOMUX_GPIOxx 1 +#define GPIO_16_IOMUX_USB10_OC_L 0 #define GPIO_16_IOMUX_GPIOxx 1 #define GPIO_17_IOMUX_USB11_OC_L 0 #define GPIO_17_IOMUX_GPIOxx 1 @@ -136,35 +150,52 @@ #define GPIO_20_IOMUX_I2C5_SDA 0 #define GPIO_20_IOMUX_SMBUS1_SDA 1 #define GPIO_20_IOMUX_GPIOxx 2 -#define GPIO_21_IOMUX_GPIOxx 0 -#define GPIO_22_IOMUX_GPIOxx 0 +#define GPIO_21_IOMUX_GPIOxx 2 +#define GPIO_22_IOMUX_GPIOxx 2 #define GPIO_23_IOMUX_ESPI_RST_OUT_L 0 #define GPIO_23_IOMUX_GPIOxx 1 #define GPIO_24_IOMUX_SMERR_L 0 #define GPIO_24_IOMUX_GPIOxx 1 #define GPIO_26_IOMUX_PCIE_RST1_L 0 #define GPIO_26_IOMUX_GPIOxx 1 +#define GPIO_27_IOMUX_GPIOxx 1 +#define GPIO_28_IOMUX_X48M_OUT 0 +#define GPIO_29_IOMUX_GPIOxx 0 +#define GPIO_30_IOMUX_GPIOxx 0 +#define GPIO_31_IOMUX_GPIOxx 0 +#define GPIO_32_IOMUX_GPIOxx 0 +#define GPIO_40_IOMUX_GPIOxx 0 +#define GPIO_42_IOMUX_GPIOxx 0 +#define GPIO_70_IOMUX_GPIOxx 0 #define GPIO_74_IOMUX_ESPI_CLK2 0 -#define GPIO_74_IOMUX_GPIOxx 1 +#define GPIO_74_IOMUX_GPIOxx 2 #define GPIO_75_IOMUX_ESPI_CLK1 0 -#define GPIO_75_IOMUX_GPIOxx 1 +#define GPIO_75_IOMUX_GPIOxx 2 #define GPIO_76_IOMUX_GPIOxx 0 #define GPIO_76_IOMUX_SPI_TPM_CS_L 1 -#define GPIO_86_IOMUX_NMI_SYNC_FLOOD_L 0 -#define GPIO_87_IOMUX_GPIOxx 0 -#define GPIO_88_IOMUX_GPIOxx 0 +#define GPIO_84_IOMUX_GPIOxx 1 +#define GPIO_85_IOMUX_GPIOxx 1 +#define GPIO_86_IOMUX_GPIOxx 1 +#define GPIO_86_IOMUX_LPC_SMI_L 2 +#define GPIO_87_IOMUX_GPIOxx 2 +#define GPIO_88_IOMUX_GPIOxx 2 #define GPIO_89_IOMUX_GENINT_L 0 #define GPIO_89_IOMUX_PM_INTR_L 1 #define GPIO_89_IOMUX_GPIOxx 2 -#define GPIO_104_IOMUX_GPIOxx 0 -#define GPIO_105_IOMUX_GPIOxx 0 -#define GPIO_106_IOMUX_GPIOxx 0 -#define GPIO_107_IOMUX_GPIOxx 0 +#define GPIO_90_IOMUX_GPIOxx 2 +#define GPIO_91_IOMUX_GPIOxx 1 +#define GPIO_92_IOMUX_GPIOxx 3 +#define GPIO_104_IOMUX_GPIOxx 3 +#define GPIO_105_IOMUX_GPIOxx 3 +#define GPIO_106_IOMUX_GPIOxx 3 +#define GPIO_107_IOMUX_GPIOxx 3 #define GPIO_108_IOMUX_ESPI0_ALERT_D1 0 -#define GPIO_108_IOMUX_GPIOxx 1 -#define GPIO_109_IOMUX_GPIOxx 0 +#define GPIO_108_IOMUX_GPIOxx 2 +#define GPIO_109_IOMUX_GPIOxx 2 #define GPIO_110_IOMUX_ESPI1_ALERT_D1 0 #define GPIO_110_IOMUX_GPIOxx 1 +#define GPIO_113_IOMUX_GPIOxx 2 +#define GPIO_114_IOMUX_GPIOxx 2 #define GPIO_115_IOMUX_GPIOxx 0 #define GPIO_115_IOMUX_CLK_REQ11_L 1 #define GPIO_116_IOMUX_GPIOxx 0 @@ -174,7 +205,7 @@ #define GPIO_118_IOMUX_SPI_CS0_L 0 #define GPIO_118_IOMUX_GPIOxx 1 #define GPIO_119_IOMUX_SPI_CS1_L 0 -#define GPIO_119_IOMUX_GPIOxx 1 +#define GPIO_119_IOMUX_GPIOxx 2 #define GPIO_120_IOMUX_ESPI0_DATA0 0 #define GPIO_120_IOMUX_GPIOxx 1 #define GPIO_121_IOMUX_ESPI0_DATA1 0 @@ -192,8 +223,9 @@ #define GPIO_129_IOMUX_ESPI_RSTIN_L 0 #define GPIO_129_IOMUX_KBRST_L 1 #define GPIO_129_IOMUX_GPIOxx 2 +#define GPIO_130_IOMUX_GPIOxx 1 #define GPIO_131_IOMUX_ESPI1_DATA0 0 -#define GPIO_131_IOMUX_GPIOxx 1 +#define GPIO_131_IOMUX_GPIOxx 3 #define GPIO_132_IOMUX_ESPI1_DATA1 0 #define GPIO_132_IOMUX_GPIOxx 1 #define GPIO_133_IOMUX_ESPI1_DATA2 0 @@ -212,10 +244,15 @@ #define GPIO_138_IOMUX_GPIOxx 1 #define GPIO_139_IOMUX_UART0_INTR 0 #define GPIO_139_IOMUX_GPIOxx 1 +#define GPIO_140_IOMUX_UART3_RXD 0 +#define GPIO_140_IOMUX_GPIOxx 2 #define GPIO_141_IOMUX_UART1_RXD 0 #define GPIO_141_IOMUX_GPIOxx 1 #define GPIO_142_IOMUX_UART1_TXD 0 -#define GPIO_142_IOMUX_GPIOxx 1 +#define GPIO_142_IOMUX_UART3_TXD 1 +#define GPIO_142_IOMUX_GPIOxx 2 +#define GPIO_143_IOMUX_GPIOxx 1 +#define GPIO_144_IOMUX_GPIOxx 1 #define GPIO_145_IOMUX_I3C0_SCL_SPD0_SCL 0 #define GPIO_145_IOMUX_I2C0_SCL_SPD0_SCL 1 #define GPIO_145_IOMUX_SMBUS0_SCL 2 @@ -258,8 +295,6 @@ #define GPIO_260_IOMUX_GPIOxx 1 #define GPIO_261_IOMUX_SGPIO_LOAD 0 #define GPIO_261_IOMUX_GPIOxx 1 -#define GPIO_262_IOMUX_GPIOxx 0 -#define GPIO_263_IOMUX_GPIOxx 0 #define GPIO_264_IOMUX_USB00_OC_L 0 #define GPIO_264_IOMUX_GPIOxx 1 #define GPIO_265_IOMUX_USB01_OC_L 0 diff --git a/src/soc/amd/turin_poc/include/soc/iomap.h b/src/soc/amd/turin_poc/include/soc/iomap.h index f1d692121f..d85597e051 100644 --- a/src/soc/amd/turin_poc/include/soc/iomap.h +++ b/src/soc/amd/turin_poc/include/soc/iomap.h @@ -8,17 +8,20 @@ #define I2C_CTRLR_COUNT (I2C_MASTER_DEV_COUNT + I2C_PERIPHERAL_DEV_COUNT) #define I3C_CTRLR_COUNT 4 -#define SPI_BASE_ADDRESS 0xfec10000 +#define ACPIMMIO_RGPIO_BASE 0xfed81200 -/* @Todo : Check these values for Turin */ +#define SPI_BASE_ADDRESS 0xfec10000 -/* I/O Ranges */ -#define ACPI_IO_BASE 0x0400 -#define ACPI_CSTATE_CONTROL (ACPI_IO_BASE + 0x10) +#define FCH_WATCHDOG_BASE 0xfeb00000 /* FCH AL2AHB Registers */ #define ALINK_AHB_ADDRESS 0xfedc0000 +#define APU_DMA0_BASE 0xfedc7000 +#define APU_DMA1_BASE 0xfedc8000 +#define APU_DMA2_BASE 0xfedcc000 +#define APU_DMA3_BASE 0xfedcd000 + #define APU_I2C0_BASE 0xfedc2000 #define APU_I2C1_BASE 0xfedc3000 #define APU_I2C2_BASE 0xfedc4000 @@ -29,10 +32,25 @@ #define APU_UART0_BASE 0xfedc9000 #define APU_UART1_BASE 0xfedca000 #define APU_UART2_BASE 0xfedce000 +#define APU_UART3_BASE 0xfedcf000 +#define APU_UART4_BASE 0xfedd1000 #define APU_I3C0_BASE 0xfedd2000 #define APU_I3C1_BASE 0xfedd3000 #define APU_I3C2_BASE 0xfedd4000 #define APU_I3C3_BASE 0xfedd6000 +/* I/O Ranges */ +#define ACPI_IO_BASE 0x0400 +#define ACPI_PM_EVT_BLK (ACPI_IO_BASE + 0x00) +#define ACPI_PM1_STS (ACPI_PM_EVT_BLK + 0x00) +#define ACPI_PM1_EN (ACPI_PM_EVT_BLK + 0x02) +#define ACPI_PM1_CNT_BLK (ACPI_IO_BASE + 0x04) +#define ACPI_PM_TMR_BLK (ACPI_IO_BASE + 0x08) +#define ACPI_CSTATE_CONTROL (ACPI_IO_BASE + 0x10) +#define ACPI_GPE0_BLK (ACPI_IO_BASE + 0x20) +#define ACPI_GPE0_STS (ACPI_GPE0_BLK + 0x00) +#define ACPI_GPE0_EN (ACPI_GPE0_BLK + 0x04) +#define SMB_BASE_ADDR 0x0b00 + #endif /* AMD_TURIN_POC_IOMAP_H */ diff --git a/src/soc/amd/turin_poc/include/soc/msr.h b/src/soc/amd/turin_poc/include/soc/msr.h index ba2c25f997..a1773b2269 100644 --- a/src/soc/amd/turin_poc/include/soc/msr.h +++ b/src/soc/amd/turin_poc/include/soc/msr.h @@ -8,8 +8,8 @@ /* MSRC001_00[6B:64] P-state [7:0] bit definitions */ union pstate_msr { struct { - uint64_t cpu_fid_0_7 : 8; /* [ 0.. 7] */ - uint64_t cpu_dfs_id : 6; /* [ 8..13] */ + uint64_t cpu_fid_0_11 : 12; /* [ 0..11] */ + uint64_t : 2; /* [12..13] */ uint64_t cpu_vid_0_7 : 8; /* [14..21] */ uint64_t idd_value : 8; /* [22..29] */ uint64_t idd_div : 2; /* [30..31] */ diff --git a/src/soc/amd/turin_poc/include/soc/smi.h b/src/soc/amd/turin_poc/include/soc/smi.h index df56b6750f..7712860531 100644 --- a/src/soc/amd/turin_poc/include/soc/smi.h +++ b/src/soc/amd/turin_poc/include/soc/smi.h @@ -78,7 +78,8 @@ /* 31 Reserved */ #define SMITYPE_WAKE_L2 32 #define SMITYPE_PSP 33 -/* 34-35 Reserved */ +#define SMITYPE_PSP2 34 +#define SMITYPE_PSP3 35 #define SMITYPE_ESPI_SCI_B 36 #define SMITYPE_ESPI1_SYS_EVT_B 37 #define SMITYPE_ESPI1_WAKE_PME 38 diff --git a/src/soc/amd/turin_poc/include/soc/smu.h b/src/soc/amd/turin_poc/include/soc/smu.h index dd34044264..e18fc8e3b0 100644 --- a/src/soc/amd/turin_poc/include/soc/smu.h +++ b/src/soc/amd/turin_poc/include/soc/smu.h @@ -1,11 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef AMD_GENOA_POC_SMU_H -#define AMD_GENOA_POC_SMU_H +#ifndef AMD_TURIN_POC_SMU_H +#define AMD_TURIN_POC_SMU_H /* SMU mailbox register offsets in SMN */ -#define SMN_SMU_MESG_ID 0x3b10530 -#define SMN_SMU_MESG_RESP 0x3b1057c +#define SMN_SMU_MESG_ID 0x3b10930 +#define SMN_SMU_MESG_RESP 0x3b1097c #define SMN_SMU_MESG_ARGS_BASE 0x3b109c4 #define SMU_NUM_ARGS 6 @@ -20,4 +20,4 @@ enum smu_message_id { */ void smu_sx_entry(void); -#endif /* AMD_GENOA_POC_SMU_H */ +#endif /* AMD_TURIN_POC_SMU_H */ diff --git a/src/soc/amd/turin_poc/include/soc/southbridge.h b/src/soc/amd/turin_poc/include/soc/southbridge.h index 1027a58455..8447b32be7 100644 --- a/src/soc/amd/turin_poc/include/soc/southbridge.h +++ b/src/soc/amd/turin_poc/include/soc/southbridge.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef AMD_GENOA_POC_SOUTHBRIDGE_H -#define AMD_GENOA_POC_SOUTHBRIDGE_H +#ifndef AMD_TURIN_POC_SOUTHBRIDGE_H +#define AMD_TURIN_POC_SOUTHBRIDGE_H #include @@ -9,6 +9,7 @@ #define PM_ISACONTROL 0x04 #define ABCLKGATEEN BIT(16) #define PM_PCI_CTRL 0x08 +#define FORCE_STPCLK_RETRY BIT(24) #define FORCE_SLPSTATE_RETRY BIT(25) #define PWR_RESET_CFG 0x10 #define TOGGLE_ALL_PWR_GOOD (1 << 1) @@ -72,8 +73,6 @@ #define PM_ACPI_RTC_WAKE_EN BIT(29) #define PM_ACPI_USE_GATED_ALINK_CLK BIT(30) #define PM_ACPI_DELAY_GPP_OFF_TIME BIT(31) -#define PM_SPI_PAD_PU_PD 0x90 -#define PM_ESPI_CS_USE_DATA2 BIT(16) #define PM_LPC_GATING 0xec #define PM_LPC_AB_NO_BYPASS_EN BIT(2) #define PM_LPC_A20_EN BIT(1) @@ -119,4 +118,4 @@ void fch_pre_init(void); void fch_early_init(void); void fch_init(void *chip_info); -#endif /* AMD_GENOA_POC_SOUTHBRIDGE_H */ +#endif /* AMD_TURIN_POC_SOUTHBRIDGE_H */ diff --git a/src/soc/amd/turin_poc/include/soc/xhci.h b/src/soc/amd/turin_poc/include/soc/xhci.h new file mode 100644 index 0000000000..4645a629d2 --- /dev/null +++ b/src/soc/amd/turin_poc/include/soc/xhci.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef AMD_TURIN_XHCI_H +#define AMD_TURIN_XHCI_H + +#include + +#define SOC_XHCI_0 DEV_PTR(xhci_0) +#define SOC_XHCI_1 DEV_PTR(xhci_1) +#define SOC_XHCI_2 NULL +#define SOC_XHCI_3 NULL +#define SOC_XHCI_4 NULL +#define SOC_XHCI_5 NULL +#define SOC_XHCI_6 NULL +#define SOC_XHCI_7 NULL + +#endif /* AMD_TURIN_XHCI_H */ diff --git a/src/soc/amd/turin_poc/mca.c b/src/soc/amd/turin_poc/mca.c index 9a6df2b53e..460d9afee2 100644 --- a/src/soc/amd/turin_poc/mca.c +++ b/src/soc/amd/turin_poc/mca.c @@ -4,7 +4,11 @@ #include #include -/* TODO: Check if non-core MCA banks are same for all cores */ +/* + * Non-core MCA banks are not the same for all cores. + * Refer to "Table 56: Non-core MCA Bank to Block Mapping" + * in Turin C1 PPR (doc 57238). + */ static const char *const mca_bank_name[] = { [0] = "Load-store unit", [1] = "Instruction fetch unit", @@ -22,22 +26,22 @@ static const char *const mca_bank_name[] = { [13] = "L3 cache unit", [14] = "L3 cache unit", [15] = "Microprocessor5 Management Controller", - [16] = "Parameter Block", - [17] = "GMI Controller", - [18] = "GMI Controller", - [19] = "High Speed Interface Unit (GMI)", - [20] = "High Speed Interface Unit (GMI)", + [16] = "GMI Controller (PCS_GMI)", + [17] = "GMI Controller (PCS_GMI)", + [18] = "High Speed Interface Unit (KPX_GMI)", + [19] = "High Speed Interface Unit (KPX_GMI)", + [20] = "MPDMA", [21] = "Unified Memory Controller", [22] = "Unified Memory Controller", [23] = "Coherent Station", [24] = "Coherent Station", - [25] = "Northbridge IO Unit", - [26] = "PCIe Root Port", - [27] = "PCIe Root Port", - [28] = "Power Management, Interrupts, Etc.", + [25] = "PCIE", + [26] = "SATA", + [27] = "Northbridge IO Unit", + [28] = "NBIF", [29] = "SMU", - [30] = "XGMI Controller", - [31] = "High Speed Interface Unit (XGMI)", + [30] = "Power Management, Interrupts, Etc.", + [31] = "High Speed Interface Unit (SERDES)", }; bool mca_has_expected_bank_count(void) diff --git a/src/soc/amd/turin_poc/root_complex.c b/src/soc/amd/turin_poc/root_complex.c index 3171febe9f..ffff6d1c32 100644 --- a/src/soc/amd/turin_poc/root_complex.c +++ b/src/soc/amd/turin_poc/root_complex.c @@ -2,24 +2,52 @@ #include #include +#include +#include #include +/* + * The order of IOHCs here is not random. They are sorted so that: + * 1. The First IOHC is the one with primary FCH. We want the LPC/SMBUS + * devices be on bus 0. + * 2. The rest of IOHCs are listed in an order so that ECAM MMIO region is one + * continuous block for all domains. + * + * AGESA/OpenSIL sets up the PCI configuration decoding ranges in line with + * this. + */ static const struct domain_iohc_info iohc_info[] = { [0] = { - .fabric_id = 0x22, - .misc_smn_base = SMN_IOHC_MISC_BASE_13C1, + .fabric_id = 0x24, + .misc_smn_base = SMN_IOHC_MISC_BASE_13D1, }, [1] = { - .fabric_id = 0x23, - .misc_smn_base = SMN_IOHC_MISC_BASE_13B1, + .fabric_id = 0x25, + .misc_smn_base = SMN_IOHC_MISC_BASE_1D61, }, [2] = { - .fabric_id = 0x21, + .fabric_id = 0x26, .misc_smn_base = SMN_IOHC_MISC_BASE_13E1, }, [3] = { + .fabric_id = 0x27, + .misc_smn_base = SMN_IOHC_MISC_BASE_1D51, + }, + [4] = { + .fabric_id = 0x23, + .misc_smn_base = SMN_IOHC_MISC_BASE_1D41, + }, + [5] = { + .fabric_id = 0x22, + .misc_smn_base = SMN_IOHC_MISC_BASE_13C1, + }, + [6] = { + .fabric_id = 0x21, + .misc_smn_base = SMN_IOHC_MISC_BASE_1D71, + }, + [7] = { .fabric_id = 0x20, - .misc_smn_base = SMN_IOHC_MISC_BASE_13D1, + .misc_smn_base = SMN_IOHC_MISC_BASE_13B1, }, }; @@ -33,15 +61,18 @@ static const struct non_pci_mmio_reg non_pci_mmio[] = { { 0x2d8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, { 0x2e0, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, { 0x2e8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, - /* The hardware has a 256 byte alignment requirement for the IOAPIC MMIO base, but we - tell the FSP to configure a 4k-aligned base address and this is reported as 4 KiB - resource. */ - { 0x2f0, 0xffffffffff00ull, 4 * KiB, IOMMU_IOAPIC_IDX }, + /* + * The hardware has a 256 byte alignment requirement for the IOAPIC + * MMIO base, but OpenSIL configures 64k-aligned base address and this + * is reported as 256 byte resource. + */ + { 0x2f0, 0xffffffffff00ull, 256, IOMMU_IOAPIC_IDX }, { 0x2f8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, { 0x300, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, { 0x308, 0xfffffffff000ull, 4 * KiB, NON_PCI_RES_IDX_AUTO }, { 0x310, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, { 0x318, 0xfffffff80000ull, 512 * KiB, NON_PCI_RES_IDX_AUTO }, + { 0x338, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, }; const struct non_pci_mmio_reg *get_iohc_non_pci_mmio_regs(size_t *count) @@ -49,3 +80,17 @@ const struct non_pci_mmio_reg *get_iohc_non_pci_mmio_regs(size_t *count) *count = ARRAY_SIZE(non_pci_mmio); return non_pci_mmio; } + +static const char *gnb_acpi_name(const struct device *dev) +{ + return "GNB"; +} + +struct device_operations turin_root_complex_operations = { + /* The root complex has no PCI BARs implemented, so there's no need to call + pci_dev_read_resources for it */ + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, + .enable_resources = pci_dev_enable_resources, + .acpi_name = gnb_acpi_name, +}; diff --git a/src/soc/amd/turin_poc/smihandler.c b/src/soc/amd/turin_poc/smihandler.c index 1eb051317b..80185a843d 100644 --- a/src/soc/amd/turin_poc/smihandler.c +++ b/src/soc/amd/turin_poc/smihandler.c @@ -61,6 +61,7 @@ static void fch_slp_typ_handler(void) /* Do not send SMI before AcpiPm1CntBlkx00[SlpTyp] */ pci_ctrl = pm_read32(PM_PCI_CTRL); pci_ctrl &= ~FORCE_SLPSTATE_RETRY; + pci_ctrl |= FORCE_STPCLK_RETRY; pm_write32(PM_PCI_CTRL, pci_ctrl); /* Enable SlpTyp */ diff --git a/src/soc/amd/turin_poc/uart.c b/src/soc/amd/turin_poc/uart.c index 19f7746bc8..c90485318f 100644 --- a/src/soc/amd/turin_poc/uart.c +++ b/src/soc/amd/turin_poc/uart.c @@ -24,6 +24,10 @@ static const struct soc_uart_ctrlr_info uart_info[] = { PAD_NF(GPIO_137, UART2_RXD, PULL_NONE), PAD_NF(GPIO_135, UART2_TXD, PULL_NONE), } }, + [3] = { APU_UART2_BASE, FCH_AOAC_DEV_UART3, "FUR3", { + PAD_NF(GPIO_140, UART3_RXD, PULL_NONE), + PAD_NF(GPIO_142, UART3_TXD, PULL_NONE), + } }, }; const struct soc_uart_ctrlr_info *soc_get_uart_ctrlr_info(size_t *num_ctrlrs) From cb25e6cb72df99f7bbe7a65a0287b09ab1bdbbb6 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Fri, 28 Nov 2025 21:50:52 +0100 Subject: [PATCH 248/789] mb/amd/birman_plus: Increase flash size to 64M Update it as per schematics. Since the commit wasn't actually tested with the phoenix SOC, keep the BIOS region in the first 16M. Signed-off-by: Maximilian Brune Change-Id: I6138d37be1b56178ce989996109157671f6973b1 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90265 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/mainboard/amd/birman_plus/board_phoenix.fmd | 4 ++-- src/mainboard/amd/birman_plus/chromeos_glinda.fmd | 4 ++-- src/mainboard/amd/birman_plus/chromeos_phoenix.fmd | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mainboard/amd/birman_plus/board_phoenix.fmd b/src/mainboard/amd/birman_plus/board_phoenix.fmd index 4f5598cd77..1335409418 100644 --- a/src/mainboard/amd/birman_plus/board_phoenix.fmd +++ b/src/mainboard/amd/birman_plus/board_phoenix.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - BIOS { +FLASH 64M { + BIOS 16M { EC_SIG 4K FMAP 4K COREBOOT(CBFS) diff --git a/src/mainboard/amd/birman_plus/chromeos_glinda.fmd b/src/mainboard/amd/birman_plus/chromeos_glinda.fmd index 9cc4fbd050..de5bcc788f 100644 --- a/src/mainboard/amd/birman_plus/chromeos_glinda.fmd +++ b/src/mainboard/amd/birman_plus/chromeos_glinda.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - SI_BIOS { +FLASH 64M { + SI_BIOS 16M { WP_RO 8M { EC_SIG 4K RO_VPD(PRESERVE) 16K diff --git a/src/mainboard/amd/birman_plus/chromeos_phoenix.fmd b/src/mainboard/amd/birman_plus/chromeos_phoenix.fmd index 9cc4fbd050..de5bcc788f 100644 --- a/src/mainboard/amd/birman_plus/chromeos_phoenix.fmd +++ b/src/mainboard/amd/birman_plus/chromeos_phoenix.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - SI_BIOS { +FLASH 64M { + SI_BIOS 16M { WP_RO 8M { EC_SIG 4K RO_VPD(PRESERVE) 16K From f65f674343a2ef16501f0a40218f94082fa49e86 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Fri, 28 Nov 2025 21:51:50 +0100 Subject: [PATCH 249/789] mb/amd/birman: Increase flash size to 32M Update as per schematics. Since the commit wasn't actually tested on the mainboard, keep the BIOS region in the first 16M. Signed-off-by: Maximilian Brune Change-Id: I6d3cdbec82539007c6a0923c1f1415882dd9f2c1 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90266 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/mainboard/amd/birman/board_glinda.fmd | 4 ++-- src/mainboard/amd/birman/board_phoenix.fmd | 4 ++-- src/mainboard/amd/birman/chromeos_glinda.fmd | 4 ++-- src/mainboard/amd/birman/chromeos_phoenix.fmd | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mainboard/amd/birman/board_glinda.fmd b/src/mainboard/amd/birman/board_glinda.fmd index 4f5598cd77..01340430cd 100644 --- a/src/mainboard/amd/birman/board_glinda.fmd +++ b/src/mainboard/amd/birman/board_glinda.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - BIOS { +FLASH 32M { + BIOS 16M { EC_SIG 4K FMAP 4K COREBOOT(CBFS) diff --git a/src/mainboard/amd/birman/board_phoenix.fmd b/src/mainboard/amd/birman/board_phoenix.fmd index 4f5598cd77..01340430cd 100644 --- a/src/mainboard/amd/birman/board_phoenix.fmd +++ b/src/mainboard/amd/birman/board_phoenix.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - BIOS { +FLASH 32M { + BIOS 16M { EC_SIG 4K FMAP 4K COREBOOT(CBFS) diff --git a/src/mainboard/amd/birman/chromeos_glinda.fmd b/src/mainboard/amd/birman/chromeos_glinda.fmd index 9cc4fbd050..bf10c06c3b 100644 --- a/src/mainboard/amd/birman/chromeos_glinda.fmd +++ b/src/mainboard/amd/birman/chromeos_glinda.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - SI_BIOS { +FLASH 32M { + SI_BIOS 16M { WP_RO 8M { EC_SIG 4K RO_VPD(PRESERVE) 16K diff --git a/src/mainboard/amd/birman/chromeos_phoenix.fmd b/src/mainboard/amd/birman/chromeos_phoenix.fmd index 9cc4fbd050..bf10c06c3b 100644 --- a/src/mainboard/amd/birman/chromeos_phoenix.fmd +++ b/src/mainboard/amd/birman/chromeos_phoenix.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - SI_BIOS { +FLASH 32M { + SI_BIOS 16M { WP_RO 8M { EC_SIG 4K RO_VPD(PRESERVE) 16K From f97a933140fc30a1bad53396beb9bd3b6d4fb72c Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Fri, 28 Nov 2025 21:52:27 +0100 Subject: [PATCH 250/789] mb/amd/crater/Kconfig: Decrease flash size to 16M Update because the board by default has 16M flash. TEST=build and run on the crater mainboard Signed-off-by: Maximilian Brune Change-Id: I7ecb7721c523d8995e124b61715afac2090b3235 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90267 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/mainboard/amd/crater/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/amd/crater/Kconfig b/src/mainboard/amd/crater/Kconfig index b2fc3d63e0..0861a216f7 100644 --- a/src/mainboard/amd/crater/Kconfig +++ b/src/mainboard/amd/crater/Kconfig @@ -2,7 +2,7 @@ config BOARD_AMD_CRATER_COMMON def_bool n - select BOARD_ROMSIZE_KB_32768 + select BOARD_ROMSIZE_KB_16384 select EC_ACPI select SOC_AMD_COMMON_BLOCK_USE_ESPI if !SOC_AMD_COMMON_BLOCK_SIMNOW_BUILD select DRIVERS_PCIE_RTD3_DEVICE From 4cc705e56d474fb79db0403b5bf8c4135ba50ef2 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Fri, 28 Nov 2025 21:52:58 +0100 Subject: [PATCH 251/789] mb/amd/mayan: Increase flash size to 32M Update as per schematics. Since the commit wasn't actually tested on the mainboard, keep the BIOS region in the first 16M. Signed-off-by: Maximilian Brune Change-Id: I0f1ae9d410804380d5465dcae35cc5965515506f Reviewed-on: https://review.coreboot.org/c/coreboot/+/90268 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/mainboard/amd/mayan/board.fmd | 4 ++-- src/mainboard/amd/mayan/chromeos.fmd | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mainboard/amd/mayan/board.fmd b/src/mainboard/amd/mayan/board.fmd index 2600ec75a2..6ba6b4d68f 100644 --- a/src/mainboard/amd/mayan/board.fmd +++ b/src/mainboard/amd/mayan/board.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - BIOS { +FLASH 32M { + BIOS 16M { EC 4K FMAP 4K COREBOOT(CBFS) diff --git a/src/mainboard/amd/mayan/chromeos.fmd b/src/mainboard/amd/mayan/chromeos.fmd index b77203f589..b819c9c3cc 100644 --- a/src/mainboard/amd/mayan/chromeos.fmd +++ b/src/mainboard/amd/mayan/chromeos.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - SI_BIOS { +FLASH 32M { + SI_BIOS 16M { WP_RO 8M { EC 4K RO_VPD(PRESERVE) 16K From f8a32a1cfa4aaa01a1b75b17f6e47d6ae3055d26 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Tue, 20 Jan 2026 18:23:35 +0100 Subject: [PATCH 252/789] include/fmap.h: Require FMAP_FLASH_SIZE == CONFIG_ROM_SIZE In our current tree this is always the case. The coreboot code (as far as I know) doesn't have a hard requirement on that. But if these values differ then it is usually always a mistake made by the programmer and it is hard to catch since the value don't really depend on each other. So until a time in which there comes a platform which needs a flashmap that doesn't cover the whole flash, this check is introduced. For that purpose we need to replace the default .config file for tests, because otherwise the check won't match. The config file that is used now is based on the fact that we use the same mainboard for the `.config` as for the `fmap_config.h` in `tests/include/tests/lib/fmap/fmap_config.h` Signed-off-by: Maximilian Brune Change-Id: I8bc05a17a2630516ede949660b4fc428f199f3ab Reviewed-on: https://review.coreboot.org/c/coreboot/+/90264 Reviewed-by: Jakub "Kuba" Czapiga Tested-by: build bot (Jenkins) --- src/include/fmap.h | 8 ++++++++ tests/Makefile.common | 2 +- tests/include/tests/lib/fmap_config.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/include/fmap.h b/src/include/fmap.h index 900bfff542..1fadaef3c5 100644 --- a/src/include/fmap.h +++ b/src/include/fmap.h @@ -13,6 +13,14 @@ #error "FMAP must always start flash address 0" #endif +/* This is usually the case. And it can to lead to confusion if one them is updated without the + * other. There is however no code that has a hard dependency on this check. So if there comes + * a platform at some point, which has a Flashmap which doesn't cover the whole flash, we can + * remove the check again. */ +#if FMAP_SECTION_FLASH_SIZE != CONFIG_ROM_SIZE + #error "ROM_SIZE must always be equal to FMAP flash size" +#endif + /* Return the name of the boot region. Falls back to COREBOOT, if not overridden * by any multi-slot mechanism (e.g Intel Top Swap, vboot). */ const char *cbfs_fmap_region_hint(void); diff --git a/tests/Makefile.common b/tests/Makefile.common index cfb6fe945e..085e4cffc4 100644 --- a/tests/Makefile.common +++ b/tests/Makefile.common @@ -18,7 +18,7 @@ CMAKE := cmake OBJCOPY ?= objcopy OBJDUMP ?= objdump -TEST_DEFAULT_CONFIG ?= $(top)/configs/config.emulation_qemu_x86_i440fx +TEST_DEFAULT_CONFIG ?= $(top)/configs/config.google_octopus_spi_flash_console TEST_DOTCONFIG := $(testobj)/.config TEST_KCONFIG_AUTOHEADER := $(testobj)/config.src.h TEST_KCONFIG_AUTOCONFIG := $(testobj)/auto.conf diff --git a/tests/include/tests/lib/fmap_config.h b/tests/include/tests/lib/fmap_config.h index 5b3540020b..690ee19fca 100644 --- a/tests/include/tests/lib/fmap_config.h +++ b/tests/include/tests/lib/fmap_config.h @@ -8,5 +8,6 @@ * Keeps the build tests from failing since fmap.h needs fmap_config.h */ #define FMAP_SECTION_FLASH_START 0 +#define FMAP_SECTION_FLASH_SIZE 0x1000000 #endif From 6127a1d19dc6fe61395f0acfefe75173e3cbda14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Tue, 16 Sep 2025 08:20:15 +0200 Subject: [PATCH 253/789] amdblock/lpc: Add SoC hook to set up SPI TPM decoding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some SoCs may require additional programming to get the SPI TPM work properly. This hook is especially needed if mainboard selects TPM_MEASURED_BOOT_INIT_BOOTBLOCK and TPM is initialized before any vendor silicon initialization code runs (FSP or OpenSIL). Change-Id: I90dbcbfb554ac3cfbcf23d708c3440d27959c632 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/89191 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/soc/amd/common/block/include/amdblocks/lpc.h | 1 + src/soc/amd/common/block/lpc/lpc_util.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/soc/amd/common/block/include/amdblocks/lpc.h b/src/soc/amd/common/block/include/amdblocks/lpc.h index f85c4676cc..1106e3483a 100644 --- a/src/soc/amd/common/block/include/amdblocks/lpc.h +++ b/src/soc/amd/common/block/include/amdblocks/lpc.h @@ -140,6 +140,7 @@ void lpc_enable_sio_decode(const bool addr); uintptr_t lpc_spibase(void); void lpc_tpm_decode(void); void lpc_tpm_decode_spi(void); +void soc_lpc_tpm_decode_spi(void); void lpc_enable_rom(void); void lpc_enable_spi_prefetch(void); uint32_t lpc_get_rom2_region(size_t *bios_size); diff --git a/src/soc/amd/common/block/lpc/lpc_util.c b/src/soc/amd/common/block/lpc/lpc_util.c index b796f3faa4..d41ce0cff1 100644 --- a/src/soc/amd/common/block/lpc/lpc_util.c +++ b/src/soc/amd/common/block/lpc/lpc_util.c @@ -220,6 +220,8 @@ void lpc_tpm_decode(void) pci_write_config32(_LPCB_DEV, LPC_TRUSTED_PLATFORM_MODULE, value); } +void __weak soc_lpc_tpm_decode_spi(void) { } + /* * Enable FCH to decode TPM associated Memory and IO regions to SPI * @@ -236,6 +238,8 @@ void lpc_tpm_decode_spi(void) SPI_BASE_ADDRESS_REGISTER); pci_write_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER, spibase | ROUTE_TPM_2_SPI); + + soc_lpc_tpm_decode_spi(); } /* From c8386195e174dd1b8a3f7fdde4e579b62d8e5176 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Tue, 20 Jan 2026 13:26:29 -0800 Subject: [PATCH 254/789] vc/intel/fsp/fsp2_0/wcl: Export TccOffsetLock UPD This commit exposes the TccOffsetLock UPD option in the FSP-M UPD structure for Wildcat Lake platforms. Since Panther Lake, the FSP locks the TCC (Thermal Control Circuit) MSR by default, which can interfere with Linux-based thermal management systems that expect to configure this register from the operating system. By making TccOffsetLock available to coreboot, firmware integrators can now prevent the FSP from locking the TCC MSR, thereby allowing the OS to manage thermal parameters as needed. BUG=b:474002582 Change-Id: I934dec88f88179c7859c6e1a35ea22c24bcfcbde Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/90839 Reviewed-by: Alicja Michalska Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N --- .../intel/fsp/fsp2_0/wildcatlake/FspmUpd.h | 77 +++++++++++-------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspmUpd.h b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspmUpd.h index 661948e325..2c5c2af641 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspmUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspmUpd.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2025, Intel Corporation. All rights reserved.
+Copyright (c) 2026, Intel Corporation. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -2275,7 +2275,18 @@ typedef struct { /** Offset 0x07D2 - Reserved **/ - UINT8 Reserved63[98]; + UINT8 Reserved63[92]; + +/** Offset 0x082E - Tcc Offset Lock + Tcc Offset Lock for Runtime Average Temperature Limit (RATL) to lock temperature + target; 1:Enabled ; 0: Disabled. + $EN_DIS +**/ + UINT8 TccOffsetLock; + +/** Offset 0x082F - Reserved +**/ + UINT8 Reserved64[5]; /** Offset 0x0834 - SinitMemorySize Enable/Disable. 0: Disable, define default value of SinitMemorySize , 1: enable @@ -2342,7 +2353,7 @@ typedef struct { /** Offset 0x086E - Reserved **/ - UINT8 Reserved64[2]; + UINT8 Reserved65[2]; /** Offset 0x0870 - Platform Power Pmax PSYS PMax power, defined in 1/8 Watt increments. 0 - Auto Specified in 1/8 @@ -2394,7 +2405,7 @@ typedef struct { /** Offset 0x08BA - Reserved **/ - UINT8 Reserved65[26]; + UINT8 Reserved66[26]; /** Offset 0x08D4 - Icc Max limit Voltage Regulator Current Limit (Icc Max). This value represents the Maximum instantaneous @@ -2406,7 +2417,7 @@ typedef struct { /** Offset 0x08E0 - Reserved **/ - UINT8 Reserved66[42]; + UINT8 Reserved67[42]; /** Offset 0x090A - Thermal Design Current enable/disable Thermal Design Current enable/disable; 0: Disable; 1: Enable. [0] for IA, @@ -2416,7 +2427,7 @@ typedef struct { /** Offset 0x0910 - Reserved **/ - UINT8 Reserved67[6]; + UINT8 Reserved68[6]; /** Offset 0x0916 - Disable Fast Slew Rate for Deep Package C States for VR domains This option needs to be configured to reduce acoustic noise during deeper C states. @@ -2438,7 +2449,7 @@ typedef struct { /** Offset 0x0922 - Reserved **/ - UINT8 Reserved68[6]; + UINT8 Reserved69[6]; /** Offset 0x0928 - Thermal Design Current time window Auto = 0 is default. Range is from 1ms to 448s. 0: Auto. [0] for IA, [1] @@ -2454,7 +2465,7 @@ typedef struct { /** Offset 0x0946 - Reserved **/ - UINT8 Reserved69[2]; + UINT8 Reserved70[2]; /** Offset 0x0948 - DLVR RFI Enable Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. @@ -2474,7 +2485,7 @@ typedef struct { /** Offset 0x094B - Reserved **/ - UINT8 Reserved70[11]; + UINT8 Reserved71[11]; /** Offset 0x0956 - VR Fast Vmode ICC Limit support Voltage Regulator Fast Vmode ICC Limit. A value of 400 = 100A. A value of 0 corresponds @@ -2499,7 +2510,7 @@ typedef struct { /** Offset 0x096E - Reserved **/ - UINT8 Reserved71[28]; + UINT8 Reserved72[28]; /** Offset 0x098A - PCH Port80 Route Control where the Port 80h cycles are sent, 0: LPC; 1: PCI. @@ -2516,7 +2527,7 @@ typedef struct { /** Offset 0x098C - Reserved **/ - UINT8 Reserved72[4]; + UINT8 Reserved73[4]; /** Offset 0x0990 - PMR Size Size of PMR memory buffer. 0x400000 for normal boot and 0x200000 for S3 boot @@ -2542,7 +2553,7 @@ typedef struct { /** Offset 0x0997 - Reserved **/ - UINT8 Reserved73; + UINT8 Reserved74; /** Offset 0x0998 - Base addresses for VT-d function MMIO access Base addresses for VT-d MMIO access per VT-d engine @@ -2551,7 +2562,7 @@ typedef struct { /** Offset 0x09BC - Reserved **/ - UINT8 Reserved74[20]; + UINT8 Reserved75[20]; /** Offset 0x09D0 - MMIO Size Size of MMIO space reserved for devices. 0(Default)=Auto, non-Zero=size in MB @@ -2566,7 +2577,7 @@ typedef struct { /** Offset 0x09D4 - Reserved **/ - UINT8 Reserved75[36]; + UINT8 Reserved76[36]; /** Offset 0x09F8 - Enable above 4GB MMIO resource support Enable/disable above 4GB MMIO resource support @@ -2582,7 +2593,7 @@ typedef struct { /** Offset 0x09FA - Reserved **/ - UINT8 Reserved76[10]; + UINT8 Reserved77[10]; /** Offset 0x0A04 - Enable/Disable CrashLog Device Enable or Disable CrashLog/Telemetry Device 0- Disable, 1- Enable @@ -2592,7 +2603,7 @@ typedef struct { /** Offset 0x0A08 - Reserved **/ - UINT8 Reserved77[20]; + UINT8 Reserved78[20]; /** Offset 0x0A1C - Platform Debug Option Enabled Trace active: TraceHub is enabled and trace is active, blocks s0ix.\n @@ -2609,7 +2620,7 @@ typedef struct { /** Offset 0x0A1D - Reserved **/ - UINT8 Reserved78[14]; + UINT8 Reserved79[14]; /** Offset 0x0A2B - Program GPIOs for LFP on DDI port-A device 0=Disabled,1(Default)=eDP, 2=MIPI DSI @@ -2619,7 +2630,7 @@ typedef struct { /** Offset 0x0A2C - Reserved **/ - UINT8 Reserved79[2]; + UINT8 Reserved80[2]; /** Offset 0x0A2E - Program GPIOs for LFP on DDI port-B device 0(Default)=Disabled,1=eDP, 2=MIPI DSI @@ -2713,7 +2724,7 @@ typedef struct { /** Offset 0x0A3D - Reserved **/ - UINT8 Reserved80[3]; + UINT8 Reserved81[3]; /** Offset 0x0A40 - Temporary MMIO address for GMADR The reference code will use this as Temporary MMIO address space to access GMADR @@ -2732,7 +2743,7 @@ typedef struct { /** Offset 0x0A50 - Reserved **/ - UINT8 Reserved81[2]; + UINT8 Reserved82[2]; /** Offset 0x0A52 - Enable/Disable Memory Bandwidth Compression 0=Disable, 1(Default)=Enable @@ -2762,7 +2773,7 @@ typedef struct { /** Offset 0x0A56 - Reserved **/ - UINT8 Reserved82[2]; + UINT8 Reserved83[2]; /** Offset 0x0A58 - Intel Graphics VBT (Video BIOS Table) Size Size of Internal Graphics VBT Image @@ -2771,7 +2782,7 @@ typedef struct { /** Offset 0x0A5C - Reserved **/ - UINT8 Reserved83[4]; + UINT8 Reserved84[4]; /** Offset 0x0A60 - Graphics Configuration Ptr Points to VBT @@ -2832,7 +2843,7 @@ typedef struct { /** Offset 0x0A83 - Reserved **/ - UINT8 Reserved84[4]; + UINT8 Reserved85[4]; /** Offset 0x0A87 - TCSS Type C Port 0 Set TCSS Type C Port 0 Type, Options are 0=DISABLE, 1=DP_ONLY, 2=NO_TBT, 3=NO_PCIE, @@ -2864,7 +2875,7 @@ typedef struct { /** Offset 0x0A8B - Reserved **/ - UINT8 Reserved85; + UINT8 Reserved86; /** Offset 0x0A8C - TypeC port GPIO setting GPIO Pin number for Type C Aux orientation setting, use the GpioPad that is defined @@ -2932,7 +2943,7 @@ typedef struct { /** Offset 0x0AC9 - Reserved **/ - UINT8 Reserved86; + UINT8 Reserved87; /** Offset 0x0ACA - DLL Weak Lock Support Enables/Disable DLL Weak Lock Support @@ -2942,7 +2953,7 @@ typedef struct { /** Offset 0x0ACB - Reserved **/ - UINT8 Reserved87; + UINT8 Reserved88; /** Offset 0x0ACC - Rx DQS Delay Comp Support Enables/Disable Rx DQS Delay Comp Support @@ -2952,7 +2963,7 @@ typedef struct { /** Offset 0x0ACD - Reserved **/ - UINT8 Reserved88[2]; + UINT8 Reserved89[2]; /** Offset 0x0ACF - Mrc Failure On Unsupported Dimm Enables/Disable Mrc Failure On Unsupported Dimm @@ -2962,7 +2973,7 @@ typedef struct { /** Offset 0x0AD0 - Reserved **/ - UINT8 Reserved89[4]; + UINT8 Reserved90[4]; /** Offset 0x0AD4 - DynamicMemoryBoost Enable/Disable Dynamic Memory Boost Feature. Only valid if SpdProfileSelected is @@ -2980,7 +2991,7 @@ typedef struct { /** Offset 0x0ADC - Reserved **/ - UINT8 Reserved90[9]; + UINT8 Reserved91[9]; /** Offset 0x0AE5 - Vref Offset Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.VrefOffset @@ -2991,7 +3002,7 @@ typedef struct { /** Offset 0x0AE6 - Reserved **/ - UINT8 Reserved91[2]; + UINT8 Reserved92[2]; /** Offset 0x0AE8 - tRRSG Delta Delay between Read-to-Read commands in the same Bank Group. 0 - Auto. Signed TAT @@ -3107,7 +3118,7 @@ typedef struct { /** Offset 0x0AF8 - Reserved **/ - UINT8 Reserved92[41]; + UINT8 Reserved93[41]; /** Offset 0x0B21 - Channel to CKD QCK Mapping Specify Channel to CKD QCK Mapping for CH0D0/CH0D1/CH1D0&CH1D1 @@ -3121,7 +3132,7 @@ typedef struct { /** Offset 0x0B31 - Reserved **/ - UINT8 Reserved93[17]; + UINT8 Reserved94[17]; /** Offset 0x0B42 - VDD2 Voltage Voltage is multiple of 5mV where 0 means Auto. @@ -3145,7 +3156,7 @@ typedef struct { /** Offset 0x0B4A - Reserved **/ - UINT8 Reserved94[30]; + UINT8 Reserved95[30]; } FSP_M_CONFIG; /** Fsp M UPD Configuration From c852840f11871a5bf8e42be6df79db9fa02a376b Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Fri, 9 Jan 2026 08:07:27 -0800 Subject: [PATCH 255/789] soc/intel/pantherlake: Disable TCC MSR lock in FSP Since Panther Lake, the FSP locks the TCC (Thermal Control Circuit) MSR by default. However, Linux-based thermal management systems typically configure this register from the operating system rather than the firmware. Locking the TCC MSR in firmware prevents the OS from adjusting thermal parameters as needed, potentially impacting system thermal management and flexibility. This commit explicitly sets the TccOffsetLock field to 0 in the FSP-M configuration, ensuring that the TCC MSR remains unlocked after firmware initialization. BUG=b:474002582 TEST=MSR 0x1A2 is writable from the OS, as indicated by the successful operation of /sys/bus/pci/devices/0000:00:04/tcc_offset_degree_celsius on a Fatcat device. Change-Id: I445bc1408018d3de82919e46c8a368d93bbb1a77 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/90718 Reviewed-by: Alicja Michalska Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N --- src/soc/intel/pantherlake/romstage/fsp_params.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/soc/intel/pantherlake/romstage/fsp_params.c b/src/soc/intel/pantherlake/romstage/fsp_params.c index 5ec92bb80f..d6f628b36a 100644 --- a/src/soc/intel/pantherlake/romstage/fsp_params.c +++ b/src/soc/intel/pantherlake/romstage/fsp_params.c @@ -313,6 +313,7 @@ static void fill_fspm_thermal_params(FSP_M_CONFIG *m_cfg, const struct soc_intel_pantherlake_config *config) { m_cfg->TccActivationOffset = config->tcc_offset; + m_cfg->TccOffsetLock = 0; } static const struct soc_intel_pantherlake_power_map *get_map(const struct soc_intel_pantherlake_config *config) From df44756c8a9a6b9d476729f15965eebd3921678b Mon Sep 17 00:00:00 2001 From: "P, Usha" Date: Fri, 26 Sep 2025 13:49:39 +0530 Subject: [PATCH 256/789] mb/google/ocelot: Disable EC software sync for Microchip EC This patch disables EC software sync specifically for the Microchip EC on the ocelot board. This change selects `GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC` for boards w/ microchip EC (EC_GOOGLE_CHROMEEC_MEC) like ocelot. This allows other ocelot variants (Nuvoton, ITE EC AIC) to potentially enable EC software sync, which is not compatible with the Microchip EC. TEST= Verified EC software sync functionality on a Nuvoton AIC ocelot variant. Change-Id: Ibcd6b0231a5390a9843419da86acee54811ec3d7 Signed-off-by: P, Usha Reviewed-on: https://review.coreboot.org/c/coreboot/+/89357 Reviewed-by: Pranava Y N Tested-by: build bot (Jenkins) Reviewed-by: Avi Uday --- src/mainboard/google/ocelot/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/ocelot/Kconfig b/src/mainboard/google/ocelot/Kconfig index d2a2e189e4..b20ef17289 100644 --- a/src/mainboard/google/ocelot/Kconfig +++ b/src/mainboard/google/ocelot/Kconfig @@ -145,7 +145,7 @@ config BASEBOARD_DIR config CHROMEOS select EC_GOOGLE_CHROMEEC_SWITCHES - select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC if EC_GOOGLE_CHROMEEC_MEC select GBB_FLAG_FORCE_DEV_BOOT_USB select GBB_FLAG_FORCE_MANUAL_RECOVERY select HAS_RECOVERY_MRC_CACHE From cd8e9cd717ccac68adf7eaeee446c87179f6f511 Mon Sep 17 00:00:00 2001 From: Alicja Michalska Date: Wed, 21 Jan 2026 18:05:10 +0100 Subject: [PATCH 257/789] soc/intel/pantherlake: Allow access to eSPI 4e address in bootblock Some Intel development boards have SuperIO located at address 4e instead of "default" 2e. In order to correctly initialize the SIO/EC, we need to allow access to that address in bootblock. For further information refer to #854345 (Intel CNDA). TEST: Build/boot intel/pantherlake_crb (out-of-tree, pending clearance). Make sure that RS232 is working and SIO ACPI tables are correct. Change-Id: I7944a48738fe0146cdf94635a01153a5d2331b24 Signed-off-by: Alicja Michalska Reviewed-on: https://review.coreboot.org/c/coreboot/+/90854 Reviewed-by: Pranava Y N Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/soc/intel/pantherlake/bootblock/pcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/pantherlake/bootblock/pcd.c b/src/soc/intel/pantherlake/bootblock/pcd.c index 50e6ebd73d..bd87dfa82a 100644 --- a/src/soc/intel/pantherlake/bootblock/pcd.c +++ b/src/soc/intel/pantherlake/bootblock/pcd.c @@ -48,8 +48,8 @@ static void pcd_die_config_pwrmbase(void) static void pcd_die_early_iorange_init(void) { - uint16_t io_enables = LPC_IOE_SUPERIO_2E_2F | LPC_IOE_KBC_60_64 | - LPC_IOE_EC_62_66 | LPC_IOE_LGE_200; + uint16_t io_enables = LPC_IOE_SUPERIO_2E_2F | LPC_IOE_EC_4E_4F | + LPC_IOE_KBC_60_64 | LPC_IOE_EC_62_66 | LPC_IOE_LGE_200; /* IO Decode Range */ if (CONFIG(DRIVERS_UART_8250IO)) From d19cb011294d33cf06d5fe508ff186d0dee97af0 Mon Sep 17 00:00:00 2001 From: Ren Kuo Date: Wed, 21 Jan 2026 14:46:37 +0800 Subject: [PATCH 258/789] mb/google/fatcat/moonstone: Remove RTD3 config for SSD The Moonstone hardware design does not have a power load switch for the SSD. Without it, the platform cannot cut off the main power rail to the device to enter D3cold. Therefore, remove the RTD3 chip driver and its associated GPIO configurations (enable/reset) in the overridetree to align with the hardware capability. The system will support D3hot instead of D3cold. BUG=460038237 TEST=Build and boot to OS on Moonstone, verify SSD still functions correctly and power state transitions align with HW design. Change-Id: I8fd12d2f629977f939d11f26aef21552a947c5e3 Signed-off-by: Ren Kuo Reviewed-on: https://review.coreboot.org/c/coreboot/+/90841 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik Reviewed-by: Pranava Y N --- .../google/fatcat/variants/moonstone/overridetree.cb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/mainboard/google/fatcat/variants/moonstone/overridetree.cb b/src/mainboard/google/fatcat/variants/moonstone/overridetree.cb index 17d461248c..16847cc41f 100644 --- a/src/mainboard/google/fatcat/variants/moonstone/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/moonstone/overridetree.cb @@ -390,13 +390,6 @@ chip soc/intel/pantherlake .clk_req = 1, .flags = PCIE_RP_CLK_REQ_DETECT | PCIE_RP_LTR | PCIE_RP_AER, }" - chip soc/intel/common/block/pcie/rtd3 - register "is_storage" = "true" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B16)" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E03)" - register "srcclk_pin" = "1" - device generic 0 on end - end end # Gen5 M.2 SSD device ref cnvi_wifi on chip drivers/wifi/generic From f650bf95ab1f2171ef8a53802876b2afa91f878f Mon Sep 17 00:00:00 2001 From: Bora Guvendik Date: Tue, 13 Jan 2026 12:28:25 -0800 Subject: [PATCH 259/789] soc/intel: Add Nova Lake device IDs This patch adds Nova Lake specific device IDs to the header files and driver-specific code. Note: Device IDs D750h - D75Fh are intentionally omitted and will be added in a future patch once validation is complete. Reference: - Nova Lake External Design Specification (EDS) Volume 1 (#844316) BUG=none Change-Id: I00900c4f796b8bcc40f2bc09917172c71039c8a6 Signed-off-by: Bora Guvendik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90748 Reviewed-by: Kim, Wonkyu Tested-by: build bot (Jenkins) --- src/drivers/intel/ish/ish.c | 1 + src/drivers/intel/touch/touch.c | 4 + src/include/device/pci_ids.h | 104 ++++++++++++++++++ src/soc/intel/common/block/cnvi/cnvi.c | 5 + src/soc/intel/common/block/cse/cse.c | 1 + src/soc/intel/common/block/dsp/dsp.c | 8 ++ .../intel/common/block/graphics/graphics.c | 5 + src/soc/intel/common/block/hda/hda.c | 8 ++ src/soc/intel/common/block/i2c/i2c.c | 6 + src/soc/intel/common/block/ipu/ipu.c | 1 + src/soc/intel/common/block/lpc/lpc.c | 32 ++++++ src/soc/intel/common/block/p2sb/p2sb.c | 1 + src/soc/intel/common/block/p2sb/p2sb2.c | 1 + src/soc/intel/common/block/pcie/pcie.c | 14 +++ src/soc/intel/common/block/pmc/pmc.c | 1 + src/soc/intel/common/block/spi/spi.c | 4 + src/soc/intel/common/block/sram/sram.c | 2 + .../common/block/systemagent/systemagent.c | 5 + .../intel/common/block/tracehub/tracehub.c | 1 + src/soc/intel/common/block/uart/uart.c | 6 + src/soc/intel/common/block/usb4/usb4.c | 1 + src/soc/intel/common/block/usb4/xhci.c | 1 + src/soc/intel/common/block/xdci/xdci.c | 1 + src/soc/intel/common/block/xhci/xhci.c | 1 + 24 files changed, 214 insertions(+) diff --git a/src/drivers/intel/ish/ish.c b/src/drivers/intel/ish/ish.c index 9cf6b7c0e5..fc153fba3a 100644 --- a/src/drivers/intel/ish/ish.c +++ b/src/drivers/intel/ish/ish.c @@ -85,6 +85,7 @@ static const struct device_operations pci_ish_device_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_ISHB, PCI_DID_INTEL_WCL_ISHB, PCI_DID_INTEL_PTL_H_ISHB, PCI_DID_INTEL_PTL_U_H_ISHB, diff --git a/src/drivers/intel/touch/touch.c b/src/drivers/intel/touch/touch.c index 03738741b8..0d27ca3936 100644 --- a/src/drivers/intel/touch/touch.c +++ b/src/drivers/intel/touch/touch.c @@ -626,6 +626,10 @@ static const struct device_operations pci_thc_device_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_THC0_1, + PCI_DID_INTEL_NVL_THC0_2, + PCI_DID_INTEL_NVL_THC1_1, + PCI_DID_INTEL_NVL_THC1_2, PCI_DID_INTEL_MTL_THC0_SPI, PCI_DID_INTEL_MTL_THC1_SPI, PCI_DID_INTEL_PTL_U_H_THC0_I2C, diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h index a3c3e58056..ed3ba38d99 100644 --- a/src/include/device/pci_ids.h +++ b/src/include/device/pci_ids.h @@ -2190,6 +2190,7 @@ #define PCI_DID_INTEL_PTL_H_ISHB 0xe445 #define PCI_DID_INTEL_PTL_U_H_ISHB 0xe345 #define PCI_DID_INTEL_WCL_ISHB 0x4d45 +#define PCI_DID_INTEL_NVL_ISHB 0xd354 /* Intel 82371FB (PIIX) */ #define PCI_DID_INTEL_82371FB_ISA 0x122e @@ -3349,6 +3350,38 @@ #define PCI_DID_INTEL_WCL_ESPI_29 0x4d1d #define PCI_DID_INTEL_WCL_ESPI_30 0x4d1e #define PCI_DID_INTEL_WCL_ESPI_31 0x4d1f +#define PCI_DID_INTEL_NVL_ESPI_0 0xd300 +#define PCI_DID_INTEL_NVL_ESPI_1 0xd301 +#define PCI_DID_INTEL_NVL_ESPI_2 0xd302 +#define PCI_DID_INTEL_NVL_ESPI_3 0xd303 +#define PCI_DID_INTEL_NVL_ESPI_4 0xd304 +#define PCI_DID_INTEL_NVL_ESPI_5 0xd305 +#define PCI_DID_INTEL_NVL_ESPI_6 0xd306 +#define PCI_DID_INTEL_NVL_ESPI_7 0xd307 +#define PCI_DID_INTEL_NVL_ESPI_8 0xd308 +#define PCI_DID_INTEL_NVL_ESPI_9 0xd309 +#define PCI_DID_INTEL_NVL_ESPI_10 0xd30a +#define PCI_DID_INTEL_NVL_ESPI_11 0xd30b +#define PCI_DID_INTEL_NVL_ESPI_12 0xd30c +#define PCI_DID_INTEL_NVL_ESPI_13 0xd30d +#define PCI_DID_INTEL_NVL_ESPI_14 0xd30e +#define PCI_DID_INTEL_NVL_ESPI_15 0xd30f +#define PCI_DID_INTEL_NVL_ESPI_16 0xd310 +#define PCI_DID_INTEL_NVL_ESPI_17 0xd311 +#define PCI_DID_INTEL_NVL_ESPI_18 0xd312 +#define PCI_DID_INTEL_NVL_ESPI_19 0xd313 +#define PCI_DID_INTEL_NVL_ESPI_20 0xd314 +#define PCI_DID_INTEL_NVL_ESPI_21 0xd315 +#define PCI_DID_INTEL_NVL_ESPI_22 0xd316 +#define PCI_DID_INTEL_NVL_ESPI_23 0xd317 +#define PCI_DID_INTEL_NVL_ESPI_24 0xd318 +#define PCI_DID_INTEL_NVL_ESPI_25 0xd319 +#define PCI_DID_INTEL_NVL_ESPI_26 0xd31a +#define PCI_DID_INTEL_NVL_ESPI_27 0xd31b +#define PCI_DID_INTEL_NVL_ESPI_28 0xd31c +#define PCI_DID_INTEL_NVL_ESPI_29 0xd31d +#define PCI_DID_INTEL_NVL_ESPI_30 0xd31e +#define PCI_DID_INTEL_NVL_ESPI_31 0xd31f /* Intel PCIE device ids */ #define PCI_DID_INTEL_LPT_H_PCIE_RP1 0x8c10 @@ -3829,6 +3862,21 @@ #define PCI_DID_INTEL_WCL_PCIE_RP5 0x4d61 #define PCI_DID_INTEL_WCL_PCIE_RP6 0x4d5c +#define PCI_DID_INTEL_NVL_PCIE_RP1 0xd338 +#define PCI_DID_INTEL_NVL_PCIE_RP2 0xd339 +#define PCI_DID_INTEL_NVL_PCIE_RP3 0xd33a +#define PCI_DID_INTEL_NVL_PCIE_RP4 0xd33b +#define PCI_DID_INTEL_NVL_PCIE_RP5 0xd33c +#define PCI_DID_INTEL_NVL_PCIE_RP6 0xd33d +#define PCI_DID_INTEL_NVL_PCIE_RP7 0xd33e +#define PCI_DID_INTEL_NVL_PCIE_RP8 0xd33f +#define PCI_DID_INTEL_NVL_PCIE_RP9 0xd361 +#define PCI_DID_INTEL_NVL_PCIE_RP10 0xd35c +#define PCI_DID_INTEL_NVL_PCIE_RP11 0xd365 +#define PCI_DID_INTEL_NVL_PCIE_RP12 0xd366 +#define PCI_DID_INTEL_NVL_PCIE_RP13 0xd367 +#define PCI_DID_INTEL_NVL_PCIE_RP14 0xd368 + /* Intel SATA device Ids */ #define PCI_DID_INTEL_LPT_H_DESKTOP_SATA_IDE 0x8c00 #define PCI_DID_INTEL_LPT_H_DESKTOP_SATA_AHCI 0x8c02 @@ -3954,6 +4002,7 @@ #define PCI_DID_INTEL_PTL_H_PMC 0xe421 #define PCI_DID_INTEL_PTL_U_H_PMC 0xe321 #define PCI_DID_INTEL_WCL_PMC 0x4d21 +#define PCI_DID_INTEL_NVL_PMC 0xd321 /* Intel I2C device Ids */ #define PCI_DID_INTEL_LPT_LP_I2C0 0x9c61 @@ -4119,6 +4168,13 @@ #define PCI_DID_INTEL_WCL_I2C4 0x4d50 #define PCI_DID_INTEL_WCL_I2C5 0x4d51 +#define PCI_DID_INTEL_NVL_I2C0 0xd378 +#define PCI_DID_INTEL_NVL_I2C1 0xd379 +#define PCI_DID_INTEL_NVL_I2C2 0xd37a +#define PCI_DID_INTEL_NVL_I2C3 0xd37b +#define PCI_DID_INTEL_NVL_I2C4 0xd350 +#define PCI_DID_INTEL_NVL_I2C5 0xd351 + /* Intel UART device Ids */ #define PCI_DID_INTEL_LPT_LP_UART0 0x9c63 #define PCI_DID_INTEL_LPT_LP_UART1 0x9c64 @@ -4222,6 +4278,10 @@ #define PCI_DID_INTEL_WCL_UART1 0x4d26 #define PCI_DID_INTEL_WCL_UART2 0x4d52 +#define PCI_DID_INTEL_NVL_UART0 0xd325 +#define PCI_DID_INTEL_NVL_UART1 0xd326 +#define PCI_DID_INTEL_NVL_UART2 0xd352 + /* Intel SPI device Ids */ #define PCI_DID_INTEL_LPT_LP_GSPI0 0x9c65 #define PCI_DID_INTEL_LPT_LP_GSPI1 0x9c66 @@ -4349,6 +4409,11 @@ #define PCI_DID_INTEL_WCL_SPI1 0x4d30 #define PCI_DID_INTEL_WCL_SPI2 0x4d46 +#define PCI_DID_INTEL_NVL_HWSEQ_SPI 0xd323 +#define PCI_DID_INTEL_NVL_SPI0 0xd327 +#define PCI_DID_INTEL_NVL_SPI1 0xd330 +#define PCI_DID_INTEL_NVL_SPI2 0xd347 + /* Intel IGD device Ids */ #define PCI_DID_INTEL_SKL_GT1F_DT2 0x1902 #define PCI_DID_INTEL_SKL_GT1_SULTM 0x1906 @@ -4522,6 +4587,11 @@ #define PCI_DID_INTEL_PTL_H_GT2_4 0xb08f #define PCI_DID_INTEL_WCL_GT2_1 0xfd80 #define PCI_DID_INTEL_WCL_GT2_2 0xfd81 +#define PCI_DID_INTEL_NVL_GT2_1 0xd741 +#define PCI_DID_INTEL_NVL_GT2_2 0xd742 +#define PCI_DID_INTEL_NVL_GT2_3 0xd743 +#define PCI_DID_INTEL_NVL_GT2_4 0xd744 +#define PCI_DID_INTEL_NVL_GT2_5 0xd745 /* Intel Northbridge Ids */ #define PCI_DID_INTEL_APL_NB 0x5af0 @@ -4691,6 +4761,11 @@ #define PCI_DID_INTEL_WCL_ID_3 0xfd02 #define PCI_DID_INTEL_WCL_ID_4 0xfd03 #define PCI_DID_INTEL_WCL_ID_5 0xfd04 +#define PCI_DID_INTEL_NVL_ID_1 0xd701 +#define PCI_DID_INTEL_NVL_ID_2 0xd702 +#define PCI_DID_INTEL_NVL_ID_3 0xd704 +#define PCI_DID_INTEL_NVL_ID_4 0xd705 +#define PCI_DID_INTEL_NVL_ID_5 0xd70e /* Intel SMBUS device Ids */ #define PCI_DID_INTEL_LPT_H_SMBUS 0x8c22 @@ -4777,6 +4852,8 @@ #define PCI_DID_INTEL_SNR_XHCI 0x18d0 #define PCI_DID_INTEL_WCL_XHCI 0x4d7d #define PCI_DID_INTEL_WCL_TCSS_XHCI 0x4d31 +#define PCI_DID_INTEL_NVL_XHCI 0xd37d +#define PCI_DID_INTEL_NVL_TCSS_XHCI 0xd331 /* Intel P2SB device Ids */ #define PCI_DID_INTEL_APL_P2SB 0x5a92 @@ -4815,6 +4892,8 @@ #define PCI_DID_INTEL_SNR_P2SB 0x18dd #define PCI_DID_INTEL_WCL_P2SB 0x4d20 #define PCI_DID_INTEL_WCL_P2SB2 0x4d4c +#define PCI_DID_INTEL_NVL_P2SB 0xd320 +#define PCI_DID_INTEL_NVL_P2SB2 0xd34c /* Intel SRAM device Ids */ #define PCI_DID_INTEL_APL_SRAM 0x5aec @@ -4836,6 +4915,7 @@ #define PCI_DID_INTEL_PTL_H_SRAM 0xe47f #define PCI_DID_INTEL_PTL_U_H_SRAM 0xe37f #define PCI_DID_INTEL_WCL_SRAM 0x4d7f +#define PCI_DID_INTEL_NVL_SRAM 0xd37e /* Intel AUDIO device Ids */ #define PCI_DID_INTEL_LPT_H_AUDIO 0x8c20 @@ -4932,6 +5012,15 @@ #define PCI_DID_INTEL_WCL_AUDIO_7 0x4d2e #define PCI_DID_INTEL_WCL_AUDIO_8 0x4d2f +#define PCI_DID_INTEL_NVL_AUDIO_1 0xd328 +#define PCI_DID_INTEL_NVL_AUDIO_2 0xd329 +#define PCI_DID_INTEL_NVL_AUDIO_3 0xd32a +#define PCI_DID_INTEL_NVL_AUDIO_4 0xd32b +#define PCI_DID_INTEL_NVL_AUDIO_5 0xd32c +#define PCI_DID_INTEL_NVL_AUDIO_6 0xd32d +#define PCI_DID_INTEL_NVL_AUDIO_7 0xd32e +#define PCI_DID_INTEL_NVL_AUDIO_8 0xd32f + /* Intel HECI/ME device Ids */ #define PCI_DID_INTEL_LPT_H_MEI 0x8c3a #define PCI_DID_INTEL_LPT_H_MEI_9 0x8cba @@ -4989,6 +5078,7 @@ #define PCI_DID_INTEL_PTL_U_H_CSE0 0xe370 #define PCI_DID_INTEL_SNR_HECI1 0x18d3 #define PCI_DID_INTEL_WCL_CSE0 0x4d70 +#define PCI_DID_INTEL_NVL_CSE0 0xd370 /* Intel XDCI device Ids */ #define PCI_DID_INTEL_APL_XDCI 0x5aaa @@ -5017,6 +5107,7 @@ #define PCI_DID_INTEL_PTL_H_XDCI 0xe47e #define PCI_DID_INTEL_PTL_U_H_XDCI 0xe37e #define PCI_DID_INTEL_WCL_XDCI 0x4d7e +#define PCI_DID_INTEL_NVL_XDCI 0xd37f /* Intel SD device Ids */ #define PCI_DID_INTEL_LPT_LP_SD 0x9c35 @@ -5078,6 +5169,7 @@ #define PCI_DID_INTEL_PTL_TBT_DMA0 0xe433 #define PCI_DID_INTEL_PTL_TBT_DMA1 0xe434 #define PCI_DID_INTEL_WCL_TBT_DMA0 0x4d33 +#define PCI_DID_INTEL_NVL_TBT_DMA0 0xd333 /* Intel WIFI Ids */ #define PCI_DID_1000_SERIES_WIFI 0x0084 @@ -5120,6 +5212,7 @@ #define PCI_DID_INTEL_RPL_IPU 0xa75d #define PCI_DID_INTEL_LNL_IPU 0x645d #define PCI_DID_INTEL_PTL_IPU 0xb05d +#define PCI_DID_INTEL_NVL_IPU 0xd719 /* Intel Dynamic Tuning Technology Device */ #define PCI_DID_INTEL_CML_DTT 0x1903 @@ -5199,6 +5292,11 @@ #define PCI_DID_INTEL_WCL_CNVI_WIFI_2 0x4d42 #define PCI_DID_INTEL_WCL_CNVI_WIFI_3 0x4d43 #define PCI_DID_INTEL_WCL_CNVI_BT 0x4d76 +#define PCI_DID_INTEL_NVL_CNVI_WIFI_0 0xd340 +#define PCI_DID_INTEL_NVL_CNVI_WIFI_1 0xd341 +#define PCI_DID_INTEL_NVL_CNVI_WIFI_2 0xd342 +#define PCI_DID_INTEL_NVL_CNVI_WIFI_3 0xd343 +#define PCI_DID_INTEL_NVL_CNVI_BT 0xd346 /* Platform Security Engine */ #define PCI_DID_INTEL_LNL_PSE0 0xa862 @@ -5224,6 +5322,7 @@ #define PCI_DID_INTEL_RPP_S_PMC_CRASHLOG_SRAM 0x7a27 #define PCI_DID_INTEL_PTL_PUNIT_CRASHLOG_SRAM 0xb07d #define PCI_DID_INTEL_WCL_PUNIT_CRASHLOG_SRAM 0xfd7d +#define PCI_DID_INTEL_NVL_PUNIT_CRASHLOG_SRAM 0xd70d /* Intel Trace Hub */ #define PCI_DID_INTEL_MTL_TRACEHUB 0x7e24 @@ -5234,6 +5333,7 @@ #define PCI_DID_INTEL_PTL_H_TRACEHUB 0xe424 #define PCI_DID_INTEL_PTL_U_H_TRACEHUB 0xe324 #define PCI_DID_INTEL_WCL_TRACEHUB 0x4d24 +#define PCI_DID_INTEL_NVL_TRACEHUB 0xd324 /* Intel Ethernet Controller device Ids */ #define PCI_DID_INTEL_EHL_GBE_HOST 0x4B32 @@ -5265,6 +5365,10 @@ #define PCI_DID_INTEL_ARP_S_THC0_2 0x7f59 #define PCI_DID_INTEL_ARP_S_THC1_1 0x7f5a #define PCI_DID_INTEL_ARP_S_THC1_2 0x7f5b +#define PCI_DID_INTEL_NVL_THC0_1 0xd348 +#define PCI_DID_INTEL_NVL_THC0_2 0xd349 +#define PCI_DID_INTEL_NVL_THC1_1 0xd34a +#define PCI_DID_INTEL_NVL_THC1_2 0xd34b #define PCI_VID_COMPUTONE 0x8e0e #define PCI_DID_COMPUTONE_IP2EX 0x0291 diff --git a/src/soc/intel/common/block/cnvi/cnvi.c b/src/soc/intel/common/block/cnvi/cnvi.c index 80fed3a23d..0511fd20c0 100644 --- a/src/soc/intel/common/block/cnvi/cnvi.c +++ b/src/soc/intel/common/block/cnvi/cnvi.c @@ -473,6 +473,10 @@ static struct device_operations cnvi_wifi_ops = { }; static const unsigned short wifi_pci_device_ids[] = { + PCI_DID_INTEL_NVL_CNVI_WIFI_0, + PCI_DID_INTEL_NVL_CNVI_WIFI_1, + PCI_DID_INTEL_NVL_CNVI_WIFI_2, + PCI_DID_INTEL_NVL_CNVI_WIFI_3, PCI_DID_INTEL_WCL_CNVI_WIFI_0, PCI_DID_INTEL_WCL_CNVI_WIFI_1, PCI_DID_INTEL_WCL_CNVI_WIFI_2, @@ -858,6 +862,7 @@ static struct device_operations cnvi_bt_ops = { }; static const unsigned short bt_pci_device_ids[] = { + PCI_DID_INTEL_NVL_CNVI_BT, PCI_DID_INTEL_WCL_CNVI_BT, PCI_DID_INTEL_PTL_H_CNVI_BT, PCI_DID_INTEL_PTL_U_H_CNVI_BT, diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index d02bb85b37..d60b9b5195 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -1527,6 +1527,7 @@ struct device_operations cse_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_CSE0, PCI_DID_INTEL_WCL_CSE0, PCI_DID_INTEL_PTL_H_CSE0, PCI_DID_INTEL_PTL_U_H_CSE0, diff --git a/src/soc/intel/common/block/dsp/dsp.c b/src/soc/intel/common/block/dsp/dsp.c index 9155a2a7b7..6656042674 100644 --- a/src/soc/intel/common/block/dsp/dsp.c +++ b/src/soc/intel/common/block/dsp/dsp.c @@ -14,6 +14,14 @@ static struct device_operations dsp_dev_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_AUDIO_1, + PCI_DID_INTEL_NVL_AUDIO_2, + PCI_DID_INTEL_NVL_AUDIO_3, + PCI_DID_INTEL_NVL_AUDIO_4, + PCI_DID_INTEL_NVL_AUDIO_5, + PCI_DID_INTEL_NVL_AUDIO_6, + PCI_DID_INTEL_NVL_AUDIO_7, + PCI_DID_INTEL_NVL_AUDIO_8, PCI_DID_INTEL_WCL_AUDIO_1, PCI_DID_INTEL_WCL_AUDIO_2, PCI_DID_INTEL_WCL_AUDIO_3, diff --git a/src/soc/intel/common/block/graphics/graphics.c b/src/soc/intel/common/block/graphics/graphics.c index 12f29b567b..14893869a0 100644 --- a/src/soc/intel/common/block/graphics/graphics.c +++ b/src/soc/intel/common/block/graphics/graphics.c @@ -361,6 +361,11 @@ const struct device_operations graphics_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_GT2_1, + PCI_DID_INTEL_NVL_GT2_2, + PCI_DID_INTEL_NVL_GT2_3, + PCI_DID_INTEL_NVL_GT2_4, + PCI_DID_INTEL_NVL_GT2_5, PCI_DID_INTEL_WCL_GT2_1, PCI_DID_INTEL_WCL_GT2_2, PCI_DID_INTEL_PTL_U_GT2_1, diff --git a/src/soc/intel/common/block/hda/hda.c b/src/soc/intel/common/block/hda/hda.c index f5e22bc6d9..e779dee312 100644 --- a/src/soc/intel/common/block/hda/hda.c +++ b/src/soc/intel/common/block/hda/hda.c @@ -30,6 +30,14 @@ struct device_operations hda_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_AUDIO_1, + PCI_DID_INTEL_NVL_AUDIO_2, + PCI_DID_INTEL_NVL_AUDIO_3, + PCI_DID_INTEL_NVL_AUDIO_4, + PCI_DID_INTEL_NVL_AUDIO_5, + PCI_DID_INTEL_NVL_AUDIO_6, + PCI_DID_INTEL_NVL_AUDIO_7, + PCI_DID_INTEL_NVL_AUDIO_8, PCI_DID_INTEL_WCL_AUDIO_1, PCI_DID_INTEL_WCL_AUDIO_2, PCI_DID_INTEL_WCL_AUDIO_3, diff --git a/src/soc/intel/common/block/i2c/i2c.c b/src/soc/intel/common/block/i2c/i2c.c index 2c0e010ccb..161e61fc47 100644 --- a/src/soc/intel/common/block/i2c/i2c.c +++ b/src/soc/intel/common/block/i2c/i2c.c @@ -174,6 +174,12 @@ struct device_operations i2c_dev_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_I2C0, + PCI_DID_INTEL_NVL_I2C1, + PCI_DID_INTEL_NVL_I2C2, + PCI_DID_INTEL_NVL_I2C3, + PCI_DID_INTEL_NVL_I2C4, + PCI_DID_INTEL_NVL_I2C5, PCI_DID_INTEL_WCL_I2C0, PCI_DID_INTEL_WCL_I2C1, PCI_DID_INTEL_WCL_I2C2, diff --git a/src/soc/intel/common/block/ipu/ipu.c b/src/soc/intel/common/block/ipu/ipu.c index 989da2e76a..a0acc6332d 100644 --- a/src/soc/intel/common/block/ipu/ipu.c +++ b/src/soc/intel/common/block/ipu/ipu.c @@ -12,6 +12,7 @@ struct device_operations ipu_pci_ops = { }; static const uint16_t pci_device_ids[] = { + PCI_DID_INTEL_NVL_IPU, PCI_DID_INTEL_PTL_IPU, PCI_DID_INTEL_LNL_IPU, PCI_DID_INTEL_RPL_IPU, diff --git a/src/soc/intel/common/block/lpc/lpc.c b/src/soc/intel/common/block/lpc/lpc.c index 391a0182f2..99c628e12c 100644 --- a/src/soc/intel/common/block/lpc/lpc.c +++ b/src/soc/intel/common/block/lpc/lpc.c @@ -151,6 +151,38 @@ struct device_operations lpc_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_ESPI_0, + PCI_DID_INTEL_NVL_ESPI_1, + PCI_DID_INTEL_NVL_ESPI_2, + PCI_DID_INTEL_NVL_ESPI_3, + PCI_DID_INTEL_NVL_ESPI_4, + PCI_DID_INTEL_NVL_ESPI_5, + PCI_DID_INTEL_NVL_ESPI_6, + PCI_DID_INTEL_NVL_ESPI_7, + PCI_DID_INTEL_NVL_ESPI_8, + PCI_DID_INTEL_NVL_ESPI_9, + PCI_DID_INTEL_NVL_ESPI_10, + PCI_DID_INTEL_NVL_ESPI_11, + PCI_DID_INTEL_NVL_ESPI_12, + PCI_DID_INTEL_NVL_ESPI_13, + PCI_DID_INTEL_NVL_ESPI_14, + PCI_DID_INTEL_NVL_ESPI_15, + PCI_DID_INTEL_NVL_ESPI_16, + PCI_DID_INTEL_NVL_ESPI_17, + PCI_DID_INTEL_NVL_ESPI_18, + PCI_DID_INTEL_NVL_ESPI_19, + PCI_DID_INTEL_NVL_ESPI_20, + PCI_DID_INTEL_NVL_ESPI_21, + PCI_DID_INTEL_NVL_ESPI_22, + PCI_DID_INTEL_NVL_ESPI_23, + PCI_DID_INTEL_NVL_ESPI_24, + PCI_DID_INTEL_NVL_ESPI_25, + PCI_DID_INTEL_NVL_ESPI_26, + PCI_DID_INTEL_NVL_ESPI_27, + PCI_DID_INTEL_NVL_ESPI_28, + PCI_DID_INTEL_NVL_ESPI_29, + PCI_DID_INTEL_NVL_ESPI_30, + PCI_DID_INTEL_NVL_ESPI_31, PCI_DID_INTEL_WCL_ESPI_0, PCI_DID_INTEL_WCL_ESPI_1, PCI_DID_INTEL_WCL_ESPI_2, diff --git a/src/soc/intel/common/block/p2sb/p2sb.c b/src/soc/intel/common/block/p2sb/p2sb.c index 194c18f86a..64600b197c 100644 --- a/src/soc/intel/common/block/p2sb/p2sb.c +++ b/src/soc/intel/common/block/p2sb/p2sb.c @@ -145,6 +145,7 @@ const struct device_operations p2sb_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_P2SB, PCI_DID_INTEL_WCL_P2SB, PCI_DID_INTEL_PTL_H_P2SB, PCI_DID_INTEL_PTL_U_H_P2SB, diff --git a/src/soc/intel/common/block/p2sb/p2sb2.c b/src/soc/intel/common/block/p2sb/p2sb2.c index 2627a7182c..1223f7339a 100644 --- a/src/soc/intel/common/block/p2sb/p2sb2.c +++ b/src/soc/intel/common/block/p2sb/p2sb2.c @@ -37,6 +37,7 @@ struct device_operations p2sb2_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_P2SB2, PCI_DID_INTEL_WCL_P2SB2, PCI_DID_INTEL_PTL_H_P2SB2, PCI_DID_INTEL_PTL_U_H_P2SB2, diff --git a/src/soc/intel/common/block/pcie/pcie.c b/src/soc/intel/common/block/pcie/pcie.c index 18b938e280..4b64f85b8a 100644 --- a/src/soc/intel/common/block/pcie/pcie.c +++ b/src/soc/intel/common/block/pcie/pcie.c @@ -67,6 +67,20 @@ struct device_operations pcie_rp_ops = { }; static const unsigned short pcie_device_ids[] = { + PCI_DID_INTEL_NVL_PCIE_RP1, + PCI_DID_INTEL_NVL_PCIE_RP2, + PCI_DID_INTEL_NVL_PCIE_RP3, + PCI_DID_INTEL_NVL_PCIE_RP4, + PCI_DID_INTEL_NVL_PCIE_RP5, + PCI_DID_INTEL_NVL_PCIE_RP6, + PCI_DID_INTEL_NVL_PCIE_RP7, + PCI_DID_INTEL_NVL_PCIE_RP8, + PCI_DID_INTEL_NVL_PCIE_RP9, + PCI_DID_INTEL_NVL_PCIE_RP10, + PCI_DID_INTEL_NVL_PCIE_RP11, + PCI_DID_INTEL_NVL_PCIE_RP12, + PCI_DID_INTEL_NVL_PCIE_RP13, + PCI_DID_INTEL_NVL_PCIE_RP14, PCI_DID_INTEL_WCL_PCIE_RP1, PCI_DID_INTEL_WCL_PCIE_RP2, PCI_DID_INTEL_WCL_PCIE_RP3, diff --git a/src/soc/intel/common/block/pmc/pmc.c b/src/soc/intel/common/block/pmc/pmc.c index 09c08cdbb5..80db323ac6 100644 --- a/src/soc/intel/common/block/pmc/pmc.c +++ b/src/soc/intel/common/block/pmc/pmc.c @@ -111,6 +111,7 @@ struct device_operations pmc_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_PMC, PCI_DID_INTEL_WCL_PMC, PCI_DID_INTEL_PTL_H_PMC, PCI_DID_INTEL_PTL_U_H_PMC, diff --git a/src/soc/intel/common/block/spi/spi.c b/src/soc/intel/common/block/spi/spi.c index 1ac0de0d7c..680e14e035 100644 --- a/src/soc/intel/common/block/spi/spi.c +++ b/src/soc/intel/common/block/spi/spi.c @@ -123,6 +123,10 @@ struct device_operations spi_dev_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_HWSEQ_SPI, + PCI_DID_INTEL_NVL_SPI0, + PCI_DID_INTEL_NVL_SPI1, + PCI_DID_INTEL_NVL_SPI2, PCI_DID_INTEL_WCL_HWSEQ_SPI, PCI_DID_INTEL_WCL_SPI0, PCI_DID_INTEL_WCL_SPI1, diff --git a/src/soc/intel/common/block/sram/sram.c b/src/soc/intel/common/block/sram/sram.c index ba2ed8616f..cc51bcd084 100644 --- a/src/soc/intel/common/block/sram/sram.c +++ b/src/soc/intel/common/block/sram/sram.c @@ -33,6 +33,8 @@ static const struct device_operations device_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_SRAM, + PCI_DID_INTEL_NVL_PUNIT_CRASHLOG_SRAM, PCI_DID_INTEL_WCL_SRAM, PCI_DID_INTEL_WCL_PUNIT_CRASHLOG_SRAM, PCI_DID_INTEL_PTL_H_SRAM, diff --git a/src/soc/intel/common/block/systemagent/systemagent.c b/src/soc/intel/common/block/systemagent/systemagent.c index 749e9c6ad9..7ea802ae06 100644 --- a/src/soc/intel/common/block/systemagent/systemagent.c +++ b/src/soc/intel/common/block/systemagent/systemagent.c @@ -425,6 +425,11 @@ struct device_operations systemagent_ops = { }; static const unsigned short systemagent_ids[] = { + PCI_DID_INTEL_NVL_ID_1, + PCI_DID_INTEL_NVL_ID_2, + PCI_DID_INTEL_NVL_ID_3, + PCI_DID_INTEL_NVL_ID_4, + PCI_DID_INTEL_NVL_ID_5, PCI_DID_INTEL_WCL_ID_1, PCI_DID_INTEL_WCL_ID_2, PCI_DID_INTEL_WCL_ID_3, diff --git a/src/soc/intel/common/block/tracehub/tracehub.c b/src/soc/intel/common/block/tracehub/tracehub.c index dc8c3fd2d6..1341779630 100644 --- a/src/soc/intel/common/block/tracehub/tracehub.c +++ b/src/soc/intel/common/block/tracehub/tracehub.c @@ -42,6 +42,7 @@ static struct device_operations dev_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_TRACEHUB, PCI_DID_INTEL_WCL_TRACEHUB, PCI_DID_INTEL_PTL_H_TRACEHUB, PCI_DID_INTEL_PTL_U_H_TRACEHUB, diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index 8133551a27..0e9132d4c1 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -308,6 +308,7 @@ static const char *uart_acpi_hid(const struct device *dev) static const char *uart_acpi_name(const struct device *dev) { switch (dev->device) { + case PCI_DID_INTEL_NVL_UART0: case PCI_DID_INTEL_WCL_UART0: case PCI_DID_INTEL_PTL_H_UART0: case PCI_DID_INTEL_PTL_U_H_UART0: @@ -319,6 +320,7 @@ static const char *uart_acpi_name(const struct device *dev) case PCI_DID_INTEL_SPT_H_UART0: case PCI_DID_INTEL_CNP_H_UART0: return "UAR0"; + case PCI_DID_INTEL_NVL_UART1: case PCI_DID_INTEL_WCL_UART1: case PCI_DID_INTEL_PTL_H_UART1: case PCI_DID_INTEL_PTL_U_H_UART1: @@ -330,6 +332,7 @@ static const char *uart_acpi_name(const struct device *dev) case PCI_DID_INTEL_SPT_H_UART1: case PCI_DID_INTEL_CNP_H_UART1: return "UAR1"; + case PCI_DID_INTEL_NVL_UART2: case PCI_DID_INTEL_WCL_UART2: case PCI_DID_INTEL_PTL_H_UART2: case PCI_DID_INTEL_PTL_U_H_UART2: @@ -360,6 +363,9 @@ struct device_operations uart_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_UART0, + PCI_DID_INTEL_NVL_UART1, + PCI_DID_INTEL_NVL_UART2, PCI_DID_INTEL_WCL_UART0, PCI_DID_INTEL_WCL_UART1, PCI_DID_INTEL_WCL_UART2, diff --git a/src/soc/intel/common/block/usb4/usb4.c b/src/soc/intel/common/block/usb4/usb4.c index 9d176a3695..1daaf86fbb 100644 --- a/src/soc/intel/common/block/usb4/usb4.c +++ b/src/soc/intel/common/block/usb4/usb4.c @@ -52,6 +52,7 @@ static void tbt_dma_fill_ssdt(const struct device *dev) #endif static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_TBT_DMA0, PCI_DID_INTEL_WCL_TBT_DMA0, PCI_DID_INTEL_PTL_TBT_DMA0, PCI_DID_INTEL_PTL_TBT_DMA1, diff --git a/src/soc/intel/common/block/usb4/xhci.c b/src/soc/intel/common/block/usb4/xhci.c index a23845820a..ac455f284c 100644 --- a/src/soc/intel/common/block/usb4/xhci.c +++ b/src/soc/intel/common/block/usb4/xhci.c @@ -26,6 +26,7 @@ static struct device_operations usb4_xhci_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_TCSS_XHCI, PCI_DID_INTEL_WCL_TCSS_XHCI, PCI_DID_INTEL_PTL_H_TCSS_XHCI, PCI_DID_INTEL_PTL_U_H_TCSS_XHCI, diff --git a/src/soc/intel/common/block/xdci/xdci.c b/src/soc/intel/common/block/xdci/xdci.c index ed6a15b363..6916d8c3f5 100644 --- a/src/soc/intel/common/block/xdci/xdci.c +++ b/src/soc/intel/common/block/xdci/xdci.c @@ -28,6 +28,7 @@ struct device_operations usb_xdci_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_XDCI, PCI_DID_INTEL_WCL_XDCI, PCI_DID_INTEL_PTL_H_XDCI, PCI_DID_INTEL_PTL_U_H_XDCI, diff --git a/src/soc/intel/common/block/xhci/xhci.c b/src/soc/intel/common/block/xhci/xhci.c index 8350c3650b..d12792dbb8 100644 --- a/src/soc/intel/common/block/xhci/xhci.c +++ b/src/soc/intel/common/block/xhci/xhci.c @@ -131,6 +131,7 @@ struct device_operations usb_xhci_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_XHCI, PCI_DID_INTEL_WCL_XHCI, PCI_DID_INTEL_PTL_H_XHCI, PCI_DID_INTEL_PTL_U_H_XHCI, From 71296476a84a43f0ca872ccda5a063e8432aa9e1 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Tue, 20 Jan 2026 17:06:18 +0100 Subject: [PATCH 260/789] tests/lib/coreboot_table-test.c: Add lb_string_platform_blob_version A later patch changes the .config file which we use for our tests. However that causes the PLATFORM_USES_FSP2_0 option to be enabled, which in turn causes build errors in our tests, because the function is obviously not defined in our tests. Create a stub function of sorts like we do for other coreboot table entries. It also moves the declaration of the `lb_string_platform_blob_version` function to coreboot_tables.h, since it doesn't belong in the FSP header file. Because of that we can also remove the `if (CONFIG_PLATFORM_USES_FSP2_0)` check, which makes the code a bit cleaner. Signed-off-by: Maximilian Brune Change-Id: I7721dfe4d287b2274a383bb7e5337b85a0f3f148 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90830 Tested-by: build bot (Jenkins) Reviewed-by: Jakub "Kuba" Czapiga --- src/drivers/intel/fsp2_0/include/fsp/util.h | 1 - src/include/boot/coreboot_tables.h | 2 ++ src/lib/coreboot_table.c | 5 ----- tests/lib/coreboot_table-test.c | 19 +++++++++++++++++++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/drivers/intel/fsp2_0/include/fsp/util.h b/src/drivers/intel/fsp2_0/include/fsp/util.h index ce6666a453..88b0b6a22c 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/util.h +++ b/src/drivers/intel/fsp2_0/include/fsp/util.h @@ -166,7 +166,6 @@ void display_fsp_error_info_hob(const void *hob); void fsp_get_version(char *buf); /* fsp_verify_upd_header_signature calls die() on signature mismatch */ void fsp_verify_upd_header_signature(uint64_t upd_signature, uint64_t expected_signature); -void lb_string_platform_blob_version(struct lb_header *header); void report_fspt_output(void); void soc_validate_fspm_header(const struct fsp_header *hdr); /* diff --git a/src/include/boot/coreboot_tables.h b/src/include/boot/coreboot_tables.h index 3a5e31651c..ec56c15923 100644 --- a/src/include/boot/coreboot_tables.h +++ b/src/include/boot/coreboot_tables.h @@ -24,6 +24,8 @@ void lb_add_console(uint16_t consoletype, void *data); enum cb_err fill_lb_pcie(struct lb_pcie *pcie); +void lb_string_platform_blob_version(struct lb_header *header); + /* Define this in mainboard.c to add board-specific table entries. */ void lb_board(struct lb_header *header); diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index 6218784adc..5aa0e92d15 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -29,11 +29,6 @@ #if CONFIG(USE_OPTION_TABLE) #include #endif -#if CONFIG(PLATFORM_USES_FSP2_0) -#include -#else -void lb_string_platform_blob_version(struct lb_header *header); -#endif __weak enum cb_err fill_lb_pcie(struct lb_pcie *pcie) { diff --git a/tests/lib/coreboot_table-test.c b/tests/lib/coreboot_table-test.c index 9547ee07a6..2197b95631 100644 --- a/tests/lib/coreboot_table-test.c +++ b/tests/lib/coreboot_table-test.c @@ -176,6 +176,8 @@ const unsigned int coreboot_minor_revision = 13; const char coreboot_compile_time[] = "13:58:22"; const char coreboot_dmi_date[] = "03/31/2021"; +const uint8_t platform_blob_version[] = "3.2.1"; + const struct bcd_date coreboot_build_date = { .century = 0x20, .year = 0x20, @@ -228,6 +230,18 @@ enum cb_err fill_lb_serial(struct lb_serial *serial) return CB_SUCCESS; } +void lb_string_platform_blob_version(struct lb_header *header) +{ + struct lb_string *rec; + size_t len; + + rec = (struct lb_string *)lb_new_record(header); + rec->tag = LB_TAG_PLATFORM_BLOB_VERSION; + len = sizeof(platform_blob_version); + rec->size = ALIGN_UP(sizeof(*rec) + len, 8); + memcpy(rec->string, platform_blob_version, len); +} + struct cbfs_boot_device cbfs_boot_dev = { .rdev = REGION_DEV_INIT(NULL, 0, 0x1000), .mcache = (void *)0x1000, @@ -464,6 +478,11 @@ static void test_write_tables(void **state) const struct lb_acpi_rsdp *acpi_rsdp = (struct lb_acpi_rsdp *)record; assert_int_equal(ebda_base, acpi_rsdp->rsdp_pointer); break; + case LB_TAG_PLATFORM_BLOB_VERSION: + uint32_t platform_blob_version_size = + ALIGN_UP(sizeof(struct lb_string) + sizeof(platform_blob_version), 8); + assert_int_equal(platform_blob_version_size, record->size); + break; default: fail_msg("Unexpected tag found in record. Tag ID: 0x%x", record->tag); } From cbca308a056be421566803f241e6d7d7f0e32286 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Tue, 20 Jan 2026 17:20:30 +0100 Subject: [PATCH 261/789] include/console/console.h: Enable console for ENV_TEST `tests/stubs/console.c` also implements printk for our test functions. Change-Id: Ic6ad8832515b90f4706cb9c5b9d9525a25485992 Signed-off-by: Maximilian Brune Reviewed-on: https://review.coreboot.org/c/coreboot/+/90831 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/include/console/console.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/include/console/console.h b/src/include/console/console.h index 8d1a5c5dde..927b1d6ef0 100644 --- a/src/include/console/console.h +++ b/src/include/console/console.h @@ -45,7 +45,8 @@ static inline int get_console_loglevel(void) ((ENV_BOOTBLOCK && CONFIG(BOOTBLOCK_CONSOLE)) || \ (ENV_POSTCAR && CONFIG(POSTCAR_CONSOLE)) || \ ENV_SEPARATE_VERSTAGE || ENV_SEPARATE_ROMSTAGE || ENV_RAMSTAGE || \ - ENV_LIBAGESA || (ENV_SMM && CONFIG(DEBUG_SMI))) + ENV_LIBAGESA || (ENV_SMM && CONFIG(DEBUG_SMI)) || \ + ENV_TEST) #if __CONSOLE_ENABLE__ int get_log_level(void); From 177c2b86246361227ac9ece54322182c4c76d28b Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 22 Jan 2026 14:53:54 -0800 Subject: [PATCH 262/789] ec/google/chromeec/acpi: Fix typo in sensor event comment Correct a spelling error in the comment within the EC0 device block, changing "reaading" to "reading". Change-Id: I5cc57cad86f72be96e1465a1e8de9b9850adf7c1 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/90869 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Caveh Jalali --- src/ec/google/chromeec/acpi/ec.asl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ec/google/chromeec/acpi/ec.asl b/src/ec/google/chromeec/acpi/ec.asl index ebba0faffd..93b04718ec 100644 --- a/src/ec/google/chromeec/acpi/ec.asl +++ b/src/ec/google/chromeec/acpi/ec.asl @@ -589,7 +589,7 @@ Device (EC0) \_SB.DPTF.TEVT (Local0) #endif - /* Keep reaading sensor ID for event */ + /* Keep reading sensor ID for event */ Local0 = ^PATI } From 472b2928f3e68b898fb4339ab51c5b474f65705a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Fri, 5 Dec 2025 11:26:48 +0100 Subject: [PATCH 263/789] util/amdfwtool: Use enum values for address mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace hardcoded values of address mode with its corresponding enum value to increase code readability. Change-Id: Ib2d97f36aa19235a312558e397f97e2607476e61 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/90391 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- util/amdfwtool/amdfwread.c | 9 +++++---- util/amdfwtool/amdfwtool.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/util/amdfwtool/amdfwread.c b/util/amdfwtool/amdfwread.c index 46884f1e48..4dde162cd3 100644 --- a/util/amdfwtool/amdfwread.c +++ b/util/amdfwtool/amdfwread.c @@ -269,7 +269,7 @@ static int amdfw_bios_dir_walk(FILE *fw, uint32_t bios_offset, uint32_t cookie, size_t num_current_entries = 0; bios_directory_hdr header; uint32_t l2_dir_offset = 0; - uint64_t dir_mode = 0; + uint64_t dir_mode = AMD_ADDR_PHYSICAL; char indent[MAX_INDENTATION_LEN] = {0}; if (read_bios_directory(fw, bios_offset, cookie, &header, @@ -287,7 +287,7 @@ static int amdfw_bios_dir_walk(FILE *fw, uint32_t bios_offset, uint32_t cookie, uint64_t mode = current_entries[i].address_mode; uint64_t addr = current_entries[i].source; - if (dir_mode < 2) + if (dir_mode < AMD_ADDR_REL_TAB) mode = dir_mode; if (type == AMD_BIOS_APOB || type == AMD_BIOS_PSP_SHARED_MEM) @@ -386,7 +386,7 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui uint32_t bios_dir_offset = 0; uint32_t ish_dir_offset = 0; ish_directory_table ish_dir; - uint64_t dir_mode = 0; + uint64_t dir_mode = AMD_ADDR_PHYSICAL; char indent[MAX_INDENTATION_LEN] = {0}; if (read_psp_directory(fw, psp_offset, cookie, &header, @@ -404,7 +404,8 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui uint64_t mode = current_entries[i].address_mode; uint64_t addr = current_entries[i].addr; uint32_t dir_size = 0; - if (dir_mode < 2) + + if (dir_mode < AMD_ADDR_REL_TAB) mode = dir_mode; if (type == AMD_PSP_FUSE_CHAIN) diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c index 4184a60b74..6c1ec632a6 100644 --- a/util/amdfwtool/amdfwtool.c +++ b/util/amdfwtool/amdfwtool.c @@ -1088,7 +1088,7 @@ static void integrate_psp_firmwares(context *ctx, pspdir->entries[count].rsvd = 0; pspdir->entries[count].size = 0xFFFFFFFF; pspdir->entries[count].addr = fw_table[i].other; - pspdir->entries[count].address_mode = 0; + pspdir->entries[count].address_mode = AMD_ADDR_PHYSICAL; count++; } else if (fw_table[i].type == AMD_FW_PSP_NVRAM || fw_table[i].type == AMD_RPMC_NVRAM) { From c377682973a77466988d992d0221789accfa2865 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Thu, 22 Jan 2026 14:02:49 -0600 Subject: [PATCH 264/789] util/inteltool: Add support for Arrow Lake H Add PCI IDs necessary to support Intel Core Ultra 9 285H (Arrow Lake-H platform). Arrow Lake is a Meteor Lake variant, so handle the same as Meteor Lake-P. Add a missing PCI ID for MTL-P as well. TEST=dump GPIOs on Starlabs Starfighter with Core Ultra 125H (MTL) and 285H (ARL) CPUs. Change-Id: I14b74227ce808a7b4269741b7e2c5f23326bced4 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90868 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- util/inteltool/gpio.c | 2 ++ util/inteltool/gpio_groups.c | 1 + util/inteltool/inteltool.c | 6 ++++++ util/inteltool/inteltool.h | 7 +++++++ util/inteltool/pcr.c | 1 + 5 files changed, 17 insertions(+) diff --git a/util/inteltool/gpio.c b/util/inteltool/gpio.c index ff21d2452b..2a893a2daf 100644 --- a/util/inteltool/gpio.c +++ b/util/inteltool/gpio.c @@ -1133,6 +1133,7 @@ int print_gpios(struct pci_dev *sb, int show_all, int show_diffs) case PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_3: case PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_4: case PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_5: + case PCI_DEVICE_ID_INTEL_CORE_ARL_ID_H_1: case PCI_DEVICE_ID_INTEL_MTL_0: case PCI_DEVICE_ID_INTEL_MTL_1: case PCI_DEVICE_ID_INTEL_MTL_2: @@ -1141,6 +1142,7 @@ int print_gpios(struct pci_dev *sb, int show_all, int show_diffs) case PCI_DEVICE_ID_INTEL_MTL_5: case PCI_DEVICE_ID_INTEL_MTL_6: case PCI_DEVICE_ID_INTEL_MTL_7: + case PCI_DEVICE_ID_INTEL_ARL_1: print_gpio_groups(sb); return 0; case PCI_DEVICE_ID_INTEL_82371XX: diff --git a/util/inteltool/gpio_groups.c b/util/inteltool/gpio_groups.c index fb50905b25..23757ba630 100644 --- a/util/inteltool/gpio_groups.c +++ b/util/inteltool/gpio_groups.c @@ -264,6 +264,7 @@ const struct gpio_community *const *get_gpio_communities(struct pci_dev *const s case PCI_DEVICE_ID_INTEL_MTL_5: case PCI_DEVICE_ID_INTEL_MTL_6: case PCI_DEVICE_ID_INTEL_MTL_7: + case PCI_DEVICE_ID_INTEL_ARL_1: *community_count = ARRAY_SIZE(meteorlake_pch_communities); *pad_stepping = 16; return meteorlake_pch_communities; diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c index d58b850717..5bd9a05949 100644 --- a/util/inteltool/inteltool.c +++ b/util/inteltool/inteltool.c @@ -204,6 +204,8 @@ static const struct { "14th generation (Meteor Lake P family) Core Processor"}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_5, "14th generation (Meteor Lake P family) Core Processor"}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_ARL_ID_H_1, + "14th generation (Arrow Lake H family) Core Processor"}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_1, "Elkhart Lake Processor" }, @@ -465,6 +467,8 @@ static const struct { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_JSL, "Jasper Lake" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_N, "Alder Lake-N"}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_RPL_P, "Raptor Lake" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MTL_P, "Meteor Lake-P"}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ARL_H, "Arrow Lake-H"}, /* Intel GPUs */ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_G35_EXPRESS, @@ -643,6 +647,8 @@ static const struct { "Intel(R) MeteorLake-P GT2" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MTL_P_GT2_4, "Intel(R) MeteorLake-P GT2" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ARL_H_GT2_1, + "Intel(R) ArrowLake-H GT2" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_GT1_1, "Intel(R) Elkhart Lake GT1" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_GT1_2, diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h index f0ddef283d..c279d02e87 100644 --- a/util/inteltool/inteltool.h +++ b/util/inteltool/inteltool.h @@ -258,6 +258,8 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_MTL_6 0x7e06 #define PCI_DEVICE_ID_INTEL_MTL_7 0x7e07 +#define PCI_DEVICE_ID_INTEL_ARL_1 0x7702 + #define PCI_DEVICE_ID_INTEL_82810 0x7120 #define PCI_DEVICE_ID_INTEL_82810_DC 0x7122 #define PCI_DEVICE_ID_INTEL_82810E_DC 0x7124 @@ -321,6 +323,9 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_RPL_P 0x519d #define PCI_DEVICE_ID_INTEL_ADL_N 0x5481 +#define PCI_DEVICE_ID_INTEL_MTL_P 0x7e27 +#define PCI_DEVICE_ID_INTEL_ARL_H 0x7727 + #define PCI_DEVICE_ID_INTEL_EHL 0x4b00 #define PCI_DEVICE_ID_INTEL_JSL 0x4d87 @@ -420,6 +425,7 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_M 0x7D00 /* Meteorlake M */ #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_1 0x7D01 /* Meteorlake P */ #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_2 0x7D02 /* Meteorlake P */ +#define PCI_DEVICE_ID_INTEL_CORE_ARL_ID_H_1 0x7D06 /* Arrowlake H */ #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_3 0x7d14 /* Meteorlake P */ #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_4 0x7d15 /* Meteorlake P */ #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_5 0x7d16 /* Meteorlake P */ @@ -521,6 +527,7 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_MTL_P_GT2_2 0x7d50 #define PCI_DEVICE_ID_INTEL_MTL_P_GT2_3 0x7d55 #define PCI_DEVICE_ID_INTEL_MTL_P_GT2_4 0x7d60 +#define PCI_DEVICE_ID_INTEL_ARL_H_GT2_1 0x7d51 #define PCI_DEVICE_ID_INTEL_RPL_H_IRIS_XE 0xa7a0 #if !defined(__DARWIN__) && !defined(__FreeBSD__) diff --git a/util/inteltool/pcr.c b/util/inteltool/pcr.c index 6594561257..6d70905021 100644 --- a/util/inteltool/pcr.c +++ b/util/inteltool/pcr.c @@ -188,6 +188,7 @@ void pcr_init(struct pci_dev *const sb) case PCI_DEVICE_ID_INTEL_MTL_5: case PCI_DEVICE_ID_INTEL_MTL_6: case PCI_DEVICE_ID_INTEL_MTL_7: + case PCI_DEVICE_ID_INTEL_ARL_1: sbbar_phys = 0xe0000000; use_p2sb = false; break; From 6c7f734f7bceeba3f75d45a18ec9f74254687ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sun, 18 Jan 2026 17:53:45 +0100 Subject: [PATCH 265/789] util/amdfwtool: Fix a bug clearing two bits of soft fuse value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PSP soft fuse is a 64bit value which does not use address mode bits. Those address mode bits are also part of the soft fuse value, thus must not be hardcoded to 0. Change-Id: I5a3e078800653d15baf1939fdce11a60031b9978 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/90789 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- util/amdfwtool/amdfwtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c index 6c1ec632a6..af24697bca 100644 --- a/util/amdfwtool/amdfwtool.c +++ b/util/amdfwtool/amdfwtool.c @@ -1088,7 +1088,7 @@ static void integrate_psp_firmwares(context *ctx, pspdir->entries[count].rsvd = 0; pspdir->entries[count].size = 0xFFFFFFFF; pspdir->entries[count].addr = fw_table[i].other; - pspdir->entries[count].address_mode = AMD_ADDR_PHYSICAL; + pspdir->entries[count].address_mode = fw_table[i].other >> 62; count++; } else if (fw_table[i].type == AMD_FW_PSP_NVRAM || fw_table[i].type == AMD_RPMC_NVRAM) { From c9cbd45cbed1438762174d45a8341bf645fc8721 Mon Sep 17 00:00:00 2001 From: Felix Held Date: Fri, 23 Jan 2026 17:08:16 +0100 Subject: [PATCH 266/789] soc/amd/glinda,picasso/xhci: use XHCI_GEVENT define The other AMD SoCs already use the XHCI_GEVENT define and since it's defined as GEVENT_31, this won't change the behavior. Change-Id: I895f453497f6e03e1aff237ba6d6ec1ebecfaaaf Signed-off-by: Felix Held Reviewed-on: https://review.coreboot.org/c/coreboot/+/90876 Tested-by: build bot (Jenkins) Reviewed-by: Maximilian Brune --- src/soc/amd/glinda/xhci.c | 9 +++++---- src/soc/amd/picasso/xhci.c | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/soc/amd/glinda/xhci.c b/src/soc/amd/glinda/xhci.c index b67bb5a060..64eb72c8d8 100644 --- a/src/soc/amd/glinda/xhci.c +++ b/src/soc/amd/glinda/xhci.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -14,25 +15,25 @@ static const struct sci_source xhci_sci_sources[] = { { .scimap = SMITYPE_XHC0_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG }, { .scimap = SMITYPE_XHC1_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG }, { .scimap = SMITYPE_XHC3_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG }, { .scimap = SMITYPE_XHC4_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG } diff --git a/src/soc/amd/picasso/xhci.c b/src/soc/amd/picasso/xhci.c index a238916b71..1258234df4 100644 --- a/src/soc/amd/picasso/xhci.c +++ b/src/soc/amd/picasso/xhci.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -12,13 +13,13 @@ static const struct sci_source xhci_sci_sources[] = { { .scimap = SMITYPE_XHC0_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG }, { .scimap = SMITYPE_XHC1_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG } From 09b8b5a33a88fb20b4cf0b55d008d3bf718ead97 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 4 Jan 2026 12:25:20 +0100 Subject: [PATCH 267/789] mb/lenovo/*: Add CBFS_SIZE for some boards Add a default CBFS_SIZE for some boards to make sure they use the whole BIOS region by default. Change-Id: Ia032a9d5b3ba271390cc5f35ee734a1bbb1b90a4 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/90721 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Paul Menzel --- src/mainboard/lenovo/haswell/Kconfig | 3 +++ src/mainboard/lenovo/t420/Kconfig | 3 +++ src/mainboard/lenovo/t420s/Kconfig | 3 +++ src/mainboard/lenovo/t430/Kconfig | 3 +++ src/mainboard/lenovo/t430s/Kconfig | 3 +++ src/mainboard/lenovo/t520/Kconfig | 3 +++ src/mainboard/lenovo/t530/Kconfig | 3 +++ src/mainboard/lenovo/x131e/Kconfig | 3 +++ src/mainboard/lenovo/x1_carbon_gen1/Kconfig | 3 +++ src/mainboard/lenovo/x220/Kconfig | 3 +++ src/mainboard/lenovo/x230/Kconfig | 4 ++++ 11 files changed, 34 insertions(+) diff --git a/src/mainboard/lenovo/haswell/Kconfig b/src/mainboard/lenovo/haswell/Kconfig index 46da23cfd2..8803717024 100644 --- a/src/mainboard/lenovo/haswell/Kconfig +++ b/src/mainboard/lenovo/haswell/Kconfig @@ -51,6 +51,9 @@ config VARIANT_DIR config DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" +config CBFS_SIZE + default 0x700000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/t420/Kconfig b/src/mainboard/lenovo/t420/Kconfig index 1b9ddd6e4c..54d1cda106 100644 --- a/src/mainboard/lenovo/t420/Kconfig +++ b/src/mainboard/lenovo/t420/Kconfig @@ -44,6 +44,9 @@ config VBOOT config VBOOT_SLOTS_RW_A default y +config CBFS_SIZE + default 0x300000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT diff --git a/src/mainboard/lenovo/t420s/Kconfig b/src/mainboard/lenovo/t420s/Kconfig index 21bbd87431..bbfc9d0ef5 100644 --- a/src/mainboard/lenovo/t420s/Kconfig +++ b/src/mainboard/lenovo/t420s/Kconfig @@ -42,6 +42,9 @@ config VBOOT config VBOOT_SLOTS_RW_A default y +config CBFS_SIZE + default 0x300000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT diff --git a/src/mainboard/lenovo/t430/Kconfig b/src/mainboard/lenovo/t430/Kconfig index 20726edb50..fe1d5fcd7b 100644 --- a/src/mainboard/lenovo/t430/Kconfig +++ b/src/mainboard/lenovo/t430/Kconfig @@ -43,6 +43,9 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0x700000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/t430s/Kconfig b/src/mainboard/lenovo/t430s/Kconfig index 10ce88c6f1..1e80628384 100644 --- a/src/mainboard/lenovo/t430s/Kconfig +++ b/src/mainboard/lenovo/t430s/Kconfig @@ -45,6 +45,9 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0xB00000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/t520/Kconfig b/src/mainboard/lenovo/t520/Kconfig index a93c859615..ed424ed0a7 100644 --- a/src/mainboard/lenovo/t520/Kconfig +++ b/src/mainboard/lenovo/t520/Kconfig @@ -60,6 +60,9 @@ config MAINBOARD_DIR config OVERRIDE_DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" +config CBFS_SIZE + default 0x300000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT diff --git a/src/mainboard/lenovo/t530/Kconfig b/src/mainboard/lenovo/t530/Kconfig index 801e931fbd..a825e1186b 100644 --- a/src/mainboard/lenovo/t530/Kconfig +++ b/src/mainboard/lenovo/t530/Kconfig @@ -50,6 +50,9 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0x700000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/x131e/Kconfig b/src/mainboard/lenovo/x131e/Kconfig index df435e9cfb..c59660adf1 100644 --- a/src/mainboard/lenovo/x131e/Kconfig +++ b/src/mainboard/lenovo/x131e/Kconfig @@ -36,6 +36,9 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0x700000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/x1_carbon_gen1/Kconfig b/src/mainboard/lenovo/x1_carbon_gen1/Kconfig index 902b92d5d3..39daee8b0d 100644 --- a/src/mainboard/lenovo/x1_carbon_gen1/Kconfig +++ b/src/mainboard/lenovo/x1_carbon_gen1/Kconfig @@ -43,6 +43,9 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0x700000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/x220/Kconfig b/src/mainboard/lenovo/x220/Kconfig index 453afd4bef..3b4c6ce0ea 100644 --- a/src/mainboard/lenovo/x220/Kconfig +++ b/src/mainboard/lenovo/x220/Kconfig @@ -49,6 +49,9 @@ config VARIANT_DIR default "x220" if BOARD_LENOVO_X220 || BOARD_LENOVO_X220I default "x1" if BOARD_LENOVO_X1 +config CBFS_SIZE + default 0x300000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT diff --git a/src/mainboard/lenovo/x230/Kconfig b/src/mainboard/lenovo/x230/Kconfig index 81049412df..2980c91b3a 100644 --- a/src/mainboard/lenovo/x230/Kconfig +++ b/src/mainboard/lenovo/x230/Kconfig @@ -45,6 +45,10 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0x700000 if BOARD_LENOVO_X230 || BOARD_LENOVO_X230T || BOARD_LENOVO_X230_EDP + default 0xB00000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT From deeb884c8dbc639bb0e95087acea5e1d44d2e5be Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Tue, 20 Jan 2026 18:17:39 +0100 Subject: [PATCH 268/789] Makefile.mk: Remove RISC-V workaround The issue has been fixed since binutils version 2.43 Signed-off-by: Maximilian Brune Change-Id: I9d8802aa0908dd2838199399e739b13c345702f3 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90815 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- Makefile.mk | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Makefile.mk b/Makefile.mk index a823a115a4..e83a304ca6 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -614,12 +614,7 @@ LDFLAGS_common += -nostdlib LDFLAGS_common += --nmagic LDFLAGS_common += -static LDFLAGS_common += -z noexecstack - -# Workaround for RISC-V linker bug, merge back into above line when fixed. -# https://sourceware.org/bugzilla/show_bug.cgi?id=27180 -ifneq ($(CONFIG_ARCH_RISCV),y) LDFLAGS_common += --emit-relocs -endif ifeq ($(CONFIG_WARNINGS_ARE_ERRORS),y) CFLAGS_common += -Werror From 8dd881ea47e0f39e2afdbab0b8992138bb454ff3 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Sat, 29 Nov 2025 06:34:52 +0100 Subject: [PATCH 269/789] Makefile.mk: Remove "crt0" dead code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also removes some dead code below which uses a dongle.py binary. Signed-off-by: Maximilian Brune Change-Id: Ia9b31a79f7637d31bbd824a8f6ad9137df429711 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90818 Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) --- Documentation/POSTCODES | 2 +- Documentation/acronyms.md | 1 - Makefile.mk | 7 ------- src/arch/x86/Kconfig | 2 +- src/commonlib/include/commonlib/console/post_codes.h | 2 +- src/soc/amd/common/block/cpu/car/cache_as_ram.S | 2 +- src/soc/intel/common/block/cpu/car/cache_as_ram_fsp.S | 2 +- 7 files changed, 5 insertions(+), 13 deletions(-) diff --git a/Documentation/POSTCODES b/Documentation/POSTCODES index 0e67dd173c..8240375e11 100644 --- a/Documentation/POSTCODES +++ b/Documentation/POSTCODES @@ -5,7 +5,7 @@ coreboot POST Codes This is an (incomplete) list of POST codes emitted by coreboot v4. 0x10 Entry into protected mode -0x01 Entry into 'crt0.s' reset code jumps to here +0x01 Entry into 'entry16.S' reset code jumps to here 0x11 Start copying coreboot to RAM with decompression if compressed 0x12 Copy/decompression finished jumping to RAM 0x80 Entry into coreboot in RAM diff --git a/Documentation/acronyms.md b/Documentation/acronyms.md index 199a7da78c..a52d206636 100644 --- a/Documentation/acronyms.md +++ b/Documentation/acronyms.md @@ -204,7 +204,6 @@ Spec](https://uefi.org/specifications) for details, or run the tool * CRLF - Carriage Return, Line Feed - \\r\\n - The standard window EOL (End-of-Line) marker. * crt0 - [**C Run Time 0**](https://en.wikipedia.org/wiki/Crt0) -* crt0s - crt0 Source code * CRT - [**Cathode Ray Tube**](https://en.wikipedia.org/wiki/Cathode-ray_tube) * CSE - Intel: Converged Security Engine * CSI - MIPI: [**Camera Serial diff --git a/Makefile.mk b/Makefile.mk index e83a304ca6..92098ba1b7 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -822,13 +822,6 @@ clean-abuild: ####################################################################### # Development utilities -printcrt0s: - @echo crt0s=$(crt0s) - @echo ldscripts=$(ldscripts) - -update: - dongle.py -c /dev/term/1 $(obj)/coreboot.rom EOF - check-style: grep "^# DESCR:" util/lint/check-style | sed "s,.*DESCR: *,," echo "========" diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig index b58907e230..8e6babceb3 100644 --- a/src/arch/x86/Kconfig +++ b/src/arch/x86/Kconfig @@ -185,7 +185,7 @@ config BOOTBLOCK_DEBUG_SPINLOOP bool default n help - Add a spin (JMP .) in bootblock_crt0.S during early bootblock to wait + Add a spin (JMP .) in entry32.S during early bootblock to wait for a JTAG debugger to break into the execution sequence. config HAVE_CMOS_DEFAULT diff --git a/src/commonlib/include/commonlib/console/post_codes.h b/src/commonlib/include/commonlib/console/post_codes.h index d581bc487f..b0f9565e35 100644 --- a/src/commonlib/include/commonlib/console/post_codes.h +++ b/src/commonlib/include/commonlib/console/post_codes.h @@ -34,7 +34,7 @@ #define POSTCODE_CODE_CLEAR 0x00 /** - * \brief Entry into 'crt0.s'. reset code jumps to here + * \brief Entry into 'entry16.S'. reset code jumps to here * * First instruction that gets executed after the reset vector jumps. * This indicates that the reset vector points to the correct code segment. diff --git a/src/soc/amd/common/block/cpu/car/cache_as_ram.S b/src/soc/amd/common/block/cpu/car/cache_as_ram.S index 8d41826bfd..9411ad0a6f 100644 --- a/src/soc/amd/common/block/cpu/car/cache_as_ram.S +++ b/src/soc/amd/common/block/cpu/car/cache_as_ram.S @@ -3,7 +3,7 @@ /****************************************************************************** * $Workfile:: cache_as_ram.S * - * Description: CAR setup called from bootblock_crt0.S. + * Description: CAR setup called from entry32.S. * ****************************************************************************** */ diff --git a/src/soc/intel/common/block/cpu/car/cache_as_ram_fsp.S b/src/soc/intel/common/block/cpu/car/cache_as_ram_fsp.S index ed735dbce3..1e55039a3c 100644 --- a/src/soc/intel/common/block/cpu/car/cache_as_ram_fsp.S +++ b/src/soc/intel/common/block/cpu/car/cache_as_ram_fsp.S @@ -90,7 +90,7 @@ CAR_init_done: or %rsi, %rdi andl $0xfffffff0, %esp #else - /* Restore the timestamp from bootblock_crt0.S (ebp:mm1) */ + /* Restore the timestamp from entry32.S (ebp:mm1) */ push %ebp movd %mm1, %eax push %eax From aa77ddb44aa4f400d0ed17b5c3eb929ca00d7419 Mon Sep 17 00:00:00 2001 From: Chen-Tsung Hsieh Date: Fri, 23 Jan 2026 08:42:23 +0000 Subject: [PATCH 270/789] soc/mediatek/common: Combine dsi_cmdq_size register writes Combine the size calculation and the CMDQ_SIZE_SEL bit setting into a single write32 call for dsi->dsi_cmdq_size to optimize register access. BUG=b:474187570 TEST=util/abuild/abuild -x -t GOOGLE_SKYWALKER -a --clean BRANCH=skywalker Change-Id: Idd08c8fab4120878c53fb94bf0e3cddb9a7eb513 Signed-off-by: Chen-Tsung Hsieh Reviewed-on: https://review.coreboot.org/c/coreboot/+/90874 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Yu-Ping Wu --- src/soc/mediatek/common/dsi_common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/soc/mediatek/common/dsi_common.c b/src/soc/mediatek/common/dsi_common.c index b2df010a48..6f8d640845 100644 --- a/src/soc/mediatek/common/dsi_common.c +++ b/src/soc/mediatek/common/dsi_common.c @@ -421,8 +421,7 @@ static enum cb_err mtk_dsi_cmdq(enum mipi_dsi_transaction type, const u8 *data, } buffer_to_fifo32_prefix(tx_buf, prefix, prefsz, prefsz + len, &dsi->dsi_cmdq[0], 4, 4); - write32(&dsi->dsi_cmdq_size, DIV_ROUND_UP(prefsz + len, 4)); - setbits32(&dsi->dsi_cmdq_size, CMDQ_SIZE_SEL); + write32(&dsi->dsi_cmdq_size, DIV_ROUND_UP(prefsz + len, 4) | CMDQ_SIZE_SEL); } mtk_dsi_enable_and_start(is_dsi_dual_channel); From 97d9c985ce6b30b25edbabe641b2665ab2fd560d Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 23 Jan 2026 11:22:07 -0600 Subject: [PATCH 271/789] soc/intel/{mtl,ptl}/fsp_params: Program PcieRpDetectTimeoutMs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This UPD is programmed for ADL, but not MTL and PTL. Add it to the latter two so it functions as expected when set in devicetree for a given PCIe root port. TEST=build/boot Starlabs Starfighter MTL, verify Samsung NVMe drive reliably detected in PCH-attached socket when timeout increased. Change-Id: Iea744fed987d413c6487559005d668329a05fff4 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90877 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes Reviewed-by: Subrata Banik Reviewed-by: Jérémy Compostella --- src/soc/intel/meteorlake/fsp_params.c | 1 + src/soc/intel/pantherlake/fsp_params.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/soc/intel/meteorlake/fsp_params.c b/src/soc/intel/meteorlake/fsp_params.c index 61be03ad47..5e7bdc53ab 100644 --- a/src/soc/intel/meteorlake/fsp_params.c +++ b/src/soc/intel/meteorlake/fsp_params.c @@ -641,6 +641,7 @@ static void fill_fsps_pcie_params(FSP_S_CONFIG *s_cfg, s_cfg->PcieRpHotPlug[i] = !!(rp_cfg->flags & PCIE_RP_HOTPLUG) || CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); s_cfg->PcieRpClkReqDetect[i] = !!(rp_cfg->flags & PCIE_RP_CLK_REQ_DETECT); + s_cfg->PcieRpDetectTimeoutMs[i] = rp_cfg->pcie_rp_detect_timeout_ms; configure_pch_rp_power_management(s_cfg, rp_cfg, i); } s_cfg->PcieComplianceTestMode = CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); diff --git a/src/soc/intel/pantherlake/fsp_params.c b/src/soc/intel/pantherlake/fsp_params.c index 0133e72c00..2fbcbea5b9 100644 --- a/src/soc/intel/pantherlake/fsp_params.c +++ b/src/soc/intel/pantherlake/fsp_params.c @@ -639,6 +639,7 @@ static void fill_fsps_pcie_params(FSP_S_CONFIG *s_cfg, s_cfg->PcieRpHotPlug[i] = !!(rp_cfg->flags & PCIE_RP_HOTPLUG) || CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); s_cfg->PcieRpClkReqDetect[i] = !!(rp_cfg->flags & PCIE_RP_CLK_REQ_DETECT); + s_cfg->PcieRpDetectTimeoutMs[i] = rp_cfg->pcie_rp_detect_timeout_ms; if (rp_cfg->pcie_rp_aspm) s_cfg->PcieRpAspm[i] = get_aspm_control(rp_cfg->pcie_rp_aspm); } From 673ce1845e7b78fb21bdfbaac73fca306bff3c68 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 11 Jan 2026 09:44:29 +0100 Subject: [PATCH 272/789] ec/lenovo/h8: Cache EC version string When APM_CNT_ACPI_DISABLE is issued during LPC init it will enable SMI's when the EC asserts the GPE_EC_SCI GPIO, looking like: [NOTE ] coreboot-25.12 x86_64 smm starting (log level: 6)... [DEBUG] GPI (mask 0002) This happens on all ec_read() calls whenever bits in the status register change, causing lots of unnecessary SMIs at boot. Cache the EC version string when it's first read and use the cached version when writing SMBIOS tables. While on it introduce defines for registers and drop function from global scope. TEST=Seen less SMIs during boot. Version string is still correctly shown in dmidecode. Change-Id: I514c628947c4e14f2379f7e2f265f28a9c7086d6 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/90722 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Paul Menzel --- src/ec/lenovo/h8/h8.c | 56 +++++++++++++++++++++++-------------------- src/ec/lenovo/h8/h8.h | 9 ++++++- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c index acf5ce5408..564ba85b89 100644 --- a/src/ec/lenovo/h8/h8.c +++ b/src/ec/lenovo/h8/h8.c @@ -81,6 +81,34 @@ static void f1_to_f12_as_primary(int on) ec_clr_bit(0x3b, 3); } +static u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len) +{ + static char str[16 + 1]; /* 16 ASCII chars + \0 */ + u8 i, c; + + if (!str[0]) { + /* Build ID */ + for (i = 0; i < 8; i++) { + c = ec_read(H8_EC_BUILD_ID + i); + if (c < 0x20 || c > 0x7f) { + i = snprintf(str, sizeof(str), "*INVALID"); + break; + } + str[i] = c; + } + + /* Lenovo EC firmware function specification version */ + i += snprintf(str + i, sizeof(str) - i, "-%u.%u", + ec_read(H8_EC_FUNC_MAJOR_VER), ec_read(H8_EC_FUNC_MINOR_VER)); + } else + i = strlen(str); + + i = MIN(buf_len, i); + memcpy(buf, str, i); + + return i; +} + static void h8_log_ec_version(void) { char ecfw[17]; @@ -90,8 +118,8 @@ static void h8_log_ec_version(void) len = h8_build_id_and_function_spec_version(ecfw, sizeof(ecfw) - 1); ecfw[len] = 0; - fwvh = ec_read(0xe9); - fwvl = ec_read(0xe8); + fwvh = ec_read(H8_EC_FIRMWARE_MAJOR_VER); + fwvl = ec_read(H8_EC_FIRMWARE_MINOR_VER); printk(BIOS_INFO, "H8: EC Firmware ID %s, Version %d.%d%d%c\n", ecfw, fwvh >> 4, fwvh & 0x0f, fwvl >> 4, 0x41 + (fwvl & 0xf)); @@ -162,30 +190,6 @@ int h8_ultrabay_device_present(void) return ec_read(H8_STATUS1) & 0x5 ? 0 : 1; } -u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len) -{ - u8 i, c; - char str[16 + 1]; /* 16 ASCII chars + \0 */ - - /* Build ID */ - for (i = 0; i < 8; i++) { - c = ec_read(0xf0 + i); - if (c < 0x20 || c > 0x7f) { - i = snprintf(str, sizeof(str), "*INVALID"); - break; - } - str[i] = c; - } - - /* EC firmware function specification version */ - i += snprintf(str + i, sizeof(str) - i, "-%u.%u", ec_read(0xef), ec_read(0xeb)); - - i = MIN(buf_len, i); - memcpy(buf, str, i); - - return i; -} - #if CONFIG(GENERATE_SMBIOS_TABLES) static void h8_smbios_strings(struct device *dev, struct smbios_type11 *t) { diff --git a/src/ec/lenovo/h8/h8.h b/src/ec/lenovo/h8/h8.h index 40816117b1..88d7b07136 100644 --- a/src/ec/lenovo/h8/h8.h +++ b/src/ec/lenovo/h8/h8.h @@ -20,7 +20,6 @@ void h8_usb_power_enable(int on); void h8_enable_event(int event); void h8_disable_event(int event); int h8_ultrabay_device_present(void); -u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len); void h8_usb_always_on(void); int h8_get_fn_key(void); @@ -141,4 +140,12 @@ void h8_mb_init(void); #define H8_EVENT_FN_F5 0x64 #define H8_EVENT_FN_F6 0x65 +#define H8_EC_FIRMWARE_MINOR_VER 0xe8 +#define H8_EC_FIRMWARE_MAJOR_VER 0xe9 + +#define H8_EC_FUNC_MINOR_VER 0xeb +#define H8_EC_FUNC_MAJOR_VER 0xef + +#define H8_EC_BUILD_ID 0xf0 + #endif /* EC_LENOVO_H8_H */ From e98bc0e02ab2f4f2a5189090536e46c544b0bb5e Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 11 Jan 2026 11:37:06 +0100 Subject: [PATCH 273/789] ec/lenovo/h8: Properly advertised used I/O Properly advertise I/O ports decoded by H8 and PMH7. Therefore implement read_resources() and set_resources() in coreboot and advertise the ports using ACPI. TEST=I/O ports are properly seen as fixed and assigned in coreboot and the OS. Change-Id: Iae1b72d2d565750020f2943804165b9d5d2efdfb Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/90723 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/ec/lenovo/h8/acpi/ec.asl | 49 ++++++++++++++++++++++++++++++++++++ src/ec/lenovo/h8/h8.c | 11 ++++++++ src/ec/lenovo/pmh7/pmh7.c | 21 ++++++++++------ src/ec/lenovo/pmh7/pmh7.h | 2 -- 4 files changed, 74 insertions(+), 9 deletions(-) diff --git a/src/ec/lenovo/h8/acpi/ec.asl b/src/ec/lenovo/h8/acpi/ec.asl index bc54d3b422..fe39c19761 100644 --- a/src/ec/lenovo/h8/acpi/ec.asl +++ b/src/ec/lenovo/h8/acpi/ec.asl @@ -335,3 +335,52 @@ Device(EC) #include "systemstatus.asl" #include "thinkpad.asl" } + +#if CONFIG(EC_LENOVO_H8) +// EC SMM interface +Device(ECMM) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 10) + + Name (_CRS, ResourceTemplate() { + IO (Decode16, 0x1600, 0x1600, 1, 1) + IO (Decode16, 0x1604, 0x1604, 1, 1) + }) +} + +// EC Gravity sensor interface +Device(ECGS) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 11) + + Name (_CRS, ResourceTemplate() { + IO (Decode16, 0x1602, 0x1602, 1, 1) + IO (Decode16, 0x1606, 0x1606, 1, 1) + }) +} + +// Battery two wire interface +Device(TWRI) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 12) + + Name (_CRS, ResourceTemplate() { + IO (Decode16, 0x1610, 0x1610, 16, 16) + }) +} +#endif + +#if CONFIG(EC_LENOVO_PMH7) +Device(PMH7) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 13) + + Name (_CRS, ResourceTemplate() { + IO (Decode16, 0x15e0, 0x15e0, 16, 16) + }) +} +#endif diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c index 564ba85b89..1ea3ccfa40 100644 --- a/src/ec/lenovo/h8/h8.c +++ b/src/ec/lenovo/h8/h8.c @@ -213,6 +213,15 @@ static const char *h8_acpi_name(const struct device *dev) } #endif +static void h8_read_resources(struct device *dev) +{ + static const u16 ports[] = {0x60, 0x64, 0x62, 0x66, 0x1600, 0x1604, 0x1602, 0x1606}; + for (int i = 0; i < ARRAY_SIZE(ports); i++) + fixed_io_range_flags(dev, ports[i], ports[i], 1, IORESOURCE_ASSIGNED); + + fixed_io_range_flags(dev, 0x1610, 0x1610, 16, IORESOURCE_ASSIGNED); +} + struct device_operations h8_dev_ops = { #if CONFIG(GENERATE_SMBIOS_TABLES) .get_smbios_strings = h8_smbios_strings, @@ -221,6 +230,8 @@ struct device_operations h8_dev_ops = { .acpi_fill_ssdt = h8_ssdt_generator, .acpi_name = h8_acpi_name, #endif + .read_resources = h8_read_resources, + .set_resources = noop_set_resources, .init = h8_init, }; diff --git a/src/ec/lenovo/pmh7/pmh7.c b/src/ec/lenovo/pmh7/pmh7.c index 95502f3d88..00d34edb56 100644 --- a/src/ec/lenovo/pmh7/pmh7.c +++ b/src/ec/lenovo/pmh7/pmh7.c @@ -101,17 +101,23 @@ void pmh7_register_write(int reg, int val) outb(val, EC_LENOVO_PMH7_DATA); } +#if ENV_RAMSTAGE +static void pmh7_read_resources(struct device *dev) +{ + fixed_io_range_flags(dev, EC_LENOVO_PMH7_BASE, EC_LENOVO_PMH7_BASE, + 16, IORESOURCE_ASSIGNED); +} + +struct device_operations pmh7_dev_ops = { + .read_resources = pmh7_read_resources, + .set_resources = noop_set_resources, +}; + static void enable_dev(struct device *dev) { const struct ec_lenovo_pmh7_config *conf = dev->chip_info; - struct resource *resource; - resource = new_resource(dev, EC_LENOVO_PMH7_INDEX); - resource->base = EC_LENOVO_PMH7_BASE; - resource->size = 16; - resource->align = 5; - resource->gran = 5; - resource->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_ASSIGNED; + dev->ops = &pmh7_dev_ops; pmh7_backlight_enable(conf->backlight_enable); pmh7_dock_event_enable(conf->dock_event_enable); @@ -129,3 +135,4 @@ struct chip_operations ec_lenovo_pmh7_ops = { .name = "Lenovo Power Management Hardware Hub 7", .enable_dev = enable_dev, }; +#endif diff --git a/src/ec/lenovo/pmh7/pmh7.h b/src/ec/lenovo/pmh7/pmh7.h index 61dc1137d3..b06e79920d 100644 --- a/src/ec/lenovo/pmh7/pmh7.h +++ b/src/ec/lenovo/pmh7/pmh7.h @@ -5,8 +5,6 @@ #include -#define EC_LENOVO_PMH7_INDEX 0x77 - #define EC_LENOVO_PMH7_BASE 0x15e0 #define EC_LENOVO_PMH7_ADDR_L (EC_LENOVO_PMH7_BASE + 0x0c) #define EC_LENOVO_PMH7_ADDR_H (EC_LENOVO_PMH7_BASE + 0x0d) From bb299bb530f1bd01e346f6ba6cd6f59b2bacb7cc Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 23 Jan 2026 12:20:11 -0600 Subject: [PATCH 274/789] mb/starlabs/starfighter/mtl: Add detection delay to PCH-attached SSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some SSDs connected to the PCH-attached PCIe root port/m.2 socket need a small delay in order to be reliably detected. Add a 15ms delay (the default is 0) to ensure this. TEST=build/boot Starfighter MTL 125H/285H with Samsung 970 EVO plus, WD SN720, and Intel Optane P1600x SSDs in outer SSD socket. Ensure all drives detected and bootable after both cold and warm resets. Change-Id: I16ec0a313fc7cccb2807593c07db04cdbb59c979 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90880 Reviewed-by: Paul Menzel Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb b/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb index f83df3e27a..23ad639cc2 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb +++ b/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb @@ -241,6 +241,7 @@ chip soc/intel/meteorlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, + .pcie_rp_detect_timeout_ms = 15, }" smbios_slot_desc "SlotTypeM2Socket3" From 76149f25c64175dfa397e45e7541f1acbd9c6b2d Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Sat, 29 Nov 2025 00:05:03 +0100 Subject: [PATCH 275/789] treewide: Rename FMAP_ROM_SIZE -> FMAP_FLASH_SIZE Its actually the size FMAP flash region so the name is more appropriate. Signed-off-by: Maximilian Brune Change-Id: I152b66abedb68f1ab809d918502efe096e9dde59 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90811 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- Makefile.mk | 6 +++--- util/cbfstool/default-x86.fmd | 4 ++-- util/cbfstool/default.fmd | 4 ++-- util/ifdtool/ifdtool.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.mk b/Makefile.mk index 92098ba1b7..e2b49b36fe 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -1099,7 +1099,7 @@ endif # ifeq($(CONFIG_HAVE_IFD_BIN),y) endif # ifneq($(CONFIG_IFD_CHIPSET),) # entire flash -FMAP_ROM_SIZE := $(CONFIG_ROM_SIZE) +FMAP_FLASH_SIZE := $(CONFIG_ROM_SIZE) # entire "BIOS" region (everything directly of concern to the host system) FMAP_BIOS_BASE := $(call int-align, $(call int-subtract, $(CONFIG_ROM_SIZE) $(CONFIG_CBFS_SIZE)), 0x10000) FMAP_BIOS_SIZE := $(call int-align-down, $(shell echo $(CONFIG_CBFS_SIZE) | tr A-F a-f), 0x10000) @@ -1186,7 +1186,7 @@ else # ifeq ($(CONFIG_ARCH_X86),y) DEFAULT_FLASHMAP:=$(top)/util/cbfstool/default.fmd # entire flash -FMAP_ROM_SIZE := $(CONFIG_ROM_SIZE) +FMAP_FLASH_SIZE := $(CONFIG_ROM_SIZE) # entire "BIOS" region (everything directly of concern to the host system) FMAP_BIOS_BASE := 0 FMAP_BIOS_SIZE := $(CONFIG_CBFS_SIZE) @@ -1232,7 +1232,7 @@ FMAP_CBFS_SIZE := $(call int-subtract,$(FMAP_BIOS_SIZE) $(FMAP_CBFS_BASE)) endif # ifeq ($(CONFIG_ARCH_X86),y) $(obj)/fmap.fmd: $(top)/Makefile.mk $(DEFAULT_FLASHMAP) $(obj)/config.h - sed -e "s,##ROM_SIZE##,$(call _tohex,$(FMAP_ROM_SIZE))," \ + sed -e "s,##FLASH_SIZE##,$(call _tohex,$(FMAP_FLASH_SIZE))," \ -e "s,##BIOS_BASE##,$(call _tohex,$(FMAP_BIOS_BASE))," \ -e "s,##BIOS_SIZE##,$(call _tohex,$(FMAP_BIOS_SIZE))," \ -e "s,##FMAP_BASE##,$(call _tohex,$(FMAP_FMAP_BASE))," \ diff --git a/util/cbfstool/default-x86.fmd b/util/cbfstool/default-x86.fmd index 795e025f9f..d0e17b194e 100644 --- a/util/cbfstool/default-x86.fmd +++ b/util/cbfstool/default-x86.fmd @@ -1,5 +1,5 @@ # layout for firmware residing at top of 4GB address space -# +-------------+ <-- 4GB - ROM_SIZE / start of flash +# +-------------+ <-- 4GB - FLASH_SIZE / start of flash # | unspecified | # +-------------+ <-- 4GB - BIOS_SIZE # | FMAP | @@ -7,7 +7,7 @@ # | CBFS | # +-------------+ <-- 4GB / end of flash -FLASH ##ROM_SIZE## { +FLASH ##FLASH_SIZE## { BIOS@##BIOS_BASE## ##BIOS_SIZE## { ##CONSOLE_ENTRY## ##MRC_CACHE_ENTRY## diff --git a/util/cbfstool/default.fmd b/util/cbfstool/default.fmd index d20789f404..97cf441445 100644 --- a/util/cbfstool/default.fmd +++ b/util/cbfstool/default.fmd @@ -7,9 +7,9 @@ # | FMAP | # +-------------+ <-- BIOS_BASE + 128K + FMAP_SIZE # | CBFS | -# +-------------+ <-- ROM_SIZE +# +-------------+ <-- FLASH_SIZE -FLASH ##ROM_SIZE## { +FLASH ##FLASH_SIZE## { BIOS@##BIOS_BASE## ##BIOS_SIZE## { BOOTBLOCK 128K FMAP@##FMAP_BASE## ##FMAP_SIZE## diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c index 75238c73b2..0592785bf6 100644 --- a/util/ifdtool/ifdtool.c +++ b/util/ifdtool/ifdtool.c @@ -1094,7 +1094,7 @@ static void create_fmap_template(char *image, int size, const char *layout_fname exit(EXIT_FAILURE); } - char *bbuf = "FLASH ##ROM_SIZE## {\n"; + char *bbuf = "FLASH ##FLASH_SIZE## {\n"; if (write(layout_fd, bbuf, strlen(bbuf)) < 0) { perror("Could not write to file"); exit(EXIT_FAILURE); From 5cae481856dd9c89eeecc6ff4cb6157dad84f6a5 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Sat, 29 Nov 2025 00:13:26 +0100 Subject: [PATCH 276/789] Makefile.mk: Use same FMAP_FLASH_SIZE for all architectures For both x86 and non-x86 its the same anyway, so factor it out. Signed-off-by: Maximilian Brune Change-Id: I30e6d1da8a663cd79d59d55446eda2b70269f118 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90812 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- Makefile.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile.mk b/Makefile.mk index e2b49b36fe..14f9b835d7 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -1085,6 +1085,8 @@ prebuild-files = $(foreach region,$(all-regions), \ # If no FMD file (Flashmap) is supplied by mainboard, fall back to a default ifeq ($(CONFIG_FMDFILE),) +FMAP_FLASH_SIZE := $(CONFIG_ROM_SIZE) + ifeq ($(CONFIG_ARCH_X86),y) DEFAULT_FLASHMAP:=$(top)/util/cbfstool/default-x86.fmd @@ -1098,8 +1100,6 @@ $(DEFAULT_FLASHMAP): $(call strip_quotes,$(CONFIG_IFD_BIN_PATH)) $(IFDTOOL) endif # ifeq($(CONFIG_HAVE_IFD_BIN),y) endif # ifneq($(CONFIG_IFD_CHIPSET),) -# entire flash -FMAP_FLASH_SIZE := $(CONFIG_ROM_SIZE) # entire "BIOS" region (everything directly of concern to the host system) FMAP_BIOS_BASE := $(call int-align, $(call int-subtract, $(CONFIG_ROM_SIZE) $(CONFIG_CBFS_SIZE)), 0x10000) FMAP_BIOS_SIZE := $(call int-align-down, $(shell echo $(CONFIG_CBFS_SIZE) | tr A-F a-f), 0x10000) @@ -1186,7 +1186,6 @@ else # ifeq ($(CONFIG_ARCH_X86),y) DEFAULT_FLASHMAP:=$(top)/util/cbfstool/default.fmd # entire flash -FMAP_FLASH_SIZE := $(CONFIG_ROM_SIZE) # entire "BIOS" region (everything directly of concern to the host system) FMAP_BIOS_BASE := 0 FMAP_BIOS_SIZE := $(CONFIG_CBFS_SIZE) From 23410a873a323fd0ca6a804fa555d05abf3087e6 Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Fri, 23 Jan 2026 15:29:48 +0800 Subject: [PATCH 277/789] assert.h: Remove printk dependency for ENV_TEST With the current implementation of assert() for ENV_TEST, the printk() function must be linked. As we are already using cmocka's mock_assert() implementation for unit tests, those printk() calls within assert-related macros should be changed to no-ops. Also, disable __build_time_assert() for ENV_TEST. Change-Id: Ia9bea29a32362d68dff89bb7bbf417126ac31fb7 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90870 Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) --- src/include/assert.h | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/include/assert.h b/src/include/assert.h index 0e09eef392..19d041010f 100644 --- a/src/include/assert.h +++ b/src/include/assert.h @@ -22,7 +22,7 @@ #define __ASSERT_LINE__ __LINE__ #endif -#ifndef _PORTING_H_ /* TODO: Isolate AGESA properly. */ +#if !ENV_TEST && !defined(_PORTING_H_) /* TODO: Isolate AGESA properly. */ #define __build_time_assert(x) \ (__builtin_constant_p(x) ? ((x) ? 1 : dead_code_t(int)) : 0) #else @@ -34,11 +34,13 @@ void mock_assert(const int result, const char *const expression, const char *const file, const int line); #if ENV_TEST -#define MOCK_ASSERT(result, expression) \ +#define _ASSERT_MSG(...) +#define _MOCK_ASSERT(result, expression) \ mock_assert((result), (expression), __ASSERT_FILE__, __ASSERT_LINE__) -#else -#define MOCK_ASSERT(result, expression) -#endif +#else /* ENV_TEST */ +#define _ASSERT_MSG(...) printk(BIOS_EMERG, __VA_ARGS__) +#define _MOCK_ASSERT(result, expression) +#endif /* ENV_TEST */ /* * assert() should be used to test stuff that the programmer *knows* to be true. @@ -54,30 +56,30 @@ void mock_assert(const int result, const char *const expression, */ #define ASSERT(x) { \ if (!__build_time_assert(x) && !(x)) { \ - printk(BIOS_EMERG, \ + _ASSERT_MSG( \ "ASSERTION ERROR: file '%s', line %d\n", \ __ASSERT_FILE__, __ASSERT_LINE__); \ - MOCK_ASSERT(!!(x), #x); \ + _MOCK_ASSERT(!!(x), #x); \ if (CONFIG(FATAL_ASSERTS)) \ hlt(); \ } \ } #define ASSERT_MSG(x, msg) { \ if (!__build_time_assert(x) && !(x)) { \ - printk(BIOS_EMERG, \ + _ASSERT_MSG( \ "ASSERTION ERROR: file '%s', line %d\n", \ __ASSERT_FILE__, __ASSERT_LINE__); \ - printk(BIOS_EMERG, "%s", msg); \ - MOCK_ASSERT(!!(x), (msg)); \ + _ASSERT_MSG("%s", msg); \ + _MOCK_ASSERT(!!(x), (msg)); \ if (CONFIG(FATAL_ASSERTS)) \ hlt(); \ } \ } #define BUG() { \ - printk(BIOS_EMERG, \ + _ASSERT_MSG( \ "ERROR: BUG ENCOUNTERED at file '%s', line %d\n", \ __ASSERT_FILE__, __ASSERT_LINE__); \ - MOCK_ASSERT(0, "BUG ENCOUNTERED"); \ + _MOCK_ASSERT(0, "BUG ENCOUNTERED"); \ if (CONFIG(FATAL_ASSERTS)) \ hlt(); \ } From 54e7b5734f915860e55a1e6240986261b29e84e6 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Sun, 25 Jan 2026 07:52:55 +0000 Subject: [PATCH 278/789] soc/qualcomm/x1p42100: Add 75MHz configuration for QSPI core Add a new frequency entry to the QSPI core clock configuration table to support 75MHz (75 * 4 = 300MHz). This is achieved by using the GPLL0 600MHz source with a divisor of 2. Providing a 300MHz core clock allows for more granular control over the physical bus speed (SCK). Specifically, it enables a stable 75MHz SPI bus frequency via a clean 1/4 divider, which is an optimization target for improving boot times on Bluey/Quenbi platforms. BUG=b:478226455 TEST=Verified that 'clock_configure_qspi' can correctly look up and set the 300MHz frequency in romstage. Change-Id: I5320a68ff50a0d79daa2fc855b18b0f3ae819bbe Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90886 Reviewed-by: Kapil Porwal Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Derek Huang --- src/soc/qualcomm/x1p42100/clock.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/soc/qualcomm/x1p42100/clock.c b/src/soc/qualcomm/x1p42100/clock.c index c2566c5d5b..eba4987217 100644 --- a/src/soc/qualcomm/x1p42100/clock.c +++ b/src/soc/qualcomm/x1p42100/clock.c @@ -28,6 +28,11 @@ static struct clock_freq_config qspi_core_cfg[] = { .src = SRC_GPLL0_MAIN_600MHZ, .div = QCOM_CLOCK_DIV(3), }, + { + .hz = 300 * MHz, + .src = SRC_GPLL0_MAIN_600MHZ, + .div = QCOM_CLOCK_DIV(2), + }, { .hz = 400 * MHz, .src = SRC_GPLL0_MAIN_600MHZ, From c31c194228f5370f91825d7beef6878ddd1dae99 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Sun, 25 Jan 2026 07:54:41 +0000 Subject: [PATCH 279/789] soc/qualcomm/x1p42100: Increase SPI bus frequency to 75MHz Boost the SPI bus clock frequency from 50MHz to 75MHz in the bootblock early initialization. This increase reduces the latency for loading subsequent stages (romstage/ramstage) from the SPI flash. Since the QSPI core can now be configured to 300MHz, this 75MHz bus speed maintains a stable 1:4 integer divider ratio, ensuring optimal signal integrity and timing margins for the flash interface. BUG=b:478226455 TEST=Verified successful boot on Bluey. Observed a reduction (10ms) in 'read SPI' duration in the console logs and confirmed that the vboot hash verification passes consistently. Change-Id: Idea0dbdd435cbbfe22a756d2b94b1cdfa3c70ffe Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90887 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Kapil Porwal Reviewed-by: Derek Huang --- src/soc/qualcomm/x1p42100/bootblock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/qualcomm/x1p42100/bootblock.c b/src/soc/qualcomm/x1p42100/bootblock.c index d106912de7..44641397d2 100644 --- a/src/soc/qualcomm/x1p42100/bootblock.c +++ b/src/soc/qualcomm/x1p42100/bootblock.c @@ -5,7 +5,7 @@ #include #include -#define SPI_BUS_CLOCK_FREQ (50 * MHz) +#define SPI_BUS_CLOCK_FREQ (75 * MHz) void bootblock_soc_early_init(void) { From 4fa14338efa95c25d83176fd6afaef1c42d22d41 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Sun, 25 Jan 2026 07:55:47 +0000 Subject: [PATCH 280/789] soc/qualcomm/x1p42100: Align and expand DMA and stack regions Fix the 4K alignment for PRERAM_DMA_COHERENT and adjust the post-RAM memory layout to ensure page-aligned boundaries. - Shift PRERAM_DMA_COHERENT from 0x14857000 to 0x14858000. This 4K alignment is required for the MMU to correctly apply uncached attributes without overlapping adjacent regions. - Increase POSTRAM_STACK from 16K to 32K to provide more headroom for complex ramstage operations. - Shift and expand POSTRAM_DMA_COHERENT to 0x8000C000 (16K). This ensures the coherent region starts on a 4K boundary after the expanded stack, preventing cache coherency issues. This alignment fix resolves intermittent SPI DMA failures and hash mismatches observed when the DMA engine was handed unaligned buffer addresses. BUG=b:477842629 TEST=Verified successful boot on Bluey; confirmed SPI read stability and vboot verification pass. Change-Id: Ic5f813e4722d732c122186897abf845e4060db37 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90888 Reviewed-by: Derek Huang Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/soc/qualcomm/x1p42100/memlayout.ld | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/soc/qualcomm/x1p42100/memlayout.ld b/src/soc/qualcomm/x1p42100/memlayout.ld index 1c2865a5c8..c3d79b8890 100644 --- a/src/soc/qualcomm/x1p42100/memlayout.ld +++ b/src/soc/qualcomm/x1p42100/memlayout.ld @@ -215,7 +215,7 @@ SECTIONS TTB(0x14842000, 56K) PRERAM_STACK(0x14850000, 16K) VBOOT2_WORK(0x14854000, 12K) - PRERAM_DMA_COHERENT(0x14857000, 8K) + PRERAM_DMA_COHERENT(0x14858000, 8K) REGION(qclib_serial_log, 0x1485B000, 4K, 4K) CBFS_MCACHE(0x1485C000,16K) FMAP_CACHE(0x14860400, 2K) @@ -236,8 +236,8 @@ SECTIONS REGION(shrm, 0x24040000, 128K , 4K) DRAM_START(0x80000000) - POSTRAM_STACK(0x80000000, 16K) - POSTRAM_DMA_COHERENT(0x80004000, 8K) + POSTRAM_STACK(0x80000000, 32K) + POSTRAM_DMA_COHERENT(0x8000C000, 16K) REGION(dram_ncc, 0x80A00000, 0x400000, 4K) REGION(dram_cpucp, 0x80E00000, 0x7A0000, 4K) From c4be70f6ff5379bcaeb7f0d2f17b140c70fc12cf Mon Sep 17 00:00:00 2001 From: Yu-Ping Wu Date: Fri, 9 Jan 2026 16:58:14 +0800 Subject: [PATCH 281/789] commonlib/list: Support circular list In some use cases, we want to add items to the linked list and then iterate over them with the insertion order. With the current API, the call site needs to either use the inefficient list_append() function to append items to the end of the list, or manually maintain a "tail" node pointer. To support that use case and make the change backward compatible, add a helper list_init() function to initialize the list as a circular linked list. list_init() is automatically called within list_insert_after() and list_append(). In list_insert_before(), an assertion is added to avoid an insertion before the head node (which should be invalid). The implementation ensures that the list is initialized as a circular one whenever the first element is added. That also allows all call sites to be auto-upgraded to the "circular list" implementation without any modification. Modify list_for_each() to support circular lists, and improve list_append() efficiency by inserting the new node before the placeholder head node. Also add a few assertions in the implementation. Add a new test case to test iterating over an empty list. Note that '(uintptr_t)ptr + (uintptr_t)offsetof(typeof(*(ptr)), member)' was used instead of the simpler '&((ptr)->member)' because GCC9+ assumes that the address can never be NULL. See commit 88991caf00d3 ("include/list.h: Add support for GCC9+) for details. Now, with the new list_for_each() implementation, that pointer value can never be NULL. Change-Id: I8451f711d4e522e239c241b3943e00070896dec9 Signed-off-by: Yu-Ping Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/90799 Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) --- src/commonlib/include/commonlib/list.h | 21 ++++++-- src/commonlib/list.c | 24 +++++++-- tests/commonlib/list-test.c | 70 ++++++++++++++++++-------- 3 files changed, 84 insertions(+), 31 deletions(-) diff --git a/src/commonlib/include/commonlib/list.h b/src/commonlib/include/commonlib/list.h index 970d68ea49..7cd3460f8a 100644 --- a/src/commonlib/include/commonlib/list.h +++ b/src/commonlib/include/commonlib/list.h @@ -17,14 +17,25 @@ void list_remove(struct list_node *node); // Insert list_node node after list_node after in a doubly linked list. void list_insert_after(struct list_node *node, struct list_node *after); // Insert list_node node before list_node before in a doubly linked list. +// `before` must not be the placeholder head node. void list_insert_before(struct list_node *node, struct list_node *before); -// Appends the node to the end of the list. +// Append the node to the end of the list. void list_append(struct list_node *node, struct list_node *head); -#define list_for_each(ptr, head, member) \ - for ((ptr) = container_of((head).next, typeof(*(ptr)), member); \ - (uintptr_t)ptr + (uintptr_t)offsetof(typeof(*(ptr)), member); \ - (ptr) = container_of((ptr)->member.next, \ +/* + * Explanation of `ptr` initialization: + * 1. head.next != NULL: This means the list isn't empty. As the implementation ensures that + * list_init() is called when the very first element is added, we can safely assume that + * the list is circular, and hence set `ptr` to the 1st element. + * 2. head.next == NULL: This means the list is empty, and list_init() hasn't been called. + * As the `head` arg might be const, we cannot simply call list_init() here. Instead, we set + * `ptr` to a special value such that `&(ptr->member) == &head`, causing the loop to + * terminate immediately. + */ +#define list_for_each(ptr, head, member) \ + for ((ptr) = container_of((head).next ?: &(head), typeof(*(ptr)), member); \ + (&((ptr)->member) != &(head)); \ + (ptr) = container_of((ptr)->member.next, \ typeof(*(ptr)), member)) #endif /* __COMMONLIB_LIST_H__ */ diff --git a/src/commonlib/list.c b/src/commonlib/list.c index b1030c8263..9cbb554b41 100644 --- a/src/commonlib/list.c +++ b/src/commonlib/list.c @@ -1,10 +1,22 @@ /* Taken from depthcharge: src/base/list.c */ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include #include +// Initialize a circular list, with `head` being a placeholder head node. +static void list_init(struct list_node *head) +{ + if (!head->next) { + assert(!head->prev); + head->next = head->prev = head; + } +} + void list_remove(struct list_node *node) { + /* Cannot remove the head node. */ + assert(node->prev && node->next); if (node->prev) node->prev->next = node->next; if (node->next) @@ -13,6 +25,9 @@ void list_remove(struct list_node *node) void list_insert_after(struct list_node *node, struct list_node *after) { + /* Check uninitialized head node. */ + if (after->prev == NULL) + list_init(after); node->next = after->next; node->prev = after; after->next = node; @@ -22,6 +37,8 @@ void list_insert_after(struct list_node *node, struct list_node *after) void list_insert_before(struct list_node *node, struct list_node *before) { + /* `before` cannot be an uninitialized head node. */ + assert(before->prev) node->prev = before->prev; node->next = before; before->prev = node; @@ -31,8 +48,7 @@ void list_insert_before(struct list_node *node, struct list_node *before) void list_append(struct list_node *node, struct list_node *head) { - while (head->next) - head = head->next; - - list_insert_after(node, head); + list_init(head); + /* With a circular list, we just need to insert before the head. */ + list_insert_before(node, head); } diff --git a/tests/commonlib/list-test.c b/tests/commonlib/list-test.c index 4ca48a468f..eeeeded059 100644 --- a/tests/commonlib/list-test.c +++ b/tests/commonlib/list-test.c @@ -1,9 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include +#include #include #include -#include +#include +#include struct test_container { int value; @@ -11,10 +12,20 @@ struct test_container { struct list_node list_node; }; -void test_list_insert_after(void **state) +static void test_list_empty(void **state) +{ + struct list_node head = {}; + struct test_container *node; + + list_for_each(node, head, list_node) { + assert_true(false); + } +} + +static void test_list_insert_after(void **state) { int i = 0; - struct list_node root = { .prev = NULL, .next = NULL }; + struct list_node head = {}; struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1)); struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2)); struct test_container *c3 = (struct test_container *)malloc(sizeof(*c2)); @@ -29,11 +40,11 @@ void test_list_insert_after(void **state) c2->value = values[1]; c3->value = values[2]; - list_insert_after(&c1->list_node, &root); + list_insert_after(&c1->list_node, &head); list_insert_after(&c2->list_node, &c1->list_node); list_insert_after(&c3->list_node, &c2->list_node); - list_for_each(ptr, root, list_node) { + list_for_each(ptr, head, list_node) { assert_int_equal(values[i], ptr->value); i++; } @@ -45,10 +56,10 @@ void test_list_insert_after(void **state) free(c1); } -void test_list_insert_before(void **state) +static void test_list_insert_before(void **state) { int i = 0; - struct list_node root = { .prev = NULL, .next = NULL }; + struct list_node head = {}; struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1)); struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2)); struct test_container *c3 = (struct test_container *)malloc(sizeof(*c2)); @@ -63,12 +74,11 @@ void test_list_insert_before(void **state) c2->value = values[1]; c3->value = values[2]; - list_insert_after(&c3->list_node, &root); + list_insert_after(&c3->list_node, &head); list_insert_before(&c2->list_node, &c3->list_node); list_insert_before(&c1->list_node, &c2->list_node); - - list_for_each(ptr, root, list_node) { + list_for_each(ptr, head, list_node) { assert_int_equal(values[i], ptr->value); i++; } @@ -80,19 +90,27 @@ void test_list_insert_before(void **state) free(c1); } -void test_list_remove(void **state) +static void test_list_insert_before_head(void **state) +{ + struct list_node head = {}; + struct test_container c = {}; + + expect_assert_failure(list_insert_before(&c.list_node, &head)); +} + +static void test_list_remove(void **state) { - struct list_node root = { .prev = NULL, .next = NULL }; + struct list_node head = {}; struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1)); struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2)); struct test_container *ptr; int len; - list_insert_after(&c1->list_node, &root); + list_insert_after(&c1->list_node, &head); list_insert_after(&c2->list_node, &c1->list_node); len = 0; - list_for_each(ptr, root, list_node) { + list_for_each(ptr, head, list_node) { len++; } assert_int_equal(2, len); @@ -100,14 +118,14 @@ void test_list_remove(void **state) list_remove(&c1->list_node); len = 0; - list_for_each(ptr, root, list_node) { + list_for_each(ptr, head, list_node) { len++; } assert_int_equal(1, len); list_remove(&c2->list_node); len = 0; - list_for_each(ptr, root, list_node) { + list_for_each(ptr, head, list_node) { len++; } assert_int_equal(0, len); @@ -116,20 +134,26 @@ void test_list_remove(void **state) free(c1); } -void test_list_append(void **state) +static void test_list_remove_head(void **state) +{ + struct list_node head = {}; + expect_assert_failure(list_remove(&head)); +} + +static void test_list_append(void **state) { size_t idx; struct test_container *node; - struct list_node root = {}; + struct list_node head = {}; struct test_container nodes[] = { {1}, {2}, {3} }; for (idx = 0; idx < ARRAY_SIZE(nodes); ++idx) - list_append(&nodes[idx].list_node, &root); + list_append(&nodes[idx].list_node, &head); idx = 0; - list_for_each(node, root, list_node) { + list_for_each(node, head, list_node) { assert_ptr_equal(node, &nodes[idx]); idx++; } @@ -138,12 +162,14 @@ void test_list_append(void **state) int main(void) { const struct CMUnitTest tests[] = { + cmocka_unit_test(test_list_empty), cmocka_unit_test(test_list_insert_after), cmocka_unit_test(test_list_insert_before), + cmocka_unit_test(test_list_insert_before_head), cmocka_unit_test(test_list_remove), + cmocka_unit_test(test_list_remove_head), cmocka_unit_test(test_list_append), }; - return cb_run_group_tests(tests, NULL, NULL); } From 4a5567071d9229595c1fbcf769a32b0bce1a7e8d Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 27 Jan 2026 17:13:57 +0000 Subject: [PATCH 282/789] Revert "commonlib/list: Support circular list" This reverts commit c4be70f6ff5379bcaeb7f0d2f17b140c70fc12cf. Reason for revert: The CL caused a hang in Depthcharge on Google/Quartz. BUG=b:479143030 TEST=Verify boot on Google/Quartz. Change-Id: I38087d0b2dd218dfb32a02c343b199708bb47d49 Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/90956 Tested-by: build bot (Jenkins) --- src/commonlib/include/commonlib/list.h | 21 ++------ src/commonlib/list.c | 24 ++------- tests/commonlib/list-test.c | 70 ++++++++------------------ 3 files changed, 31 insertions(+), 84 deletions(-) diff --git a/src/commonlib/include/commonlib/list.h b/src/commonlib/include/commonlib/list.h index 7cd3460f8a..970d68ea49 100644 --- a/src/commonlib/include/commonlib/list.h +++ b/src/commonlib/include/commonlib/list.h @@ -17,25 +17,14 @@ void list_remove(struct list_node *node); // Insert list_node node after list_node after in a doubly linked list. void list_insert_after(struct list_node *node, struct list_node *after); // Insert list_node node before list_node before in a doubly linked list. -// `before` must not be the placeholder head node. void list_insert_before(struct list_node *node, struct list_node *before); -// Append the node to the end of the list. +// Appends the node to the end of the list. void list_append(struct list_node *node, struct list_node *head); -/* - * Explanation of `ptr` initialization: - * 1. head.next != NULL: This means the list isn't empty. As the implementation ensures that - * list_init() is called when the very first element is added, we can safely assume that - * the list is circular, and hence set `ptr` to the 1st element. - * 2. head.next == NULL: This means the list is empty, and list_init() hasn't been called. - * As the `head` arg might be const, we cannot simply call list_init() here. Instead, we set - * `ptr` to a special value such that `&(ptr->member) == &head`, causing the loop to - * terminate immediately. - */ -#define list_for_each(ptr, head, member) \ - for ((ptr) = container_of((head).next ?: &(head), typeof(*(ptr)), member); \ - (&((ptr)->member) != &(head)); \ - (ptr) = container_of((ptr)->member.next, \ +#define list_for_each(ptr, head, member) \ + for ((ptr) = container_of((head).next, typeof(*(ptr)), member); \ + (uintptr_t)ptr + (uintptr_t)offsetof(typeof(*(ptr)), member); \ + (ptr) = container_of((ptr)->member.next, \ typeof(*(ptr)), member)) #endif /* __COMMONLIB_LIST_H__ */ diff --git a/src/commonlib/list.c b/src/commonlib/list.c index 9cbb554b41..b1030c8263 100644 --- a/src/commonlib/list.c +++ b/src/commonlib/list.c @@ -1,22 +1,10 @@ /* Taken from depthcharge: src/base/list.c */ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include #include -// Initialize a circular list, with `head` being a placeholder head node. -static void list_init(struct list_node *head) -{ - if (!head->next) { - assert(!head->prev); - head->next = head->prev = head; - } -} - void list_remove(struct list_node *node) { - /* Cannot remove the head node. */ - assert(node->prev && node->next); if (node->prev) node->prev->next = node->next; if (node->next) @@ -25,9 +13,6 @@ void list_remove(struct list_node *node) void list_insert_after(struct list_node *node, struct list_node *after) { - /* Check uninitialized head node. */ - if (after->prev == NULL) - list_init(after); node->next = after->next; node->prev = after; after->next = node; @@ -37,8 +22,6 @@ void list_insert_after(struct list_node *node, struct list_node *after) void list_insert_before(struct list_node *node, struct list_node *before) { - /* `before` cannot be an uninitialized head node. */ - assert(before->prev) node->prev = before->prev; node->next = before; before->prev = node; @@ -48,7 +31,8 @@ void list_insert_before(struct list_node *node, struct list_node *before) void list_append(struct list_node *node, struct list_node *head) { - list_init(head); - /* With a circular list, we just need to insert before the head. */ - list_insert_before(node, head); + while (head->next) + head = head->next; + + list_insert_after(node, head); } diff --git a/tests/commonlib/list-test.c b/tests/commonlib/list-test.c index eeeeded059..4ca48a468f 100644 --- a/tests/commonlib/list-test.c +++ b/tests/commonlib/list-test.c @@ -1,10 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include +#include #include #include -#include -#include +#include struct test_container { int value; @@ -12,20 +11,10 @@ struct test_container { struct list_node list_node; }; -static void test_list_empty(void **state) -{ - struct list_node head = {}; - struct test_container *node; - - list_for_each(node, head, list_node) { - assert_true(false); - } -} - -static void test_list_insert_after(void **state) +void test_list_insert_after(void **state) { int i = 0; - struct list_node head = {}; + struct list_node root = { .prev = NULL, .next = NULL }; struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1)); struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2)); struct test_container *c3 = (struct test_container *)malloc(sizeof(*c2)); @@ -40,11 +29,11 @@ static void test_list_insert_after(void **state) c2->value = values[1]; c3->value = values[2]; - list_insert_after(&c1->list_node, &head); + list_insert_after(&c1->list_node, &root); list_insert_after(&c2->list_node, &c1->list_node); list_insert_after(&c3->list_node, &c2->list_node); - list_for_each(ptr, head, list_node) { + list_for_each(ptr, root, list_node) { assert_int_equal(values[i], ptr->value); i++; } @@ -56,10 +45,10 @@ static void test_list_insert_after(void **state) free(c1); } -static void test_list_insert_before(void **state) +void test_list_insert_before(void **state) { int i = 0; - struct list_node head = {}; + struct list_node root = { .prev = NULL, .next = NULL }; struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1)); struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2)); struct test_container *c3 = (struct test_container *)malloc(sizeof(*c2)); @@ -74,11 +63,12 @@ static void test_list_insert_before(void **state) c2->value = values[1]; c3->value = values[2]; - list_insert_after(&c3->list_node, &head); + list_insert_after(&c3->list_node, &root); list_insert_before(&c2->list_node, &c3->list_node); list_insert_before(&c1->list_node, &c2->list_node); - list_for_each(ptr, head, list_node) { + + list_for_each(ptr, root, list_node) { assert_int_equal(values[i], ptr->value); i++; } @@ -90,27 +80,19 @@ static void test_list_insert_before(void **state) free(c1); } -static void test_list_insert_before_head(void **state) -{ - struct list_node head = {}; - struct test_container c = {}; - - expect_assert_failure(list_insert_before(&c.list_node, &head)); -} - -static void test_list_remove(void **state) +void test_list_remove(void **state) { - struct list_node head = {}; + struct list_node root = { .prev = NULL, .next = NULL }; struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1)); struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2)); struct test_container *ptr; int len; - list_insert_after(&c1->list_node, &head); + list_insert_after(&c1->list_node, &root); list_insert_after(&c2->list_node, &c1->list_node); len = 0; - list_for_each(ptr, head, list_node) { + list_for_each(ptr, root, list_node) { len++; } assert_int_equal(2, len); @@ -118,14 +100,14 @@ static void test_list_remove(void **state) list_remove(&c1->list_node); len = 0; - list_for_each(ptr, head, list_node) { + list_for_each(ptr, root, list_node) { len++; } assert_int_equal(1, len); list_remove(&c2->list_node); len = 0; - list_for_each(ptr, head, list_node) { + list_for_each(ptr, root, list_node) { len++; } assert_int_equal(0, len); @@ -134,26 +116,20 @@ static void test_list_remove(void **state) free(c1); } -static void test_list_remove_head(void **state) -{ - struct list_node head = {}; - expect_assert_failure(list_remove(&head)); -} - -static void test_list_append(void **state) +void test_list_append(void **state) { size_t idx; struct test_container *node; - struct list_node head = {}; + struct list_node root = {}; struct test_container nodes[] = { {1}, {2}, {3} }; for (idx = 0; idx < ARRAY_SIZE(nodes); ++idx) - list_append(&nodes[idx].list_node, &head); + list_append(&nodes[idx].list_node, &root); idx = 0; - list_for_each(node, head, list_node) { + list_for_each(node, root, list_node) { assert_ptr_equal(node, &nodes[idx]); idx++; } @@ -162,14 +138,12 @@ static void test_list_append(void **state) int main(void) { const struct CMUnitTest tests[] = { - cmocka_unit_test(test_list_empty), cmocka_unit_test(test_list_insert_after), cmocka_unit_test(test_list_insert_before), - cmocka_unit_test(test_list_insert_before_head), cmocka_unit_test(test_list_remove), - cmocka_unit_test(test_list_remove_head), cmocka_unit_test(test_list_append), }; + return cb_run_group_tests(tests, NULL, NULL); } From a1e602f8ca6c09ddbbe3bf9f44001a79cd350596 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 27 Jan 2026 19:16:26 +0530 Subject: [PATCH 283/789] mb/google/bluey: Reduce WP_RO size to 8MB for SPI compatibility The previous 12MB WP_RO size is an invalid range for the SPI controller. Hardware write-protection requires power-of-two or specific block-aligned boundaries, making 12MB unenforceable. Reduce WP_RO to 8MB to ensure hardware WP can be correctly enabled. The reclaimed space is assigned to RW_UNUSED. BUG=b:479139462 TEST=Build and verify FMAP layout on Bluey; confirm hardware WP enforcement. Change-Id: I4515eab3941913942fc5994e7094986e2edbd6d6 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90952 Reviewed-by: Jayvik Desai Reviewed-by: Kapil Porwal Reviewed-by: Avi Uday Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/chromeos.fmd | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/bluey/chromeos.fmd b/src/mainboard/google/bluey/chromeos.fmd index 01a2331b22..b70b49811d 100644 --- a/src/mainboard/google/bluey/chromeos.fmd +++ b/src/mainboard/google/bluey/chromeos.fmd @@ -1,7 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only FLASH@0x0 CONFIG_ROM_SIZE { - WP_RO 12M { + WP_RO 8M { RO_SECTION { BOOTBLOCK 512K FMAP 4K @@ -38,5 +38,7 @@ FLASH@0x0 CONFIG_ROM_SIZE { RW_FWID_B 256 } + RW_UNUSED 4M + RW_LEGACY(CBFS) } From 50099def6fdb69386dc15e11f475d2ec304c2232 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 26 Jan 2026 13:39:32 +0000 Subject: [PATCH 284/789] soc/qualcomm/x1p42100: Relocate CBMEM top to PIL region base The current CBMEM top is situated at the base of 'dram_xbl_log' (0x81A00000), leaving only 4.4MB of usable memory below it. This space has become insufficient for the growing size requirements of the coreboot configuration tables and boot services. Relocate the CBMEM top to the base of the PIL region (0x866C0000). This move increases the available contiguous memory for CBMEM allocation from 4.4MB to 7.3MB, ensuring sufficient headroom for the tables and reducing fragmentation for the OS and runtime services. Changes: - Update cbmem_top_chipset() to return _dram_pil as the new boundary. - Update memlayout.ld documentation to reflect CBMEM's new position directly below the PIL region. TEST=Verified CBMEM initialization on Bluey; confirmed coreboot tables are correctly allocated at the new high-memory boundary and no overlaps occur with reserved regions. Change-Id: I26d95b952634ce06ed2171c75bc6a129c15ec3b8 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90912 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) Reviewed-by: Avi Uday --- src/soc/qualcomm/x1p42100/cbmem.c | 2 +- src/soc/qualcomm/x1p42100/memlayout.ld | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/soc/qualcomm/x1p42100/cbmem.c b/src/soc/qualcomm/x1p42100/cbmem.c index 0524c67f03..568f23ab74 100644 --- a/src/soc/qualcomm/x1p42100/cbmem.c +++ b/src/soc/qualcomm/x1p42100/cbmem.c @@ -6,5 +6,5 @@ uintptr_t cbmem_top_chipset(void) { - return (uintptr_t)_dram_xbl_log; + return (uintptr_t)_dram_pil; } diff --git a/src/soc/qualcomm/x1p42100/memlayout.ld b/src/soc/qualcomm/x1p42100/memlayout.ld index c3d79b8890..2c06eccd24 100644 --- a/src/soc/qualcomm/x1p42100/memlayout.ld +++ b/src/soc/qualcomm/x1p42100/memlayout.ld @@ -51,6 +51,8 @@ * 0x91380000 +----------------------------------------------------------+ | | * | dram_pil | | | * 0x866C0000 +----------------------------------------------------------+ | | + * | CBMEM | | | + * +----------------------------------------------------------+ | | * | ... Usable memory ... | | | * 0x85F80000 +----------------------------------------------------------+ | | * | dram_wlan | | | @@ -81,8 +83,6 @@ * 0x81A40000 +----------------------------------------------------------+ | | * | dram_xbl_log | | | * 0x81A00000 +----------------------------------------------------------+ | | - * | CBMEM | | | - * +----------------------------------------------------------+ | | * | ... Usable memory ... | | | * 0x815A0000 +----------------------------------------------------------+ | | * | dram_cpucp | | | From 81af46e68b695d529892145c3406ab80fc8316b7 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Wed, 16 Apr 2025 20:58:00 +0200 Subject: [PATCH 285/789] vc/amd/fsp: Add SMBIOS Type 19 and 20 TEST=Boot glinda based mainboard and see Type 19 and 20 entries using dmidecode tool. Signed-off-by: Maximilian Brune Change-Id: I9a0abab9a5324f83659180a3842a8b5d9c6b3820 Reviewed-on: https://review.coreboot.org/c/coreboot/+/87586 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h | 2 + src/vendorcode/amd/fsp/common/dmi_info.h | 52 +++++++++++++++++++ src/vendorcode/amd/fsp/glinda/soc_dmi_info.h | 3 +- .../amd/fsp/mendocino/soc_dmi_info.h | 2 + src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h | 2 + src/vendorcode/amd/fsp/picasso/soc_dmi_info.h | 2 + src/vendorcode/amd/fsp/renoir/soc_dmi_info.h | 2 + 7 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h b/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h index 47500defa3..cc18977cf5 100644 --- a/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h @@ -10,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 2 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 8 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 4 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 1 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 21 #define SMBIOS_3_2_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/common/dmi_info.h b/src/vendorcode/amd/fsp/common/dmi_info.h index e38a44ed94..8879b4b3a1 100644 --- a/src/vendorcode/amd/fsp/common/dmi_info.h +++ b/src/vendorcode/amd/fsp/common/dmi_info.h @@ -185,8 +185,60 @@ typedef struct { #endif } __packed TYPE17_DMI_INFO; +/// DMI Type 19 - Memory Array Mapped Address +typedef struct { + OUT UINT32 StartingAddr; ///< The physical address, in kilobytes, + ///< of a range of memory mapped to the + ///< specified physical memory array. + OUT UINT32 EndingAddr; ///< The physical ending address of the + ///< last kilobyte of a range of addresses + ///< mapped to the specified physical memory array. + OUT UINT16 MemoryArrayHandle; ///< The handle, or instance number, associated + ///< with the physical memory array to which this + ///< address range is mapped. + OUT UINT8 PartitionWidth; ///< Identifies the number of memory devices that + ///< form a single row of memory for the address + ///< partition defined by this structure. + OUT UINT64 ExtStartingAddr; ///< The physical address, in bytes, of a range of + ///< memory mapped to the specified Physical Memory Array. + OUT UINT64 ExtEndingAddr; ///< The physical address, in bytes, of a range of + ///< memory mapped to the specified Physical Memory Array. +} __packed TYPE19_DMI_INFO; + +///DMI Type 20 - Memory Device Mapped Address +typedef struct { + OUT UINT32 StartingAddr; ///< The physical address, in kilobytes, of a range + ///< of memory mapped to the referenced Memory Device. + OUT UINT32 EndingAddr; ///< The handle, or instance number, associated with + ///< the Memory Device structure to which this address + ///< range is mapped. + OUT UINT16 MemoryDeviceHandle; ///< The handle, or instance number, associated with + ///< the Memory Device structure to which this address + ///< range is mapped. + OUT UINT16 MemoryArrayMappedAddressHandle; ///< The handle, or instance number, associated + ///< with the Memory Array Mapped Address structure to + ///< which this device address range is mapped. + OUT UINT8 PartitionRowPosition; ///< Identifies the position of the referenced Memory + ///< Device in a row of the address partition. + OUT UINT8 InterleavePosition; ///< The position of the referenced Memory Device in + ///< an interleave. + OUT UINT8 InterleavedDataDepth; ///< The maximum number of consecutive rows from the + ///< referenced Memory Device that are accessed in a + ///< single interleaved transfer. + OUT UINT64 ExtStartingAddr; ///< The physical address, in bytes, of a range of + ///< memory mapped to the referenced Memory Device. + OUT UINT64 ExtEndingAddr; ///< The physical ending address, in bytes, of the last of + ///< a range of addresses mapped to the referenced Memory Device. +} __packed TYPE20_DMI_INFO; + /// Collection of pointers to the DMI records typedef struct { OUT TYPE16_DMI_INFO T16; ///< Type 16 struc OUT TYPE17_DMI_INFO T17[AGESA_STRUCT_SOCKET_COUNT][AGESA_STRUCT_CHANNELS_PER_SOCKET][AGESA_STRUCT_DIMMS_PER_CHANNEL]; ///< Type 17 struc +#ifdef AGESA_STRUCT_T19_REGION_SUPPORTED + OUT TYPE19_DMI_INFO T19[AGESA_STRUCT_T19_REGION_SUPPORTED]; +#endif +#ifdef AGESA_STRUCT_T20_REGION_SUPPORTED + OUT TYPE20_DMI_INFO T20[AGESA_STRUCT_SOCKET_COUNT][AGESA_STRUCT_CHANNELS_PER_SOCKET][AGESA_STRUCT_DIMMS_PER_CHANNEL][AGESA_STRUCT_T20_REGION_SUPPORTED]; ///< Type 20 struc +#endif } DMI_INFO; diff --git a/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h b/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h index 15c7b63a71..85381fd691 100644 --- a/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h @@ -2,7 +2,6 @@ /* * These definitions are used to describe memory modules physical layout - * TODO: Update for Glinda */ #ifndef SOC_DMI_INFO_H @@ -11,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 4 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 16 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 2 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 3 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 31 #define SMBIOS_3_2_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h b/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h index bf35aea3e5..4c3776e458 100644 --- a/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h @@ -10,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 4 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 12 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 2 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 1 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 21 #define SMBIOS_3_2_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h b/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h index bf35aea3e5..4c3776e458 100644 --- a/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h @@ -10,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 4 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 12 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 2 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 1 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 21 #define SMBIOS_3_2_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h b/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h index 94a43f55b0..c9063ac640 100644 --- a/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h @@ -10,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 1 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 4 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 4 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 1 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 21 #endif /* SOC_DMI_INFO_H */ diff --git a/src/vendorcode/amd/fsp/renoir/soc_dmi_info.h b/src/vendorcode/amd/fsp/renoir/soc_dmi_info.h index 762320cdc3..701c91f166 100644 --- a/src/vendorcode/amd/fsp/renoir/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/renoir/soc_dmi_info.h @@ -10,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 2 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 8 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 4 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 1 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 21 //TODO check #define SMBIOS_3_2_SUPPORT 1 From 6cb3e3e4a6d02b4a2a1580e3ffeaef36c07abdcd Mon Sep 17 00:00:00 2001 From: Luca Lai Date: Tue, 27 Jan 2026 11:28:26 +0800 Subject: [PATCH 286/789] mb/fatcat/var/ruby: Change touchscreen HID Checked with the SED team and confirmed that the HID name needs to be changed to "GT 7936". BUG=b:478990702 BRANCH=none TEST=Build the image and boot to the OS, then check that the touchscreen HID name has changed to "GT 7936" in the diagnostics app. Change-Id: Id0ce797b121c4a7bcf7bf15bfc81e9b079ebb3c4 Signed-off-by: Luca Lai Reviewed-on: https://review.coreboot.org/c/coreboot/+/90941 Reviewed-by: YH Lin Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N --- src/mainboard/google/fatcat/variants/ruby/overridetree.cb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/fatcat/variants/ruby/overridetree.cb b/src/mainboard/google/fatcat/variants/ruby/overridetree.cb index e643ee9fae..0ad94b8912 100644 --- a/src/mainboard/google/fatcat/variants/ruby/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/ruby/overridetree.cb @@ -337,7 +337,7 @@ chip soc/intel/pantherlake end # I2C4 device ref i2c5 on chip drivers/i2c/hid - register "generic.hid" = ""GT7936L"" + register "generic.hid" = ""GT 7936"" register "generic.desc" = ""Goodix Touchscreen"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" register "generic.detect" = "1" @@ -355,7 +355,7 @@ chip soc/intel/pantherlake device i2c 0x14 on end end chip drivers/i2c/hid - register "generic.hid" = ""GT7936L"" + register "generic.hid" = ""GT 7936"" register "generic.desc" = ""Goodix Touchscreen"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" register "generic.detect" = "1" From 47a24d1d512f965d3323f512bdea7bb6d6762d9d Mon Sep 17 00:00:00 2001 From: Varun Upadhyay Date: Tue, 9 Dec 2025 09:44:48 +0530 Subject: [PATCH 287/789] mb/google/ocelot: Add support for AUDIO_MAX98360_ALC5682I_I2S This change adds support for I2S codec in the device tree and enables it based on the fw_config based on WCL_GPIO_Implementation Rev0p7. RDC Doc no: 836031 BUG=b:465888555 TEST=Boot on google ocelot board and Enable I2C Codec for Audio. Check Mic and Speaker functionality Change-Id: I51fb849bf365108be1ff59d65069329e5fd08824 Signed-off-by: Varun Upadhyay Reviewed-on: https://review.coreboot.org/c/coreboot/+/90427 Reviewed-by: P, Usha Reviewed-by: Avi Uday Tested-by: build bot (Jenkins) --- .../google/ocelot/variants/ocelot/fw_config.c | 61 ++++++++++--------- .../ocelot/variants/ocelot/overridetree.cb | 31 +++++++++- 2 files changed, 61 insertions(+), 31 deletions(-) diff --git a/src/mainboard/google/ocelot/variants/ocelot/fw_config.c b/src/mainboard/google/ocelot/variants/ocelot/fw_config.c index 818be9b9aa..d9f68ab505 100644 --- a/src/mainboard/google/ocelot/variants/ocelot/fw_config.c +++ b/src/mainboard/google/ocelot/variants/ocelot/fw_config.c @@ -12,37 +12,36 @@ #define GPIO_CONFIGURE_PADS(t) gpio_configure_pads(t, ARRAY_SIZE(t)) static const struct pad_config i2s_enable_pads[] = { - /* I2S_MCLK1_OUT */ + /* GPP_D09: I2S_MCLK1_OUT */ PAD_CFG_NF(GPP_D09, NONE, DEEP, NF2), - /* I2S0_SCLK_HDR */ - PAD_CFG_NF(GPP_D10, NONE, DEEP, NF1), - /* I2S0_SFRM_HDR */ - PAD_CFG_NF(GPP_D11, NONE, DEEP, NF1), - /* I2S0_TXD_HDR */ - PAD_CFG_NF(GPP_D12, NONE, DEEP, NF1), - /* I2S0_RXD_HDR */ - PAD_CFG_NF(GPP_D13, NONE, DEEP, NF1), - /* I2S1_TXD_HDR */ - PAD_CFG_NF(GPP_S00, NONE, DEEP, NF1), - /* I2S1_RXD_HDR */ - PAD_CFG_NF(GPP_S01, NONE, DEEP, NF1), - /* I2S1_SCLK_HDR */ - PAD_CFG_NF(GPP_S02, NONE, DEEP, NF1), - /* I2S1_SFRM_HDR */ - PAD_CFG_NF(GPP_S03, NONE, DEEP, NF1), - /* I2S2_SCLK_HDR */ - PAD_CFG_NF(GPP_S04, NONE, DEEP, NF1), - /* I2S2_SFRM_HDR */ - PAD_CFG_NF(GPP_S05, NONE, DEEP, NF1), - /* I2S2_TXD_HDR */ - PAD_NC(GPP_S06, NONE), - /* I2S2_RXD_HDR */ - PAD_NC(GPP_S07, NONE), - - /* DMIC_CLK */ - PAD_NC(GPP_D16, NONE), - /* DMIC_DATA */ - PAD_NC(GPP_D17, NONE), + /* GPP_D10: I2S0_SCLK_HDR */ + PAD_CFG_NF(GPP_D10, NONE, DEEP, NF2), + /* GPP_D11: I2S0_SFRM_HDR */ + PAD_CFG_NF(GPP_D11, NONE, DEEP, NF2), + /* GPP_D12: I2S0_TXD_HDR */ + PAD_CFG_NF(GPP_D12, NONE, DEEP, NF2), + /* GPP_D13: I2S0_RXD_HDR */ + PAD_CFG_NF(GPP_D13, NONE, DEEP, NF2), + /* GPP_S00: I2S1_TXD_HDR */ + PAD_CFG_NF(GPP_S00, NONE, DEEP, NF6), + /* GPP_S01: I2S1_RXD_HDR */ + PAD_CFG_NF(GPP_S01, NONE, DEEP, NF6), + /* GPP_S02: I2S1_SCLK_HDR */ + PAD_CFG_NF(GPP_S02, NONE, DEEP, NF6), + /* GPP_S03: I2S1_SFRM_HDR */ + PAD_CFG_NF(GPP_S03, NONE, DEEP, NF6), + /* GPP_S04: I2S2_SCLK_HDR */ + PAD_CFG_NF(GPP_S04, NONE, DEEP, NF6), + /* GPP_S05: I2S2_SFRM_HDR */ + PAD_CFG_NF(GPP_S05, NONE, DEEP, NF6), + /* GPP_S06: DMIC1_CLK (HDR) */ + PAD_CFG_NF(GPP_S06, NONE, DEEP, NF5), + /* GPP_S07: DMIC1_DATA (HDR) */ + PAD_CFG_NF(GPP_S07, NONE, DEEP, NF5), + /* GPP_D16: DMIC_CLK */ + PAD_CFG_NF(GPP_D16, NONE, DEEP, NF3), + /* GPP_D17: DMIC_DATA */ + PAD_CFG_NF(GPP_D17, NONE, DEEP, NF3), }; static const struct pad_config hda_enable_pads[] = { @@ -93,6 +92,8 @@ static const struct pad_config sndw_alc721_enable_pads[] = { }; static const struct pad_config audio_disable_pads[] = { + /* GPP_D09: I2S_MCLK1_OUT */ + PAD_NC(GPP_D09, NONE), /* GPP_D10: HDA_BCLK (HDR) */ PAD_NC(GPP_D10, NONE), /* GPP_D11: HDA_SYNC (HDR) */ diff --git a/src/mainboard/google/ocelot/variants/ocelot/overridetree.cb b/src/mainboard/google/ocelot/variants/ocelot/overridetree.cb index 117e7d8610..d7bd320ccd 100644 --- a/src/mainboard/google/ocelot/variants/ocelot/overridetree.cb +++ b/src/mainboard/google/ocelot/variants/ocelot/overridetree.cb @@ -92,7 +92,7 @@ chip soc/intel/pantherlake [PchSerialIoIndexI2C0] = PchSerialIoPci, [PchSerialIoIndexI2C1] = PchSerialIoPci, [PchSerialIoIndexI2C2] = PchSerialIoDisabled, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, + [PchSerialIoIndexI2C3] = PchSerialIoPci, [PchSerialIoIndexI2C4] = PchSerialIoDisabled, [PchSerialIoIndexI2C5] = PchSerialIoPci, }" @@ -108,6 +108,7 @@ chip soc/intel/pantherlake #| Field | Value | #+-------------------+---------------------------+ #| I2C1 | TPM(cr50) | + #| I2C3 | Audio | #| I2C5 | Touchpad | #+-------------------+---------------------------+ register "common_soc_config" = "{ @@ -118,6 +119,10 @@ chip soc/intel/pantherlake .speed = I2C_SPEED_FAST, .early_init = 1, }, + .i2c[3] = { + .speed = I2C_SPEED_FAST, + .early_init = 1, + }, .i2c[5] = { .speed = I2C_SPEED_FAST, }, @@ -532,6 +537,22 @@ chip soc/intel/pantherlake device i2c 50 on end end end + device ref i2c3 on + chip drivers/i2c/generic + register "hid" = ""RTL5682"" + register "name" = ""RT58"" + register "desc" = ""Headset Codec"" + register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_F17)" + # Set the jd_src to RT5668_JD1 for jack detection + register "property_count" = "1" + register "property_list[0].type" = "ACPI_DP_TYPE_INTEGER" + register "property_list[0].name" = ""realtek,jd-src"" + register "property_list[0].integer" = "1" + device i2c 1a on + probe AUDIO AUDIO_MAX98360_ALC5682I_I2S + end + end + end #I2C3 device ref i2c5 on chip drivers/i2c/hid register "generic.hid" = ""HFW68H"" @@ -586,6 +607,14 @@ chip soc/intel/pantherlake end end end + chip drivers/generic/max98357a + register "hid" = ""MX98360A"" + register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A15)" + register "sdmode_delay" = "5" + device generic 0 on + probe AUDIO AUDIO_MAX98360_ALC5682I_I2S + end + end end end end From db0f677fd10be05edc7e0d13e36edd643f63784b Mon Sep 17 00:00:00 2001 From: Rui Zhou Date: Wed, 14 Jan 2026 14:09:18 +0800 Subject: [PATCH 288/789] mb/google/brox/var/lotso: Add RAM ID for K3KL8L80CM-MGCT Add RAM ID for K3KL8L80CM-MGCT. And importing a single RAM device, so use mb_get_channel_disable_mask to distinguish it. BUG=b/468889066 BRANCH=None TEST=boot to kernel success, and the log shows that the RAM ID is correct. Change-Id: Idc1e890ab826ec008031f54e0fc445fa5ee62978 Signed-off-by: Rui Zhou Reviewed-on: https://review.coreboot.org/c/coreboot/+/90752 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/mainboard/google/brox/Kconfig | 1 + src/mainboard/google/brox/variants/lotso/memory.c | 13 +++++++++++++ .../google/brox/variants/lotso/memory/Makefile.mk | 2 +- .../variants/lotso/memory/dram_id.generated.txt | 3 ++- .../brox/variants/lotso/memory/mem_parts_used.txt | 3 ++- 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/mainboard/google/brox/Kconfig b/src/mainboard/google/brox/Kconfig index cec63f53be..44db591f32 100644 --- a/src/mainboard/google/brox/Kconfig +++ b/src/mainboard/google/brox/Kconfig @@ -81,6 +81,7 @@ config BOARD_GOOGLE_BROX_EC_ISH config BOARD_GOOGLE_LOTSO select BOARD_GOOGLE_BASEBOARD_BROX select CHROMEOS_WIFI_SAR if CHROMEOS + select ENFORCE_MEM_CHANNEL_DISABLE select MAINBOARD_HAS_GOOGLE_STRAUSS_KEYBOARD select USE_UNIFIED_AP_FIRMWARE_FOR_UFS_AND_NON_UFS diff --git a/src/mainboard/google/brox/variants/lotso/memory.c b/src/mainboard/google/brox/variants/lotso/memory.c index 84b9f4a70d..0997707e9f 100644 --- a/src/mainboard/google/brox/variants/lotso/memory.c +++ b/src/mainboard/google/brox/variants/lotso/memory.c @@ -99,6 +99,19 @@ bool variant_is_half_populated(void) return gpio_get(GPP_S0); } +uint8_t mb_get_channel_disable_mask(void) +{ + /* + * GPP_S0 High -> One RAM Chip + * GPP_S0 Low -> Two RAM Chip + * Disable all other channels except first two on each controller + */ + if (gpio_get(GPP_S0)) + return (BIT(2) | BIT(3)); + + return 0; +} + void variant_get_spd_info(struct mem_spd *spd_info) { spd_info->topo = MEM_TOPO_MEMORY_DOWN; diff --git a/src/mainboard/google/brox/variants/lotso/memory/Makefile.mk b/src/mainboard/google/brox/variants/lotso/memory/Makefile.mk index 64f4e227ba..e38115911f 100644 --- a/src/mainboard/google/brox/variants/lotso/memory/Makefile.mk +++ b/src/mainboard/google/brox/variants/lotso/memory/Makefile.mk @@ -7,4 +7,4 @@ SPD_SOURCES = SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 0(0b0000) Parts = K3KL6L60GM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 1(0b0001) Parts = H9JCNNNBK3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 2(0b0010) Parts = K3KL8L80DM-MGCU, MT62F1G32D2DS-023 WT:C, H58G56BK8BX068, H58G56CK8BX146, K3KL8L80EM-MGCU -SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = H58G56BK7BX068 +SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = H58G56BK7BX068, K3KL8L80CM-MGCT diff --git a/src/mainboard/google/brox/variants/lotso/memory/dram_id.generated.txt b/src/mainboard/google/brox/variants/lotso/memory/dram_id.generated.txt index a4824fd008..c27f7926ca 100644 --- a/src/mainboard/google/brox/variants/lotso/memory/dram_id.generated.txt +++ b/src/mainboard/google/brox/variants/lotso/memory/dram_id.generated.txt @@ -9,6 +9,7 @@ H9JCNNNBK3MLYR-N6E 1 (0001) K3KL8L80DM-MGCU 2 (0010) MT62F1G32D2DS-023 WT:C 2 (0010) H58G56BK8BX068 2 (0010) -H58G56BK7BX068 3 (0011) H58G56CK8BX146 2 (0010) K3KL8L80EM-MGCU 2 (0010) +H58G56BK7BX068 3 (0011) +K3KL8L80CM-MGCT 3 (0011) diff --git a/src/mainboard/google/brox/variants/lotso/memory/mem_parts_used.txt b/src/mainboard/google/brox/variants/lotso/memory/mem_parts_used.txt index dac8c9957c..7df5ad3b41 100644 --- a/src/mainboard/google/brox/variants/lotso/memory/mem_parts_used.txt +++ b/src/mainboard/google/brox/variants/lotso/memory/mem_parts_used.txt @@ -10,10 +10,11 @@ # Part Name K3KL6L60GM-MGCT +K3KL8L80CM-MGCT H9JCNNNBK3MLYR-N6E K3KL8L80DM-MGCU MT62F1G32D2DS-023 WT:C H58G56BK8BX068 -H58G56BK7BX068 H58G56CK8BX146 K3KL8L80EM-MGCU +H58G56BK7BX068 From 58aed45731b3a8b04f44ccd901ee531bfdd089be Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 17:46:17 -0600 Subject: [PATCH 289/789] mb/google/dedede: Remove alias for shared_ram from devicetree The alias isn't referenced anywhere, so remove it in preparation of adding a chipset devicetree using the same alias in a subsequent patch. TEST=build google/dedede (dexi) Change-Id: I0745eab9b0947b790f64383549e205bd906ba555 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90896 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- src/mainboard/google/dedede/variants/baseboard/devicetree.cb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/dedede/variants/baseboard/devicetree.cb b/src/mainboard/google/dedede/variants/baseboard/devicetree.cb index be057ea57d..94e0bae07c 100644 --- a/src/mainboard/google/dedede/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/dedede/variants/baseboard/devicetree.cb @@ -360,7 +360,7 @@ chip soc/intel/jasperlake end end # USB xHCI device pci 14.1 off end # USB xDCI (OTG) - device pci 14.2 alias shared_ram on end # PMC SRAM + device pci 14.2 on end # PMC SRAM device pci 14.3 on chip drivers/wifi/generic register "wake" = "GPE0_PME_B0" From e1e79dc53b29f779258d033cec6d457df0d67990 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 17:50:20 -0600 Subject: [PATCH 290/789] mb/google/dedede: Rework I2C enablement In order to keep coreboot and FSP in sync for which i2c ports are enabled, disable all I2C ports in the baseboard, in both the PCI devices and the SerialIoI2cMode register. Each variant enables only the ports it uses by overriding the SerialIoI2cMode register index for those ports, and enabling the PCI device(s) and defining the attached devices. References to i2c ports which were off/disabled are removed from all variants, as they are redundant. TEST=build google/dedede (dexi), verify SerialIoI2cMode in static.c enables only the single port used (i2c4) Change-Id: I7fcab382cc0eaf4fb0bc9d8095587018b4e226b1 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90897 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- .../dedede/variants/awasuki/overridetree.cb | 13 +++--------- .../dedede/variants/baseboard/devicetree.cb | 20 +++++++++---------- .../dedede/variants/beadrix/overridetree.cb | 12 ++++------- .../dedede/variants/blipper/overridetree.cb | 13 +++--------- .../dedede/variants/boten/overridetree.cb | 14 +++++-------- .../dedede/variants/boxy/overridetree.cb | 6 ++---- .../dedede/variants/bugzzy/overridetree.cb | 7 +++++++ .../dedede/variants/cappy2/overridetree.cb | 6 ++++++ .../dedede/variants/corori/overridetree.cb | 12 +---------- .../dedede/variants/cret/overridetree.cb | 13 +++--------- .../dedede/variants/dexi/overridetree.cb | 6 ++---- .../dedede/variants/dibbi/overridetree.cb | 6 ++---- .../dedede/variants/dita/overridetree.cb | 6 ++---- .../dedede/variants/drawcia/overridetree.cb | 6 ++++++ .../dedede/variants/driblee/overridetree.cb | 13 ++---------- .../dedede/variants/galtic/overridetree.cb | 10 +++------- .../dedede/variants/gooey/overridetree.cb | 14 +++++-------- .../dedede/variants/haboki/overridetree.cb | 6 ++++++ .../dedede/variants/kracko/overridetree.cb | 14 +++++-------- .../dedede/variants/lalala/overridetree.cb | 6 ++++++ .../dedede/variants/lantis/overridetree.cb | 13 +++--------- .../dedede/variants/madoo/overridetree.cb | 13 +++--------- .../dedede/variants/magolor/overridetree.cb | 6 ++++++ .../variants/metaknight/overridetree.cb | 13 ++++-------- .../dedede/variants/pirika/overridetree.cb | 10 +++------- .../dedede/variants/sasuke/overridetree.cb | 7 +++++++ .../dedede/variants/sasukette/overridetree.cb | 6 ++++++ .../dedede/variants/shotzo/overridetree.cb | 6 ++++-- .../dedede/variants/storo/overridetree.cb | 13 +++++------- .../dedede/variants/taranza/overridetree.cb | 6 ++---- .../dedede/variants/waddledee/overridetree.cb | 6 ++++++ .../dedede/variants/waddledoo/overridetree.cb | 7 +++++++ 32 files changed, 139 insertions(+), 170 deletions(-) diff --git a/src/mainboard/google/dedede/variants/awasuki/overridetree.cb b/src/mainboard/google/dedede/variants/awasuki/overridetree.cb index 76b7033f54..f791468b2b 100644 --- a/src/mainboard/google/dedede/variants/awasuki/overridetree.cb +++ b/src/mainboard/google/dedede/variants/awasuki/overridetree.cb @@ -53,14 +53,9 @@ chip soc/intel/jasperlake }" # SerialIO device mode selection - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ @@ -191,7 +186,6 @@ chip soc/intel/jasperlake device i2c 15 on end end end # I2C 0 - device pci 15.1 off end # I2C 1 device pci 15.2 on probe TOUCHSCREEN TOUCHSCREEN_PRESENT chip drivers/i2c/generic @@ -213,7 +207,6 @@ chip soc/intel/jasperlake device i2c 10 on end end end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/rt5645 register "hid" = ""10EC5650"" diff --git a/src/mainboard/google/dedede/variants/baseboard/devicetree.cb b/src/mainboard/google/dedede/variants/baseboard/devicetree.cb index 94e0bae07c..2ce85b2813 100644 --- a/src/mainboard/google/dedede/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/dedede/variants/baseboard/devicetree.cb @@ -80,11 +80,11 @@ chip soc/intel/jasperlake register "usb3_ports[3]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/1 Type-A Port A1 register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoPci, - [PchSerialIoIndexI2C4] = PchSerialIoPci, + [PchSerialIoIndexI2C0] = PchSerialIoDisabled, + [PchSerialIoIndexI2C1] = PchSerialIoDisabled, + [PchSerialIoIndexI2C2] = PchSerialIoDisabled, + [PchSerialIoIndexI2C3] = PchSerialIoDisabled, + [PchSerialIoIndexI2C4] = PchSerialIoDisabled, [PchSerialIoIndexI2C5] = PchSerialIoDisabled, }" @@ -368,16 +368,16 @@ chip soc/intel/jasperlake end end # CNVi wifi device pci 14.5 on end # SDCard - device pci 15.0 on end # I2C 0 - device pci 15.1 on end # I2C 1 - device pci 15.2 on end # I2C 2 - device pci 15.3 on end # I2C 3 + device pci 15.0 off end # I2C 0 + device pci 15.1 off end # I2C 1 + device pci 15.2 off end # I2C 2 + device pci 15.3 off end # I2C 3 device pci 16.0 on end # HECI 1 device pci 16.1 off end # HECI 2 device pci 16.4 off end # HECI 3 device pci 16.5 off end # HECI 4 device pci 17.0 off end # SATA - device pci 19.0 on end # I2C 4 + device pci 19.0 off end # I2C 4 device pci 19.1 off end # I2C 5 device pci 19.2 on end # UART 2 device pci 1a.0 on end # eMMC diff --git a/src/mainboard/google/dedede/variants/beadrix/overridetree.cb b/src/mainboard/google/dedede/variants/beadrix/overridetree.cb index c4e550c172..cba95da235 100644 --- a/src/mainboard/google/dedede/variants/beadrix/overridetree.cb +++ b/src/mainboard/google/dedede/variants/beadrix/overridetree.cb @@ -54,14 +54,10 @@ chip soc/intel/jasperlake }, }" - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" device domain 0 on device pci 04.0 on diff --git a/src/mainboard/google/dedede/variants/blipper/overridetree.cb b/src/mainboard/google/dedede/variants/blipper/overridetree.cb index 4b42f0e3aa..db0bdc2049 100644 --- a/src/mainboard/google/dedede/variants/blipper/overridetree.cb +++ b/src/mainboard/google/dedede/variants/blipper/overridetree.cb @@ -50,14 +50,9 @@ chip soc/intel/jasperlake register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # UF Camera register "usb2_ports[6]" = "USB2_PORT_EMPTY" # Not Used - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" register "tcc_offset" = "10" # TCC of 95C @@ -126,7 +121,6 @@ chip soc/intel/jasperlake device i2c 0x2c on end end end # I2C 0 - device pci 15.1 off end # I2C 1 device pci 15.2 on chip drivers/i2c/hid register "generic.hid" = ""GTCH7503"" @@ -164,7 +158,6 @@ chip soc/intel/jasperlake device i2c 10 on end end end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" diff --git a/src/mainboard/google/dedede/variants/boten/overridetree.cb b/src/mainboard/google/dedede/variants/boten/overridetree.cb index 3e0e7b32fc..56b2d935bc 100644 --- a/src/mainboard/google/dedede/variants/boten/overridetree.cb +++ b/src/mainboard/google/dedede/variants/boten/overridetree.cb @@ -73,14 +73,11 @@ chip soc/intel/jasperlake register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # UF Camera register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" # WF Camera - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" # Enable Acoustic noise mitigation and set slew rate to 1/8 # Rest of the parameters are 0 by default. @@ -258,7 +255,6 @@ chip soc/intel/jasperlake device i2c 10 on end end end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" diff --git a/src/mainboard/google/dedede/variants/boxy/overridetree.cb b/src/mainboard/google/dedede/variants/boxy/overridetree.cb index 36eadcbd1f..11c7ae399e 100644 --- a/src/mainboard/google/dedede/variants/boxy/overridetree.cb +++ b/src/mainboard/google/dedede/variants/boxy/overridetree.cb @@ -33,6 +33,8 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 6, @@ -192,10 +194,6 @@ chip soc/intel/jasperlake end end end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" diff --git a/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb b/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb index 6c399f8768..a1303d7a4f 100644 --- a/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb +++ b/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb @@ -86,6 +86,13 @@ chip soc/intel/jasperlake .fall_time_ns = 8, }, }" + + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + device domain 0 on device pci 04.0 on chip drivers/intel/dptf diff --git a/src/mainboard/google/dedede/variants/cappy2/overridetree.cb b/src/mainboard/google/dedede/variants/cappy2/overridetree.cb index e4e39f331d..2b361a3d93 100644 --- a/src/mainboard/google/dedede/variants/cappy2/overridetree.cb +++ b/src/mainboard/google/dedede/variants/cappy2/overridetree.cb @@ -41,6 +41,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "disable_external_bypass_vr" = "1" # Does not support external vnn power rail register "tcc_offset" = "10" # TCC of 95C diff --git a/src/mainboard/google/dedede/variants/corori/overridetree.cb b/src/mainboard/google/dedede/variants/corori/overridetree.cb index ed4a0976a1..59afb06e93 100644 --- a/src/mainboard/google/dedede/variants/corori/overridetree.cb +++ b/src/mainboard/google/dedede/variants/corori/overridetree.cb @@ -17,14 +17,7 @@ chip soc/intel/jasperlake register "usb3_ports[1]" = "USB3_PORT_EMPTY" # None register "usb3_ports[3]" = "USB3_PORT_EMPTY" # None - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoDisabled, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -120,9 +113,6 @@ chip soc/intel/jasperlake device i2c 15 on end end end #I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" diff --git a/src/mainboard/google/dedede/variants/cret/overridetree.cb b/src/mainboard/google/dedede/variants/cret/overridetree.cb index 1c834f411d..f1a00ffb20 100644 --- a/src/mainboard/google/dedede/variants/cret/overridetree.cb +++ b/src/mainboard/google/dedede/variants/cret/overridetree.cb @@ -18,14 +18,9 @@ chip soc/intel/jasperlake register "usb3_ports[1]" = "USB3_PORT_EMPTY" # None register "usb3_ports[3]" = "USB3_PORT_DEFAULT(OC_SKIP)" # LTE - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -155,7 +150,6 @@ chip soc/intel/jasperlake device i2c 2c on end end end #I2C 0 - device pci 15.1 off end # I2C 1 device pci 15.2 on chip drivers/i2c/hid register "generic.hid" = ""WDHT0002"" @@ -246,7 +240,6 @@ chip soc/intel/jasperlake device i2c 40 on end end end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 1c.7 on end device pci 19.0 on chip drivers/i2c/da7219 diff --git a/src/mainboard/google/dedede/variants/dexi/overridetree.cb b/src/mainboard/google/dedede/variants/dexi/overridetree.cb index f53a11a89e..38a2d520a8 100644 --- a/src/mainboard/google/dedede/variants/dexi/overridetree.cb +++ b/src/mainboard/google/dedede/variants/dexi/overridetree.cb @@ -25,6 +25,8 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 6, @@ -261,10 +263,6 @@ chip soc/intel/jasperlake end end end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""RTL5682"" diff --git a/src/mainboard/google/dedede/variants/dibbi/overridetree.cb b/src/mainboard/google/dedede/variants/dibbi/overridetree.cb index c7d6afb495..eb05d24c94 100644 --- a/src/mainboard/google/dedede/variants/dibbi/overridetree.cb +++ b/src/mainboard/google/dedede/variants/dibbi/overridetree.cb @@ -25,6 +25,8 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 6, @@ -228,10 +230,6 @@ chip soc/intel/jasperlake end end end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""RTL5682"" diff --git a/src/mainboard/google/dedede/variants/dita/overridetree.cb b/src/mainboard/google/dedede/variants/dita/overridetree.cb index f53a11a89e..38a2d520a8 100644 --- a/src/mainboard/google/dedede/variants/dita/overridetree.cb +++ b/src/mainboard/google/dedede/variants/dita/overridetree.cb @@ -25,6 +25,8 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 6, @@ -261,10 +263,6 @@ chip soc/intel/jasperlake end end end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""RTL5682"" diff --git a/src/mainboard/google/dedede/variants/drawcia/overridetree.cb b/src/mainboard/google/dedede/variants/drawcia/overridetree.cb index c84f9487fe..3ba688fb67 100644 --- a/src/mainboard/google/dedede/variants/drawcia/overridetree.cb +++ b/src/mainboard/google/dedede/variants/drawcia/overridetree.cb @@ -67,6 +67,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "tcc_offset" = "20" # TCC of 85C # Enable Acoustic noise mitigation and set slew rate to 1/4 diff --git a/src/mainboard/google/dedede/variants/driblee/overridetree.cb b/src/mainboard/google/dedede/variants/driblee/overridetree.cb index 3c9c92c98e..a703ada882 100644 --- a/src/mainboard/google/dedede/variants/driblee/overridetree.cb +++ b/src/mainboard/google/dedede/variants/driblee/overridetree.cb @@ -9,14 +9,8 @@ chip soc/intel/jasperlake register "usb3_ports[1]" = "USB3_PORT_EMPTY" # None register "usb3_ports[3]" = "USB3_PORT_EMPTY" # None - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoDisabled, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -119,9 +113,6 @@ chip soc/intel/jasperlake device i2c 2c on end end end #I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/cs42l42 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" diff --git a/src/mainboard/google/dedede/variants/galtic/overridetree.cb b/src/mainboard/google/dedede/variants/galtic/overridetree.cb index 0ef9cdb5da..3a5597c3f4 100644 --- a/src/mainboard/google/dedede/variants/galtic/overridetree.cb +++ b/src/mainboard/google/dedede/variants/galtic/overridetree.cb @@ -59,13 +59,9 @@ chip soc/intel/jasperlake }, }" - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # USB Port Configuration register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # Camera diff --git a/src/mainboard/google/dedede/variants/gooey/overridetree.cb b/src/mainboard/google/dedede/variants/gooey/overridetree.cb index 728ab919e1..d7e9d47241 100644 --- a/src/mainboard/google/dedede/variants/gooey/overridetree.cb +++ b/src/mainboard/google/dedede/variants/gooey/overridetree.cb @@ -49,14 +49,11 @@ chip soc/intel/jasperlake register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # UF Camera register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" # WF Camera - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" register "SerialIoGSpiMode[PchSerialIoIndexGSPI0]" = "PchSerialIoDisabled" # Disable GSPI0 register "SerialIoGSpiCsMode[PchSerialIoIndexGSPI0]" = "0" @@ -237,7 +234,6 @@ chip soc/intel/jasperlake device i2c 10 on end end end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" diff --git a/src/mainboard/google/dedede/variants/haboki/overridetree.cb b/src/mainboard/google/dedede/variants/haboki/overridetree.cb index 92b3bb2c48..030b143204 100644 --- a/src/mainboard/google/dedede/variants/haboki/overridetree.cb +++ b/src/mainboard/google/dedede/variants/haboki/overridetree.cb @@ -35,6 +35,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "tcc_offset" = "20" # TCC of 85C register "SerialIoGSpiMode[PchSerialIoIndexGSPI0]" = "PchSerialIoDisabled" # Disable GSPI0 diff --git a/src/mainboard/google/dedede/variants/kracko/overridetree.cb b/src/mainboard/google/dedede/variants/kracko/overridetree.cb index e4d9ad966e..388850570b 100644 --- a/src/mainboard/google/dedede/variants/kracko/overridetree.cb +++ b/src/mainboard/google/dedede/variants/kracko/overridetree.cb @@ -11,14 +11,11 @@ chip soc/intel/jasperlake register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # Camera register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" # WF Camera - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -244,7 +241,6 @@ chip soc/intel/jasperlake end end # I2C 2 - device pci 15.3 off end #I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" diff --git a/src/mainboard/google/dedede/variants/lalala/overridetree.cb b/src/mainboard/google/dedede/variants/lalala/overridetree.cb index 9609011a0c..90620d6c7d 100644 --- a/src/mainboard/google/dedede/variants/lalala/overridetree.cb +++ b/src/mainboard/google/dedede/variants/lalala/overridetree.cb @@ -56,6 +56,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 7, diff --git a/src/mainboard/google/dedede/variants/lantis/overridetree.cb b/src/mainboard/google/dedede/variants/lantis/overridetree.cb index 5f6ed2368b..c21ccf2643 100644 --- a/src/mainboard/google/dedede/variants/lantis/overridetree.cb +++ b/src/mainboard/google/dedede/variants/lantis/overridetree.cb @@ -15,14 +15,9 @@ chip soc/intel/jasperlake # USB Port Configuration register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # Camera - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -180,7 +175,6 @@ chip soc/intel/jasperlake device i2c 15 on end end end #I2C 0 - device pci 15.1 off end #I2C 1 device pci 15.2 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" @@ -240,7 +234,6 @@ chip soc/intel/jasperlake device i2c 0x5d on end end end # I2C 2 - device pci 15.3 off end #I2C 3 device pci 1c.7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" diff --git a/src/mainboard/google/dedede/variants/madoo/overridetree.cb b/src/mainboard/google/dedede/variants/madoo/overridetree.cb index 437c60a5cd..c69b482ef0 100644 --- a/src/mainboard/google/dedede/variants/madoo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/madoo/overridetree.cb @@ -3,14 +3,9 @@ chip soc/intel/jasperlake # USB Port Configuration register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # Camera - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -114,7 +109,6 @@ chip soc/intel/jasperlake device i2c 15 on end end end #I2C 0 - device pci 15.1 off end # I2C 1 device pci 15.2 on chip drivers/i2c/hid register "generic.hid" = ""GDIX0000"" @@ -132,7 +126,6 @@ chip soc/intel/jasperlake device i2c 0x5d on end end end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 1c.7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" diff --git a/src/mainboard/google/dedede/variants/magolor/overridetree.cb b/src/mainboard/google/dedede/variants/magolor/overridetree.cb index a09adeeff2..c32429dc24 100644 --- a/src/mainboard/google/dedede/variants/magolor/overridetree.cb +++ b/src/mainboard/google/dedede/variants/magolor/overridetree.cb @@ -95,6 +95,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 7, diff --git a/src/mainboard/google/dedede/variants/metaknight/overridetree.cb b/src/mainboard/google/dedede/variants/metaknight/overridetree.cb index d50fb7c59d..c116cccdae 100644 --- a/src/mainboard/google/dedede/variants/metaknight/overridetree.cb +++ b/src/mainboard/google/dedede/variants/metaknight/overridetree.cb @@ -62,14 +62,10 @@ chip soc/intel/jasperlake }, }" - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ @@ -243,7 +239,6 @@ chip soc/intel/jasperlake device i2c 15 on end end end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" diff --git a/src/mainboard/google/dedede/variants/pirika/overridetree.cb b/src/mainboard/google/dedede/variants/pirika/overridetree.cb index cf1f95e722..d413e060e0 100644 --- a/src/mainboard/google/dedede/variants/pirika/overridetree.cb +++ b/src/mainboard/google/dedede/variants/pirika/overridetree.cb @@ -46,13 +46,9 @@ chip soc/intel/jasperlake }, }" - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # USB Port Configuration register "usb2_ports[0]" = "{ diff --git a/src/mainboard/google/dedede/variants/sasuke/overridetree.cb b/src/mainboard/google/dedede/variants/sasuke/overridetree.cb index 0da00caef2..6f72562fe9 100644 --- a/src/mainboard/google/dedede/variants/sasuke/overridetree.cb +++ b/src/mainboard/google/dedede/variants/sasuke/overridetree.cb @@ -77,6 +77,13 @@ chip soc/intel/jasperlake .fall_time_ns = 8, }, }" + + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + device domain 0 on device pci 04.0 on chip drivers/intel/dptf diff --git a/src/mainboard/google/dedede/variants/sasukette/overridetree.cb b/src/mainboard/google/dedede/variants/sasukette/overridetree.cb index ba262b6282..aa61b8e11d 100644 --- a/src/mainboard/google/dedede/variants/sasukette/overridetree.cb +++ b/src/mainboard/google/dedede/variants/sasukette/overridetree.cb @@ -59,6 +59,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # USB Port Configuration register "usb2_ports[2]" = "{ .enable = 1, diff --git a/src/mainboard/google/dedede/variants/shotzo/overridetree.cb b/src/mainboard/google/dedede/variants/shotzo/overridetree.cb index 0935457092..7a821d7f8f 100644 --- a/src/mainboard/google/dedede/variants/shotzo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/shotzo/overridetree.cb @@ -38,6 +38,10 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "disable_external_bypass_vr" = "1" # Does not support external vnn power rail # Power limit config @@ -183,7 +187,6 @@ chip soc/intel/jasperlake end end end # USB xHCI - device pci 15.0 off end # I2C 0 device pci 15.2 on chip drivers/i2c/hid register "generic.hid" = ""ILTK0001"" @@ -200,7 +203,6 @@ chip soc/intel/jasperlake device i2c 41 on end end end # I2C 2 - device pci 15.3 off end #I2C 3 device pci 1c.7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" diff --git a/src/mainboard/google/dedede/variants/storo/overridetree.cb b/src/mainboard/google/dedede/variants/storo/overridetree.cb index c22c796f68..f893829dc0 100644 --- a/src/mainboard/google/dedede/variants/storo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/storo/overridetree.cb @@ -73,14 +73,11 @@ chip soc/intel/jasperlake .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, }" # WWAN - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoPci, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ diff --git a/src/mainboard/google/dedede/variants/taranza/overridetree.cb b/src/mainboard/google/dedede/variants/taranza/overridetree.cb index f53a11a89e..38a2d520a8 100644 --- a/src/mainboard/google/dedede/variants/taranza/overridetree.cb +++ b/src/mainboard/google/dedede/variants/taranza/overridetree.cb @@ -25,6 +25,8 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 6, @@ -261,10 +263,6 @@ chip soc/intel/jasperlake end end end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 device pci 19.0 on chip drivers/i2c/generic register "hid" = ""RTL5682"" diff --git a/src/mainboard/google/dedede/variants/waddledee/overridetree.cb b/src/mainboard/google/dedede/variants/waddledee/overridetree.cb index c177a8b32e..4fdddd18cc 100644 --- a/src/mainboard/google/dedede/variants/waddledee/overridetree.cb +++ b/src/mainboard/google/dedede/variants/waddledee/overridetree.cb @@ -54,6 +54,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + device domain 0 on device pci 05.0 on end # IPU - MIPI Camera device pci 14.0 on diff --git a/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb b/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb index 321b05eda5..8a1d5556c1 100644 --- a/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb @@ -49,6 +49,13 @@ chip soc/intel/jasperlake } }, }" + + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + device domain 0 on device pci 05.0 on # IPU - MIPI Camera chip drivers/intel/mipi_camera From a09f541e0349486262527347a0b487374c47a380 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 18:28:33 -0600 Subject: [PATCH 291/789] mb/google/dedede: Disable PCIe RP8 by default All variants which use a discrete (vs CNVi) WiFi module enable RP8 (or RP7) in their overridetree, so enabling RP8 in the baseboard is superfluous. Additionally, disabling it in the baseboard makes things cleaner when switching to using chipset devicetree references in a subsequent patch. Change-Id: I591508e5c41f2019a6360e08c89b0a4982178a07 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90898 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- src/mainboard/google/dedede/variants/baseboard/devicetree.cb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/dedede/variants/baseboard/devicetree.cb b/src/mainboard/google/dedede/variants/baseboard/devicetree.cb index 2ce85b2813..05c77da3e5 100644 --- a/src/mainboard/google/dedede/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/dedede/variants/baseboard/devicetree.cb @@ -389,7 +389,7 @@ chip soc/intel/jasperlake device pci 1c.5 off end # PCI Express Root Port 6 device pci 1c.6 off end # PCI Express Root Port 7 # External PCIe port 4 is mapped to PCIe Root port 8 - device pci 1c.7 on end # PCI Express Root Port 8 - hosts M.2 E-key WLAN + device pci 1c.7 off end # PCI Express Root Port 8 - hosts M.2 E-key WLAN device pci 1e.0 off end # UART 0 device pci 1e.1 off end # UART 1 device pci 1e.2 on From 0d183076401d6314664f1eb0b69d7fefa9afda52 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 26 Jan 2026 09:47:11 -0600 Subject: [PATCH 292/789] device/pciexp: Make aspm_type_str pointer const Fix checkpatch warning by changing aspm_type_str array to use 'static const char * const' instead of 'static const char *'. Change-Id: Id1082447e309b840c965326a74c4ab00f3a1536c Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90914 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- src/device/pciexp_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/pciexp_device.c b/src/device/pciexp_device.c index 1b8f8ad79b..ec90a22b74 100644 --- a/src/device/pciexp_device.c +++ b/src/device/pciexp_device.c @@ -569,7 +569,7 @@ static int pciexp_aspm_latency(struct device *root, unsigned int root_cap, static void pciexp_enable_aspm(struct device *root, unsigned int root_cap, struct device *endp, unsigned int endp_cap) { - const char *aspm_type_str[] = { "None", "L0s", "L1", "L0s and L1" }; + static const char * const aspm_type_str[] = { "None", "L0s", "L1", "L0s and L1" }; enum aspm_type apmc = PCIE_ASPM_NONE; int exit_latency, ok_latency; u16 lnkctl; From a2a868f199c53f96f71a0cc85f4667cad4186f33 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 26 Jan 2026 09:41:42 -0600 Subject: [PATCH 293/789] device/pciexp: Enable ASPM on root ports without endpoints Program ASPM on PCIe root ports when no endpoint device is connected at boot. This ensures proper power management for TBT ports that often do not have devices connected at boot. Add pciexp_enable_aspm_root_port_only() to program ASPM based on the root port's Link Capabilities, and call it from pciexp_scan_bus() when no children are detected on a root port. TEST=build/boot Starlabs Starfighter MTL, verify ASPM enabled on TBT ports even when no devices attached via lspci: LnkCtrl: ASPM L1 Enabled Change-Id: I1da6d36afcbe18411c01ceabf8b903c4ae13cd73 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90913 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- src/device/pciexp_device.c | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/device/pciexp_device.c b/src/device/pciexp_device.c index ec90a22b74..3c2f06e013 100644 --- a/src/device/pciexp_device.c +++ b/src/device/pciexp_device.c @@ -563,6 +563,42 @@ static int pciexp_aspm_latency(struct device *root, unsigned int root_cap, return (endp_lat > root_lat) ? endp_lat : root_lat; } +/* + * Enable ASPM on PCIe root port when no endpoint is connected. + * This programs ASPM based on the root port's own capabilities. + */ +static void pciexp_enable_aspm_root_port_only(struct device *root, unsigned int root_cap) +{ + static const char * const aspm_type_str[] = { "None", "L0s", "L1", "L0s and L1" }; + enum aspm_type apmc = PCIE_ASPM_NONE; + u16 lnkctl; + u32 lnkcap; + + /* Read root port's ASPM support from Link Capabilities */ + lnkcap = pci_read_config32(root, root_cap + PCI_EXP_LNKCAP); + + /* Extract ASPM support bits (11:10) */ + u32 aspm_support = (lnkcap & PCI_EXP_LNKCAP_ASPMS) >> 10; + + /* Map ASPM support to control value: + * 00 = No ASPM -> apmc = 0 (NONE) + * 01 = L0s supported -> apmc = 1 (L0S) + * 10 = L1 supported -> apmc = 2 (L1) + * 11 = L0s and L1 supported -> apmc = 3 (BOTH) + */ + apmc = (enum aspm_type)aspm_support; + + if (apmc != PCIE_ASPM_NONE) { + /* Set ASPM control in root port's Link Control register */ + lnkctl = pci_read_config16(root, root_cap + PCI_EXP_LNKCTL); + /* Clear existing ASPM bits (0:1) and set new value */ + lnkctl = (lnkctl & ~0x3) | apmc; + pci_write_config16(root, root_cap + PCI_EXP_LNKCTL, lnkctl); + printk(BIOS_INFO, "%s: ASPM enabled %s (no endpoint)\n", + dev_path(root), aspm_type_str[apmc]); + } +} + /* * Enable ASPM on PCIe root port and endpoint. */ @@ -843,6 +879,8 @@ void pciexp_scan_bus(struct bus *bus, unsigned int min_devfn, { struct device *child; unsigned int max_payload; + bool has_children = false; + unsigned int root_cap; pciexp_enable_ltr(bus->dev); @@ -862,9 +900,20 @@ void pciexp_scan_bus(struct bus *bus, unsigned int min_devfn, (child->path.pci.devfn > max_devfn)) { continue; } + has_children = true; pciexp_tune_dev(child); } + /* + * If no endpoint is connected and this is a root port, program ASPM + * based on the root port's own capabilities. + */ + if (!has_children && pcie_is_root_port(bus->dev) && CONFIG(PCIEXP_ASPM)) { + root_cap = pci_find_capability(bus->dev, PCI_CAP_ID_PCIE); + if (root_cap) + pciexp_enable_aspm_root_port_only(bus->dev, root_cap); + } + /* * Now the root port's Max Payload Size should be set to the highest * possible value supported by all devices under a given root port. From 7ce04e929137f661b5aaa1bdab5f11abe420aa89 Mon Sep 17 00:00:00 2001 From: Vladimir Epifantsev Date: Mon, 8 Sep 2025 00:11:43 +0200 Subject: [PATCH 294/789] util/inteltool: improve support for Comet Lake-U/H MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for MCH, spi and bios_cntrl, LPC/eSPI, GPIO, EPBAR, DMIBAR and add product description. References: * 10th Generation Intel® Core™ Processors, Datasheet Volume 1 of 2 * 10th Generation Intel® Core™ Processors, Datasheet Volume 2 of 2 * Intel® 400 Series Chipset Family Platform Controller Hub, Datasheet Volume 1 of 2 * Intel® 400 Series Chipset Family Platform Controller Hub, Datasheet Volume 2 of 2 Change-Id: I9ae2447d2f122b9c05bcd50c16c1f19330ee9656 Signed-off-by: Vladimir Epifantsev Reviewed-on: https://review.coreboot.org/c/coreboot/+/89098 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- util/inteltool/gpio.c | 1 + util/inteltool/gpio_groups.c | 1 + util/inteltool/inteltool.c | 29 ++++++++++-- util/inteltool/inteltool.h | 12 +++++ util/inteltool/lpc.c | 17 +++++++ util/inteltool/memory.c | 3 ++ util/inteltool/pcie.c | 53 ++++++++++++++++++++++ util/inteltool/pcr.c | 1 + util/inteltool/rootcmplx.c | 1 + util/inteltool/spi.c | 87 +++++++++++++++++++++++++++++++----- 10 files changed, 190 insertions(+), 15 deletions(-) diff --git a/util/inteltool/gpio.c b/util/inteltool/gpio.c index 2a893a2daf..07f39593a0 100644 --- a/util/inteltool/gpio.c +++ b/util/inteltool/gpio.c @@ -1118,6 +1118,7 @@ int print_gpios(struct pci_dev *sb, int show_all, int show_diffs) case PCI_DEVICE_ID_INTEL_B760: case PCI_DEVICE_ID_INTEL_HM770: case PCI_DEVICE_ID_INTEL_WM790: + case PCI_DEVICE_ID_INTEL_HM470: case PCI_DEVICE_ID_INTEL_C262: case PCI_DEVICE_ID_INTEL_C266: case PCI_DEVICE_ID_INTEL_ADL_P: diff --git a/util/inteltool/gpio_groups.c b/util/inteltool/gpio_groups.c index 23757ba630..c8fbdb4439 100644 --- a/util/inteltool/gpio_groups.c +++ b/util/inteltool/gpio_groups.c @@ -186,6 +186,7 @@ const struct gpio_community *const *get_gpio_communities(struct pci_dev *const s case PCI_DEVICE_ID_INTEL_QM370: case PCI_DEVICE_ID_INTEL_HM370: case PCI_DEVICE_ID_INTEL_CM246: + case PCI_DEVICE_ID_INTEL_HM470: *community_count = ARRAY_SIZE(cannonlake_pch_h_communities); *pad_stepping = 16; return cannonlake_pch_h_communities; diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c index 5bd9a05949..0ed9b8331c 100644 --- a/util/inteltool/inteltool.c +++ b/util/inteltool/inteltool.c @@ -145,11 +145,17 @@ static const struct { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_10TH_GEN_U, "10th generation (Icelake family) Core Processor (Mobile)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_U1, - "10th generation (Comet Lake family) Core Processor (Mobile)" }, + "10th generation (Comet Lake-U family) Core Processor (Mobile)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_U2, - "10th generation (Comet Lake family) Core Processor (Mobile)" }, + "10th generation (Comet Lake-U family) Core Processor (Mobile)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_U3, - "10th generation (Comet Lake family) Core Processor (Mobile)" }, + "10th generation (Comet Lake-U family) Core Processor (Mobile)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2, + "10th generation (Comet Lake-H family) Core Processor (Mobile)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2, + "10th generation (Comet Lake-H family) Core Processor (Mobile)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2, + "10th generation (Comet Lake-H family) Core Processor (Mobile)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HEWITTLAKE, "Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D (Hewitt Lake)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SAPPHIRERAPIDS_SP, @@ -435,6 +441,7 @@ static const struct { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK_LPC, "Gemini Lake" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_H510, "H510" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_H570, "H570" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HM470, "HM470" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Z590, "Z590" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q570, "Q570" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_B560, "B560" }, @@ -617,6 +624,22 @@ static const struct { "Intel(R) UHD Graphics for 11th Gen Intel(R) Processors" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGL_GT2_ULT_2, "Intel(R) UHD Graphics for 11th Gen Intel(R) Processors" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT1_S_1, + "Intel(R) CometLake-S GT1" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT1_S_2, + "Intel(R) CometLake-S GT1" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT2_S_G0, + "Intel(R) CometLake-S GT2" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT2_S_P0, + "Intel(R) CometLake-S GT2" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT1_H_1, + "Intel(R) CometLake-H GT1" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT1_H_2, + "Intel(R) CometLake-H GT1" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT2_H_R0, + "Intel(R) CometLake-H GT2" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT2_H_R1, + "Intel(R) CometLake-H GT2" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_S_GT1, "Intel(R) AlderLake-S GT1" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_S_GT1_2, diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h index c279d02e87..a9419e3431 100644 --- a/util/inteltool/inteltool.h +++ b/util/inteltool/inteltool.h @@ -224,6 +224,7 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_WM590 0x4389 #define PCI_DEVICE_ID_INTEL_QM580 0x438a #define PCI_DEVICE_ID_INTEL_HM570 0x438b +#define PCI_DEVICE_ID_INTEL_HM470 0x068d #define PCI_DEVICE_ID_INTEL_C252 0x438c #define PCI_DEVICE_ID_INTEL_C256 0x438d #define PCI_DEVICE_ID_INTEL_W580 0x438f @@ -399,6 +400,9 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_CORE_CML_U1 0x9b51 /* Cometlake U (Mobile) */ #define PCI_DEVICE_ID_INTEL_CORE_CML_U2 0x9b61 /* Cometlake U (Mobile) */ #define PCI_DEVICE_ID_INTEL_CORE_CML_U3 0x9b71 /* Cometlake U (Mobile) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2 0x9b44 /* Cometlake H 8+2 (Mobile) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2 0x9b54 /* Cometlake H 6+2 (Mobile) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2 0x9b64 /* Cometlake H 4+2 (Mobile) */ #define PCI_DEVICE_ID_INTEL_CORE_TGL_ID_U_2 0x9a04 /* Tigerlake UP3 2 Cores */ #define PCI_DEVICE_ID_INTEL_CORE_TGL_ID_U_4 0x9a14 /* Tigerlake UP3 4 Cores */ #define PCI_DEVICE_ID_INTEL_CORE_TGL_ID_Y_2 0x9a02 /* Tigerlake UP4 2 Cores */ @@ -506,6 +510,14 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_TGL_GT1_2 0x9A68 #define PCI_DEVICE_ID_INTEL_TGL_GT2_ULT_1 0x9A78 #define PCI_DEVICE_ID_INTEL_TGL_GT2_ULT_2 0x9A70 +#define PCI_DEVICE_ID_INTEL_CML_GT1_S_1 0x9BA5 +#define PCI_DEVICE_ID_INTEL_CML_GT1_S_2 0x9BA8 +#define PCI_DEVICE_ID_INTEL_CML_GT2_S_G0 0x9BC8 +#define PCI_DEVICE_ID_INTEL_CML_GT2_S_P0 0x9BC5 +#define PCI_DEVICE_ID_INTEL_CML_GT1_H_1 0x9BA4 +#define PCI_DEVICE_ID_INTEL_CML_GT1_H_2 0x9BA2 +#define PCI_DEVICE_ID_INTEL_CML_GT2_H_R0 0x9BC2 +#define PCI_DEVICE_ID_INTEL_CML_GT2_H_R1 0x9BC4 /* Elkhart Lake */ #define PCI_DEVICE_ID_INTEL_EHL_GT1_1 0x4541 #define PCI_DEVICE_ID_INTEL_EHL_GT1_2 0x4551 diff --git a/util/inteltool/lpc.c b/util/inteltool/lpc.c index 4ce06ae5b9..9fbec66402 100644 --- a/util/inteltool/lpc.c +++ b/util/inteltool/lpc.c @@ -150,6 +150,23 @@ int print_lpc(struct pci_dev *sb, struct pci_access *pacc) cfg_registers_size = ARRAY_SIZE(sunrise_lpc_cfg_registers); } break; + case PCI_DEVICE_ID_INTEL_HM470: + dev = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 0); + if (!dev) { + printf("LPC/eSPI interface not found.\n"); + return 1; + } + bc = pci_read_long(dev, SUNRISE_LPC_BC); + if (bc & (1 << 2)) { + printf("Device 0:1f.0 is eSPI (BC.LPC_ESPI=1)\n\n"); + cfg_registers = alderlake_espi_cfg_registers; + cfg_registers_size = ARRAY_SIZE(alderlake_espi_cfg_registers); + } else { + printf("Device 0:1f.0 is LPC (BC.LPC_ESPI=0)\n\n"); + cfg_registers = sunrise_lpc_cfg_registers; + cfg_registers_size = ARRAY_SIZE(sunrise_lpc_cfg_registers); + } + break; case PCI_DEVICE_ID_INTEL_ADL_N: dev = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 0); if (!dev) { diff --git a/util/inteltool/memory.c b/util/inteltool/memory.c index bb7ad60617..608a95533a 100644 --- a/util/inteltool/memory.c +++ b/util/inteltool/memory.c @@ -229,6 +229,9 @@ int print_mchbar(struct pci_dev *nb, struct pci_access *pacc, const char *dump_s case PCI_DEVICE_ID_INTEL_CORE_CML_U1: case PCI_DEVICE_ID_INTEL_CORE_CML_U2: case PCI_DEVICE_ID_INTEL_CORE_CML_U3: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2: mchbar_phys = pci_read_long(nb, 0x48); mchbar_phys |= ((uint64_t)pci_read_long(nb, 0x4c)) << 32; mchbar_phys &= 0x0000007fffff8000UL; /* 38:15 */ diff --git a/util/inteltool/pcie.c b/util/inteltool/pcie.c index 32afa714fc..06a09df3ca 100644 --- a/util/inteltool/pcie.c +++ b/util/inteltool/pcie.c @@ -227,6 +227,35 @@ static const io_register_t alderlake_dmi_registers[] = { { 0x1D4, 4, "DMICEMSK" }, // DMI Correctable Error Mask }; +/* 10th Generation Intel® Core™ Processors, Datasheet Volume 2 of 2, ID 615211 */ +static const io_register_t cometlake_dmi_registers[] = { + { 0x00, 4, "DMIVCECH" }, // DMI Virtual Channel Enhanced Capability + { 0x04, 4, "DMIPVCCAP1" }, // DMI Port VC Capability Register 1 + { 0x08, 4, "DMIPVCCAP2" }, // DMI Port VC Capability Register 2 + { 0x0C, 2, "DMIPVCCTL" }, // DMI Port VC Control + { 0x10, 4, "DMIVC0RCAP" }, // DMI VC0 Resource Capability + { 0x14, 4, "DMIVC0RCTL" }, // DMI VC0 Resource Control + { 0x1A, 2, "DMIVC0RSTS" }, // DMI VC0 Resource Status + { 0x1C, 4, "DMIVC1RCAP" }, // DMI VC1 Resource Capability + { 0x20, 4, "DMIVC1RCTL" }, // DMI VC1 Resource Control + { 0x26, 2, "DMIVC1RSTS" }, // DMI VC1 Resource Status + { 0x34, 4, "DMIVCMRCAP" }, // DMI VCm Resource Capability + { 0x38, 4, "DMIVCMRCTL" }, // DMI VCm Resource Control + { 0x3E, 2, "DMIVCMRSTS" }, // DMI VCm Resource Status + { 0x40, 4, "DMIRCLDECH" }, // DMI Root Complex Link Declaration + { 0x44, 4, "DMIESD" }, // DMI Element Self Description + { 0x50, 4, "DMILE1D" }, // DMI Link Entry 1 Description + { 0x58, 4, "DMILE1A" }, // DMI Link Entry 1 Address + { 0x5C, 4, "DMILUE1A" }, // DMI Link Upper Entry 1 Address + { 0x60, 4, "DMILE2D" }, // DMI Link Entry 2 Description + { 0x68, 4, "DMILE2A" }, // DMI Link Entry 2 Address + { 0x84, 4, "LCAP" }, // Link Capabilities + { 0x88, 2, "LCTL" }, // Link Control + { 0x8A, 2, "LSTS" }, // DMI Link Status + { 0x98, 2, "LCTL2" }, // Link Control 2 + { 0x9A, 2, "LSTS2" }, // Link Status 2 +}; + /* * Egress Port Root Complex MMIO configuration space */ @@ -292,6 +321,12 @@ int print_epbar(struct pci_dev *nb) case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_8: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4_1: + case PCI_DEVICE_ID_INTEL_CORE_CML_U1: + case PCI_DEVICE_ID_INTEL_CORE_CML_U2: + case PCI_DEVICE_ID_INTEL_CORE_CML_U3: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2: epbar_phys = pci_read_long(nb, 0x40) & 0xfffffffe; epbar_phys |= ((uint64_t)pci_read_long(nb, 0x44)) << 32; break; @@ -433,6 +468,18 @@ int print_dmibar(struct pci_dev *nb) dmibar_phys |= ((uint64_t)pci_read_long(nb, 0x6c)) << 32; dmibar_phys &= 0x0000007ffffff000UL; /* 38:12 */ break; + case PCI_DEVICE_ID_INTEL_CORE_CML_U1: + case PCI_DEVICE_ID_INTEL_CORE_CML_U2: + case PCI_DEVICE_ID_INTEL_CORE_CML_U3: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2: + dmi_registers = cometlake_dmi_registers; + size = ARRAY_SIZE(cometlake_dmi_registers); + dmibar_phys = pci_read_long(nb, 0x68); + dmibar_phys |= ((uint64_t)pci_read_long(nb, 0x6c)) << 32; + dmibar_phys &= 0x0000007ffffff000UL; /* 38:12 */ + break; case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_8: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4_1: @@ -555,6 +602,12 @@ int print_pciexbar(struct pci_dev *nb) case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_8: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4_1: + case PCI_DEVICE_ID_INTEL_CORE_CML_U1: + case PCI_DEVICE_ID_INTEL_CORE_CML_U2: + case PCI_DEVICE_ID_INTEL_CORE_CML_U3: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2: pciexbar_reg = pci_read_long(nb, 0x60); pciexbar_reg |= ((uint64_t)pci_read_long(nb, 0x64)) << 32; break; diff --git a/util/inteltool/pcr.c b/util/inteltool/pcr.c index 6d70905021..8654e32a89 100644 --- a/util/inteltool/pcr.c +++ b/util/inteltool/pcr.c @@ -141,6 +141,7 @@ void pcr_init(struct pci_dev *const sb) case PCI_DEVICE_ID_INTEL_C252: case PCI_DEVICE_ID_INTEL_C256: case PCI_DEVICE_ID_INTEL_W580: + case PCI_DEVICE_ID_INTEL_HM470: case PCI_DEVICE_ID_INTEL_CANNONPOINT_LP_U_PREM: case PCI_DEVICE_ID_INTEL_COMETPOINT_LP_U_PREM: case PCI_DEVICE_ID_INTEL_COMETPOINT_LP_U_BASE: diff --git a/util/inteltool/rootcmplx.c b/util/inteltool/rootcmplx.c index 87fa38ffbc..a11cf5f2e8 100644 --- a/util/inteltool/rootcmplx.c +++ b/util/inteltool/rootcmplx.c @@ -125,6 +125,7 @@ int print_rcba(struct pci_dev *sb) case PCI_DEVICE_ID_INTEL_ICH4M: case PCI_DEVICE_ID_INTEL_ICH5: case PCI_DEVICE_ID_INTEL_ADL_N: + case PCI_DEVICE_ID_INTEL_HM470: printf("This southbridge does not have RCBA.\n"); return 1; default: diff --git a/util/inteltool/spi.c b/util/inteltool/spi.c index cba43ed10e..9c3d2f12f5 100644 --- a/util/inteltool/spi.c +++ b/util/inteltool/spi.c @@ -171,6 +171,53 @@ static const io_register_t elkhart_spi_bar_registers[] = { { 0x198, 4, "CSXE_WPR0 - Write Protected Range 0" }, }; +/* Intel® 400 Series Chipset Family Platform Controller Hub, 620855-002 */ +static const io_register_t cometlake_spi_bar_registers[] = { + { 0x00, 4, "BFPREG - BIOS Flash Primary Region" }, + { 0x04, 2, "HSFSTS - Hardware Sequencing Flash Status" }, + { 0x06, 2, "HSFCTL - Hardware Sequencing Flash Control" }, + { 0x08, 4, "FADDR - Flash Address" }, + { 0x0c, 4, "DLOCK - Discrete Lock Bits" }, + { 0x10, 4, "FDATA0 - Flash Data 0" }, + { 0x14, 4, "FDATA1 - Flash Data 1" }, + { 0x18, 4, "FDATA2 - Flash Data 2" }, + { 0x1c, 4, "FDATA3 - Flash Data 3" }, + { 0x20, 4, "FDATA4 - Flash Data 4" }, + { 0x24, 4, "FDATA5 - Flash Data 5" }, + { 0x28, 4, "FDATA6 - Flash Data 6" }, + { 0x2c, 4, "FDATA7 - Flash Data 7" }, + { 0x30, 4, "FDATA8 - Flash Data 8" }, + { 0x34, 4, "FDATA9 - Flash Data 9" }, + { 0x38, 4, "FDATA10 - Flash Data 10" }, + { 0x3c, 4, "FDATA11 - Flash Data 11" }, + { 0x40, 4, "FDATA12 - Flash Data 12" }, + { 0x44, 4, "FDATA13 - Flash Data 13" }, + { 0x48, 4, "FDATA14 - Flash Data 14" }, + { 0x4c, 4, "FDATA15 - Flash Data 15" }, + { 0x50, 4, "FRACC - Flash Region Access Permissions" }, + { 0x54, 4, "FREG0 - Flash Region 0" }, + { 0x58, 4, "FREG1 - Flash Region 1" }, + { 0x5c, 4, "FREG2 - Flash Region 2" }, + { 0x60, 4, "FREG3 - Flash Region 3" }, + { 0x64, 4, "FREG4 - Flash Region 4" }, + { 0x68, 4, "FREG5 - Flash Region 5" }, + { 0x84, 4, "FPR0 - Flash Protected Range 0" }, + { 0x88, 4, "FPR1 - Flash Protected Range 1" }, + { 0x8c, 4, "FPR2 - Flash Protected Range 2" }, + { 0x90, 4, "FPR3 - Flash Protected Range 3" }, + { 0x94, 4, "FPR4 - Flash Protected Range 4" }, + { 0x98, 4, "GPR0 - Global Protected Range 0" }, + { 0xb0, 4, "SFRACC - Secondary Flash Region Access Permissions" }, + { 0xb4, 4, "FDOC - Flash Descriptor Observability Control" }, + { 0xb8, 4, "FDOD - Flash Descriptor Observability Data" }, + { 0xc0, 4, "AFC - Additional Flash Control" }, + { 0xc4, 4, "SFDP0_VSCC0 - Vendor Specific Component Capabilities for Component 0" }, + { 0xc8, 4, "SFDP1_VSCC1 - Vendor Specific Component Capabilities for Component 1" }, + { 0xcc, 4, "PTINX - Parameter Table Index" }, + { 0xd0, 4, "PTDATA - Parameter Table Data" }, + { 0xd4, 4, "SBRS - SPI Bus Requester Status" }, +}; + static int print_bioscntl(struct pci_dev *sb) { int i, size = 0; @@ -303,6 +350,7 @@ static int print_bioscntl(struct pci_dev *sb) size = ARRAY_SIZE(pch_bios_cntl_registers); break; case PCI_DEVICE_ID_INTEL_ADL_N: + case PCI_DEVICE_ID_INTEL_HM470: bios_cntl = pci_read_byte(sb, 0xdc); bios_cntl_register = adl_pch_bios_cntl_registers; size = ARRAY_SIZE(adl_pch_bios_cntl_registers); @@ -330,13 +378,29 @@ static int print_bioscntl(struct pci_dev *sb) return 0; } +static int get_espibar_phys(struct pci_dev *sb, struct pci_access *pacc, uint8_t func, uint8_t offset, uint32_t mask, uint32_t *addr) { + struct pci_dev *spidev; + + if (!(spidev = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, func))) { + fprintf(stderr, "Error: no spi device 0:31.%x\n", func); + return 1; + } + + *addr = pci_read_long(spidev, offset) & mask; + if (!*addr) { + fprintf(stderr, "Error: no valid bar 0 of device 0:31.%x found %x\n", func, *addr); + return 1; + } + + return 0; +} + static int print_spibar(struct pci_dev *sb, struct pci_access *pacc) { int i, size = 0, rcba_size = 0x4000; volatile uint8_t *rcba; uint32_t rcba_phys; const io_register_t *spi_register = NULL; uint32_t spibaroffset; - struct pci_dev *spidev; printf("\n============= SPI Bar ==============\n\n"); @@ -461,23 +525,22 @@ static int print_spibar(struct pci_dev *sb, struct pci_access *pacc) { break; case PCI_DEVICE_ID_INTEL_EHL: /* the southbridge is the eSPI controller, we need to get the SPI flash controller */ - if (!(spidev = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 5))) { - perror("Error: no spi device 0:31.5\n"); + /* this is not rcba, but we keep it to use common code */ + if (get_espibar_phys(sb, pacc, 5, 0x10, 0xfffff000, &rcba_phys)) return 1; - } - - rcba_phys = ((uint64_t)pci_read_long(spidev, 0x10) & 0xfffff000); rcba_size = 4096; - if (!rcba_phys) { - fprintf(stderr, "Error: no valid bar 0 of device 0:31.5 found %x %x\n", rcba_phys, rcba_size); - return 1; - } - - /* this is not rcba, but we keep it to use common code */ spibaroffset = 0; spi_register = elkhart_spi_bar_registers; size = ARRAY_SIZE(elkhart_spi_bar_registers); break; + case PCI_DEVICE_ID_INTEL_HM470: + if (get_espibar_phys(sb, pacc, 5, 0x10, 0xfffff000, &rcba_phys)) + return 1; + rcba_size = 4096; + spibaroffset = 0; + spi_register = cometlake_spi_bar_registers; + size = ARRAY_SIZE(cometlake_spi_bar_registers); + break; case PCI_DEVICE_ID_INTEL_ICH: case PCI_DEVICE_ID_INTEL_ICH0: case PCI_DEVICE_ID_INTEL_ICH2: From 4d1d27fcf3e30a4d443c58bea1d8088e8e38b706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Tue, 8 Jul 2025 20:46:36 +0200 Subject: [PATCH 295/789] vendorcode/amd/opensil: Add Turin OpenSIL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Turin OpenSIL driver and submodule pointing to turin_poc branch of github.com/openSIL/openSIL repository. Change-Id: Idd6d4e78a055926061de330da620c943b42a50a7 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/88711 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Felix Held --- .gitmodules | 4 + src/soc/amd/turin_poc/Kconfig | 1 + src/vendorcode/amd/opensil/Kconfig | 8 + src/vendorcode/amd/opensil/Kconfig.debug | 30 +++ src/vendorcode/amd/opensil/Makefile.mk | 7 +- .../amd/opensil/turin_poc/Makefile.mk | 8 +- src/vendorcode/amd/opensil/turin_poc/acpi.c | 4 +- src/vendorcode/amd/opensil/turin_poc/filter.h | 28 +- src/vendorcode/amd/opensil/turin_poc/memmap.c | 7 +- .../opensil/turin_poc/meson_cross.template | 2 + .../amd/opensil/turin_poc/mpio/Makefile.mk | 2 +- .../amd/opensil/turin_poc/mpio/chip.c | 106 +++++--- .../amd/opensil/turin_poc/mpio/chip.h | 12 +- src/vendorcode/amd/opensil/turin_poc/opensil | 1 + .../opensil/turin_poc/opensil_config.template | 2 +- .../amd/opensil/turin_poc/opensil_console.c | 29 ++- .../amd/opensil/turin_poc/opensil_console.h | 6 +- .../amd/opensil/turin_poc/ramstage.c | 241 ++++++++++++++++-- 18 files changed, 410 insertions(+), 88 deletions(-) create mode 160000 src/vendorcode/amd/opensil/turin_poc/opensil diff --git a/.gitmodules b/.gitmodules index 4fa82999dc..7a8d618619 100644 --- a/.gitmodules +++ b/.gitmodules @@ -70,3 +70,7 @@ [submodule "3rdparty/open-power-signing-utils"] path = 3rdparty/open-power-signing-utils url = https://review.coreboot.org/open-power-signing-utils.git +[submodule "src/vendorcode/amd/opensil/turin_poc/opensil"] + path = src/vendorcode/amd/opensil/turin_poc/opensil + url = https://github.com/openSIL/openSIL.git + branch = turin_poc diff --git a/src/soc/amd/turin_poc/Kconfig b/src/soc/amd/turin_poc/Kconfig index 8eadb04933..afdedfd94a 100644 --- a/src/soc/amd/turin_poc/Kconfig +++ b/src/soc/amd/turin_poc/Kconfig @@ -68,6 +68,7 @@ config SOC_SPECIFIC_OPTIONS select SOC_AMD_COMMON_BLOCK_USE_ESPI select SOC_AMD_COMMON_BLOCK_XHCI select SOC_AMD_OPENSIL + select SOC_AMD_OPENSIL_TURIN_POC select OPENSIL_DRIVER select DRAM_SUPPORT_DDR5 select SSE2 diff --git a/src/vendorcode/amd/opensil/Kconfig b/src/vendorcode/amd/opensil/Kconfig index 11308a7f73..735d6e1feb 100644 --- a/src/vendorcode/amd/opensil/Kconfig +++ b/src/vendorcode/amd/opensil/Kconfig @@ -15,10 +15,17 @@ config SOC_AMD_OPENSIL_GENOA_POC Select this on SoCs that use the Genoa proof of concept version of openSIL. +config SOC_AMD_OPENSIL_TURIN_POC + bool + help + Select this on SoCs that use the Turin proof of concept version of + openSIL. + config AMD_OPENSIL_PATH string "Path to openSIL source" depends on !SOC_AMD_OPENSIL_STUB default "$(top)/src/vendorcode/amd/opensil/genoa_poc/opensil" if SOC_AMD_OPENSIL_GENOA_POC + default "$(top)/src/vendorcode/amd/opensil/turin_poc/opensil" if SOC_AMD_OPENSIL_TURIN_POC help Set to the path of the openSIL directory containing meson.build. example @@ -26,6 +33,7 @@ config AMD_OPENSIL_PATH config AMD_OPENSIL_MPIO_CHIP_H_FILE string "Location of specific MPIO chip.h implementation" default "$(top)/src/vendorcode/amd/opensil/genoa_poc/mpio/chip.h" if SOC_AMD_OPENSIL_GENOA_POC + default "$(top)/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h" if SOC_AMD_OPENSIL_TURIN_POC default "$(top)/src/vendorcode/amd/opensil/stub/mpio/chip.h" help Set to the location of the MPIO chip.h in the selected openSIL diff --git a/src/vendorcode/amd/opensil/Kconfig.debug b/src/vendorcode/amd/opensil/Kconfig.debug index 859122b2a8..14b57662c6 100644 --- a/src/vendorcode/amd/opensil/Kconfig.debug +++ b/src/vendorcode/amd/opensil/Kconfig.debug @@ -66,6 +66,36 @@ config OPENSIL_DEBUG_RAS help Enable printing RAS related messages. +config OPENSIL_DEBUG_MPIO + bool "Enable MPIO messages" + default y + help + Enable printing MPIO related messages. + +config OPENSIL_DEBUG_CXL + bool "Enable CXL messages" + default y + help + Enable printing CXL related messages. + +config OPENSIL_DEBUG_SDXI + bool "Enable SDXI messages" + default y + help + Enable printing SDXI related messages. + +config OPENSIL_DEBUG_RCMGR + bool "Enable RC MGR messages" + default y + help + Enable printing Resource Manager related messages. + +config OPENSIL_DEBUG_XUSL_CMN + bool "Enable xUSL CommonLib messages" + default y + help + Enable printing xUSL CommonLib related messages. + endif # OPENSIL_DEBUG_OUTPUT endif # SOC_AMD_OPENSIL diff --git a/src/vendorcode/amd/opensil/Makefile.mk b/src/vendorcode/amd/opensil/Makefile.mk index 5c881f9bc6..beebaf5782 100644 --- a/src/vendorcode/amd/opensil/Makefile.mk +++ b/src/vendorcode/amd/opensil/Makefile.mk @@ -15,6 +15,7 @@ endif opensil_dir := $(call strip_quotes,$(CONFIG_AMD_OPENSIL_PATH)) subdirs-$(CONFIG_SOC_AMD_OPENSIL_GENOA_POC) += genoa_poc +subdirs-$(CONFIG_SOC_AMD_OPENSIL_TURIN_POC) += turin_poc ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y) cpu_family_string="x86" @@ -63,7 +64,11 @@ $(OBJPATH)/$(OPENSIL_CONFIG): $(opensil_dir)/../opensil_config.template $< > $@ $(OBJPATH)/$(OPENSIL_CONFIG).h: $(OBJPATH)/$(OPENSIL_CONFIG) $(obj)/config.h $(objutil)/kconfig/conf - cd $(opensil_dir); KCONFIG_CONFIG=$(OBJPATH)/$(OPENSIL_CONFIG) KCONFIG_AUTOHEADER=$@ $(PYTHON) util/kconfig/lib/genconfig.py Kconfig + cd $(opensil_dir); \ + KCONFIG_CONFIG=$(OBJPATH)/$(OPENSIL_CONFIG) \ + KCONFIG_AUTOHEADER=$@ \ + $(PYTHON) util/kconfig/lib/genconfig.py \ + --config-out $(OBJPATH)/$(OPENSIL_CONFIG) Kconfig # meson handles ccache on its own OPENSIL_COMPILER=$(filter-out $(CCACHE), $(CC_ramstage)) diff --git a/src/vendorcode/amd/opensil/turin_poc/Makefile.mk b/src/vendorcode/amd/opensil/turin_poc/Makefile.mk index 62bd00bf91..c203476502 100644 --- a/src/vendorcode/amd/opensil/turin_poc/Makefile.mk +++ b/src/vendorcode/amd/opensil/turin_poc/Makefile.mk @@ -1,5 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only +CFLAGS_opensil = -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas + subdirs-y += mpio CPPFLAGS_common += -I$(opensil_dir)/Include -I$(opensil_dir)/xUSL -I$(opensil_dir)/xUSL/Include -I$(opensil_dir)/xUSL/FCH -I$(opensil_dir)/xUSL/FCH/Common -I$(opensil_dir)/xSIM -I$(opensil_dir)/xPRF @@ -12,7 +14,7 @@ ramstage-y += memmap.c ramstage-y += opensil_console.c ramstage-y += ramstage.c -$(obj)/romstage/vendorcode/amd/opensil/turin_poc/opensil_console.o: CFLAGS_romstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas -$(obj)/romstage/vendorcode/amd/opensil/turin_poc/romstage.o: CFLAGS_romstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas +$(obj)/romstage/vendorcode/amd/opensil/turin_poc/opensil_console.o: CFLAGS_romstage += $(CFLAGS_opensil) +$(obj)/romstage/vendorcode/amd/opensil/turin_poc/romstage.o: CFLAGS_romstage += $(CFLAGS_opensil) -$(obj)/ramstage/vendorcode/amd/opensil/turin_poc/opensil_console.o: CFLAGS_ramstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas +$(obj)/ramstage/vendorcode/amd/opensil/turin_poc/opensil_console.o: CFLAGS_ramstage += $(CFLAGS_opensil) diff --git a/src/vendorcode/amd/opensil/turin_poc/acpi.c b/src/vendorcode/amd/opensil/turin_poc/acpi.c index fcdf167c12..dc172e3311 100644 --- a/src/vendorcode/amd/opensil/turin_poc/acpi.c +++ b/src/vendorcode/amd/opensil/turin_poc/acpi.c @@ -4,13 +4,13 @@ #include #include #include -#include +#include #include "../opensil.h" void opensil_fill_fadt(acpi_fadt_t *fadt) { - FCHHWACPI_INPUT_BLK *blk = SilFindStructure(SilId_FchHwAcpiP, 0); + FCHHWACPI_INPUT_BLK *blk = SilFindStructure(SilId_FchHwAcpiP, 0); fadt->pm1a_evt_blk = blk->AcpiPm1EvtBlkAddr; fadt->pm1a_cnt_blk = blk->AcpiPm1CntBlkAddr; diff --git a/src/vendorcode/amd/opensil/turin_poc/filter.h b/src/vendorcode/amd/opensil/turin_poc/filter.h index f0817f7502..84f1db1f38 100644 --- a/src/vendorcode/amd/opensil/turin_poc/filter.h +++ b/src/vendorcode/amd/opensil/turin_poc/filter.h @@ -1,14 +1,19 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* Keep this in sync with openSIL SilCommon.h file */ -#define DEBUG_FILTER_APOB 0x00000001UL -#define DEBUG_FILTER_NBIO 0x00000002UL -#define DEBUG_FILTER_CCX 0x00000004UL -#define DEBUG_FILTER_SMU 0x00000008UL -#define DEBUG_FILTER_DF 0x00000010UL -#define DEBUG_FILTER_MEM 0x00000040UL -#define DEBUG_FILTER_FCH 0x00000080UL -#define DEBUG_FILTER_RAS 0x00000100UL +#define DEBUG_FILTER_APOB 0x00000001UL +#define DEBUG_FILTER_NBIO 0x00000002UL +#define DEBUG_FILTER_CCX 0x00000004UL +#define DEBUG_FILTER_SMU 0x00000008UL +#define DEBUG_FILTER_DF 0x00000010UL +#define DEBUG_FILTER_MPIO 0x00000020UL +#define DEBUG_FILTER_MEM 0x00000040UL +#define DEBUG_FILTER_FCH 0x00000080UL +#define DEBUG_FILTER_RAS 0x00000100UL +#define DEBUG_FILTER_CXL 0x00000200UL +#define DEBUG_FILTER_SDXI 0x00000400UL +#define DEBUG_FILTER_RCMGR 0x00000800UL +#define DEBUG_FILTER_XUSL_CMN 0x00001000UL #define SIL_DEBUG(topic) (CONFIG(OPENSIL_DEBUG_##topic) ? DEBUG_FILTER_##topic : 0) @@ -18,6 +23,11 @@ SIL_DEBUG(CCX) | \ SIL_DEBUG(SMU) | \ SIL_DEBUG(DF) | \ + SIL_DEBUG(MPIO) | \ SIL_DEBUG(MEM) | \ SIL_DEBUG(FCH) | \ - SIL_DEBUG(RAS) ) + SIL_DEBUG(RAS) | \ + SIL_DEBUG(CXL) | \ + SIL_DEBUG(SDXI) | \ + SIL_DEBUG(RCMGR) | \ + SIL_DEBUG(XUSL_CMN) ) diff --git a/src/vendorcode/amd/opensil/turin_poc/memmap.c b/src/vendorcode/amd/opensil/turin_poc/memmap.c index eed1be7e5f..cf95b312e5 100644 --- a/src/vendorcode/amd/opensil/turin_poc/memmap.c +++ b/src/vendorcode/amd/opensil/turin_poc/memmap.c @@ -1,8 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include -#include // needed above ApobCmn.h -#include +#include +#include // needed above ApobCmn.h +#include #include #include "../opensil.h" @@ -46,7 +47,7 @@ const char *opensil_get_hole_info_type(uint32_t type) void opensil_get_hole_info(uint32_t *n_holes, uint64_t *top_of_mem, void **hole_info) { - SIL_STATUS status = xPrfGetSystemMemoryMap(n_holes, top_of_mem, hole_info); + SIL_STATUS status = xPrfGetSystemMemoryMap(n_holes, top_of_mem, hole_info); SIL_STATUS_report("xPrfGetSystemMemoryMap", status); // Make sure hole_info does not get initialized to something odd by xPRF on failure if (status != SilPass) { diff --git a/src/vendorcode/amd/opensil/turin_poc/meson_cross.template b/src/vendorcode/amd/opensil/turin_poc/meson_cross.template index 6473b65225..b8fdf618fa 100644 --- a/src/vendorcode/amd/opensil/turin_poc/meson_cross.template +++ b/src/vendorcode/amd/opensil/turin_poc/meson_cross.template @@ -22,6 +22,8 @@ c_args = ['-nostdinc', '-Wno-unused-parameter', # ubiquitous problem in openSIL '-Wno-missing-field-initializers', + # remove after https://github.com/openSIL/openSIL/pull/39 is merged + '-Wno-unused-but-set-variable', ##CLANG_ARGS## ] diff --git a/src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk b/src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk index fafdc5935f..8ee80c97b0 100644 --- a/src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk +++ b/src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk @@ -2,4 +2,4 @@ ramstage-y += chip.c -$(obj)/ramstage/vendorcode/amd/opensil/turin_poc/mpio/chip.o: CFLAGS_ramstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas +$(obj)/ramstage/vendorcode/amd/opensil/turin_poc/mpio/chip.o: CFLAGS_ramstage += $(CFLAGS_opensil) diff --git a/src/vendorcode/amd/opensil/turin_poc/mpio/chip.c b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.c index 587ab81e02..3586245b54 100644 --- a/src/vendorcode/amd/opensil/turin_poc/mpio/chip.c +++ b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.c @@ -2,18 +2,38 @@ #include #include +#include +#include +#include #include #include -#include +#include #include #include #include +#include #include "chip.h" static void mpio_params_config(void) { MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0); + struct device *gnb = DEV_PTR(gnb_0); + struct device *iommu = DEV_PTR(iommu_0); + struct device *psp = DEV_PTR(asp); + struct device *nbif = DEV_PTR(nbif_0); + + mpio_data->CfgNbioSsid = gnb->subsystem_vendor | + ((uint32_t)gnb->subsystem_device << 16); + mpio_data->CfgIommuSsid = iommu->subsystem_vendor | + ((uint32_t)iommu->subsystem_device << 16); + mpio_data->CfgPspccpSsid = psp->subsystem_vendor | + ((uint32_t)psp->subsystem_device << 16); + mpio_data->CfgNbifF0Ssid = nbif->subsystem_vendor | + ((uint32_t)nbif->subsystem_device << 16); + mpio_data->CfgNtbSsid = 0; // Not implemented in OpenSIL + mpio_data->CfgNtbccpSsid = 0; // Not implemented in OpenSIL + mpio_data->CfgDxioClockGating = 1; mpio_data->PcieDxioTimingControlEnable = 0; mpio_data->PCIELinkReceiverDetectionPolling = 0; @@ -24,13 +44,12 @@ static void mpio_params_config(void) mpio_data->DxioPhyProgramming = 1; mpio_data->CfgSkipPspMessage = 1; mpio_data->DxioSaveRestoreModes = 0xff; - mpio_data->AmdAllowCompliance = 0; - mpio_data->AmdAllowCompliance = 0xff; + mpio_data->AmdAllowCompliance = 0xf; mpio_data->SrisEnableMode = 0xff; mpio_data->SrisSkipInterval = 0; mpio_data->SrisSkpIntervalSel = 1; mpio_data->SrisCfgType = 0; - mpio_data->SrisAutoDetectMode = 0xff; + mpio_data->SrisAutoDetectMode = 0xf; mpio_data->SrisAutodetectFactor = 0; mpio_data->SrisLowerSkpOsGenSup = 0; mpio_data->SrisLowerSkpOsRcvSup = 0; @@ -45,28 +64,21 @@ static void mpio_params_config(void) mpio_data->SurpriseDownFeature = 1; mpio_data->LcMultAutoSpdChgOnLastRateEnable = 0; mpio_data->AmdRxMarginEnabled = 1; - mpio_data->CfgPcieCVTestWA = 1; + mpio_data->CfgPcieCVTestWA = 0; mpio_data->CfgPcieAriSupport = 1; mpio_data->CfgNbioCTOtoSC = 0; mpio_data->CfgNbioCTOIgnoreError = 1; - mpio_data->CfgNbioSsid = 0; - mpio_data->CfgIommuSsid = 0; - mpio_data->CfgPspccpSsid = 0; - mpio_data->CfgNtbccpSsid = 0; - mpio_data->CfgNbifF0Ssid = 0; - mpio_data->CfgNtbSsid = 0; mpio_data->AmdPcieSubsystemDeviceID = 0x1453; mpio_data->AmdPcieSubsystemVendorID = 0x1022; mpio_data->GppAtomicOps = 1; mpio_data->GfxAtomicOps = 1; mpio_data->AmdNbioReportEdbErrors = 0; mpio_data->OpnSpare = 0; - mpio_data->AmdPreSilCtrl0 = 0; mpio_data->MPIOAncDataSupport = 1; mpio_data->AfterResetDelay = 0; mpio_data->CfgEarlyLink = 0; mpio_data->AmdCfgExposeUnusedPciePorts = 1; // Show all ports - mpio_data->CfgForcePcieGenSpeed = 0; + mpio_data->CfgForcePcieGenSpeed = 0xff; mpio_data->CfgSataPhyTuning = 0; mpio_data->PcieLinkComplianceModeAllPorts = 0; mpio_data->AmdMCTPEnable = 0; @@ -79,30 +91,64 @@ static void mpio_params_config(void) // A getter and setter, both are needed for this PCD. mpio_data->AmdPciePresetMask32GtAllPort = 0xffffffff; mpio_data->PcieLinkAspmAllPort = 0xff; - mpio_data->SyncHeaderByPass = 1; mpio_data->CxlTempGen5AdvertAltPtcl = 0; + mpio_data->CfgSevSnpSupport = 0; + mpio_data->CfgSevTioSupport = 0; + mpio_data->PcieIdeCapSup = 0; + mpio_data->Master7bitSteeringTag = 1; /* TODO handle this differently on multisocket */ mpio_data->PcieTopologyData.PlatformData[0].Flags = DESCRIPTOR_TERMINATE_LIST; mpio_data->PcieTopologyData.PlatformData[0].PciePortList = mpio_data->PcieTopologyData.PortList; } +static void cxl_params_config(void) +{ + CXLCLASS_DATA_BLK *cxl_data = SilFindStructure(SilId_CxlClass, 0); + CXLCLASS_INPUT_BLK *input = &cxl_data->CxlInputBlock; + input->AmdPcieAerReportMechanism = 1; +} + static void nbio_params_config(void) { NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0); - NBIOCLASS_INPUT_BLK *input = &nbio_data->NbioInputBlk; - input->CfgHdAudioEnable = false; - input->EsmEnableAllRootPorts = false; - input->EsmTargetSpeed = 16; - input->CfgRxMarginPersistenceMode = 1; - input->CfgDxioFrequencyVetting = false; - input->CfgSkipPspMessage = 1; - input->CfgEarlyTrainTwoPcieLinks = false; - input->EarlyBmcLinkTraining = true; - input->EdpcEnable = 0; - input->PcieAerReportMechanism = 2; - input->SevSnpSupport = false; + NBIO_CONFIG_DATA *input = &nbio_data->NbioConfigData; + input->EsmEnableAllRootPorts = false; + input->EsmTargetSpeed = 16; + input->CfgRxMarginPersistenceMode = 1; + input->SevSnpSupport = false; + input->AerEnRccDev0 = false; + input->CfgAEREnable = true; + input->AtomicRoutingEnStrap5 = true; + input->CfgSriovEnDev0F1 = true; + input->CfgAriEnDev0F1 = true; + input->CfgAerEnDev0F1 = true; + input->CfgAcsEnDev0F1 = true; + input->CfgAtsEnDev0F1 = true; + input->CfgPasidEnDev0F1 = true; + input->CfgRtrEnDev0F1 = true; + input->CfgPriEnDev0F1 = true; + input->CfgPwrEnDev0F1 = true; + input->AtcEnable = true; + input->NbifDev0F1AtomicRequestEn = true; + input->AcsEnRccDev0 = true; + input->AcsP2pReq = true; + input->AcsSourceVal = true; + input->RccDev0E2EPrefix = true; + input->RccDev0ExtendedFmtSupported = true; + input->CfgSyshubMgcgClkGating = 1; + input->IoApicIdPreDefineEn = true; + /* Up to 16 IOAPICs for 2 sockets (8 per socket) */ + input->IoApicIdBase = 240; + input->IommuAvicSupport = true; + + if (CONFIG(XAPIC_ONLY) || CONFIG(X2APIC_LATE_WORKAROUND)) + input->AmdApicMode = xApicMode; + else if (CONFIG(X2APIC_ONLY)) + input->AmdApicMode = x2ApicMode; + else + input->AmdApicMode = ApicAutoMode; } static void setup_bmc_lanes(uint8_t lane, uint8_t socket) @@ -111,16 +157,11 @@ static void setup_bmc_lanes(uint8_t lane, uint8_t socket) rc_mgr_input_block->BmcSocket = socket; rc_mgr_input_block->EarlyBmcLinkLaneNum = lane; - NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0); - NBIOCLASS_INPUT_BLK *nbio_input = &nbio_data->NbioInputBlk; - nbio_input->EarlyBmcLinkSocket = socket; - nbio_input->EarlyBmcLinkLaneNum = lane; - nbio_input->EarlyBmcLinkDie = 0; - MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0); mpio_data->EarlyBmcLinkSocket = socket; mpio_data->EarlyBmcLinkLaneNum = lane; mpio_data->EarlyBmcLinkDie = 0; + mpio_data->EarlyBmcLinkTraining = true; } void opensil_mpio_per_device_config(struct device *dev) @@ -198,5 +239,6 @@ void opensil_mpio_per_device_config(struct device *dev) void opensil_mpio_global_config(void) { mpio_params_config(); + cxl_params_config(); nbio_params_config(); } diff --git a/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h index ce5468cbde..db6a094ed4 100644 --- a/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h +++ b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h @@ -8,13 +8,13 @@ /* * TURIN MPIO mapping * P0 -> [0-15] - * G0 -> [16-31] + * P3 -> [16-31] * P1 -> [32-47] - * G1 -> [48-63] - * P2 -> [64-79] - * G2 -> [80-95] - * P3 -> [96-111] - * G3 -> [112-127] + * P2 -> [48-63] + * G1 -> [64-79] + * G3 -> [80-95] + * G0 -> [96-111] + * G2 -> [112-127] * P4 -> [128-131] * P5 -> [132-136] */ diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil b/src/vendorcode/amd/opensil/turin_poc/opensil new file mode 160000 index 0000000000..a65485ffa7 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/opensil @@ -0,0 +1 @@ +Subproject commit a65485ffa7bddec696576323c6fc839ea5bb081d diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil_config.template b/src/vendorcode/amd/opensil/turin_poc/opensil_config.template index 2ddd3b4ec1..1bbc650990 100644 --- a/src/vendorcode/amd/opensil/turin_poc/opensil_config.template +++ b/src/vendorcode/amd/opensil/turin_poc/opensil_config.template @@ -2,4 +2,4 @@ CONFIG_PLAT_APOB_ADDRESS=##APOB_BASE## CONFIG_PSP_BIOS_BIN_BASE=##BIOS_ENTRY_BASE## CONFIG_PSP_BIOS_BIN_SIZE=##BIOS_ENTRY_SIZE## CONFIG_PLAT_NUMBER_SOCKETS=1 -CONFIG_SOC_F19M10=y +CONFIG_SOC_F1AM00=y diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil_console.c b/src/vendorcode/amd/opensil/turin_poc/opensil_console.c index 35e5eeb2b4..7a7d451f72 100644 --- a/src/vendorcode/amd/opensil/turin_poc/opensil_console.c +++ b/src/vendorcode/amd/opensil/turin_poc/opensil_console.c @@ -14,11 +14,13 @@ static int translate_opensil_debug_level(size_t MsgLevel) return BIOS_ERR; case SIL_TRACE_WARNING: return BIOS_WARNING; + case SIL_TRACE_INFO: + return BIOS_DEBUG; case SIL_TRACE_ENTRY: case SIL_TRACE_EXIT: + case SIL_TRACE_RAW: + case SIL_TRACE_VERBOSE: return BIOS_SPEW; - case SIL_TRACE_INFO: - return BIOS_DEBUG; default: return BIOS_NEVER; } @@ -32,9 +34,26 @@ void HostDebugService(size_t MsgLevel, const char *SilPrefix, const char *Messag const int loglevel = translate_opensil_debug_level(MsgLevel); - /* print fomatted prefix */ - if (CONFIG(OPENSIL_DEBUG_PREFIX)) - printk(loglevel, "%s%s:%zu:", SilPrefix, Function, Line); + /* print formatted prefix */ + if (CONFIG(OPENSIL_DEBUG_PREFIX)) { + switch (MsgLevel) { + case SIL_TRACE_RAW: break; // Raw print do nothing + case SIL_TRACE_ENTRY: + printk(loglevel, "%s Enter %s:%zu:", SilPrefix, Function, Line); + break; + case SIL_TRACE_EXIT: + printk(loglevel, "%s Exit %s:%zu:", SilPrefix, Function, Line); + break; + case SIL_TRACE_ERROR: + case SIL_TRACE_WARNING: + case SIL_TRACE_INFO: + case SIL_TRACE_VERBOSE: + /* fallthrough */ + default: + printk(loglevel, "%s%s:%zu:", SilPrefix, Function, Line); + break; + } + } /* print formatted message */ va_list args; diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil_console.h b/src/vendorcode/amd/opensil/turin_poc/opensil_console.h index d3ffb6857f..424f002d37 100644 --- a/src/vendorcode/amd/opensil/turin_poc/opensil_console.h +++ b/src/vendorcode/amd/opensil/turin_poc/opensil_console.h @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef _VENDORCODE_AND_OPENSIL_CONSOLE -#define _VENDORCODE_AND_OPENSIL_CONSOLE +#ifndef _VENDORCODE_AMD_OPENSIL_CONSOLE +#define _VENDORCODE_AMD_OPENSIL_CONSOLE + +#include void HostDebugService(size_t MsgLevel, const char *SilPrefix, const char *Message, const char *Function, size_t Line, ...); diff --git a/src/vendorcode/amd/opensil/turin_poc/ramstage.c b/src/vendorcode/amd/opensil/turin_poc/ramstage.c index f4474f0be5..f206ef5f58 100644 --- a/src/vendorcode/amd/opensil/turin_poc/ramstage.c +++ b/src/vendorcode/amd/opensil/turin_poc/ramstage.c @@ -1,13 +1,25 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include +/* opensil_config.h needed for PROJ_MAX_* defines */ +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include #include #include +#include #include +#include +#include #include #include #include @@ -16,6 +28,64 @@ #include "opensil_console.h" #include "../opensil.h" + +#define TURIN_USB_STRUCT_MAJOR_VERSION 0xd +#define TURIN_USB_STRUCT_MINOR_VERSION 0x13 + +#define TURIN_USB_PORT_PER_CONTROLLER 2 +#define TURIN_USB_CONTROLLERS_PER_SOCKET 2 +#define TURIN_NUM_USB_PORTS \ + (TURIN_USB_PORT_PER_CONTROLLER * TURIN_USB_CONTROLLERS_PER_SOCKET) + +/* + * Structures copied from Genoa POC code, because Turin POC does not define these. + * It appears the USB structures are identical for Turin and Genoa. + */ +typedef struct { + uint8_t COMPDSTUNE; + uint8_t SQRXTUNE; + uint8_t TXFSLSTUNE; + uint8_t TXPREEMPAMPTUNE; + uint8_t TXPREEMPPULSETUNE; + uint8_t TXRISETUNE; + uint8_t TXVREFTUNE; + uint8_t TXHSXVTUNE; + uint8_t TXRESTUNE; +} __packed FCH_USB20_PHY; + +typedef struct { + uint8_t RX_ANA_IQ_PHASE_ADJUST; + uint8_t RX_EQ_DELTA_IQ_OVRD_EN; + uint8_t RX_EQ_DELTA_IQ_OVRD_VAL; + uint8_t RX_IQ_PHASE_ADJUST; + uint8_t TX_VBOOST_LVL_EN; + uint8_t TX_VBOOST_LVL; + uint8_t RX_VREF_CTRL_EN; + uint8_t RX_VREF_CTRL; + uint8_t TX_VBOOST_LVL_EN_X; + uint8_t TX_VBOOST_LVL_X; + uint8_t RX_VREF_CTRL_EN_X; + uint8_t RX_VREF_CTRL_X; +} __packed FCH_USB31_PHY; + +typedef struct { + uint8_t Version_Major; + uint8_t Version_Minor; + uint8_t TableLength; + uint8_t Reserved0; + uint8_t Usb20PhyEnable; + FCH_USB20_PHY Usb20PhyPort[TURIN_NUM_USB_PORTS]; + uint8_t Reserved1; + uint8_t S1Usb20PhyEnable; + FCH_USB20_PHY S1Usb20PhyPort[TURIN_NUM_USB_PORTS]; + uint8_t Usb31PhyEnable; + FCH_USB31_PHY Usb31PhyPort[TURIN_NUM_USB_PORTS]; + uint8_t S1Usb31PhyEnable; + FCH_USB31_PHY S1Usb31PhyPort[TURIN_NUM_USB_PORTS]; +} __packed FCH_USB_OEM_PLATFORM_TABLE; + +static FCH_USB_OEM_PLATFORM_TABLE usb_config = { 0 }; + void SIL_STATUS_report(const char *function, const int status) { const int log_level = status == SilPass ? BIOS_DEBUG : BIOS_ERR; @@ -42,30 +112,52 @@ void SIL_STATUS_report(const char *function, const int status) int i; for (i = 0; i < ARRAY_SIZE(errors); i++) { - if (errors[i].status == status) + if (errors[i].status == status) { error_string = errors[i].string; + break; + } } printk(log_level, "%s returned %d (%s)\n", function, status, error_string); } static void setup_rc_manager_default(void) { - DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0); + DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0); + /* Let openSIL distribute the resources to the different PCI roots */ rc_mgr_input_block->SetRcBasedOnNv = false; /* Currently 1P is the only supported configuration */ rc_mgr_input_block->SocketNumber = 1; - rc_mgr_input_block->RbsPerSocket = 4; /* PCI root bridges per socket */ + rc_mgr_input_block->RbsPerSocket = 8; /* PCI root bridges per socket */ rc_mgr_input_block->McptEnable = true; rc_mgr_input_block->PciExpressBaseAddress = CONFIG_ECAM_MMCONF_BASE_ADDRESS; rc_mgr_input_block->BottomMmioReservedForPrimaryRb = 4ull * GiB - 32 * MiB; rc_mgr_input_block->MmioSizePerRbForNonPciDevice = 16 * MiB; - /* MmioAbove4GLimit will be adjusted down in openSIL */ - rc_mgr_input_block->MmioAbove4GLimit = POWER_OF_2(cpu_phys_address_size()); + /* + * Turin has 52 bits of available physical address space without SME + * enabled. To avoid using 5-level paging (which we do not support yet + * in coreboot and UEFI payload) required to cover MMIO above 48 bits + * of address space (since 4-level paging can cover only 48 bits of + * physical address space), limit the MMIO to maximum of 48 bits. + * MmioAbove4GLimit will be adjusted down in openSIL if needed. + */ + rc_mgr_input_block->MmioAbove4GLimit = POWER_OF_2(MIN(48, cpu_phys_address_size())); rc_mgr_input_block->Above4GMmioSizePerRbForNonPciDevice = 0; } +static void setup_data_fabric_default(void) +{ + DFCLASS_INPUT_BLK *df_input_block = SilFindStructure(SilId_DfClass, 0); + + if (!df_input_block) { + printk(BIOS_ERR, "OpenSIL: Data Fabric block not found\n"); + return; + } + + df_input_block->AmdPciExpressBaseAddress = CONFIG_ECAM_MMCONF_BASE_ADDRESS; +} + #define NUM_XHCI_CONTROLLERS 2 static void configure_usb(void) { @@ -73,6 +165,7 @@ static void configure_usb(void) const struct soc_usb_config *usb = &soc_config->usb; FCHUSB_INPUT_BLK *fch_usb_data = SilFindStructure(SilId_FchUsb, 0); + fch_usb_data->Xhci0Enable = usb->xhci0_enable; fch_usb_data->Xhci1Enable = usb->xhci1_enable; fch_usb_data->Xhci2Enable = false; /* there's no XHCI2 on this SoC */ @@ -85,25 +178,37 @@ static void configure_usb(void) fch_usb_data->XhciOcPolarityCfgLow = usb->polarity_cfg_low; fch_usb_data->Usb3PortForceGen1 = usb->usb3_force_gen1.raw; - /* Instead of overwriting the whole OemUsbConfigurationTable, only copy the relevant - fields to the pre-populated data structure */ - fch_usb_data->OemUsbConfigurationTable.Usb31PhyEnable = usb->usb31_phy_enable; - if (usb->usb31_phy_enable) - memcpy(&fch_usb_data->OemUsbConfigurationTable.Usb31PhyPort, usb->usb31_phy, - sizeof(fch_usb_data->OemUsbConfigurationTable.Usb31PhyPort)); - fch_usb_data->OemUsbConfigurationTable.Usb31PhyEnable = usb->s1_usb31_phy_enable; - if (usb->s1_usb31_phy_enable) - memcpy(&fch_usb_data->OemUsbConfigurationTable.S1Usb31PhyPort, usb->s1_usb31_phy, - sizeof(fch_usb_data->OemUsbConfigurationTable.S1Usb31PhyPort)); + memset(&usb_config, 0, sizeof(usb_config)); + + usb_config.Version_Major = TURIN_USB_STRUCT_MAJOR_VERSION; + usb_config.Version_Minor = TURIN_USB_STRUCT_MINOR_VERSION; + usb_config.TableLength = sizeof(FCH_USB_OEM_PLATFORM_TABLE); + + usb_config.Usb31PhyEnable = usb->usb31_phy_enable; + memcpy(usb_config.Usb31PhyPort, usb->usb31_phy, sizeof(usb_config.Usb31PhyPort)); + + usb_config.S1Usb31PhyEnable = usb->s1_usb31_phy_enable; + memcpy(usb_config.S1Usb31PhyPort, usb->s1_usb31_phy, sizeof(usb_config.S1Usb31PhyPort)); + + fch_usb_data->OemUsbConfigurationTable = (uintptr_t)&usb_config; } #define NUM_SATA_CONTROLLERS 4 static void configure_sata(void) { FCHSATA_INPUT_BLK *fch_sata_data = SilFindStructure(SilId_FchSata, 0); - FCH_SATA2 *fch_sata_defaults = GetFchSataData(); + FCHSATA_INPUT_BLK *fch_sata_defaults = FchSataGetInputBlk(); + struct device *sata[NUM_SATA_CONTROLLERS] = { + DEV_PTR(sata_2_0), + DEV_PTR(sata_2_1), + DEV_PTR(sata_7_0), + DEV_PTR(sata_7_1) + }; + for (int i = 0; i < NUM_SATA_CONTROLLERS; i++) { fch_sata_data[i] = fch_sata_defaults[i]; + fch_sata_data[i].SataAhciSsid = (sata[i])->subsystem_vendor | + ((uint32_t)((sata[i])->subsystem_device) << 16); fch_sata_data[i].SataSetMaxGen2 = false; fch_sata_data[i].SataMsiEnable = true; fch_sata_data[i].SataEspPort = 0xFF; @@ -115,6 +220,93 @@ static void configure_sata(void) } } +static void configure_fch_isa(void) +{ + FCHISA_INPUT_BLK *fch_isa_data = SilFindStructure(SilId_FchIsa, 0); + struct device *lpc = DEV_PTR(lpc_bridge); + + fch_isa_data->LpcConfig.LpcSsid = lpc->subsystem_vendor | + ((uint32_t)lpc->subsystem_device << 16); + + /* Keep defaults that were set by either EFS or coreboot */ + fch_isa_data->SpiConfig.SpiSpeed = 0; + fch_isa_data->SpiConfig.SpiTpmSpeed = 0; + fch_isa_data->SpiConfig.WriteSpeed = 0; +} + +#define FCH_DEV_ENABLE(dev, aoac_bit) \ + fch_data->FchRunTime.FchDeviceEnableMap |= ((DEV_PTR(dev))->enabled ? aoac_bit : 0) + +static void configure_fch_acpi(void) +{ + FCHHWACPI_INPUT_BLK *fch_hwacpi_data = SilFindStructure(SilId_FchHwAcpiP, 0); + FCHCLASS_INPUT_BLK *fch_data = SilFindStructure(SilId_FchClass, 0); + struct device *smb = DEV_PTR(smbus); + + fch_data->Smbus.SmbusSsid = smb->subsystem_vendor | + ((uint32_t)smb->subsystem_device << 16); + + fch_data->FchBldCfg.CfgSioPmeBaseAddress = 0; + fch_data->FchBldCfg.CfgAcpiPm1EvtBlkAddr = ACPI_PM_EVT_BLK; + fch_data->FchBldCfg.CfgAcpiPm1CntBlkAddr = ACPI_PM1_CNT_BLK; + fch_data->FchBldCfg.CfgAcpiPmTmrBlkAddr = ACPI_PM_TMR_BLK; + fch_data->FchBldCfg.CfgCpuControlBlkAddr = ACPI_CSTATE_CONTROL; + fch_data->FchBldCfg.CfgAcpiGpe0BlkAddr = ACPI_GPE0_BLK; + fch_data->FchBldCfg.CfgSmiCmdPortAddr = APM_CNT; + + fch_data->CfgIoApicIdPreDefEnable = true; + fch_data->FchIoApicId = 128; + + fch_data->WdtEnable = false; + + /* Servers usually don't have KBC on SIO */ + fch_data->Misc.NoneSioKbcSupport = true; + + fch_hwacpi_data->PwrFailShadow = (CONFIG_MAINBOARD_POWER_FAILURE_STATE == 2) ? + 3 : CONFIG_MAINBOARD_POWER_FAILURE_STATE; + + fch_data->FchRunTime.FchDeviceEnableMap = 0; + FCH_DEV_ENABLE(i2c_0, FCH_AOAC_DEV_I2C0); + FCH_DEV_ENABLE(i2c_1, FCH_AOAC_DEV_I2C1); + FCH_DEV_ENABLE(i2c_2, FCH_AOAC_DEV_I2C2); + FCH_DEV_ENABLE(i2c_3, FCH_AOAC_DEV_I2C3); + FCH_DEV_ENABLE(i2c_4, FCH_AOAC_DEV_I2C4); + FCH_DEV_ENABLE(i2c_5, FCH_AOAC_DEV_I2C5); + FCH_DEV_ENABLE(uart_0, FCH_AOAC_DEV_UART0); + FCH_DEV_ENABLE(uart_1, FCH_AOAC_DEV_UART1); + FCH_DEV_ENABLE(uart_2, FCH_AOAC_DEV_UART2); + FCH_DEV_ENABLE(i3c_0, FCH_AOAC_DEV_I3C0); + FCH_DEV_ENABLE(i3c_1, FCH_AOAC_DEV_I3C1); + FCH_DEV_ENABLE(i3c_2, FCH_AOAC_DEV_I3C2); + FCH_DEV_ENABLE(i3c_3, FCH_AOAC_DEV_I3C3); +} + +static void configure_sdxi(void) +{ + MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0); + SDXICLASS_INPUT_BLK *sdxi_data = SilFindStructure(SilId_SdxiClass, 0); + + mpio_data->AmdFabricSdxi = true; + sdxi_data->AmdFabricSdxi = true; +} + +static void configure_ccx(void) +{ + CCXCLASS_DATA_BLK *ccx_data = SilFindStructure(SilId_CcxClass, 0); + + if (CONFIG(XAPIC_ONLY) || CONFIG(X2APIC_LATE_WORKAROUND)) + ccx_data->CcxInputBlock.AmdApicMode = xApicMode; + else if (CONFIG(X2APIC_ONLY)) + ccx_data->CcxInputBlock.AmdApicMode = x2ApicMode; + else + ccx_data->CcxInputBlock.AmdApicMode = ApicAutoMode; + + ccx_data->CcxInputBlock.EnableAvx512 = 1; + ccx_data->CcxInputBlock.EnableSvmX2AVIC = 1; + ccx_data->CcxInputBlock.EnableSvmAVIC = true; + ccx_data->CcxInputBlock.AmdCStateIoBaseAddress = ACPI_CSTATE_CONTROL; +} + void setup_opensil(void) { const SIL_STATUS debug_ret = SilDebugSetup(HostDebugService); @@ -127,8 +319,13 @@ void setup_opensil(void) SIL_STATUS_report("xSimAssignMemory", assign_mem_ret); setup_rc_manager_default(); + setup_data_fabric_default(); + configure_ccx(); + configure_fch_isa(); + configure_fch_acpi(); configure_usb(); configure_sata(); + configure_sdxi(); } static void opensil_entry(SIL_TIMEPOINT timepoint) @@ -138,13 +335,13 @@ static void opensil_entry(SIL_TIMEPOINT timepoint) switch (tp) { case SIL_TP1: - ret = InitializeSiTp1(); + ret = InitializeAMDSiTp1(); break; case SIL_TP2: - ret = InitializeSiTp2(); + ret = InitializeAMDSiTp2(); break; case SIL_TP3: - ret = InitializeSiTp3(); + ret = InitializeAMDSiTp3(); break; default: printk(BIOS_ERR, "Unknown openSIL timepoint\n"); @@ -176,5 +373,3 @@ void opensil_xSIM_timepoint_3(void) { opensil_entry(SIL_TP3); } - -/* TODO: also call timepoints 2 and 3 from coreboot. Are they NOOP? */ From 90a5942254e50a85f022e3f2bfaf99efe68a0812 Mon Sep 17 00:00:00 2001 From: Luca Lai Date: Mon, 26 Jan 2026 10:28:53 +0800 Subject: [PATCH 296/789] mb/fatcat/var/ruby: Remove rtd3 setting I checked with the EE team. The previous status was neither D3hot nor D3cold; it was in idle state, with power consumption around 1W. With the locally tested BIOS that includes this change, the system now enters D3hot and the power consumption is reduced to about 0.4W, achieving the power-saving goal. BUG=b:475990377 BRANCH=none TEST=Build and boot to OS, check the code change could obtain power saving. Change-Id: Ib407e68dc70509e4431d87993597cd096dc0d9bc Signed-off-by: Luca Lai Reviewed-on: https://review.coreboot.org/c/coreboot/+/90907 Reviewed-by: YH Lin Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/mainboard/google/fatcat/variants/ruby/overridetree.cb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/mainboard/google/fatcat/variants/ruby/overridetree.cb b/src/mainboard/google/fatcat/variants/ruby/overridetree.cb index 0ad94b8912..f2a4e75198 100644 --- a/src/mainboard/google/fatcat/variants/ruby/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/ruby/overridetree.cb @@ -265,13 +265,6 @@ chip soc/intel/pantherlake .clk_req = 6, .flags = PCIE_RP_CLK_REQ_DETECT | PCIE_RP_LTR | PCIE_RP_AER, }" - chip soc/intel/common/block/pcie/rtd3 - register "is_storage" = "true" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B16)" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_B09)" - register "srcclk_pin" = "6" - device generic 0 on end - end end # Gen4 M.2 SSD device ref cnvi_wifi on From 4a71e5fe6643b3e2b0c4b1bc21ed4a5d9fe62d80 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 15:38:47 -0600 Subject: [PATCH 297/789] tree: Remove Ice Lake PCI ID remnants Commit ad6e3c847f4b ("tree: Drop Intel Ice Lake support") removed most of the Ice Lake PCI IDs, but missed the ones with the ICP prefix (Ice Point? Ice Lake Point?). Remove all PCI_DID_INTEL_ICP* defines and references in common block drivers. Change-Id: I9d33c69d174130aa781a00441fca367e0a67bcb4 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90904 Reviewed-by: Maximilian Brune Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- src/include/device/pci_ids.h | 35 ------------------- .../intel/common/block/fast_spi/fast_spi.c | 1 - src/soc/intel/common/block/i2c/i2c.c | 6 ---- src/soc/intel/common/block/pcie/pcie.c | 16 --------- src/soc/intel/common/block/pmc/pmc.c | 1 - src/soc/intel/common/block/sata/sata.c | 1 - src/soc/intel/common/block/smbus/smbus.c | 1 - src/soc/intel/common/block/spi/spi.c | 3 -- src/soc/intel/common/block/uart/uart.c | 3 -- src/soc/intel/common/block/xdci/xdci.c | 1 - src/soc/intel/common/block/xhci/xhci.c | 1 - 11 files changed, 69 deletions(-) diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h index ed3ba38d99..d990b86a02 100644 --- a/src/include/device/pci_ids.h +++ b/src/include/device/pci_ids.h @@ -3525,23 +3525,6 @@ #define PCI_DID_INTEL_CNL_LP_PCIE_RP15 0x9db6 #define PCI_DID_INTEL_CNL_LP_PCIE_RP16 0x9db7 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP1 0x34b8 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP2 0x34b9 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP3 0x34ba -#define PCI_DID_INTEL_ICP_LP_PCIE_RP4 0x34bb -#define PCI_DID_INTEL_ICP_LP_PCIE_RP5 0x34bc -#define PCI_DID_INTEL_ICP_LP_PCIE_RP6 0x34bd -#define PCI_DID_INTEL_ICP_LP_PCIE_RP7 0x34be -#define PCI_DID_INTEL_ICP_LP_PCIE_RP8 0x34bf -#define PCI_DID_INTEL_ICP_LP_PCIE_RP9 0x34b0 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP10 0x34b1 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP11 0x34b2 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP12 0x34b3 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP13 0x34b4 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP14 0x34b5 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP15 0x34b6 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP16 0x34b7 - #define PCI_DID_INTEL_TGP_LP_PCIE_RP1 0xa0b8 #define PCI_DID_INTEL_TGP_LP_PCIE_RP2 0xa0b9 #define PCI_DID_INTEL_TGP_LP_PCIE_RP3 0xa0ba @@ -3930,7 +3913,6 @@ #define PCI_DID_INTEL_CNP_H_SATA 0xa352 #define PCI_DID_INTEL_CNP_H_HALO_SATA 0xa353 #define PCI_DID_INTEL_CNP_LP_SATA 0x9dd3 -#define PCI_DID_INTEL_ICP_U_SATA 0x34d3 #define PCI_DID_INTEL_CMP_SATA 0x02d5 #define PCI_DID_INTEL_CMP_PREMIUM_SATA 0x02d7 #define PCI_DID_INTEL_CMP_LP_SATA 0x02d3 @@ -3980,7 +3962,6 @@ #define PCI_DID_INTEL_GLK_PMC 0x3194 #define PCI_DID_INTEL_CNL_PMC 0x9da1 #define PCI_DID_INTEL_CNP_H_PMC 0xa321 -#define PCI_DID_INTEL_ICP_PMC 0x34a1 #define PCI_DID_INTEL_CMP_PMC 0x02a1 #define PCI_DID_INTEL_CMP_H_PMC 0x06a1 #define PCI_DID_INTEL_TGP_PMC 0xa0a1 @@ -4043,12 +4024,6 @@ #define PCI_DID_INTEL_CNP_H_I2C1 0xa369 #define PCI_DID_INTEL_CNP_H_I2C2 0xa36a #define PCI_DID_INTEL_CNP_H_I2C3 0xa36b -#define PCI_DID_INTEL_ICP_I2C0 0x34e8 -#define PCI_DID_INTEL_ICP_I2C1 0x34e9 -#define PCI_DID_INTEL_ICP_I2C2 0x34ea -#define PCI_DID_INTEL_ICP_I2C3 0x34eb -#define PCI_DID_INTEL_ICP_I2C4 0x34c5 -#define PCI_DID_INTEL_ICP_I2C5 0x34c6 #define PCI_DID_INTEL_CMP_I2C0 0x02e8 #define PCI_DID_INTEL_CMP_I2C1 0x02e9 #define PCI_DID_INTEL_CMP_I2C2 0x02ea @@ -4201,9 +4176,6 @@ #define PCI_DID_INTEL_CNP_H_UART0 0xa328 #define PCI_DID_INTEL_CNP_H_UART1 0xa329 #define PCI_DID_INTEL_CNP_H_UART2 0xa347 -#define PCI_DID_INTEL_ICP_UART0 0x34a8 -#define PCI_DID_INTEL_ICP_UART1 0x34a9 -#define PCI_DID_INTEL_ICP_UART2 0x34c7 #define PCI_DID_INTEL_CMP_UART0 0x02a8 #define PCI_DID_INTEL_CMP_UART1 0x02a9 #define PCI_DID_INTEL_CMP_UART2 0x02c7 @@ -4306,10 +4278,6 @@ #define PCI_DID_INTEL_CNP_H_SPI1 0xa32b #define PCI_DID_INTEL_CNP_H_SPI2 0xa37b #define PCI_DID_INTEL_CNP_H_HWSEQ_SPI 0xa324 -#define PCI_DID_INTEL_ICP_SPI0 0x34aa -#define PCI_DID_INTEL_ICP_SPI1 0x34ab -#define PCI_DID_INTEL_ICP_SPI2 0x34fb -#define PCI_DID_INTEL_ICP_HWSEQ_SPI 0x34a4 #define PCI_DID_INTEL_CMP_SPI0 0x02aa #define PCI_DID_INTEL_CMP_SPI1 0x02ab #define PCI_DID_INTEL_CMP_SPI2 0x02fb @@ -4781,7 +4749,6 @@ #define PCI_DID_INTEL_LWB_SMBUS_SUPER 0xa223 #define PCI_DID_INTEL_CNL_SMBUS 0x9da3 #define PCI_DID_INTEL_CNP_H_SMBUS 0xa323 -#define PCI_DID_INTEL_ICP_LP_SMBUS 0x34a3 #define PCI_DID_INTEL_CMP_SMBUS 0x02a3 #define PCI_DID_INTEL_CMP_H_SMBUS 0x06a3 #define PCI_DID_INTEL_TGP_LP_SMBUS 0xa0a3 @@ -4822,7 +4789,6 @@ #define PCI_DID_INTEL_UPT_H_XHCI 0xa2af #define PCI_DID_INTEL_CNL_LP_XHCI 0x9ded #define PCI_DID_INTEL_CNP_H_XHCI 0xa36d -#define PCI_DID_INTEL_ICP_LP_XHCI 0x34ed #define PCI_DID_INTEL_CMP_LP_XHCI 0x02ed #define PCI_DID_INTEL_CMP_H_XHCI 0x06ed #define PCI_DID_INTEL_TGP_LP_XHCI 0xa0ed @@ -5086,7 +5052,6 @@ #define PCI_DID_INTEL_SPT_LP_XDCI 0x9d30 #define PCI_DID_INTEL_CNL_LP_XDCI 0x9dee #define PCI_DID_INTEL_CNP_H_XDCI 0xa36e -#define PCI_DID_INTEL_ICP_LP_XDCI 0x34ee #define PCI_DID_INTEL_CMP_LP_XDCI 0x02ee #define PCI_DID_INTEL_CMP_H_XDCI 0x06ee #define PCI_DID_INTEL_TGP_LP_XDCI 0xa0ee diff --git a/src/soc/intel/common/block/fast_spi/fast_spi.c b/src/soc/intel/common/block/fast_spi/fast_spi.c index 627ab28e9b..a939369ecd 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi.c +++ b/src/soc/intel/common/block/fast_spi/fast_spi.c @@ -572,7 +572,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_CMP_H_HWSEQ_SPI, PCI_DID_INTEL_CNL_HWSEQ_SPI, PCI_DID_INTEL_CNP_H_HWSEQ_SPI, - PCI_DID_INTEL_ICP_HWSEQ_SPI, PCI_DID_INTEL_JSP_HWSEQ_SPI, PCI_DID_INTEL_LWB_SPI, PCI_DID_INTEL_LWB_SPI_SUPER, diff --git a/src/soc/intel/common/block/i2c/i2c.c b/src/soc/intel/common/block/i2c/i2c.c index 161e61fc47..7609b217a3 100644 --- a/src/soc/intel/common/block/i2c/i2c.c +++ b/src/soc/intel/common/block/i2c/i2c.c @@ -248,12 +248,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_CNP_H_I2C1, PCI_DID_INTEL_CNP_H_I2C2, PCI_DID_INTEL_CNP_H_I2C3, - PCI_DID_INTEL_ICP_I2C0, - PCI_DID_INTEL_ICP_I2C1, - PCI_DID_INTEL_ICP_I2C2, - PCI_DID_INTEL_ICP_I2C3, - PCI_DID_INTEL_ICP_I2C4, - PCI_DID_INTEL_ICP_I2C5, PCI_DID_INTEL_CMP_I2C0, PCI_DID_INTEL_CMP_I2C1, PCI_DID_INTEL_CMP_I2C2, diff --git a/src/soc/intel/common/block/pcie/pcie.c b/src/soc/intel/common/block/pcie/pcie.c index 4b64f85b8a..31e70d6edc 100644 --- a/src/soc/intel/common/block/pcie/pcie.c +++ b/src/soc/intel/common/block/pcie/pcie.c @@ -249,22 +249,6 @@ static const unsigned short pcie_device_ids[] = { PCI_DID_INTEL_CNP_H_PCIE_RP22, PCI_DID_INTEL_CNP_H_PCIE_RP23, PCI_DID_INTEL_CNP_H_PCIE_RP24, - PCI_DID_INTEL_ICP_LP_PCIE_RP1, - PCI_DID_INTEL_ICP_LP_PCIE_RP2, - PCI_DID_INTEL_ICP_LP_PCIE_RP3, - PCI_DID_INTEL_ICP_LP_PCIE_RP4, - PCI_DID_INTEL_ICP_LP_PCIE_RP5, - PCI_DID_INTEL_ICP_LP_PCIE_RP6, - PCI_DID_INTEL_ICP_LP_PCIE_RP7, - PCI_DID_INTEL_ICP_LP_PCIE_RP8, - PCI_DID_INTEL_ICP_LP_PCIE_RP9, - PCI_DID_INTEL_ICP_LP_PCIE_RP10, - PCI_DID_INTEL_ICP_LP_PCIE_RP11, - PCI_DID_INTEL_ICP_LP_PCIE_RP12, - PCI_DID_INTEL_ICP_LP_PCIE_RP13, - PCI_DID_INTEL_ICP_LP_PCIE_RP14, - PCI_DID_INTEL_ICP_LP_PCIE_RP15, - PCI_DID_INTEL_ICP_LP_PCIE_RP16, PCI_DID_INTEL_CMP_LP_PCIE_RP1, PCI_DID_INTEL_CMP_LP_PCIE_RP2, PCI_DID_INTEL_CMP_LP_PCIE_RP3, diff --git a/src/soc/intel/common/block/pmc/pmc.c b/src/soc/intel/common/block/pmc/pmc.c index 80db323ac6..0b7a9495ce 100644 --- a/src/soc/intel/common/block/pmc/pmc.c +++ b/src/soc/intel/common/block/pmc/pmc.c @@ -129,7 +129,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_APL_PMC, PCI_DID_INTEL_GLK_PMC, PCI_DID_INTEL_CNP_H_PMC, - PCI_DID_INTEL_ICP_PMC, PCI_DID_INTEL_CMP_PMC, PCI_DID_INTEL_CMP_H_PMC, PCI_DID_INTEL_TGP_PMC, diff --git a/src/soc/intel/common/block/sata/sata.c b/src/soc/intel/common/block/sata/sata.c index f406096c85..0f85faed50 100644 --- a/src/soc/intel/common/block/sata/sata.c +++ b/src/soc/intel/common/block/sata/sata.c @@ -60,7 +60,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_CNP_H_SATA, PCI_DID_INTEL_CNP_H_HALO_SATA, PCI_DID_INTEL_CNP_LP_SATA, - PCI_DID_INTEL_ICP_U_SATA, PCI_DID_INTEL_CMP_SATA, PCI_DID_INTEL_CMP_PREMIUM_SATA, PCI_DID_INTEL_CMP_LP_SATA, diff --git a/src/soc/intel/common/block/smbus/smbus.c b/src/soc/intel/common/block/smbus/smbus.c index dba5ed29d8..ebaf655499 100644 --- a/src/soc/intel/common/block/smbus/smbus.c +++ b/src/soc/intel/common/block/smbus/smbus.c @@ -66,7 +66,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_EBG_SMBUS, PCI_DID_INTEL_LWB_SMBUS_SUPER, PCI_DID_INTEL_LWB_SMBUS, - PCI_DID_INTEL_ICP_LP_SMBUS, PCI_DID_INTEL_CMP_SMBUS, PCI_DID_INTEL_CMP_H_SMBUS, PCI_DID_INTEL_TGP_LP_SMBUS, diff --git a/src/soc/intel/common/block/spi/spi.c b/src/soc/intel/common/block/spi/spi.c index 680e14e035..9ac9719c7a 100644 --- a/src/soc/intel/common/block/spi/spi.c +++ b/src/soc/intel/common/block/spi/spi.c @@ -164,9 +164,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_CNP_H_SPI0, PCI_DID_INTEL_CNP_H_SPI1, PCI_DID_INTEL_CNP_H_SPI2, - PCI_DID_INTEL_ICP_SPI0, - PCI_DID_INTEL_ICP_SPI1, - PCI_DID_INTEL_ICP_SPI2, PCI_DID_INTEL_CMP_SPI0, PCI_DID_INTEL_CMP_SPI1, PCI_DID_INTEL_CMP_SPI2, diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index 0e9132d4c1..2b2c8c28fc 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -402,9 +402,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_CNP_H_UART0, PCI_DID_INTEL_CNP_H_UART1, PCI_DID_INTEL_CNP_H_UART2, - PCI_DID_INTEL_ICP_UART0, - PCI_DID_INTEL_ICP_UART1, - PCI_DID_INTEL_ICP_UART2, PCI_DID_INTEL_CMP_UART0, PCI_DID_INTEL_CMP_UART1, PCI_DID_INTEL_CMP_UART2, diff --git a/src/soc/intel/common/block/xdci/xdci.c b/src/soc/intel/common/block/xdci/xdci.c index 6916d8c3f5..3ead495010 100644 --- a/src/soc/intel/common/block/xdci/xdci.c +++ b/src/soc/intel/common/block/xdci/xdci.c @@ -39,7 +39,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_CNL_LP_XDCI, PCI_DID_INTEL_GLK_XDCI, PCI_DID_INTEL_CNP_H_XDCI, - PCI_DID_INTEL_ICP_LP_XDCI, PCI_DID_INTEL_CMP_LP_XDCI, PCI_DID_INTEL_CMP_H_XDCI, PCI_DID_INTEL_TGP_LP_XDCI, diff --git a/src/soc/intel/common/block/xhci/xhci.c b/src/soc/intel/common/block/xhci/xhci.c index d12792dbb8..5eb73ed562 100644 --- a/src/soc/intel/common/block/xhci/xhci.c +++ b/src/soc/intel/common/block/xhci/xhci.c @@ -145,7 +145,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_LWB_XHCI, PCI_DID_INTEL_LWB_XHCI_SUPER, PCI_DID_INTEL_CNP_H_XHCI, - PCI_DID_INTEL_ICP_LP_XHCI, PCI_DID_INTEL_CMP_LP_XHCI, PCI_DID_INTEL_CMP_H_XHCI, PCI_DID_INTEL_TGP_LP_XHCI, From 23f97be6102e121903b8e356be8e61dc139d979a Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 16:31:26 -0600 Subject: [PATCH 298/789] soc/intel/jasperlake: Add initial chipset.cb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to other Intel SoCs, create a chipset.cb for Jasperlake giving alias names to all known PCI devices. Taken from comments in existing JSL board devicetrees, cross-referenced against the publicly available JSL EDS. At the same time, remove the usb2_lte device aliases in the BOTEN and DRAWCIA dedede variants, and replace their references with the new usb2_port4 alias, since we can only have a single alias per device. TEST=build boten and drawcia dedede variants Change-Id: I32552dbe0ab5305ea44b5e89432603884cf6589f Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90899 Tested-by: build bot (Jenkins) Reviewed-by: Jérémy Compostella Reviewed-by: Sean Rhodes Reviewed-by: Jakub "Kuba" Czapiga --- .../dedede/variants/boten/overridetree.cb | 2 +- .../dedede/variants/drawcia/overridetree.cb | 2 +- .../google/dedede/variants/drawcia/ramstage.c | 2 +- src/soc/intel/jasperlake/Kconfig | 4 + src/soc/intel/jasperlake/chipset.cb | 100 ++++++++++++++++++ 5 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 src/soc/intel/jasperlake/chipset.cb diff --git a/src/mainboard/google/dedede/variants/boten/overridetree.cb b/src/mainboard/google/dedede/variants/boten/overridetree.cb index 56b2d935bc..a1c33fa809 100644 --- a/src/mainboard/google/dedede/variants/boten/overridetree.cb +++ b/src/mainboard/google/dedede/variants/boten/overridetree.cb @@ -156,7 +156,7 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "10" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 2.3 alias usb2_lte on end + device usb 2.3 on end end chip drivers/usb/acpi register "desc" = ""UFCamera"" diff --git a/src/mainboard/google/dedede/variants/drawcia/overridetree.cb b/src/mainboard/google/dedede/variants/drawcia/overridetree.cb index 3ba688fb67..12e45d9308 100644 --- a/src/mainboard/google/dedede/variants/drawcia/overridetree.cb +++ b/src/mainboard/google/dedede/variants/drawcia/overridetree.cb @@ -163,7 +163,7 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 2.3 alias lte_usb2 on + device usb 2.3 on probe DB_PORTS DB_PORTS_1A_HDMI_LTE end end diff --git a/src/mainboard/google/dedede/variants/drawcia/ramstage.c b/src/mainboard/google/dedede/variants/drawcia/ramstage.c index be1b253219..543d7457a8 100644 --- a/src/mainboard/google/dedede/variants/drawcia/ramstage.c +++ b/src/mainboard/google/dedede/variants/drawcia/ramstage.c @@ -18,7 +18,7 @@ static void ext_vr_update(void) static void update_lte_device_drawcia(void) { - struct device *lte_usb2 = DEV_PTR(lte_usb2); + struct device *lte_usb2 = DEV_PTR(usb2_port4); struct drivers_usb_acpi_config *config; struct acpi_gpio lte_reset_gpio = ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H0); diff --git a/src/soc/intel/jasperlake/Kconfig b/src/soc/intel/jasperlake/Kconfig index 727e9609ce..e80028ae80 100644 --- a/src/soc/intel/jasperlake/Kconfig +++ b/src/soc/intel/jasperlake/Kconfig @@ -105,6 +105,10 @@ config IFD_CHIPSET string default "jsl" +config CHIPSET_DEVICETREE + string + default "soc/intel/jasperlake/chipset.cb" + config IED_REGION_SIZE hex default 0x400000 diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb new file mode 100644 index 0000000000..f713d22595 --- /dev/null +++ b/src/soc/intel/jasperlake/chipset.cb @@ -0,0 +1,100 @@ +chip soc/intel/jasperlake + + device cpu_cluster 0 on end + + device domain 0 on + device pci 00.0 alias system_agent on end + device pci 02.0 alias igpu off end + device pci 04.0 alias dptf off end + device pci 05.0 alias ipu off end + device pci 08.0 alias gna off end + device pci 09.0 alias north_tracehub off end + device pci 12.0 alias ish off end + device pci 12.5 alias ufs_scs off end + device pci 12.6 alias gspi2 off end + device pci 14.0 alias south_xhci off + chip drivers/usb/acpi + register "type" = "UPC_TYPE_HUB" + device usb 0.0 alias xhci_root_hub off + chip drivers/usb/acpi + device usb 2.0 alias usb2_port1 off end + end + chip drivers/usb/acpi + device usb 2.1 alias usb2_port2 off end + end + chip drivers/usb/acpi + device usb 2.2 alias usb2_port3 off end + end + chip drivers/usb/acpi + device usb 2.3 alias usb2_port4 off end + end + chip drivers/usb/acpi + device usb 2.4 alias usb2_port5 off end + end + chip drivers/usb/acpi + device usb 2.5 alias usb2_port6 off end + end + chip drivers/usb/acpi + device usb 2.6 alias usb2_port7 off end + end + chip drivers/usb/acpi + device usb 2.7 alias usb2_port8 off end + end + chip drivers/usb/acpi + device usb 3.0 alias usb3_port1 off end + end + chip drivers/usb/acpi + device usb 3.1 alias usb3_port2 off end + end + chip drivers/usb/acpi + device usb 3.2 alias usb3_port3 off end + end + chip drivers/usb/acpi + device usb 3.3 alias usb3_port4 off end + end + chip drivers/usb/acpi + device usb 3.4 alias usb3_port5 off end + end + chip drivers/usb/acpi + device usb 3.5 alias usb3_port6 off end + end + end + end + end + device pci 14.1 alias south_xdci off end + device pci 14.2 alias shared_ram off end + device pci 14.3 alias cnvi_wifi off end + device pci 14.5 alias sdxc off end + device pci 15.0 alias i2c0 off end + device pci 15.1 alias i2c1 off end + device pci 15.2 alias i2c2 off end + device pci 15.3 alias i2c3 off end + device pci 16.0 alias heci1 off end + device pci 16.1 alias heci2 off end + device pci 16.4 alias heci3 off end + device pci 17.0 alias sata off end + device pci 19.0 alias i2c4 off end + device pci 19.1 alias i2c5 off end + device pci 19.2 alias uart2 off end + device pci 1a.0 alias emmc off end + device pci 1c.0 alias pcie_rp1 off end + device pci 1c.1 alias pcie_rp2 off end + device pci 1c.2 alias pcie_rp3 off end + device pci 1c.3 alias pcie_rp4 off end + device pci 1c.4 alias pcie_rp5 off end + device pci 1c.5 alias pcie_rp6 off end + device pci 1c.6 alias pcie_rp7 off end + device pci 1c.7 alias pcie_rp8 off end + device pci 1e.0 alias uart0 off end + device pci 1e.1 alias uart1 off end + device pci 1e.2 alias gspi0 off end + device pci 1e.3 alias gspi1 off end + device pci 1f.0 alias pch_espi on end + device pci 1f.1 alias p2sb hidden end + device pci 1f.2 alias pmc hidden end + device pci 1f.3 alias hda off end + device pci 1f.4 alias smbus off end + device pci 1f.5 alias fast_spi on end + device pci 1f.7 alias south_tracehub off end + end +end From c7b016bb7f964574c86741ba375d8ada94cdd575 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 17:16:20 -0600 Subject: [PATCH 299/789] mb/google/dedede: Use aliases in device/overridetrees Convert all PCI device and USB port references in dedede baseboard devicetree and variant overridetrees to use aliases from the Jasperlake chipset.cb instead of direct device/function numbers. This improves maintainability by using symbolic names, and reduces file size by eliminating entries which match those in the chipset or baseboard devicetrees. TEST=Build all dedede variants Change-Id: I00c8f79ab040cd634ea94d4d596128ef3d6f7e73 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90900 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- .../dedede/variants/awasuki/overridetree.cb | 54 ++++------ .../dedede/variants/baseboard/devicetree.cb | 102 ++++++------------ .../dedede/variants/beadrix/overridetree.cb | 30 +++--- .../dedede/variants/blipper/overridetree.cb | 28 ++--- .../dedede/variants/boten/overridetree.cb | 42 ++++---- .../dedede/variants/boxy/overridetree.cb | 41 ++++--- .../dedede/variants/bugzzy/overridetree.cb | 41 ++++--- .../dedede/variants/cappy2/overridetree.cb | 30 +++--- .../dedede/variants/corori/overridetree.cb | 41 +++---- .../dedede/variants/cret/overridetree.cb | 42 ++++---- .../dedede/variants/dexi/overridetree.cb | 49 +++++---- .../dedede/variants/dibbi/overridetree.cb | 48 ++++----- .../dedede/variants/dita/overridetree.cb | 49 +++++---- .../dedede/variants/drawcia/overridetree.cb | 44 ++++---- .../dedede/variants/driblee/overridetree.cb | 43 +++----- .../dedede/variants/galtic/overridetree.cb | 24 ++--- .../dedede/variants/gooey/overridetree.cb | 47 ++++---- .../dedede/variants/haboki/overridetree.cb | 35 +++--- .../dedede/variants/kracko/overridetree.cb | 42 ++++---- .../dedede/variants/lalala/overridetree.cb | 33 +++--- .../dedede/variants/lantis/overridetree.cb | 36 +++---- .../dedede/variants/madoo/overridetree.cb | 36 +++---- .../dedede/variants/magolor/overridetree.cb | 30 +++--- .../variants/metaknight/overridetree.cb | 24 ++--- .../dedede/variants/pirika/overridetree.cb | 24 ++--- .../dedede/variants/sasuke/overridetree.cb | 26 +++-- .../dedede/variants/sasukette/overridetree.cb | 25 +++-- .../dedede/variants/shotzo/overridetree.cb | 46 ++++---- .../dedede/variants/storo/overridetree.cb | 37 ++++--- .../dedede/variants/taranza/overridetree.cb | 49 +++++---- .../dedede/variants/waddledee/overridetree.cb | 30 +++--- .../dedede/variants/waddledoo/overridetree.cb | 30 +++--- 32 files changed, 573 insertions(+), 685 deletions(-) diff --git a/src/mainboard/google/dedede/variants/awasuki/overridetree.cb b/src/mainboard/google/dedede/variants/awasuki/overridetree.cb index f791468b2b..570403f81f 100644 --- a/src/mainboard/google/dedede/variants/awasuki/overridetree.cb +++ b/src/mainboard/google/dedede/variants/awasuki/overridetree.cb @@ -84,7 +84,7 @@ chip soc/intel/jasperlake register "SdCardPowerEnableActiveHigh" = "0" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## sensor information register "options.tsr[0].desc" = ""Ambient"" @@ -134,48 +134,30 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on - chip drivers/usb/acpi - device usb 2.1 off end - end - chip drivers/usb/acpi - device usb 2.3 off end - end - chip drivers/usb/acpi - device usb 2.4 off end - end + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""User Facing Camera"" register "type" = "UPC_TYPE_INTERNAL" register "has_power_resource" = "true" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D15)" register "enable_delay_ms" = "20" - device usb 2.5 on end - end - chip drivers/usb/acpi - device usb 2.6 off end - end - chip drivers/usb/acpi - device usb 3.1 off end - end - chip drivers/usb/acpi - device usb 3.3 off end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 14.3 on + end + device ref cnvi_wifi on chip drivers/wifi/generic register "wake" = "GPE0_PME_B0" register "enable_cnvi_ddr_rfim" = "true" register "add_acpi_dma_property" = "true" device generic 0 on end end - end # CNVi wifi - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""PNP0C50"" register "generic.desc" = ""PIXART Touchpad"" @@ -185,8 +167,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 15 on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on probe TOUCHSCREEN TOUCHSCREEN_PRESENT chip drivers/i2c/generic register "hid" = ""ELAN0001"" @@ -206,8 +188,8 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" device i2c 10 on end end - end # I2C 2 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/rt5645 register "hid" = ""10EC5650"" register "name" = ""RT58"" @@ -217,20 +199,20 @@ chip soc/intel/jasperlake register "jd_mode" = "2" device i2c 1a on end end - end # I2C 4 - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 1f.3 on + end + device ref hda on chip drivers/sof register "spkr_tplg" = "rt5650_sp" register "jack_tplg" = "rt5650_hp" register "mic_tplg" = "_2ch_pdm0" device generic 0 on end end - end # Intel HDA/cAVS + end end end diff --git a/src/mainboard/google/dedede/variants/baseboard/devicetree.cb b/src/mainboard/google/dedede/variants/baseboard/devicetree.cb index 05c77da3e5..240c3e6c4b 100644 --- a/src/mainboard/google/dedede/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/dedede/variants/baseboard/devicetree.cb @@ -228,11 +228,10 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "9" device domain 0 on - device pci 00.0 on end # Host Bridge - device pci 02.0 on + device ref igpu on register "gfx" = "GMA_DEFAULT_PANEL(0)" - end # Integrated Graphics Device - device pci 04.0 on + end + device ref dptf on # Default DPTF Policy for all Dedede boards if not overridden chip drivers/intel/dptf ## Passive Policy @@ -283,132 +282,96 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 05.0 off end # IPU - device pci 08.0 on end # GNA - device pci 09.0 off end # Intel Trace Hub - device pci 12.6 off end # GSPI 2 - device pci 14.0 on + end + device ref gna on end + device ref south_xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.3 on end - end - chip drivers/usb/acpi - device usb 2.4 off end - end - chip drivers/usb/acpi - device usb 2.5 off end - end - chip drivers/usb/acpi - device usb 2.6 off end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.7 on end + device ref usb2_port8 on end end chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 14.1 off end # USB xDCI (OTG) - device pci 14.2 on end # PMC SRAM - device pci 14.3 on + end + device ref shared_ram on end + device ref cnvi_wifi on chip drivers/wifi/generic register "wake" = "GPE0_PME_B0" device generic 0 on end end - end # CNVi wifi - device pci 14.5 on end # SDCard - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 16.0 on end # HECI 1 - device pci 16.1 off end # HECI 2 - device pci 16.4 off end # HECI 3 - device pci 16.5 off end # HECI 4 - device pci 17.0 off end # SATA - device pci 19.0 off end # I2C 4 - device pci 19.1 off end # I2C 5 - device pci 19.2 on end # UART 2 - device pci 1a.0 on end # eMMC - device pci 1c.0 off end # PCI Express Root Port 1 - device pci 1c.1 off end # PCI Express Root Port 2 - device pci 1c.2 off end # PCI Express Root Port 3 - device pci 1c.3 off end # PCI Express Root Port 4 - device pci 1c.4 off end # PCI Express Root Port 5 - device pci 1c.5 off end # PCI Express Root Port 6 - device pci 1c.6 off end # PCI Express Root Port 7 - # External PCIe port 4 is mapped to PCIe Root port 8 - device pci 1c.7 off end # PCI Express Root Port 8 - hosts M.2 E-key WLAN - device pci 1e.0 off end # UART 0 - device pci 1e.1 off end # UART 1 - device pci 1e.2 on + end + device ref sdxc on end + device ref heci1 on end + device ref i2c4 on end + device ref uart2 on end + device ref emmc on end + device ref gspi0 on chip drivers/spi/acpi register "hid" = "ACPI_DT_NAMESPACE_HID" register "compat_string" = ""google,cr50"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_B4_IRQ)" device spi 0 on end end - end # GSPI 0 - device pci 1e.3 off end # GSPI 1 - device pci 1f.0 on + end + device ref pch_espi on chip ec/google/chromeec device pnp 0c09.0 on end end - end # eSPI Interface - device pci 1f.1 on end # P2SB - device pci 1f.2 hidden end # Power Management Controller - device pci 1f.3 on + end + device ref hda on chip drivers/sof register "spkr_tplg" = "rt1015" register "jack_tplg" = "rt5682" @@ -427,9 +390,6 @@ chip soc/intel/jasperlake probe AUDIO_AMP MAX98360 end end - end # Intel HDA/cAVS - device pci 1f.4 off end # SMBus - device pci 1f.5 on end # PCH SPI - device pci 1f.7 off end # Intel Trace Hub + end end end diff --git a/src/mainboard/google/dedede/variants/beadrix/overridetree.cb b/src/mainboard/google/dedede/variants/beadrix/overridetree.cb index cba95da235..a1c95148ba 100644 --- a/src/mainboard/google/dedede/variants/beadrix/overridetree.cb +++ b/src/mainboard/google/dedede/variants/beadrix/overridetree.cb @@ -60,7 +60,7 @@ chip soc/intel/jasperlake register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" device domain 0 on - device pci 04.0 on + device ref dptf on # Default DPTF Policy for all Dedede boards if not overridden chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" @@ -100,10 +100,10 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 05.0 off end # IPU - MIPI Camera - device pci 14.0 on + device ref ipu off end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" @@ -117,7 +117,7 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on + device ref usb3_port2 on probe DB_PORTS DB_PORTS_1C_LTE probe DB_PORTS DB_PORTS_1C end @@ -135,15 +135,15 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1C_LTE probe DB_PORTS DB_PORTS_LTE end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""PIXA2635"" register "generic.desc" = ""PIXA Touchpad"" @@ -153,8 +153,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 15 on end end - end # I2C 0 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -182,8 +182,8 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end # I2C 4 - device pci 19.1 on + end + device ref i2c5 on chip drivers/i2c/sx9324 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E11_IRQ)" @@ -239,13 +239,13 @@ chip soc/intel/jasperlake probe DB_PORTS DB_PORTS_LTE end end - end # I2C 5 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/blipper/overridetree.cb b/src/mainboard/google/dedede/variants/blipper/overridetree.cb index db0bdc2049..535c0f6934 100644 --- a/src/mainboard/google/dedede/variants/blipper/overridetree.cb +++ b/src/mainboard/google/dedede/variants/blipper/overridetree.cb @@ -63,7 +63,7 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -89,19 +89,19 @@ chip soc/intel/jasperlake .granularity = 1000,}" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -120,8 +120,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""GTCH7503"" register "generic.desc" = ""G2 Touchscreen"" @@ -157,8 +157,8 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" device i2c 10 on end end - end # I2C 2 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -186,12 +186,12 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end # I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/boten/overridetree.cb b/src/mainboard/google/dedede/variants/boten/overridetree.cb index a1c33fa809..5e3614c0b4 100644 --- a/src/mainboard/google/dedede/variants/boten/overridetree.cb +++ b/src/mainboard/google/dedede/variants/boten/overridetree.cb @@ -89,7 +89,7 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "0" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -136,17 +136,17 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -156,33 +156,33 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "10" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""WFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -201,8 +201,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -254,8 +254,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 10 on end end - end # I2C 2 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -301,8 +301,8 @@ chip soc/intel/jasperlake probe AUDIO_AMP UNPROVISIONED end end - end # I2C 4 - device pci 19.1 on + end + device ref i2c5 on chip drivers/i2c/sx9324 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E11_IRQ)" @@ -355,14 +355,14 @@ chip soc/intel/jasperlake register "reg_irq_cfg2" = "0x00" device i2c 28 on end end - end # I2C 5 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/boxy/overridetree.cb b/src/mainboard/google/dedede/variants/boxy/overridetree.cb index 11c7ae399e..f3fb01df4b 100644 --- a/src/mainboard/google/dedede/variants/boxy/overridetree.cb +++ b/src/mainboard/google/dedede/variants/boxy/overridetree.cb @@ -90,7 +90,7 @@ chip soc/intel/jasperlake USB_PORT_WAKE_ENABLE(4)" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -139,62 +139,62 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C1"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C1"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -221,8 +221,8 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end # I2C 4 - device pci 1c.2 on + end + device ref pcie_rp3 on chip drivers/net register "customized_leds" = "0x07af" register "wake" = "GPE0_DW0_03" # GPP_B3 @@ -230,14 +230,13 @@ chip soc/intel/jasperlake register "device_index" = "0" device pci 00.0 on end end - end # PCI Express Root Port 3 - RTL8111H LAN - device pci 1c.6 on + end + device ref pcie_rp7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 7 - WLAN - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb b/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb index a1303d7a4f..441707e940 100644 --- a/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb +++ b/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb @@ -94,7 +94,7 @@ chip soc/intel/jasperlake register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" register "options.tsr[1].desc" = ""CPU"" @@ -138,8 +138,8 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 05.0 on # IPU - MIPI Camera + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -153,16 +153,16 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" register "has_power_resource" = "true" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D13)" register "enable_delay_ms" = "20" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -172,14 +172,14 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1C_1A_LTE end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -197,8 +197,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0xE" device i2c 40 on end end - end # I2C 0 - device pci 15.1 on + end + device ref i2c1 on chip drivers/i2c/hid register "generic.hid" = ""WCOM014B"" register "generic.desc" = ""WCOM Digitizer"" @@ -222,8 +222,8 @@ chip soc/intel/jasperlake probe DB_PORTS DB_PORTS_1C_1A_LTE end end - end # I2C #1 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""HX121A"" register "generic.desc" = ""HX Touchscreen"" @@ -236,8 +236,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x1" device i2c 0x4F on end end - end # I2C #2 - device pci 15.3 on + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI8856"" register "acpi_uid" = "0" @@ -310,9 +310,8 @@ chip soc/intel/jasperlake device i2c 50 on end end - end # I2C 3 - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/da7219 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" register "btn_cfg" = "50" @@ -330,13 +329,13 @@ chip soc/intel/jasperlake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/cappy2/overridetree.cb b/src/mainboard/google/dedede/variants/cappy2/overridetree.cb index 2b361a3d93..59c7f9fd1c 100644 --- a/src/mainboard/google/dedede/variants/cappy2/overridetree.cb +++ b/src/mainboard/google/dedede/variants/cappy2/overridetree.cb @@ -77,7 +77,7 @@ chip soc/intel/jasperlake }" # Camera device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -112,22 +112,22 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" register "has_power_resource" = "true" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D15)" register "enable_delay_ms" = "20" - device usb 2.5 on end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0A00"" register "generic.desc" = ""SYNA Touchpad"" @@ -172,8 +172,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -219,13 +219,13 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_CS42l42 end end - end #I2C 4 - device pci 1f.0 on + end + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM - end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1f.3 on + end + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on @@ -239,6 +239,6 @@ chip soc/intel/jasperlake probe AUDIO_AMP MAX98360 end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/corori/overridetree.cb b/src/mainboard/google/dedede/variants/corori/overridetree.cb index 59afb06e93..76aadb44dd 100644 --- a/src/mainboard/google/dedede/variants/corori/overridetree.cb +++ b/src/mainboard/google/dedede/variants/corori/overridetree.cb @@ -44,7 +44,7 @@ chip soc/intel/jasperlake register "SerialIoGSpiCsMode[PchSerialIoIndexGSPI0]" = "0" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -79,31 +79,19 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on - chip drivers/usb/acpi - device usb 2.1 off end - end - chip drivers/usb/acpi - device usb 2.3 off end - end + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera (UFC)"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end - end - chip drivers/usb/acpi - device usb 3.1 off end - end - chip drivers/usb/acpi - device usb 3.3 off end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -112,8 +100,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -143,19 +131,18 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end #I2C 4 - device pci 1e.2 off end # GSPI 0 - device pci 1f.0 on + end + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/cret/overridetree.cb b/src/mainboard/google/dedede/variants/cret/overridetree.cb index f1a00ffb20..aaf7321b90 100644 --- a/src/mainboard/google/dedede/variants/cret/overridetree.cb +++ b/src/mainboard/google/dedede/variants/cret/overridetree.cb @@ -52,7 +52,7 @@ chip soc/intel/jasperlake }, }" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -87,32 +87,26 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on - chip drivers/usb/acpi - device usb 2.1 off end - end + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.3 on + device ref usb2_port4 on probe LTE LTE_PRESENT end end chip drivers/usb/acpi register "desc" = ""Camera (UFC)"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""Camera (WFC)"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end - end - chip drivers/usb/acpi - device usb 3.1 off end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -124,14 +118,14 @@ chip soc/intel/jasperlake register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 3.3 on + device ref usb3_port4 on probe LTE LTE_PRESENT end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -149,8 +143,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 2c on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""WDHT0002"" register "generic.desc" = ""WDT Touchscreen"" @@ -239,9 +233,9 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # I2C 2 - device pci 1c.7 on end - device pci 19.0 on + end + device ref pcie_rp8 on end + device ref i2c4 on chip drivers/i2c/da7219 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" register "btn_cfg" = "50" @@ -280,13 +274,13 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_CS42l42 end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/dexi/overridetree.cb b/src/mainboard/google/dedede/variants/dexi/overridetree.cb index 38a2d520a8..54910d5f4c 100644 --- a/src/mainboard/google/dedede/variants/dexi/overridetree.cb +++ b/src/mainboard/google/dedede/variants/dexi/overridetree.cb @@ -135,7 +135,7 @@ chip soc/intel/jasperlake USB_PORT_WAKE_ENABLE(6)" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -184,86 +184,86 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A2"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A3"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A4"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A4"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A3"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A2"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # USB xHCI - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""RTL5682"" register "name" = ""RT58"" @@ -275,8 +275,8 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end # I2C 4 - device pci 1c.2 on + end + device ref pcie_rp3 on chip drivers/net register "customized_leds" = "0x05af" register "wake" = "GPE0_DW0_03" # GPP_B3 @@ -284,14 +284,13 @@ chip soc/intel/jasperlake register "device_index" = "0" device pci 00.0 on end end - end # PCI Express Root Port 3 - RTL8111H LAN - device pci 1c.6 on + end + device ref pcie_rp7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 7 - WLAN - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/dibbi/overridetree.cb b/src/mainboard/google/dedede/variants/dibbi/overridetree.cb index eb05d24c94..1c6ee0706e 100644 --- a/src/mainboard/google/dedede/variants/dibbi/overridetree.cb +++ b/src/mainboard/google/dedede/variants/dibbi/overridetree.cb @@ -111,7 +111,7 @@ chip soc/intel/jasperlake register "usb3_ports[5]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/1 Type-A Port A3 device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -160,77 +160,74 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A2"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 4)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A3"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 5)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.0 on end - end - chip drivers/usb/acpi - device usb 3.1 off end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A3"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 5)" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A2"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 4)" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # USB xHCI - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""RTL5682"" register "name" = ""RT58"" @@ -242,8 +239,8 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end # I2C 4 - device pci 1c.2 on + end + device ref pcie_rp3 on chip drivers/net register "customized_leds" = "0x05af" register "wake" = "GPE0_DW0_03" # GPP_B3 @@ -251,14 +248,13 @@ chip soc/intel/jasperlake register "device_index" = "0" device pci 00.0 on end end - end # PCI Express Root Port 3 - RTL8111H LAN - device pci 1c.6 on + end + device ref pcie_rp7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 7 - WLAN - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/dita/overridetree.cb b/src/mainboard/google/dedede/variants/dita/overridetree.cb index 38a2d520a8..54910d5f4c 100644 --- a/src/mainboard/google/dedede/variants/dita/overridetree.cb +++ b/src/mainboard/google/dedede/variants/dita/overridetree.cb @@ -135,7 +135,7 @@ chip soc/intel/jasperlake USB_PORT_WAKE_ENABLE(6)" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -184,86 +184,86 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A2"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A3"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A4"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A4"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A3"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A2"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # USB xHCI - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""RTL5682"" register "name" = ""RT58"" @@ -275,8 +275,8 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end # I2C 4 - device pci 1c.2 on + end + device ref pcie_rp3 on chip drivers/net register "customized_leds" = "0x05af" register "wake" = "GPE0_DW0_03" # GPP_B3 @@ -284,14 +284,13 @@ chip soc/intel/jasperlake register "device_index" = "0" device pci 00.0 on end end - end # PCI Express Root Port 3 - RTL8111H LAN - device pci 1c.6 on + end + device ref pcie_rp7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 7 - WLAN - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/drawcia/overridetree.cb b/src/mainboard/google/dedede/variants/drawcia/overridetree.cb index 12e45d9308..8e13098ccc 100644 --- a/src/mainboard/google/dedede/variants/drawcia/overridetree.cb +++ b/src/mainboard/google/dedede/variants/drawcia/overridetree.cb @@ -82,7 +82,7 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 05.0 on # IPU - MIPI Camera + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -97,7 +97,7 @@ chip soc/intel/jasperlake end end - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf # Default DPTF Policy for all drawcia boards if not overridden register "options.tsr[0].desc" = ""Memory"" @@ -150,10 +150,10 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" @@ -163,7 +163,7 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 2.3 on + device ref usb2_port4 on probe DB_PORTS DB_PORTS_1A_HDMI_LTE end end @@ -171,7 +171,7 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.3 on + device ref usb2_port4 on probe DB_PORTS DB_PORTS_1A_HDMI probe DB_PORTS DB_PORTS_1C_1A end @@ -179,13 +179,13 @@ chip soc/intel/jasperlake chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1A_HDMI_LTE end end @@ -193,15 +193,15 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1A_HDMI probe DB_PORTS DB_PORTS_1C_1A end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -220,8 +220,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -296,8 +296,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 2c alias wdht0002 on end end - end # I2C 2 - device pci 15.3 on + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI8856"" register "acpi_uid" = "0" @@ -395,8 +395,8 @@ chip soc/intel/jasperlake register "off_seq.ops[0]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" device i2c 50 on end end - end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -426,19 +426,19 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end #I2C 4 - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end end - device pci 1f.3 on + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/driblee/overridetree.cb b/src/mainboard/google/dedede/variants/driblee/overridetree.cb index a703ada882..23d1875054 100644 --- a/src/mainboard/google/dedede/variants/driblee/overridetree.cb +++ b/src/mainboard/google/dedede/variants/driblee/overridetree.cb @@ -35,7 +35,7 @@ chip soc/intel/jasperlake register "SerialIoGSpiCsMode[PchSerialIoIndexGSPI0]" = "0" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -70,31 +70,19 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on - chip drivers/usb/acpi - device usb 2.1 off end - end - chip drivers/usb/acpi - device usb 2.3 off end - end + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera (UFC)"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end - end - chip drivers/usb/acpi - device usb 3.1 off end - end - chip drivers/usb/acpi - device usb 3.3 off end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -112,8 +100,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 2c on end end - end #I2C 0 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/cs42l42 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_H16)" @@ -130,19 +118,18 @@ chip soc/intel/jasperlake register "hs_bias_sense_disable" = "true" device i2c 48 on end end - end #I2C 4 - device pci 1e.2 off end # GSPI 0 - device pci 1f.0 on + end + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM - end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1f.3 on + end + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/galtic/overridetree.cb b/src/mainboard/google/dedede/variants/galtic/overridetree.cb index 3a5597c3f4..189029b5cd 100644 --- a/src/mainboard/google/dedede/variants/galtic/overridetree.cb +++ b/src/mainboard/google/dedede/variants/galtic/overridetree.cb @@ -69,7 +69,7 @@ chip soc/intel/jasperlake register "tcc_offset" = "8" # TCC of 97C device domain 0 on - device pci 04.0 on + device ref dptf on # Default DPTF Policy for all Dedede boards if not overridden chip drivers/intel/dptf ## Passive Policy @@ -120,20 +120,20 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end end end - end # USB xHCI + end - device pci 15.0 on + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -150,7 +150,7 @@ chip soc/intel/jasperlake device i2c 15 alias elan2702 on end end end - device pci 15.2 on + device ref i2c2 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -183,8 +183,8 @@ chip soc/intel/jasperlake probe TOUCHSCREEN_SOURCE TOUCHSCREEN_ELAN9008 end end - end # I2C 2 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -231,13 +231,13 @@ chip soc/intel/jasperlake end end end - device pci 1f.3 on + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/gooey/overridetree.cb b/src/mainboard/google/dedede/variants/gooey/overridetree.cb index d7e9d47241..0a73b9c471 100644 --- a/src/mainboard/google/dedede/variants/gooey/overridetree.cb +++ b/src/mainboard/google/dedede/variants/gooey/overridetree.cb @@ -68,7 +68,7 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "0" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -115,17 +115,17 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -135,33 +135,33 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "10" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""WFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -180,8 +180,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -233,8 +233,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 10 on end end - end # I2C 2 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -280,8 +280,8 @@ chip soc/intel/jasperlake probe AUDIO_AMP UNPROVISIONED end end - end # I2C 4 - device pci 19.1 on + end + device ref i2c5 on chip drivers/i2c/sx9324 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E11_IRQ)" @@ -335,19 +335,18 @@ chip soc/intel/jasperlake device i2c 28 on end end end # I2C 5 - device pci 1f.0 on + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM - end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1e.2 off end # GSPI 0 - device pci 1f.3 on + end + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/haboki/overridetree.cb b/src/mainboard/google/dedede/variants/haboki/overridetree.cb index 030b143204..7146bd899f 100644 --- a/src/mainboard/google/dedede/variants/haboki/overridetree.cb +++ b/src/mainboard/google/dedede/variants/haboki/overridetree.cb @@ -53,7 +53,7 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 05.0 on # IPU - MIPI Camera + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -68,7 +68,7 @@ chip soc/intel/jasperlake end end - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf # Default DPTF Policy for all drawcia boards if not overridden register "options.tsr[0].desc" = ""Memory"" @@ -122,7 +122,7 @@ chip soc/intel/jasperlake device generic 0 on end end end # SA Thermal device - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi device usb 0.0 on chip drivers/usb/acpi @@ -132,8 +132,8 @@ chip soc/intel/jasperlake end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -142,8 +142,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -210,8 +210,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 15 on end end - end # I2C 2 - device pci 15.3 on + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI8856"" register "acpi_uid" = "0" @@ -284,8 +284,8 @@ chip soc/intel/jasperlake device i2c 50 on end end - end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -298,19 +298,18 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end #I2C 4 - device pci 1f.0 on + end + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM - end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1e.2 off end # GSPI 0 - device pci 1f.3 on + end + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/kracko/overridetree.cb b/src/mainboard/google/dedede/variants/kracko/overridetree.cb index 388850570b..c45ccdc428 100644 --- a/src/mainboard/google/dedede/variants/kracko/overridetree.cb +++ b/src/mainboard/google/dedede/variants/kracko/overridetree.cb @@ -65,7 +65,7 @@ chip soc/intel/jasperlake register "tcc_offset" = "20" # TCC of 85C device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf # Default DPTF Policy for all drawcia boards if not overridden register "options.tsr[0].desc" = ""Memory"" @@ -113,10 +113,10 @@ chip soc/intel/jasperlake }" device generic 0 alias dptf_policy on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" @@ -126,7 +126,7 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 2.3 on + device ref usb2_port4 on probe DB_PORTS DB_PORTS_1C_LTE probe DB_PORTS DB_PORTS_LTE end @@ -135,7 +135,7 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.1 on + device ref usb2_port2 on probe DB_PORTS DB_PORTS_1C_1A probe DB_PORTS DB_PORTS_1C_LTE end @@ -144,25 +144,25 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.3 on + device ref usb2_port4 on probe DB_PORTS DB_PORTS_1C_1A end end chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""WFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on + device ref usb3_port2 on probe DB_PORTS DB_PORTS_1C_1A probe DB_PORTS DB_PORTS_1C_LTE end @@ -171,7 +171,7 @@ chip soc/intel/jasperlake register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1C_LTE probe DB_PORTS DB_PORTS_LTE end @@ -180,14 +180,14 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1C_1A end end end end end # USB xHCI - device pci 15.0 on + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -196,8 +196,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -240,8 +240,8 @@ chip soc/intel/jasperlake device i2c 40 on end end - end # I2C 2 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -270,8 +270,8 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end #I2C 4 - device pci 19.1 on + end + device ref i2c5 on chip drivers/i2c/sx9324 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E11_IRQ)" @@ -324,12 +324,12 @@ chip soc/intel/jasperlake device i2c 28 on end end end # I2C 5 - device pci 1f.3 on + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/lalala/overridetree.cb b/src/mainboard/google/dedede/variants/lalala/overridetree.cb index 90620d6c7d..26569c52ca 100644 --- a/src/mainboard/google/dedede/variants/lalala/overridetree.cb +++ b/src/mainboard/google/dedede/variants/lalala/overridetree.cb @@ -87,7 +87,7 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" register "options.tsr[1].desc" = ""Ambient"" @@ -121,8 +121,8 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 05.0 on # IPU - MIPI Camera + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -135,18 +135,18 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0000"" register "generic.cid" = ""ACPI0C50"" @@ -165,8 +165,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""ELAN6915"" register "generic.desc" = ""ELAN Touchscreen"" @@ -209,7 +209,7 @@ chip soc/intel/jasperlake device i2c 39 on end end end # I2C 2 - device pci 15.3 on # I2C 3 + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI5675"" register "acpi_uid" = "0" @@ -285,7 +285,7 @@ chip soc/intel/jasperlake device i2c 50 on end end end - device pci 19.0 on + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -310,14 +310,13 @@ chip soc/intel/jasperlake device i2c 29 on end end end - device pci 1f.0 on + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1e.2 off end # GSPI 0 - device pci 1f.3 on end # Intel HDA - device pci 1c.7 on + end + device ref hda on end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end diff --git a/src/mainboard/google/dedede/variants/lantis/overridetree.cb b/src/mainboard/google/dedede/variants/lantis/overridetree.cb index c21ccf2643..21e15d43ee 100644 --- a/src/mainboard/google/dedede/variants/lantis/overridetree.cb +++ b/src/mainboard/google/dedede/variants/lantis/overridetree.cb @@ -90,7 +90,7 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" register "options.tsr[1].desc" = ""Ambient"" @@ -141,31 +141,31 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Discrete Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""Integrated Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.7 on end + device ref usb2_port8 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -174,8 +174,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -233,14 +233,14 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 0x5d on end end - end # I2C 2 - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -268,13 +268,13 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/madoo/overridetree.cb b/src/mainboard/google/dedede/variants/madoo/overridetree.cb index c69b482ef0..801b947f1e 100644 --- a/src/mainboard/google/dedede/variants/madoo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/madoo/overridetree.cb @@ -57,7 +57,7 @@ chip soc/intel/jasperlake register "SlowSlewRate" = "2" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf register "policies.passive" = "{ [0] = DPTF_PASSIVE(CPU, CPU, 65, 1000), @@ -81,25 +81,19 @@ chip soc/intel/jasperlake .granularity = 1000,}" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on - chip drivers/usb/acpi - device usb 2.2 off end - end + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end - end - chip drivers/usb/acpi - device usb 3.2 off end + device ref usb2_port6 on end end end end end # USB xHCI - device pci 15.0 on + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -108,8 +102,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""GDIX0000"" register "generic.desc" = ""Goodix Touchscreen"" @@ -125,14 +119,14 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 0x5d on end end - end # I2C 2 - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -145,13 +139,13 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/magolor/overridetree.cb b/src/mainboard/google/dedede/variants/magolor/overridetree.cb index c32429dc24..45cd9971ca 100644 --- a/src/mainboard/google/dedede/variants/magolor/overridetree.cb +++ b/src/mainboard/google/dedede/variants/magolor/overridetree.cb @@ -126,7 +126,7 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" register "options.tsr[1].desc" = ""Ambient"" @@ -160,8 +160,8 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 05.0 on # IPU - MIPI Camera + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -174,7 +174,7 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi device usb 0.0 on chip drivers/usb/acpi @@ -184,8 +184,8 @@ chip soc/intel/jasperlake end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0000"" register "generic.cid" = ""ACPI0C50"" @@ -204,8 +204,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -342,8 +342,8 @@ chip soc/intel/jasperlake probe TS_SOURCE TS_RAYD_0001 end end - end # I2C 2 - device pci 15.3 on # I2C 3 + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI5675"" register "acpi_uid" = "0" @@ -470,7 +470,7 @@ chip soc/intel/jasperlake device i2c 50 on end end end - device pci 19.0 on + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -536,19 +536,19 @@ chip soc/intel/jasperlake end end end - device pci 1f.3 on + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN + end end end diff --git a/src/mainboard/google/dedede/variants/metaknight/overridetree.cb b/src/mainboard/google/dedede/variants/metaknight/overridetree.cb index c116cccdae..631fb5c5df 100644 --- a/src/mainboard/google/dedede/variants/metaknight/overridetree.cb +++ b/src/mainboard/google/dedede/variants/metaknight/overridetree.cb @@ -84,7 +84,7 @@ chip soc/intel/jasperlake }" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" register "options.tsr[1].desc" = ""CPU"" @@ -118,10 +118,10 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" @@ -171,8 +171,8 @@ chip soc/intel/jasperlake end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0000"" register "generic.cid" = ""ACPI0C50"" @@ -191,8 +191,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -238,8 +238,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 15 on end end - end # I2C 2 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -285,13 +285,13 @@ chip soc/intel/jasperlake end end end - device pci 1f.3 on + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/pirika/overridetree.cb b/src/mainboard/google/dedede/variants/pirika/overridetree.cb index d413e060e0..01f724c5fa 100644 --- a/src/mainboard/google/dedede/variants/pirika/overridetree.cb +++ b/src/mainboard/google/dedede/variants/pirika/overridetree.cb @@ -78,7 +78,7 @@ chip soc/intel/jasperlake register "tcc_offset" = "8" # TCC of 97C device domain 0 on - device pci 04.0 on + device ref dptf on # Default DPTF Policy for all Dedede boards if not overridden chip drivers/intel/dptf ## Passive Policy @@ -119,20 +119,20 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end end end - end # USB xHCI + end - device pci 15.0 on + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -152,7 +152,7 @@ chip soc/intel/jasperlake device i2c 0x2c on end end end - device pci 15.2 on + device ref i2c2 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -165,8 +165,8 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" device i2c 10 on end end - end # I2C 2 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -226,13 +226,13 @@ chip soc/intel/jasperlake end end end - device pci 1f.3 on + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/sasuke/overridetree.cb b/src/mainboard/google/dedede/variants/sasuke/overridetree.cb index 6f72562fe9..4be52ff3d2 100644 --- a/src/mainboard/google/dedede/variants/sasuke/overridetree.cb +++ b/src/mainboard/google/dedede/variants/sasuke/overridetree.cb @@ -85,7 +85,7 @@ chip soc/intel/jasperlake register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Charger"" register "options.tsr[1].desc" = ""Vcore"" @@ -123,8 +123,8 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi device usb 0.0 on chip drivers/usb/acpi @@ -133,7 +133,7 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D13)" register "enable_delay_ms" = "20" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -143,12 +143,12 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -166,10 +166,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0xE" device i2c 40 on end end - end # I2C 0 - device pci 15.2 on end - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/da7219 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" register "btn_cfg" = "50" @@ -187,13 +185,13 @@ chip soc/intel/jasperlake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/sasukette/overridetree.cb b/src/mainboard/google/dedede/variants/sasukette/overridetree.cb index aa61b8e11d..90a7a10199 100644 --- a/src/mainboard/google/dedede/variants/sasukette/overridetree.cb +++ b/src/mainboard/google/dedede/variants/sasukette/overridetree.cb @@ -96,7 +96,7 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "0" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -131,8 +131,8 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi device usb 0.0 on chip drivers/usb/acpi @@ -141,7 +141,7 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D15)" register "enable_delay_ms" = "20" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -151,12 +151,12 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0A00"" register "generic.desc" = ""SYNA Touchpad"" @@ -201,8 +201,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -230,13 +230,12 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end #I2C 4 - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/shotzo/overridetree.cb b/src/mainboard/google/dedede/variants/shotzo/overridetree.cb index 7a821d7f8f..b32e39b1c9 100644 --- a/src/mainboard/google/dedede/variants/shotzo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/shotzo/overridetree.cb @@ -67,7 +67,7 @@ chip soc/intel/jasperlake register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" # Lan device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf # Default DPTF Policy for all drawcia boards if not overridden register "options.tsr[0].desc" = ""Ambient"" @@ -111,83 +111,83 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A2"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A3"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 4)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""LAN"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.7 on end + device ref usb2_port8 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""LAN"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on end + device ref usb3_port4 on end end end end end # USB xHCI - device pci 15.2 on + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""ILTK0001"" register "generic.desc" = ""ILITEK Touchscreen"" @@ -202,14 +202,14 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 41 on end end - end # I2C 2 - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""RTL5682"" register "name" = ""RT58"" @@ -222,12 +222,12 @@ chip soc/intel/jasperlake device i2c 1a on end end end #I2C 4 - device pci 1f.3 on + device ref hda on chip drivers/generic/alc1015 register "hid" = ""RTL1019"" register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/storo/overridetree.cb b/src/mainboard/google/dedede/variants/storo/overridetree.cb index f893829dc0..729aff50a2 100644 --- a/src/mainboard/google/dedede/variants/storo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/storo/overridetree.cb @@ -100,7 +100,7 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "0" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -135,8 +135,8 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 05.0 on # IPU - MIPI Camera + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -150,9 +150,9 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""User Facing Camera"" register "type" = "UPC_TYPE_INTERNAL" @@ -179,8 +179,8 @@ chip soc/intel/jasperlake end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -189,8 +189,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -216,8 +216,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 10 on end end - end # I2C 2 - device pci 15.3 on + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI8856"" register "acpi_uid" = "0" @@ -290,8 +290,8 @@ chip soc/intel/jasperlake device i2c 50 on end end - end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -319,14 +319,14 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end # I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA - device pci 19.1 on + end + device ref i2c5 on chip drivers/i2c/sx9324 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E11_IRQ)" @@ -379,7 +379,6 @@ chip soc/intel/jasperlake register "reg_irq_cfg2" = "0x01" device i2c 28 on end end - end # I2C 5 - device pci 1c.7 off end # PCI Express Root Port 8 + end end end diff --git a/src/mainboard/google/dedede/variants/taranza/overridetree.cb b/src/mainboard/google/dedede/variants/taranza/overridetree.cb index 38a2d520a8..54910d5f4c 100644 --- a/src/mainboard/google/dedede/variants/taranza/overridetree.cb +++ b/src/mainboard/google/dedede/variants/taranza/overridetree.cb @@ -135,7 +135,7 @@ chip soc/intel/jasperlake USB_PORT_WAKE_ENABLE(6)" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -184,86 +184,86 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A2"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A3"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A4"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A4"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A3"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A2"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # USB xHCI - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""RTL5682"" register "name" = ""RT58"" @@ -275,8 +275,8 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end # I2C 4 - device pci 1c.2 on + end + device ref pcie_rp3 on chip drivers/net register "customized_leds" = "0x05af" register "wake" = "GPE0_DW0_03" # GPP_B3 @@ -284,14 +284,13 @@ chip soc/intel/jasperlake register "device_index" = "0" device pci 00.0 on end end - end # PCI Express Root Port 3 - RTL8111H LAN - device pci 1c.6 on + end + device ref pcie_rp7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 7 - WLAN - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/waddledee/overridetree.cb b/src/mainboard/google/dedede/variants/waddledee/overridetree.cb index 4fdddd18cc..7356e95625 100644 --- a/src/mainboard/google/dedede/variants/waddledee/overridetree.cb +++ b/src/mainboard/google/dedede/variants/waddledee/overridetree.cb @@ -61,26 +61,26 @@ chip soc/intel/jasperlake register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" device domain 0 on - device pci 05.0 on end # IPU - MIPI Camera - device pci 14.0 on + device ref ipu on end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Discrete Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""Integrated Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.7 on end + device ref usb2_port8 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0000"" register "generic.cid" = ""ACPI0C50"" @@ -92,7 +92,7 @@ chip soc/intel/jasperlake device i2c 0x2c on end end end - device pci 15.2 on + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""SIS6496"" register "generic.desc" = ""SIS Touchscreen"" @@ -125,8 +125,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 0x5d on end end - end # I2C 2 - device pci 15.3 on + end + device ref i2c3 on chip drivers/i2c/gpiomux/mux register "mux_gpio_count" = "1" register "mux_gpio[0]" = "ACPI_GPIO_OUTPUT(GPP_E5)" @@ -139,8 +139,8 @@ chip soc/intel/jasperlake end end # I2C MUX end - end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -165,12 +165,12 @@ chip soc/intel/jasperlake device i2c 29 on end end end - device pci 1c.7 on + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb b/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb index 8a1d5556c1..9b9d308019 100644 --- a/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb @@ -57,7 +57,7 @@ chip soc/intel/jasperlake register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" device domain 0 on - device pci 05.0 on # IPU - MIPI Camera + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -72,9 +72,9 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Discrete Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" @@ -94,8 +94,8 @@ chip soc/intel/jasperlake end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -104,8 +104,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""SIS6496"" register "generic.desc" = ""SIS Touchscreen"" @@ -143,8 +143,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 10 on end end - end # I2C 2 - device pci 15.3 on #I2C #3 CAM0 CAM1 and VCM0 + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI8856"" register "acpi_uid" = "0" @@ -259,13 +259,13 @@ chip soc/intel/jasperlake device i2c 36 on end end end - device pci 1c.7 on + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/da7219 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" register "btn_cfg" = "50" @@ -283,13 +283,13 @@ chip soc/intel/jasperlake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end From 5f666a5f688782662c87be3052f113d1f8c7355f Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 18:35:13 -0600 Subject: [PATCH 300/789] mb/google/dedede/var/cret: Drop unused PCIe RP8 CRET uses CNVi WiFi, not discrete, and has nothing attached to this port, so don't enable it. TEST=build/boot CRET Change-Id: Iac9e01c6ecd4f3f32cd1c39a87a10530a36b40a4 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90901 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- src/mainboard/google/dedede/variants/cret/overridetree.cb | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mainboard/google/dedede/variants/cret/overridetree.cb b/src/mainboard/google/dedede/variants/cret/overridetree.cb index aaf7321b90..3156c9096f 100644 --- a/src/mainboard/google/dedede/variants/cret/overridetree.cb +++ b/src/mainboard/google/dedede/variants/cret/overridetree.cb @@ -234,7 +234,6 @@ chip soc/intel/jasperlake device i2c 40 on end end end - device ref pcie_rp8 on end device ref i2c4 on chip drivers/i2c/da7219 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" From 438d1b1c1ad23c75279667daa14975c8a6650cec Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 17:18:02 -0600 Subject: [PATCH 301/789] mb/intel/jasperlake_rvp: Use aliases in devicetree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert all PCI device and USB port references in the jasperlake_rvp devicetree to use device aliases from the Jasperlake chipset.cb instead of direct device/function numbers. This improves maintainability by using symbolic names, and reduces file size by eliminating entries which match those in the chipset devicetree. Additionally, the p2sb device reference is dropped, as the correct state (hidden) is set by the chipset devicetree. TEST=Build jslrvp Change-Id: I04fd2d1655f08fb0671deeeb55a3e88eb97b7f44 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90902 Reviewed-by: Jérémy Compostella Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- .../variants/jslrvp/devicetree.cb | 98 +++++++------------ 1 file changed, 38 insertions(+), 60 deletions(-) diff --git a/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb b/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb index fadd309dab..4b95f52b36 100644 --- a/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb +++ b/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb @@ -195,9 +195,8 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "9" device domain 0 on - device pci 00.0 on end # Host Bridge - device pci 02.0 on end # Integrated Graphics Device - device pci 04.0 on + device ref igpu on end + device ref dptf on chip drivers/intel/dptf register "policies.passive[0]" = "DPTF_PASSIVE(CPU, CPU, 95, 1000)" register "policies.critical[0]" = "DPTF_CRITICAL(CPU, 119, SHUTDOWN)" @@ -216,9 +215,9 @@ chip soc/intel/jasperlake .granularity = 1000,}" device generic 0 on end end - end # SA Thermal device + end - device pci 05.0 on + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -233,97 +232,92 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 12.0 off end # Thermal Subsystem - device pci 12.5 off end # UFS SCS - device pci 12.6 off end # GSPI #2 - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB3/2 Type-A Left Lower"" register "type" = "UPC_TYPE_A" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""WWAN"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB C Connector 1"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB C Connector 2"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""USB C Connector 3"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""USB C Connector 4"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""USB3/2 Type-A Left Upper"" register "type" = "UPC_TYPE_A" - device usb 2.7 on end + device ref usb2_port8 on end end chip drivers/usb/acpi register "desc" = ""USB3/2 Type-A Left Lower"" register "type" = "UPC_TYPE_A" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3/2 Type-A Left Upper"" register "type" = "UPC_TYPE_A" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""WLAN"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Port Unused1"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Port Unused2"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Port Unused3"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # USB xHCI - device pci 14.1 off end # USB xDCI (OTG) - device pci 14.2 off end # PMC SRAM - device pci 14.3 on + end + device ref cnvi_wifi on chip drivers/wifi/generic register "wake" = "GPE0_PME_B0" device generic 0 on end end - end # CNVi wifi - device pci 14.5 on end # SDCard - device pci 15.0 on + end + device ref sdxc on end + device ref i2c0 on chip drivers/i2c/max98373 register "vmon_slot_no" = "4" register "imon_slot_no" = "5" @@ -357,18 +351,9 @@ chip soc/intel/jasperlake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # I2C #0 Audio - device pci 15.1 off end # I2C #1 - device pci 15.2 off end # I2C #2 - device pci 15.3 off end # I2C #3 - device pci 16.0 on end # Management Engine Interface 1 - device pci 16.1 off end # Management Engine Interface 2 - device pci 16.2 off end # Management Engine IDE-R - device pci 16.3 off end # Management Engine KT Redirection - device pci 16.4 off end # Management Engine Interface 3 - device pci 16.5 off end # Management Engine Interface 4 - device pci 17.0 off end # SATA - device pci 19.0 on # I2C #4 Cam 0 + end + device ref heci1 on end + device ref i2c4 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI2740"" register "acpi_uid" = "0" @@ -407,7 +392,7 @@ chip soc/intel/jasperlake device i2c 10 on end end end - device pci 19.1 on # I2C #5 Cam 1 and VCM + device ref i2c5 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI5675"" register "acpi_uid" = "0" @@ -467,27 +452,20 @@ chip soc/intel/jasperlake end end - device pci 19.2 on end # UART #2 - device pci 1a.0 on end # eMMC - device pci 1c.1 on end # PCI Express Port 2 - M.2 E-key WLAN - device pci 1c.4 on end # PCI Express Port 5 - NVMe - device pci 1e.0 on end # UART #0 - device pci 1e.1 off end # UART #1 - device pci 1e.2 off end # GSPI #0 - device pci 1e.3 on + device ref uart2 on end + device ref emmc on end + device ref pcie_rp2 on end + device ref pcie_rp5 on end + device ref uart0 on end + device ref gspi1 on chip drivers/spi/acpi register "hid" = "ACPI_DT_NAMESPACE_HID" register "compat_string" = ""google,cr50"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_H13_IRQ)" device spi 0 on end end - end # GSPI #1 - device pci 1f.0 on end # eSPI Interface - device pci 1f.1 on end # P2SB - device pci 1f.2 hidden end # Power Management Controller - device pci 1f.3 on end # Intel HDA - device pci 1f.4 on end # SMBus - device pci 1f.5 on end # PCH SPI - device pci 1f.6 off end # GbE + end + device ref hda on end + device ref smbus on end end end From 6bf998765ccc85f1d99bef6be1ea6ca7740baa81 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 27 Jan 2026 20:58:18 +0000 Subject: [PATCH 302/789] mb/starlabs/starfighter/mtl: Correct option name to control wireless This board used the older "wireless" option, which no longer exists to control wireless. Update it to check "wifi". Change-Id: I8ddec94ea729790c9d13cd54516b8802df0e77aa Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90957 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/starfighter/variants/mtl/romstage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c b/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c index 486912cbfe..4a50059cd5 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c +++ b/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c @@ -100,7 +100,7 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) mupd->FspmConfig.VtdDisable = !vtd; /* Enable/Disable Wireless (RP09) based on CMOS settings */ - if (get_uint_option("wireless", 1) == 0) + if (get_uint_option("wifi", 1) == 0) mupd->FspmConfig.PcieRpEnableMask &= ~(1 << 8); /* Enable/Disable Thunderbolt based on CMOS settings */ From 90b819b2793c82a33747aeb883de04d80487e14c Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 27 Jan 2026 20:59:28 +0000 Subject: [PATCH 303/789] mb/starlabs/starfighter/mtl: Add missing control for Bluetooth This board was missing the control of Bluetooth; add it so it matches all the other Star Labs boards. Change-Id: I11e39b4c02095b762717ff041a654838fd4c5897 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90958 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/starfighter/variants/mtl/devtree.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c b/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c index c4b0da67fd..5ac632b4b7 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c +++ b/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c @@ -15,6 +15,10 @@ void devtree_update(void) config_t *cfg = config_of_soc(); update_power_limits(cfg); + /* Enable/Disable Bluetooth based on CMOS settings */ + if (get_uint_option("bluetooth", 1) == 0) + cfg->usb2_ports[9].enable = 0; + /* Enable/Disable Webcam based on CMOS settings */ if (get_uint_option("webcam", 1) == 0) cfg->usb2_ports[CONFIG_CCD_PORT].enable = 0; From 7ee1bdf9b30bd53e4e3e22e7cf9e0ae1c3bc5aa1 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 17:21:56 -0600 Subject: [PATCH 304/789] mb/purism/librem_jsl: Use device aliases in devicetree Convert all PCI device and USB port references in the librem_jsl devicetree to use device aliases from the Jasperlake chipset.cb instead of direct device/function numbers. This improves maintainability by using symbolic names, and reduces file size by eliminating entries which match those in the chipset devicetree. Additionally, the p2sb device reference is dropped, as the correct state (hidden) is set by the chipset devicetree. TEST=Build librem_jsl Change-Id: Iba2959156ccede68bceb46f8458676bc7a88247a Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90903 Reviewed-by: Jonathon Hall Tested-by: build bot (Jenkins) --- src/mainboard/purism/librem_jsl/devicetree.cb | 74 ++++++------------- 1 file changed, 21 insertions(+), 53 deletions(-) diff --git a/src/mainboard/purism/librem_jsl/devicetree.cb b/src/mainboard/purism/librem_jsl/devicetree.cb index 82cac1239a..a8528f3459 100644 --- a/src/mainboard/purism/librem_jsl/devicetree.cb +++ b/src/mainboard/purism/librem_jsl/devicetree.cb @@ -43,13 +43,10 @@ chip soc/intel/jasperlake register "PchHdaAudioLinkHdaEnable" = "1" device domain 0 on - device pci 00.0 on end # Host Bridge - device pci 02.0 on end # Integrated Graphics Device - device pci 04.0 on end # SA Thermal device - device pci 05.0 on end # IPU - device pci 09.0 off end # Intel Trace Hub - device pci 12.6 off end # GSPI 2 - device pci 14.0 on # USB xHCI + device ref igpu on end + device ref dptf on end + device ref ipu on end + device ref south_xhci on register "usb2_ports[0]" = "USB2_PORT_MID(OC_SKIP)" # Fingerprint reader register "usb2_ports[1]" = "USB2_PORT_MID(OC_SKIP)" # microSD register "usb2_ports[2]" = "USB2_PORT_MID(OC_SKIP)" # Type-C 1 @@ -64,70 +61,66 @@ chip soc/intel/jasperlake chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Fingerprint Reader"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""microSD Card Reader"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""Type-C Port 1"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(0, 0)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""Type-C Port 2"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(0, 1)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""Cameras"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""Keyboard Dock"" register "type" = "UPC_TYPE_PROPRIETARY" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.7 on end + device ref usb2_port8 on end end chip drivers/usb/acpi register "desc" = ""Type-C Port 2"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(0, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""Type-C Port 1"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(0, 0)" - device usb 3.1 on end + device ref usb3_port2 on end end end end end - device pci 14.1 off end # USB xDCI (OTG) - device pci 14.2 on end # PMC SRAM - device pci 14.3 on # CNVi wifi + device ref shared_ram on end + device ref cnvi_wifi on chip drivers/wifi/generic device generic 0 on end end end - device pci 14.5 off end # SD card - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 on # I2C 2 + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""GXTP7380"" register "generic.cid" = ""PNP0C50"" @@ -138,7 +131,7 @@ chip soc/intel/jasperlake device i2c 5d on end end end - device pci 15.3 on # I2C 3 + device ref i2c3 on chip drivers/i2c/generic register "hid" = ""MXC6655"" register "cid" = ""MXC6655"" @@ -147,37 +140,12 @@ chip soc/intel/jasperlake device i2c 15 on end end end - device pci 16.0 off end # HECI 1 - device pci 16.1 off end # HECI 2 - device pci 16.4 off end # HECI 3 - device pci 16.5 off end # HECI 4 - device pci 17.0 off end # SATA - device pci 19.0 on end # I2C 4 - device pci 19.1 off end # I2C 5 - device pci 19.2 off end # UART 2 - device pci 1a.0 off end # eMMC - device pci 1c.0 off end # PCI Express Root Port 1 - device pci 1c.1 off end # PCI Express Root Port 2 - device pci 1c.2 on # PCI Express Root Port 3 - M.2 M-key, PCIe only + device ref i2c4 on end + device ref pcie_rp3 on register "PcieClkSrcUsage[0]" = "2" register "PcieClkSrcClkReq[0]" = "0" smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M.2/M 2280" "SlotDataBusWidth2X" end - device pci 1c.3 off end # PCI Express Root Port 4 - device pci 1c.4 off end # PCI Express Root Port 5 - device pci 1c.5 off end # PCI Express Root Port 6 - device pci 1c.6 off end # PCI Express Root Port 7 - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1e.0 off end # UART 0 - device pci 1e.1 off end # UART 1 - device pci 1e.2 off end # GSPI 0 - device pci 1e.3 off end # GSPI 1 - device pci 1f.0 on end # eSPI Interface - device pci 1f.1 off end # P2SB - device pci 1f.2 hidden end # Power Management Controller - device pci 1f.3 on end # Intel HDA/cAVS - device pci 1f.4 off end # SMBus - device pci 1f.5 on end # PCH SPI - device pci 1f.7 off end # Intel Trace Hub + device ref hda on end end end From a1ef551f4a71d83c824bf2a02dbda126861ecb50 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 15:26:47 -0600 Subject: [PATCH 305/789] soc/intel: Use chipset.cb for PCIe root port ops linking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move PCIe root port operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them, matching the approach used by Skylake. Remove corresponding DIDs from pcie.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. Some of these will be removed/cleaned up in subsequent patches. This standardizes the approach across Intel SoCs and makes the PCIe root port configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common PCIe driver code. Change-Id: I8586b6efb8dbe164bc2a1d68b7131ffa22b00001 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90905 Tested-by: build bot (Jenkins) Reviewed-by: Jérémy Compostella Reviewed-by: Sean Rhodes Reviewed-by: Jakub "Kuba" Czapiga --- src/soc/intel/alderlake/chipset.cb | 24 +- src/soc/intel/alderlake/chipset_pch_s.cb | 56 ++-- src/soc/intel/apollolake/chipset_apl.cb | 12 +- src/soc/intel/apollolake/chipset_glk.cb | 12 +- src/soc/intel/cannonlake/chipset.cb | 32 +-- src/soc/intel/cannonlake/chipset_pch_h.cb | 48 ++-- src/soc/intel/common/block/pcie/pcie.c | 331 ---------------------- src/soc/intel/jasperlake/chipset.cb | 16 +- src/soc/intel/meteorlake/chipset.cb | 24 +- src/soc/intel/pantherlake/chipset_ptl.cb | 24 +- src/soc/intel/pantherlake/chipset_wcl.cb | 12 +- src/soc/intel/tigerlake/chipset.cb | 24 +- src/soc/intel/tigerlake/chipset_pch_h.cb | 48 ++-- 13 files changed, 166 insertions(+), 497 deletions(-) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index 355ef2e6e2..e2b4570a6b 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -248,18 +248,18 @@ chip soc/intel/alderlake device pci 19.2 alias uart2 off end # eMMC device is applicable only for ADL-N device pci 1a.0 alias emmc off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end - device pci 1d.0 alias pcie_rp9 off end - device pci 1d.1 alias pcie_rp10 off end - device pci 1d.2 alias pcie_rp11 off end - device pci 1d.3 alias pcie_rp12 off end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off end device pci 1e.1 alias uart1 off end device pci 1e.2 alias gspi0 off end diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index 6bcfab1f45..06b50f6844 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -377,34 +377,34 @@ chip soc/intel/alderlake device pci 19.0 alias i2c4 off end device pci 19.1 alias i2c5 off end device pci 19.2 alias uart2 off end - device pci 1a.0 alias pcie_rp25 off end - device pci 1a.1 alias pcie_rp26 off end - device pci 1a.2 alias pcie_rp27 off end - device pci 1a.3 alias pcie_rp28 off end - device pci 1b.0 alias pcie_rp17 off end - device pci 1b.1 alias pcie_rp18 off end - device pci 1b.2 alias pcie_rp19 off end - device pci 1b.3 alias pcie_rp20 off end - device pci 1b.4 alias pcie_rp21 off end - device pci 1b.5 alias pcie_rp22 off end - device pci 1b.6 alias pcie_rp23 off end - device pci 1b.7 alias pcie_rp24 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end - device pci 1d.0 alias pcie_rp9 off end - device pci 1d.1 alias pcie_rp10 off end - device pci 1d.2 alias pcie_rp11 off end - device pci 1d.3 alias pcie_rp12 off end - device pci 1d.4 alias pcie_rp13 off end - device pci 1d.5 alias pcie_rp14 off end - device pci 1d.6 alias pcie_rp15 off end - device pci 1d.7 alias pcie_rp16 off end + device pci 1a.0 alias pcie_rp25 off ops pcie_rp_ops end + device pci 1a.1 alias pcie_rp26 off ops pcie_rp_ops end + device pci 1a.2 alias pcie_rp27 off ops pcie_rp_ops end + device pci 1a.3 alias pcie_rp28 off ops pcie_rp_ops end + device pci 1b.0 alias pcie_rp17 off ops pcie_rp_ops end + device pci 1b.1 alias pcie_rp18 off ops pcie_rp_ops end + device pci 1b.2 alias pcie_rp19 off ops pcie_rp_ops end + device pci 1b.3 alias pcie_rp20 off ops pcie_rp_ops end + device pci 1b.4 alias pcie_rp21 off ops pcie_rp_ops end + device pci 1b.5 alias pcie_rp22 off ops pcie_rp_ops end + device pci 1b.6 alias pcie_rp23 off ops pcie_rp_ops end + device pci 1b.7 alias pcie_rp24 off ops pcie_rp_ops end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end + device pci 1d.4 alias pcie_rp13 off ops pcie_rp_ops end + device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end + device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end + device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off end device pci 1e.1 alias uart1 off end device pci 1e.2 alias gspi0 off end diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index 03a67765ec..a39461d6de 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -16,12 +16,12 @@ chip soc/intel/apollolake device pci 0f.2 alias heci3 off end # HECI3 device pci 11.0 alias ish off end # SensorHub device pci 12.0 alias sata off end # SATA - device pci 13.0 alias pcie_rp01 off end # PCIE Express Root Port 1 - device pci 13.1 alias pcie_rp02 off end # PCIE Express Root Port 2 - device pci 13.2 alias pcie_rp03 off end # PCIE Express Root Port 3 - device pci 13.3 alias pcie_rp04 off end # PCIE Express Root Port 4 - device pci 14.0 alias pcie_rp05 off end # PCIE Express Root Port 5 - device pci 14.1 alias pcie_rp06 off end # PCIE Express Root Port 6 + device pci 13.0 alias pcie_rp01 off ops pcie_rp_ops end # PCIE Express Root Port 1 + device pci 13.1 alias pcie_rp02 off ops pcie_rp_ops end # PCIE Express Root Port 2 + device pci 13.2 alias pcie_rp03 off ops pcie_rp_ops end # PCIE Express Root Port 3 + device pci 13.3 alias pcie_rp04 off ops pcie_rp_ops end # PCIE Express Root Port 4 + device pci 14.0 alias pcie_rp05 off ops pcie_rp_ops end # PCIE Express Root Port 5 + device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 device pci 15.0 alias xhci off end # XHCI device pci 15.1 alias xdci off end # XDCI device pci 16.0 alias i2c0 off end # I2C0 diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index c6f2db1fe1..1fcc37e800 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -17,12 +17,12 @@ chip soc/intel/apollolake device pci 0f.2 alias heci3 off end # HECI3 device pci 11.0 alias ish off end # SensorHub device pci 12.0 alias sata off end # SATA - device pci 13.0 alias pcie_rp01 off end # PCIE Express Root Port 1 - device pci 13.1 alias pcie_rp02 off end # PCIE Express Root Port 2 - device pci 13.2 alias pcie_rp03 off end # PCIE Express Root Port 3 - device pci 13.3 alias pcie_rp04 off end # PCIE Express Root Port 4 - device pci 14.0 alias pcie_rp05 off end # PCIE Express Root Port 5 - device pci 14.1 alias pcie_rp06 off end # PCIE Express Root Port 6 + device pci 13.0 alias pcie_rp01 off ops pcie_rp_ops end # PCIE Express Root Port 1 + device pci 13.1 alias pcie_rp02 off ops pcie_rp_ops end # PCIE Express Root Port 2 + device pci 13.2 alias pcie_rp03 off ops pcie_rp_ops end # PCIE Express Root Port 3 + device pci 13.3 alias pcie_rp04 off ops pcie_rp_ops end # PCIE Express Root Port 4 + device pci 14.0 alias pcie_rp05 off ops pcie_rp_ops end # PCIE Express Root Port 5 + device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 device pci 15.0 alias xhci off end # XHCI device pci 15.1 alias xdci off end # XDCI device pci 16.0 alias i2c0 off end # I2C0 diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index b33aadfd32..eb0a0bcb92 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -97,22 +97,22 @@ chip soc/intel/cannonlake device pci 19.1 alias i2c5 off end # I2C #5 device pci 19.2 alias uart2 off end # UART #2 device pci 1a.0 alias emmc off end # eMMC - device pci 1c.0 alias pcie_rp1 off end # PCI Express Port 1 - device pci 1c.1 alias pcie_rp2 off end # PCI Express Port 2 - device pci 1c.2 alias pcie_rp3 off end # PCI Express Port 3 - device pci 1c.3 alias pcie_rp4 off end # PCI Express Port 4 - device pci 1c.4 alias pcie_rp5 off end # PCI Express Port 5 - device pci 1c.5 alias pcie_rp6 off end # PCI Express Port 6 - device pci 1c.6 alias pcie_rp7 off end # PCI Express Port 7 - device pci 1c.7 alias pcie_rp8 off end # PCI Express Port 8 - device pci 1d.0 alias pcie_rp9 off end # PCI Express Port 9 - device pci 1d.1 alias pcie_rp10 off end # PCI Express Port 10 - device pci 1d.2 alias pcie_rp11 off end # PCI Express Port 11 - device pci 1d.3 alias pcie_rp12 off end # PCI Express Port 12 - device pci 1d.4 alias pcie_rp13 off end # PCI Express Port 13 - device pci 1d.5 alias pcie_rp14 off end # PCI Express Port 14 - device pci 1d.6 alias pcie_rp15 off end # PCI Express Port 15 - device pci 1d.7 alias pcie_rp16 off end # PCI Express Port 16 + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end # PCI Express Port 1 + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end # PCI Express Port 2 + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end # PCI Express Port 3 + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end # PCI Express Port 4 + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end # PCI Express Port 5 + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end # PCI Express Port 6 + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end # PCI Express Port 7 + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end # PCI Express Port 8 + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end # PCI Express Port 9 + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end # PCI Express Port 10 + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end # PCI Express Port 11 + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end # PCI Express Port 12 + device pci 1d.4 alias pcie_rp13 off ops pcie_rp_ops end # PCI Express Port 13 + device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end # PCI Express Port 14 + device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end # PCI Express Port 15 + device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end # PCI Express Port 16 device pci 1e.0 alias uart0 off end # UART #0 device pci 1e.1 alias uart1 off end # UART #1 device pci 1e.2 alias gspi0 off end # GSPI #0 diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index 3904697b11..fa7660b5af 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -123,30 +123,30 @@ chip soc/intel/cannonlake ops uart_ops end device pci 1a.0 alias emmc off end # eMMC - device pci 1b.0 alias pcie_rp17 off end # PCI Express Port 17 - device pci 1b.1 alias pcie_rp18 off end # PCI Express Port 18 - device pci 1b.2 alias pcie_rp19 off end # PCI Express Port 19 - device pci 1b.3 alias pcie_rp20 off end # PCI Express Port 20 - device pci 1b.4 alias pcie_rp21 off end # PCI Express Port 21 - device pci 1b.5 alias pcie_rp22 off end # PCI Express Port 22 - device pci 1b.6 alias pcie_rp23 off end # PCI Express Port 23 - device pci 1b.7 alias pcie_rp24 off end # PCI Express Port 24 - device pci 1c.0 alias pcie_rp1 off end # PCI Express Port 1 - device pci 1c.1 alias pcie_rp2 off end # PCI Express Port 2 - device pci 1c.2 alias pcie_rp3 off end # PCI Express Port 3 - device pci 1c.3 alias pcie_rp4 off end # PCI Express Port 4 - device pci 1c.4 alias pcie_rp5 off end # PCI Express Port 5 - device pci 1c.5 alias pcie_rp6 off end # PCI Express Port 6 - device pci 1c.6 alias pcie_rp7 off end # PCI Express Port 7 - device pci 1c.7 alias pcie_rp8 off end # PCI Express Port 8 - device pci 1d.0 alias pcie_rp9 off end # PCI Express Port 9 - device pci 1d.1 alias pcie_rp10 off end # PCI Express Port 10 - device pci 1d.2 alias pcie_rp11 off end # PCI Express Port 11 - device pci 1d.3 alias pcie_rp12 off end # PCI Express Port 12 - device pci 1d.4 alias pcie_rp13 off end # PCI Express Port 13 - device pci 1d.5 alias pcie_rp14 off end # PCI Express Port 14 - device pci 1d.6 alias pcie_rp15 off end # PCI Express Port 15 - device pci 1d.7 alias pcie_rp16 off end # PCI Express Port 16 + device pci 1b.0 alias pcie_rp17 off ops pcie_rp_ops end # PCI Express Port 17 + device pci 1b.1 alias pcie_rp18 off ops pcie_rp_ops end # PCI Express Port 18 + device pci 1b.2 alias pcie_rp19 off ops pcie_rp_ops end # PCI Express Port 19 + device pci 1b.3 alias pcie_rp20 off ops pcie_rp_ops end # PCI Express Port 20 + device pci 1b.4 alias pcie_rp21 off ops pcie_rp_ops end # PCI Express Port 21 + device pci 1b.5 alias pcie_rp22 off ops pcie_rp_ops end # PCI Express Port 22 + device pci 1b.6 alias pcie_rp23 off ops pcie_rp_ops end # PCI Express Port 23 + device pci 1b.7 alias pcie_rp24 off ops pcie_rp_ops end # PCI Express Port 24 + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end # PCI Express Port 1 + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end # PCI Express Port 2 + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end # PCI Express Port 3 + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end # PCI Express Port 4 + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end # PCI Express Port 5 + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end # PCI Express Port 6 + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end # PCI Express Port 7 + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end # PCI Express Port 8 + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end # PCI Express Port 9 + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end # PCI Express Port 10 + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end # PCI Express Port 11 + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end # PCI Express Port 12 + device pci 1d.4 alias pcie_rp13 off ops pcie_rp_ops end # PCI Express Port 13 + device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end # PCI Express Port 14 + device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end # PCI Express Port 15 + device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end # PCI Express Port 16 device pci 1e.0 alias uart0 off end # UART #0 device pci 1e.1 alias uart1 off end # UART #1 device pci 1e.2 alias gspi0 off end # GSPI #0 diff --git a/src/soc/intel/common/block/pcie/pcie.c b/src/soc/intel/common/block/pcie/pcie.c index 31e70d6edc..ccddb8026f 100644 --- a/src/soc/intel/common/block/pcie/pcie.c +++ b/src/soc/intel/common/block/pcie/pcie.c @@ -81,34 +81,6 @@ static const unsigned short pcie_device_ids[] = { PCI_DID_INTEL_NVL_PCIE_RP12, PCI_DID_INTEL_NVL_PCIE_RP13, PCI_DID_INTEL_NVL_PCIE_RP14, - PCI_DID_INTEL_WCL_PCIE_RP1, - PCI_DID_INTEL_WCL_PCIE_RP2, - PCI_DID_INTEL_WCL_PCIE_RP3, - PCI_DID_INTEL_WCL_PCIE_RP4, - PCI_DID_INTEL_WCL_PCIE_RP5, - PCI_DID_INTEL_WCL_PCIE_RP6, - PCI_DID_INTEL_PTL_H_PCIE_RP1, - PCI_DID_INTEL_PTL_H_PCIE_RP2, - PCI_DID_INTEL_PTL_H_PCIE_RP3, - PCI_DID_INTEL_PTL_H_PCIE_RP4, - PCI_DID_INTEL_PTL_H_PCIE_RP5, - PCI_DID_INTEL_PTL_H_PCIE_RP6, - PCI_DID_INTEL_PTL_H_PCIE_RP7, - PCI_DID_INTEL_PTL_H_PCIE_RP8, - PCI_DID_INTEL_PTL_H_PCIE_RP9, - PCI_DID_INTEL_PTL_H_PCIE_RP10, - PCI_DID_INTEL_PTL_U_H_PCIE_RP1, - PCI_DID_INTEL_PTL_U_H_PCIE_RP2, - PCI_DID_INTEL_PTL_U_H_PCIE_RP3, - PCI_DID_INTEL_PTL_U_H_PCIE_RP4, - PCI_DID_INTEL_PTL_U_H_PCIE_RP5, - PCI_DID_INTEL_PTL_U_H_PCIE_RP6, - PCI_DID_INTEL_PTL_U_H_PCIE_RP7, - PCI_DID_INTEL_PTL_U_H_PCIE_RP8, - PCI_DID_INTEL_PTL_U_H_PCIE_RP9, - PCI_DID_INTEL_PTL_U_H_PCIE_RP10, - PCI_DID_INTEL_PTL_U_H_PCIE_RP11, - PCI_DID_INTEL_PTL_U_H_PCIE_RP12, PCI_DID_INTEL_LNL_PCIE_RP1, PCI_DID_INTEL_LNL_PCIE_RP2, PCI_DID_INTEL_LNL_PCIE_RP3, @@ -117,218 +89,6 @@ static const unsigned short pcie_device_ids[] = { PCI_DID_INTEL_LNL_PCIE_RP6, PCI_DID_INTEL_LNL_PCIE_RP7, PCI_DID_INTEL_LNL_PCIE_RP8, - PCI_DID_INTEL_RPL_P_PCIE_RP1, - PCI_DID_INTEL_RPL_P_PCIE_RP2, - PCI_DID_INTEL_RPL_P_PCIE_RP3, - PCI_DID_INTEL_RPL_P_PCIE_RP4, - PCI_DID_INTEL_MTL_SOC_PCIE_RP1, - PCI_DID_INTEL_MTL_SOC_PCIE_RP2, - PCI_DID_INTEL_MTL_SOC_PCIE_RP3, - PCI_DID_INTEL_MTL_SOC_PCIE_RP4, - PCI_DID_INTEL_MTL_SOC_PCIE_RP5, - PCI_DID_INTEL_MTL_SOC_PCIE_RP6, - PCI_DID_INTEL_MTL_SOC_PCIE_RP7, - PCI_DID_INTEL_MTL_SOC_PCIE_RP8, - PCI_DID_INTEL_MTL_SOC_PCIE_RP9, - PCI_DID_INTEL_MTL_IOE_P_PCIE_RP10, - PCI_DID_INTEL_MTL_IOE_P_PCIE_RP11, - PCI_DID_INTEL_MTL_IOE_P_PCIE_RP12, - PCI_DID_INTEL_ARL_SOC_PCIE_RP1, - PCI_DID_INTEL_ARL_SOC_PCIE_RP2, - PCI_DID_INTEL_ARL_SOC_PCIE_RP3, - PCI_DID_INTEL_ARL_SOC_PCIE_RP4, - PCI_DID_INTEL_ARL_SOC_PCIE_RP5, - PCI_DID_INTEL_ARL_SOC_PCIE_RP6, - PCI_DID_INTEL_ARL_SOC_PCIE_RP7, - PCI_DID_INTEL_ARL_SOC_PCIE_RP8, - PCI_DID_INTEL_ARL_SOC_PCIE_RP9, - PCI_DID_INTEL_ARL_S_PCIE_RP13, - PCI_DID_INTEL_ARL_S_PCIE_RP14, - PCI_DID_INTEL_ARL_S_PCIE_RP15, - PCI_DID_INTEL_ARP_S_PCIE_RP1, - PCI_DID_INTEL_ARP_S_PCIE_RP2, - PCI_DID_INTEL_ARP_S_PCIE_RP3, - PCI_DID_INTEL_ARP_S_PCIE_RP4, - PCI_DID_INTEL_ARP_S_PCIE_RP5, - PCI_DID_INTEL_ARP_S_PCIE_RP6, - PCI_DID_INTEL_ARP_S_PCIE_RP7, - PCI_DID_INTEL_ARP_S_PCIE_RP8, - PCI_DID_INTEL_ARP_S_PCIE_RP9, - PCI_DID_INTEL_ARP_S_PCIE_RP10, - PCI_DID_INTEL_ARP_S_PCIE_RP11, - PCI_DID_INTEL_ARP_S_PCIE_RP12, - PCI_DID_INTEL_ARP_S_PCIE_RP13, - PCI_DID_INTEL_ARP_S_PCIE_RP14, - PCI_DID_INTEL_ARP_S_PCIE_RP15, - PCI_DID_INTEL_ARP_S_PCIE_RP16, - PCI_DID_INTEL_ARP_S_PCIE_RP17, - PCI_DID_INTEL_ARP_S_PCIE_RP18, - PCI_DID_INTEL_ARP_S_PCIE_RP19, - PCI_DID_INTEL_ARP_S_PCIE_RP20, - PCI_DID_INTEL_ARP_S_PCIE_RP21, - PCI_DID_INTEL_ARP_S_PCIE_RP22, - PCI_DID_INTEL_ARP_S_PCIE_RP23, - PCI_DID_INTEL_ARP_S_PCIE_RP24, - PCI_DID_INTEL_LWB_PCIE_RP1, - PCI_DID_INTEL_LWB_PCIE_RP2, - PCI_DID_INTEL_LWB_PCIE_RP3, - PCI_DID_INTEL_LWB_PCIE_RP4, - PCI_DID_INTEL_LWB_PCIE_RP5, - PCI_DID_INTEL_LWB_PCIE_RP6, - PCI_DID_INTEL_LWB_PCIE_RP7, - PCI_DID_INTEL_LWB_PCIE_RP8, - PCI_DID_INTEL_LWB_PCIE_RP9, - PCI_DID_INTEL_LWB_PCIE_RP10, - PCI_DID_INTEL_LWB_PCIE_RP11, - PCI_DID_INTEL_LWB_PCIE_RP12, - PCI_DID_INTEL_LWB_PCIE_RP13, - PCI_DID_INTEL_LWB_PCIE_RP14, - PCI_DID_INTEL_LWB_PCIE_RP15, - PCI_DID_INTEL_LWB_PCIE_RP16, - PCI_DID_INTEL_LWB_PCIE_RP17, - PCI_DID_INTEL_LWB_PCIE_RP18, - PCI_DID_INTEL_LWB_PCIE_RP19, - PCI_DID_INTEL_LWB_PCIE_RP20, - PCI_DID_INTEL_LWB_PCIE_RP1_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP2_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP3_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP4_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP5_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP6_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP7_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP8_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP9_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP10_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP11_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP12_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP13_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP14_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP15_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP16_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP17_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP18_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP19_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP20_SUPER, - PCI_DID_INTEL_CNL_LP_PCIE_RP1, - PCI_DID_INTEL_CNL_LP_PCIE_RP2, - PCI_DID_INTEL_CNL_LP_PCIE_RP3, - PCI_DID_INTEL_CNL_LP_PCIE_RP4, - PCI_DID_INTEL_CNL_LP_PCIE_RP5, - PCI_DID_INTEL_CNL_LP_PCIE_RP6, - PCI_DID_INTEL_CNL_LP_PCIE_RP7, - PCI_DID_INTEL_CNL_LP_PCIE_RP8, - PCI_DID_INTEL_CNL_LP_PCIE_RP9, - PCI_DID_INTEL_CNL_LP_PCIE_RP10, - PCI_DID_INTEL_CNL_LP_PCIE_RP11, - PCI_DID_INTEL_CNL_LP_PCIE_RP12, - PCI_DID_INTEL_CNL_LP_PCIE_RP13, - PCI_DID_INTEL_CNL_LP_PCIE_RP14, - PCI_DID_INTEL_CNL_LP_PCIE_RP15, - PCI_DID_INTEL_CNL_LP_PCIE_RP16, - PCI_DID_INTEL_CNP_H_PCIE_RP1, - PCI_DID_INTEL_CNP_H_PCIE_RP2, - PCI_DID_INTEL_CNP_H_PCIE_RP3, - PCI_DID_INTEL_CNP_H_PCIE_RP4, - PCI_DID_INTEL_CNP_H_PCIE_RP5, - PCI_DID_INTEL_CNP_H_PCIE_RP6, - PCI_DID_INTEL_CNP_H_PCIE_RP7, - PCI_DID_INTEL_CNP_H_PCIE_RP8, - PCI_DID_INTEL_CNP_H_PCIE_RP9, - PCI_DID_INTEL_CNP_H_PCIE_RP10, - PCI_DID_INTEL_CNP_H_PCIE_RP11, - PCI_DID_INTEL_CNP_H_PCIE_RP12, - PCI_DID_INTEL_CNP_H_PCIE_RP13, - PCI_DID_INTEL_CNP_H_PCIE_RP14, - PCI_DID_INTEL_CNP_H_PCIE_RP15, - PCI_DID_INTEL_CNP_H_PCIE_RP16, - PCI_DID_INTEL_CNP_H_PCIE_RP17, - PCI_DID_INTEL_CNP_H_PCIE_RP18, - PCI_DID_INTEL_CNP_H_PCIE_RP19, - PCI_DID_INTEL_CNP_H_PCIE_RP20, - PCI_DID_INTEL_CNP_H_PCIE_RP21, - PCI_DID_INTEL_CNP_H_PCIE_RP22, - PCI_DID_INTEL_CNP_H_PCIE_RP23, - PCI_DID_INTEL_CNP_H_PCIE_RP24, - PCI_DID_INTEL_CMP_LP_PCIE_RP1, - PCI_DID_INTEL_CMP_LP_PCIE_RP2, - PCI_DID_INTEL_CMP_LP_PCIE_RP3, - PCI_DID_INTEL_CMP_LP_PCIE_RP4, - PCI_DID_INTEL_CMP_LP_PCIE_RP5, - PCI_DID_INTEL_CMP_LP_PCIE_RP6, - PCI_DID_INTEL_CMP_LP_PCIE_RP7, - PCI_DID_INTEL_CMP_LP_PCIE_RP8, - PCI_DID_INTEL_CMP_LP_PCIE_RP9, - PCI_DID_INTEL_CMP_LP_PCIE_RP10, - PCI_DID_INTEL_CMP_LP_PCIE_RP11, - PCI_DID_INTEL_CMP_LP_PCIE_RP12, - PCI_DID_INTEL_CMP_LP_PCIE_RP13, - PCI_DID_INTEL_CMP_LP_PCIE_RP14, - PCI_DID_INTEL_CMP_LP_PCIE_RP15, - PCI_DID_INTEL_CMP_LP_PCIE_RP16, - PCI_DID_INTEL_CMP_H_PCIE_RP1, - PCI_DID_INTEL_CMP_H_PCIE_RP2, - PCI_DID_INTEL_CMP_H_PCIE_RP3, - PCI_DID_INTEL_CMP_H_PCIE_RP4, - PCI_DID_INTEL_CMP_H_PCIE_RP5, - PCI_DID_INTEL_CMP_H_PCIE_RP6, - PCI_DID_INTEL_CMP_H_PCIE_RP7, - PCI_DID_INTEL_CMP_H_PCIE_RP8, - PCI_DID_INTEL_CMP_H_PCIE_RP9, - PCI_DID_INTEL_CMP_H_PCIE_RP10, - PCI_DID_INTEL_CMP_H_PCIE_RP11, - PCI_DID_INTEL_CMP_H_PCIE_RP12, - PCI_DID_INTEL_CMP_H_PCIE_RP13, - PCI_DID_INTEL_CMP_H_PCIE_RP14, - PCI_DID_INTEL_CMP_H_PCIE_RP15, - PCI_DID_INTEL_CMP_H_PCIE_RP16, - PCI_DID_INTEL_CMP_H_PCIE_RP17, - PCI_DID_INTEL_CMP_H_PCIE_RP18, - PCI_DID_INTEL_CMP_H_PCIE_RP19, - PCI_DID_INTEL_CMP_H_PCIE_RP20, - PCI_DID_INTEL_CMP_H_PCIE_RP21, - PCI_DID_INTEL_CMP_H_PCIE_RP22, - PCI_DID_INTEL_CMP_H_PCIE_RP23, - PCI_DID_INTEL_CMP_H_PCIE_RP24, - PCI_DID_INTEL_TGP_LP_PCIE_RP1, - PCI_DID_INTEL_TGP_LP_PCIE_RP2, - PCI_DID_INTEL_TGP_LP_PCIE_RP3, - PCI_DID_INTEL_TGP_LP_PCIE_RP4, - PCI_DID_INTEL_TGP_LP_PCIE_RP5, - PCI_DID_INTEL_TGP_LP_PCIE_RP6, - PCI_DID_INTEL_TGP_LP_PCIE_RP7, - PCI_DID_INTEL_TGP_LP_PCIE_RP8, - PCI_DID_INTEL_TGP_LP_PCIE_RP9, - PCI_DID_INTEL_TGP_LP_PCIE_RP10, - PCI_DID_INTEL_TGP_LP_PCIE_RP11, - PCI_DID_INTEL_TGP_LP_PCIE_RP12, - PCI_DID_INTEL_TGP_LP_PCIE_RP13, - PCI_DID_INTEL_TGP_LP_PCIE_RP14, - PCI_DID_INTEL_TGP_LP_PCIE_RP15, - PCI_DID_INTEL_TGP_LP_PCIE_RP16, - PCI_DID_INTEL_TGP_H_PCIE_RP1, - PCI_DID_INTEL_TGP_H_PCIE_RP2, - PCI_DID_INTEL_TGP_H_PCIE_RP3, - PCI_DID_INTEL_TGP_H_PCIE_RP4, - PCI_DID_INTEL_TGP_H_PCIE_RP5, - PCI_DID_INTEL_TGP_H_PCIE_RP6, - PCI_DID_INTEL_TGP_H_PCIE_RP7, - PCI_DID_INTEL_TGP_H_PCIE_RP8, - PCI_DID_INTEL_TGP_H_PCIE_RP9, - PCI_DID_INTEL_TGP_H_PCIE_RP10, - PCI_DID_INTEL_TGP_H_PCIE_RP11, - PCI_DID_INTEL_TGP_H_PCIE_RP12, - PCI_DID_INTEL_TGP_H_PCIE_RP13, - PCI_DID_INTEL_TGP_H_PCIE_RP14, - PCI_DID_INTEL_TGP_H_PCIE_RP15, - PCI_DID_INTEL_TGP_H_PCIE_RP16, - PCI_DID_INTEL_TGP_H_PCIE_RP17, - PCI_DID_INTEL_TGP_H_PCIE_RP18, - PCI_DID_INTEL_TGP_H_PCIE_RP19, - PCI_DID_INTEL_TGP_H_PCIE_RP20, - PCI_DID_INTEL_TGP_H_PCIE_RP21, - PCI_DID_INTEL_TGP_H_PCIE_RP22, - PCI_DID_INTEL_TGP_H_PCIE_RP23, - PCI_DID_INTEL_TGP_H_PCIE_RP24, PCI_DID_INTEL_MCC_PCIE_RP1, PCI_DID_INTEL_MCC_PCIE_RP2, PCI_DID_INTEL_MCC_PCIE_RP3, @@ -336,97 +96,6 @@ static const unsigned short pcie_device_ids[] = { PCI_DID_INTEL_MCC_PCIE_RP5, PCI_DID_INTEL_MCC_PCIE_RP6, PCI_DID_INTEL_MCC_PCIE_RP7, - PCI_DID_INTEL_JSP_PCIE_RP1, - PCI_DID_INTEL_JSP_PCIE_RP2, - PCI_DID_INTEL_JSP_PCIE_RP3, - PCI_DID_INTEL_JSP_PCIE_RP4, - PCI_DID_INTEL_JSP_PCIE_RP5, - PCI_DID_INTEL_JSP_PCIE_RP6, - PCI_DID_INTEL_JSP_PCIE_RP7, - PCI_DID_INTEL_JSP_PCIE_RP8, - PCI_DID_INTEL_ADL_P_PCIE_RP1, - PCI_DID_INTEL_ADL_P_PCIE_RP2, - PCI_DID_INTEL_ADL_P_PCIE_RP3, - PCI_DID_INTEL_ADP_P_PCIE_RP1, - PCI_DID_INTEL_ADP_P_PCIE_RP2, - PCI_DID_INTEL_ADP_P_PCIE_RP3, - PCI_DID_INTEL_ADP_P_PCIE_RP4, - PCI_DID_INTEL_ADP_P_PCIE_RP5, - PCI_DID_INTEL_ADP_P_PCIE_RP6, - PCI_DID_INTEL_ADP_P_PCIE_RP7, - PCI_DID_INTEL_ADP_P_PCIE_RP8, - PCI_DID_INTEL_ADP_P_PCIE_RP9, - PCI_DID_INTEL_ADP_P_PCIE_RP10, - PCI_DID_INTEL_ADP_P_PCIE_RP11, - PCI_DID_INTEL_ADP_P_PCIE_RP12, - PCI_DID_INTEL_ADP_S_PCIE_RP1, - PCI_DID_INTEL_ADP_S_PCIE_RP2, - PCI_DID_INTEL_ADP_S_PCIE_RP3, - PCI_DID_INTEL_ADP_S_PCIE_RP4, - PCI_DID_INTEL_ADP_S_PCIE_RP5, - PCI_DID_INTEL_ADP_S_PCIE_RP6, - PCI_DID_INTEL_ADP_S_PCIE_RP7, - PCI_DID_INTEL_ADP_S_PCIE_RP8, - PCI_DID_INTEL_ADP_S_PCIE_RP9, - PCI_DID_INTEL_ADP_S_PCIE_RP10, - PCI_DID_INTEL_ADP_S_PCIE_RP11, - PCI_DID_INTEL_ADP_S_PCIE_RP12, - PCI_DID_INTEL_ADP_S_PCIE_RP13, - PCI_DID_INTEL_ADP_S_PCIE_RP14, - PCI_DID_INTEL_ADP_S_PCIE_RP15, - PCI_DID_INTEL_ADP_S_PCIE_RP16, - PCI_DID_INTEL_ADP_S_PCIE_RP17, - PCI_DID_INTEL_ADP_S_PCIE_RP18, - PCI_DID_INTEL_ADP_S_PCIE_RP19, - PCI_DID_INTEL_ADP_S_PCIE_RP20, - PCI_DID_INTEL_ADP_S_PCIE_RP21, - PCI_DID_INTEL_ADP_S_PCIE_RP22, - PCI_DID_INTEL_ADP_S_PCIE_RP23, - PCI_DID_INTEL_ADP_S_PCIE_RP24, - PCI_DID_INTEL_ADP_S_PCIE_RP25, - PCI_DID_INTEL_ADP_S_PCIE_RP26, - PCI_DID_INTEL_ADP_S_PCIE_RP27, - PCI_DID_INTEL_ADP_S_PCIE_RP28, - PCI_DID_INTEL_ADP_M_N_PCIE_RP1, - PCI_DID_INTEL_ADP_M_N_PCIE_RP2, - PCI_DID_INTEL_ADP_M_N_PCIE_RP3, - PCI_DID_INTEL_ADP_M_N_PCIE_RP4, - PCI_DID_INTEL_ADP_M_PCIE_RP5, - PCI_DID_INTEL_ADP_M_PCIE_RP6, - PCI_DID_INTEL_ADP_M_N_PCIE_RP7, - PCI_DID_INTEL_ADP_M_PCIE_RP8, - PCI_DID_INTEL_ADP_M_N_PCIE_RP9, - PCI_DID_INTEL_ADP_M_N_PCIE_RP10, - PCI_DID_INTEL_ADP_N_PCIE_RP11, - PCI_DID_INTEL_ADP_N_PCIE_RP12, - PCI_DID_INTEL_RPP_S_PCIE_RP1, - PCI_DID_INTEL_RPP_S_PCIE_RP2, - PCI_DID_INTEL_RPP_S_PCIE_RP3, - PCI_DID_INTEL_RPP_S_PCIE_RP4, - PCI_DID_INTEL_RPP_S_PCIE_RP5, - PCI_DID_INTEL_RPP_S_PCIE_RP6, - PCI_DID_INTEL_RPP_S_PCIE_RP7, - PCI_DID_INTEL_RPP_S_PCIE_RP8, - PCI_DID_INTEL_RPP_S_PCIE_RP9, - PCI_DID_INTEL_RPP_S_PCIE_RP10, - PCI_DID_INTEL_RPP_S_PCIE_RP11, - PCI_DID_INTEL_RPP_S_PCIE_RP12, - PCI_DID_INTEL_RPP_S_PCIE_RP13, - PCI_DID_INTEL_RPP_S_PCIE_RP14, - PCI_DID_INTEL_RPP_S_PCIE_RP15, - PCI_DID_INTEL_RPP_S_PCIE_RP16, - PCI_DID_INTEL_RPP_S_PCIE_RP17, - PCI_DID_INTEL_RPP_S_PCIE_RP18, - PCI_DID_INTEL_RPP_S_PCIE_RP19, - PCI_DID_INTEL_RPP_S_PCIE_RP20, - PCI_DID_INTEL_RPP_S_PCIE_RP21, - PCI_DID_INTEL_RPP_S_PCIE_RP22, - PCI_DID_INTEL_RPP_S_PCIE_RP23, - PCI_DID_INTEL_RPP_S_PCIE_RP24, - PCI_DID_INTEL_RPP_S_PCIE_RP25, - PCI_DID_INTEL_RPP_S_PCIE_RP26, - PCI_DID_INTEL_RPP_S_PCIE_RP27, - PCI_DID_INTEL_RPP_S_PCIE_RP28, 0 }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index f713d22595..aa25ff5e8e 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -77,14 +77,14 @@ chip soc/intel/jasperlake device pci 19.1 alias i2c5 off end device pci 19.2 alias uart2 off end device pci 1a.0 alias emmc off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off end device pci 1e.1 alias uart1 off end device pci 1e.2 alias gspi0 off end diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index 7b26670ff8..6851b5769f 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -31,13 +31,13 @@ chip soc/intel/meteorlake device domain 0 on device pci 00.0 alias system_agent on end - device pci 01.0 alias pcie_rp12 off end + device pci 01.0 alias pcie_rp12 off ops pcie_rp_ops end device pci 02.0 alias igpu off end device pci 04.0 alias dtt off end device pci 05.0 alias ipu off end - device pci 06.0 alias pcie_rp9 off end - device pci 06.1 alias pcie_rp10 off end - device pci 06.2 alias pcie_rp11 off end + device pci 06.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 06.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 06.2 alias pcie_rp11 off ops pcie_rp_ops end device pci 07.0 alias tbt_pcie_rp0 off chip soc/intel/common/block/usb4 use tcss_dma0 as usb4_port @@ -169,14 +169,14 @@ chip soc/intel/meteorlake device pci 19.0 alias i2c4 off end device pci 19.1 alias i2c5 off end device pci 19.2 alias uart2 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off end device pci 1e.1 alias uart1 off end device pci 1e.2 alias gspi0 off end diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index fb78b88659..31a898182f 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -112,10 +112,10 @@ chip soc/intel/pantherlake device pci 02.0 alias igpu on end device pci 04.0 alias dtt off end device pci 05.0 alias ipu off end - device pci 06.0 alias pcie_rp9 off end - device pci 06.1 alias pcie_rp10 off end - device pci 06.2 alias pcie_rp11 off end - device pci 06.3 alias pcie_rp12 off end + device pci 06.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 06.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 06.2 alias pcie_rp11 off ops pcie_rp_ops end + device pci 06.3 alias pcie_rp12 off ops pcie_rp_ops end device pci 07.0 alias tbt_pcie_rp0 off chip soc/intel/common/block/usb4 use tcss_dma0 as usb4_port @@ -229,14 +229,14 @@ chip soc/intel/pantherlake device pci 19.0 alias i2c4 off end device pci 19.1 alias i2c5 off end device pci 19.2 alias uart2 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off end device pci 1e.1 alias uart1 off end device pci 1e.2 alias gspi0 off end diff --git a/src/soc/intel/pantherlake/chipset_wcl.cb b/src/soc/intel/pantherlake/chipset_wcl.cb index 31abe5be94..2236d930e2 100644 --- a/src/soc/intel/pantherlake/chipset_wcl.cb +++ b/src/soc/intel/pantherlake/chipset_wcl.cb @@ -20,8 +20,8 @@ chip soc/intel/pantherlake device pci 00.0 alias system_agent on end device pci 02.0 alias igpu on end device pci 04.0 alias dtt off end - device pci 06.0 alias pcie_rp5 off end - device pci 06.1 alias pcie_rp6 off end + device pci 06.0 alias pcie_rp5 off ops pcie_rp_ops end + device pci 06.1 alias pcie_rp6 off ops pcie_rp_ops end device pci 07.0 alias tbt_pcie_rp0 off chip soc/intel/common/block/usb4 use tcss_dma0 as usb4_port @@ -116,10 +116,10 @@ chip soc/intel/pantherlake device pci 19.0 alias i2c4 off end device pci 19.1 alias i2c5 off end device pci 19.2 alias uart2 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off end device pci 1e.1 alias uart1 off end device pci 1e.2 alias gspi0 off end diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index f0576ad5e6..bdf0138229 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -129,18 +129,18 @@ chip soc/intel/tigerlake device pci 19.0 alias i2c4 off end device pci 19.1 alias i2c5 off end device pci 19.2 alias uart2 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end - device pci 1d.0 alias pcie_rp9 off end - device pci 1d.1 alias pcie_rp10 off end - device pci 1d.2 alias pcie_rp11 off end - device pci 1d.3 alias pcie_rp12 off end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off end device pci 1e.1 alias uart1 off end device pci 1e.2 alias gspi0 off end diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index 40f613ff4a..e2c7022546 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -151,30 +151,30 @@ chip soc/intel/tigerlake device pci 19.0 alias i2c4 off end device pci 19.1 alias i2c5 off end device pci 19.2 alias uart2 off end - device pci 1b.0 alias pcie_rp17 off end - device pci 1b.1 alias pcie_rp18 off end - device pci 1b.2 alias pcie_rp19 off end - device pci 1b.3 alias pcie_rp20 off end - device pci 1b.4 alias pcie_rp21 off end - device pci 1b.5 alias pcie_rp22 off end - device pci 1b.6 alias pcie_rp23 off end - device pci 1b.7 alias pcie_rp24 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end - device pci 1d.0 alias pcie_rp9 off end - device pci 1d.1 alias pcie_rp10 off end - device pci 1d.2 alias pcie_rp11 off end - device pci 1d.3 alias pcie_rp12 off end - device pci 1d.4 alias pcie_rp13 off end - device pci 1d.5 alias pcie_rp14 off end - device pci 1d.6 alias pcie_rp15 off end - device pci 1d.7 alias pcie_rp16 off end + device pci 1b.0 alias pcie_rp17 off ops pcie_rp_ops end + device pci 1b.1 alias pcie_rp18 off ops pcie_rp_ops end + device pci 1b.2 alias pcie_rp19 off ops pcie_rp_ops end + device pci 1b.3 alias pcie_rp20 off ops pcie_rp_ops end + device pci 1b.4 alias pcie_rp21 off ops pcie_rp_ops end + device pci 1b.5 alias pcie_rp22 off ops pcie_rp_ops end + device pci 1b.6 alias pcie_rp23 off ops pcie_rp_ops end + device pci 1b.7 alias pcie_rp24 off ops pcie_rp_ops end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end + device pci 1d.4 alias pcie_rp13 off ops pcie_rp_ops end + device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end + device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end + device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off end device pci 1e.1 alias uart1 off end device pci 1e.2 alias gspi0 off end From d80482400f88a187739c44eb9f4bfb13a2d34f54 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Mon, 26 Jan 2026 13:03:59 +0000 Subject: [PATCH 306/789] drivers/option/cfr: Fix numeric default override CFR default overrides use SM_OBJ_* kinds, but write_numeric_option() compared them to CFR_TAG_OPTION_*, so enum/number/bool overrides were always skipped. Compare kinds against the expected SM_OBJ_* for each numeric tag, then apply the override. Change-Id: I02046974a7b0a3ef32973689833e1b0d38a5d6f4 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90911 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/drivers/option/cfr.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/drivers/option/cfr.c b/src/drivers/option/cfr.c index d5390231d6..1a5f1d67d7 100644 --- a/src/drivers/option/cfr.c +++ b/src/drivers/option/cfr.c @@ -123,6 +123,21 @@ static uint32_t sm_write_enum_value(char *current, const struct sm_enum_value *e return enum_val->size; } + +static bool override_matches_numeric_tag(enum sm_object_kind override_kind, uint32_t tag) +{ + switch (tag) { + case CFR_TAG_OPTION_ENUM: + return override_kind == SM_OBJ_ENUM; + case CFR_TAG_OPTION_NUMBER: + return override_kind == SM_OBJ_NUMBER; + case CFR_TAG_OPTION_BOOL: + return override_kind == SM_OBJ_BOOL; + default: + return false; + } +} + static uint32_t write_numeric_option(char *current, uint32_t tag, const uint64_t object_id, const char *opt_name, const char *ui_name, const char *ui_helptext, uint32_t flags, uint32_t default_value, uint32_t min, uint32_t max, uint32_t step, @@ -135,10 +150,8 @@ static uint32_t write_numeric_option(char *current, uint32_t tag, const uint64_t /* Check for mainboard override of default value */ const struct cfr_default_override *ovr = find_override(opt_name); if (ovr) { - if (ovr->kind != tag) + if (!override_matches_numeric_tag(ovr->kind, tag)) printk(BIOS_WARNING, "CFR: override for option '%s' has mismatched type; skipping.\n", opt_name); - else if (tag == CFR_TAG_OPTION_BOOL) - default_value = ovr->bool_value; else default_value = ovr->uint_value; } From 7d9fb0c1876434e45dfd88afa268931654ee97fa Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 18:56:22 -0600 Subject: [PATCH 307/789] soc/intel: Use chipset.cb for I2C device ops linking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move I2C device operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them, matching the approach used by Skylake. Remove corresponding DIDs from i2c.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. This standardizes the approach across Intel SoCs and makes the I2C controller configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common I2C driver code. Change-Id: Ib68dd19c7c94d4cb6b41a1caf092b77f463c1c74 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90906 Reviewed-by: Jakub "Kuba" Czapiga Tested-by: build bot (Jenkins) Reviewed-by: Jérémy Compostella --- src/soc/intel/alderlake/chipset.cb | 16 +-- src/soc/intel/alderlake/chipset_pch_s.cb | 12 +-- src/soc/intel/apollolake/chipset_apl.cb | 16 +-- src/soc/intel/apollolake/chipset_glk.cb | 16 +-- src/soc/intel/cannonlake/chipset.cb | 12 +-- src/soc/intel/cannonlake/chipset_pch_h.cb | 12 +-- src/soc/intel/common/block/i2c/i2c.c | 119 ---------------------- src/soc/intel/jasperlake/chipset.cb | 12 +-- src/soc/intel/meteorlake/chipset.cb | 12 +-- src/soc/intel/pantherlake/chipset_ptl.cb | 12 +-- src/soc/intel/pantherlake/chipset_wcl.cb | 12 +-- src/soc/intel/tigerlake/chipset.cb | 12 +-- src/soc/intel/tigerlake/chipset_pch_h.cb | 14 +-- 13 files changed, 79 insertions(+), 198 deletions(-) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index e2b4570a6b..dcd5ebc400 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -172,8 +172,8 @@ chip soc/intel/alderlake device pci 0d.2 alias tcss_dma0 off end device pci 0d.3 alias tcss_dma1 off end device pci 0e.0 alias vmd off end - device pci 10.0 alias i2c6 off end - device pci 10.1 alias i2c7 off end + device pci 10.0 alias i2c6 off ops i2c_dev_ops end + device pci 10.1 alias i2c7 off ops i2c_dev_ops end device pci 10.6 alias thc0 off end device pci 10.7 alias thc1 off end device pci 12.0 alias ish off end @@ -232,10 +232,10 @@ chip soc/intel/alderlake device pci 14.1 alias usb_otg off end device pci 14.2 alias shared_sram off end device pci 14.3 alias cnvi_wifi off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 on end device pci 16.1 alias heci2 off end device pci 16.2 alias ide_r off end @@ -243,8 +243,8 @@ chip soc/intel/alderlake device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end device pci 17.0 alias sata off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end # eMMC device is applicable only for ADL-N device pci 1a.0 alias emmc off end diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index 06b50f6844..a1a056bcf2 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -363,10 +363,10 @@ chip soc/intel/alderlake device pci 14.1 alias xdci off end device pci 14.2 alias shared_sram off end device pci 14.3 alias cnvi_wifi off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 on end device pci 16.1 alias heci2 off end device pci 16.2 alias ide_r off end @@ -374,8 +374,8 @@ chip soc/intel/alderlake device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end device pci 17.0 alias sata off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end device pci 1a.0 alias pcie_rp25 off ops pcie_rp_ops end device pci 1a.1 alias pcie_rp26 off ops pcie_rp_ops end diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index a39461d6de..7184a0c401 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -24,14 +24,14 @@ chip soc/intel/apollolake device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 device pci 15.0 alias xhci off end # XHCI device pci 15.1 alias xdci off end # XDCI - device pci 16.0 alias i2c0 off end # I2C0 - device pci 16.1 alias i2c1 off end # I2C1 - device pci 16.2 alias i2c2 off end # I2C2 - device pci 16.3 alias i2c3 off end # I2C3 - device pci 17.0 alias i2c4 off end # I2C4 - device pci 17.1 alias i2c5 off end # I2C5 - device pci 17.2 alias i2c6 off end # I2C6 - device pci 17.3 alias i2c7 off end # I2C7 + device pci 16.0 alias i2c0 off ops i2c_dev_ops end # I2C0 + device pci 16.1 alias i2c1 off ops i2c_dev_ops end # I2C1 + device pci 16.2 alias i2c2 off ops i2c_dev_ops end # I2C2 + device pci 16.3 alias i2c3 off ops i2c_dev_ops end # I2C3 + device pci 17.0 alias i2c4 off ops i2c_dev_ops end # I2C4 + device pci 17.1 alias i2c5 off ops i2c_dev_ops end # I2C5 + device pci 17.2 alias i2c6 off ops i2c_dev_ops end # I2C6 + device pci 17.3 alias i2c7 off ops i2c_dev_ops end # I2C7 device pci 18.0 alias uart0 off end # UART0 device pci 18.1 alias uart1 off end # UART1 device pci 18.2 alias uart2 off end # UART2 diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index 1fcc37e800..963ed40339 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -25,14 +25,14 @@ chip soc/intel/apollolake device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 device pci 15.0 alias xhci off end # XHCI device pci 15.1 alias xdci off end # XDCI - device pci 16.0 alias i2c0 off end # I2C0 - device pci 16.1 alias i2c1 off end # I2C1 - device pci 16.2 alias i2c2 off end # I2C2 - device pci 16.3 alias i2c3 off end # I2C3 - device pci 17.0 alias i2c4 off end # I2C4 - device pci 17.1 alias i2c5 off end # I2C5 - device pci 17.2 alias i2c6 off end # I2C6 - device pci 17.3 alias i2c7 off end # I2C7 + device pci 16.0 alias i2c0 off ops i2c_dev_ops end # I2C0 + device pci 16.1 alias i2c1 off ops i2c_dev_ops end # I2C1 + device pci 16.2 alias i2c2 off ops i2c_dev_ops end # I2C2 + device pci 16.3 alias i2c3 off ops i2c_dev_ops end # I2C3 + device pci 17.0 alias i2c4 off ops i2c_dev_ops end # I2C4 + device pci 17.1 alias i2c5 off ops i2c_dev_ops end # I2C5 + device pci 17.2 alias i2c6 off ops i2c_dev_ops end # I2C6 + device pci 17.3 alias i2c7 off ops i2c_dev_ops end # I2C7 device pci 18.0 alias uart0 off end # UART0 device pci 18.1 alias uart1 off end # UART1 device pci 18.2 alias uart2 off end # UART2 diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index eb0a0bcb92..acdac57a77 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -82,10 +82,10 @@ chip soc/intel/cannonlake device pci 14.2 alias shared_sram off end # Shared SRAM device pci 14.3 alias cnvi_wifi off end # CNVi Wifi device pci 14.5 alias sdxc off end # SDCard - device pci 15.0 alias i2c0 off end # I2C #0 - device pci 15.1 alias i2c1 off end # I2C #1 - device pci 15.2 alias i2c2 off end # I2C #2 - device pci 15.3 alias i2c3 off end # I2C #3 + device pci 15.0 alias i2c0 off ops i2c_dev_ops end # I2C #0 + device pci 15.1 alias i2c1 off ops i2c_dev_ops end # I2C #1 + device pci 15.2 alias i2c2 off ops i2c_dev_ops end # I2C #2 + device pci 15.3 alias i2c3 off ops i2c_dev_ops end # I2C #3 device pci 16.0 alias heci1 on end # Management Engine Interface 1 device pci 16.1 alias heci2 off end # Management Engine Interface 2 device pci 16.2 alias csme_ider off end # Management Engine IDE-R @@ -93,8 +93,8 @@ chip soc/intel/cannonlake device pci 16.4 alias heci3 off end # Management Engine Interface 3 device pci 16.5 alias heci4 off end # Management Engine Interface 4 device pci 17.0 alias sata off end # SATA - device pci 19.0 alias i2c4 off end # I2C #4 - device pci 19.1 alias i2c5 off end # I2C #5 + device pci 19.0 alias i2c4 off ops i2c_dev_ops end # I2C #4 + device pci 19.1 alias i2c5 off ops i2c_dev_ops end # I2C #5 device pci 19.2 alias uart2 off end # UART #2 device pci 1a.0 alias emmc off end # eMMC device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end # PCI Express Port 1 diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index fa7660b5af..eeeab7b7ad 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -106,10 +106,10 @@ chip soc/intel/cannonlake device pci 14.2 alias shared_sram off end # Shared SRAM device pci 14.3 alias cnvi_wifi off end # CNVi Wifi device pci 14.5 alias sdxc off end # SDCard - device pci 15.0 alias i2c0 off end # I2C #0 - device pci 15.1 alias i2c1 off end # I2C #1 - device pci 15.2 alias i2c2 off end # I2C #2 - device pci 15.3 alias i2c3 off end # I2C #3 + device pci 15.0 alias i2c0 off ops i2c_dev_ops end # I2C #0 + device pci 15.1 alias i2c1 off ops i2c_dev_ops end # I2C #1 + device pci 15.2 alias i2c2 off ops i2c_dev_ops end # I2C #2 + device pci 15.3 alias i2c3 off ops i2c_dev_ops end # I2C #3 device pci 16.0 alias heci1 on end # Management Engine Interface 1 device pci 16.1 alias heci2 off end # Management Engine Interface 2 device pci 16.2 alias csme_ider off end # Management Engine IDE-R @@ -117,8 +117,8 @@ chip soc/intel/cannonlake device pci 16.4 alias heci3 off end # Management Engine Interface 3 device pci 16.5 alias heci4 off end # Management Engine Interface 4 device pci 17.0 alias sata off end # SATA - device pci 19.0 alias i2c4 off end # I2C #4 - device pci 19.1 alias i2c5 off end # I2C #5 + device pci 19.0 alias i2c4 off ops i2c_dev_ops end # I2C #4 + device pci 19.1 alias i2c5 off ops i2c_dev_ops end # I2C #5 device pci 19.2 alias uart2 off # UART #2 ops uart_ops end diff --git a/src/soc/intel/common/block/i2c/i2c.c b/src/soc/intel/common/block/i2c/i2c.c index 7609b217a3..8018ee573d 100644 --- a/src/soc/intel/common/block/i2c/i2c.c +++ b/src/soc/intel/common/block/i2c/i2c.c @@ -180,99 +180,12 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_NVL_I2C3, PCI_DID_INTEL_NVL_I2C4, PCI_DID_INTEL_NVL_I2C5, - PCI_DID_INTEL_WCL_I2C0, - PCI_DID_INTEL_WCL_I2C1, - PCI_DID_INTEL_WCL_I2C2, - PCI_DID_INTEL_WCL_I2C3, - PCI_DID_INTEL_WCL_I2C4, - PCI_DID_INTEL_WCL_I2C5, - PCI_DID_INTEL_PTL_H_I2C0, - PCI_DID_INTEL_PTL_H_I2C1, - PCI_DID_INTEL_PTL_H_I2C2, - PCI_DID_INTEL_PTL_H_I2C3, - PCI_DID_INTEL_PTL_H_I2C4, - PCI_DID_INTEL_PTL_H_I2C5, - PCI_DID_INTEL_PTL_U_H_I2C0, - PCI_DID_INTEL_PTL_U_H_I2C1, - PCI_DID_INTEL_PTL_U_H_I2C2, - PCI_DID_INTEL_PTL_U_H_I2C3, - PCI_DID_INTEL_PTL_U_H_I2C4, - PCI_DID_INTEL_PTL_U_H_I2C5, PCI_DID_INTEL_LNL_I2C0, PCI_DID_INTEL_LNL_I2C1, PCI_DID_INTEL_LNL_I2C2, PCI_DID_INTEL_LNL_I2C3, PCI_DID_INTEL_LNL_I2C4, PCI_DID_INTEL_LNL_I2C5, - PCI_DID_INTEL_MTL_I2C0, - PCI_DID_INTEL_MTL_I2C1, - PCI_DID_INTEL_MTL_I2C2, - PCI_DID_INTEL_MTL_I2C3, - PCI_DID_INTEL_MTL_I2C4, - PCI_DID_INTEL_MTL_I2C5, - PCI_DID_INTEL_ARL_I2C0, - PCI_DID_INTEL_ARL_I2C1, - PCI_DID_INTEL_ARL_I2C2, - PCI_DID_INTEL_ARL_I2C3, - PCI_DID_INTEL_ARL_I2C4, - PCI_DID_INTEL_ARL_I2C5, - PCI_DID_INTEL_ARP_S_I2C0, - PCI_DID_INTEL_ARP_S_I2C1, - PCI_DID_INTEL_ARP_S_I2C2, - PCI_DID_INTEL_ARP_S_I2C3, - PCI_DID_INTEL_ARP_S_I2C4, - PCI_DID_INTEL_ARP_S_I2C5, - PCI_DID_INTEL_APL_I2C0, - PCI_DID_INTEL_APL_I2C1, - PCI_DID_INTEL_APL_I2C2, - PCI_DID_INTEL_APL_I2C3, - PCI_DID_INTEL_APL_I2C4, - PCI_DID_INTEL_APL_I2C5, - PCI_DID_INTEL_APL_I2C6, - PCI_DID_INTEL_APL_I2C7, - PCI_DID_INTEL_CNL_I2C0, - PCI_DID_INTEL_CNL_I2C1, - PCI_DID_INTEL_CNL_I2C2, - PCI_DID_INTEL_CNL_I2C3, - PCI_DID_INTEL_CNL_I2C4, - PCI_DID_INTEL_CNL_I2C5, - PCI_DID_INTEL_GLK_I2C0, - PCI_DID_INTEL_GLK_I2C1, - PCI_DID_INTEL_GLK_I2C2, - PCI_DID_INTEL_GLK_I2C3, - PCI_DID_INTEL_GLK_I2C4, - PCI_DID_INTEL_GLK_I2C5, - PCI_DID_INTEL_GLK_I2C6, - PCI_DID_INTEL_GLK_I2C7, - PCI_DID_INTEL_CNP_H_I2C0, - PCI_DID_INTEL_CNP_H_I2C1, - PCI_DID_INTEL_CNP_H_I2C2, - PCI_DID_INTEL_CNP_H_I2C3, - PCI_DID_INTEL_CMP_I2C0, - PCI_DID_INTEL_CMP_I2C1, - PCI_DID_INTEL_CMP_I2C2, - PCI_DID_INTEL_CMP_I2C3, - PCI_DID_INTEL_CMP_I2C4, - PCI_DID_INTEL_CMP_I2C5, - PCI_DID_INTEL_CMP_H_I2C0, - PCI_DID_INTEL_CMP_H_I2C1, - PCI_DID_INTEL_CMP_H_I2C2, - PCI_DID_INTEL_CMP_H_I2C3, - PCI_DID_INTEL_TGP_I2C0, - PCI_DID_INTEL_TGP_I2C1, - PCI_DID_INTEL_TGP_I2C2, - PCI_DID_INTEL_TGP_I2C3, - PCI_DID_INTEL_TGP_I2C4, - PCI_DID_INTEL_TGP_I2C5, - PCI_DID_INTEL_TGP_I2C6, - PCI_DID_INTEL_TGP_I2C7, - PCI_DID_INTEL_TGP_H_I2C0, - PCI_DID_INTEL_TGP_H_I2C1, - PCI_DID_INTEL_TGP_H_I2C2, - PCI_DID_INTEL_TGP_H_I2C3, - PCI_DID_INTEL_TGP_H_I2C4, - PCI_DID_INTEL_TGP_H_I2C5, - PCI_DID_INTEL_TGP_H_I2C6, PCI_DID_INTEL_MCC_I2C0, PCI_DID_INTEL_MCC_I2C1, PCI_DID_INTEL_MCC_I2C2, @@ -281,38 +194,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_MCC_I2C5, PCI_DID_INTEL_MCC_I2C6, PCI_DID_INTEL_MCC_I2C7, - PCI_DID_INTEL_JSP_I2C0, - PCI_DID_INTEL_JSP_I2C1, - PCI_DID_INTEL_JSP_I2C2, - PCI_DID_INTEL_JSP_I2C3, - PCI_DID_INTEL_JSP_I2C4, - PCI_DID_INTEL_JSP_I2C5, - PCI_DID_INTEL_ADP_P_I2C0, - PCI_DID_INTEL_ADP_P_I2C1, - PCI_DID_INTEL_ADP_P_I2C2, - PCI_DID_INTEL_ADP_P_I2C3, - PCI_DID_INTEL_ADP_P_I2C4, - PCI_DID_INTEL_ADP_P_I2C5, - PCI_DID_INTEL_ADP_P_I2C6, - PCI_DID_INTEL_ADP_P_I2C7, - PCI_DID_INTEL_ADP_S_I2C0, - PCI_DID_INTEL_ADP_S_I2C1, - PCI_DID_INTEL_ADP_S_I2C2, - PCI_DID_INTEL_ADP_S_I2C3, - PCI_DID_INTEL_ADP_S_I2C4, - PCI_DID_INTEL_ADP_S_I2C5, - PCI_DID_INTEL_ADP_M_N_I2C0, - PCI_DID_INTEL_ADP_M_N_I2C1, - PCI_DID_INTEL_ADP_M_N_I2C2, - PCI_DID_INTEL_ADP_M_N_I2C3, - PCI_DID_INTEL_ADP_M_N_I2C4, - PCI_DID_INTEL_ADP_M_N_I2C5, - PCI_DID_INTEL_RPP_S_I2C0, - PCI_DID_INTEL_RPP_S_I2C1, - PCI_DID_INTEL_RPP_S_I2C2, - PCI_DID_INTEL_RPP_S_I2C3, - PCI_DID_INTEL_RPP_S_I2C4, - PCI_DID_INTEL_RPP_S_I2C5, 0, }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index aa25ff5e8e..1a85aa8e40 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -65,16 +65,16 @@ chip soc/intel/jasperlake device pci 14.2 alias shared_ram off end device pci 14.3 alias cnvi_wifi off end device pci 14.5 alias sdxc off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 off end device pci 16.1 alias heci2 off end device pci 16.4 alias heci3 off end device pci 17.0 alias sata off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end device pci 1a.0 alias emmc off end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index 6851b5769f..57c82b3b61 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -153,10 +153,10 @@ chip soc/intel/meteorlake device pci 14.2 alias pmc_shared_sram off end device pci 14.3 alias cnvi_wifi off end device pci 14.5 alias ieh off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 15.4 alias i3c off end device pci 16.0 alias heci1 on end device pci 16.1 alias heci2 off end @@ -166,8 +166,8 @@ chip soc/intel/meteorlake device pci 18.0 alias eheci1 off end device pci 18.1 alias eheci2 off end device pci 18.2 alias eheci3 off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index 31a898182f..e45558b4ec 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -215,10 +215,10 @@ chip soc/intel/pantherlake device pci 14.3 alias cnvi_wifi off end device pci 14.7 alias cnvi_bluetooth off end device pci 14.5 alias ieh off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 on end device pci 16.1 alias heci2 off end device pci 16.4 alias heci3 off end @@ -226,8 +226,8 @@ chip soc/intel/pantherlake device pci 18.0 alias eheci1 off end device pci 18.1 alias eheci2 off end device pci 18.2 alias eheci3 off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end diff --git a/src/soc/intel/pantherlake/chipset_wcl.cb b/src/soc/intel/pantherlake/chipset_wcl.cb index 2236d930e2..3d4f641260 100644 --- a/src/soc/intel/pantherlake/chipset_wcl.cb +++ b/src/soc/intel/pantherlake/chipset_wcl.cb @@ -101,10 +101,10 @@ chip soc/intel/pantherlake device pci 14.3 alias cnvi_wifi off end device pci 14.7 alias cnvi_bluetooth off end device pci 14.5 alias ieh off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 on end device pci 16.1 alias heci2 off end device pci 16.4 alias heci3 off end @@ -113,8 +113,8 @@ chip soc/intel/pantherlake device pci 18.0 alias eheci1 off end device pci 18.1 alias eheci2 off end device pci 18.2 alias eheci3 off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index bdf0138229..38cfc0dca1 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -115,10 +115,10 @@ chip soc/intel/tigerlake device pci 14.1 alias south_xdci off end device pci 14.2 alias shared_ram off end device pci 14.3 alias cnvi_wifi off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 off end device pci 16.1 alias heci2 off end device pci 16.2 alias csme1 off end @@ -126,8 +126,8 @@ chip soc/intel/tigerlake device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end device pci 17.0 alias sata off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index e2c7022546..a43778794c 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -63,7 +63,7 @@ chip soc/intel/tigerlake device pci 10.6 alias thc0 off end device pci 10.7 alias thc1 off end device pci 11.0 alias uart3 off end - device pci 11.3 alias i2c6 off end + device pci 11.3 alias i2c6 off ops i2c_dev_ops end device pci 12.0 alias ish off end device pci 12.6 alias gspi2 off end device pci 13.0 alias gspi3 off end @@ -137,10 +137,10 @@ chip soc/intel/tigerlake device pci 14.1 alias south_xdci off end device pci 14.2 alias shared_ram off end device pci 14.3 alias cnvi_wifi off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 off end device pci 16.1 alias heci2 off end device pci 16.2 alias csme1 off end @@ -148,8 +148,8 @@ chip soc/intel/tigerlake device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end device pci 17.0 alias sata off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end device pci 1b.0 alias pcie_rp17 off ops pcie_rp_ops end device pci 1b.1 alias pcie_rp18 off ops pcie_rp_ops end From fafa37d2bdd7403c71eaefb4c865d5c8017e68cc Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 19:05:49 -0600 Subject: [PATCH 308/789] soc/intel: Use chipset.cb for SATA device ops linking Move SATA device operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them, matching the approach used by Skylake. Remove corresponding DIDs from sata.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. Add `select SOC_INTEL_COMMON_BLOCK_SATA` to Apollolake SoC so that the common block code is included, which it was not previously, even though the APL/GLK PCI DIDs were included in the list. The net effect is that the `SATA` ACPI device is now added to SSDT for APL/GLK boards when they have SATA enabled. This standardizes the approach across Intel SoCs and makes the SATA controller configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common driver code. Change-Id: I4c296a88c4da5f91d1039877ec858857496527f0 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90915 Tested-by: build bot (Jenkins) Reviewed-by: Jakub "Kuba" Czapiga --- src/soc/intel/alderlake/chipset.cb | 2 +- src/soc/intel/alderlake/chipset_pch_s.cb | 2 +- src/soc/intel/apollolake/Kconfig | 1 + src/soc/intel/apollolake/chipset_apl.cb | 2 +- src/soc/intel/apollolake/chipset_glk.cb | 2 +- src/soc/intel/cannonlake/chipset.cb | 2 +- src/soc/intel/cannonlake/chipset_pch_h.cb | 2 +- src/soc/intel/common/block/sata/sata.c | 43 ----------------------- src/soc/intel/jasperlake/chipset.cb | 2 +- src/soc/intel/meteorlake/chipset.cb | 2 +- src/soc/intel/tigerlake/chipset.cb | 2 +- src/soc/intel/tigerlake/chipset_pch_h.cb | 2 +- 12 files changed, 11 insertions(+), 53 deletions(-) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index dcd5ebc400..1758d9df74 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -242,7 +242,7 @@ chip soc/intel/alderlake device pci 16.3 alias kt off end device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end - device pci 17.0 alias sata off end + device pci 17.0 alias sata off ops sata_ops end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index a1a056bcf2..28dbc9e458 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -373,7 +373,7 @@ chip soc/intel/alderlake device pci 16.3 alias kt off end device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end - device pci 17.0 alias sata off end + device pci 17.0 alias sata off ops sata_ops end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index ef5d4f6b8a..be87a8c10d 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -66,6 +66,7 @@ config SOC_INTEL_APOLLOLAKE select SOC_INTEL_COMMON_BLOCK_PMC_DISCOVERABLE select SOC_INTEL_COMMON_BLOCK_SRAM select SOC_INTEL_COMMON_BLOCK_SA + select SOC_INTEL_COMMON_BLOCK_SATA select SOC_INTEL_COMMON_BLOCK_SCS select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_BLOCK_SMM diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index 7184a0c401..10d2b04cfe 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -15,7 +15,7 @@ chip soc/intel/apollolake device pci 0f.1 alias heci2 off end # HECI2 device pci 0f.2 alias heci3 off end # HECI3 device pci 11.0 alias ish off end # SensorHub - device pci 12.0 alias sata off end # SATA + device pci 12.0 alias sata off ops sata_ops end # SATA device pci 13.0 alias pcie_rp01 off ops pcie_rp_ops end # PCIE Express Root Port 1 device pci 13.1 alias pcie_rp02 off ops pcie_rp_ops end # PCIE Express Root Port 2 device pci 13.2 alias pcie_rp03 off ops pcie_rp_ops end # PCIE Express Root Port 3 diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index 963ed40339..7d1bb35ba4 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -16,7 +16,7 @@ chip soc/intel/apollolake device pci 0f.1 alias heci2 off end # HECI2 device pci 0f.2 alias heci3 off end # HECI3 device pci 11.0 alias ish off end # SensorHub - device pci 12.0 alias sata off end # SATA + device pci 12.0 alias sata off ops sata_ops end # SATA device pci 13.0 alias pcie_rp01 off ops pcie_rp_ops end # PCIE Express Root Port 1 device pci 13.1 alias pcie_rp02 off ops pcie_rp_ops end # PCIE Express Root Port 2 device pci 13.2 alias pcie_rp03 off ops pcie_rp_ops end # PCIE Express Root Port 3 diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index acdac57a77..d55036e7fa 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -92,7 +92,7 @@ chip soc/intel/cannonlake device pci 16.3 alias csme_ktr off end # Management Engine KT Redirection device pci 16.4 alias heci3 off end # Management Engine Interface 3 device pci 16.5 alias heci4 off end # Management Engine Interface 4 - device pci 17.0 alias sata off end # SATA + device pci 17.0 alias sata off ops sata_ops end # SATA device pci 19.0 alias i2c4 off ops i2c_dev_ops end # I2C #4 device pci 19.1 alias i2c5 off ops i2c_dev_ops end # I2C #5 device pci 19.2 alias uart2 off end # UART #2 diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index eeeab7b7ad..fb9c67ca46 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -116,7 +116,7 @@ chip soc/intel/cannonlake device pci 16.3 alias csme_ktr off end # Management Engine KT Redirection device pci 16.4 alias heci3 off end # Management Engine Interface 3 device pci 16.5 alias heci4 off end # Management Engine Interface 4 - device pci 17.0 alias sata off end # SATA + device pci 17.0 alias sata off ops sata_ops end # SATA device pci 19.0 alias i2c4 off ops i2c_dev_ops end # I2C #4 device pci 19.1 alias i2c5 off ops i2c_dev_ops end # I2C #5 device pci 19.2 alias uart2 off # UART #2 diff --git a/src/soc/intel/common/block/sata/sata.c b/src/soc/intel/common/block/sata/sata.c index 0f85faed50..dd92b9d7ec 100644 --- a/src/soc/intel/common/block/sata/sata.c +++ b/src/soc/intel/common/block/sata/sata.c @@ -35,13 +35,6 @@ struct device_operations sata_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_MTL_SATA, - PCI_DID_INTEL_ARL_SATA, - PCI_DID_INTEL_ARP_S_SATA_1, - PCI_DID_INTEL_ARP_S_SATA_2, - PCI_DID_INTEL_RPP_P_SATA_1, - PCI_DID_INTEL_RPP_P_SATA_2, - PCI_DID_INTEL_RPP_S_SATA, PCI_DID_INTEL_LWB_SATA_AHCI, PCI_DID_INTEL_LWB_SSATA_AHCI, PCI_DID_INTEL_LWB_SATA_RAID, @@ -54,43 +47,7 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_LWB_SATA_ALT_RST, PCI_DID_INTEL_LWB_SSATA_ALT, PCI_DID_INTEL_LWB_SSATA_ALT_RST, - PCI_DID_INTEL_CNL_SATA, - PCI_DID_INTEL_CNL_PREMIUM_SATA, - PCI_DID_INTEL_CNP_CMP_COMPAT_SATA, - PCI_DID_INTEL_CNP_H_SATA, - PCI_DID_INTEL_CNP_H_HALO_SATA, - PCI_DID_INTEL_CNP_LP_SATA, - PCI_DID_INTEL_CMP_SATA, - PCI_DID_INTEL_CMP_PREMIUM_SATA, - PCI_DID_INTEL_CMP_LP_SATA, - PCI_DID_INTEL_CMP_H_SATA, - PCI_DID_INTEL_CMP_H_HALO_SATA, - PCI_DID_INTEL_CMP_H_PREMIUM_SATA, - PCI_DID_INTEL_TGP_LP_SATA, - PCI_DID_INTEL_TGP_SATA, - PCI_DID_INTEL_TGP_PREMIUM_SATA, - PCI_DID_INTEL_TGP_COMPAT_SATA, - PCI_DID_INTEL_TGP_H_SATA, PCI_DID_INTEL_MCC_AHCI_SATA, - PCI_DID_INTEL_JSP_SATA_1, - PCI_DID_INTEL_JSP_SATA_2, - PCI_DID_INTEL_ADP_P_SATA_1, - PCI_DID_INTEL_ADP_P_SATA_2, - PCI_DID_INTEL_ADP_P_SATA_3, - PCI_DID_INTEL_ADP_P_SATA_4, - PCI_DID_INTEL_ADP_P_SATA_5, - PCI_DID_INTEL_ADP_P_SATA_6, - PCI_DID_INTEL_ADP_S_SATA_1, - PCI_DID_INTEL_ADP_S_SATA_2, - PCI_DID_INTEL_ADP_S_SATA_3, - PCI_DID_INTEL_ADP_S_SATA_4, - PCI_DID_INTEL_ADP_S_SATA_5, - PCI_DID_INTEL_ADP_S_SATA_6, - PCI_DID_INTEL_ADP_M_SATA_1, - PCI_DID_INTEL_ADP_M_SATA_2, - PCI_DID_INTEL_ADP_M_SATA_3, - PCI_DID_INTEL_APL_SATA, - PCI_DID_INTEL_GLK_SATA, 0 }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index 1a85aa8e40..4c7b8e8cd6 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -72,7 +72,7 @@ chip soc/intel/jasperlake device pci 16.0 alias heci1 off end device pci 16.1 alias heci2 off end device pci 16.4 alias heci3 off end - device pci 17.0 alias sata off end + device pci 17.0 alias sata off ops sata_ops end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index 57c82b3b61..01ab3c134f 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -162,7 +162,7 @@ chip soc/intel/meteorlake device pci 16.1 alias heci2 off end device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end - device pci 17.0 alias sata off end + device pci 17.0 alias sata off ops sata_ops end device pci 18.0 alias eheci1 off end device pci 18.1 alias eheci2 off end device pci 18.2 alias eheci3 off end diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index 38cfc0dca1..a75057a4e9 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -125,7 +125,7 @@ chip soc/intel/tigerlake device pci 16.3 alias csme2 off end device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end - device pci 17.0 alias sata off end + device pci 17.0 alias sata off ops sata_ops end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index a43778794c..45fd63403c 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -147,7 +147,7 @@ chip soc/intel/tigerlake device pci 16.3 alias csme2 off end device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end - device pci 17.0 alias sata off end + device pci 17.0 alias sata off ops sata_ops end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end device pci 19.2 alias uart2 off end From d1e1d36fff09b5242246d183bf8f745fcebeb35e Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 19:08:51 -0600 Subject: [PATCH 309/789] soc/intel: Use chipset.cb for UART device ops linking Move UART device operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them, matching the approach used by Skylake. Remove corresponding DIDs from uart.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. This standardizes the approach across Intel SoCs and makes the UART controller configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common driver code. Change-Id: Id26dad7997d64bcaad53fa39be23e52cb47dcc1d Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90916 Reviewed-by: Jakub "Kuba" Czapiga Tested-by: build bot (Jenkins) --- src/soc/intel/alderlake/chipset.cb | 6 +- src/soc/intel/alderlake/chipset_pch_s.cb | 8 +-- src/soc/intel/apollolake/chipset_apl.cb | 8 +-- src/soc/intel/apollolake/chipset_glk.cb | 8 +-- src/soc/intel/cannonlake/chipset.cb | 6 +- src/soc/intel/cannonlake/chipset_pch_h.cb | 4 +- src/soc/intel/common/block/uart/uart.c | 71 ----------------------- src/soc/intel/jasperlake/chipset.cb | 6 +- src/soc/intel/meteorlake/chipset.cb | 6 +- src/soc/intel/pantherlake/chipset_ptl.cb | 6 +- src/soc/intel/pantherlake/chipset_wcl.cb | 6 +- src/soc/intel/tigerlake/chipset.cb | 6 +- src/soc/intel/tigerlake/chipset_pch_h.cb | 8 +-- 13 files changed, 39 insertions(+), 110 deletions(-) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index 1758d9df74..4c925b4677 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -245,7 +245,7 @@ chip soc/intel/alderlake device pci 17.0 alias sata off ops sata_ops end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end - device pci 19.2 alias uart2 off end + device pci 19.2 alias uart2 off ops uart_ops end # eMMC device is applicable only for ADL-N device pci 1a.0 alias emmc off end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end @@ -260,8 +260,8 @@ chip soc/intel/alderlake device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end device pci 1e.2 alias gspi0 off end device pci 1e.3 alias gspi1 off end device pci 1f.0 alias pch_espi on end diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index 28dbc9e458..90395a9cf6 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -277,7 +277,7 @@ chip soc/intel/alderlake device pci 09.0 alias north_tracehub off end device pci 0a.0 alias crashlog on end device pci 0e.0 alias vmd off end - device pci 11.0 alias uart3 off end + device pci 11.0 alias uart3 off ops uart_ops end device pci 12.0 alias ish off end device pci 12.6 alias gspi2 off end device pci 13.0 alias gspi3 off end @@ -376,7 +376,7 @@ chip soc/intel/alderlake device pci 17.0 alias sata off ops sata_ops end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end - device pci 19.2 alias uart2 off end + device pci 19.2 alias uart2 off ops uart_ops end device pci 1a.0 alias pcie_rp25 off ops pcie_rp_ops end device pci 1a.1 alias pcie_rp26 off ops pcie_rp_ops end device pci 1a.2 alias pcie_rp27 off ops pcie_rp_ops end @@ -405,8 +405,8 @@ chip soc/intel/alderlake device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end device pci 1e.2 alias gspi0 off end device pci 1e.3 alias gspi1 off end device pci 1f.0 alias pch_espi on end diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index 10d2b04cfe..f0ffffc269 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -32,10 +32,10 @@ chip soc/intel/apollolake device pci 17.1 alias i2c5 off ops i2c_dev_ops end # I2C5 device pci 17.2 alias i2c6 off ops i2c_dev_ops end # I2C6 device pci 17.3 alias i2c7 off ops i2c_dev_ops end # I2C7 - device pci 18.0 alias uart0 off end # UART0 - device pci 18.1 alias uart1 off end # UART1 - device pci 18.2 alias uart2 off end # UART2 - device pci 18.3 alias uart3 off end # UART3 + device pci 18.0 alias uart0 off ops uart_ops end # UART0 + device pci 18.1 alias uart1 off ops uart_ops end # UART1 + device pci 18.2 alias uart2 off ops uart_ops end # UART2 + device pci 18.3 alias uart3 off ops uart_ops end # UART3 device pci 19.0 alias spi0 off end # SPI0 device pci 19.1 alias spi1 off end # SPI1 device pci 19.2 alias spi2 off end # SPI3 diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index 7d1bb35ba4..8e534e4e2f 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -33,10 +33,10 @@ chip soc/intel/apollolake device pci 17.1 alias i2c5 off ops i2c_dev_ops end # I2C5 device pci 17.2 alias i2c6 off ops i2c_dev_ops end # I2C6 device pci 17.3 alias i2c7 off ops i2c_dev_ops end # I2C7 - device pci 18.0 alias uart0 off end # UART0 - device pci 18.1 alias uart1 off end # UART1 - device pci 18.2 alias uart2 off end # UART2 - device pci 18.3 alias uart3 off end # UART3 + device pci 18.0 alias uart0 off ops uart_ops end # UART0 + device pci 18.1 alias uart1 off ops uart_ops end # UART1 + device pci 18.2 alias uart2 off ops uart_ops end # UART2 + device pci 18.3 alias uart3 off ops uart_ops end # UART3 device pci 19.0 alias spi0 off end # SPI0 device pci 19.1 alias spi1 off end # SPI1 device pci 19.2 alias spi2 off end # SPI3 diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index d55036e7fa..20a7250794 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -95,7 +95,7 @@ chip soc/intel/cannonlake device pci 17.0 alias sata off ops sata_ops end # SATA device pci 19.0 alias i2c4 off ops i2c_dev_ops end # I2C #4 device pci 19.1 alias i2c5 off ops i2c_dev_ops end # I2C #5 - device pci 19.2 alias uart2 off end # UART #2 + device pci 19.2 alias uart2 off ops uart_ops end # UART #2 device pci 1a.0 alias emmc off end # eMMC device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end # PCI Express Port 1 device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end # PCI Express Port 2 @@ -113,8 +113,8 @@ chip soc/intel/cannonlake device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end # PCI Express Port 14 device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end # PCI Express Port 15 device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end # PCI Express Port 16 - device pci 1e.0 alias uart0 off end # UART #0 - device pci 1e.1 alias uart1 off end # UART #1 + device pci 1e.0 alias uart0 off ops uart_ops end # UART #0 + device pci 1e.1 alias uart1 off ops uart_ops end # UART #1 device pci 1e.2 alias gspi0 off end # GSPI #0 device pci 1e.3 alias gspi1 off end # GSPI #1 device pci 1f.0 alias lpc_espi on end # LPC Interface diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index fb9c67ca46..76648c0ca0 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -147,8 +147,8 @@ chip soc/intel/cannonlake device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end # PCI Express Port 14 device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end # PCI Express Port 15 device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end # PCI Express Port 16 - device pci 1e.0 alias uart0 off end # UART #0 - device pci 1e.1 alias uart1 off end # UART #1 + device pci 1e.0 alias uart0 off ops uart_ops end # UART #0 + device pci 1e.1 alias uart1 off ops uart_ops end # UART #1 device pci 1e.2 alias gspi0 off end # GSPI #0 device pci 1e.3 alias gspi1 off end # GSPI #1 device pci 1f.0 alias lpc_espi on end # LPC Interface diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index 2b2c8c28fc..f16d337e64 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -366,83 +366,12 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_NVL_UART0, PCI_DID_INTEL_NVL_UART1, PCI_DID_INTEL_NVL_UART2, - PCI_DID_INTEL_WCL_UART0, - PCI_DID_INTEL_WCL_UART1, - PCI_DID_INTEL_WCL_UART2, - PCI_DID_INTEL_PTL_H_UART0, - PCI_DID_INTEL_PTL_H_UART1, - PCI_DID_INTEL_PTL_H_UART2, - PCI_DID_INTEL_PTL_U_H_UART0, - PCI_DID_INTEL_PTL_U_H_UART1, - PCI_DID_INTEL_PTL_U_H_UART2, PCI_DID_INTEL_LNL_UART0, PCI_DID_INTEL_LNL_UART1, PCI_DID_INTEL_LNL_UART2, - PCI_DID_INTEL_MTL_UART0, - PCI_DID_INTEL_MTL_UART1, - PCI_DID_INTEL_MTL_UART2, - PCI_DID_INTEL_ARL_UART0, - PCI_DID_INTEL_ARL_UART1, - PCI_DID_INTEL_ARL_UART2, - PCI_DID_INTEL_ARP_S_UART0, - PCI_DID_INTEL_ARP_S_UART1, - PCI_DID_INTEL_ARP_S_UART2, - PCI_DID_INTEL_ARP_S_UART3, - PCI_DID_INTEL_APL_UART0, - PCI_DID_INTEL_APL_UART1, - PCI_DID_INTEL_APL_UART2, - PCI_DID_INTEL_APL_UART3, - PCI_DID_INTEL_CNL_UART0, - PCI_DID_INTEL_CNL_UART1, - PCI_DID_INTEL_CNL_UART2, - PCI_DID_INTEL_GLK_UART0, - PCI_DID_INTEL_GLK_UART1, - PCI_DID_INTEL_GLK_UART2, - PCI_DID_INTEL_GLK_UART3, - PCI_DID_INTEL_CNP_H_UART0, - PCI_DID_INTEL_CNP_H_UART1, - PCI_DID_INTEL_CNP_H_UART2, - PCI_DID_INTEL_CMP_UART0, - PCI_DID_INTEL_CMP_UART1, - PCI_DID_INTEL_CMP_UART2, - PCI_DID_INTEL_CMP_H_UART0, - PCI_DID_INTEL_CMP_H_UART1, - PCI_DID_INTEL_CMP_H_UART2, - PCI_DID_INTEL_TGP_UART0, - PCI_DID_INTEL_TGP_UART1, - PCI_DID_INTEL_TGP_UART2, - PCI_DID_INTEL_TGP_H_UART0, - PCI_DID_INTEL_TGP_H_UART1, - PCI_DID_INTEL_TGP_H_UART2, - PCI_DID_INTEL_TGP_H_UART3, PCI_DID_INTEL_MCC_UART0, PCI_DID_INTEL_MCC_UART1, PCI_DID_INTEL_MCC_UART2, - PCI_DID_INTEL_JSP_UART0, - PCI_DID_INTEL_JSP_UART1, - PCI_DID_INTEL_JSP_UART2, - PCI_DID_INTEL_ADP_S_UART0, - PCI_DID_INTEL_ADP_S_UART1, - PCI_DID_INTEL_ADP_S_UART2, - PCI_DID_INTEL_ADP_S_UART3, - PCI_DID_INTEL_ADP_S_UART4, - PCI_DID_INTEL_ADP_S_UART5, - PCI_DID_INTEL_ADP_S_UART6, - PCI_DID_INTEL_ADP_P_UART0, - PCI_DID_INTEL_ADP_P_UART1, - PCI_DID_INTEL_ADP_P_UART2, - PCI_DID_INTEL_ADP_P_UART3, - PCI_DID_INTEL_ADP_P_UART4, - PCI_DID_INTEL_ADP_P_UART5, - PCI_DID_INTEL_ADP_P_UART6, - PCI_DID_INTEL_ADP_M_N_UART0, - PCI_DID_INTEL_ADP_M_N_UART1, - PCI_DID_INTEL_ADP_M_N_UART2, - PCI_DID_INTEL_ADP_M_N_UART3, - PCI_DID_INTEL_RPP_S_UART0, - PCI_DID_INTEL_RPP_S_UART1, - PCI_DID_INTEL_RPP_S_UART2, - PCI_DID_INTEL_RPP_S_UART3, 0, }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index 4c7b8e8cd6..49cb3d2e98 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -75,7 +75,7 @@ chip soc/intel/jasperlake device pci 17.0 alias sata off ops sata_ops end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end - device pci 19.2 alias uart2 off end + device pci 19.2 alias uart2 off ops uart_ops end device pci 1a.0 alias emmc off end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end @@ -85,8 +85,8 @@ chip soc/intel/jasperlake device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end device pci 1e.2 alias gspi0 off end device pci 1e.3 alias gspi1 off end device pci 1f.0 alias pch_espi on end diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index 01ab3c134f..8abfa1261d 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -168,7 +168,7 @@ chip soc/intel/meteorlake device pci 18.2 alias eheci3 off end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end - device pci 19.2 alias uart2 off end + device pci 19.2 alias uart2 off ops uart_ops end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end @@ -177,8 +177,8 @@ chip soc/intel/meteorlake device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end device pci 1e.2 alias gspi0 off end device pci 1e.3 alias gspi1 off end device pci 1e.4 alias tsn_gbe1 off end diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index e45558b4ec..4540ce7a08 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -228,7 +228,7 @@ chip soc/intel/pantherlake device pci 18.2 alias eheci3 off end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end - device pci 19.2 alias uart2 off end + device pci 19.2 alias uart2 off ops uart_ops end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end @@ -237,8 +237,8 @@ chip soc/intel/pantherlake device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end device pci 1e.2 alias gspi0 off end device pci 1e.3 alias gspi1 off end device pci 1f.0 alias soc_espi on end diff --git a/src/soc/intel/pantherlake/chipset_wcl.cb b/src/soc/intel/pantherlake/chipset_wcl.cb index 3d4f641260..b2ec967c75 100644 --- a/src/soc/intel/pantherlake/chipset_wcl.cb +++ b/src/soc/intel/pantherlake/chipset_wcl.cb @@ -115,13 +115,13 @@ chip soc/intel/pantherlake device pci 18.2 alias eheci3 off end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end - device pci 19.2 alias uart2 off end + device pci 19.2 alias uart2 off ops uart_ops end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end device pci 1e.2 alias gspi0 off end device pci 1e.3 alias gspi1 off end device pci 1f.0 alias soc_espi on end diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index a75057a4e9..4258988603 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -128,7 +128,7 @@ chip soc/intel/tigerlake device pci 17.0 alias sata off ops sata_ops end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end - device pci 19.2 alias uart2 off end + device pci 19.2 alias uart2 off ops uart_ops end device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end @@ -141,8 +141,8 @@ chip soc/intel/tigerlake device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end device pci 1e.2 alias gspi0 off end device pci 1e.3 alias gspi1 off end device pci 1f.0 alias pch_espi on end diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index 45fd63403c..c980f62f1c 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -62,7 +62,7 @@ chip soc/intel/tigerlake device pci 0e.0 alias vmd off end device pci 10.6 alias thc0 off end device pci 10.7 alias thc1 off end - device pci 11.0 alias uart3 off end + device pci 11.0 alias uart3 off ops uart_ops end device pci 11.3 alias i2c6 off ops i2c_dev_ops end device pci 12.0 alias ish off end device pci 12.6 alias gspi2 off end @@ -150,7 +150,7 @@ chip soc/intel/tigerlake device pci 17.0 alias sata off ops sata_ops end device pci 19.0 alias i2c4 off ops i2c_dev_ops end device pci 19.1 alias i2c5 off ops i2c_dev_ops end - device pci 19.2 alias uart2 off end + device pci 19.2 alias uart2 off ops uart_ops end device pci 1b.0 alias pcie_rp17 off ops pcie_rp_ops end device pci 1b.1 alias pcie_rp18 off ops pcie_rp_ops end device pci 1b.2 alias pcie_rp19 off ops pcie_rp_ops end @@ -175,8 +175,8 @@ chip soc/intel/tigerlake device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end device pci 1e.2 alias gspi0 off end device pci 1e.3 alias gspi1 off end device pci 1f.0 alias pch_espi on end From e519cacd26de2b2cc60fa5528efc8e2c1636c00d Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 19:11:20 -0600 Subject: [PATCH 310/789] soc/intel: Use chipset.cb for GSPI device ops linking Move GSPI/SPI device operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them, matching the approach used by Skylake. Remove corresponding DIDs from spi.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. This standardizes the approach across Intel SoCs and makes the GSPI/SPI controller configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common driver code. Change-Id: Ia379cff36a5b277d89cad757edc094a5d786a51b Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90917 Reviewed-by: Jakub "Kuba" Czapiga Tested-by: build bot (Jenkins) --- src/soc/intel/alderlake/chipset.cb | 8 +-- src/soc/intel/alderlake/chipset_pch_s.cb | 8 +-- src/soc/intel/apollolake/chipset_apl.cb | 6 +- src/soc/intel/apollolake/chipset_glk.cb | 6 +- src/soc/intel/cannonlake/chipset.cb | 6 +- src/soc/intel/cannonlake/chipset_pch_h.cb | 6 +- src/soc/intel/common/block/spi/spi.c | 76 ----------------------- src/soc/intel/jasperlake/chipset.cb | 6 +- src/soc/intel/meteorlake/chipset.cb | 6 +- src/soc/intel/pantherlake/chipset_ptl.cb | 6 +- src/soc/intel/pantherlake/chipset_wcl.cb | 6 +- src/soc/intel/tigerlake/chipset.cb | 8 +-- src/soc/intel/tigerlake/chipset_pch_h.cb | 8 +-- 13 files changed, 40 insertions(+), 116 deletions(-) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index 4c925b4677..36685783a2 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -177,9 +177,9 @@ chip soc/intel/alderlake device pci 10.6 alias thc0 off end device pci 10.7 alias thc1 off end device pci 12.0 alias ish off end - device pci 12.6 alias gspi2 off end + device pci 12.6 alias gspi2 off ops spi_dev_ops end device pci 12.7 alias ufs off end - device pci 13.0 alias gspi3 off end + device pci 13.0 alias gspi3 off ops spi_dev_ops end device pci 14.0 alias xhci off chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" @@ -262,8 +262,8 @@ chip soc/intel/alderlake device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off ops uart_ops end device pci 1e.1 alias uart1 off ops uart_ops end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index 90395a9cf6..a7f2b64399 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -279,8 +279,8 @@ chip soc/intel/alderlake device pci 0e.0 alias vmd off end device pci 11.0 alias uart3 off ops uart_ops end device pci 12.0 alias ish off end - device pci 12.6 alias gspi2 off end - device pci 13.0 alias gspi3 off end + device pci 12.6 alias gspi2 off ops spi_dev_ops end + device pci 13.0 alias gspi3 off ops spi_dev_ops end device pci 14.0 alias xhci off chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" @@ -407,8 +407,8 @@ chip soc/intel/alderlake device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off ops uart_ops end device pci 1e.1 alias uart1 off ops uart_ops end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index f0ffffc269..2766ef8d16 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -36,9 +36,9 @@ chip soc/intel/apollolake device pci 18.1 alias uart1 off ops uart_ops end # UART1 device pci 18.2 alias uart2 off ops uart_ops end # UART2 device pci 18.3 alias uart3 off ops uart_ops end # UART3 - device pci 19.0 alias spi0 off end # SPI0 - device pci 19.1 alias spi1 off end # SPI1 - device pci 19.2 alias spi2 off end # SPI3 + device pci 19.0 alias spi0 off ops spi_dev_ops end # SPI0 + device pci 19.1 alias spi1 off ops spi_dev_ops end # SPI1 + device pci 19.2 alias spi2 off ops spi_dev_ops end # SPI3 device pci 1a.0 alias pwm off end # PWM device pci 1b.0 alias sdcard off end # SD Card device pci 1c.0 alias emmc off end # eMMC diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index 8e534e4e2f..3255407abb 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -37,9 +37,9 @@ chip soc/intel/apollolake device pci 18.1 alias uart1 off ops uart_ops end # UART1 device pci 18.2 alias uart2 off ops uart_ops end # UART2 device pci 18.3 alias uart3 off ops uart_ops end # UART3 - device pci 19.0 alias spi0 off end # SPI0 - device pci 19.1 alias spi1 off end # SPI1 - device pci 19.2 alias spi2 off end # SPI3 + device pci 19.0 alias spi0 off ops spi_dev_ops end # SPI0 + device pci 19.1 alias spi1 off ops spi_dev_ops end # SPI1 + device pci 19.2 alias spi2 off ops spi_dev_ops end # SPI3 device pci 1a.0 alias pwm off end # PWM device pci 1c.0 alias emmc off end # eMMC device pci 1d.0 alias ufs off end # UFS diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index 20a7250794..2fd801051a 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -15,7 +15,7 @@ chip soc/intel/cannonlake device pci 08.0 alias gna off end # Gaussian mixture model, Neural network accelerator device pci 12.0 alias thermal off end # Thermal Subsystem device pci 12.5 alias ufs off end # UFS SCS - device pci 12.6 alias gspi2 off end # GSPI #2 + device pci 12.6 alias gspi2 off ops spi_dev_ops end # GSPI #2 device pci 13.0 alias ish off end # ISH device pci 14.0 alias xhci off # USB xHCI chip drivers/usb/acpi @@ -115,8 +115,8 @@ chip soc/intel/cannonlake device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end # PCI Express Port 16 device pci 1e.0 alias uart0 off ops uart_ops end # UART #0 device pci 1e.1 alias uart1 off ops uart_ops end # UART #1 - device pci 1e.2 alias gspi0 off end # GSPI #0 - device pci 1e.3 alias gspi1 off end # GSPI #1 + device pci 1e.2 alias gspi0 off ops spi_dev_ops end # GSPI #0 + device pci 1e.3 alias gspi1 off ops spi_dev_ops end # GSPI #1 device pci 1f.0 alias lpc_espi on end # LPC Interface device pci 1f.1 alias p2sb hidden end # P2SB device pci 1f.2 alias pmc hidden end # Power Management Controller diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index 76648c0ca0..b00e556a2e 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -15,7 +15,7 @@ chip soc/intel/cannonlake device pci 08.0 alias gna off end # Gaussian mixture model, Neural network accelerator device pci 12.0 alias thermal off end # Thermal Subsystem device pci 12.5 alias ufs off end # UFS SCS - device pci 12.6 alias gspi2 off end # GSPI #2 + device pci 12.6 alias gspi2 off ops spi_dev_ops end # GSPI #2 device pci 13.0 alias ish off end # ISH device pci 14.0 alias xhci off # USB xHCI chip drivers/usb/acpi @@ -149,8 +149,8 @@ chip soc/intel/cannonlake device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end # PCI Express Port 16 device pci 1e.0 alias uart0 off ops uart_ops end # UART #0 device pci 1e.1 alias uart1 off ops uart_ops end # UART #1 - device pci 1e.2 alias gspi0 off end # GSPI #0 - device pci 1e.3 alias gspi1 off end # GSPI #1 + device pci 1e.2 alias gspi0 off ops spi_dev_ops end # GSPI #0 + device pci 1e.3 alias gspi1 off ops spi_dev_ops end # GSPI #1 device pci 1f.0 alias lpc_espi on end # LPC Interface device pci 1f.1 alias p2sb hidden end # P2SB device pci 1f.2 alias pmc hidden end # Power Management Controller diff --git a/src/soc/intel/common/block/spi/spi.c b/src/soc/intel/common/block/spi/spi.c index 9ac9719c7a..5c75a2240b 100644 --- a/src/soc/intel/common/block/spi/spi.c +++ b/src/soc/intel/common/block/spi/spi.c @@ -127,88 +127,12 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_NVL_SPI0, PCI_DID_INTEL_NVL_SPI1, PCI_DID_INTEL_NVL_SPI2, - PCI_DID_INTEL_WCL_HWSEQ_SPI, - PCI_DID_INTEL_WCL_SPI0, - PCI_DID_INTEL_WCL_SPI1, - PCI_DID_INTEL_WCL_SPI2, - PCI_DID_INTEL_PTL_H_HWSEQ_SPI, - PCI_DID_INTEL_PTL_H_SPI0, - PCI_DID_INTEL_PTL_H_SPI1, - PCI_DID_INTEL_PTL_H_SPI2, - PCI_DID_INTEL_PTL_U_H_HWSEQ_SPI, - PCI_DID_INTEL_PTL_U_H_SPI0, - PCI_DID_INTEL_PTL_U_H_SPI1, - PCI_DID_INTEL_PTL_U_H_SPI2, PCI_DID_INTEL_LNL_GSPI0, PCI_DID_INTEL_LNL_GSPI1, PCI_DID_INTEL_LNL_GSPI2, - PCI_DID_INTEL_MTL_GSPI0, - PCI_DID_INTEL_MTL_GSPI1, - PCI_DID_INTEL_MTL_GSPI2, - PCI_DID_INTEL_ARL_GSPI0, - PCI_DID_INTEL_ARL_GSPI1, - PCI_DID_INTEL_ARL_GSPI2, - PCI_DID_INTEL_ARP_S_GSPI0, - PCI_DID_INTEL_ARP_S_GSPI1, - PCI_DID_INTEL_ARP_S_GSPI2, - PCI_DID_INTEL_ARP_S_GSPI3, - PCI_DID_INTEL_APL_SPI0, - PCI_DID_INTEL_APL_SPI1, - PCI_DID_INTEL_APL_SPI2, - PCI_DID_INTEL_GLK_SPI0, - PCI_DID_INTEL_GLK_SPI1, - PCI_DID_INTEL_GLK_SPI2, - PCI_DID_INTEL_CNL_SPI0, - PCI_DID_INTEL_CNL_SPI1, - PCI_DID_INTEL_CNL_SPI2, - PCI_DID_INTEL_CNP_H_SPI0, - PCI_DID_INTEL_CNP_H_SPI1, - PCI_DID_INTEL_CNP_H_SPI2, - PCI_DID_INTEL_CMP_SPI0, - PCI_DID_INTEL_CMP_SPI1, - PCI_DID_INTEL_CMP_SPI2, - PCI_DID_INTEL_CMP_H_SPI0, - PCI_DID_INTEL_CMP_H_SPI1, - PCI_DID_INTEL_CMP_H_SPI2, - PCI_DID_INTEL_TGP_GSPI0, - PCI_DID_INTEL_TGP_GSPI1, - PCI_DID_INTEL_TGP_GSPI2, - PCI_DID_INTEL_TGP_GSPI3, - PCI_DID_INTEL_TGP_GSPI4, - PCI_DID_INTEL_TGP_GSPI5, - PCI_DID_INTEL_TGP_GSPI6, - PCI_DID_INTEL_TGP_H_SPI0, - PCI_DID_INTEL_TGP_H_GSPI0, - PCI_DID_INTEL_TGP_H_GSPI1, - PCI_DID_INTEL_TGP_H_GSPI2, - PCI_DID_INTEL_TGP_H_GSPI3, PCI_DID_INTEL_MCC_GSPI0, PCI_DID_INTEL_MCC_GSPI1, PCI_DID_INTEL_MCC_GSPI2, - PCI_DID_INTEL_JSP_SPI0, - PCI_DID_INTEL_JSP_SPI1, - PCI_DID_INTEL_JSP_SPI2, - PCI_DID_INTEL_ADP_P_SPI0, - PCI_DID_INTEL_ADP_P_SPI1, - PCI_DID_INTEL_ADP_P_SPI2, - PCI_DID_INTEL_ADP_P_SPI3, - PCI_DID_INTEL_ADP_P_SPI4, - PCI_DID_INTEL_ADP_P_SPI5, - PCI_DID_INTEL_ADP_P_SPI6, - PCI_DID_INTEL_ADP_S_SPI0, - PCI_DID_INTEL_ADP_S_SPI1, - PCI_DID_INTEL_ADP_S_SPI2, - PCI_DID_INTEL_ADP_S_SPI3, - PCI_DID_INTEL_ADP_S_SPI4, - PCI_DID_INTEL_ADP_S_SPI5, - PCI_DID_INTEL_ADP_S_SPI6, - PCI_DID_INTEL_ADP_M_N_SPI0, - PCI_DID_INTEL_ADP_M_N_SPI1, - PCI_DID_INTEL_ADP_M_SPI2, - PCI_DID_INTEL_RPP_S_SPI0, - PCI_DID_INTEL_RPP_S_SPI1, - PCI_DID_INTEL_RPP_S_SPI2, - PCI_DID_INTEL_RPP_S_SPI3, PCI_DID_INTEL_DNV_SPI, 0 }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index 49cb3d2e98..6d50296019 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -11,7 +11,7 @@ chip soc/intel/jasperlake device pci 09.0 alias north_tracehub off end device pci 12.0 alias ish off end device pci 12.5 alias ufs_scs off end - device pci 12.6 alias gspi2 off end + device pci 12.6 alias gspi2 off ops spi_dev_ops end device pci 14.0 alias south_xhci off chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" @@ -87,8 +87,8 @@ chip soc/intel/jasperlake device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off ops uart_ops end device pci 1e.1 alias uart1 off ops uart_ops end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index 8abfa1261d..1efa776ec0 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -94,7 +94,7 @@ chip soc/intel/meteorlake device pci 10.0 alias thc0 off end device pci 10.1 alias thc1 off end device pci 12.0 alias ish off end - device pci 12.6 alias gspi2 off end + device pci 12.6 alias gspi2 off ops spi_dev_ops end device pci 12.7 alias ufs off end device pci 13.0 alias ioe_p2sb hidden end device pci 13.1 alias ieh2 off end @@ -179,8 +179,8 @@ chip soc/intel/meteorlake device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off ops uart_ops end device pci 1e.1 alias uart1 off ops uart_ops end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1e.4 alias tsn_gbe1 off end device pci 1e.5 alias tsn_gbe2 off end device pci 1f.0 alias soc_espi on end diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index 4540ce7a08..99962c56b0 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -170,7 +170,7 @@ chip soc/intel/pantherlake device pci 10.1 alias thc1 off end device pci 12.0 alias ish off end device pci 12.1 alias p2sb2 hidden end - device pci 12.6 alias gspi0a off end + device pci 12.6 alias gspi0a off ops spi_dev_ops end device pci 13.0 alias heci_1 off end device pci 13.1 alias heci_2 off end device pci 13.2 alias heci_3 off end @@ -239,8 +239,8 @@ chip soc/intel/pantherlake device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off ops uart_ops end device pci 1e.1 alias uart1 off ops uart_ops end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias soc_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end diff --git a/src/soc/intel/pantherlake/chipset_wcl.cb b/src/soc/intel/pantherlake/chipset_wcl.cb index b2ec967c75..cdd57f5a88 100644 --- a/src/soc/intel/pantherlake/chipset_wcl.cb +++ b/src/soc/intel/pantherlake/chipset_wcl.cb @@ -56,7 +56,7 @@ chip soc/intel/pantherlake device pci 10.1 alias thc1 off end device pci 12.0 alias ish off end device pci 12.1 alias p2sb2 hidden end - device pci 12.6 alias gspi0a off end + device pci 12.6 alias gspi0a off ops spi_dev_ops end device pci 13.0 alias heci_1 off end device pci 13.1 alias heci_2 off end device pci 13.2 alias heci_3 off end @@ -122,8 +122,8 @@ chip soc/intel/pantherlake device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off ops uart_ops end device pci 1e.1 alias uart1 off ops uart_ops end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias soc_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index 4258988603..abecd82f61 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -61,8 +61,8 @@ chip soc/intel/tigerlake device pci 10.6 alias thc0 off end device pci 10.7 alias thc1 off end device pci 12.0 alias ish off end - device pci 12.6 alias gspi2 off end - device pci 13.0 alias gspi3 off end + device pci 12.6 alias gspi2 off ops spi_dev_ops end + device pci 13.0 alias gspi3 off ops spi_dev_ops end device pci 14.0 alias south_xhci off chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" @@ -143,8 +143,8 @@ chip soc/intel/tigerlake device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off ops uart_ops end device pci 1e.1 alias uart1 off ops uart_ops end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb off end device pci 1f.2 alias pmc hidden end diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index c980f62f1c..d0a3df588e 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -65,8 +65,8 @@ chip soc/intel/tigerlake device pci 11.0 alias uart3 off ops uart_ops end device pci 11.3 alias i2c6 off ops i2c_dev_ops end device pci 12.0 alias ish off end - device pci 12.6 alias gspi2 off end - device pci 13.0 alias gspi3 off end + device pci 12.6 alias gspi2 off ops spi_dev_ops end + device pci 13.0 alias gspi3 off ops spi_dev_ops end device pci 14.0 alias south_xhci off chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" @@ -177,8 +177,8 @@ chip soc/intel/tigerlake device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end device pci 1e.0 alias uart0 off ops uart_ops end device pci 1e.1 alias uart1 off ops uart_ops end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb off end device pci 1f.2 alias pmc hidden end From 038829feb36b351013a119769c05e2ef996911bc Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 20:11:20 -0600 Subject: [PATCH 311/789] soc/intel: Use chipset.cb for SMBUS device ops linking Move SMBUS device operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them, matching the approach used by Skylake. Remove corresponding DIDs from smbus.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. This standardizes the approach across Intel SoCs and makes the SMBUS controller configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common driver code. Change-Id: I1c742836d923eb8f521bdbd7fa8260c82c1156ac Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90918 Tested-by: build bot (Jenkins) Reviewed-by: Jakub "Kuba" Czapiga --- src/soc/intel/alderlake/chipset.cb | 2 +- src/soc/intel/alderlake/chipset_pch_s.cb | 2 +- src/soc/intel/apollolake/chipset_apl.cb | 2 +- src/soc/intel/apollolake/chipset_glk.cb | 2 +- src/soc/intel/cannonlake/chipset.cb | 2 +- src/soc/intel/cannonlake/chipset_pch_h.cb | 2 +- src/soc/intel/common/block/smbus/smbus.c | 21 --------------------- src/soc/intel/jasperlake/chipset.cb | 2 +- src/soc/intel/meteorlake/chipset.cb | 2 +- src/soc/intel/pantherlake/chipset_ptl.cb | 2 +- src/soc/intel/pantherlake/chipset_wcl.cb | 2 +- src/soc/intel/tigerlake/chipset.cb | 2 +- src/soc/intel/tigerlake/chipset_pch_h.cb | 2 +- 13 files changed, 12 insertions(+), 33 deletions(-) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index 36685783a2..c8b4b4283e 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -268,7 +268,7 @@ chip soc/intel/alderlake device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias south_tracehub off end diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index a7f2b64399..fc575bc583 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -413,7 +413,7 @@ chip soc/intel/alderlake device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias south_tracehub off end diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index 2766ef8d16..8ec70cc8a1 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -44,6 +44,6 @@ chip soc/intel/apollolake device pci 1c.0 alias emmc off end # eMMC device pci 1e.0 alias sdio off end # SDIO device pci 1f.0 alias lpc_espi on end # LPC - device pci 1f.1 alias smbus off end # SMBUS + device pci 1f.1 alias smbus off ops smbus_ops end # SMBUS end end diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index 3255407abb..688197a49b 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -45,6 +45,6 @@ chip soc/intel/apollolake device pci 1d.0 alias ufs off end # UFS device pci 1e.0 alias sdio off end # SDIO device pci 1f.0 alias lpc_espi on end # LPC - device pci 1f.1 alias smbus on end # SMBUS + device pci 1f.1 alias smbus on ops smbus_ops end # SMBUS end end diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index 2fd801051a..12a93eee3b 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -121,7 +121,7 @@ chip soc/intel/cannonlake device pci 1f.1 alias p2sb hidden end # P2SB device pci 1f.2 alias pmc hidden end # Power Management Controller device pci 1f.3 alias hda off end # Intel HDA - device pci 1f.4 alias smbus off end # SMBus + device pci 1f.4 alias smbus off ops smbus_ops end # SMBus device pci 1f.5 alias fast_spi on end # PCH SPI device pci 1f.6 alias gbe off end # GbE device pci 1f.7 alias tracehub off end # TraceHub diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index b00e556a2e..17944a472f 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -155,7 +155,7 @@ chip soc/intel/cannonlake device pci 1f.1 alias p2sb hidden end # P2SB device pci 1f.2 alias pmc hidden end # Power Management Controller device pci 1f.3 alias hda off end # Intel HDA - device pci 1f.4 alias smbus off end # SMBus + device pci 1f.4 alias smbus off ops smbus_ops end # SMBus device pci 1f.5 alias fast_spi on end # PCH SPI device pci 1f.6 alias gbe off end # GbE device pci 1f.7 alias tracehub off end # TraceHub diff --git a/src/soc/intel/common/block/smbus/smbus.c b/src/soc/intel/common/block/smbus/smbus.c index ebaf655499..573aea5b8e 100644 --- a/src/soc/intel/common/block/smbus/smbus.c +++ b/src/soc/intel/common/block/smbus/smbus.c @@ -49,32 +49,11 @@ struct device_operations smbus_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_WCL_SMBUS, - PCI_DID_INTEL_PTL_H_SMBUS, - PCI_DID_INTEL_PTL_U_H_SMBUS, PCI_DID_INTEL_LNL_SMBUS, - PCI_DID_INTEL_MTL_SMBUS, - PCI_DID_INTEL_ARL_SMBUS, - PCI_DID_INTEL_ARL_S_SMBUS, - PCI_DID_INTEL_ARP_S_SMBUS, - PCI_DID_INTEL_RPP_P_SMBUS, - PCI_DID_INTEL_RPP_S_SMBUS, - PCI_DID_INTEL_APL_SMBUS, - PCI_DID_INTEL_GLK_SMBUS, - PCI_DID_INTEL_CNL_SMBUS, - PCI_DID_INTEL_CNP_H_SMBUS, PCI_DID_INTEL_EBG_SMBUS, PCI_DID_INTEL_LWB_SMBUS_SUPER, PCI_DID_INTEL_LWB_SMBUS, - PCI_DID_INTEL_CMP_SMBUS, - PCI_DID_INTEL_CMP_H_SMBUS, - PCI_DID_INTEL_TGP_LP_SMBUS, - PCI_DID_INTEL_TGP_H_SMBUS, PCI_DID_INTEL_MCC_SMBUS, - PCI_DID_INTEL_JSP_SMBUS, - PCI_DID_INTEL_ADP_P_SMBUS, - PCI_DID_INTEL_ADP_S_SMBUS, - PCI_DID_INTEL_ADP_M_N_SMBUS, PCI_DID_INTEL_DNV_SMBUS_LEGACY, 0 }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index 6d50296019..83dda97454 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -93,7 +93,7 @@ chip soc/intel/jasperlake device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.7 alias south_tracehub off end end diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index 1efa776ec0..d1ca7e0781 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -187,7 +187,7 @@ chip soc/intel/meteorlake device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias npk off end diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index 99962c56b0..5de54b59f5 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -245,7 +245,7 @@ chip soc/intel/pantherlake device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias npk off end diff --git a/src/soc/intel/pantherlake/chipset_wcl.cb b/src/soc/intel/pantherlake/chipset_wcl.cb index cdd57f5a88..fbe7420005 100644 --- a/src/soc/intel/pantherlake/chipset_wcl.cb +++ b/src/soc/intel/pantherlake/chipset_wcl.cb @@ -128,7 +128,7 @@ chip soc/intel/pantherlake device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias npk off end diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index abecd82f61..67fe7fbeb5 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -149,7 +149,7 @@ chip soc/intel/tigerlake device pci 1f.1 alias p2sb off end device pci 1f.2 alias pmc hidden end device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias tracehub off end diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index d0a3df588e..9271488015 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -183,7 +183,7 @@ chip soc/intel/tigerlake device pci 1f.1 alias p2sb off end device pci 1f.2 alias pmc hidden end device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias thermal off end From f2d9c137e6c65d8e0a4eb52f9b535355e47430d5 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 20:49:26 -0600 Subject: [PATCH 312/789] soc/intel: Use chipset.cb for HDA device ops linking Move HDA device operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them, matching the approach used by Skylake. Remove corresponding DIDs from hda.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. Add 'Select SOC_INTEL_COMMON_BLOCK_HDA` to Apollolake/Geminilake so those platforms can make use of the common driver. Since no APL/GLK boards currently select `SOC_INTEL_COMMON_BLOCK_HDA_VERB` the addition is a no-op. This standardizes the approach across Intel SoCs and makes the HDA controller configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common HDA driver code. Change-Id: I0b3af4c2a441d4897341ee6c2cc5d75d70a6ebc4 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90919 Reviewed-by: Jakub "Kuba" Czapiga Tested-by: build bot (Jenkins) --- src/soc/intel/alderlake/chipset.cb | 2 +- src/soc/intel/alderlake/chipset_pch_s.cb | 2 +- src/soc/intel/apollolake/Kconfig | 1 + src/soc/intel/apollolake/chipset_apl.cb | 2 +- src/soc/intel/apollolake/chipset_glk.cb | 2 +- src/soc/intel/cannonlake/chipset.cb | 2 +- src/soc/intel/cannonlake/chipset_pch_h.cb | 2 +- src/soc/intel/common/block/hda/hda.c | 68 ----------------------- src/soc/intel/jasperlake/chipset.cb | 2 +- src/soc/intel/meteorlake/chipset.cb | 2 +- src/soc/intel/pantherlake/chipset_ptl.cb | 2 +- src/soc/intel/pantherlake/chipset_wcl.cb | 2 +- src/soc/intel/tigerlake/chipset.cb | 2 +- src/soc/intel/tigerlake/chipset_pch_h.cb | 2 +- 14 files changed, 13 insertions(+), 80 deletions(-) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index c8b4b4283e..b942157c4d 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -267,7 +267,7 @@ chip soc/intel/alderlake device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end + device pci 1f.3 alias hda off ops hda_ops end device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index fc575bc583..36ca14755d 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -412,7 +412,7 @@ chip soc/intel/alderlake device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end + device pci 1f.3 alias hda off ops hda_ops end device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index be87a8c10d..18e8466cff 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -61,6 +61,7 @@ config SOC_INTEL_APOLLOLAKE select SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT select SOC_INTEL_COMMON_BLOCK_GPIO_MULTI_ACPI_DEVICES select SOC_INTEL_COMMON_BLOCK_GPIO_IOSTANDBY + select SOC_INTEL_COMMON_BLOCK_HDA select SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PCR select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_BLOCK_PMC_DISCOVERABLE diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index 8ec70cc8a1..5784265855 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -10,7 +10,7 @@ chip soc/intel/apollolake device pci 0d.1 alias pmc off end # PMC device pci 0d.2 alias fast_spi off end # SPI device pci 0d.3 alias sram off end # Shared SRAM - device pci 0e.0 alias hda off end # HDA + device pci 0e.0 alias hda off ops hda_ops end # HDA device pci 0f.0 alias heci1 off end # HECI1 device pci 0f.1 alias heci2 off end # HECI2 device pci 0f.2 alias heci3 off end # HECI3 diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index 688197a49b..2a4defe7c7 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -11,7 +11,7 @@ chip soc/intel/apollolake device pci 0d.1 alias pmc off end # PMC device pci 0d.2 alias fast_spi off end # SPI device pci 0d.3 alias sram off end # Shared SRAM - device pci 0e.0 alias hda off end # HDA + device pci 0e.0 alias hda off ops hda_ops end # HDA device pci 0f.0 alias heci1 off end # HECI1 device pci 0f.1 alias heci2 off end # HECI2 device pci 0f.2 alias heci3 off end # HECI3 diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index 12a93eee3b..e0f20ae8a8 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -120,7 +120,7 @@ chip soc/intel/cannonlake device pci 1f.0 alias lpc_espi on end # LPC Interface device pci 1f.1 alias p2sb hidden end # P2SB device pci 1f.2 alias pmc hidden end # Power Management Controller - device pci 1f.3 alias hda off end # Intel HDA + device pci 1f.3 alias hda off ops hda_ops end # Intel HDA device pci 1f.4 alias smbus off ops smbus_ops end # SMBus device pci 1f.5 alias fast_spi on end # PCH SPI device pci 1f.6 alias gbe off end # GbE diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index 17944a472f..240054d3bf 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -154,7 +154,7 @@ chip soc/intel/cannonlake device pci 1f.0 alias lpc_espi on end # LPC Interface device pci 1f.1 alias p2sb hidden end # P2SB device pci 1f.2 alias pmc hidden end # Power Management Controller - device pci 1f.3 alias hda off end # Intel HDA + device pci 1f.3 alias hda off ops hda_ops end # Intel HDA device pci 1f.4 alias smbus off ops smbus_ops end # SMBus device pci 1f.5 alias fast_spi on end # PCH SPI device pci 1f.6 alias gbe off end # GbE diff --git a/src/soc/intel/common/block/hda/hda.c b/src/soc/intel/common/block/hda/hda.c index e779dee312..66ad97dd12 100644 --- a/src/soc/intel/common/block/hda/hda.c +++ b/src/soc/intel/common/block/hda/hda.c @@ -38,30 +38,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_NVL_AUDIO_6, PCI_DID_INTEL_NVL_AUDIO_7, PCI_DID_INTEL_NVL_AUDIO_8, - PCI_DID_INTEL_WCL_AUDIO_1, - PCI_DID_INTEL_WCL_AUDIO_2, - PCI_DID_INTEL_WCL_AUDIO_3, - PCI_DID_INTEL_WCL_AUDIO_4, - PCI_DID_INTEL_WCL_AUDIO_5, - PCI_DID_INTEL_WCL_AUDIO_6, - PCI_DID_INTEL_WCL_AUDIO_7, - PCI_DID_INTEL_WCL_AUDIO_8, - PCI_DID_INTEL_PTL_H_AUDIO_1, - PCI_DID_INTEL_PTL_H_AUDIO_2, - PCI_DID_INTEL_PTL_H_AUDIO_3, - PCI_DID_INTEL_PTL_H_AUDIO_4, - PCI_DID_INTEL_PTL_H_AUDIO_5, - PCI_DID_INTEL_PTL_H_AUDIO_6, - PCI_DID_INTEL_PTL_H_AUDIO_7, - PCI_DID_INTEL_PTL_H_AUDIO_8, - PCI_DID_INTEL_PTL_U_H_AUDIO_1, - PCI_DID_INTEL_PTL_U_H_AUDIO_2, - PCI_DID_INTEL_PTL_U_H_AUDIO_3, - PCI_DID_INTEL_PTL_U_H_AUDIO_4, - PCI_DID_INTEL_PTL_U_H_AUDIO_5, - PCI_DID_INTEL_PTL_U_H_AUDIO_6, - PCI_DID_INTEL_PTL_U_H_AUDIO_7, - PCI_DID_INTEL_PTL_U_H_AUDIO_8, PCI_DID_INTEL_LNL_AUDIO_1, PCI_DID_INTEL_LNL_AUDIO_2, PCI_DID_INTEL_LNL_AUDIO_3, @@ -70,54 +46,10 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_LNL_AUDIO_6, PCI_DID_INTEL_LNL_AUDIO_7, PCI_DID_INTEL_LNL_AUDIO_8, - PCI_DID_INTEL_MTL_AUDIO_1, - PCI_DID_INTEL_MTL_AUDIO_2, - PCI_DID_INTEL_MTL_AUDIO_3, - PCI_DID_INTEL_MTL_AUDIO_4, - PCI_DID_INTEL_MTL_AUDIO_5, - PCI_DID_INTEL_MTL_AUDIO_6, - PCI_DID_INTEL_MTL_AUDIO_7, - PCI_DID_INTEL_MTL_AUDIO_8, - PCI_DID_INTEL_ARL_AUDIO, - PCI_DID_INTEL_ARP_S_AUDIO, - PCI_DID_INTEL_RPP_P_AUDIO, - PCI_DID_INTEL_RPP_S_AUDIO_1, - PCI_DID_INTEL_RPP_S_AUDIO_2, - PCI_DID_INTEL_RPP_S_AUDIO_3, - PCI_DID_INTEL_RPP_S_AUDIO_4, - PCI_DID_INTEL_RPP_S_AUDIO_5, - PCI_DID_INTEL_RPP_S_AUDIO_6, - PCI_DID_INTEL_RPP_S_AUDIO_7, - PCI_DID_INTEL_RPP_S_AUDIO_8, - PCI_DID_INTEL_APL_AUDIO, - PCI_DID_INTEL_GLK_AUDIO, PCI_DID_INTEL_LWB_AUDIO, PCI_DID_INTEL_LWB_AUDIO_SUPER, - PCI_DID_INTEL_CNL_AUDIO, - PCI_DID_INTEL_CNP_H_AUDIO, - PCI_DID_INTEL_CMP_AUDIO, - PCI_DID_INTEL_CMP_H_AUDIO, PCI_DID_INTEL_BSW_AUDIO, - PCI_DID_INTEL_TGL_AUDIO, - PCI_DID_INTEL_TGL_H_AUDIO, PCI_DID_INTEL_MCC_AUDIO, - PCI_DID_INTEL_JSP_AUDIO, - PCI_DID_INTEL_ADP_P_AUDIO, - PCI_DID_INTEL_ADP_S_AUDIO_1, - PCI_DID_INTEL_ADP_S_AUDIO_2, - PCI_DID_INTEL_ADP_S_AUDIO_3, - PCI_DID_INTEL_ADP_S_AUDIO_4, - PCI_DID_INTEL_ADP_S_AUDIO_5, - PCI_DID_INTEL_ADP_S_AUDIO_6, - PCI_DID_INTEL_ADP_S_AUDIO_7, - PCI_DID_INTEL_ADP_S_AUDIO_8, - PCI_DID_INTEL_ADP_M_N_AUDIO_1, - PCI_DID_INTEL_ADP_M_N_AUDIO_2, - PCI_DID_INTEL_ADP_M_N_AUDIO_3, - PCI_DID_INTEL_ADP_M_N_AUDIO_4, - PCI_DID_INTEL_ADP_M_N_AUDIO_5, - PCI_DID_INTEL_ADP_M_N_AUDIO_6, - PCI_DID_INTEL_ADP_M_N_AUDIO_7, 0 }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index 83dda97454..ca18683d8b 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -92,7 +92,7 @@ chip soc/intel/jasperlake device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end + device pci 1f.3 alias hda off ops hda_ops end device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.7 alias south_tracehub off end diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index d1ca7e0781..a1b995c5c9 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -186,7 +186,7 @@ chip soc/intel/meteorlake device pci 1f.0 alias soc_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end + device pci 1f.3 alias hda off ops hda_ops end device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index 5de54b59f5..e2277d319c 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -244,7 +244,7 @@ chip soc/intel/pantherlake device pci 1f.0 alias soc_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end + device pci 1f.3 alias hda off ops hda_ops end device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end diff --git a/src/soc/intel/pantherlake/chipset_wcl.cb b/src/soc/intel/pantherlake/chipset_wcl.cb index fbe7420005..0cb6e6634e 100644 --- a/src/soc/intel/pantherlake/chipset_wcl.cb +++ b/src/soc/intel/pantherlake/chipset_wcl.cb @@ -127,7 +127,7 @@ chip soc/intel/pantherlake device pci 1f.0 alias soc_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end + device pci 1f.3 alias hda off ops hda_ops end device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index 67fe7fbeb5..40932489da 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -148,7 +148,7 @@ chip soc/intel/tigerlake device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb off end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end + device pci 1f.3 alias hda off ops hda_ops end device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index 9271488015..3761527edb 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -182,7 +182,7 @@ chip soc/intel/tigerlake device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb off end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end + device pci 1f.3 alias hda off ops hda_ops end device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end From b6e80702a1c32c370b2f946669fbba8abca34b9f Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 20:55:07 -0600 Subject: [PATCH 313/789] soc/intel: Use chipset.cb for XHCI device ops linking Move XHCI device operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them, matching the approach used by Skylake. Remove corresponding DIDs from xhci.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. This standardizes the approach across Intel SoCs and makes the XHCI controller configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common driver code. Change-Id: I4a0551a0fc5a233153c62d5bb7b0b2f3596a81ac Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90920 Tested-by: build bot (Jenkins) Reviewed-by: Jakub "Kuba" Czapiga --- src/soc/intel/alderlake/chipset.cb | 2 +- src/soc/intel/alderlake/chipset_pch_s.cb | 2 +- src/soc/intel/apollolake/chipset_apl.cb | 2 +- src/soc/intel/apollolake/chipset_glk.cb | 2 +- src/soc/intel/cannonlake/chipset.cb | 2 +- src/soc/intel/cannonlake/chipset_pch_h.cb | 2 +- src/soc/intel/common/block/xhci/xhci.c | 19 ------------------- src/soc/intel/jasperlake/chipset.cb | 2 +- src/soc/intel/meteorlake/chipset.cb | 2 +- src/soc/intel/pantherlake/chipset_ptl.cb | 2 +- src/soc/intel/pantherlake/chipset_wcl.cb | 2 +- src/soc/intel/tigerlake/chipset.cb | 2 +- src/soc/intel/tigerlake/chipset_pch_h.cb | 2 +- 13 files changed, 12 insertions(+), 31 deletions(-) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index b942157c4d..3d2ced5f00 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -180,7 +180,7 @@ chip soc/intel/alderlake device pci 12.6 alias gspi2 off ops spi_dev_ops end device pci 12.7 alias ufs off end device pci 13.0 alias gspi3 off ops spi_dev_ops end - device pci 14.0 alias xhci off + device pci 14.0 alias xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index 36ca14755d..6e4247817a 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -281,7 +281,7 @@ chip soc/intel/alderlake device pci 12.0 alias ish off end device pci 12.6 alias gspi2 off ops spi_dev_ops end device pci 13.0 alias gspi3 off ops spi_dev_ops end - device pci 14.0 alias xhci off + device pci 14.0 alias xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index 5784265855..5abba624bf 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -22,7 +22,7 @@ chip soc/intel/apollolake device pci 13.3 alias pcie_rp04 off ops pcie_rp_ops end # PCIE Express Root Port 4 device pci 14.0 alias pcie_rp05 off ops pcie_rp_ops end # PCIE Express Root Port 5 device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 - device pci 15.0 alias xhci off end # XHCI + device pci 15.0 alias xhci off ops usb_xhci_ops end # XHCI device pci 15.1 alias xdci off end # XDCI device pci 16.0 alias i2c0 off ops i2c_dev_ops end # I2C0 device pci 16.1 alias i2c1 off ops i2c_dev_ops end # I2C1 diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index 2a4defe7c7..9a8732dd94 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -23,7 +23,7 @@ chip soc/intel/apollolake device pci 13.3 alias pcie_rp04 off ops pcie_rp_ops end # PCIE Express Root Port 4 device pci 14.0 alias pcie_rp05 off ops pcie_rp_ops end # PCIE Express Root Port 5 device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 - device pci 15.0 alias xhci off end # XHCI + device pci 15.0 alias xhci off ops usb_xhci_ops end # XHCI device pci 15.1 alias xdci off end # XDCI device pci 16.0 alias i2c0 off ops i2c_dev_ops end # I2C0 device pci 16.1 alias i2c1 off ops i2c_dev_ops end # I2C1 diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index e0f20ae8a8..5b94869d87 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -17,7 +17,7 @@ chip soc/intel/cannonlake device pci 12.5 alias ufs off end # UFS SCS device pci 12.6 alias gspi2 off ops spi_dev_ops end # GSPI #2 device pci 13.0 alias ish off end # ISH - device pci 14.0 alias xhci off # USB xHCI + device pci 14.0 alias xhci off ops usb_xhci_ops # USB xHCI chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index 240054d3bf..9d96061bf1 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -17,7 +17,7 @@ chip soc/intel/cannonlake device pci 12.5 alias ufs off end # UFS SCS device pci 12.6 alias gspi2 off ops spi_dev_ops end # GSPI #2 device pci 13.0 alias ish off end # ISH - device pci 14.0 alias xhci off # USB xHCI + device pci 14.0 alias xhci off ops usb_xhci_ops # USB xHCI chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off diff --git a/src/soc/intel/common/block/xhci/xhci.c b/src/soc/intel/common/block/xhci/xhci.c index 5eb73ed562..a7b56e8d5c 100644 --- a/src/soc/intel/common/block/xhci/xhci.c +++ b/src/soc/intel/common/block/xhci/xhci.c @@ -132,29 +132,10 @@ struct device_operations usb_xhci_ops = { static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_NVL_XHCI, - PCI_DID_INTEL_WCL_XHCI, - PCI_DID_INTEL_PTL_H_XHCI, - PCI_DID_INTEL_PTL_U_H_XHCI, PCI_DID_INTEL_LNL_XHCI, - PCI_DID_INTEL_MTL_XHCI, - PCI_DID_INTEL_ARL_XHCI, - PCI_DID_INTEL_ARP_S_XHCI, - PCI_DID_INTEL_APL_XHCI, - PCI_DID_INTEL_CNL_LP_XHCI, - PCI_DID_INTEL_GLK_XHCI, PCI_DID_INTEL_LWB_XHCI, PCI_DID_INTEL_LWB_XHCI_SUPER, - PCI_DID_INTEL_CNP_H_XHCI, - PCI_DID_INTEL_CMP_LP_XHCI, - PCI_DID_INTEL_CMP_H_XHCI, - PCI_DID_INTEL_TGP_LP_XHCI, - PCI_DID_INTEL_TGP_H_XHCI, PCI_DID_INTEL_MCC_XHCI, - PCI_DID_INTEL_JSP_XHCI, - PCI_DID_INTEL_ADP_P_XHCI, - PCI_DID_INTEL_ADP_S_XHCI, - PCI_DID_INTEL_ADP_M_XHCI, - PCI_DID_INTEL_RPP_S_XHCI, PCI_DID_INTEL_SNR_XHCI, 0 }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index ca18683d8b..c6cc992ae6 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -12,7 +12,7 @@ chip soc/intel/jasperlake device pci 12.0 alias ish off end device pci 12.5 alias ufs_scs off end device pci 12.6 alias gspi2 off ops spi_dev_ops end - device pci 14.0 alias south_xhci off + device pci 14.0 alias south_xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index a1b995c5c9..df62835b56 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -100,7 +100,7 @@ chip soc/intel/meteorlake device pci 13.1 alias ieh2 off end device pci 13.2 alias pmc2 hidden end device pci 13.3 alias ioe_shared_sram off end - device pci 14.0 alias xhci off + device pci 14.0 alias xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index e2277d319c..82dc449d80 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -174,7 +174,7 @@ chip soc/intel/pantherlake device pci 13.0 alias heci_1 off end device pci 13.1 alias heci_2 off end device pci 13.2 alias heci_3 off end - device pci 14.0 alias xhci on + device pci 14.0 alias xhci on ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off diff --git a/src/soc/intel/pantherlake/chipset_wcl.cb b/src/soc/intel/pantherlake/chipset_wcl.cb index 0cb6e6634e..ccc5948d1f 100644 --- a/src/soc/intel/pantherlake/chipset_wcl.cb +++ b/src/soc/intel/pantherlake/chipset_wcl.cb @@ -60,7 +60,7 @@ chip soc/intel/pantherlake device pci 13.0 alias heci_1 off end device pci 13.1 alias heci_2 off end device pci 13.2 alias heci_3 off end - device pci 14.0 alias xhci on + device pci 14.0 alias xhci on ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index 40932489da..9594917ef8 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -63,7 +63,7 @@ chip soc/intel/tigerlake device pci 12.0 alias ish off end device pci 12.6 alias gspi2 off ops spi_dev_ops end device pci 13.0 alias gspi3 off ops spi_dev_ops end - device pci 14.0 alias south_xhci off + device pci 14.0 alias south_xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index 3761527edb..8b0355a443 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -67,7 +67,7 @@ chip soc/intel/tigerlake device pci 12.0 alias ish off end device pci 12.6 alias gspi2 off ops spi_dev_ops end device pci 13.0 alias gspi3 off ops spi_dev_ops end - device pci 14.0 alias south_xhci off + device pci 14.0 alias south_xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off From 32563645a9323ca3116443693a23fa25beb6474f Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 20:58:42 -0600 Subject: [PATCH 314/789] soc/intel: Use chipset.cb for XDCI device ops linking Move XDCI device operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them, matching the approach used by Skylake. Remove corresponding DIDs from xdci.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. This standardizes the approach across Intel SoCs and makes the XDCI controller configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common driver code. Change-Id: Ie8f8b5a952d072ecd1721bc8537734e85769b09d Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90921 Tested-by: build bot (Jenkins) Reviewed-by: Jakub "Kuba" Czapiga --- src/soc/intel/alderlake/chipset.cb | 2 +- src/soc/intel/alderlake/chipset_pch_s.cb | 2 +- src/soc/intel/apollolake/chipset_apl.cb | 2 +- src/soc/intel/apollolake/chipset_glk.cb | 2 +- src/soc/intel/cannonlake/chipset.cb | 2 +- src/soc/intel/cannonlake/chipset_pch_h.cb | 2 +- src/soc/intel/common/block/xdci/xdci.c | 19 ------------------- src/soc/intel/jasperlake/chipset.cb | 2 +- src/soc/intel/meteorlake/chipset.cb | 2 +- src/soc/intel/pantherlake/chipset_ptl.cb | 2 +- src/soc/intel/tigerlake/chipset.cb | 2 +- src/soc/intel/tigerlake/chipset_pch_h.cb | 2 +- 12 files changed, 11 insertions(+), 30 deletions(-) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index 3d2ced5f00..487b4ca961 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -168,7 +168,7 @@ chip soc/intel/alderlake end end end - device pci 0d.1 alias tcss_xdci off end + device pci 0d.1 alias tcss_xdci off ops usb_xdci_ops end device pci 0d.2 alias tcss_dma0 off end device pci 0d.3 alias tcss_dma1 off end device pci 0e.0 alias vmd off end diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index 6e4247817a..6d7be6f10d 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -360,7 +360,7 @@ chip soc/intel/alderlake end end end - device pci 14.1 alias xdci off end + device pci 14.1 alias xdci off ops usb_xdci_ops end device pci 14.2 alias shared_sram off end device pci 14.3 alias cnvi_wifi off end device pci 15.0 alias i2c0 off ops i2c_dev_ops end diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index 5abba624bf..f8bb1b0fd5 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -23,7 +23,7 @@ chip soc/intel/apollolake device pci 14.0 alias pcie_rp05 off ops pcie_rp_ops end # PCIE Express Root Port 5 device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 device pci 15.0 alias xhci off ops usb_xhci_ops end # XHCI - device pci 15.1 alias xdci off end # XDCI + device pci 15.1 alias xdci off ops usb_xdci_ops end # XDCI device pci 16.0 alias i2c0 off ops i2c_dev_ops end # I2C0 device pci 16.1 alias i2c1 off ops i2c_dev_ops end # I2C1 device pci 16.2 alias i2c2 off ops i2c_dev_ops end # I2C2 diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index 9a8732dd94..818954dd52 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -24,7 +24,7 @@ chip soc/intel/apollolake device pci 14.0 alias pcie_rp05 off ops pcie_rp_ops end # PCIE Express Root Port 5 device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 device pci 15.0 alias xhci off ops usb_xhci_ops end # XHCI - device pci 15.1 alias xdci off end # XDCI + device pci 15.1 alias xdci off ops usb_xdci_ops end # XDCI device pci 16.0 alias i2c0 off ops i2c_dev_ops end # I2C0 device pci 16.1 alias i2c1 off ops i2c_dev_ops end # I2C1 device pci 16.2 alias i2c2 off ops i2c_dev_ops end # I2C2 diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index 5b94869d87..a8d5d3133f 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -78,7 +78,7 @@ chip soc/intel/cannonlake end end end - device pci 14.1 alias xdci off end # USB xDCI (OTG) + device pci 14.1 alias xdci off ops usb_xdci_ops end # USB xDCI (OTG) device pci 14.2 alias shared_sram off end # Shared SRAM device pci 14.3 alias cnvi_wifi off end # CNVi Wifi device pci 14.5 alias sdxc off end # SDCard diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index 9d96061bf1..89411e7cbc 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -102,7 +102,7 @@ chip soc/intel/cannonlake end end end - device pci 14.1 alias xdci off end # USB xDCI (OTG) + device pci 14.1 alias xdci off ops usb_xdci_ops end # USB xDCI (OTG) device pci 14.2 alias shared_sram off end # Shared SRAM device pci 14.3 alias cnvi_wifi off end # CNVi Wifi device pci 14.5 alias sdxc off end # SDCard diff --git a/src/soc/intel/common/block/xdci/xdci.c b/src/soc/intel/common/block/xdci/xdci.c index 3ead495010..28f8231e7b 100644 --- a/src/soc/intel/common/block/xdci/xdci.c +++ b/src/soc/intel/common/block/xdci/xdci.c @@ -29,26 +29,7 @@ struct device_operations usb_xdci_ops = { static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_NVL_XDCI, - PCI_DID_INTEL_WCL_XDCI, - PCI_DID_INTEL_PTL_H_XDCI, - PCI_DID_INTEL_PTL_U_H_XDCI, - PCI_DID_INTEL_MTL_XDCI, - PCI_DID_INTEL_ARL_XDCI, - PCI_DID_INTEL_ARP_S_XDCI, - PCI_DID_INTEL_APL_XDCI, - PCI_DID_INTEL_CNL_LP_XDCI, - PCI_DID_INTEL_GLK_XDCI, - PCI_DID_INTEL_CNP_H_XDCI, - PCI_DID_INTEL_CMP_LP_XDCI, - PCI_DID_INTEL_CMP_H_XDCI, - PCI_DID_INTEL_TGP_LP_XDCI, - PCI_DID_INTEL_TGP_H_XDCI, PCI_DID_INTEL_MCC_XDCI, - PCI_DID_INTEL_JSP_XDCI, - PCI_DID_INTEL_ADP_P_XDCI, - PCI_DID_INTEL_ADP_S_XDCI, - PCI_DID_INTEL_ADP_M_XDCI, - PCI_DID_INTEL_RPP_S_XDCI, 0 }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index c6cc992ae6..4288b425fe 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -61,7 +61,7 @@ chip soc/intel/jasperlake end end end - device pci 14.1 alias south_xdci off end + device pci 14.1 alias south_xdci off ops usb_xdci_ops end device pci 14.2 alias shared_ram off end device pci 14.3 alias cnvi_wifi off end device pci 14.5 alias sdxc off end diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index df62835b56..ef023c1e23 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -87,7 +87,7 @@ chip soc/intel/meteorlake end end end - device pci 0d.1 alias tcss_xdci off end + device pci 0d.1 alias tcss_xdci off ops usb_xdci_ops end device pci 0d.2 alias tcss_dma0 off end device pci 0d.3 alias tcss_dma1 off end device pci 0e.0 alias vmd off end diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index 82dc449d80..debb0a2bae 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -162,7 +162,7 @@ chip soc/intel/pantherlake end end end - device pci 0d.1 alias tcss_xdci off end + device pci 0d.1 alias tcss_xdci off ops usb_xdci_ops end device pci 0d.2 alias tcss_dma0 off end device pci 0d.3 alias tcss_dma1 off end device pci 0e.0 alias vmd off end diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index 9594917ef8..9e33123c73 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -112,7 +112,7 @@ chip soc/intel/tigerlake end end end - device pci 14.1 alias south_xdci off end + device pci 14.1 alias south_xdci off ops usb_xdci_ops end device pci 14.2 alias shared_ram off end device pci 14.3 alias cnvi_wifi off end device pci 15.0 alias i2c0 off ops i2c_dev_ops end diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index 8b0355a443..fe98239693 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -134,7 +134,7 @@ chip soc/intel/tigerlake end end end - device pci 14.1 alias south_xdci off end + device pci 14.1 alias south_xdci off ops usb_xdci_ops end device pci 14.2 alias shared_ram off end device pci 14.3 alias cnvi_wifi off end device pci 15.0 alias i2c0 off ops i2c_dev_ops end From 0d947e59cbbd45c7bdad5c1978f391b309bcd4db Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 21:01:41 -0600 Subject: [PATCH 315/789] soc/intel: Use chipset.cb for CNVI WiFi device ops linking Move CNVI WiFi device operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them. Remove corresponding DIDs from cnvi.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. Remove the static declaration from cnvi_wifi_ops so the symbol is exported and visible outside of cnvi.c. This standardizes the approach across Intel SoCs and makes the CNVI WiFi controller configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common driver code. Change-Id: I82a2b20a8b967d1a3d5a80ae477def260c366be7 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90922 Reviewed-by: Jakub "Kuba" Czapiga Tested-by: build bot (Jenkins) --- src/soc/intel/alderlake/chipset.cb | 2 +- src/soc/intel/alderlake/chipset_pch_s.cb | 2 +- src/soc/intel/apollolake/chipset_glk.cb | 2 +- src/soc/intel/cannonlake/chipset.cb | 2 +- src/soc/intel/cannonlake/chipset_pch_h.cb | 2 +- src/soc/intel/common/block/cnvi/cnvi.c | 53 +---------------------- src/soc/intel/jasperlake/chipset.cb | 2 +- src/soc/intel/meteorlake/chipset.cb | 2 +- src/soc/intel/pantherlake/chipset_ptl.cb | 2 +- src/soc/intel/pantherlake/chipset_wcl.cb | 2 +- src/soc/intel/tigerlake/chipset.cb | 2 +- src/soc/intel/tigerlake/chipset_pch_h.cb | 2 +- 12 files changed, 12 insertions(+), 63 deletions(-) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index 487b4ca961..a18da51a89 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -231,7 +231,7 @@ chip soc/intel/alderlake end device pci 14.1 alias usb_otg off end device pci 14.2 alias shared_sram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 15.0 alias i2c0 off ops i2c_dev_ops end device pci 15.1 alias i2c1 off ops i2c_dev_ops end device pci 15.2 alias i2c2 off ops i2c_dev_ops end diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index 6d7be6f10d..962a46617b 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -362,7 +362,7 @@ chip soc/intel/alderlake end device pci 14.1 alias xdci off ops usb_xdci_ops end device pci 14.2 alias shared_sram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 15.0 alias i2c0 off ops i2c_dev_ops end device pci 15.1 alias i2c1 off ops i2c_dev_ops end device pci 15.2 alias i2c2 off ops i2c_dev_ops end diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index 818954dd52..ab5ca0cf36 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -6,7 +6,7 @@ chip soc/intel/apollolake device pci 00.2 alias npk off end # NorthPeak device pci 02.0 alias igd off end # Integrated Graphics Device device pci 03.0 alias gmm off end # GMM - device pci 0c.0 alias cnvi off end # CNVi + device pci 0c.0 alias cnvi off ops cnvi_wifi_ops end # CNVi device pci 0d.0 alias p2sb off end # P2SB device pci 0d.1 alias pmc off end # PMC device pci 0d.2 alias fast_spi off end # SPI diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index a8d5d3133f..fafb02bf50 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -80,7 +80,7 @@ chip soc/intel/cannonlake end device pci 14.1 alias xdci off ops usb_xdci_ops end # USB xDCI (OTG) device pci 14.2 alias shared_sram off end # Shared SRAM - device pci 14.3 alias cnvi_wifi off end # CNVi Wifi + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end # CNVi Wifi device pci 14.5 alias sdxc off end # SDCard device pci 15.0 alias i2c0 off ops i2c_dev_ops end # I2C #0 device pci 15.1 alias i2c1 off ops i2c_dev_ops end # I2C #1 diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index 89411e7cbc..2ce5269274 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -104,7 +104,7 @@ chip soc/intel/cannonlake end device pci 14.1 alias xdci off ops usb_xdci_ops end # USB xDCI (OTG) device pci 14.2 alias shared_sram off end # Shared SRAM - device pci 14.3 alias cnvi_wifi off end # CNVi Wifi + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end # CNVi Wifi device pci 14.5 alias sdxc off end # SDCard device pci 15.0 alias i2c0 off ops i2c_dev_ops end # I2C #0 device pci 15.1 alias i2c1 off ops i2c_dev_ops end # I2C #1 diff --git a/src/soc/intel/common/block/cnvi/cnvi.c b/src/soc/intel/common/block/cnvi/cnvi.c index 0511fd20c0..214bd0890e 100644 --- a/src/soc/intel/common/block/cnvi/cnvi.c +++ b/src/soc/intel/common/block/cnvi/cnvi.c @@ -462,7 +462,7 @@ static void cnvw_fill_ssdt(const struct device *dev) acpigen_write_scope_end(); } -static struct device_operations cnvi_wifi_ops = { +struct device_operations cnvi_wifi_ops = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, @@ -477,61 +477,10 @@ static const unsigned short wifi_pci_device_ids[] = { PCI_DID_INTEL_NVL_CNVI_WIFI_1, PCI_DID_INTEL_NVL_CNVI_WIFI_2, PCI_DID_INTEL_NVL_CNVI_WIFI_3, - PCI_DID_INTEL_WCL_CNVI_WIFI_0, - PCI_DID_INTEL_WCL_CNVI_WIFI_1, - PCI_DID_INTEL_WCL_CNVI_WIFI_2, - PCI_DID_INTEL_WCL_CNVI_WIFI_3, - PCI_DID_INTEL_PTL_H_CNVI_WIFI_0, - PCI_DID_INTEL_PTL_H_CNVI_WIFI_1, - PCI_DID_INTEL_PTL_H_CNVI_WIFI_2, - PCI_DID_INTEL_PTL_H_CNVI_WIFI_3, - PCI_DID_INTEL_PTL_U_H_CNVI_WIFI_0, - PCI_DID_INTEL_PTL_U_H_CNVI_WIFI_1, - PCI_DID_INTEL_PTL_U_H_CNVI_WIFI_2, - PCI_DID_INTEL_PTL_U_H_CNVI_WIFI_3, PCI_DID_INTEL_LNL_CNVI_WIFI_0, PCI_DID_INTEL_LNL_CNVI_WIFI_1, PCI_DID_INTEL_LNL_CNVI_WIFI_2, PCI_DID_INTEL_LNL_CNVI_WIFI_3, - PCI_DID_INTEL_MTL_CNVI_WIFI_0, - PCI_DID_INTEL_MTL_CNVI_WIFI_1, - PCI_DID_INTEL_MTL_CNVI_WIFI_2, - PCI_DID_INTEL_MTL_CNVI_WIFI_3, - PCI_DID_INTEL_ARL_CNVI_WIFI, - PCI_DID_INTEL_ARP_S_CNVI_WIFI, - PCI_DID_INTEL_CML_LP_CNVI_WIFI, - PCI_DID_INTEL_CML_H_CNVI_WIFI, - PCI_DID_INTEL_CNL_LP_CNVI_WIFI, - PCI_DID_INTEL_CNL_H_CNVI_WIFI, - PCI_DID_INTEL_GLK_CNVI_WIFI, - PCI_DID_INTEL_JSL_CNVI_WIFI_0, - PCI_DID_INTEL_JSL_CNVI_WIFI_1, - PCI_DID_INTEL_JSL_CNVI_WIFI_2, - PCI_DID_INTEL_JSL_CNVI_WIFI_3, - PCI_DID_INTEL_TGL_CNVI_WIFI_0, - PCI_DID_INTEL_TGL_CNVI_WIFI_1, - PCI_DID_INTEL_TGL_CNVI_WIFI_2, - PCI_DID_INTEL_TGL_CNVI_WIFI_3, - PCI_DID_INTEL_TGL_H_CNVI_WIFI_0, - PCI_DID_INTEL_TGL_H_CNVI_WIFI_1, - PCI_DID_INTEL_TGL_H_CNVI_WIFI_2, - PCI_DID_INTEL_TGL_H_CNVI_WIFI_3, - PCI_DID_INTEL_ADL_P_CNVI_WIFI_0, - PCI_DID_INTEL_ADL_P_CNVI_WIFI_1, - PCI_DID_INTEL_ADL_P_CNVI_WIFI_2, - PCI_DID_INTEL_ADL_P_CNVI_WIFI_3, - PCI_DID_INTEL_ADL_S_CNVI_WIFI_0, - PCI_DID_INTEL_ADL_S_CNVI_WIFI_1, - PCI_DID_INTEL_ADL_S_CNVI_WIFI_2, - PCI_DID_INTEL_ADL_S_CNVI_WIFI_3, - PCI_DID_INTEL_ADL_N_CNVI_WIFI_0, - PCI_DID_INTEL_ADL_N_CNVI_WIFI_1, - PCI_DID_INTEL_ADL_N_CNVI_WIFI_2, - PCI_DID_INTEL_ADL_N_CNVI_WIFI_3, - PCI_DID_INTEL_RPL_S_CNVI_WIFI_0, - PCI_DID_INTEL_RPL_S_CNVI_WIFI_1, - PCI_DID_INTEL_RPL_S_CNVI_WIFI_2, - PCI_DID_INTEL_RPL_S_CNVI_WIFI_3, 0 }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index 4288b425fe..278ba50050 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -63,7 +63,7 @@ chip soc/intel/jasperlake end device pci 14.1 alias south_xdci off ops usb_xdci_ops end device pci 14.2 alias shared_ram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 14.5 alias sdxc off end device pci 15.0 alias i2c0 off ops i2c_dev_ops end device pci 15.1 alias i2c1 off ops i2c_dev_ops end diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index ef023c1e23..3488a0f684 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -151,7 +151,7 @@ chip soc/intel/meteorlake end device pci 14.1 alias usb_otg off end device pci 14.2 alias pmc_shared_sram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 14.5 alias ieh off end device pci 15.0 alias i2c0 off ops i2c_dev_ops end device pci 15.1 alias i2c1 off ops i2c_dev_ops end diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index debb0a2bae..d2521efc78 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -212,7 +212,7 @@ chip soc/intel/pantherlake end end device pci 14.2 alias pmc_shared_sram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 14.7 alias cnvi_bluetooth off end device pci 14.5 alias ieh off end device pci 15.0 alias i2c0 off ops i2c_dev_ops end diff --git a/src/soc/intel/pantherlake/chipset_wcl.cb b/src/soc/intel/pantherlake/chipset_wcl.cb index ccc5948d1f..465ad05ad9 100644 --- a/src/soc/intel/pantherlake/chipset_wcl.cb +++ b/src/soc/intel/pantherlake/chipset_wcl.cb @@ -98,7 +98,7 @@ chip soc/intel/pantherlake end end device pci 14.2 alias pmc_shared_sram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 14.7 alias cnvi_bluetooth off end device pci 14.5 alias ieh off end device pci 15.0 alias i2c0 off ops i2c_dev_ops end diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index 9e33123c73..725f8296a3 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -114,7 +114,7 @@ chip soc/intel/tigerlake end device pci 14.1 alias south_xdci off ops usb_xdci_ops end device pci 14.2 alias shared_ram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 15.0 alias i2c0 off ops i2c_dev_ops end device pci 15.1 alias i2c1 off ops i2c_dev_ops end device pci 15.2 alias i2c2 off ops i2c_dev_ops end diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index fe98239693..28adb940e4 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -136,7 +136,7 @@ chip soc/intel/tigerlake end device pci 14.1 alias south_xdci off ops usb_xdci_ops end device pci 14.2 alias shared_ram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 15.0 alias i2c0 off ops i2c_dev_ops end device pci 15.1 alias i2c1 off ops i2c_dev_ops end device pci 15.2 alias i2c2 off ops i2c_dev_ops end From b4b4d6c730711880f29d3c0467d99c18ad7ccc8e Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 25 Jan 2026 21:07:41 -0600 Subject: [PATCH 316/789] soc/intel: Use chipset.cb for SDXC device ops linking Move SDXC device operations linking from PCI Device ID matching to chipset.cb files for all Intel SoCs that have them, matching the approach used by Skylake. Remove corresponding DIDs from sd.c for these SoCs; keep DID matching only for SoCs without chipset.cb files. This standardizes the approach across Intel SoCs and makes the SDXC controller configuration explicit in devicetree, and prevents the endless proliferation of DIDs in the common driver code. Change-Id: Ifee16988d0e5625a7b3c2be51ab70d2c8471747a Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90923 Tested-by: build bot (Jenkins) Reviewed-by: Jakub "Kuba" Czapiga --- src/soc/intel/apollolake/chipset_apl.cb | 2 +- src/soc/intel/cannonlake/chipset.cb | 2 +- src/soc/intel/cannonlake/chipset_pch_h.cb | 2 +- src/soc/intel/common/block/scs/sd.c | 6 ------ src/soc/intel/jasperlake/chipset.cb | 2 +- 5 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index f8bb1b0fd5..fc2ec2822d 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -40,7 +40,7 @@ chip soc/intel/apollolake device pci 19.1 alias spi1 off ops spi_dev_ops end # SPI1 device pci 19.2 alias spi2 off ops spi_dev_ops end # SPI3 device pci 1a.0 alias pwm off end # PWM - device pci 1b.0 alias sdcard off end # SD Card + device pci 1b.0 alias sdcard off ops sd_ops end # SD Card device pci 1c.0 alias emmc off end # eMMC device pci 1e.0 alias sdio off end # SDIO device pci 1f.0 alias lpc_espi on end # LPC diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index fafb02bf50..ff68963c3e 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -81,7 +81,7 @@ chip soc/intel/cannonlake device pci 14.1 alias xdci off ops usb_xdci_ops end # USB xDCI (OTG) device pci 14.2 alias shared_sram off end # Shared SRAM device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end # CNVi Wifi - device pci 14.5 alias sdxc off end # SDCard + device pci 14.5 alias sdxc off ops sd_ops end # SDCard device pci 15.0 alias i2c0 off ops i2c_dev_ops end # I2C #0 device pci 15.1 alias i2c1 off ops i2c_dev_ops end # I2C #1 device pci 15.2 alias i2c2 off ops i2c_dev_ops end # I2C #2 diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index 2ce5269274..de36773c50 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -105,7 +105,7 @@ chip soc/intel/cannonlake device pci 14.1 alias xdci off ops usb_xdci_ops end # USB xDCI (OTG) device pci 14.2 alias shared_sram off end # Shared SRAM device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end # CNVi Wifi - device pci 14.5 alias sdxc off end # SDCard + device pci 14.5 alias sdxc off ops sd_ops end # SDCard device pci 15.0 alias i2c0 off ops i2c_dev_ops end # I2C #0 device pci 15.1 alias i2c1 off ops i2c_dev_ops end # I2C #1 device pci 15.2 alias i2c2 off ops i2c_dev_ops end # I2C #2 diff --git a/src/soc/intel/common/block/scs/sd.c b/src/soc/intel/common/block/scs/sd.c index eee02009f1..84eac7ef75 100644 --- a/src/soc/intel/common/block/scs/sd.c +++ b/src/soc/intel/common/block/scs/sd.c @@ -49,14 +49,8 @@ struct device_operations sd_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_APL_SD, - PCI_DID_INTEL_CNL_SD, PCI_DID_INTEL_GLK_SD, - PCI_DID_INTEL_CNP_H_SD, - PCI_DID_INTEL_CMP_SD, - PCI_DID_INTEL_CMP_H_SD, PCI_DID_INTEL_MCC_SD, - PCI_DID_INTEL_JSP_SD, 0 }; diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb index 278ba50050..cbd5d2efc9 100644 --- a/src/soc/intel/jasperlake/chipset.cb +++ b/src/soc/intel/jasperlake/chipset.cb @@ -64,7 +64,7 @@ chip soc/intel/jasperlake device pci 14.1 alias south_xdci off ops usb_xdci_ops end device pci 14.2 alias shared_ram off end device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end - device pci 14.5 alias sdxc off end + device pci 14.5 alias sdxc off ops sd_ops end device pci 15.0 alias i2c0 off ops i2c_dev_ops end device pci 15.1 alias i2c1 off ops i2c_dev_ops end device pci 15.2 alias i2c2 off ops i2c_dev_ops end From 8a8b0df24dc911e9f73528f5a95aabc5fc4100b5 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 23 Jan 2026 11:34:47 -0600 Subject: [PATCH 317/789] soc/intel/pantherlake/fsp_params: Use common PCIe RP power management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Select SOC_INTEL_COMMON_BLOCK_ASPM and use the SoC common code for programming PCIe root port power management. This adds programming of PCIe RP clock PM and port speed, as well as allows for user override via setup options for all fields. Remove the now-unused static methods get_l1_substate_control() and get_aspm_control(). Additionally, check the port enable status before declaring the root port config struct, to be consistent with ADL and MTL. Change-Id: Ic30d714e609612ea46d34252c7c1d799652a9c2b Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90879 Reviewed-by: Paul Menzel Reviewed-by: Subrata Banik Reviewed-by: Sean Rhodes Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/Kconfig | 1 + src/soc/intel/pantherlake/fsp_params.c | 49 ++------------------------ 2 files changed, 4 insertions(+), 46 deletions(-) diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index bf02cde32f..59369a6a46 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -62,6 +62,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_BLOCK_ACPI_LPIT select SOC_INTEL_COMMON_BLOCK_ACPI_PEP select SOC_INTEL_COMMON_BLOCK_ACPI_PEP_LPM_REQ + select SOC_INTEL_COMMON_BLOCK_ASPM select SOC_INTEL_COMMON_BLOCK_CAR select SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG select SOC_INTEL_COMMON_BLOCK_CNVI diff --git a/src/soc/intel/pantherlake/fsp_params.c b/src/soc/intel/pantherlake/fsp_params.c index 2fbcbea5b9..d447879475 100644 --- a/src/soc/intel/pantherlake/fsp_params.c +++ b/src/soc/intel/pantherlake/fsp_params.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -59,47 +60,6 @@ static const pci_devfn_t gspi_dev[] = { PCI_DEVFN_GSPI2 }; -/* - * Chip config parameter PcieRpL1Substates uses (UPD value + 1) - * because UPD value of 0 for PcieRpL1Substates means disabled for FSP. - * In order to ensure that mainboard setting does not disable L1 substates - * incorrectly, chip config parameter values are offset by 1 with 0 meaning - * use FSP UPD default. get_l1_substate_control() ensures that the right UPD - * value is set in fsp_params. - * 0: Use FSP UPD default - * 1: Disable L1 substates - * 2: Use L1.1 - * 3: Use L1.2 (FSP UPD default) - */ -static int get_l1_substate_control(enum L1_substates_control ctl) -{ - if (CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE)) - ctl = L1_SS_DISABLED; - else if (ctl > L1_SS_L1_2 || ctl == L1_SS_FSP_DEFAULT) - ctl = L1_SS_L1_2; - return ctl - 1; -} - -/* - * Chip config parameter pcie_rp_aspm uses (UPD value + 1) because - * a UPD value of 0 for pcie_rp_aspm means disabled. In order to ensure - * that the mainboard setting does not disable ASPM incorrectly, chip - * config parameter values are offset by 1 with 0 meaning use FSP UPD default. - * get_aspm_control() ensures that the right UPD value is set in fsp_params. - * 0: Use FSP UPD default - * 1: Disable ASPM - * 2: L0s only - * 3: L1 only - * 4: L0s and L1 - * 5: Auto configuration - */ -static unsigned int get_aspm_control(enum ASPM_control ctl) -{ - if (ctl > ASPM_AUTO || ctl == ASPM_DEFAULT) - ctl = ASPM_AUTO; - return ctl - 1; -} - __weak void mainboard_update_soc_chip_config(struct soc_intel_pantherlake_config *config) { /* Override settings per board. */ @@ -629,19 +589,16 @@ static void fill_fsps_pcie_params(FSP_S_CONFIG *s_cfg, uint32_t enable_mask = pcie_rp_enable_mask(get_pcie_rp_table()); for (size_t i = 0; i < CONFIG_MAX_ROOT_PORTS; i++) { - const struct pcie_rp_config *rp_cfg = &config->pcie_rp[i]; if (!(enable_mask & BIT(i))) continue; - s_cfg->PcieRpL1Substates[i] = - get_l1_substate_control(rp_cfg->PcieRpL1Substates); + const struct pcie_rp_config *rp_cfg = &config->pcie_rp[i]; s_cfg->PcieRpLtrEnable[i] = !!(rp_cfg->flags & PCIE_RP_LTR); s_cfg->PcieRpAdvancedErrorReporting[i] = !!(rp_cfg->flags & PCIE_RP_AER); s_cfg->PcieRpHotPlug[i] = !!(rp_cfg->flags & PCIE_RP_HOTPLUG) || CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); s_cfg->PcieRpClkReqDetect[i] = !!(rp_cfg->flags & PCIE_RP_CLK_REQ_DETECT); s_cfg->PcieRpDetectTimeoutMs[i] = rp_cfg->pcie_rp_detect_timeout_ms; - if (rp_cfg->pcie_rp_aspm) - s_cfg->PcieRpAspm[i] = get_aspm_control(rp_cfg->pcie_rp_aspm); + configure_pch_rp_power_management(s_cfg, rp_cfg, i); } s_cfg->PcieComplianceTestMode = CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); From 317d2e43e587ce908ab01ccb717501af9e3a48f3 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 26 Jan 2026 11:32:53 -0600 Subject: [PATCH 318/789] soc/intel/apollolake: Add USB port aliases to chipset.cb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add USB port aliases to chipset_glk.cb and chipset_apl.cb to enable boards to use device ref syntax for USB devices. Port counts match hardware specs: GLK has 9 USB2/7 USB3 ports, APL has 8 USB2/7 USB3 ports. Select 'DRIVERS_USB_ACPI' so that the required USB ACPI drivers are built and linked for all boards. Change-Id: Ibc7dd2cbfda8c8eb42b243ea7adcdb6d1fdea98b Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90924 Tested-by: build bot (Jenkins) Reviewed-by: Jérémy Compostella Reviewed-by: Eric Lai --- src/soc/intel/apollolake/Kconfig | 1 + src/soc/intel/apollolake/chipset_apl.cb | 53 ++++++++++++++++++++++- src/soc/intel/apollolake/chipset_glk.cb | 56 ++++++++++++++++++++++++- 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index 18e8466cff..2f0ea9953d 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -20,6 +20,7 @@ config SOC_INTEL_APOLLOLAKE select SOC_INTEL_COMMON_NHLT # Misc options select CACHE_MRC_SETTINGS + select DRIVERS_USB_ACPI select EDK2_CPU_TIMER_LIB if PAYLOAD_EDK2 select FAST_SPI_GENERATE_SSDT select FSP_PLATFORM_MEMORY_SETTINGS_VERSIONS diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index fc2ec2822d..547cbee2f8 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -22,7 +22,58 @@ chip soc/intel/apollolake device pci 13.3 alias pcie_rp04 off ops pcie_rp_ops end # PCIE Express Root Port 4 device pci 14.0 alias pcie_rp05 off ops pcie_rp_ops end # PCIE Express Root Port 5 device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 - device pci 15.0 alias xhci off ops usb_xhci_ops end # XHCI + device pci 15.0 alias xhci off ops usb_xhci_ops + chip drivers/usb/acpi + register "type" = "UPC_TYPE_HUB" + device usb 0.0 alias xhci_root_hub off + chip drivers/usb/acpi + device usb 2.0 alias usb2_port1 off end + end + chip drivers/usb/acpi + device usb 2.1 alias usb2_port2 off end + end + chip drivers/usb/acpi + device usb 2.2 alias usb2_port3 off end + end + chip drivers/usb/acpi + device usb 2.3 alias usb2_port4 off end + end + chip drivers/usb/acpi + device usb 2.4 alias usb2_port5 off end + end + chip drivers/usb/acpi + device usb 2.5 alias usb2_port6 off end + end + chip drivers/usb/acpi + device usb 2.6 alias usb2_port7 off end + end + chip drivers/usb/acpi + device usb 2.7 alias usb2_port8 off end + end + chip drivers/usb/acpi + device usb 3.0 alias usb3_port1 off end + end + chip drivers/usb/acpi + device usb 3.1 alias usb3_port2 off end + end + chip drivers/usb/acpi + device usb 3.2 alias usb3_port3 off end + end + chip drivers/usb/acpi + device usb 3.3 alias usb3_port4 off end + end + chip drivers/usb/acpi + device usb 3.4 alias usb3_port5 off end + end + chip drivers/usb/acpi + device usb 3.5 alias usb3_port6 off end + end + chip drivers/usb/acpi + device usb 3.6 alias usb3_port7 off end + end + end + end + end # XHCI device pci 15.1 alias xdci off ops usb_xdci_ops end # XDCI device pci 16.0 alias i2c0 off ops i2c_dev_ops end # I2C0 device pci 16.1 alias i2c1 off ops i2c_dev_ops end # I2C1 diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index ab5ca0cf36..dbbab3dab3 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -23,7 +23,61 @@ chip soc/intel/apollolake device pci 13.3 alias pcie_rp04 off ops pcie_rp_ops end # PCIE Express Root Port 4 device pci 14.0 alias pcie_rp05 off ops pcie_rp_ops end # PCIE Express Root Port 5 device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 - device pci 15.0 alias xhci off ops usb_xhci_ops end # XHCI + device pci 15.0 alias xhci off ops usb_xhci_ops + chip drivers/usb/acpi + register "type" = "UPC_TYPE_HUB" + device usb 0.0 alias xhci_root_hub off + chip drivers/usb/acpi + device usb 2.0 alias usb2_port1 off end + end + chip drivers/usb/acpi + device usb 2.1 alias usb2_port2 off end + end + chip drivers/usb/acpi + device usb 2.2 alias usb2_port3 off end + end + chip drivers/usb/acpi + device usb 2.3 alias usb2_port4 off end + end + chip drivers/usb/acpi + device usb 2.4 alias usb2_port5 off end + end + chip drivers/usb/acpi + device usb 2.5 alias usb2_port6 off end + end + chip drivers/usb/acpi + device usb 2.6 alias usb2_port7 off end + end + chip drivers/usb/acpi + device usb 2.7 alias usb2_port8 off end + end + chip drivers/usb/acpi + device usb 2.8 alias usb2_port9 off end + end + chip drivers/usb/acpi + device usb 3.0 alias usb3_port1 off end + end + chip drivers/usb/acpi + device usb 3.1 alias usb3_port2 off end + end + chip drivers/usb/acpi + device usb 3.2 alias usb3_port3 off end + end + chip drivers/usb/acpi + device usb 3.3 alias usb3_port4 off end + end + chip drivers/usb/acpi + device usb 3.4 alias usb3_port5 off end + end + chip drivers/usb/acpi + device usb 3.5 alias usb3_port6 off end + end + chip drivers/usb/acpi + device usb 3.6 alias usb3_port7 off end + end + end + end + end # XHCI device pci 15.1 alias xdci off ops usb_xdci_ops end # XDCI device pci 16.0 alias i2c0 off ops i2c_dev_ops end # I2C0 device pci 16.1 alias i2c1 off ops i2c_dev_ops end # I2C1 From 94d1bb7ff918fa3790eda13beeac4e5810cf4c78 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 26 Jan 2026 12:34:32 -0600 Subject: [PATCH 319/789] mb/google/octopus: Drop selection of DRIVERS_USB_ACPI It's selected at the SoC level now, so no need for the mainboard to select it as well. TEST=build octopus Change-Id: Id8bf73de73fd9c93e875c52b339b63970c32d50a Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90926 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- src/mainboard/google/octopus/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mainboard/google/octopus/Kconfig b/src/mainboard/google/octopus/Kconfig index 1ba172e687..8723820f14 100644 --- a/src/mainboard/google/octopus/Kconfig +++ b/src/mainboard/google/octopus/Kconfig @@ -12,7 +12,6 @@ config BOARD_GOOGLE_BASEBOARD_OCTOPUS select DRIVERS_I2C_SX9310 select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select DRIVERS_SPI_ACPI - select DRIVERS_USB_ACPI select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_BOARDID select EC_GOOGLE_CHROMEEC_ESPI From 8cf6088ba563b62d4539660ddb019be71a77fa78 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 26 Jan 2026 11:47:28 -0600 Subject: [PATCH 320/789] mb/google/octopus: Use aliases in device/overridetrees Convert all PCI device and USB port references in octopus baseboard devicetree and variant overridetrees to use aliases from the Geminilake chipset.cb instead of direct device/function numbers. This improves maintainability by using symbolic names, and reduces file size by eliminating entries which match those in the chipset or baseboard devicetrees. TEST=Build all octopus variants Change-Id: Ic4f93608234b52d548d8e5f94b137754e8924484 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90925 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes --- .../octopus/variants/ampton/overridetree.cb | 16 +-- .../octopus/variants/baseboard/devicetree.cb | 112 +++++++----------- .../octopus/variants/bloog/overridetree.cb | 14 +-- .../octopus/variants/bobba/overridetree.cb | 20 ++-- .../octopus/variants/casta/overridetree.cb | 22 ++-- .../octopus/variants/dood/overridetree.cb | 14 +-- .../octopus/variants/fleex/overridetree.cb | 18 +-- .../octopus/variants/foob/overridetree.cb | 16 +-- .../octopus/variants/garg/overridetree.cb | 16 +-- .../octopus/variants/lick/overridetree.cb | 8 +- .../octopus/variants/meep/overridetree.cb | 38 +++--- .../octopus/variants/phaser/overridetree.cb | 16 +-- .../octopus/variants/yorp/overridetree.cb | 16 +-- 13 files changed, 153 insertions(+), 173 deletions(-) diff --git a/src/mainboard/google/octopus/variants/ampton/overridetree.cb b/src/mainboard/google/octopus/variants/ampton/overridetree.cb index ee607aa6f0..2647d518e6 100644 --- a/src/mainboard/google/octopus/variants/ampton/overridetree.cb +++ b/src/mainboard/google/octopus/variants/ampton/overridetree.cb @@ -71,7 +71,7 @@ chip soc/intel/apollolake }, }" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -83,8 +83,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -98,8 +98,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -108,8 +108,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -135,6 +135,6 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end end diff --git a/src/mainboard/google/octopus/variants/baseboard/devicetree.cb b/src/mainboard/google/octopus/variants/baseboard/devicetree.cb index 671150d656..21c68bab82 100644 --- a/src/mainboard/google/octopus/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/octopus/variants/baseboard/devicetree.cb @@ -106,168 +106,148 @@ chip soc/intel/apollolake register "pnp_settings" = "PNP_PERF_POWER" device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen + device ref igd on register "gfx" = "GMA_DEFAULT_PANEL(0)" end - device pci 03.0 off end # - Gaussian Mixture Model (GMM) - device pci 0c.0 on + device ref cnvi on chip drivers/wifi/generic register "wake" = "GPE0A_CNVI_PME_STS" device generic 0 on end end - end # - CNVi - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - Fast SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on + end + device ref p2sb on end + device ref pmc on end + device ref fast_spi on end + device ref sram on end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98357A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_91)" register "sdmode_delay" = "5" device generic 0 on end end - end # - Audio - device pci 0f.0 on end # - Heci1 - device pci 0f.1 on end # - Heci2 - device pci 0f.2 on end # - Heci3 - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 on + end + device ref heci1 on end + device ref heci2 on end + device ref heci3 on end + device ref pcie_rp01 on chip drivers/wifi/generic register "wake" = "GPE0_DW3_11" device pci 00.0 on end end - end # - PCIe-A 0 Onboard M2 Slot(Wifi) - device pci 13.1 off end # - PCIe-A 1 - device pci 13.2 off end # - PCIe-A 2 - device pci 13.3 off end # - PCIe-A 3 - device pci 14.0 off end # - PCIe-B 0 - device pci 14.1 off end # - PCIe-B 1 - device pci 15.0 on + end + device ref xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPIO_109)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""SDCard"" register "type" = "UPC_TYPE_EXPRESSCARD" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""User Facing Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""World Facing Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.7 on end + device ref usb2_port8 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPIO_109)" - device usb 2.8 on end + device ref usb2_port9 on end end chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""SDCard"" register "type" = "UPC_TYPE_EXPRESSCARD" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on end # - I2C 0 - device pci 16.1 off end # - I2C 1 - device pci 16.2 off end # - I2C 2 - device pci 16.3 off end # - I2C 3 - device pci 17.0 on end # - I2C 4 - device pci 17.1 on end # - I2C 5 - device pci 17.2 on end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 off end # - UART 1 - device pci 18.2 on end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on + end + device ref i2c0 on end + device ref i2c4 on end + device ref i2c5 on end + device ref i2c6 on end + device ref uart0 on end + device ref uart2 on end + device ref spi0 on chip drivers/spi/acpi register "hid" = "ACPI_DT_NAMESPACE_HID" register "compat_string" = ""google,cr50"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_63_IRQ)" device spi 0 on end end - end # - GSPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 on end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1c.0 on end # - eMMC - device pci 1d.0 on end # - UFS - device pci 1e.0 off end # - SDIO - device pci 1f.0 on + end + device ref spi2 on end + device ref pwm on end + device ref emmc on end + device ref ufs on end + device ref lpc_espi on chip ec/google/chromeec device pnp 0c09.0 on end end - end # - ESPI - device pci 1f.1 on end # - SMBUS + end + device ref smbus on end end # FSP provides UPD interface to execute IPC command. PMIC has diff --git a/src/mainboard/google/octopus/variants/bloog/overridetree.cb b/src/mainboard/google/octopus/variants/bloog/overridetree.cb index 32e17cbb1a..5b3db19d90 100644 --- a/src/mainboard/google/octopus/variants/bloog/overridetree.cb +++ b/src/mainboard/google/octopus/variants/bloog/overridetree.cb @@ -81,8 +81,8 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 off end # - I2C 0 - device pci 17.1 on + device ref i2c0 off end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -113,8 +113,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -123,8 +123,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -164,7 +164,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/bobba/overridetree.cb b/src/mainboard/google/octopus/variants/bobba/overridetree.cb index a79d15e2f1..d466695eb3 100644 --- a/src/mainboard/google/octopus/variants/bobba/overridetree.cb +++ b/src/mainboard/google/octopus/variants/bobba/overridetree.cb @@ -92,7 +92,7 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -116,8 +116,8 @@ chip soc/intel/apollolake register "key.wakeup_event_action" = "EV_ACT_DEASSERTED" device generic 0 on end end - end # - I2C 0 - device pci 16.1 on + end + device ref i2c1 on chip drivers/i2c/sx9310 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_214_IRQ)" @@ -132,8 +132,8 @@ chip soc/intel/apollolake register "proxraw_strength" = "0" device i2c 28 on end end - end # - I2C 1 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -164,8 +164,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -184,8 +184,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -223,7 +223,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/casta/overridetree.cb b/src/mainboard/google/octopus/variants/casta/overridetree.cb index 8d3fafd956..a6cac573a3 100644 --- a/src/mainboard/google/octopus/variants/casta/overridetree.cb +++ b/src/mainboard/google/octopus/variants/casta/overridetree.cb @@ -83,33 +83,33 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 15.0 on + device ref xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi - device usb 2.3 off end + device ref usb2_port4 off end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi - device usb 3.3 off end + device ref usb3_port4 off end end end end - end # - XHCI - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -127,8 +127,8 @@ chip soc/intel/apollolake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -146,7 +146,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0xE" device i2c 40 on end end - end # - I2C 6 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/dood/overridetree.cb b/src/mainboard/google/octopus/variants/dood/overridetree.cb index eb8490da76..8e04bd3060 100644 --- a/src/mainboard/google/octopus/variants/dood/overridetree.cb +++ b/src/mainboard/google/octopus/variants/dood/overridetree.cb @@ -80,8 +80,8 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 off end # - I2C 0 - device pci 17.1 on + device ref i2c0 off end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -99,8 +99,8 @@ chip soc/intel/apollolake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -119,8 +119,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -158,7 +158,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/fleex/overridetree.cb b/src/mainboard/google/octopus/variants/fleex/overridetree.cb index 3a17abba45..4583787f88 100644 --- a/src/mainboard/google/octopus/variants/fleex/overridetree.cb +++ b/src/mainboard/google/octopus/variants/fleex/overridetree.cb @@ -89,7 +89,7 @@ chip soc/intel/apollolake register "disable_xhci_lfps_pm" = "0" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -102,9 +102,9 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 0 - device pci 16.1 off end # - I2C 1 - device pci 17.1 on + end + device ref i2c1 off end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -151,8 +151,8 @@ chip soc/intel/apollolake register "hs_bias_sense_disable" = "true" device i2c 48 on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -170,8 +170,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -210,6 +210,6 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end end diff --git a/src/mainboard/google/octopus/variants/foob/overridetree.cb b/src/mainboard/google/octopus/variants/foob/overridetree.cb index 154345599c..b7d70935f2 100644 --- a/src/mainboard/google/octopus/variants/foob/overridetree.cb +++ b/src/mainboard/google/octopus/variants/foob/overridetree.cb @@ -83,7 +83,7 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -94,8 +94,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -113,8 +113,8 @@ chip soc/intel/apollolake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -133,8 +133,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/hid register "generic.hid" = ""ELAN90FC"" register "generic.desc" = ""ELAN Touchscreen"" @@ -159,7 +159,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 20 on end end - end # - I2C 7 + end end # Disable xHCI compliance mode diff --git a/src/mainboard/google/octopus/variants/garg/overridetree.cb b/src/mainboard/google/octopus/variants/garg/overridetree.cb index a653148d10..4084297fe6 100644 --- a/src/mainboard/google/octopus/variants/garg/overridetree.cb +++ b/src/mainboard/google/octopus/variants/garg/overridetree.cb @@ -86,7 +86,7 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -109,8 +109,8 @@ chip soc/intel/apollolake register "key.wakeup_event_action" = "EV_ACT_DEASSERTED" device generic 0 on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -141,8 +141,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -161,8 +161,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -200,7 +200,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/lick/overridetree.cb b/src/mainboard/google/octopus/variants/lick/overridetree.cb index a89a506dae..a534173a6b 100644 --- a/src/mainboard/google/octopus/variants/lick/overridetree.cb +++ b/src/mainboard/google/octopus/variants/lick/overridetree.cb @@ -73,7 +73,7 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 17.1 on + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -91,8 +91,8 @@ chip soc/intel/apollolake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -111,7 +111,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/meep/overridetree.cb b/src/mainboard/google/octopus/variants/meep/overridetree.cb index 9634cf13bb..11038d7e0a 100644 --- a/src/mainboard/google/octopus/variants/meep/overridetree.cb +++ b/src/mainboard/google/octopus/variants/meep/overridetree.cb @@ -83,63 +83,63 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 15.0 on + device ref xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.4 on end + device ref usb3_port5 on end end end end - end # - XHCI - device pci 16.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -162,8 +162,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0xa on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -194,8 +194,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -204,8 +204,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -244,7 +244,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/phaser/overridetree.cb b/src/mainboard/google/octopus/variants/phaser/overridetree.cb index 41b654c871..468ae4cb90 100644 --- a/src/mainboard/google/octopus/variants/phaser/overridetree.cb +++ b/src/mainboard/google/octopus/variants/phaser/overridetree.cb @@ -83,7 +83,7 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -95,8 +95,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -127,8 +127,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -147,8 +147,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -198,7 +198,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable xHCI compliance mode diff --git a/src/mainboard/google/octopus/variants/yorp/overridetree.cb b/src/mainboard/google/octopus/variants/yorp/overridetree.cb index 82a0ee4263..85db9f2aae 100644 --- a/src/mainboard/google/octopus/variants/yorp/overridetree.cb +++ b/src/mainboard/google/octopus/variants/yorp/overridetree.cb @@ -42,7 +42,7 @@ chip soc/intel/apollolake register "emmc_rx_strobe_cntl" = "0x0a0a" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -53,8 +53,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -72,8 +72,8 @@ chip soc/intel/apollolake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -82,8 +82,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -96,6 +96,6 @@ chip soc/intel/apollolake register "has_power_resource" = "true" device i2c 10 on end end - end # - I2C 7 + end end end From bbc3042bbfb49ca5f01fa7bd3ad591a45bf05c5e Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 26 Jan 2026 12:10:10 -0600 Subject: [PATCH 321/789] mb/google/reef: Use aliases in devicetrees Convert all PCI device and USB port references in the reef devicetrees to use aliases from the Apollolake chipset.cb instead of direct device/ function numbers. This improves maintainability by using symbolic names, and reduces file size by eliminating entries which match those in the chipset devicetree. TEST=Build all reef variants Change-Id: I08f96d2367fa8fc1ac7eb785c0d5cc08e293921b Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90927 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- .../reef/variants/baseboard/devicetree.cb | 78 ++++++++----------- .../google/reef/variants/coral/devicetree.cb | 78 ++++++++----------- .../google/reef/variants/pyro/devicetree.cb | 77 ++++++++---------- .../google/reef/variants/sand/devicetree.cb | 78 ++++++++----------- .../google/reef/variants/snappy/devicetree.cb | 78 ++++++++----------- 5 files changed, 155 insertions(+), 234 deletions(-) diff --git a/src/mainboard/google/reef/variants/baseboard/devicetree.cb b/src/mainboard/google/reef/variants/baseboard/devicetree.cb index 5eee33e790..6c3f3f5d1e 100644 --- a/src/mainboard/google/reef/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/reef/variants/baseboard/devicetree.cb @@ -118,18 +118,14 @@ chip soc/intel/apollolake register "slp_s3_assertion_width_usecs" = "28000" device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen + device ref igd on register "gfx" = "GMA_DEFAULT_PANEL(0)" end - device pci 03.0 off end # - Iunit - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on # - Audio + device ref p2sb on end + device ref pmc on end + device ref fast_spi on end + device ref sram on end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98357A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" @@ -137,23 +133,17 @@ chip soc/intel/apollolake device generic 0 on end end end - device pci 0f.0 on end # - CSE - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 off end # - Root Port 2 - PCIe-A 0 - device pci 13.1 off end # - Root Port 3 - PCIe-A 1 - device pci 13.2 off end # - Root Port 4 - PCIe-A 2 - device pci 13.3 off end # - Root Port 5 - PCIe-A 3 - device pci 14.0 on + device ref heci1 on end + device ref heci2 on end + device ref heci3 on end + device ref pcie_rp05 on chip drivers/wifi/generic register "wake" = "GPE0_DW3_00" device pci 00.0 on end end - end # - Root Port 0 - PCIe-B 0 - Wifi - device pci 14.1 off end # - Root Port 1 - PCIe-B 1 - device pci 15.0 on end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on # - I2C 0 + end + device ref xhci on end + device ref i2c0 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" register "btn_cfg" = "50" @@ -172,15 +162,15 @@ chip soc/intel/apollolake device i2c 1a on end end end - device pci 16.1 on end # - I2C 1 - device pci 16.2 on + device ref i2c1 on end + device ref i2c2 on chip drivers/i2c/tpm register "hid" = ""GOOG0005"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" device i2c 50 on end end - end # - I2C 2 - device pci 16.3 on + end + device ref i2c3 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -193,8 +183,8 @@ chip soc/intel/apollolake register "has_power_resource" = "true" device i2c 10 on end end - end # - I2C 3 - device pci 17.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -203,8 +193,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 4 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -212,25 +202,19 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 5 - device pci 17.2 off end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 on end # - UART 1 - device pci 18.2 on end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on end # - SPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 off end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1b.0 on end # - SDCARD - device pci 1c.0 on end # - eMMC - device pci 1e.0 off end # - SDIO - device pci 1f.0 on # - LPC + end + device ref uart0 on end + device ref uart1 on end + device ref uart2 on end + device ref spi0 on end + device ref pwm on end + device ref sdcard on end + device ref emmc on end + device ref lpc_espi on chip ec/google/chromeec device pnp 0c09.0 on end end end - device pci 1f.1 on end # - SMBUS + device ref smbus on end end end diff --git a/src/mainboard/google/reef/variants/coral/devicetree.cb b/src/mainboard/google/reef/variants/coral/devicetree.cb index ecfd522560..c7ddc9f33e 100644 --- a/src/mainboard/google/reef/variants/coral/devicetree.cb +++ b/src/mainboard/google/reef/variants/coral/devicetree.cb @@ -118,18 +118,14 @@ chip soc/intel/apollolake register "slp_s3_assertion_width_usecs" = "28000" device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen + device ref igd on register "gfx" = "GMA_DEFAULT_PANEL(0)" end - device pci 03.0 off end # - Iunit - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on # - Audio + device ref p2sb on end + device ref pmc on end + device ref fast_spi on end + device ref sram on end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98357A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" @@ -137,23 +133,17 @@ chip soc/intel/apollolake device generic 0 on end end end - device pci 0f.0 on end # - CSE - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 off end # - Root Port 2 - PCIe-A 0 - device pci 13.1 off end # - Root Port 3 - PCIe-A 1 - device pci 13.2 off end # - Root Port 4 - PCIe-A 2 - device pci 13.3 off end # - Root Port 5 - PCIe-A 3 - device pci 14.0 on + device ref heci1 on end + device ref heci2 on end + device ref heci3 on end + device ref pcie_rp05 on chip drivers/wifi/generic register "wake" = "GPE0_DW3_00" device pci 00.0 on end end - end # - Root Port 0 - PCIe-B 0 - Wifi - device pci 14.1 off end # - Root Port 1 - PCIe-B 1 - device pci 15.0 on end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on # - I2C 0 + end + device ref xhci on end + device ref i2c0 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" register "btn_cfg" = "50" @@ -172,15 +162,15 @@ chip soc/intel/apollolake device i2c 1a on end end end - device pci 16.1 on end # - I2C 1 - device pci 16.2 on + device ref i2c1 on end + device ref i2c2 on chip drivers/i2c/tpm register "hid" = ""GOOG0005"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" device i2c 50 on end end - end # - I2C 2 - device pci 16.3 on + end + device ref i2c3 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -205,8 +195,8 @@ chip soc/intel/apollolake register "has_power_resource" = "true" device i2c 39 on end end - end # - I2C 3 - device pci 17.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -225,8 +215,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 4 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -234,25 +224,19 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 5 - device pci 17.2 off end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 off end # - UART 1 - device pci 18.2 off end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on end # - SPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 off end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1b.0 on end # - SDCARD - device pci 1c.0 on end # - eMMC - device pci 1e.0 off end # - SDIO - device pci 1f.0 on # - LPC + end + device ref uart0 on end + device ref uart1 off end + device ref uart2 off end + device ref spi0 on end + device ref pwm on end + device ref sdcard on end + device ref emmc on end + device ref lpc_espi on chip ec/google/chromeec device pnp 0c09.0 on end end end - device pci 1f.1 on end # - SMBUS + device ref smbus on end end end diff --git a/src/mainboard/google/reef/variants/pyro/devicetree.cb b/src/mainboard/google/reef/variants/pyro/devicetree.cb index 5385aaaccf..479fc92802 100644 --- a/src/mainboard/google/reef/variants/pyro/devicetree.cb +++ b/src/mainboard/google/reef/variants/pyro/devicetree.cb @@ -127,18 +127,14 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen + device ref igd on register "gfx" = "GMA_DEFAULT_PANEL(0)" end - device pci 03.0 off end # - Iunit - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on # - Audio + device ref p2sb on end + device ref pmc on end + device ref fast_spi on end + device ref sram on end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98357A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" @@ -146,23 +142,17 @@ chip soc/intel/apollolake device generic 0 on end end end - device pci 0f.0 on end # - CSE - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 off end # - Root Port 2 - PCIe-A 0 - device pci 13.1 off end # - Root Port 3 - PCIe-A 1 - device pci 13.2 off end # - Root Port 4 - PCIe-A 2 - device pci 13.3 off end # - Root Port 5 - PCIe-A 3 - device pci 14.0 on + device ref heci1 on end + device ref heci2 on end + device ref heci3 on end + device ref pcie_rp05 on chip drivers/wifi/generic register "wake" = "GPE0_DW3_00" device pci 00.0 on end end - end # - Root Port 0 - PCIe-B 0 - Wifi - device pci 14.1 off end # - Root Port 1 - PCIe-B 1 - device pci 15.0 on end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on # - I2C 0 + end + device ref xhci on end + device ref i2c0 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" register "btn_cfg" = "50" @@ -181,15 +171,15 @@ chip soc/intel/apollolake device i2c 1a on end end end - device pci 16.1 on end # - I2C 1 - device pci 16.2 on + device ref i2c1 on end + device ref i2c2 on chip drivers/i2c/tpm register "hid" = ""GOOG0005"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" device i2c 50 on end end - end # - I2C 2 - device pci 16.3 on + end + device ref i2c3 on chip drivers/i2c/hid register "generic.hid" = ""WCOMNTN2"" register "generic.desc" = ""WCOM Touchscreen"" @@ -215,8 +205,8 @@ chip soc/intel/apollolake register "has_power_resource" = "true" device i2c 10 on end end - end # - I2C 3 - device pci 17.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -225,26 +215,21 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 4 - device pci 17.1 off end # - I2C 5 - device pci 17.2 off end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 on end # - UART 1 - device pci 18.2 on end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on end # - SPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 off end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1b.0 on end # - SDCARD - device pci 1c.0 on end # - eMMC - device pci 1e.0 off end # - SDIO - device pci 1f.0 on # - LPC + end + device ref i2c5 off end + device ref i2c6 off end + device ref uart0 on end + device ref uart1 on end + device ref uart2 on end + device ref spi0 on end + device ref pwm on end + device ref sdcard on end + device ref emmc on end + device ref lpc_espi on chip ec/google/chromeec device pnp 0c09.0 on end end end - device pci 1f.1 on end # - SMBUS + device ref smbus on end end end diff --git a/src/mainboard/google/reef/variants/sand/devicetree.cb b/src/mainboard/google/reef/variants/sand/devicetree.cb index f27d26a5e4..f1e8b1a21a 100644 --- a/src/mainboard/google/reef/variants/sand/devicetree.cb +++ b/src/mainboard/google/reef/variants/sand/devicetree.cb @@ -114,18 +114,14 @@ chip soc/intel/apollolake register "slp_s3_assertion_width_usecs" = "28000" device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen + device ref igd on register "gfx" = "GMA_DEFAULT_PANEL(0)" end - device pci 03.0 off end # - Iunit - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on # - Audio + device ref p2sb on end + device ref pmc on end + device ref fast_spi on end + device ref sram on end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98357A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" @@ -133,23 +129,17 @@ chip soc/intel/apollolake device generic 0 on end end end - device pci 0f.0 on end # - CSE - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 off end # - Root Port 2 - PCIe-A 0 - device pci 13.1 off end # - Root Port 3 - PCIe-A 1 - device pci 13.2 off end # - Root Port 4 - PCIe-A 2 - device pci 13.3 off end # - Root Port 5 - PCIe-A 3 - device pci 14.0 on + device ref heci1 on end + device ref heci2 on end + device ref heci3 on end + device ref pcie_rp05 on chip drivers/wifi/generic register "wake" = "GPE0_DW3_00" device pci 00.0 on end end - end # - Root Port 0 - PCIe-B 0 - Wifi - device pci 14.1 off end # - Root Port 1 - PCIe-B 1 - device pci 15.0 on end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on # - I2C 0 + end + device ref xhci on end + device ref i2c0 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" register "btn_cfg" = "50" @@ -168,15 +158,15 @@ chip soc/intel/apollolake device i2c 1a on end end end - device pci 16.1 on end # - I2C 1 - device pci 16.2 on + device ref i2c1 on end + device ref i2c2 on chip drivers/i2c/tpm register "hid" = ""GOOG0005"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" device i2c 50 on end end - end # - I2C 2 - device pci 16.3 on + end + device ref i2c3 on chip drivers/i2c/generic register "hid" = ""RAYD0001"" register "desc" = ""Raydium Touchscreen"" @@ -189,8 +179,8 @@ chip soc/intel/apollolake register "has_power_resource" = "true" device i2c 39 on end end - end # - I2C 3 - device pci 17.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -199,8 +189,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 4 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -208,25 +198,19 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 5 - device pci 17.2 off end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 on end # - UART 1 - device pci 18.2 on end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on end # - SPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 off end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1b.0 on end # - SDCARD - device pci 1c.0 on end # - eMMC - device pci 1e.0 off end # - SDIO - device pci 1f.0 on # - LPC + end + device ref uart0 on end + device ref uart1 on end + device ref uart2 on end + device ref spi0 on end + device ref pwm on end + device ref sdcard on end + device ref emmc on end + device ref lpc_espi on chip ec/google/chromeec device pnp 0c09.0 on end end end - device pci 1f.1 on end # - SMBUS + device ref smbus on end end end diff --git a/src/mainboard/google/reef/variants/snappy/devicetree.cb b/src/mainboard/google/reef/variants/snappy/devicetree.cb index e755776aae..fcc75a37d3 100644 --- a/src/mainboard/google/reef/variants/snappy/devicetree.cb +++ b/src/mainboard/google/reef/variants/snappy/devicetree.cb @@ -123,18 +123,14 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen + device ref igd on register "gfx" = "GMA_DEFAULT_PANEL(0)" end - device pci 03.0 off end # - Iunit - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on # - Audio + device ref p2sb on end + device ref pmc on end + device ref fast_spi on end + device ref sram on end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98357A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" @@ -142,23 +138,17 @@ chip soc/intel/apollolake device generic 0 on end end end - device pci 0f.0 on end # - CSE - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 off end # - Root Port 2 - PCIe-A 0 - device pci 13.1 off end # - Root Port 3 - PCIe-A 1 - device pci 13.2 off end # - Root Port 4 - PCIe-A 2 - device pci 13.3 off end # - Root Port 5 - PCIe-A 3 - device pci 14.0 on + device ref heci1 on end + device ref heci2 on end + device ref heci3 on end + device ref pcie_rp05 on chip drivers/wifi/generic register "wake" = "GPE0_DW3_00" device pci 00.0 on end end - end # - Root Port 0 - PCIe-B 0 - Wifi - device pci 14.1 off end # - Root Port 1 - PCIe-B 1 - device pci 15.0 on end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on # - I2C 0 + end + device ref xhci on end + device ref i2c0 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" register "btn_cfg" = "50" @@ -177,15 +167,15 @@ chip soc/intel/apollolake device i2c 1a on end end end - device pci 16.1 on end # - I2C 1 - device pci 16.2 on + device ref i2c1 on end + device ref i2c2 on chip drivers/i2c/tpm register "hid" = ""GOOG0005"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" device i2c 50 on end end - end # - I2C 2 - device pci 16.3 on + end + device ref i2c3 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -257,8 +247,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 3 - device pci 17.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -267,8 +257,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 4 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -276,25 +266,19 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 5 - device pci 17.2 off end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 on end # - UART 1 - device pci 18.2 on end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on end # - SPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 off end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1b.0 on end # - SDCARD - device pci 1c.0 on end # - eMMC - device pci 1e.0 off end # - SDIO - device pci 1f.0 on # - LPC + end + device ref uart0 on end + device ref uart1 on end + device ref uart2 on end + device ref spi0 on end + device ref pwm on end + device ref sdcard on end + device ref emmc on end + device ref lpc_espi on chip ec/google/chromeec device pnp 0c09.0 on end end end - device pci 1f.1 on end # - SMBUS + device ref smbus on end end end From 2bccc76db6e4a758854eb7b593ef8b6e321b3306 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 26 Jan 2026 12:27:04 -0600 Subject: [PATCH 322/789] mb/google/reef: Convert to use variant overridetrees Rather than separate devicetrees for each variant, convert to using a single baseboard devicetree plus overridetrees for each variant. The Reef uses variant uses the baseboard only (no override). - Set DEVICETREE to variants/baseboard/devicetree.cb for all variants - Add OVERRIDE_DEVICETREE for non-reef variants - Add overridetree.cb for coral, sand, pyro, snappy with only the differences from the baseboard - Remove variant devicetree.cb files TEST=build all REEF variants Change-Id: I1e8edc968cb0a733b23007dc2295b7f1189ea4fa Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90928 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- src/mainboard/google/reef/Kconfig | 7 +- .../google/reef/variants/coral/devicetree.cb | 242 --------------- .../reef/variants/coral/overridetree.cb | 52 ++++ .../google/reef/variants/pyro/devicetree.cb | 235 --------------- .../google/reef/variants/pyro/overridetree.cb | 74 +++++ .../google/reef/variants/sand/devicetree.cb | 216 ------------- .../google/reef/variants/sand/overridetree.cb | 48 +++ .../google/reef/variants/snappy/devicetree.cb | 284 ------------------ .../reef/variants/snappy/overridetree.cb | 113 +++++++ 9 files changed, 290 insertions(+), 981 deletions(-) delete mode 100644 src/mainboard/google/reef/variants/coral/devicetree.cb create mode 100644 src/mainboard/google/reef/variants/coral/overridetree.cb delete mode 100644 src/mainboard/google/reef/variants/pyro/devicetree.cb create mode 100644 src/mainboard/google/reef/variants/pyro/overridetree.cb delete mode 100644 src/mainboard/google/reef/variants/sand/devicetree.cb create mode 100644 src/mainboard/google/reef/variants/sand/overridetree.cb delete mode 100644 src/mainboard/google/reef/variants/snappy/devicetree.cb create mode 100644 src/mainboard/google/reef/variants/snappy/overridetree.cb diff --git a/src/mainboard/google/reef/Kconfig b/src/mainboard/google/reef/Kconfig index 899efeb4b8..06c5575e45 100644 --- a/src/mainboard/google/reef/Kconfig +++ b/src/mainboard/google/reef/Kconfig @@ -76,12 +76,11 @@ config VARIANT_DIR default "coral" if BOARD_GOOGLE_CORAL config DEVICETREE - default "variants/coral/devicetree.cb" if BOARD_GOOGLE_CORAL - default "variants/pyro/devicetree.cb" if BOARD_GOOGLE_PYRO - default "variants/sand/devicetree.cb" if BOARD_GOOGLE_SAND - default "variants/snappy/devicetree.cb" if BOARD_GOOGLE_SNAPPY default "variants/baseboard/devicetree.cb" +config OVERRIDE_DEVICETREE + default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" if !BOARD_GOOGLE_REEF + config MAINBOARD_PART_NUMBER default "Reef" if BOARD_GOOGLE_REEF default "Pyro" if BOARD_GOOGLE_PYRO diff --git a/src/mainboard/google/reef/variants/coral/devicetree.cb b/src/mainboard/google/reef/variants/coral/devicetree.cb deleted file mode 100644 index c7ddc9f33e..0000000000 --- a/src/mainboard/google/reef/variants/coral/devicetree.cb +++ /dev/null @@ -1,242 +0,0 @@ -chip soc/intel/apollolake - - register "pcie_rp_clkreq_pin[0]" = "0" # wifi/bt - # Disable unused clkreq of PCIe root ports - register "pcie_rp_clkreq_pin[1]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[2]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[3]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[4]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[5]" = "CLKREQ_DISABLED" - - # GPIO for PERST_0 - # If the Board has PERST_0 signal, assign the GPIO - # If the Board does not have PERST_0, assign GPIO_PRT0_UDEF - register "prt0_gpio" = "GPIO_122" - - # GPIO for SD card detect - register "sdcard_cd_gpio" = "GPIO_177" - - # EMMC TX DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [14:8] steps of delay for HS400, each 125ps. - # [6:0] steps of delay for SDR104/HS200, each 125ps. - register "emmc_tx_data_cntl1" = "0x0C16" - - # EMMC TX DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_tx_data_cntl2" = "0x28162828" - - # EMMC RX CMD/DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_rx_cmd_data_cntl1" = "0x00181717" - - # EMMC RX CMD/DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [17:16] stands for Rx Clock before Output Buffer - # [14:8] steps of delay for Auto Tuning Mode, each 125ps. - # [6:0] steps of delay for HS200, each 125ps. - register "emmc_rx_cmd_data_cntl2" = "0x10008" - - # Enable DPTF - register "dptf_enable" = "true" - - # PL1 override 12 W: the energy calculation is wrong with the - # current VR solution. Experiments show that SoC TDP max (6W) can - # be reached when RAPL PL1 is set to 12W. - # Set RAPL PL2 to 15W. - register "power_limits_config" = "{ - .tdp_pl1_override = 12, - .tdp_pl2_override = 15, - }" - - # Enable Audio Clock and Power gating - register "hdaudio_clk_gate_enable" = "1" - register "hdaudio_pwr_gate_enable" = "1" - register "hdaudio_bios_config_lockdown" = "1" - - # Enable lpss s0ix - register "lpss_s0ix_enable" = "true" - - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route, i.e., if this route changes then the affected GPE - # offset bits also need to be changed. This sets the PMC register - # GPE_CFG fields. - register "gpe0_dw1" = "PMC_GPE_N_31_0" - register "gpe0_dw2" = "PMC_GPE_N_63_32" - register "gpe0_dw3" = "PMC_GPE_SW_31_0" - - # Intel Common SoC Config - #+-------------------+---------------------------+ - #| Field | Value | - #+-------------------+---------------------------+ - #| I2C0 | Audio | - #| I2C2 | TPM | - #| I2C3 | Touchscreen | - #| I2C4 | Trackpad | - #| I2C5 | Digitizer | - #+-------------------+---------------------------+ - register "common_soc_config" = "{ - .i2c[0] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 104, - .fall_time_ns = 52, - }, - .i2c[2] = { - .early_init = 1, - .speed = I2C_SPEED_FAST, - .rise_time_ns = 57, - .fall_time_ns = 28, - }, - .i2c[3] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 76, - .fall_time_ns = 164, - }, - .i2c[4] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 114, - .fall_time_ns = 164, - .data_hold_time_ns = 350, - }, - .i2c[5] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 152, - .fall_time_ns = 30, - }, - }" - - # Minimum SLP S3 assertion width 28ms. - register "slp_s3_assertion_width_usecs" = "28000" - - device domain 0 on - device ref igd on - register "gfx" = "GMA_DEFAULT_PANEL(0)" - end - device ref p2sb on end - device ref pmc on end - device ref fast_spi on end - device ref sram on end - device ref hda on - chip drivers/generic/max98357a - register "hid" = ""MX98357A"" - register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" - register "sdmode_delay" = "5" - device generic 0 on end - end - end - device ref heci1 on end - device ref heci2 on end - device ref heci3 on end - device ref pcie_rp05 on - chip drivers/wifi/generic - register "wake" = "GPE0_DW3_00" - device pci 00.0 on end - end - end - device ref xhci on end - device ref i2c0 on - chip drivers/i2c/da7219 - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" - register "btn_cfg" = "50" - register "mic_det_thr" = "200" - register "jack_ins_deb" = "20" - register "jack_det_rate" = ""32ms_64ms"" - register "jack_rem_deb" = "1" - register "a_d_btn_thr" = "0xa" - register "d_b_btn_thr" = "0x16" - register "b_c_btn_thr" = "0x21" - register "c_mic_btn_thr" = "0x3e" - register "btn_avg" = "4" - register "adc_1bit_rpt" = "1" - register "micbias_lvl" = "2600" - register "mic_amp_in_sel" = ""diff"" - device i2c 1a on end - end - end - device ref i2c1 on end - device ref i2c2 on - chip drivers/i2c/tpm - register "hid" = ""GOOG0005"" - register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" - device i2c 50 on end - end - end - device ref i2c3 on - chip drivers/i2c/generic - register "hid" = ""ELAN0001"" - register "desc" = ""ELAN Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "20" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "1" - register "has_power_resource" = "true" - device i2c 10 on end - end - chip drivers/i2c/generic - register "hid" = ""RAYD0001"" - register "desc" = ""Raydium Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "1" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "50" - register "has_power_resource" = "true" - device i2c 39 on end - end - end - device ref i2c4 on - chip drivers/i2c/generic - register "hid" = ""ELAN0000"" - register "desc" = ""ELAN Touchpad"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" - register "wake" = "GPE0_DW1_15" - register "detect" = "1" - device i2c 15 on end - end - chip drivers/i2c/hid - register "generic.hid" = ""SYNA0000"" - register "generic.cid" = ""ACPI0C50"" - register "generic.desc" = ""Synaptics Touchpad"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" - register "generic.wake" = "GPE0_DW1_15" - register "generic.detect" = "1" - register "hid_desc_reg_offset" = "0x20" - device i2c 0x2c on end - end - end - device ref i2c5 on - chip drivers/i2c/hid - register "generic.hid" = ""WCOM50C1"" - register "generic.desc" = ""WCOM Digitizer"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_13_IRQ)" - register "hid_desc_reg_offset" = "0x1" - device i2c 0x9 on end - end - end - device ref uart0 on end - device ref uart1 off end - device ref uart2 off end - device ref spi0 on end - device ref pwm on end - device ref sdcard on end - device ref emmc on end - device ref lpc_espi on - chip ec/google/chromeec - device pnp 0c09.0 on end - end - end - device ref smbus on end - end -end diff --git a/src/mainboard/google/reef/variants/coral/overridetree.cb b/src/mainboard/google/reef/variants/coral/overridetree.cb new file mode 100644 index 0000000000..0df53c0f7a --- /dev/null +++ b/src/mainboard/google/reef/variants/coral/overridetree.cb @@ -0,0 +1,52 @@ +chip soc/intel/apollolake + device domain 0 on + device ref i2c3 on + chip drivers/i2c/generic + register "hid" = ""ELAN0001"" + register "desc" = ""ELAN Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "20" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "1" + register "has_power_resource" = "true" + device i2c 10 on end + end + chip drivers/i2c/generic + register "hid" = ""RAYD0001"" + register "desc" = ""Raydium Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "1" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "50" + register "has_power_resource" = "true" + device i2c 39 on end + end + end + device ref i2c4 on + chip drivers/i2c/generic + register "hid" = ""ELAN0000"" + register "desc" = ""ELAN Touchpad"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" + register "wake" = "GPE0_DW1_15" + register "detect" = "1" + device i2c 15 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""SYNA0000"" + register "generic.cid" = ""ACPI0C50"" + register "generic.desc" = ""Synaptics Touchpad"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" + register "generic.wake" = "GPE0_DW1_15" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x20" + device i2c 0x2c on end + end + end + device ref uart1 off end + device ref uart2 off end + end +end diff --git a/src/mainboard/google/reef/variants/pyro/devicetree.cb b/src/mainboard/google/reef/variants/pyro/devicetree.cb deleted file mode 100644 index 479fc92802..0000000000 --- a/src/mainboard/google/reef/variants/pyro/devicetree.cb +++ /dev/null @@ -1,235 +0,0 @@ -chip soc/intel/apollolake - - register "pcie_rp_clkreq_pin[0]" = "0" # wifi/bt - # Disable unused clkreq of PCIe root ports - register "pcie_rp_clkreq_pin[1]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[2]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[3]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[4]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[5]" = "CLKREQ_DISABLED" - - # GPIO for PERST_0 - # If the Board has PERST_0 signal, assign the GPIO - # If the Board does not have PERST_0, assign GPIO_PRT0_UDEF - register "prt0_gpio" = "GPIO_122" - - # GPIO for SD card detect - register "sdcard_cd_gpio" = "GPIO_177" - - # EMMC TX DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [14:8] steps of delay for HS400, each 125ps. - # [6:0] steps of delay for SDR104/HS200, each 125ps. - register "emmc_tx_data_cntl1" = "0x0C16" - - # EMMC TX DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_tx_data_cntl2" = "0x28162828" - - # EMMC RX CMD/DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_rx_cmd_data_cntl1" = "0x00181717" - - # EMMC RX CMD/DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [17:16] stands for Rx Clock before Output Buffer - # [14:8] steps of delay for Auto Tuning Mode, each 125ps. - # [6:0] steps of delay for HS200, each 125ps. - register "emmc_rx_cmd_data_cntl2" = "0x10008" - - # Enable DPTF - register "dptf_enable" = "true" - - # PL1 override 12 W: the energy calculation is wrong with the - # current VR solution. Experiments show that SoC TDP max (6W) can - # be reached when RAPL PL1 is set to 12W. - # Set RAPL PL2 to 15W. - register "power_limits_config" = "{ - .tdp_pl1_override = 12, - .tdp_pl2_override = 15, - }" - - # Enable Audio Clock and Power gating - register "hdaudio_clk_gate_enable" = "1" - register "hdaudio_pwr_gate_enable" = "1" - register "hdaudio_bios_config_lockdown" = "1" - - # Enable lpss s0ix - register "lpss_s0ix_enable" = "true" - - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route, i.e., if this route changes then the affected GPE - # offset bits also need to be changed. This sets the PMC register - # GPE_CFG fields. - register "gpe0_dw1" = "PMC_GPE_N_31_0" - register "gpe0_dw2" = "PMC_GPE_N_63_32" - register "gpe0_dw3" = "PMC_GPE_SW_31_0" - - # Intel Common SoC Config - #+-------------------+---------------------------+ - #| Field | Value | - #+-------------------+---------------------------+ - #| I2C0 | Audio | - #| I2C2 | TPM | - #| I2C3 | Touchscreen | - #| I2C4 | Trackpad | - #+-------------------+---------------------------+ - register "common_soc_config" = "{ - .i2c[0] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 104, - .fall_time_ns = 52, - }, - .i2c[2] = { - .early_init = 1, - .speed = I2C_SPEED_FAST, - .rise_time_ns = 50, - .fall_time_ns = 23, - }, - .i2c[3] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 76, - .fall_time_ns = 164, - }, - .i2c[4] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 90, - .fall_time_ns = 164, - }, - }" - - # Minimum SLP S3 assertion width 28ms. - register "slp_s3_assertion_width_usecs" = "28000" - - # Override USB2 PER PORT register (PORT 0) - register "usb2eye[0]" = "{ - .Usb20PerPortPeTxiSet = 7, - .Usb20PerPortTxiSet = 1, - .Usb20IUsbTxEmphasisEn = 3, - .Usb20PerPortTxPeHalf = 0, - }" - - # Override USB2 PER PORT register (PORT 1) - register "usb2eye[1]" = "{ - .Usb20PerPortPeTxiSet = 7, - .Usb20PerPortTxiSet = 2, - .Usb20IUsbTxEmphasisEn = 3, - .Usb20PerPortTxPeHalf = 0, - }" - - device domain 0 on - device ref igd on - register "gfx" = "GMA_DEFAULT_PANEL(0)" - end - device ref p2sb on end - device ref pmc on end - device ref fast_spi on end - device ref sram on end - device ref hda on - chip drivers/generic/max98357a - register "hid" = ""MX98357A"" - register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" - register "sdmode_delay" = "5" - device generic 0 on end - end - end - device ref heci1 on end - device ref heci2 on end - device ref heci3 on end - device ref pcie_rp05 on - chip drivers/wifi/generic - register "wake" = "GPE0_DW3_00" - device pci 00.0 on end - end - end - device ref xhci on end - device ref i2c0 on - chip drivers/i2c/da7219 - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" - register "btn_cfg" = "50" - register "mic_det_thr" = "200" - register "jack_ins_deb" = "20" - register "jack_det_rate" = ""32ms_64ms"" - register "jack_rem_deb" = "1" - register "a_d_btn_thr" = "0xa" - register "d_b_btn_thr" = "0x16" - register "b_c_btn_thr" = "0x21" - register "c_mic_btn_thr" = "0x3e" - register "btn_avg" = "4" - register "adc_1bit_rpt" = "1" - register "micbias_lvl" = "2600" - register "mic_amp_in_sel" = ""diff"" - device i2c 1a on end - end - end - device ref i2c1 on end - device ref i2c2 on - chip drivers/i2c/tpm - register "hid" = ""GOOG0005"" - register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" - device i2c 50 on end - end - end - device ref i2c3 on - chip drivers/i2c/hid - register "generic.hid" = ""WCOMNTN2"" - register "generic.desc" = ""WCOM Touchscreen"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "generic.detect" = "1" - register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "generic.reset_delay_ms" = "20" - register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "generic.enable_delay_ms" = "1" - register "generic.has_power_resource" = "1" - register "hid_desc_reg_offset" = "0x1" - device i2c 0xA on end - end - chip drivers/i2c/generic - register "hid" = ""ELAN0001"" - register "desc" = ""ELAN Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "20" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "1" - register "has_power_resource" = "true" - device i2c 10 on end - end - end - device ref i2c4 on - chip drivers/i2c/generic - register "hid" = ""ELAN0000"" - register "desc" = ""ELAN Touchpad"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" - register "wake" = "GPE0_DW1_15" - register "detect" = "1" - device i2c 15 on end - end - end - device ref i2c5 off end - device ref i2c6 off end - device ref uart0 on end - device ref uart1 on end - device ref uart2 on end - device ref spi0 on end - device ref pwm on end - device ref sdcard on end - device ref emmc on end - device ref lpc_espi on - chip ec/google/chromeec - device pnp 0c09.0 on end - end - end - device ref smbus on end - end -end diff --git a/src/mainboard/google/reef/variants/pyro/overridetree.cb b/src/mainboard/google/reef/variants/pyro/overridetree.cb new file mode 100644 index 0000000000..f669639695 --- /dev/null +++ b/src/mainboard/google/reef/variants/pyro/overridetree.cb @@ -0,0 +1,74 @@ +chip soc/intel/apollolake + # Intel Common SoC Config (no i2c[5]) + register "common_soc_config" = "{ + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 104, + .fall_time_ns = 52, + }, + .i2c[2] = { + .early_init = 1, + .speed = I2C_SPEED_FAST, + .rise_time_ns = 50, + .fall_time_ns = 23, + }, + .i2c[3] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 76, + .fall_time_ns = 164, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 90, + .fall_time_ns = 164, + }, + }" + + # Override USB2 PER PORT register (PORT 0) + register "usb2eye[0]" = "{ + .Usb20PerPortPeTxiSet = 7, + .Usb20PerPortTxiSet = 1, + .Usb20IUsbTxEmphasisEn = 3, + .Usb20PerPortTxPeHalf = 0, + }" + + # Override USB2 PER PORT register (PORT 1) + register "usb2eye[1]" = "{ + .Usb20PerPortPeTxiSet = 7, + .Usb20PerPortTxiSet = 2, + .Usb20IUsbTxEmphasisEn = 3, + .Usb20PerPortTxPeHalf = 0, + }" + + device domain 0 on + device ref i2c3 on + chip drivers/i2c/hid + register "generic.hid" = ""WCOMNTN2"" + register "generic.desc" = ""WCOM Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "generic.detect" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "generic.reset_delay_ms" = "20" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x1" + device i2c 0xA on end + end + chip drivers/i2c/generic + register "hid" = ""ELAN0001"" + register "desc" = ""ELAN Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "20" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "1" + register "has_power_resource" = "true" + device i2c 10 on end + end + end + device ref i2c5 off end + device ref i2c6 off end + end +end diff --git a/src/mainboard/google/reef/variants/sand/devicetree.cb b/src/mainboard/google/reef/variants/sand/devicetree.cb deleted file mode 100644 index f1e8b1a21a..0000000000 --- a/src/mainboard/google/reef/variants/sand/devicetree.cb +++ /dev/null @@ -1,216 +0,0 @@ -chip soc/intel/apollolake - - register "pcie_rp_clkreq_pin[0]" = "0" # wifi/bt - # Disable unused clkreq of PCIe root ports - register "pcie_rp_clkreq_pin[1]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[2]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[3]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[4]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[5]" = "CLKREQ_DISABLED" - - # GPIO for PERST_0 - # If the Board has PERST_0 signal, assign the GPIO - # If the Board does not have PERST_0, assign GPIO_PRT0_UDEF - register "prt0_gpio" = "GPIO_122" - - # EMMC TX DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [14:8] steps of delay for HS400, each 125ps. - # [6:0] steps of delay for SDR104/HS200, each 125ps. - register "emmc_tx_data_cntl1" = "0x0C16" - - # EMMC TX DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_tx_data_cntl2" = "0x28162828" - - # EMMC RX CMD/DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_rx_cmd_data_cntl1" = "0x00181717" - - # EMMC RX CMD/DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [17:16] stands for Rx Clock before Output Buffer - # [14:8] steps of delay for Auto Tuning Mode, each 125ps. - # [6:0] steps of delay for HS200, each 125ps. - register "emmc_rx_cmd_data_cntl2" = "0x10008" - - # Enable DPTF - register "dptf_enable" = "true" - - # PL1 override 12 W: the energy calculation is wrong with the - # current VR solution. Experiments show that SoC TDP max (6W) can - # be reached when RAPL PL1 is set to 12W. - # Set RAPL PL2 to 15W. - register "power_limits_config" = "{ - .tdp_pl1_override = 12, - .tdp_pl2_override = 15, - }" - - # Enable Audio Clock and Power gating - register "hdaudio_clk_gate_enable" = "1" - register "hdaudio_pwr_gate_enable" = "1" - register "hdaudio_bios_config_lockdown" = "1" - - # Enable lpss s0ix - register "lpss_s0ix_enable" = "true" - - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route, i.e., if this route changes then the affected GPE - # offset bits also need to be changed. This sets the PMC register - # GPE_CFG fields. - register "gpe0_dw1" = "PMC_GPE_N_31_0" - register "gpe0_dw2" = "PMC_GPE_N_63_32" - register "gpe0_dw3" = "PMC_GPE_SW_31_0" - - # Intel Common SoC Config - #+-------------------+---------------------------+ - #| Field | Value | - #+-------------------+---------------------------+ - #| I2C0 | Audio | - #| I2C2 | TPM | - #| I2C3 | Touchscreen | - #| I2C4 | Trackpad | - #| I2C5 | Digitizer | - #+-------------------+---------------------------+ - register "common_soc_config" = "{ - .i2c[0] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 104, - .fall_time_ns = 52, - }, - .i2c[2] = { - .early_init = 1, - .speed = I2C_SPEED_FAST, - .rise_time_ns = 57, - .fall_time_ns = 28, - }, - .i2c[3] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 76, - .fall_time_ns = 164, - }, - .i2c[4] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 114, - .fall_time_ns = 164, - }, - .i2c[5] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 152, - .fall_time_ns = 30, - }, - }" - - # Minimum SLP S3 assertion width 28ms. - register "slp_s3_assertion_width_usecs" = "28000" - - device domain 0 on - device ref igd on - register "gfx" = "GMA_DEFAULT_PANEL(0)" - end - device ref p2sb on end - device ref pmc on end - device ref fast_spi on end - device ref sram on end - device ref hda on - chip drivers/generic/max98357a - register "hid" = ""MX98357A"" - register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" - register "sdmode_delay" = "5" - device generic 0 on end - end - end - device ref heci1 on end - device ref heci2 on end - device ref heci3 on end - device ref pcie_rp05 on - chip drivers/wifi/generic - register "wake" = "GPE0_DW3_00" - device pci 00.0 on end - end - end - device ref xhci on end - device ref i2c0 on - chip drivers/i2c/da7219 - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" - register "btn_cfg" = "50" - register "mic_det_thr" = "200" - register "jack_ins_deb" = "20" - register "jack_det_rate" = ""32ms_64ms"" - register "jack_rem_deb" = "1" - register "a_d_btn_thr" = "0xa" - register "d_b_btn_thr" = "0x16" - register "b_c_btn_thr" = "0x21" - register "c_mic_btn_thr" = "0x3e" - register "btn_avg" = "4" - register "adc_1bit_rpt" = "1" - register "micbias_lvl" = "2600" - register "mic_amp_in_sel" = ""diff"" - device i2c 1a on end - end - end - device ref i2c1 on end - device ref i2c2 on - chip drivers/i2c/tpm - register "hid" = ""GOOG0005"" - register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" - device i2c 50 on end - end - end - device ref i2c3 on - chip drivers/i2c/generic - register "hid" = ""RAYD0001"" - register "desc" = ""Raydium Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "20" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "1" - register "has_power_resource" = "true" - device i2c 39 on end - end - end - device ref i2c4 on - chip drivers/i2c/generic - register "hid" = ""ELAN0000"" - register "desc" = ""ELAN Touchpad"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" - register "wake" = "GPE0_DW1_15" - register "detect" = "1" - device i2c 15 on end - end - end - device ref i2c5 on - chip drivers/i2c/hid - register "generic.hid" = ""WCOM50C1"" - register "generic.desc" = ""WCOM Digitizer"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_13_IRQ)" - register "hid_desc_reg_offset" = "0x1" - device i2c 0x9 on end - end - end - device ref uart0 on end - device ref uart1 on end - device ref uart2 on end - device ref spi0 on end - device ref pwm on end - device ref sdcard on end - device ref emmc on end - device ref lpc_espi on - chip ec/google/chromeec - device pnp 0c09.0 on end - end - end - device ref smbus on end - end -end diff --git a/src/mainboard/google/reef/variants/sand/overridetree.cb b/src/mainboard/google/reef/variants/sand/overridetree.cb new file mode 100644 index 0000000000..7571a772bc --- /dev/null +++ b/src/mainboard/google/reef/variants/sand/overridetree.cb @@ -0,0 +1,48 @@ +chip soc/intel/apollolake + # Intel Common SoC Config (i2c[4] without data_hold_time_ns) + register "common_soc_config" = "{ + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 104, + .fall_time_ns = 52, + }, + .i2c[2] = { + .early_init = 1, + .speed = I2C_SPEED_FAST, + .rise_time_ns = 57, + .fall_time_ns = 28, + }, + .i2c[3] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 76, + .fall_time_ns = 164, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 114, + .fall_time_ns = 164, + }, + .i2c[5] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 152, + .fall_time_ns = 30, + }, + }" + + device domain 0 on + device ref i2c3 on + chip drivers/i2c/generic + register "hid" = ""RAYD0001"" + register "desc" = ""Raydium Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "20" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "1" + register "has_power_resource" = "true" + device i2c 39 on end + end + end + end +end diff --git a/src/mainboard/google/reef/variants/snappy/devicetree.cb b/src/mainboard/google/reef/variants/snappy/devicetree.cb deleted file mode 100644 index fcc75a37d3..0000000000 --- a/src/mainboard/google/reef/variants/snappy/devicetree.cb +++ /dev/null @@ -1,284 +0,0 @@ -chip soc/intel/apollolake - - register "pcie_rp_clkreq_pin[0]" = "0" # wifi/bt - # Disable unused clkreq of PCIe root ports - register "pcie_rp_clkreq_pin[1]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[2]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[3]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[4]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[5]" = "CLKREQ_DISABLED" - - # GPIO for PERST_0 - # If the Board has PERST_0 signal, assign the GPIO - # If the Board does not have PERST_0, assign GPIO_PRT0_UDEF - register "prt0_gpio" = "GPIO_122" - - # GPIO for SD card detect - register "sdcard_cd_gpio" = "GPIO_177" - - # EMMC TX DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [14:8] steps of delay for HS400, each 125ps. - # [6:0] steps of delay for SDR104/HS200, each 125ps. - register "emmc_tx_data_cntl1" = "0x0C16" - - # EMMC TX DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_tx_data_cntl2" = "0x28162828" - - # EMMC RX CMD/DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_rx_cmd_data_cntl1" = "0x00181717" - - # EMMC RX CMD/DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [17:16] stands for Rx Clock before Output Buffer - # [14:8] steps of delay for Auto Tuning Mode, each 125ps. - # [6:0] steps of delay for HS200, each 125ps. - register "emmc_rx_cmd_data_cntl2" = "0x10008" - - # Enable DPTF - register "dptf_enable" = "true" - - # PL1 override 12 W: the energy calculation is wrong with the - # current VR solution. Experiments show that SoC TDP max (6W) can - # be reached when RAPL PL1 is set to 12W. - # Set RAPL PL2 to 15W. - register "power_limits_config" = "{ - .tdp_pl1_override = 12, - .tdp_pl2_override = 15, - }" - - # Enable Audio Clock and Power gating - register "hdaudio_clk_gate_enable" = "1" - register "hdaudio_pwr_gate_enable" = "1" - register "hdaudio_bios_config_lockdown" = "1" - - # Enable lpss s0ix - register "lpss_s0ix_enable" = "true" - - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route, i.e., if this route changes then the affected GPE - # offset bits also need to be changed. This sets the PMC register - # GPE_CFG fields. - register "gpe0_dw1" = "PMC_GPE_N_31_0" - register "gpe0_dw2" = "PMC_GPE_N_63_32" - register "gpe0_dw3" = "PMC_GPE_SW_31_0" - - # Intel Common SoC Config - #+-------------------+---------------------------+ - #| Field | Value | - #+-------------------+---------------------------+ - #| I2C0 | Audio | - #| I2C2 | TPM | - #| I2C3 | Touchscreen | - #| I2C4 | Trackpad | - #| I2C5 | Digitizer | - #+-------------------+---------------------------+ - register "common_soc_config" = "{ - .i2c[0] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 44, - .fall_time_ns = 22, - }, - .i2c[2] = { - .early_init = 1, - .speed = I2C_SPEED_FAST, - .rise_time_ns = 40, - .fall_time_ns = 20, - }, - .i2c[3] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 70, - .fall_time_ns = 164, - }, - .i2c[4] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 20, - .fall_time_ns = 164, - }, - .i2c[5] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 152, - .fall_time_ns = 30, - }, - }" - - # Minimum SLP S3 assertion width 28ms. - register "slp_s3_assertion_width_usecs" = "28000" - - # Override USB2 PER PORT register (PORT 1) - register "usb2eye[1]" = "{ - .Usb20PerPortPeTxiSet = 7, - .Usb20PerPortTxiSet = 0, - }" - - device domain 0 on - device ref igd on - register "gfx" = "GMA_DEFAULT_PANEL(0)" - end - device ref p2sb on end - device ref pmc on end - device ref fast_spi on end - device ref sram on end - device ref hda on - chip drivers/generic/max98357a - register "hid" = ""MX98357A"" - register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" - register "sdmode_delay" = "5" - device generic 0 on end - end - end - device ref heci1 on end - device ref heci2 on end - device ref heci3 on end - device ref pcie_rp05 on - chip drivers/wifi/generic - register "wake" = "GPE0_DW3_00" - device pci 00.0 on end - end - end - device ref xhci on end - device ref i2c0 on - chip drivers/i2c/da7219 - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" - register "btn_cfg" = "50" - register "mic_det_thr" = "200" - register "jack_ins_deb" = "20" - register "jack_det_rate" = ""32ms_64ms"" - register "jack_rem_deb" = "1" - register "a_d_btn_thr" = "0xa" - register "d_b_btn_thr" = "0x16" - register "b_c_btn_thr" = "0x21" - register "c_mic_btn_thr" = "0x3e" - register "btn_avg" = "4" - register "adc_1bit_rpt" = "1" - register "micbias_lvl" = "2600" - register "mic_amp_in_sel" = ""diff"" - device i2c 1a on end - end - end - device ref i2c1 on end - device ref i2c2 on - chip drivers/i2c/tpm - register "hid" = ""GOOG0005"" - register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" - device i2c 50 on end - end - end - device ref i2c3 on - chip drivers/i2c/generic - register "hid" = ""ELAN0001"" - register "desc" = ""ELAN Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "20" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "1" - register "has_power_resource" = "true" - device i2c 10 on end - end - chip drivers/i2c/generic - register "hid" = ""MLFS0000"" - register "desc" = ""Melfas Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - # Melfas TS IC doesn't have reset pin design, current FW also not - # declare "ce-gpios" in ACPI _DSD to let Melfas TS driver to know - # "enable gpio#152 (VTSP) but because of kernel bug & Melfas TS driver - # is unable to separate clear power sequence path for certain - # TS IC (ex: MIT-410) and kernel will still obstain GPIO from _CRS - # by index "0" since no matched "gpio" in ACPI _DSD. - # coreboot needs to have "dummy pin" as workaround in order to let - # kernel driver grab "useless" GPIO to prevent Melfas TS driver cut - # power by driver itself. - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "1" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "5" - register "has_power_resource" = "true" - device i2c 34 on end - end - chip drivers/i2c/generic - register "hid" = ""RAYD0001"" - register "desc" = ""Raydium Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "1" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "50" - register "has_power_resource" = "true" - device i2c 39 on end - end - chip drivers/i2c/hid - register "generic.hid" = ""WDHT0002"" - register "generic.desc" = ""WDT Touchscreen"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "generic.detect" = "1" - register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "generic.reset_delay_ms" = "130" - register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "generic.enable_delay_ms" = "1" - register "generic.has_power_resource" = "1" - register "hid_desc_reg_offset" = "0x20" - device i2c 2c on end - end - chip drivers/i2c/hid - register "generic.hid" = ""GTCH7503"" - register "generic.desc" = ""G2TOUCH Touchscreen"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "generic.detect" = "1" - register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "generic.reset_delay_ms" = "50" - register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "generic.enable_delay_ms" = "1" - register "generic.has_power_resource" = "1" - register "hid_desc_reg_offset" = "0x01" - device i2c 40 on end - end - end - device ref i2c4 on - chip drivers/i2c/generic - register "hid" = ""ELAN0000"" - register "desc" = ""ELAN Touchpad"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" - register "wake" = "GPE0_DW1_15" - register "detect" = "1" - device i2c 15 on end - end - end - device ref i2c5 on - chip drivers/i2c/hid - register "generic.hid" = ""WCOM50C1"" - register "generic.desc" = ""WCOM Digitizer"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_13_IRQ)" - register "hid_desc_reg_offset" = "0x1" - device i2c 0x9 on end - end - end - device ref uart0 on end - device ref uart1 on end - device ref uart2 on end - device ref spi0 on end - device ref pwm on end - device ref sdcard on end - device ref emmc on end - device ref lpc_espi on - chip ec/google/chromeec - device pnp 0c09.0 on end - end - end - device ref smbus on end - end -end diff --git a/src/mainboard/google/reef/variants/snappy/overridetree.cb b/src/mainboard/google/reef/variants/snappy/overridetree.cb new file mode 100644 index 0000000000..3c420d4ddb --- /dev/null +++ b/src/mainboard/google/reef/variants/snappy/overridetree.cb @@ -0,0 +1,113 @@ +chip soc/intel/apollolake + # Intel Common SoC Config + register "common_soc_config" = "{ + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 44, + .fall_time_ns = 22, + }, + .i2c[2] = { + .early_init = 1, + .speed = I2C_SPEED_FAST, + .rise_time_ns = 40, + .fall_time_ns = 20, + }, + .i2c[3] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 70, + .fall_time_ns = 164, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 20, + .fall_time_ns = 164, + }, + .i2c[5] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 152, + .fall_time_ns = 30, + }, + }" + + # Override USB2 PER PORT register (PORT 1) + register "usb2eye[1]" = "{ + .Usb20PerPortPeTxiSet = 7, + .Usb20PerPortTxiSet = 0, + }" + + device domain 0 on + device ref i2c3 on + chip drivers/i2c/generic + register "hid" = ""ELAN0001"" + register "desc" = ""ELAN Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "20" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "1" + register "has_power_resource" = "true" + device i2c 10 on end + end + chip drivers/i2c/generic + register "hid" = ""MLFS0000"" + register "desc" = ""Melfas Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + # Melfas TS IC doesn't have reset pin design, current FW also not + # declare "ce-gpios" in ACPI _DSD to let Melfas TS driver to know + # "enable gpio#152 (VTSP) but because of kernel bug & Melfas TS driver + # is unable to separate clear power sequence path for certain + # TS IC (ex: MIT-410) and kernel will still obstain GPIO from _CRS + # by index "0" since no matched "gpio" in ACPI _DSD. + # coreboot needs to have "dummy pin" as workaround in order to let + # kernel driver grab "useless" GPIO to prevent Melfas TS driver cut + # power by driver itself. + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "1" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "5" + register "has_power_resource" = "true" + device i2c 34 on end + end + chip drivers/i2c/generic + register "hid" = ""RAYD0001"" + register "desc" = ""Raydium Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "1" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "50" + register "has_power_resource" = "true" + device i2c 39 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""WDHT0002"" + register "generic.desc" = ""WDT Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "generic.detect" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "generic.reset_delay_ms" = "130" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x20" + device i2c 2c on end + end + chip drivers/i2c/hid + register "generic.hid" = ""GTCH7503"" + register "generic.desc" = ""G2TOUCH Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "generic.detect" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "generic.reset_delay_ms" = "50" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 40 on end + end + end + end +end From 8602d0e2aa0063aba2437957970fd8f1bd875108 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Sun, 18 Jan 2026 21:18:35 +0000 Subject: [PATCH 323/789] soc/intel/common/block/smm: Keep selected wake sources enabled in S5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generic Intel SMM S5 entry path disables all GPEs before asserting SLP_EN, which clears OS-armed wake enables (e.g. LAN_WAKE) and prevents Wake-on-LAN from S5. Add a mainboard override hook, mainboard_smi_sleep_finalize(), called after the S5 teardown but before SLP_EN is asserted, allowing boards to restore required wake sources. Change-Id: I9e97308ed94961fc4c08a10714b1b53f198bb593 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90792 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Jérémy Compostella --- src/cpu/x86/smm/smm_module_handler.c | 1 + src/include/cpu/x86/smm.h | 1 + src/soc/intel/common/block/smm/smihandler.c | 3 +++ 3 files changed, 5 insertions(+) diff --git a/src/cpu/x86/smm/smm_module_handler.c b/src/cpu/x86/smm/smm_module_handler.c index d9f64204d6..8bcda32b33 100644 --- a/src/cpu/x86/smm/smm_module_handler.c +++ b/src/cpu/x86/smm/smm_module_handler.c @@ -226,6 +226,7 @@ void __weak southbridge_smi_handler(void) {} void __weak mainboard_smi_gpi(u32 gpi_sts) {} int __weak mainboard_smi_apmc(u8 data) { return 0; } void __weak mainboard_smi_sleep(u8 slp_typ) {} +void __weak mainboard_smi_sleep_finalize(u8 slp_typ) {} void __weak mainboard_smi_finalize(void) {} void __weak smm_soc_early_init(void) {} diff --git a/src/include/cpu/x86/smm.h b/src/include/cpu/x86/smm.h index b552d33b5a..8c41623817 100644 --- a/src/include/cpu/x86/smm.h +++ b/src/include/cpu/x86/smm.h @@ -61,6 +61,7 @@ void southbridge_smi_handler(void); void mainboard_smi_gpi(u32 gpi_sts); int mainboard_smi_apmc(u8 data); void mainboard_smi_sleep(u8 slp_typ); +void mainboard_smi_sleep_finalize(u8 slp_typ); void mainboard_smi_finalize(void); int mainboard_set_smm_log_level(void); diff --git a/src/soc/intel/common/block/smm/smihandler.c b/src/soc/intel/common/block/smm/smihandler.c index 59489a4f03..cd78de26c3 100644 --- a/src/soc/intel/common/block/smm/smihandler.c +++ b/src/soc/intel/common/block/smm/smihandler.c @@ -220,6 +220,9 @@ void smihandler_southbridge_sleep( break; } + /* Allow mainboard to restore wake sources (e.g. for S5 WOL). */ + mainboard_smi_sleep_finalize(slp_typ); + /* * Write back to the SLP register to cause the originally intended * event again. We need to set BIT13 (SLP_EN) though to make the From 7c4a0479dd6900b50561683f748d8cf4cdecbf37 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Sun, 18 Jan 2026 21:20:33 +0000 Subject: [PATCH 324/789] mb/starlabs/byte_adl: Allow WOL in S5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Utilise mainboard_smi_sleep_finalize to leave LAN_WAKE# armed when entering S5. Change-Id: I85d3bea71f07dae1c9d6caa89015d52dca5116ce Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90793 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Jérémy Compostella --- src/mainboard/starlabs/byte_adl/smihandler.c | 27 +++++++++++++++++++ .../byte_adl/variants/mk_ii/devicetree.cb | 4 +-- 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/mainboard/starlabs/byte_adl/smihandler.c diff --git a/src/mainboard/starlabs/byte_adl/smihandler.c b/src/mainboard/starlabs/byte_adl/smihandler.c new file mode 100644 index 0000000000..fa77eb0568 --- /dev/null +++ b/src/mainboard/starlabs/byte_adl/smihandler.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void mainboard_smi_sleep_finalize(u8 slp_typ) +{ + if (slp_typ != ACPI_S5) + return; + + /* + * Keep LAN_WAKE# armed in S5 for WOL. + * GPE0_LAN_WAK is GPE 112, which is bit 16 in the STD GPE block (127:96). + */ + const uint32_t lan_wake_mask = 1U << (GPE0_LAN_WAK - 96); + + /* Clear any pending LAN_WAKE event to avoid immediate wake. */ + outl(lan_wake_mask, ACPI_BASE_ADDRESS + GPE0_STS(GPE_STD)); + pmc_enable_std_gpe(lan_wake_mask); + outl(lan_wake_mask, ACPI_BASE_ADDRESS + GPE0_STS(GPE_STD)); +} diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb b/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb index ec5d3c03e9..0ea50a4f36 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb +++ b/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb @@ -156,7 +156,7 @@ chip soc/intel/alderlake }" chip drivers/pcie/generic register "wake_gpe" = "GPE0_LAN_WAK" - register "wake_deepest" = "ACPI_S3" + register "wake_deepest" = "ACPI_S5" device generic 0 on end end smbios_slot_desc "SlotTypePciExpressGen4x1" @@ -174,7 +174,7 @@ chip soc/intel/alderlake }" chip drivers/pcie/generic register "wake_gpe" = "GPE0_LAN_WAK" - register "wake_deepest" = "ACPI_S3" + register "wake_deepest" = "ACPI_S5" device generic 0 on end end smbios_slot_desc "SlotTypePciExpressGen3X4" From dd817408e127105da1fd68e078d73fc523549a9e Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 13 Feb 2025 13:03:37 +0100 Subject: [PATCH 325/789] device/pci_device: Fix leftover devices Don't print leftover devices when they are disabled in the devicetree. It's expected to not find a device when it's not enabled. Change-Id: Ia6e998d3088fbd329f976e66a92e08ecae9f760a Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/86491 Tested-by: build bot (Jenkins) Reviewed-by: Sean Rhodes Reviewed-by: Maximilian Brune Reviewed-by: Paul Menzel --- src/device/pci_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/pci_device.c b/src/device/pci_device.c index 202e8b5055..d7f6a3ad34 100644 --- a/src/device/pci_device.c +++ b/src/device/pci_device.c @@ -1442,7 +1442,7 @@ void pci_scan_bus(struct bus *bus, unsigned int min_devfn, * and it has a Vendor ID of 0 (the default for a device that * could not be probed). */ - if (dev->vendor != 0 || dev->hidden) { + if (dev->vendor != 0 || dev->hidden || !dev->enabled) { prev = &dev->sibling; continue; } From 37fee37ceab25dae8b1e9d9ebffedcc00b1e7420 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Wed, 28 Jan 2026 22:23:40 +0000 Subject: [PATCH 326/789] Revert "ec/starlabs/merlin: Add retry to get_ec_version()" This reverts commit 60c8496afe6e43901c774ac180965125c805fbc4. The reason for needing that was the EC initialising PM1DO to 0 on reset, which set the OBF flag, leading to coreboot consuming 0 on it's first read. This issue has now been fixed, so the rety is no longer needed. Change-Id: I87b779e3859daecfe6285cd499e8d6b61cdbb852 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90979 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/ec/starlabs/merlin/ite.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ec/starlabs/merlin/ite.c b/src/ec/starlabs/merlin/ite.c index ec4c9a65ab..953c9e3de6 100644 --- a/src/ec/starlabs/merlin/ite.c +++ b/src/ec/starlabs/merlin/ite.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include -#include #include #include #include @@ -18,9 +17,6 @@ uint16_t ec_get_version(void) { - for (int i = 0; i < 10 && ec_read(ECRAM_MAJOR_VERSION) == 0; i++) - mdelay(10); - return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION); } From 56403e52a130e3c318c0a9e9e3a89fb6ef1f2e18 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 20 Jan 2026 12:15:00 +0000 Subject: [PATCH 327/789] mb/starlabs/*: Expose BIOS Lock option Expose BIOS Lock option in CFR, that controls SMM BIOS Write Protection. Change-Id: I327881785d3292d8fd4805f5dd5ac0f2f0ed32dd Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90810 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/byte_adl/cfr.c | 1 + src/mainboard/starlabs/common/Kconfig | 6 ++++++ src/mainboard/starlabs/lite/cfr.c | 1 + src/mainboard/starlabs/starbook/cfr.c | 1 + src/mainboard/starlabs/starfighter/cfr.c | 1 + src/mainboard/starlabs/starlite_adl/cfr.c | 1 + 6 files changed, 11 insertions(+) diff --git a/src/mainboard/starlabs/byte_adl/cfr.c b/src/mainboard/starlabs/byte_adl/cfr.c index e80108ba42..d67d501508 100644 --- a/src/mainboard/starlabs/byte_adl/cfr.c +++ b/src/mainboard/starlabs/byte_adl/cfr.c @@ -50,6 +50,7 @@ static struct sm_obj_form devices_group = { static struct sm_obj_form security_group = { .ui_name = "Security", .obj_list = (const struct sm_object *[]) { + &bios_lock, &intel_tme, NULL }, diff --git a/src/mainboard/starlabs/common/Kconfig b/src/mainboard/starlabs/common/Kconfig index a59bc86dcf..e4361dea5f 100644 --- a/src/mainboard/starlabs/common/Kconfig +++ b/src/mainboard/starlabs/common/Kconfig @@ -4,6 +4,12 @@ if VENDOR_STARLABS menu "Star Labs Settings" +config BOOTMEDIA_SMM_BWP + default y + +config BOOTMEDIA_SMM_BWP_RUNTIME_OPTION + default y + config DRIVERS_EFI_FW_INFO default y diff --git a/src/mainboard/starlabs/lite/cfr.c b/src/mainboard/starlabs/lite/cfr.c index 81d236ea86..0ca59b8e48 100644 --- a/src/mainboard/starlabs/lite/cfr.c +++ b/src/mainboard/starlabs/lite/cfr.c @@ -57,6 +57,7 @@ static struct sm_obj_form devices_group = { static struct sm_obj_form security_group = { .ui_name = "Security", .obj_list = (const struct sm_object *[]) { + &bios_lock, &intel_tme, NULL }, diff --git a/src/mainboard/starlabs/starbook/cfr.c b/src/mainboard/starlabs/starbook/cfr.c index d317d2e531..f95ff65cb3 100644 --- a/src/mainboard/starlabs/starbook/cfr.c +++ b/src/mainboard/starlabs/starbook/cfr.c @@ -87,6 +87,7 @@ static struct sm_obj_form devices_group = { static struct sm_obj_form security_group = { .ui_name = "Security", .obj_list = (const struct sm_object *[]) { + &bios_lock, &intel_tme, NULL }, diff --git a/src/mainboard/starlabs/starfighter/cfr.c b/src/mainboard/starlabs/starfighter/cfr.c index 45df94c424..dc306f5776 100644 --- a/src/mainboard/starlabs/starfighter/cfr.c +++ b/src/mainboard/starlabs/starfighter/cfr.c @@ -77,6 +77,7 @@ static struct sm_obj_form devices_group = { static struct sm_obj_form security_group = { .ui_name = "Security", .obj_list = (const struct sm_object *[]) { + &bios_lock, &intel_tme, NULL }, diff --git a/src/mainboard/starlabs/starlite_adl/cfr.c b/src/mainboard/starlabs/starlite_adl/cfr.c index 62370cfc2d..9526992fd5 100644 --- a/src/mainboard/starlabs/starlite_adl/cfr.c +++ b/src/mainboard/starlabs/starlite_adl/cfr.c @@ -78,6 +78,7 @@ static struct sm_obj_form devices_group = { static struct sm_obj_form security_group = { .ui_name = "Security", .obj_list = (const struct sm_object *[]) { + &bios_lock, &intel_tme, NULL }, From 8ec0dc7356da2addf487f5a18f790ac0cb5395c9 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Wed, 28 Jan 2026 11:11:12 +0100 Subject: [PATCH 328/789] soc/intel/common/block/cpu/smmrelocate: Fix regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix regression introduced by commit d18cc50e6ab2 ("soc/intel/xeon_sp: Use common smm_relocate"). The MSR SMM_FEATURE_CONTROL_MSR is only implemented on client SoCs. Starting from Haswell server onwards the "SMM feature control" on server platforms resides on the UBOX in PCI space. Parallel SMM relocation was never supported on server platforms, thus disable parallel SMM relocation for now and thus fix booting on all Xeon-SP platforms. Added a FIXME to possibly implement this feature in the future. TEST=Can boot on OCP/tiogapass again. Change-Id: I7b4fbe633046acbf9f921cca722ff343a64962cd Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/90970 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons Reviewed-by: Jérémy Compostella Reviewed-by: Maximilian Brune --- src/soc/intel/common/block/cpu/smmrelocate.c | 9 +++++++++ src/soc/intel/snowridge/include/soc/msr.h | 8 -------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/soc/intel/common/block/cpu/smmrelocate.c b/src/soc/intel/common/block/cpu/smmrelocate.c index 8c45c218b2..e510c96f99 100644 --- a/src/soc/intel/common/block/cpu/smmrelocate.c +++ b/src/soc/intel/common/block/cpu/smmrelocate.c @@ -78,6 +78,15 @@ static int bsp_setup_msr_save_state(struct smm_relocation_params *relo_params) { msr_t smm_mca_cap; + /* + * FIXME: On Xeon-SP the MSR SMM_FEATURE_CONTROL_MSR is not implemented. + * SMM feature control resides on the UBOX PCI device. + * FIXME: Need to enable save state in MSRs on all sockets, however BSP + * runs on a single socket only. + */ + if (CONFIG(XEON_SP_COMMON_BASE) || CONFIG(SOC_INTEL_SNOWRIDGE)) + return 0; + smm_mca_cap = rdmsr(SMM_MCA_CAP_MSR); if (smm_mca_cap.hi & SMM_CPU_SVRSTR_MASK) { msr_t smm_feature_control; diff --git a/src/soc/intel/snowridge/include/soc/msr.h b/src/soc/intel/snowridge/include/soc/msr.h index b45050b794..45bf831290 100644 --- a/src/soc/intel/snowridge/include/soc/msr.h +++ b/src/soc/intel/snowridge/include/soc/msr.h @@ -5,14 +5,6 @@ #include -/** - * @brief Force serialized SMM relocation by hardcoding `SMM_CPU_SVRSTR` feature as not supported. - */ -#ifdef SMM_CPU_SVRSTR_MASK -#undef SMM_CPU_SVRSTR_MASK -#endif -#define SMM_CPU_SVRSTR_MASK 0 - #define MSR_BIOS_DONE 0x151 #define ENABLE_IA_UNTRUSTED BIT(0) From 8ade2c8239c9fe84900bd8d8a8b236e5991b257e Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 28 Jan 2026 13:21:20 +0530 Subject: [PATCH 329/789] mb/google/fatcat/var/lapis: Remove redundant splash logo alignment This patch removes logo_valignment from overridetree.cb. The alignment `FW_SPLASH_VALIGNMENT_CENTER` is the default behavior in the coreboot splash driver, making this explicit assignment unnecessary. BUG=none TEST=Build and boot lapis; verify logo remains centered. Change-Id: Ibf3ea2a9843b31f39fd08621f6056e63c2676ff7 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90965 Reviewed-by: YH Lin Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N Reviewed-by: Avi Uday Reviewed-by: Kapil Porwal --- src/mainboard/google/fatcat/variants/lapis/overridetree.cb | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mainboard/google/fatcat/variants/lapis/overridetree.cb b/src/mainboard/google/fatcat/variants/lapis/overridetree.cb index 3d7e53aba5..930a464fbf 100644 --- a/src/mainboard/google/fatcat/variants/lapis/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/lapis/overridetree.cb @@ -111,7 +111,6 @@ chip soc/intel/pantherlake #| I2C3 | cr50 TPM. | #+-------------------+---------------------------+ register "common_soc_config" = "{ - .logo_valignment = FW_SPLASH_VALIGNMENT_MIDDLE, .i2c[3] = { .early_init=1, .speed = I2C_SPEED_FAST, From 85e59e87e9a583db1266f51b872823dd44606a0c Mon Sep 17 00:00:00 2001 From: Anand Vaikar Date: Tue, 27 Jan 2026 15:54:46 +0530 Subject: [PATCH 330/789] soc/amd/common/block/apob: Fix APOB data hash mismatch issue In the first boot after coreboot is flashed, ABL FW performs memory training and passes APOB data to coreboot. coreboot writes APOB data in SPI flash along with hash of the APOB data. If APOB signature is not written in CMOS, Memory context is not restored by ABL in subsequent boot and full training is initiated which increases boot time.coreboot keeps writing the APOB data to flash in every boot due to hash mismatch of APOB data which inturn increases boot time.This change fixes the issue of ABL FW not doing Memory Context restore due to missing CMOS signature.On some older platforms FSP writes this signature unconditionally and hence this coreboot patch doesnt impact the older platforms. TEST= Validated on crater platform. APOB write is not initiated by coreboot on every boot. APOB write to flash happens only once after the coreboot flash. Change-Id: Id799d0d2ed9f54e29db7681509f3d66c1638b6ac Signed-off-by: Anand Vaikar Reviewed-on: https://review.coreboot.org/c/coreboot/+/90947 Reviewed-by: Felix Held Tested-by: build bot (Jenkins) --- src/soc/amd/common/block/apob/apob_cache.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/soc/amd/common/block/apob/apob_cache.c b/src/soc/amd/common/block/apob/apob_cache.c index d70adfc5b2..d9a7067683 100644 --- a/src/soc/amd/common/block/apob/apob_cache.c +++ b/src/soc/amd/common/block/apob/apob_cache.c @@ -17,6 +17,7 @@ #include #include #include +#include #define DEFAULT_MRC_CACHE "RW_MRC_CACHE" #define DEFAULT_MRC_CACHE_SIZE FMAP_SECTION_RW_MRC_CACHE_SIZE @@ -272,6 +273,10 @@ static void soc_update_apob_cache(void *unused) if (CONFIG(SOC_AMD_COMMON_BLOCK_APOB_HASH)) update_apob_nv_hash(ram_hash, &write_rdev); + // update the signature in CMOS to indicate APOB updated. + cmos_write(0x5A, 0x86); + cmos_write(0xA5, 0x87); + timestamp_add_now(TS_AMD_APOB_END); printk(BIOS_INFO, "Updated APOB in flash\n"); From e464a02635f2bcd3833711e09f07f9426e4b620f Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Tue, 27 Jan 2026 18:15:22 -0600 Subject: [PATCH 331/789] ec/google/chromeec: Add Kconfig to enable battery full workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 55a972236ee9 ("chromeec: Disable battery remaining capacity workaround") disabled the workaround for all ChromeEC devices, since newer EC firmware applies compensation via battery_compensate_params. Older boards use EC branches that lack this logic; without it, users can see 93–100% charge–discharge cycling and stale full-capacity reporting. Add a Kconfig to configure the workaround, and select it for older boards whose EC firmware lacks battery_compensate_params logic. EC firmware branches were inspected to determine which ones lack this logic. TEST=build/boot google/lulu, verify battery full indication works correctly with the Kconfig selected. Change-Id: I096e0cf402e07f846b961319e01fb8f2c2dde7fc Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/90960 Reviewed-by: Caveh Jalali Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/ec/google/chromeec/Kconfig | 11 +++++++++++ src/ec/google/chromeec/acpi/battery.asl | 10 ++++++---- src/mainboard/google/auron/Kconfig | 1 + src/mainboard/google/cyan/Kconfig | 1 + src/mainboard/google/eve/Kconfig | 1 + src/mainboard/google/glados/Kconfig | 1 + src/mainboard/google/link/Kconfig | 1 + src/mainboard/google/poppy/Kconfig | 1 + src/mainboard/google/rambi/Kconfig | 1 + src/mainboard/google/reef/Kconfig | 1 + src/mainboard/google/slippy/Kconfig | 1 + 11 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/ec/google/chromeec/Kconfig b/src/ec/google/chromeec/Kconfig index 0239a08904..b09c64a88c 100644 --- a/src/ec/google/chromeec/Kconfig +++ b/src/ec/google/chromeec/Kconfig @@ -220,6 +220,17 @@ config EC_GOOGLE_CHROMEEC_READ_BATTERY_LONG_STRING If unsure, say N. +config EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND + bool + help + Enable the ACPI "full battery" workaround (BFWK) for remaining capacity. + When enabled, remaining charge near full is reported as full capacity to + hide 93-100% charge-discharge cycles and to handle batteries that don't report + full capacity timely. + Select this for older boards whose EC firmware lacks battery_compensate_params + logic. + If unsure, say N. + config EC_GOOGLE_CHROMEEC_LPC_GENERIC_MEMORY_RANGE def_bool n help diff --git a/src/ec/google/chromeec/acpi/battery.asl b/src/ec/google/chromeec/acpi/battery.asl index 41b77861a5..eb19c3c422 100644 --- a/src/ec/google/chromeec/acpi/battery.asl +++ b/src/ec/google/chromeec/acpi/battery.asl @@ -414,8 +414,9 @@ Device (BAT0) }) Name (BSTP, 0) - // Workaround for full battery status, disabled by default - Name (BFWK, 0) + // Workaround for full battery status, disabled by default, + // enabled via Kconfig for older boards lacking EC compensation. + Name (BFWK, CONFIG(EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND)) // Method to enable full battery workaround Method (BFWE) @@ -504,8 +505,9 @@ Device (BAT1) }) Name (BSTP, 0) - // Workaround for full battery status, disabled by default - Name (BFWK, 0) + // Workaround for full battery status, disabled by default, + // enabled via Kconfig for older boards lacking EC compensation. + Name (BFWK, CONFIG(EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND)) // Method to enable full battery workaround Method (BFWE) diff --git a/src/mainboard/google/auron/Kconfig b/src/mainboard/google/auron/Kconfig index b84708f657..a9039912db 100644 --- a/src/mainboard/google/auron/Kconfig +++ b/src/mainboard/google/auron/Kconfig @@ -9,6 +9,7 @@ config BOARD_GOOGLE_BASEBOARD_AURON select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_LPC + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_OPTION_TABLE diff --git a/src/mainboard/google/cyan/Kconfig b/src/mainboard/google/cyan/Kconfig index fe4d2a1067..bda0416172 100644 --- a/src/mainboard/google/cyan/Kconfig +++ b/src/mainboard/google/cyan/Kconfig @@ -8,6 +8,7 @@ config BOARD_GOOGLE_BASEBOARD_CYAN select EC_GOOGLE_CHROMEEC_BOARDID select EC_GOOGLE_CHROMEEC_LPC select EC_GOOGLE_CHROMEEC_MEC + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_OPTION_TABLE diff --git a/src/mainboard/google/eve/Kconfig b/src/mainboard/google/eve/Kconfig index 40eebc5c50..b473d502bf 100644 --- a/src/mainboard/google/eve/Kconfig +++ b/src/mainboard/google/eve/Kconfig @@ -15,6 +15,7 @@ config BOARD_SPECIFIC_OPTIONS select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_BOARDID select EC_GOOGLE_CHROMEEC_ESPI + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select I2C_TPM diff --git a/src/mainboard/google/glados/Kconfig b/src/mainboard/google/glados/Kconfig index 811a03deac..6786d1b5f1 100644 --- a/src/mainboard/google/glados/Kconfig +++ b/src/mainboard/google/glados/Kconfig @@ -10,6 +10,7 @@ config BOARD_GOOGLE_BASEBOARD_GLADOS select EC_GOOGLE_CHROMEEC_BOARDID select EC_GOOGLE_CHROMEEC_LPC select EC_GOOGLE_CHROMEEC_MEC + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select EC_GOOGLE_CHROMEEC_PD select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES diff --git a/src/mainboard/google/link/Kconfig b/src/mainboard/google/link/Kconfig index 86dd014f2a..df85382246 100644 --- a/src/mainboard/google/link/Kconfig +++ b/src/mainboard/google/link/Kconfig @@ -10,6 +10,7 @@ config BOARD_SPECIFIC_OPTIONS select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_AUTO_FAN_CTRL + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select EC_GOOGLE_CHROMEEC_LPC select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES diff --git a/src/mainboard/google/poppy/Kconfig b/src/mainboard/google/poppy/Kconfig index a9b45920db..ac9aa54e56 100644 --- a/src/mainboard/google/poppy/Kconfig +++ b/src/mainboard/google/poppy/Kconfig @@ -73,6 +73,7 @@ config BOARD_GOOGLE_NOCTURNE select DRIVERS_I2C_SX9310 select DRIVERS_SPI_ACPI select DRIVERS_USB_ACPI + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select EXCLUDE_NATIVE_SD_INTERFACE select GEO_SAR_ENABLE if CHROMEOS_WIFI_SAR select INTEL_GMA_HAVE_VBT diff --git a/src/mainboard/google/rambi/Kconfig b/src/mainboard/google/rambi/Kconfig index 750eba1e30..ccdc02a45c 100644 --- a/src/mainboard/google/rambi/Kconfig +++ b/src/mainboard/google/rambi/Kconfig @@ -6,6 +6,7 @@ config BOARD_GOOGLE_BASEBOARD_RAMBI select BOARD_ROMSIZE_KB_8192 select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_LPC + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select ENABLE_BUILTIN_COM1 if CONSOLE_SERIAL select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES diff --git a/src/mainboard/google/reef/Kconfig b/src/mainboard/google/reef/Kconfig index 06c5575e45..1ce2353432 100644 --- a/src/mainboard/google/reef/Kconfig +++ b/src/mainboard/google/reef/Kconfig @@ -10,6 +10,7 @@ config BOARD_GOOGLE_BASEBOARD_REEF select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_BOARDID + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select EC_GOOGLE_CHROMEEC_LPC select GOOGLE_SMBIOS_MAINBOARD_VERSION select HAVE_ACPI_RESUME diff --git a/src/mainboard/google/slippy/Kconfig b/src/mainboard/google/slippy/Kconfig index d9684d34b3..380ed9fe72 100644 --- a/src/mainboard/google/slippy/Kconfig +++ b/src/mainboard/google/slippy/Kconfig @@ -8,6 +8,7 @@ config BOARD_GOOGLE_BASEBOARD_SLIPPY select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_LPC + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_OPTION_TABLE From 1658fb98932e038a6b42724b07ced5da57fd4213 Mon Sep 17 00:00:00 2001 From: Maximilian Brune Date: Tue, 20 Jan 2026 17:30:52 +0100 Subject: [PATCH 332/789] treewide: Use __printf macro instead of "__attribute__(format(printf" Using this, the compiler is going to check if the printf formatting is correct for our printk messages. Since we already have the macro, might as well use it. Signed-off-by: Maximilian Brune Change-Id: I247f24ed64c2be7fc411f5e2fdd38715698bc4e3 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90829 Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) --- payloads/libpayload/include/stdio.h | 12 ++++-------- payloads/libpayload/include/usb/usb.h | 2 +- src/include/console/console.h | 6 ++---- util/cbfstool/flashmap/kv_pair.h | 2 +- util/vgabios/include/console/console.h | 2 +- 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/payloads/libpayload/include/stdio.h b/payloads/libpayload/include/stdio.h index ced4d19b99..d19d3aa847 100644 --- a/payloads/libpayload/include/stdio.h +++ b/payloads/libpayload/include/stdio.h @@ -41,14 +41,10 @@ extern FILE *stdout, *stdin, *stderr; * @defgroup printf Print functions * @{ */ -int snprintf(char *str, size_t size, const char *fmt, ...) - __attribute__((format (printf, 3, 4))); -int sprintf(char *str, const char *fmt, ...) - __attribute__((format (printf, 2, 3))); -int printf(const char *fmt, ...) - __attribute__((format (printf, 1, 2))); -int fprintf(FILE *file, const char *fmt, ...) - __attribute__((format (printf, 2, 3))); +int snprintf(char *str, size_t size, const char *fmt, ...) __printf(3, 4); +int sprintf(char *str, const char *fmt, ...) __printf(2, 3); +int printf(const char *fmt, ...) __printf(1, 2); +int fprintf(FILE *file, const char *fmt, ...) __printf(2, 3); /** @} */ void perror(const char *s); diff --git a/payloads/libpayload/include/usb/usb.h b/payloads/libpayload/include/usb/usb.h index f36bb5c5be..9e929e59c8 100644 --- a/payloads/libpayload/include/usb/usb.h +++ b/payloads/libpayload/include/usb/usb.h @@ -344,7 +344,7 @@ int usb_interface_check(u16 vendor, u16 device); #define USB_QUIRK_TEST (1 << 31) #define USB_QUIRK_NONE 0 -static inline void __attribute__((format(printf, 1, 2))) usb_debug(const char *fmt, ...) +static inline void __printf(1, 2) usb_debug(const char *fmt, ...) { #ifdef USB_DEBUG va_list ap; diff --git a/src/include/console/console.h b/src/include/console/console.h index 927b1d6ef0..a24425935c 100644 --- a/src/include/console/console.h +++ b/src/include/console/console.h @@ -53,7 +53,7 @@ int get_log_level(void); void console_init(void); int console_log_level(int msg_level); -int printk(int msg_level, const char *fmt, ...) __attribute__((format(printf, 2, 3))); +int printk(int msg_level, const char *fmt, ...) __printf(2, 3); int vprintk(int msg_level, const char *fmt, va_list args); void do_putchar(unsigned char byte); @@ -80,9 +80,7 @@ enum { CONSOLE_LOG_NONE = 0, CONSOLE_LOG_FAST, CONSOLE_LOG_ALL }; static inline int get_log_level(void) { return -1; } static inline void console_init(void) {} static inline int console_log_level(int msg_level) { return 0; } -static inline int - __attribute__((format(printf, 2, 3))) - printk(int LEVEL, const char *fmt, ...) { return 0; } +static inline int __printf(2, 3) printk(int LEVEL, const char *fmt, ...) { return 0; } static inline int vprintk(int LEVEL, const char *fmt, va_list args) { return 0; } static inline void do_putchar(unsigned char byte) {} static inline long console_time_get_and_reset(void) { return 0; } diff --git a/util/cbfstool/flashmap/kv_pair.h b/util/cbfstool/flashmap/kv_pair.h index 5771570743..a582ff764d 100644 --- a/util/cbfstool/flashmap/kv_pair.h +++ b/util/cbfstool/flashmap/kv_pair.h @@ -78,7 +78,7 @@ extern struct kv_pair *kv_pair_fmt(struct kv_pair *kv_list, #if defined(_WIN32) || (_WIN64) __attribute__((format(gnu_printf, 3, 4))); #else - __attribute__((format(printf, 3, 4))); + __printf(3, 4); #endif /* diff --git a/util/vgabios/include/console/console.h b/util/vgabios/include/console/console.h index 0aa5595590..edad4d084b 100644 --- a/util/vgabios/include/console/console.h +++ b/util/vgabios/include/console/console.h @@ -3,6 +3,6 @@ #ifndef _CONSOLE_CONSOLE_H #define _CONSOLE_CONSOLE_H -int printk(int msg_level, const char *fmt, ...) __attribute__((format(printf, 2, 3))); +int printk(int msg_level, const char *fmt, ...) __printf(2, 3); #endif From 9ae5af54cc990d6f7e33eae2a56177024d2251c2 Mon Sep 17 00:00:00 2001 From: Mario Scheithauer Date: Tue, 27 Jan 2026 10:04:08 +0100 Subject: [PATCH 333/789] soc/intel/jasperlake: Move PCIe ModPHY parameter to common pcie_rp.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the ModPHY settings are also available on other Intel platforms, these parameters should be moved to common code. Change-Id: Ic2666c7bbd576681dea7f360c396c068b42306e2 Signed-off-by: Mario Scheithauer Reviewed-on: https://review.coreboot.org/c/coreboot/+/90943 Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) --- .../block/include/intelblocks/pcie_rp.h | 20 +++++++++++++++- src/soc/intel/jasperlake/chip.h | 1 - .../jasperlake/include/soc/pcie_modphy.h | 24 ------------------- 3 files changed, 19 insertions(+), 26 deletions(-) delete mode 100644 src/soc/intel/jasperlake/include/soc/pcie_modphy.h diff --git a/src/soc/intel/common/block/include/intelblocks/pcie_rp.h b/src/soc/intel/common/block/include/intelblocks/pcie_rp.h index 68137490b9..9538e3bf06 100644 --- a/src/soc/intel/common/block/include/intelblocks/pcie_rp.h +++ b/src/soc/intel/common/block/include/intelblocks/pcie_rp.h @@ -3,7 +3,7 @@ #ifndef SOC_INTEL_COMMON_BLOCK_PCIE_RP_H #define SOC_INTEL_COMMON_BLOCK_PCIE_RP_H -#include +#include /* * In schematic PCIe root port numbers are 1-based, but FSP use 0-based indexes for @@ -85,6 +85,24 @@ struct pcie_rp_config { enum PCIE_SPEED_control pcie_rp_pcie_speed; }; +struct pcie_modphy_config { + /* TX Output Downscale Amplitude Adjustment */ + bool tx_gen1_downscale_amp_override; + uint8_t tx_gen1_downscale_amp; + /* TX Output Downscale Amplitude Adjustment */ + bool tx_gen2_downscale_amp_override; + uint8_t tx_gen2_downscale_amp; + /* TX Output Downscale Amplitude Adjustment */ + bool tx_gen3_downscale_amp_override; + uint8_t tx_gen3_downscale_amp; + /* TX Output -3.5dB Mode De-Emphasis Adjustment Setting */ + uint8_t tx_gen1_de_emph; + /* TX Output -3.5dB Mode De-Emphasis Adjustment Setting */ + uint8_t tx_gen2_de_emph_3p5; + /* TX Output -6.0dB Mode De-Emphasis Adjustment Setting */ + uint8_t tx_gen2_de_emph_6p0; +}; + /* * The PCIe Root Ports usually come in groups of up to 8 PCI-device * functions. diff --git a/src/soc/intel/jasperlake/chip.h b/src/soc/intel/jasperlake/chip.h index 380549451e..3fdf82db97 100644 --- a/src/soc/intel/jasperlake/chip.h +++ b/src/soc/intel/jasperlake/chip.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/src/soc/intel/jasperlake/include/soc/pcie_modphy.h b/src/soc/intel/jasperlake/include/soc/pcie_modphy.h deleted file mode 100644 index 60f145195f..0000000000 --- a/src/soc/intel/jasperlake/include/soc/pcie_modphy.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _SOC_JASPERLAKE_PCIE_MODPHY_H_ -#define _SOC_JASPERLAKE_PCIE_MODPHY_H_ - -struct pcie_modphy_config { - /* TX Output Downscale Amplitude Adjustment */ - bool tx_gen1_downscale_amp_override; - uint8_t tx_gen1_downscale_amp; - /* TX Output Downscale Amplitude Adjustment */ - bool tx_gen2_downscale_amp_override; - uint8_t tx_gen2_downscale_amp; - /* TX Output Downscale Amplitude Adjustment */ - bool tx_gen3_downscale_amp_override; - uint8_t tx_gen3_downscale_amp; - /* TX Output -3.5dB Mode De-Emphasis Adjustment Setting */ - uint8_t tx_gen1_de_emph; - /* TX Output -3.5dB Mode De-Emphasis Adjustment Setting */ - uint8_t tx_gen2_de_emph_3p5; - /* TX Output -6.0dB Mode De-Emphasis Adjustment Setting */ - uint8_t tx_gen2_de_emph_6p0; -}; - -#endif From 388fb318add4257a74714e11b670a53aa367fe02 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 3 Nov 2025 18:40:45 -0600 Subject: [PATCH 334/789] soc/intel/common: Add opt-in runtime control for BIOS SMM write protection Add support for runtime control of BIOS lock (BOOTMEDIA_SMM_BWP) via the CFR option API. This allows users to enable/disable BIOS write protection in SMM through the setup menu when explicitly enabled. The implementation adds a new "bios_lock" CFR option that: - Controls SMM BIOS write protection at runtime - Sets EISS (Enable InSMM.STS) when enabled - Enables SPI/LPC write protection in SMM - Prevents unauthorised BIOS modifications outside SMM Security model: - Runtime control is opt-in via BOOTMEDIA_SMM_BWP_RUNTIME_OPTION config - When disabled, the option is suppressed in CFR (not exposed in UI) - Compile-time CONFIG(BOOTMEDIA_SMM_BWP) serves as the default/fallback - Protects against unauthorised EFI variable modifications, bypassing BIOS lock when the runtime option is not enabled The option is integrated into Intel's common lockdown code and SMI handlers, replacing compile-time-only checks with conditional runtime lookups where BOOTMEDIA_SMM_BWP_RUNTIME_OPTION is enabled. Change-Id: Ie3b63462501e0d204c33dc3f8a006b73da0899d3 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/89919 Reviewed-by: Werner Zeh Tested-by: build bot (Jenkins) --- src/security/lockdown/Kconfig | 8 ++++++++ src/security/lockdown/lockdown.h | 16 ++++++++++++++++ .../common/block/include/intelblocks/cfr.h | 19 +++++++++++++++++++ src/soc/intel/common/block/smm/smihandler.c | 6 ++++-- src/soc/intel/common/pch/lockdown/lockdown.c | 6 ++++-- src/southbridge/intel/common/finalize.c | 4 +++- src/southbridge/intel/common/spi.c | 4 +++- 7 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 src/security/lockdown/lockdown.h diff --git a/src/security/lockdown/Kconfig b/src/security/lockdown/Kconfig index 95a768a148..ec76cea213 100644 --- a/src/security/lockdown/Kconfig +++ b/src/security/lockdown/Kconfig @@ -107,6 +107,14 @@ config BOOTMEDIA_SMM_BWP while also preventing unauthorized writes through the internal controller. Note that this breaks flashconsole, since the flash becomes read-only. +config BOOTMEDIA_SMM_BWP_RUNTIME_OPTION + bool "Boot media only writable in SMM can be controlled via option API" + depends on BOOTMEDIA_SMM_BWP + depends on DRIVERS_OPTION_CFR + help + Provide a runtime option "bios_lock" to enable or disable SMM BIOS Write Protection + via the option API. + choice prompt "SPI Flash write protection duration" default BOOTMEDIA_SPI_LOCK_REBOOT diff --git a/src/security/lockdown/lockdown.h b/src/security/lockdown/lockdown.h new file mode 100644 index 0000000000..b81e636c32 --- /dev/null +++ b/src/security/lockdown/lockdown.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef SECURITY_LOCKDOWN_LOCKDOWN_H +#define SECURITY_LOCKDOWN_LOCKDOWN_H + +#include +#include + +static inline bool enable_smm_bios_protection(void) +{ + if (CONFIG(BOOTMEDIA_SMM_BWP_RUNTIME_OPTION)) + return get_uint_option("bios_lock", CONFIG(BOOTMEDIA_SMM_BWP)); + return CONFIG(BOOTMEDIA_SMM_BWP); +} + +#endif /* SECURITY_LOCKDOWN_LOCKDOWN_H */ diff --git a/src/soc/intel/common/block/include/intelblocks/cfr.h b/src/soc/intel/common/block/include/intelblocks/cfr.h index 15dcacab23..e31af7f4c9 100644 --- a/src/soc/intel/common/block/include/intelblocks/cfr.h +++ b/src/soc/intel/common/block/include/intelblocks/cfr.h @@ -150,5 +150,24 @@ static const struct sm_object intel_tme = SM_DECLARE_BOOL({ .default_value = CONFIG(INTEL_TME), }, WITH_CALLBACK(update_intel_tme)); +/* BIOS Lock */ +static void update_smm_bwp(struct sm_object *new) +{ + if (!CONFIG(BOOTMEDIA_SMM_BWP_RUNTIME_OPTION)) + new->sm_bool.flags |= CFR_OPTFLAG_SUPPRESS; +} + +static const struct sm_object bios_lock = SM_DECLARE_ENUM({ + .opt_name = "bios_lock", + .ui_name = "BIOS Lock", + .ui_helptext = "Enable BIOS write protection in SMM. When enabled, the boot media" + " (SPI flash) is only writable in System Management Mode, preventing" + " unauthorized writes through the internal controller.", + .default_value = CONFIG(BOOTMEDIA_SMM_BWP), + .values = (const struct sm_enum_value[]) { + { "Disabled", false }, + { "Enabled", true }, + SM_ENUM_VALUE_END }, +}, WITH_CALLBACK(update_smm_bwp)); #endif /* SOC_INTEL_CMN_CFR_H */ diff --git a/src/soc/intel/common/block/smm/smihandler.c b/src/soc/intel/common/block/smm/smihandler.c index cd78de26c3..1af03739d2 100644 --- a/src/soc/intel/common/block/smm/smihandler.c +++ b/src/soc/intel/common/block/smm/smihandler.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -352,7 +354,7 @@ static void finalize(void) /* Re-init SPI driver to handle locked BAR */ fast_spi_init(); - if (CONFIG(BOOTMEDIA_SMM_BWP)) { + if (enable_smm_bios_protection()) { fast_spi_enable_wp(); set_insmm_sts(false); } @@ -443,7 +445,7 @@ void smihandler_southbridge_tco( fast_spi_clear_sync_smi_status(); /* If enabled, enforce SMM BIOS write protection */ - if (CONFIG(BOOTMEDIA_SMM_BWP) && fast_spi_wpd_status()) { + if (enable_smm_bios_protection() && fast_spi_wpd_status()) { /* * BWE is RW, so the SMI was caused by a * write to BWE, not by a write to the BIOS diff --git a/src/soc/intel/common/pch/lockdown/lockdown.c b/src/soc/intel/common/pch/lockdown/lockdown.c index eec3beb01b..ff7ca959fc 100644 --- a/src/soc/intel/common/pch/lockdown/lockdown.c +++ b/src/soc/intel/common/pch/lockdown/lockdown.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -81,7 +83,7 @@ static void fast_spi_lockdown_cfg(int chipset_lockdown) fast_spi_set_bios_interface_lock_down(); /* Only allow writes in SMM */ - if (CONFIG(BOOTMEDIA_SMM_BWP)) { + if (enable_smm_bios_protection()) { fast_spi_set_eiss(); fast_spi_enable_wp(); } @@ -102,7 +104,7 @@ static void lpc_lockdown_config(int chipset_lockdown) lpc_set_bios_interface_lock_down(); /* Only allow writes in SMM */ - if (CONFIG(BOOTMEDIA_SMM_BWP)) { + if (enable_smm_bios_protection()) { lpc_set_eiss(); lpc_enable_wp(); } diff --git a/src/southbridge/intel/common/finalize.c b/src/southbridge/intel/common/finalize.c index 490bdae74e..759ab8ea2d 100644 --- a/src/southbridge/intel/common/finalize.c +++ b/src/southbridge/intel/common/finalize.c @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include #include @@ -45,7 +47,7 @@ void intel_pch_finalize_smm(void) pci_write_config32(PCI_DEV(0, 27, 0), 0x74, pci_read_config32(PCI_DEV(0, 27, 0), 0x74)); - if (CONFIG(BOOTMEDIA_SMM_BWP)) + if (enable_smm_bios_protection()) write_pmbase16(SMI_EN, read_pmbase16(SMI_EN) | TCO_EN); write_pmbase16(TCO1_CNT, read_pmbase16(TCO1_CNT) | TCO_LOCK); diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index bcdcaa9158..089e3ce234 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -1116,7 +1118,7 @@ void spi_finalize_ops(void) } writew_(optype, cntlr.optype); - spi_set_smm_only_flashing(CONFIG(BOOTMEDIA_SMM_BWP)); + spi_set_smm_only_flashing(enable_smm_bios_protection()); } __weak void intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config) From dd60a487631f683580736913ee8739f400659608 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Fri, 19 Dec 2025 20:41:38 +0000 Subject: [PATCH 335/789] mb/starlabs/adl: Add StarBook Horizon (N305) Tested using `edk2` from `https://github.com/starlabsltd/edk2/tree/uefipayload_vs`: * Ubuntu 24.04 * Manjaro 24 No known issues. https://starlabs.systems/pages/starbook-horizon-specification Change-Id: I7535bc5f49324027eacc9c2750a9abe742fee470 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/90570 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- Documentation/mainboard/index.md | 1 + .../mainboard/starlabs/adl_horizon.md | 86 ++++++ src/mainboard/starlabs/adl/Kconfig | 117 ++++++++ src/mainboard/starlabs/adl/Kconfig.name | 4 + src/mainboard/starlabs/adl/Makefile.mk | 10 + src/mainboard/starlabs/adl/acpi/ec.asl | 1 + src/mainboard/starlabs/adl/acpi/mainboard.asl | 5 + src/mainboard/starlabs/adl/acpi/sleep.asl | 11 + src/mainboard/starlabs/adl/acpi/superio.asl | 1 + src/mainboard/starlabs/adl/board_info.txt | 6 + src/mainboard/starlabs/adl/bootblock.c | 14 + src/mainboard/starlabs/adl/cfr.c | 109 +++++++ src/mainboard/starlabs/adl/cmos.default | 6 + src/mainboard/starlabs/adl/cmos.layout | 46 +++ src/mainboard/starlabs/adl/dsdt.asl | 47 ++++ src/mainboard/starlabs/adl/include/variants.h | 17 ++ src/mainboard/starlabs/adl/mainboard.c | 22 ++ src/mainboard/starlabs/adl/spd/Makefile.mk | 5 + .../adl/spd/rs4g32l05d8fdb-5500.spd.hex | 32 +++ .../adl/spd/rs4g32l05d8fdb-6400.spd.hex | 32 +++ .../adl/spd/rs4g32l05d8fdb-7500.spd.hex | 32 +++ .../starlabs/adl/variants/hz/Makefile.mk | 12 + .../starlabs/adl/variants/hz/board.fmd | 14 + .../starlabs/adl/variants/hz/data.vbt | Bin 0 -> 9216 bytes .../adl/variants/hz/data_native_res.vbt | Bin 0 -> 9216 bytes .../starlabs/adl/variants/hz/devicetree.cb | 240 ++++++++++++++++ .../starlabs/adl/variants/hz/devtree.c | 33 +++ src/mainboard/starlabs/adl/variants/hz/gpio.c | 266 ++++++++++++++++++ .../starlabs/adl/variants/hz/hda_verb.c | 97 +++++++ .../starlabs/adl/variants/hz/ramstage.c | 19 ++ .../starlabs/adl/variants/hz/romstage.c | 102 +++++++ src/mainboard/starlabs/adl/vboot.c | 8 + 32 files changed, 1395 insertions(+) create mode 100644 Documentation/mainboard/starlabs/adl_horizon.md create mode 100644 src/mainboard/starlabs/adl/Kconfig create mode 100644 src/mainboard/starlabs/adl/Kconfig.name create mode 100644 src/mainboard/starlabs/adl/Makefile.mk create mode 100644 src/mainboard/starlabs/adl/acpi/ec.asl create mode 100644 src/mainboard/starlabs/adl/acpi/mainboard.asl create mode 100644 src/mainboard/starlabs/adl/acpi/sleep.asl create mode 100644 src/mainboard/starlabs/adl/acpi/superio.asl create mode 100644 src/mainboard/starlabs/adl/board_info.txt create mode 100644 src/mainboard/starlabs/adl/bootblock.c create mode 100644 src/mainboard/starlabs/adl/cfr.c create mode 100644 src/mainboard/starlabs/adl/cmos.default create mode 100644 src/mainboard/starlabs/adl/cmos.layout create mode 100644 src/mainboard/starlabs/adl/dsdt.asl create mode 100644 src/mainboard/starlabs/adl/include/variants.h create mode 100644 src/mainboard/starlabs/adl/mainboard.c create mode 100644 src/mainboard/starlabs/adl/spd/Makefile.mk create mode 100644 src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-5500.spd.hex create mode 100644 src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-6400.spd.hex create mode 100644 src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-7500.spd.hex create mode 100644 src/mainboard/starlabs/adl/variants/hz/Makefile.mk create mode 100644 src/mainboard/starlabs/adl/variants/hz/board.fmd create mode 100644 src/mainboard/starlabs/adl/variants/hz/data.vbt create mode 100644 src/mainboard/starlabs/adl/variants/hz/data_native_res.vbt create mode 100644 src/mainboard/starlabs/adl/variants/hz/devicetree.cb create mode 100644 src/mainboard/starlabs/adl/variants/hz/devtree.c create mode 100644 src/mainboard/starlabs/adl/variants/hz/gpio.c create mode 100644 src/mainboard/starlabs/adl/variants/hz/hda_verb.c create mode 100644 src/mainboard/starlabs/adl/variants/hz/ramstage.c create mode 100644 src/mainboard/starlabs/adl/variants/hz/romstage.c create mode 100644 src/mainboard/starlabs/adl/vboot.c diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index de731f3048..92aec1173f 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -358,6 +358,7 @@ StarBook Mk V StarBook Mk VI StarBook Mk VII (N200) StarBook Mk VII (165H) +StarBook Horizon Byte Mk II StarFighter Mk I StarFighter Mk II diff --git a/Documentation/mainboard/starlabs/adl_horizon.md b/Documentation/mainboard/starlabs/adl_horizon.md new file mode 100644 index 0000000000..4d81b7f9fc --- /dev/null +++ b/Documentation/mainboard/starlabs/adl_horizon.md @@ -0,0 +1,86 @@ +# StarBook Mk V + +## Specs + +- CPU (full processor specs available at ) + - Intel N305 (Alder Lake) +- EC + - ITE IT5570E + - Backlit keyboard, with standard PS/2 keycodes and SCI hotkeys + - Battery + - USB-C PD Charger + - Suspend / resume +- GPU + - Intel® Iris® Xe Graphics + - GOP driver is recommended, VBT is provided + - eDP 13.4-inch 2520x1680 LCD + - HDMI video + - USB-C DisplayPort video +- Memory + - 32GB LPDD% on-board memory +- Networking + - AX210 2230 WiFi / Bluetooth +- Sound + - Realtek ALC269-VB6 + - Internal speakers + - Internal microphone + - Combined headphone / microphone 3.5-mm jack + - HDMI audio + - USB-C DisplayPort audio +- Storage + - M.2 PCIe SSD +- USB + - 1920x1080 CCD camera + - USB 3.1 Gen 2 (left) + - USB 3.1 Gen 2 (right) + - USB 3.1 Gen 2 Type-A (right) + +## Building coreboot + +Please follow the [Star Labs build instructions](common/building.md) to build coreboot, using `config.starlabs_adl_horizon` as config file. + +### Preliminaries + +Prior to building coreboot the following files are required: +* Intel Flash Descriptor file (descriptor.bin) +* Intel Management Engine firmware (me.bin) +* ITE Embedded Controller firmware (ec.bin) + +The files listed below are optional: +- Splash screen image in Windows 3.1 BMP format (Logo.bmp) + +These files exist in the correct location in the StarLabsLtd/blobs repo on GitHub which is used in place of the standard 3rdparty/blobs repo. + +### Build + +The following commands will build a working image: + +```bash +make distclean +make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_adl_horizon_n +make +``` + +## Flashing coreboot + +```{eval-rst} ++---------------------+------------+ +| Type | Value | ++=====================+============+ +| Socketed flash | no | ++---------------------+------------+ +| Vendor | Winbond | ++---------------------+------------+ +| Model | W25Q256.V | ++---------------------+------------+ +| Size | 32 MiB | ++---------------------+------------+ +| Package | WSON-8 | ++---------------------+------------+ +| Internal flashing | yes | ++---------------------+------------+ +| External flashing | yes | ++---------------------+------------+ +``` + +Please see [here](common/flashing.md) for instructions on how to flash with fwupd. diff --git a/src/mainboard/starlabs/adl/Kconfig b/src/mainboard/starlabs/adl/Kconfig new file mode 100644 index 0000000000..adfa25bb8d --- /dev/null +++ b/src/mainboard/starlabs/adl/Kconfig @@ -0,0 +1,117 @@ +config BOARD_STARLABS_ADL_SERIES + def_bool n + select AZALIA_USE_LEGACY_VERB_TABLE + select CSE_DEFAULT_CFR_OPTION_STATE_DISABLED + select DRIVERS_EFI_VARIABLE_STORE + select DRIVERS_GFX_GENERIC + select DRIVERS_I2C_HID + select DRIVERS_INTEL_PMC + select DRIVERS_OPTION_CFR_ENABLED + select EC_STARLABS_MERLIN + select HAVE_ACPI_RESUME + select HAVE_ACPI_TABLES + select HAVE_CMOS_DEFAULT + select HAVE_HDA_DMIC + select HAVE_OPTION_TABLE + select HAVE_SPD_IN_CBFS + select INTEL_GMA_HAVE_VBT + select INTEL_LPSS_UART_FOR_CONSOLE + select MAINBOARD_HAS_TPM2 + select MEMORY_MAPPED_TPM + select NO_UART_ON_SUPERIO + select PMC_IPC_ACPI_INTERFACE + select SOC_INTEL_ALDERLAKE + select SOC_INTEL_COMMON_BLOCK_HDA_VERB + select SOC_INTEL_COMMON_BLOCK_TCSS + select SOC_INTEL_CRASHLOG + select SPD_READ_BY_WORD + select SPI_FLASH_WINBOND + select SYSTEM_TYPE_LAPTOP + select TPM2 + select TPM_MEASURED_BOOT + select VALIDATE_INTEL_DESCRIPTOR + +config BOARD_STARLABS_ADL_HORIZON + select BOARD_ROMSIZE_KB_16384 + select BOARD_STARLABS_ADL_SERIES + select SOC_INTEL_ALDERLAKE_PCH_N + +if BOARD_STARLABS_ADL_HORIZON + +config CCD_PORT + int + default 4 + +config CONSOLE_SERIAL + default n if !EDK2_DEBUG + +config D3COLD_SUPPORT + default n + +config DEVICETREE + default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" + +config DIMM_SPD_SIZE + default 512 + +config EDK2_BOOTSPLASH_FILE + string + default "3rdparty/blobs/mainboard/starlabs/Logo.bmp" + +config EC_STARLABS_BATTERY_MODEL + default "U5266122PV-2S1P" + +config EC_STARLABS_BATTERY_TYPE + default "LION" + +config EC_STARLABS_BATTERY_OEM + default "Shenzhen Utility Energy Co., Ltd" + +config EC_STARLABS_ITE_BIN_PATH + string + default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/ec.bin" + +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" + +config IFD_BIN_PATH + string + default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/flashdescriptor.bin" + +config MAINBOARD_DIR + default "starlabs/adl" + +config MAINBOARD_FAMILY + string + default "HZ" + +config MAINBOARD_PART_NUMBER + default "StarBook Horizon" + +config MAINBOARD_SMBIOS_PRODUCT_NAME + default "StarBook Horizon" + +config ME_BIN_PATH + string + default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/intel_me.bin" + +config POWER_STATE_DEFAULT_ON_AFTER_FAILURE + default n + +config SOC_INTEL_CSE_SEND_EOP_EARLY + default n + +config TPM_PIRQ + depends on MAINBOARD_HAS_TPM2 + default 0x28 + +config UART_FOR_CONSOLE + default 0 + +config USE_PM_ACPI_TIMER + default n + +config VARIANT_DIR + default "hz" + +endif diff --git a/src/mainboard/starlabs/adl/Kconfig.name b/src/mainboard/starlabs/adl/Kconfig.name new file mode 100644 index 0000000000..e9af44560e --- /dev/null +++ b/src/mainboard/starlabs/adl/Kconfig.name @@ -0,0 +1,4 @@ +comment "Star Labs StarLite Series" + +config BOARD_STARLABS_ADL_HORIZON + bool "Star Labs StarBook Horizon (N305)" diff --git a/src/mainboard/starlabs/adl/Makefile.mk b/src/mainboard/starlabs/adl/Makefile.mk new file mode 100644 index 0000000000..ad15bbd510 --- /dev/null +++ b/src/mainboard/starlabs/adl/Makefile.mk @@ -0,0 +1,10 @@ +## SPDX-License-Identifier: GPL-2.0-only + +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +subdirs-$(CONFIG_HAVE_SPD_IN_CBFS) += ./spd +subdirs-y += variants/$(VARIANT_DIR) + +bootblock-y += bootblock.c + +ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += cfr.c +ramstage-y += mainboard.c diff --git a/src/mainboard/starlabs/adl/acpi/ec.asl b/src/mainboard/starlabs/adl/acpi/ec.asl new file mode 100644 index 0000000000..853b0877b3 --- /dev/null +++ b/src/mainboard/starlabs/adl/acpi/ec.asl @@ -0,0 +1 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/src/mainboard/starlabs/adl/acpi/mainboard.asl b/src/mainboard/starlabs/adl/acpi/mainboard.asl new file mode 100644 index 0000000000..34b90af325 --- /dev/null +++ b/src/mainboard/starlabs/adl/acpi/mainboard.asl @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Scope (\_SB) { + #include "sleep.asl" +} diff --git a/src/mainboard/starlabs/adl/acpi/sleep.asl b/src/mainboard/starlabs/adl/acpi/sleep.asl new file mode 100644 index 0000000000..7ed74e3514 --- /dev/null +++ b/src/mainboard/starlabs/adl/acpi/sleep.asl @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Method (MPTS, 1, NotSerialized) +{ + RPTS (Arg0) +} + +Method (MWAK, 1, NotSerialized) +{ + RWAK (Arg0) +} diff --git a/src/mainboard/starlabs/adl/acpi/superio.asl b/src/mainboard/starlabs/adl/acpi/superio.asl new file mode 100644 index 0000000000..853b0877b3 --- /dev/null +++ b/src/mainboard/starlabs/adl/acpi/superio.asl @@ -0,0 +1 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/src/mainboard/starlabs/adl/board_info.txt b/src/mainboard/starlabs/adl/board_info.txt new file mode 100644 index 0000000000..5416db044b --- /dev/null +++ b/src/mainboard/starlabs/adl/board_info.txt @@ -0,0 +1,6 @@ +Vendor name: Star Labs +Board name: StarBook Horizon +Category: laptop +ROM protocol: SPI +ROM socketed: n +Flashrom support: y diff --git a/src/mainboard/starlabs/adl/bootblock.c b/src/mainboard/starlabs/adl/bootblock.c new file mode 100644 index 0000000000..ca48bb1ab2 --- /dev/null +++ b/src/mainboard/starlabs/adl/bootblock.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void bootblock_mainboard_init(void) +{ + const struct pad_config *pads; + size_t num; + + pads = variant_early_gpio_table(&num); + gpio_configure_pads(pads, num); +} diff --git a/src/mainboard/starlabs/adl/cfr.c b/src/mainboard/starlabs/adl/cfr.c new file mode 100644 index 0000000000..4f920a69f6 --- /dev/null +++ b/src/mainboard/starlabs/adl/cfr.c @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +static struct sm_obj_form performance_group = { + .ui_name = "Performance", + .obj_list = (const struct sm_object *[]) { + &fan_mode, + &memory_speed, + &power_profile, + NULL + }, +}; + +static struct sm_obj_form processor_group = { + .ui_name = "Processor", + .obj_list = (const struct sm_object *[]) { + &me_state, + &me_state_counter, + &s0ix_enable, + &vtd, + NULL + }, +}; + +static struct sm_obj_form power_group = { + .ui_name = "Power", + .obj_list = (const struct sm_object *[]) { + &max_charge, + &charging_speed, + &power_led, + &charge_led, + &power_on_after_fail_bool, + NULL + }, +}; + +static struct sm_obj_form keyboard_group = { + .ui_name = "Keyboard", + .obj_list = (const struct sm_object *[]) { + &kbl_timeout, + &fn_ctrl_swap, + NULL + }, +}; + +static struct sm_obj_form devices_group = { + .ui_name = "Devices", + .obj_list = (const struct sm_object *[]) { + &bluetooth, + &display_native_res, + &gna, + &lid_switch, + µphone, + &webcam, + &wifi, + NULL + }, +}; + +static struct sm_obj_form security_group = { + .ui_name = "Security", + .obj_list = (const struct sm_object *[]) { + &bios_lock, + &intel_tme, + NULL + }, +}; + +static struct sm_obj_form pci_group = { + .ui_name = "PCI", + .obj_list = (const struct sm_object *[]) { + &pciexp_clk_pm, + &pciexp_aspm, + &pciexp_l1ss, + NULL + }, +}; + +static struct sm_obj_form coreboot_group = { + .ui_name = "coreboot", + .obj_list = (const struct sm_object *[]) { + &debug_level, + NULL + }, +}; + +static struct sm_obj_form *sm_root[] = { + &performance_group, + &processor_group, + &power_group, + &keyboard_group, + &devices_group, + &security_group, + &pci_group, + &coreboot_group, + NULL +}; + +void mb_cfr_setup_menu(struct lb_cfr *cfr_root) +{ + starlabs_cfr_register_overrides(); + cfr_write_setup_menu(cfr_root, sm_root); +} diff --git a/src/mainboard/starlabs/adl/cmos.default b/src/mainboard/starlabs/adl/cmos.default new file mode 100644 index 0000000000..49faae3e6a --- /dev/null +++ b/src/mainboard/starlabs/adl/cmos.default @@ -0,0 +1,6 @@ +## SPDX-License-Identifier: GPL-2.0-only +# Functions +fn_lock_state=0x1 +trackpad_state=0x1 +kbl_brightness=0x0 +kbl_state=0x1 diff --git a/src/mainboard/starlabs/adl/cmos.layout b/src/mainboard/starlabs/adl/cmos.layout new file mode 100644 index 0000000000..ebba7fbd5d --- /dev/null +++ b/src/mainboard/starlabs/adl/cmos.layout @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# ----------------------------------------------------------------- +entries + +# Bank: 1 +# ----------------------------------------------------------------- +0 120 r 0 reserved_memory + +# ----------------------------------------------------------------- +# coreboot config options: ramtop +304 80 h 0 ramtop + +# RTC_BOOT_BYTE (coreboot hardcoded) +388 4 h 0 reboot_counter + +# coreboot config options: cpu +#400 8 r 0 reserved for century byte + +# coreboot config options: check sums +984 16 h 0 check_sum + +# Bank: 2 +# embedded controller settings (outside the checksummed area) +1024 8 h 1 fn_lock_state +1032 8 h 1 trackpad_state +1040 8 h 2 kbl_brightness +1048 8 h 1 kbl_state + +# ----------------------------------------------------------------- + +enumerations + +#ID value text +1 0 Disable +1 1 Enable + +2 0 Off +2 1 Low +2 2 High +2 3 On + +# ----------------------------------------------------------------- +checksums + +checksum 392 983 984 diff --git a/src/mainboard/starlabs/adl/dsdt.asl b/src/mainboard/starlabs/adl/dsdt.asl new file mode 100644 index 0000000000..b7783eae63 --- /dev/null +++ b/src/mainboard/starlabs/adl/dsdt.asl @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +DefinitionBlock( + "dsdt.aml", + "DSDT", + ACPI_DSDT_REV_2, + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20220930 +) +{ + #include + #include + #include + #include + + Device (\_SB.PCI0) + { + #include + #include + #include + + #include + + #include + + /* PS/2 Keyboard */ + #include + } + + #include + + /* Star Labs EC */ + #include + + Scope (\_SB) + { + /* HID Driver */ + #include + + /* Suspend Methods */ + #include + } + + #include "acpi/mainboard.asl" +} diff --git a/src/mainboard/starlabs/adl/include/variants.h b/src/mainboard/starlabs/adl/include/variants.h new file mode 100644 index 0000000000..c95d15bd72 --- /dev/null +++ b/src/mainboard/starlabs/adl/include/variants.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _BASEBOARD_VARIANTS_H_ +#define _BASEBOARD_VARIANTS_H_ + +#include + +/* + * The next set of functions return the gpio table and fill in the number of + * entries for each table. + */ +const struct pad_config *variant_gpio_table(size_t *num); +const struct pad_config *variant_early_gpio_table(size_t *num); + +void devtree_update(void); + +#endif /* _BASEBOARD_VARIANTS_H_ */ diff --git a/src/mainboard/starlabs/adl/mainboard.c b/src/mainboard/starlabs/adl/mainboard.c new file mode 100644 index 0000000000..1d2fceae53 --- /dev/null +++ b/src/mainboard/starlabs/adl/mainboard.c @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +static void init_mainboard(void *chip_info) +{ + const struct pad_config *pads; + size_t num; + + pads = variant_gpio_table(&num); + gpio_configure_pads(pads, num); + + devtree_update(); +} + +struct chip_operations mainboard_ops = { + .init = init_mainboard, +}; diff --git a/src/mainboard/starlabs/adl/spd/Makefile.mk b/src/mainboard/starlabs/adl/spd/Makefile.mk new file mode 100644 index 0000000000..f979c5a066 --- /dev/null +++ b/src/mainboard/starlabs/adl/spd/Makefile.mk @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +SPD_SOURCES = rs4g32l05d8fdb-5500 +SPD_SOURCES += rs4g32l05d8fdb-6400 +SPD_SOURCES += rs4g32l05d8fdb-7500 diff --git a/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-5500.spd.hex b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-5500.spd.hex new file mode 100644 index 0000000000..a52441a71b --- /dev/null +++ b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 2A 91 08 00 00 00 00 09 01 00 00 +00 00 0B 00 00 00 00 00 AE 00 90 A8 90 C0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 4B 00 50 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-6400.spd.hex b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-6400.spd.hex new file mode 100644 index 0000000000..0969d01568 --- /dev/null +++ b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-6400.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 2A 91 08 00 00 00 00 09 01 00 00 +00 00 0A 00 00 00 00 00 AA 00 90 A8 90 C0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-7500.spd.hex b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-7500.spd.hex new file mode 100644 index 0000000000..c132efab8c --- /dev/null +++ b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-7500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 2A 91 08 00 00 00 00 09 01 00 00 +00 00 08 00 00 00 00 00 AA 00 90 A8 90 C0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 46 00 42 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/adl/variants/hz/Makefile.mk b/src/mainboard/starlabs/adl/variants/hz/Makefile.mk new file mode 100644 index 0000000000..bfea7ef255 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/hz/Makefile.mk @@ -0,0 +1,12 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += gpio.c + +romstage-y += romstage.c + +ramstage-y += devtree.c +ramstage-y += gpio.c +ramstage-y += hda_verb.c +ramstage-y += ramstage.c + +$(call add_vbt_to_cbfs, vbt_native_res.bin, data_native_res.vbt) diff --git a/src/mainboard/starlabs/adl/variants/hz/board.fmd b/src/mainboard/starlabs/adl/variants/hz/board.fmd new file mode 100644 index 0000000000..2197262237 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/hz/board.fmd @@ -0,0 +1,14 @@ +FLASH 0x1000000 { + SI_ALL 0x600000 { + SI_DESC 0x1000 + SI_ME 0x411000 + } + SI_BIOS 0xa00000 { + EC@0x0 0x20000 + RW_MRC_CACHE@0x20000 0x10000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 + COREBOOT(CBFS) + } +} diff --git a/src/mainboard/starlabs/adl/variants/hz/data.vbt b/src/mainboard/starlabs/adl/variants/hz/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..a2adefc8b2589fa70efa3937551bf02da294487d GIT binary patch literal 9216 zcmeHMUrbw782`?_Z7H=#H_&ys;ejn!aKNQ($Oy@9q2Ri~D1Sz}L_^0~mBF?dvl}y&bck6Ft%zo9ZSFFJLkLi z`_Aut-*-;WIrrZE!yQ9B&=c$$=m{L}stIn4>jsyckfsu}$zRu&E z*t7IU)#^>67-PHLO`6seIyW63_YKtY-igt%@pxk}e*VqriAf&r4DrC3Gx72G)amJX zj1LaK9N+@4#MN(NDd^l`iwniK)p39vC0z1H$G!ABdliPrV(FHI%pnP?DTBM#NlHnj{E( zLxC!fyv>Ld2uZ}iA!le+7ZU7VP1}`Z`i-XTgcqc)a=I?@E~f2DiQqQyCUfm%Z@{~p zw%b8umv%;Ozrq>O@7HO&G9rhxGjr{vudw?eZ6}(6HuOuYa!_FR`$juj?;q^)q&x4x zFr6qyOc2pCOyAV}Cv|Dly|~>)6X1*B_rV{4KLURW{tEmJ_*?LI;2*)if`0@53H}RQ z97ErV7_diHra-RmY3)CfN@b$hu9CZqj$ux!&i2_oGM1A>sZYum$YEU)wP!-SNBvmn zo@-E-i(Ir^beqkUJ)V-an%pCSn{H+2(I!>lMj-S(^7G+mp- zo+=1YprMf5GxmzS5N3FPg-7?SLtv)Z#`8t^vTv}Sa;2?S0aSz+`$>eKQ!wdaXsdby_u@IRw#Tkv@N+3Zp2WD17ZkVsddG5b8uLYb;E;>ADm4**xaM)!M{z|7^7uzOri#L8YgJj7;W( zpw;P1(b<^h?U!>v`k-Pm350(+Cy@u0a8eWqcAiHRH!CO+=DRev)+t(9KA8AF0>LP1 zmGePN@~vmJ(q?$yYOU8J_1Upd38zru0}js*{$JGU6g8+U>ha)ADo92l_cM1-cX%Xx z`dobc#Obr~C*Z;g@X?m3)Qe5bacqekk%dQBigW6EQWRw;c#XudRWMG>vd&!RTZ=VG zu1o1UbDeMP+(3Z2FC7@ATivh-;plym!tnb5`;cy^*nTWR7?O5wAaVb`$m^618l$;2 z+8(0iekR2KylyTgb_)ySQLI7-TTqx-8RR0lF0VpNrH;sv5X-Ufayk73E*96)OV1xE z$H0mK-iq4W$>|@f>26`PZ|s~O504|hcJjkqK4PLS^qkFIA=?jshTUe?Z?5d0OWBdh zl^l{b zk)fD)eHEn@win;~13ZHF$C6kf9hT zSH8geYWqCXXc9IW+TmFilmrXijGZ$NbQLyFj?Vl==vG*S=Ao;}(Jjv?q&qZ42g;(& zpQF3e%V^lXz`DtVFO|@V2Vuko{&|^^=}3@99GI1BekP$aPbp*+S-M5rK16PPiWE9q zf>FZ0%))eqX4Pt7TF=-*Ct}bYOXQ_~=wiYeY{j=#UXsx7FA;f3;E^8QsJqZAo0syS t@WqSR>#5aNpX2A%_b?_-eEP$Ku>N4{szB+fGz+4 literal 0 HcmV?d00001 diff --git a/src/mainboard/starlabs/adl/variants/hz/data_native_res.vbt b/src/mainboard/starlabs/adl/variants/hz/data_native_res.vbt new file mode 100644 index 0000000000000000000000000000000000000000..7e4f64ad7fd3cd3eafeb099eab9154b2b97e3e42 GIT binary patch literal 9216 zcmeHMUrbw782`?_ZRu)}ZlLRM!vkBe;DAfnkP(vI^3QdH(H2I!L_^0~mB^sdvk%42u&fri_cd08cgszFnOH*U7zcI~y zU3J`#b{ZtEbeVTeOiecO!1y?i2%8H$lDLqVdOHzsEOiN>6gh2-h`FdNMGyqt?IaI5 zNe6RWIZ7e}%)y0{a)l{2BA=5S-t~3Rri%NN1kNfrtr}T5Q4wC+l(8!#g4@8G%(s)R0q;u2 zZYPml+8O!n3TH&SUuEpdi5$|-%(s)i!tVQwou~%d&@QdYPJ!KT8|`Slf3Pc%?z{uT zOrjVuK}63meN*)x)um0(5_T6&fG>gH2Y&$m2>dDdOYqm=Z@}Mze*pgi{uTTu_%HB| zINDZ3hdr`u8sz$p*8U^ubT*3ZD!I$)IL4&v?3mpvV>v~X{-k1o9M&ySM>fQJl#hk( zxkh!l#6`;`x7l3z<0)CQ$vqOd=}~SRZBi8<6f^KpGT^HrMQzE0TF6lDVg0b(P*#|+ z^J%%ZIj7wCheZ{)EN?RpN_*K0luqB+VVHbnpT`-iv1(VfUdG%nWH(o%%7YP-Wt^I$ zd%4f3SVNHWI1t3#^k9Ve9?}C;t9j>IEd+1tWmRqkfM6$^KJ!}=qgXC_oqfdAu?%-JsQE4Lh|r#qnV6VR_Pkg^aV0$ zGk3@+jFLj4@O2o;$;JIZs28=YzA)vY>rUEd3m6aA>XOUh*%~c$b@v*AN>2$HnJffB ztJjxevvJKEmSaHrpkgoygnv0Ekq4EqQxphxUO*JLDk&M_yEV7gC2CndnD{>e!6<2y z<3SAatw*)eZg}5nYtW+&xxP>dyHMc+HqQ_KU)1RoGpIb~@nBCXNJb&oGk0HaXe4yz zd}93MnRAIJ;KmB@(O%Q(7n_;m_!2py3y z-ikUp$mt)e?QLbWf9$*;hsP0L2l-(xkC-TnE$4Dq%=W_{VYiv}n=Ak4Qm$w6C5NQ8 z>(;IyU$@QgjznAzx!>C6aTMJzW}ujXVg`yCC}yCTfno-V8TcPF(EgdSmtGkqG87Z9 zuVS>q_ThV<{3=Q*IHrG0#8qNGGAIgLX1&3cx|?@lVAGkG=I}Z1b;cGt5rghnA}@uZiwkS872j5QNkM<0ROBUzBR#xPccWG=FBRRw7cXLO opf+1Wo}bs=L!UVD=^H
1: Enable + $EN_DIS +**/ + UINT8 EnableDynamicEfficiencyControl; + +/** Offset 0x013E - Misc Power Management MSR Lock + Enable/Disable HWP Lock support in Misc Power Management MSR. 0: Disable, 1: + Enable + $EN_DIS +**/ + UINT8 HwpLock; + +/** Offset 0x013F - Power Floor Managment for SOC + Option to disable Power Floor Managment for SOC. Disabling this might effectively + raise power floor of the SoC and may lead to stability issues. 0: Disable, 1: + Enable + $EN_DIS +**/ + UINT8 PowerFloorManagement; + +/** Offset 0x0140 - Power Floor Disaplay Disconnect + SoC can disconnect secondary/external display to lower SoC floor power (Default + disabled). 0: Disable: Display disconnect will not be used by SoC., 1: Enable + $EN_DIS +**/ + UINT8 PowerFloorDisplayDisconnect; + +/** Offset 0x0141 - Memory size per thread allocated for Processor Trace + Memory size per thread for Processor Trace. Processor Trace requires 2^N alignment + and size in bytes per thread, from 4KB to 128MB.\n + 0xff:none , 0:4k, 0x1:8k, 0x2:16k, 0x3:32k, 0x4:64k, 0x5:128k, 0x6:256k, + 0x7:512k, 0x8:1M, 0x9:2M, 0xa:4M. 0xb:8M, 0xc:16M, 0xd:32M, 0xe:64M, 0xf:128M **/ - UINT8 Reserved10[5]; + UINT8 ProcessorTraceMemSize; /** Offset 0x0142 - Enable or Disable MLC Streamer Prefetcher Enable or Disable MLC Streamer Prefetcher; 0: Disable; 1: Enable. @@ -447,9 +573,25 @@ typedef struct { **/ UINT8 ProcessorTraceEnable; -/** Offset 0x0148 - Reserved +/** Offset 0x0148 - Processor trace enabled for Bsp only or all cores + Processor trace enabled for Bsp only or all cores; 0: all cores; 1: Bsp only. + 0: all cores, 1: Bsp only +**/ + UINT8 ProcessorTraceBspOnly; + +/** Offset 0x0149 - Enable/Disable processor trace Timing Packet + Enable/Disable collocting processor trace performance (CYC, TSC); 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 ProcessorTraceTimingPacket; + +/** Offset 0x014A - Enable or Disable Three Strike Counter + Enable (default): Three Strike counter will be incremented. Disable: Prevents Three + Strike counter from incrementing; 0: Disable; 1: Enable + $EN_DIS **/ - UINT8 Reserved11[3]; + UINT8 ThreeStrikeCounter; /** Offset 0x014B - UFS enable/disable Enable/Disable UFS controller, One byte for each Controller - (1,0) to enable controller @@ -466,9 +608,12 @@ typedef struct { **/ UINT8 UfsInlineEncryption[2]; -/** Offset 0x014F - Reserved +/** Offset 0x014F - UFS Connection Status + UFS Connection Status, One byte for each Controller - (1,0) to UFS connected to + controller 0 and (0,1) to UFS connected to controller 1 + $EN_DIS **/ - UINT8 Reserved12[2]; + UINT8 UfsDeviceConnected[2]; /** Offset 0x0151 - Enable/Disable PCIe tunneling for USB4 Enable/Disable PCIe tunneling for USB4, default is enable @@ -478,7 +623,7 @@ typedef struct { /** Offset 0x0152 - Reserved **/ - UINT8 Reserved13[2]; + UINT8 Reserved3[2]; /** Offset 0x0154 - ITBTForcePowerOn Timeout value ITBTForcePowerOn value. Specified increment values in miliseconds. Range is 0-1000. @@ -504,7 +649,12 @@ typedef struct { /** Offset 0x015D - Reserved **/ - UINT8 Reserved14[19]; + UINT8 Reserved4[11]; + +/** Offset 0x0168 - FSPS Validation + Point to FSPS Validation configuration structure +**/ + UINT64 FspsValidationPtr; /** Offset 0x0170 - IEH Mode Integrated Error Handler Mode, 0: Bypass, 1: Enable @@ -563,7 +713,7 @@ typedef struct { /** Offset 0x017B - Reserved **/ - UINT8 Reserved15; + UINT8 Reserved5; /** Offset 0x017C - ISH GP GPIO Pin Muxing Determines ISH GP GPIO Pin muxing. See GPIO_*_MUXING_ISH_GP_x_GPIO_*. 'x' are GP_NUMBER @@ -746,9 +896,11 @@ typedef struct { **/ UINT8 PchIshPdtUnlock; -/** Offset 0x025C - Reserved +/** Offset 0x025C - PCH ISH MSI Interrupts + 0: False; 1: True. + $EN_DIS **/ - UINT8 Reserved16; + UINT8 PchIshMsiInterrupt; /** Offset 0x025D - End of Post message Test, Send End of Post message. Disable(0x0): Disable EOP message, Send in PEI(0x1): @@ -778,9 +930,44 @@ typedef struct { **/ UINT8 MeUnconfigOnRtcClear; -/** Offset 0x0261 - Reserved +/** Offset 0x0261 - CSE Data Resilience Support + 0: Disable CSE Data Resilience Support. 1: Enable CSE Data Resilience Support. + 2: Enable CSE Data Resilience but defer to DXE. + $EN_DIS +**/ + UINT8 CseDataResilience; + +/** Offset 0x0262 - PSE EOM Flow Control + 0: Disable PSE EOM Flow. 1: Enable PSE EOM Flow. + $EN_DIS +**/ + UINT8 PseEomFlowEnable; + +/** Offset 0x0263 - ISH I3C SDA Pin Muxing + Select ISH I3C SDA Pin muxing. Refer to GPIO_*_MUXING_ISH_I3Cx_SDA_* for possible values. **/ - UINT8 Reserved17[22]; + UINT8 IshI3cSdaPinMuxing[8]; + +/** Offset 0x026B - ISH I3C SCL Pin Muxing + Select ISH I3C SCL Pin muxing. Refer to GPIO_*_MUXING_ISH_I3Cx_SCL_* for possible values. +**/ + UINT8 IshI3cSclPinMuxing[8]; + +/** Offset 0x0273 - ISH I3C SDA Pad termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C#N Sda pads termination + respectively. #N-byte for each controller, byte0 for I2C0 Sda, byte1 for I2C1 Sda, + and so on. +**/ + UINT8 IshI3cSdaPadTermination[2]; + +/** Offset 0x0275 - ISH I3C SCL Pad termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C#N Scl pads termination + respectively. #N-byte for each controller, byte0 for I2C0 Scl, byte1 for I2C1 Scl, + and so on. +**/ + UINT8 IshI3cSclPadTermination[2]; /** Offset 0x0277 - Enable PCH ISH I3C pins assigned Set if ISH I3C native pins are to be enabled by BIOS. 0: Disable; 1: Enable. @@ -789,7 +976,7 @@ typedef struct { /** Offset 0x0279 - Reserved **/ - UINT8 Reserved18[3]; + UINT8 Reserved6[3]; /** Offset 0x027C - Power button debounce configuration Debounce time for PWRBTN in microseconds. For values not supported by HW, they will @@ -972,9 +1159,11 @@ typedef struct { **/ UINT8 PmcLpmS0ixSubStateEnableMask; -/** Offset 0x029C - Reserved +/** Offset 0x029C - PCH PMC ER Debug mode + Disable/Enable Energy Reporting Debug Mode. + $EN_DIS **/ - UINT8 Reserved19; + UINT8 PchPmErDebugMode; /** Offset 0x029D - PMC C10 dynamic threshold dajustment enable Set if you want to enable PMC C10 dynamic threshold adjustment. Only works on supported SKUs @@ -1143,9 +1332,11 @@ typedef struct { **/ UINT8 PcieRpAspm[28]; -/** Offset 0x053C - Reserved +/** Offset 0x053C - HostL0sTxDis + Disable Host L0 transmission state + $EN_DIS **/ - UINT8 Reserved20[28]; + UINT8 HostL0sTxDis[28]; /** Offset 0x0558 - PCIE RP L1 Substates The L1 Substates configuration of the root port (see: PCH_PCIE_L1SUBSTATES_CONTROL). @@ -1169,321 +1360,1121 @@ typedef struct { **/ UINT8 PcieEqOverrideDefault[12]; -/** Offset 0x05B8 - Reserved +/** Offset 0x05B8 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq **/ - UINT8 Reserved21[1525]; + UINT8 PcieGen3EqMethod[12]; -/** Offset 0x0BAD - PCIE RP Enable Peer Memory Write - This member describes whether Peer Memory Writes are enabled on the platform. +/** Offset 0x05C4 - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq +**/ + UINT8 PcieGen3EqMode[12]; + +/** Offset 0x05D0 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override $EN_DIS **/ - UINT8 PcieEnablePeerMemoryWrite[12]; + UINT8 PcieGen3EqLocalTxOverrideEn[12]; -/** Offset 0x0BB9 - Assertion on Link Down GPIOs - GPIO Assertion on Link Down. Disabled(0x0)(Default): Disable assertion on Link Down - GPIOs, Enabled(0x1): Enable assertion on Link Down GPIOs - 0:Disable, 1:Enable +/** Offset 0x05DC - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode **/ - UINT8 PcieRpLinkDownGpios[12]; + UINT8 PcieGen3EqPh3NoOfPresetOrCoeff[12]; -/** Offset 0x0BC5 - PCIE Compliance Test Mode - Compliance Test Mode shall be enabled when using Compliance Load Board. - $EN_DIS +/** Offset 0x05E8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieComplianceTestMode; + UINT8 PcieGen3EqPh3PreCursor0List[12]; -/** Offset 0x0BC6 - PCIE Rp Function Swap - Allows BIOS to use root port function number swapping when root port of function - 0 is disabled. - $EN_DIS +/** Offset 0x05F4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpFunctionSwap; + UINT8 PcieGen3EqPh3PostCursor0List[12]; -/** Offset 0x0BC7 - Reserved +/** Offset 0x0600 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved22[12]; + UINT8 PcieGen3EqPh3PreCursor1List[12]; -/** Offset 0x0BD3 - PCIe RootPort Power Gating - Describes whether the PCI Express Power Gating for each root port is enabled by - platform modules. 0: Disable; 1: Enable(Default). - $EN_DIS +/** Offset 0x060C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PciePowerGating[12]; + UINT8 PcieGen3EqPh3PostCursor1List[12]; -/** Offset 0x0BDF - Reserved +/** Offset 0x0618 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved23[49]; + UINT8 PcieGen3EqPh3PreCursor2List[12]; -/** Offset 0x0C10 - PCIE RP Ltr Max Snoop Latency - Latency Tolerance Reporting, Max Snoop Latency. +/** Offset 0x0624 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpLtrMaxSnoopLatency[24]; + UINT8 PcieGen3EqPh3PostCursor2List[12]; -/** Offset 0x0C40 - PCIE RP Ltr Max No Snoop Latency - Latency Tolerance Reporting, Max Non-Snoop Latency. +/** Offset 0x0630 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpLtrMaxNoSnoopLatency[24]; + UINT8 PcieGen3EqPh3PreCursor3List[12]; -/** Offset 0x0C70 - PCIE RP Snoop Latency Override Mode - Latency Tolerance Reporting, Snoop Latency Override Mode. +/** Offset 0x063C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSnoopLatencyOverrideMode[28]; + UINT8 PcieGen3EqPh3PostCursor3List[12]; -/** Offset 0x0C8C - PCIE RP Snoop Latency Override Multiplier - Latency Tolerance Reporting, Snoop Latency Override Multiplier. +/** Offset 0x0648 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSnoopLatencyOverrideMultiplier[28]; + UINT8 PcieGen3EqPh3PreCursor4List[12]; -/** Offset 0x0CA8 - PCIE RP Snoop Latency Override Value - Latency Tolerance Reporting, Snoop Latency Override Value. +/** Offset 0x0654 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpSnoopLatencyOverrideValue[24]; + UINT8 PcieGen3EqPh3PostCursor4List[12]; -/** Offset 0x0CD8 - PCIE RP Non Snoop Latency Override Mode - Latency Tolerance Reporting, Non-Snoop Latency Override Mode. +/** Offset 0x0660 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpNonSnoopLatencyOverrideMode[28]; + UINT8 PcieGen3EqPh3PreCursor5List[12]; -/** Offset 0x0CF4 - PCIE RP Non Snoop Latency Override Multiplier - Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier. +/** Offset 0x066C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpNonSnoopLatencyOverrideMultiplier[28]; + UINT8 PcieGen3EqPh3PostCursor5List[12]; -/** Offset 0x0D10 - PCIE RP Non Snoop Latency Override Value - Latency Tolerance Reporting, Non-Snoop Latency Override Value. +/** Offset 0x0678 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpNonSnoopLatencyOverrideValue[24]; + UINT8 PcieGen3EqPh3PreCursor6List[12]; -/** Offset 0x0D40 - PCIE RP Slot Power Limit Scale - Specifies scale used for slot power limit value. Leave as 0 to set to default. +/** Offset 0x0684 - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSlotPowerLimitScale[28]; + UINT8 PcieGen3EqPh3PostCursor6List[12]; -/** Offset 0x0D5C - PCIE RP Slot Power Limit Value - Specifies upper limit on power supplie by slot. Leave as 0 to set to default. +/** Offset 0x0690 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpSlotPowerLimitValue[24]; + UINT8 PcieGen3EqPh3PreCursor7List[12]; -/** Offset 0x0D8C - PCIE RP Enable Port8xh Decode - This member describes whether PCIE root port Port 8xh Decode is enabled. 0: Disable; - 1: Enable. - $EN_DIS +/** Offset 0x069C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieEnablePort8xhDecode; + UINT8 PcieGen3EqPh3PostCursor7List[12]; -/** Offset 0x0D8D - PCIE Port8xh Decode Port Index - The Index of PCIe Port that is selected for Port8xh Decode (1 Based). +/** Offset 0x06A8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PchPciePort8xhDecodePortIndex; + UINT8 PcieGen3EqPh3PreCursor8List[12]; -/** Offset 0x0D8E - Reserved +/** Offset 0x06B4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved24[114]; + UINT8 PcieGen3EqPh3PostCursor8List[12]; -/** Offset 0x0E00 - SPIn Device Mode - Selects SPI operation mode. N represents controller index: SPI0, SPI1, ... Available - modes: 0:LpssSpiDisabled, 1:LpssSpiPci, 2:LpssSpiHidden +/** Offset 0x06C0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiMode[7]; + UINT8 PcieGen3EqPh3PreCursor9List[12]; -/** Offset 0x0E07 - Reserved +/** Offset 0x06CC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved25[85]; + UINT8 PcieGen3EqPh3PostCursor9List[12]; -/** Offset 0x0E5C - SPIn Default Chip Select Mode HW/SW - Sets Default CS Mode Hardware or Software. N represents controller index: SPI0, - SPI1, ... Available options: 0:HW, 1:SW +/** Offset 0x06D8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiCsMode[7]; + UINT8 PcieGen3EqPh3Preset0List[12]; -/** Offset 0x0E63 - SPIn Default Chip Select State Low/High - Sets Default CS State Low or High. N represents controller index: SPI0, SPI1, ... - Available options: 0:Low, 1:High +/** Offset 0x06E4 - PCIe preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiCsState[7]; + UINT8 PcieGen3EqPh3Preset1List[12]; -/** Offset 0x0E6A - UARTn Device Mode - Selects Uart operation mode. N represents controller index: Uart0, Uart1, ... Available - modes: 0:SerialIoUartDisabled, 1:SerialIoUartPci, 2:SerialIoUartHidden, 3:SerialIoUartCom, - 4:SerialIoUartSkipInit +/** Offset 0x06F0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartMode[7]; + UINT8 PcieGen3EqPh3Preset2List[12]; -/** Offset 0x0E71 - Reserved +/** Offset 0x06FC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 Reserved26[3]; + UINT8 PcieGen3EqPh3Preset3List[12]; -/** Offset 0x0E74 - Default BaudRate for each Serial IO UART - Set default BaudRate Supported from 0 - default to 6000000 +/** Offset 0x0708 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT32 SerialIoUartBaudRate[7]; + UINT8 PcieGen3EqPh3Preset4List[12]; -/** Offset 0x0E90 - Default ParityType for each Serial IO UART - Set default Parity. 0: DefaultParity, 1: NoParity, 2: EvenParity, 3: OddParity +/** Offset 0x0714 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartParity[7]; + UINT8 PcieGen3EqPh3Preset5List[12]; -/** Offset 0x0E97 - Default DataBits for each Serial IO UART - Set default word length. 0: Default, 5,6,7,8 +/** Offset 0x0720 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartDataBits[7]; + UINT8 PcieGen3EqPh3Preset6List[12]; -/** Offset 0x0E9E - Default StopBits for each Serial IO UART - Set default stop bits. 0: DefaultStopBits, 1: OneStopBit, 2: OneFiveStopBits, 3: - TwoStopBits +/** Offset 0x072C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartStopBits[7]; + UINT8 PcieGen3EqPh3Preset7List[12]; -/** Offset 0x0EA5 - Power Gating mode for each Serial IO UART that works in COM mode - Set Power Gating. 0: Disabled, 1: Enabled, 2: Auto +/** Offset 0x0738 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartPowerGating[7]; + UINT8 PcieGen3EqPh3Preset8List[12]; -/** Offset 0x0EAC - Enable Dma for each Serial IO UART that supports it - Set DMA/PIO mode. 0: Disabled, 1: Enabled +/** Offset 0x0744 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartDmaEnable[7]; + UINT8 PcieGen3EqPh3Preset9List[12]; -/** Offset 0x0EB3 - Enables UART hardware flow control, CTS and RTS lines - Enables UART hardware flow control, CTS and RTS lines. +/** Offset 0x0750 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartAutoFlow[7]; + UINT8 PcieGen3EqPh3Preset10List[12]; -/** Offset 0x0EBA - Reserved +/** Offset 0x075C - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization **/ - UINT8 Reserved27[2]; + UINT8 PcieGen3EqPh1DpTxPreset[12]; -/** Offset 0x0EBC - SerialIoUartRtsPinMuxPolicy - Select SerialIo Uart Rts pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RTS* - for possible values. +/** Offset 0x0768 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization **/ - UINT32 SerialIoUartRtsPinMuxPolicy[7]; + UINT8 PcieGen3EqPh1UpTxPreset[12]; -/** Offset 0x0ED8 - SerialIoUartRxPinMuxPolicy - Select SerialIo Uart Rx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RX* for - possible values. +/** Offset 0x0774 - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override **/ - UINT32 SerialIoUartRxPinMuxPolicy[7]; + UINT8 PcieGen3EqPh2LocalTxOverridePreset[12]; -/** Offset 0x0EF4 - SerialIoUartTxPinMuxPolicy - Select SerialIo Uart Tx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_TX* for - possible values. +/** Offset 0x0780 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq **/ - UINT32 SerialIoUartTxPinMuxPolicy[7]; + UINT8 PcieGen4EqMethod[12]; -/** Offset 0x0F10 - Serial IO UART DBG2 table - Enable or disable Serial Io UART DBG2 table, default is Disable; 0: Disable; - 1: Enable. +/** Offset 0x078C - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq **/ - UINT8 SerialIoUartDbg2[7]; + UINT8 PcieGen4EqMode[12]; -/** Offset 0x0F17 - Reserved +/** Offset 0x0798 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override + $EN_DIS **/ - UINT8 Reserved28[7]; + UINT8 PcieGen4EqLocalTxOverrideEn[12]; -/** Offset 0x0F1E - I2Cn Device Mode - Selects I2c operation mode. N represents controller index: I2c0, I2c1, ... Available - modes: 0:SerialIoI2cDisabled, 1:SerialIoI2cPci, 2:SerialIoI2cHidden +/** Offset 0x07A4 - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode **/ - UINT8 SerialIoI2cMode[8]; + UINT8 PcieGen4EqPh3NoOfPresetOrCoeff[12]; -/** Offset 0x0F26 - Reserved +/** Offset 0x07B0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved29[2]; + UINT8 PcieGen4EqPh3PreCursor0List[12]; -/** Offset 0x0F28 - Serial IO I2C SDA Pin Muxing - Select SerialIo I2c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SDA* for - possible values. +/** Offset 0x07BC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT32 PchSerialIoI2cSdaPinMux[8]; + UINT8 PcieGen4EqPh3PostCursor0List[12]; -/** Offset 0x0F48 - Serial IO I2C SCL Pin Muxing - Select SerialIo I2c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SCL* for - possible values. +/** Offset 0x07C8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT32 PchSerialIoI2cSclPinMux[8]; + UINT8 PcieGen4EqPh3PreCursor1List[12]; -/** Offset 0x0F68 - PCH SerialIo I2C Pads Termination - 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, - 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C0,I2C1,... pads termination - respectively. One byte for each controller, byte0 for I2C0, byte1 for I2C1, and so on. +/** Offset 0x07D4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PchSerialIoI2cPadsTermination[8]; + UINT8 PcieGen4EqPh3PostCursor1List[12]; -/** Offset 0x0F70 - I3C Device Mode - Selects I3c operation mode. Available modes: 0:SerialIoI3cDisabled, 1:SerialIoI3cPci, - 2:SerialIoI3cPhantom (only applicable to I3C1, controlls GPIO enabling) +/** Offset 0x07E0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 SerialIoI3cMode[3]; + UINT8 PcieGen4EqPh3PreCursor2List[12]; -/** Offset 0x0F73 - Reserved +/** Offset 0x07EC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved30[48]; + UINT8 PcieGen4EqPh3PostCursor2List[12]; -/** Offset 0x0FA3 - Enable VMD controller - Enable/disable to VMD controller.0: Disable; 1: Enable(Default) - $EN_DIS +/** Offset 0x07F8 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdEnable; + UINT8 PcieGen4EqPh3PreCursor3List[12]; -/** Offset 0x0FA4 - Enable VMD Global Mapping - Enable/disable to VMD controller.0: Disable(Default); 1: Enable - $EN_DIS +/** Offset 0x0804 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdGlobalMapping; + UINT8 PcieGen4EqPh3PostCursor3List[12]; -/** Offset 0x0FA5 - Map port under VMD - Map/UnMap port under VMD - $EN_DIS +/** Offset 0x0810 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPort[31]; + UINT8 PcieGen4EqPh3PreCursor4List[12]; -/** Offset 0x0FC4 - Reserved +/** Offset 0x081C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved31[31]; + UINT8 PcieGen4EqPh3PostCursor4List[12]; -/** Offset 0x0FE3 - VMD Port Device - VMD Root port device number. +/** Offset 0x0828 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPortDev[31]; + UINT8 PcieGen4EqPh3PreCursor5List[12]; -/** Offset 0x1002 - VMD Port Func - VMD Root port function number. +/** Offset 0x0834 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPortFunc[31]; + UINT8 PcieGen4EqPh3PostCursor5List[12]; -/** Offset 0x1021 - Reserved +/** Offset 0x0840 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved32[7]; + UINT8 PcieGen4EqPh3PreCursor6List[12]; -/** Offset 0x1028 - VMD Variable - VMD Variable Pointer. +/** Offset 0x084C - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT64 VmdVariablePtr; + UINT8 PcieGen4EqPh3PostCursor6List[12]; -/** Offset 0x1030 - Reserved +/** Offset 0x0858 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved33[4]; + UINT8 PcieGen4EqPh3PreCursor7List[12]; -/** Offset 0x1034 - Temporary MemBar1 address for VMD - VMD Variable Pointer. +/** Offset 0x0864 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT32 VmdMemBar1Base; + UINT8 PcieGen4EqPh3PostCursor7List[12]; -/** Offset 0x1038 - Temporary MemBar2 address for VMD - VMD Variable Pointer. +/** Offset 0x0870 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT32 VmdMemBar2Base; + UINT8 PcieGen4EqPh3PreCursor8List[12]; -/** Offset 0x103C - Enable D3 Hot in TCSS +/** Offset 0x087C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PostCursor8List[12]; + +/** Offset 0x0888 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PreCursor9List[12]; + +/** Offset 0x0894 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PostCursor9List[12]; + +/** Offset 0x08A0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset0List[12]; + +/** Offset 0x08AC - PCIe preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset1List[12]; + +/** Offset 0x08B8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset2List[12]; + +/** Offset 0x08C4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset3List[12]; + +/** Offset 0x08D0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset4List[12]; + +/** Offset 0x08DC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset5List[12]; + +/** Offset 0x08E8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset6List[12]; + +/** Offset 0x08F4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset7List[12]; + +/** Offset 0x0900 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset8List[12]; + +/** Offset 0x090C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset9List[12]; + +/** Offset 0x0918 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset10List[12]; + +/** Offset 0x0924 - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization +**/ + UINT8 PcieGen4EqPh1DpTxPreset[12]; + +/** Offset 0x0930 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization +**/ + UINT8 PcieGen4EqPh1UpTxPreset[12]; + +/** Offset 0x093C - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override +**/ + UINT8 PcieGen4EqPh2LocalTxOverridePreset[12]; + +/** Offset 0x0948 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq +**/ + UINT8 PcieGen5EqMethod[12]; + +/** Offset 0x0954 - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq +**/ + UINT8 PcieGen5EqMode[12]; + +/** Offset 0x0960 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override + $EN_DIS +**/ + UINT8 PcieGen5EqLocalTxOverrideEn[12]; + +/** Offset 0x096C - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode +**/ + UINT8 PcieGen5EqPh3NoOfPresetOrCoeff[12]; + +/** Offset 0x0978 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor0List[12]; + +/** Offset 0x0984 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor0List[12]; + +/** Offset 0x0990 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor1List[12]; + +/** Offset 0x099C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor1List[12]; + +/** Offset 0x09A8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor2List[12]; + +/** Offset 0x09B4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor2List[12]; + +/** Offset 0x09C0 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor3List[12]; + +/** Offset 0x09CC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor3List[12]; + +/** Offset 0x09D8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor4List[12]; + +/** Offset 0x09E4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor4List[12]; + +/** Offset 0x09F0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor5List[12]; + +/** Offset 0x09FC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor5List[12]; + +/** Offset 0x0A08 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor6List[12]; + +/** Offset 0x0A14 - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor6List[12]; + +/** Offset 0x0A20 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor7List[12]; + +/** Offset 0x0A2C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor7List[12]; + +/** Offset 0x0A38 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor8List[12]; + +/** Offset 0x0A44 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor8List[12]; + +/** Offset 0x0A50 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor9List[12]; + +/** Offset 0x0A5C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor9List[12]; + +/** Offset 0x0A68 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset0List[12]; + +/** Offset 0x0A74 - PCIe preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset1List[12]; + +/** Offset 0x0A80 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset2List[12]; + +/** Offset 0x0A8C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset3List[12]; + +/** Offset 0x0A98 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset4List[12]; + +/** Offset 0x0AA4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset5List[12]; + +/** Offset 0x0AB0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset6List[12]; + +/** Offset 0x0ABC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset7List[12]; + +/** Offset 0x0AC8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset8List[12]; + +/** Offset 0x0AD4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset9List[12]; + +/** Offset 0x0AE0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset10List[12]; + +/** Offset 0x0AEC - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization +**/ + UINT8 PcieGen5EqPh1DpTxPreset[12]; + +/** Offset 0x0AF8 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization +**/ + UINT8 PcieGen5EqPh1UpTxPreset[12]; + +/** Offset 0x0B04 - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override +**/ + UINT8 PcieGen5EqPh2LocalTxOverridePreset[12]; + +/** Offset 0x0B10 - Phase3 RP Gen3 EQ enable + Phase3 Gen3 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen3EqPh3Bypass[12]; + +/** Offset 0x0B1C - Phase3 RP Gen4 EQ enable + Phase3 Gen4 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen4EqPh3Bypass[12]; + +/** Offset 0x0B28 - Phase3 RP Gen5 EQ enable + Phase3 Gen5 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen5EqPh3Bypass[12]; + +/** Offset 0x0B34 - Phase2-3 RP Gen3 EQ enable + Phase2-3 Gen3 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen3EqPh23Bypass[12]; + +/** Offset 0x0B40 - Phase2-3 RP Gen4 EQ enable + Phase2-3 Gen4 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen4EqPh23Bypass[12]; + +/** Offset 0x0B4C - Phase2-3 RP Gen5 EQ enable + Phase2-3 Gen5 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen5EqPh23Bypass[12]; + +/** Offset 0x0B58 - PCET Timer + Preset/Coefficient Evaluation Timeout Gen3 PCET Timer. See PCIE_GEN3_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen3PcetTimer[12]; + +/** Offset 0x0B64 - Gen4 PCET Timer + Preset/Coefficient Evaluation Timeout - Gen4 PCET Timer. See PCIE_GEN4_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen4PcetTimer[12]; + +/** Offset 0x0B70 - Gen5 PCET Timer + Preset/Coefficient Evaluation Timeout - Gen5 PCET Timer. See PCIE_GEN5_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen5PcetTimer[12]; + +/** Offset 0x0B7C - TS Lock Timer for Gen3 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen3 TS Lock + Timer. See PCIE_GEN3_TS_LOCK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen3TsLockTimer[12]; + +/** Offset 0x0B88 - PTS Lock Timer for Gen4 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen4 TS Lock + Timer. See PCIE_GEN4_TS_LCOK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen4TsLockTimer[12]; + +/** Offset 0x0B94 - PTS Lock Timer for Gen5 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen5 TS Lock + Timer. See PCIE_GEN5_TS_LCOK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen5TsLockTimer[12]; + +/** Offset 0x0BA0 - PCIE Secure Register Lock + Describes whether Secure Register Lock is enaled or disabled. When it will be enbaled, + load PcieRpSetSecuredRegisterLock recipe. 0: Disable(Default); 1: Enable + $EN_DIS +**/ + UINT8 PcieSetSecuredRegisterLock; + +/** Offset 0x0BA1 - Enable/Disable ASPM Optionality Compliance + Enable/Disable ASPM Optionality Compliance. +**/ + UINT8 PcieRpTestAspmOc[12]; + +/** Offset 0x0BAD - PCIE RP Enable Peer Memory Write + This member describes whether Peer Memory Writes are enabled on the platform. + $EN_DIS +**/ + UINT8 PcieEnablePeerMemoryWrite[12]; + +/** Offset 0x0BB9 - Assertion on Link Down GPIOs + GPIO Assertion on Link Down. Disabled(0x0)(Default): Disable assertion on Link Down + GPIOs, Enabled(0x1): Enable assertion on Link Down GPIOs + 0:Disable, 1:Enable +**/ + UINT8 PcieRpLinkDownGpios[12]; + +/** Offset 0x0BC5 - PCIE Compliance Test Mode + Compliance Test Mode shall be enabled when using Compliance Load Board. + $EN_DIS +**/ + UINT8 PcieComplianceTestMode; + +/** Offset 0x0BC6 - PCIE Rp Function Swap + Allows BIOS to use root port function number swapping when root port of function + 0 is disabled. + $EN_DIS +**/ + UINT8 PcieRpFunctionSwap; + +/** Offset 0x0BC7 - PCIe RootPort Clock Gating + Describes whether the PCI Express Clock Gating for each root port is enabled by + platform modules. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieClockGating[12]; + +/** Offset 0x0BD3 - PCIe RootPort Power Gating + Describes whether the PCI Express Power Gating for each root port is enabled by + platform modules. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PciePowerGating[12]; + +/** Offset 0x0BDF - PCIe RootPort VISA Clock Gating + Describes whether the PCI Express VISA Clock Gating. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieVisaClockGating[12]; + +/** Offset 0x0BEB - PCIe RootPort AutoPower Gating + Describes the Auto Power Gating for per controller. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieAutoPowerGating[12]; + +/** Offset 0x0BF7 - PCIe RootPort PHY AutoPower Gating + Describes the PHY Auto Power Gating for per controller. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PciePhyAutoPowerGating; + +/** Offset 0x0BF8 - FOMS Control Policy + Choose the Foms Control Policy, Default = 0 + 0: Auto, 1: Gen3 Foms, 2: Gen4 Foms, 3: Gen3 and Gen4 Foms +**/ + UINT8 PcieFomsCp[12]; + +/** Offset 0x0C04 - EqPhBypass Control Policy + PCIe Equalization Phase Enable Control, Disabled (0x0) : Disable Phase + (Default), Enabled (0x1) : Enable Phase + 0: Auto, 1: Gen3 Foms, 2: Gen4 Foms, 3: Gen3 and Gen4 Foms +**/ + UINT8 PcieEqPhBypass[12]; + +/** Offset 0x0C10 - PCIE RP Ltr Max Snoop Latency + Latency Tolerance Reporting, Max Snoop Latency. +**/ + UINT16 PcieRpLtrMaxSnoopLatency[24]; + +/** Offset 0x0C40 - PCIE RP Ltr Max No Snoop Latency + Latency Tolerance Reporting, Max Non-Snoop Latency. +**/ + UINT16 PcieRpLtrMaxNoSnoopLatency[24]; + +/** Offset 0x0C70 - PCIE RP Snoop Latency Override Mode + Latency Tolerance Reporting, Snoop Latency Override Mode. +**/ + UINT8 PcieRpSnoopLatencyOverrideMode[28]; + +/** Offset 0x0C8C - PCIE RP Snoop Latency Override Multiplier + Latency Tolerance Reporting, Snoop Latency Override Multiplier. +**/ + UINT8 PcieRpSnoopLatencyOverrideMultiplier[28]; + +/** Offset 0x0CA8 - PCIE RP Snoop Latency Override Value + Latency Tolerance Reporting, Snoop Latency Override Value. +**/ + UINT16 PcieRpSnoopLatencyOverrideValue[24]; + +/** Offset 0x0CD8 - PCIE RP Non Snoop Latency Override Mode + Latency Tolerance Reporting, Non-Snoop Latency Override Mode. +**/ + UINT8 PcieRpNonSnoopLatencyOverrideMode[28]; + +/** Offset 0x0CF4 - PCIE RP Non Snoop Latency Override Multiplier + Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier. +**/ + UINT8 PcieRpNonSnoopLatencyOverrideMultiplier[28]; + +/** Offset 0x0D10 - PCIE RP Non Snoop Latency Override Value + Latency Tolerance Reporting, Non-Snoop Latency Override Value. +**/ + UINT16 PcieRpNonSnoopLatencyOverrideValue[24]; + +/** Offset 0x0D40 - PCIE RP Slot Power Limit Scale + Specifies scale used for slot power limit value. Leave as 0 to set to default. +**/ + UINT8 PcieRpSlotPowerLimitScale[28]; + +/** Offset 0x0D5C - PCIE RP Slot Power Limit Value + Specifies upper limit on power supplie by slot. Leave as 0 to set to default. +**/ + UINT16 PcieRpSlotPowerLimitValue[24]; + +/** Offset 0x0D8C - PCIE RP Enable Port8xh Decode + This member describes whether PCIE root port Port 8xh Decode is enabled. 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 PcieEnablePort8xhDecode; + +/** Offset 0x0D8D - PCIE Port8xh Decode Port Index + The Index of PCIe Port that is selected for Port8xh Decode (1 Based). +**/ + UINT8 PchPciePort8xhDecodePortIndex; + +/** Offset 0x0D8E - PCIE RP LTR Override Spec Compliant + Override LTR based on Ep capability. +**/ + UINT8 PcieRpLtrOverrideSpecCompliant[28]; + +/** Offset 0x0DAA - PCIe AER _OSC Setting + Enable/Disable Global PCIe Advanced Error Reporting + 0:Disable, 1:Enable +**/ + UINT8 GlobalPcieAer; + +/** Offset 0x0DAB - PCIe TBT Performance Boost Bitmap + Bitmap of TBT performance boost enabled PCIe controllers to which discrete TBT controllers + connect. Bit0: PXPA, Bit1: PXPB, Bit2: PXPC, Bit3: PXPD, Bit4: PXPE +**/ + UINT8 PcieTbtPerfBoost; + +/** Offset 0x0DAC - Serial IO SPI CLK Pin Muxing + Select SerialIo LPSS SPI CS pin muxing. Refer to GPIO_*_MUXING_SERIALIO_SPIx_CLK* + for possible values. +**/ + UINT32 SerialIoLpssSpiClkPinMux[7]; + +/** Offset 0x0DC8 - Serial IO SPI CS Pin Muxing + Select SerialIo LPSS SPI CS pin muxing. Refer to GPIO_*_MUXING_SERIALIO_SPIx_CS* + for possible values. +**/ + UINT32 SerialIoLpssSpiCsPinMux[14]; + +/** Offset 0x0E00 - SPIn Device Mode + Selects SPI operation mode. N represents controller index: SPI0, SPI1, ... Available + modes: 0:LpssSpiDisabled, 1:LpssSpiPci, 2:LpssSpiHidden +**/ + UINT8 SerialIoLpssSpiMode[7]; + +/** Offset 0x0E07 - Reserved +**/ + UINT8 Reserved7; + +/** Offset 0x0E08 - LPSS SPI MOSI Pin Muxing + Select LPSS SPI MOSI pin muxing. Refer to GPIO_*_MUXING_LPSS_SPIx_MOSI* for possible values. +**/ + UINT32 SerialIoLpssSpiMosiPinMux[7]; + +/** Offset 0x0E24 - LPSS SPI MISO Pin Muxing + Select Lpss SPI MISO pin muxing. Refer to GPIO_*_MUXING_LPSS_SPIx_MISO* for possible values. +**/ + UINT32 SerialIoLpssSpiMisoPinMux[7]; + +/** Offset 0x0E40 - SPI Chip Select Polarity + Sets polarity for each chip Select. Available options: 0:LpssSpiCsActiveLow, 1:LpssSpiCsActiveHigh +**/ + UINT8 SerialIoLpssSpiCsPolarity[14]; + +/** Offset 0x0E4E - SPI Chip Select Enable + 0:Disabled, 1:Enabled. Enables GPIO for CS0 or CS1 if it is Enabled +**/ + UINT8 SerialIoLpssSpiCsEnable[14]; + +/** Offset 0x0E5C - SPIn Default Chip Select Mode HW/SW + Sets Default CS Mode Hardware or Software. N represents controller index: SPI0, + SPI1, ... Available options: 0:HW, 1:SW +**/ + UINT8 SerialIoLpssSpiCsMode[7]; + +/** Offset 0x0E63 - SPIn Default Chip Select State Low/High + Sets Default CS State Low or High. N represents controller index: SPI0, SPI1, ... + Available options: 0:Low, 1:High +**/ + UINT8 SerialIoLpssSpiCsState[7]; + +/** Offset 0x0E6A - UARTn Device Mode + Selects Uart operation mode. N represents controller index: Uart0, Uart1, ... Available + modes: 0:SerialIoUartDisabled, 1:SerialIoUartPci, 2:SerialIoUartHidden, 3:SerialIoUartCom, + 4:SerialIoUartSkipInit +**/ + UINT8 SerialIoUartMode[7]; + +/** Offset 0x0E71 - Reserved +**/ + UINT8 Reserved8[3]; + +/** Offset 0x0E74 - Default BaudRate for each Serial IO UART + Set default BaudRate Supported from 0 - default to 6000000 +**/ + UINT32 SerialIoUartBaudRate[7]; + +/** Offset 0x0E90 - Default ParityType for each Serial IO UART + Set default Parity. 0: DefaultParity, 1: NoParity, 2: EvenParity, 3: OddParity +**/ + UINT8 SerialIoUartParity[7]; + +/** Offset 0x0E97 - Default DataBits for each Serial IO UART + Set default word length. 0: Default, 5,6,7,8 +**/ + UINT8 SerialIoUartDataBits[7]; + +/** Offset 0x0E9E - Default StopBits for each Serial IO UART + Set default stop bits. 0: DefaultStopBits, 1: OneStopBit, 2: OneFiveStopBits, 3: + TwoStopBits +**/ + UINT8 SerialIoUartStopBits[7]; + +/** Offset 0x0EA5 - Power Gating mode for each Serial IO UART that works in COM mode + Set Power Gating. 0: Disabled, 1: Enabled, 2: Auto +**/ + UINT8 SerialIoUartPowerGating[7]; + +/** Offset 0x0EAC - Enable Dma for each Serial IO UART that supports it + Set DMA/PIO mode. 0: Disabled, 1: Enabled +**/ + UINT8 SerialIoUartDmaEnable[7]; + +/** Offset 0x0EB3 - Enables UART hardware flow control, CTS and RTS lines + Enables UART hardware flow control, CTS and RTS lines. +**/ + UINT8 SerialIoUartAutoFlow[7]; + +/** Offset 0x0EBA - Reserved +**/ + UINT8 Reserved9[2]; + +/** Offset 0x0EBC - SerialIoUartRtsPinMuxPolicy + Select SerialIo Uart Rts pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RTS* + for possible values. +**/ + UINT32 SerialIoUartRtsPinMuxPolicy[7]; + +/** Offset 0x0ED8 - SerialIoUartRxPinMuxPolicy + Select SerialIo Uart Rx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RX* for + possible values. +**/ + UINT32 SerialIoUartRxPinMuxPolicy[7]; + +/** Offset 0x0EF4 - SerialIoUartTxPinMuxPolicy + Select SerialIo Uart Tx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_TX* for + possible values. +**/ + UINT32 SerialIoUartTxPinMuxPolicy[7]; + +/** Offset 0x0F10 - Serial IO UART DBG2 table + Enable or disable Serial Io UART DBG2 table, default is Disable; 0: Disable; + 1: Enable. +**/ + UINT8 SerialIoUartDbg2[7]; + +/** Offset 0x0F17 - Serial IO UART PG DBG2 table + Enable or disable Serial Io UART PG DBG2 table, default is Disable; 0: Disable; + 1: Enable. +**/ + UINT8 SerialIoUartPgDbg2[7]; + +/** Offset 0x0F1E - I2Cn Device Mode + Selects I2c operation mode. N represents controller index: I2c0, I2c1, ... Available + modes: 0:SerialIoI2cDisabled, 1:SerialIoI2cPci, 2:SerialIoI2cHidden +**/ + UINT8 SerialIoI2cMode[8]; + +/** Offset 0x0F26 - Reserved +**/ + UINT8 Reserved10[2]; + +/** Offset 0x0F28 - Serial IO I2C SDA Pin Muxing + Select SerialIo I2c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SDA* for + possible values. +**/ + UINT32 PchSerialIoI2cSdaPinMux[8]; + +/** Offset 0x0F48 - Serial IO I2C SCL Pin Muxing + Select SerialIo I2c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SCL* for + possible values. +**/ + UINT32 PchSerialIoI2cSclPinMux[8]; + +/** Offset 0x0F68 - PCH SerialIo I2C Pads Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C0,I2C1,... pads termination + respectively. One byte for each controller, byte0 for I2C0, byte1 for I2C1, and so on. +**/ + UINT8 PchSerialIoI2cPadsTermination[8]; + +/** Offset 0x0F70 - I3C Device Mode + Selects I3c operation mode. Available modes: 0:SerialIoI3cDisabled, 1:SerialIoI3cPci, + 2:SerialIoI3cPhantom (only applicable to I3C1, controlls GPIO enabling) +**/ + UINT8 SerialIoI3cMode[3]; + +/** Offset 0x0F73 - Reserved +**/ + UINT8 Reserved11; + +/** Offset 0x0F74 - Serial IO I3C SDA Pin Muxing + Select SerialIo I3c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SDA* for + possible values. +**/ + UINT32 SerialIoI3cSdaPinMux[3]; + +/** Offset 0x0F80 - Serial IO I3C SDA Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSdaPadTermination[3]; + +/** Offset 0x0F83 - Reserved +**/ + UINT8 Reserved12; + +/** Offset 0x0F84 - Serial IO I3C SCL Pin Muxing + Select SerialIo I3c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SCL* for + possible values. +**/ + UINT32 SerialIoI3cSclPinMux[3]; + +/** Offset 0x0F90 - Serial IO I3C SCL Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSclPadTermination[3]; + +/** Offset 0x0F93 - Reserved +**/ + UINT8 Reserved13; + +/** Offset 0x0F94 - Serial IO I3C SCL FB Pin Muxing + Select SerialIo I3c SclFb pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SCL FB* + for possible values. +**/ + UINT32 SerialIoI3cSclFbPinMux[3]; + +/** Offset 0x0FA0 - Serial IO I3C SCL FB Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSclFbPadTermination[3]; + +/** Offset 0x0FA3 - Enable VMD controller + Enable/disable to VMD controller.0: Disable; 1: Enable(Default) + $EN_DIS +**/ + UINT8 VmdEnable; + +/** Offset 0x0FA4 - Enable VMD Global Mapping + Enable/disable to VMD controller.0: Disable(Default); 1: Enable + $EN_DIS +**/ + UINT8 VmdGlobalMapping; + +/** Offset 0x0FA5 - Map port under VMD + Map/UnMap port under VMD + $EN_DIS +**/ + UINT8 VmdPort[31]; + +/** Offset 0x0FC4 - VMD Port Bus + VMD Root port bus number. +**/ + UINT8 VmdPortBus[31]; + +/** Offset 0x0FE3 - VMD Port Device + VMD Root port device number. +**/ + UINT8 VmdPortDev[31]; + +/** Offset 0x1002 - VMD Port Func + VMD Root port function number. +**/ + UINT8 VmdPortFunc[31]; + +/** Offset 0x1021 - Reserved +**/ + UINT8 Reserved14[7]; + +/** Offset 0x1028 - VMD Variable + VMD Variable Pointer. +**/ + UINT64 VmdVariablePtr; + +/** Offset 0x1030 - Temporary CfgBar address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdCfgBarBase; + +/** Offset 0x1034 - Temporary MemBar1 address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdMemBar1Base; + +/** Offset 0x1038 - Temporary MemBar2 address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdMemBar2Base; + +/** Offset 0x103C - Enable D3 Hot in TCSS This policy will enable/disable D3 hot support in IOM $EN_DIS **/ UINT8 D3HotEnable; -/** Offset 0x103D - Reserved +/** Offset 0x103D - TCSS TBT Performance Boost Bitmap + Bitmap of TBT performance boost enabled TCSS PCIe root ports. Bit0: TCSS port0, + Bit1: TCSS port1, Bit2: TCSS port2, Bit3: TCSS port3 **/ - UINT8 Reserved34[3]; + UINT8 TcssTbtPerfBoost; + +/** Offset 0x103E - Reserved +**/ + UINT8 Reserved15[2]; /** Offset 0x1040 - TypeC port GPIO setting GPIO Ping number for Type C Aux orientation setting, use the GpioPad that is defined @@ -1508,9 +2499,17 @@ typedef struct { **/ UINT8 TcCstateLimit; -/** Offset 0x107C - Reserved +/** Offset 0x107C - TC Notify Igd + Tc Notify Igd **/ - UINT8 Reserved35[2]; + UINT8 TcNotifyIgd; + +/** Offset 0x107D - TCSS CPU USB PDO Programming + Enable/disable PDO programming for TCSS CPU USB in PEI phase. Disabling will allow + for programming during later phase. 1: enable, 0: disable + $EN_DIS +**/ + UINT8 TcssCpuUsbPdoProgramming; /** Offset 0x107E - Enable/Disable PMC-PD Solution This policy will enable/disable PMC-PD Solution vs EC-TCPC Solution @@ -1520,7 +2519,7 @@ typedef struct { /** Offset 0x107F - Reserved **/ - UINT8 Reserved36; + UINT8 Reserved16; /** Offset 0x1080 - TCSS Aux Orientation Override Enable Bits 0, 2, ... 10 control override enables, bits 1, 3, ... 11 control overrides @@ -1594,9 +2593,11 @@ typedef struct { **/ UINT8 SaPcieItbtRpLtrConfigLock[4]; -/** Offset 0x10B6 - Reserved +/** Offset 0x10B6 - Type C Port x Convert to TypeA + Enable / Disable(default) Type C Port x Convert to TypeA + $EN_DIS **/ - UINT8 Reserved37[4]; + UINT8 EnableTcssCovTypeA[4]; /** Offset 0x10BA - Touch Host Controller Assignment Assign THC 0x0:ThcAssignmentNone, 0x1:ThcAssignmentThc0, 0x2:ThcAssignmentThc1 @@ -1620,9 +2621,276 @@ typedef struct { **/ UINT8 ThcWakeOnTouch[2]; -/** Offset 0x10C8 - Reserved +/** Offset 0x10C8 - Touch Host Controller Active Ltr + Expose Active Ltr for OS driver to set +**/ + UINT32 ThcActiveLtr[2]; + +/** Offset 0x10D0 - Touch Host Controller Idle Ltr + Expose Idle Ltr for OS driver to set +**/ + UINT32 ThcIdleLtr[2]; + +/** Offset 0x10D8 - Touch Host Controller Timestamp timer behavior in D0i2 + Timestamp timer behavior in D0i2. 1 = Timer resets to 0 when entering D0i2 0 = Timer + is paused instead of reset to 0 when entering D0i2 +**/ + UINT8 TimestampTimerMode[2]; + +/** Offset 0x10DA - Reserved +**/ + UINT8 Reserved17[2]; + +/** Offset 0x10DC - Touch Host Controller Display Frame Sync Period + Period of the emulated display frame sync [ms] The minimum period is 2ms, maximum + period is 100ms +**/ + UINT32 DisplayFrameSyncPeriod[2]; + +/** Offset 0x10E4 - Touch Host Controller ResetPad + ResetPad +**/ + UINT32 ThcResetPad[2]; + +/** Offset 0x10EC - Touch Host Controller ResetPad Trigger + Hid Over Spi Reset Pad Trigger 0x0:Low, 0x1:High +**/ + UINT32 ThcResetPadTrigger[2]; + +/** Offset 0x10F4 - Touch Host Controller DYSync + Based on this setting GPIO for given THC will be in native mode +**/ + UINT8 ThcDsyncPad[2]; + +/** Offset 0x10F6 - Reserved +**/ + UINT8 Reserved18[2]; + +/** Offset 0x10F8 - Touch Host Controller Hid Over Spi Connection Speed + Hid Over Spi Connection Speed - SPI Frequency +**/ + UINT32 ThcHidSpiConnectionSpeed[2]; + +/** Offset 0x1100 - Touch Host Controller Hid Over Spi Limit PacketSize + When set, limits SPI read & write packet size to 64B. Otherwise, THC uses Max Soc + packet size for SPI Read and Write 0x0- Max Soc Packet Size, 0x11 - 64 Bytes +**/ + UINT32 ThcHidSpiLimitPacketSize[2]; + +/** Offset 0x1108 - Touch Host Controller Hid Over Spi Limit PacketSize + Minimum amount of delay the THC/QUICKSPI driver must wait between end of write operation + and begin of read operation. This value shall be in 10us multiples 0x0: Disabled, + 1-65535 (0xFFFF) - up to 655350 us +**/ + UINT32 ThcPerformanceLimitation[2]; + +/** Offset 0x1110 - Touch Host Controller Hid Over Spi Input Report Header Address + Hid Over Spi Input Report Header Address +**/ + UINT32 ThcHidSpiInputReportHeaderAddress[2]; + +/** Offset 0x1118 - Touch Host Controller Hid Over Spi Input Report Body Address + Hid Over Spi Input Report Body Address +**/ + UINT32 ThcHidSpiInputReportBodyAddress[2]; + +/** Offset 0x1120 - Touch Host Controller Hid Over Spi Output Report Address + Hid Over Spi Output Report Address +**/ + UINT32 ThcHidSpiOutputReportAddress[2]; + +/** Offset 0x1128 - Touch Host Controller Hid Over Spi Read Opcode + Hid Over Spi Read Opcode +**/ + UINT32 ThcHidSpiReadOpcode[2]; + +/** Offset 0x1130 - Touch Host Controller Hid Over Spi Write Opcode + Hid Over Spi Write Opcode +**/ + UINT32 ThcHidSpiWriteOpcode[2]; + +/** Offset 0x1138 - Touch Host Controller Hid Over Spi Flags + Hid Over Spi Flags 0x0:Single SPI Mode, 0x4000:Dual SPI Mode, 0x8000:Quad SPI Mode +**/ + UINT32 ThcHidSpiFlags[2]; + +/** Offset 0x1140 - Touch Host Controller Reset Sequencing Delay [ms] + Policy control for reset sequencing delay (ACPI _INI, _RST) default 300ms +**/ + UINT16 ThcResetSequencingDelay[2]; + +/** Offset 0x1144 - Touch Host Controller Hid Over I2c Device Address + Hid Over I2c Device Address +**/ + UINT32 ThcHidI2cDeviceAddress[2]; + +/** Offset 0x114C - Touch Host Controller Hid Over I2c Connection Speed + Hid Over I2c Connection Speed [Hz] +**/ + UINT32 ThcHidI2cConnectionSpeed[2]; + +/** Offset 0x1154 - Touch Host Controller Hid Over I2c Addressing Mode + Hid Over I2c Addressing Mode - 0x1: The connection uses 10-bit addressing. 0x0: + The connection uses 7-bit addressing. +**/ + UINT8 ThcHidI2cAddressingMode[2]; + +/** Offset 0x1156 - Reserved +**/ + UINT8 Reserved19[2]; + +/** Offset 0x1158 - Touch Host Controller Hid Over I2c Device Descriptor Address + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cDeviceDescriptorAddress[2]; + +/** Offset 0x1160 - Touch Host Controller Hid Over I2c Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialClockLineHighPeriod[2]; + +/** Offset 0x1168 - Touch Host Controller Hid Over I2c Standard Mode Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialClockLineLowPeriod[2]; + +/** Offset 0x1170 - Touch Host Controller Hid Over I2c Standard Mode Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x1178 - Touch Host Controller Hid Over I2c Standard Mode Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x1180 - Touch Host Controller Hid Over I2c Fast Mode Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialClockLineHighPeriod[2]; + +/** Offset 0x1188 - Touch Host Controller Hid Over I2c Fast Mode Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialClockLineLowPeriod[2]; + +/** Offset 0x1190 - Touch Host Controller Hid Over I2c Fast Mode Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x1198 - Touch Host Controller Hid Over I2c Fast Mode Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11A0 - Touch Host Controller Hid Over I2c Maximum Length Of Suppressed Spikes In Std Mode Fast Mode And Fast Mode Plus + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cMaxSuppressedSpikesSMFMFMP[2]; + +/** Offset 0x11A8 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialClockLineHighPeriod[2]; + +/** Offset 0x11B0 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialClockLineLowPeriod[2]; + +/** Offset 0x11B8 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x11C0 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11C8 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Clock Line High Period + Hid Over I2c Device Descriptor Address **/ - UINT8 Reserved38[337]; + UINT32 ThcHidI2cHighSpeedModePlusSerialClockLineHighPeriod[2]; + +/** Offset 0x11D0 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialClockLineLowPeriod[2]; + +/** Offset 0x11D8 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x11E0 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11E8 - Touch Host Controller Hid Over I2c Maximum Length Of Suppressed Spikes In High Speed Mode + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cMaximumLengthOfSuppressedSpikesInHighSpeedMode[2]; + +/** Offset 0x11F0 - THC Wake On Touch GPIO resource Edge or Level + Definition of GPIO resource configuration of Edge or Level +**/ + UINT8 ThcWotEdgeLevel[2]; + +/** Offset 0x11F2 - THC Wake On Touch GPIO resource of Active Level + Definition of GPIO resource configuration of Active Level +**/ + UINT8 ThcWotActiveLevel[2]; + +/** Offset 0x11F4 - THC Wake On Touch GPIO resource of pin configuration + Definition of GPIO resource configuration of pin configuration +**/ + UINT8 ThcWotPinConfig[2]; + +/** Offset 0x11F6 - THC customized SubSytem ID for Port + Definition of GPIO resource configuration of pin configuration +**/ + UINT16 ThcCustomizedSsid[2]; + +/** Offset 0x11FA - THC Sets Customized SubSytem Vendor ID for Port + Definition of GPIO resource configuration of pin configuration +**/ + UINT16 ThcCustomizedSvid[2]; + +/** Offset 0x11FE - Reserved +**/ + UINT8 Reserved20[2]; + +/** Offset 0x1200 - USB 3.1 Speed Selection + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT32 Usb31PortSpeed; + +/** Offset 0x1204 - Touch Host Controller Hid Over I2c Maximum Frame Size Enable + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT8 ThcHidI2cMaxFrameSize[2]; + +/** Offset 0x1206 - Touch Host Controller Hid Over I2c Maximum Frame Size Value + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT16 ThcHidI2cMaxFrameSizeValue[2]; + +/** Offset 0x120A - Touch Host Controller Hid Over I2c Interrupt Delay Enable + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT8 ThcHidI2cIntDelay[2]; + +/** Offset 0x120C - Touch Host Controller Hid Over I2c Interrupt Delay Value + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT16 ThcHidI2cIntDelayValue[2]; + +/** Offset 0x1210 - Reserved +**/ + UINT8 Reserved21[9]; /** Offset 0x1219 - PCHHOT# pin Enable PCHHOT# pin assertion when temperature is higher than PchHotLevel. 0: disable, 1: enable @@ -1683,7 +2951,47 @@ typedef struct { /** Offset 0x122A - Reserved **/ - UINT8 Reserved39[34]; + UINT8 Reserved22[2]; + +/** Offset 0x122C - PCH TSN MAC Address High Bits + Set TSN MAC Address High. +**/ + UINT32 PchTsn1MacAddressHigh; + +/** Offset 0x1230 - PCH TSN MAC Address Low Bits + Set TSN MAC Address Low. +**/ + UINT32 PchTsn1MacAddressLow; + +/** Offset 0x1234 - PCH TSN2 MAC Address High Bits + Set TSN2 MAC Address High. +**/ + UINT32 PchTsn2MacAddressHigh; + +/** Offset 0x1238 - PCH TSN2 MAC Address Low Bits + Set TSN2 MAC Address Low. +**/ + UINT32 PchTsn2MacAddressLow; + +/** Offset 0x123C - PCH TSN3 MAC Address High Bits + Set TSN3 MAC Address High. +**/ + UINT32 PchTsn3MacAddressHigh; + +/** Offset 0x1240 - PCH TSN3 MAC Address Low Bits + Set TSN3 MAC Address Low. +**/ + UINT32 PchTsn3MacAddressLow; + +/** Offset 0x1244 - PCH TSN4 MAC Address High Bits + Set TSN4 MAC Address High. +**/ + UINT32 PchTsn4MacAddressHigh; + +/** Offset 0x1248 - PCH TSN MAC4 Address Low Bits + Set TSN MAC4 Address Low. +**/ + UINT32 PchTsn4MacAddressLow; /** Offset 0x124C - Enable USB2 ports Enable/disable per USB2 ports. One byte for each port, byte0 for port0, byte1 for @@ -1710,9 +3018,11 @@ typedef struct { **/ UINT8 UsbPdoProgramming; -/** Offset 0x1268 - Reserved +/** Offset 0x1268 - USB Audio Offload enable + Enable/Disable USB Audio Offload capabilites. 0: disabled, 1: enabled (default) + $EN_DIS **/ - UINT8 Reserved40; + UINT8 PchXhciUaolEnable; /** Offset 0x1269 - PCH USB OverCurrent mapping enable 1: Will program USB OC pin mapping in xHCI controller memory, 0: Will clear OC pin @@ -1737,9 +3047,15 @@ typedef struct { **/ UINT8 PchUsbLtrOverrideEnable; -/** Offset 0x1285 - Reserved +/** Offset 0x1285 - USB DWB enable + Enable/Disable USB DWB. 0: disabled, 1: enabled (default) + $EN_DIS +**/ + UINT8 PchXhciDwbEnable; + +/** Offset 0x1286 - Reserved **/ - UINT8 Reserved41[3]; + UINT8 Reserved23[2]; /** Offset 0x1288 - xHCI High Idle Time LTR override Value used for overriding LTR recommendation for xHCI High Idle Time LTR setting @@ -1897,9 +3213,21 @@ typedef struct { **/ UINT8 Usb3HsioTxRate0UniqTran[10]; -/** Offset 0x13AD - Reserved +/** Offset 0x13AD - PCIe Fia Programming + Load Fia configuration if enable. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieFiaProgramming; + +/** Offset 0x13AE - Enable SSE Device + Test, 0: POR, 1: enable, 2: disable, Enable/Disable SSE/SSE++ Devices from PCI config space + $EN_DIS +**/ + UINT8 SseCommunication; + +/** Offset 0x13AF - Reserved **/ - UINT8 Reserved42[4]; + UINT8 Reserved24[2]; /** Offset 0x13B1 - Enable/Disable NPU Device Enable(Default): Enable NPU Device, Disable: Disable NPU Device @@ -1919,9 +3247,11 @@ typedef struct { **/ UINT8 PchLanLtrEnable; -/** Offset 0x13B4 - Reserved +/** Offset 0x13B4 - PCH Lan WOL Fast Support + Enables bit B_PCH_ACPI_GPE0_EN_127_96_PME_B0 during PchLanSxCallback in PchLanSxSmm. + $EN_DIS **/ - UINT8 Reserved43; + UINT8 PchLanWOLFastSupport; /** Offset 0x13B5 - Skip Ssid Programming. When set to TRUE, silicon code will not do any SSID programming and platform code @@ -1942,9 +3272,15 @@ typedef struct { **/ UINT16 SiCustomizedSsid; -/** Offset 0x13BA - Reserved +/** Offset 0x13BA - CAN Configurations + Enable/Disable CAN Controllers.0: Disable, 1: Enable + $EN_DIS +**/ + UINT8 PchCanEnable[2]; + +/** Offset 0x13BC - Reserved **/ - UINT8 Reserved44[6]; + UINT8 Reserved25[4]; /** Offset 0x13C0 - SVID SDID table Poniter. The address of the table of SVID SDID to customize each SVID SDID entry. This is @@ -1958,9 +3294,15 @@ typedef struct { **/ UINT16 SiNumberOfSsidTableEntry; -/** Offset 0x13CA - Reserved +/** Offset 0x13CA - Skip DFX. + Skip DFX. + $EN_DIS +**/ + UINT8 DfxSkipBiosDone; + +/** Offset 0x13CB - Reserved **/ - UINT8 Reserved45[10]; + UINT8 Reserved26[9]; /** Offset 0x13D4 - LogoPixelHeight Address Address of LogoPixelHeight @@ -1974,7 +3316,7 @@ typedef struct { /** Offset 0x13DC - Reserved **/ - UINT8 Reserved46[4]; + UINT8 Reserved27[4]; /** Offset 0x13E0 - Blt Buffer Address Address of Blt buffer @@ -1992,9 +3334,11 @@ typedef struct { **/ UINT8 SkipFspGop; -/** Offset 0x13F1 - Reserved +/** Offset 0x13F1 - Enable/Disable Media Configuration + Enable(Default): Configure Media for use, Disable: Skip Media Configuration + $EN_DIS **/ - UINT8 Reserved47; + UINT8 ConfigureMedia; /** Offset 0x13F2 - Enable/Disable IGFX RenderStandby Enable(Default): Enable IGFX RenderStandby, Disable: Disable IGFX RenderStandby @@ -2002,9 +3346,23 @@ typedef struct { **/ UINT8 RenderStandby; -/** Offset 0x13F3 - Reserved +/** Offset 0x13F3 - Enable/Disable GT Configuration + Enable(Default): Configure GT for use, Disable: Skip GT Configuration + $EN_DIS +**/ + UINT8 ConfigureGT; + +/** Offset 0x13F4 - Enable RC1p GT frequency request to PMA (provided all other conditions are met) + 0(Default)=Disable, 1=Enable + $EN_DIS +**/ + UINT8 RC1pGtFreqEnable; + +/** Offset 0x13F5 - Enable RC1p Media frequency request to PMA (provided all other conditions are met) + 0(Default)=Disable, 1=Enable + $EN_DIS **/ - UINT8 Reserved48[3]; + UINT8 RC1pMediaFreqEnable; /** Offset 0x13F6 - Enable/Disable PavpEnable Enable(Default): Enable PavpEnable, Disable: Disable PavpEnable @@ -2019,9 +3377,21 @@ typedef struct { **/ UINT8 PeiGraphicsPeimInit; -/** Offset 0x13F8 - Reserved +/** Offset 0x13F8 - Enable/Disable IGFX Media Standby + Enable(Default): Enable IGFX Media Standby, Disable: Disable IGFX MediaStandby + $EN_DIS +**/ + UINT8 MediaStandby; + +/** Offset 0x13F9 - Enable/Disable Gfx Workstation + Enable(Default): Is a workstation, Disable: Is not a workstation + $EN_DIS +**/ + UINT8 Dev2IsGfxWorkstation; + +/** Offset 0x13FA - Reserved **/ - UINT8 Reserved49[4]; + UINT8 Reserved28[2]; /** Offset 0x13FC - Intel Graphics VBT (Video BIOS Table) Size Size of Internal Graphics VBT Image @@ -2042,7 +3412,21 @@ typedef struct { /** Offset 0x1402 - Reserved **/ - UINT8 Reserved50[66]; + UINT8 Reserved29[2]; + +/** Offset 0x1404 - HorizontalResolution for PEI Logo + HorizontalResolution from PEIm Gfx for PEI Logo +**/ + UINT32 HorizontalResolution; + +/** Offset 0x1408 - VerticalResolution for PEI Logo + VerticalResolution from PEIm Gfx for PEI Logo +**/ + UINT32 VerticalResolution; + +/** Offset 0x140C - Reserved +**/ + UINT8 Reserved30[56]; /** Offset 0x1444 - Address of PCH_DEVICE_INTERRUPT_CONFIG table. The address of the table of PCH_DEVICE_INTERRUPT_CONFIG. @@ -2076,9 +3460,33 @@ typedef struct { **/ UINT8 TcoIrqEnable; -/** Offset 0x144D - Reserved +/** Offset 0x144D - PMC ADR enable + Enable/disable asynchronous DRAM refresh + $EN_DIS +**/ + UINT8 PmcAdrEn; + +/** Offset 0x144E - PMC ADR timer configuration enable + Enable/disable ADR timer configuration + $EN_DIS +**/ + UINT8 PmcAdrTimerEn; + +/** Offset 0x144F - PMC ADR phase 1 timer value + Enable/disable ADR timer configuration +**/ + UINT8 PmcAdrTimer1Val; + +/** Offset 0x1450 - PMC ADR phase 1 timer multiplier value + Specify the multiplier value for phase 1 ADR timer +**/ + UINT8 PmcAdrMultiplier1Val; + +/** Offset 0x1451 - PMC ADR host reset partition enable + Specify whether PMC should set ADR_RST_STS bit after receiving Reset_Warn_Ack DMI message + $EN_DIS **/ - UINT8 Reserved51[5]; + UINT8 PmcAdrHostPartitionReset; /** Offset 0x1452 - Mask to enable the usage of external V1p05 VR rail in specific S0ix or Sx states Enable External V1P05 Rail in: BIT0:S0i1/S0i2, BIT1:S0i3, BIT2:S3, BIT3:S4, BIT5:S5 @@ -2112,7 +3520,7 @@ typedef struct { /** Offset 0x1459 - Reserved **/ - UINT8 Reserved52; + UINT8 Reserved31; /** Offset 0x145A - External Vnn Voltage Value that will be used in S0ix/Sx states Value is given in 2.5mV increments (0=0mV, 1=2.5mV, 2=5mV...), Default is set to 420 @@ -2173,7 +3581,7 @@ typedef struct { /** Offset 0x1467 - Reserved **/ - UINT8 Reserved53; + UINT8 Reserved32; /** Offset 0x1468 - External V1P05 Icc Max Value Granularity of this setting is 1mA and maximal possible value is 500mA @@ -2213,9 +3621,11 @@ typedef struct { **/ UINT8 PchLegacyIoLowLatency; -/** Offset 0x1472 - Reserved +/** Offset 0x1472 - PCH P2SB + PCH P2SB + $EN_DIS **/ - UINT8 Reserved54; + UINT8 SvTestUnhideP2sb; /** Offset 0x1473 - PCH Unlock SideBand access The SideBand PortID mask for certain end point (e.g. PSFx) will be locked before @@ -2282,9 +3692,19 @@ typedef struct { **/ UINT8 CnviBtAudioOffload; -/** Offset 0x147D - Reserved +/** Offset 0x147D - WWAN Coex + WWAN Coex is getting updated from UEFI variable +**/ + UINT8 CnviWwanCoex; + +/** Offset 0x147E - Skip BtPreInit + BtPreInit can be skipped if SkipBtPreInit is enabled **/ - UINT8 Reserved55[3]; + UINT8 SkipBtPreInit; + +/** Offset 0x147F - Reserved +**/ + UINT8 Reserved33; /** Offset 0x1480 - CNVi RF_RESET pin muxing Select CNVi RF_RESET# pin depending on board routing. LP/P/M: GPP_A8 = 0x2942E408(default) @@ -2299,9 +3719,11 @@ typedef struct { **/ UINT32 CnviClkreqPinMux; -/** Offset 0x1488 - Reserved +/** Offset 0x1488 - CNVi BT Audio OffOffloadInterfaceload + Enable/Disable BT Audio OffloadInterface, Default is ENABLE. 0: DISABLE, 1: ENABLE + $EN_DIS **/ - UINT8 Reserved56; + UINT8 CnviBtAudioOffloadInterface; /** Offset 0x1489 - Enable Device 4 Enable/disable Device 4 @@ -2316,9 +3738,10 @@ typedef struct { **/ UINT8 SkipPamLock; -/** Offset 0x148B - Reserved +/** Offset 0x148B - TCSS LSx OE Enable + Bits 0, 1, ... max Type C Rettimerless port LSx OE enables **/ - UINT8 Reserved57; + UINT8 TcssLsxOe; /** Offset 0x148C - PCH HDA Verb Table Entry Number Number of Entries in Verb Table. @@ -2327,7 +3750,7 @@ typedef struct { /** Offset 0x148D - Reserved **/ - UINT8 Reserved58[3]; + UINT8 Reserved34[3]; /** Offset 0x1490 - PCH HDA Verb Table Pointer Pointer to Array of pointers to Verb Table. @@ -2359,9 +3782,11 @@ typedef struct { **/ UINT8 PchHdaMicPrivacyMode; -/** Offset 0x149C - Reserved +/** Offset 0x149C - HD Audio Microphone Privacy Deglitch + HD Audio Microphone Privacy Deglitch: 0: Disable, 1: Enable + $EN_DIS **/ - UINT8 Reserved59; + UINT8 PchHdaMicPrivacyDeglitch; /** Offset 0x149D - HD Audio Microphone Privacy applied for SoundWire Link number 0 in HW Mode HD Audio Microphone Privacy applied for SoundWire Link number 0 in HW Mode: 0: Disable, 1: Enable @@ -2401,7 +3826,17 @@ typedef struct { /** Offset 0x14A3 - Reserved **/ - UINT8 Reserved60[13]; + UINT8 Reserved35; + +/** Offset 0x14A4 - HD Audio Microphone Privacy Timeout. Indicates the time-out duration to wait before forcing the actual microphone privacy DMA data zeroing. + HD Audio Microphone Privacy Timeout. Indicates the time-out duration to wait before + forcing the actual microphone privacy DMA data zeroing. +**/ + UINT32 PchHdaMicPrivacyTimeout; + +/** Offset 0x14A8 - Reserved +**/ + UINT8 Reserved36[8]; /** Offset 0x14B0 - Pointer to ChipsetInit Binary ChipsetInit Binary Pointer. @@ -2415,7 +3850,49 @@ typedef struct { /** Offset 0x14BC - Reserved **/ - UINT8 Reserved61[36]; + UINT8 Reserved37[4]; + +/** Offset 0x14C0 - Pointer to NPHY Binary + Nphy Binary Pointer. +**/ + UINT64 NphyBinPtr; + +/** Offset 0x14C8 - Length of NPHY Binary + Nphy Binary Length. +**/ + UINT32 NphyBinLen; + +/** Offset 0x14CC - Reserved +**/ + UINT8 Reserved38[4]; + +/** Offset 0x14D0 - Pointer to SYNPS PHY Binary + Synps Binary Pointer. +**/ + UINT64 SynpsPhyBinPtr; + +/** Offset 0x14D8 - Length of SYNPS PHY Binary + Synps Binary Length. +**/ + UINT32 SynpsPhyBinLen; + +/** Offset 0x14DC - Skip setting BIOS_DONE When Fw Update. + When set to TRUE and boot mode is BOOT_ON_FLASH_UPDATE,skip setting BIOS_DONE MSR + at EndofPei. Note: BIOS_DONE MSR should be set in later phase before executing + 3rd party code if SiSkipBiosDoneWhenFwUpdate set to TRUE. + $EN_DIS +**/ + UINT8 SiSkipBiosDoneWhenFwUpdate; + +/** Offset 0x14DD - PMC WDT enable + Enable/disable PMC WDT configuration + $EN_DIS +**/ + UINT8 PmcWdtTimerEn; + +/** Offset 0x14DE - Reserved +**/ + UINT8 Reserved39[2]; } FSP_S_CONFIG; /** Fsp S UPD Configuration diff --git a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/MemInfoHob.h b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/MemInfoHob.h index c89cf2cab1..a6d862368f 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/MemInfoHob.h +++ b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/MemInfoHob.h @@ -312,7 +312,8 @@ typedef struct _PPR_RESULT_COLUMNS_HOB { - DIMM_INFO: Added SerialNumber, TotalWidth and DataWidth - DIMM_INFO: Removed SpdModuleMemoryBusWidth - MFG ID fields: use HOB_MANUFACTURER_ID_CODE instead of UINT16 for easier parsing - + Revision 4: + - Added FailingChannelMask **/ typedef struct { UINT8 Revision; @@ -363,6 +364,7 @@ typedef struct { UINT8 MaxRankCapacity; ///< Maximum possible rank capacity in [GB] UINT16 PprFailingChannelBitMask; ///< PPR failing channel mask BOOLEAN PprTargetedStatus[PPR_REQUEST_MAX]; ///< PPR status of each Targeted PPR request (0 = Targeted PPR was successful, 1 = PPR failed) + UINT8 FailingChannelMask; ///< Limp Home mode failing channel bitmask } MEMORY_INFO_DATA_HOB; /** @@ -387,6 +389,9 @@ typedef struct { PSMI_MEM_INFO PsmiInfo[MAX_TRACE_CACHE_TYPE]; PSMI_MEM_INFO PsmiRegionInfo[MAX_TRACE_REGION]; BOOLEAN MrcBasicMemoryTestPass; + UINT8 Reserved1[3]; // Reserved for alignment + UINT64 BiosPeiMemoryBaseAddress; + UINT64 BiosPeiMemoryLength; } MEMORY_PLATFORM_DATA; typedef struct { From f89ac4e6ce267ce875f6ea40f4e907e47e24ee1e Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 23 Feb 2026 12:01:42 +0530 Subject: [PATCH 562/789] soc/mediatek/common: Adjust splash logo bottom margin Increase the logo_bottom_margin from 100 to 200 in the display_logo configuration if FRAMEBUFFER_SPLASH_TEXT Kconfig is enabled. This adjustment ensures the OEM footer logo and associated splash text are rendered higher on the screen, improving visibility and alignment with updated UX requirements. BUG=None TEST=Boot MediaTek device and verify the splash text is 200px from the screen bottom edge as expected. Change-Id: I490e50e200dfffedf24cb30fe0ca6ea6ae037d3d Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91383 Reviewed-by: Yidi Lin Reviewed-by: Kapil Porwal Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/soc/mediatek/common/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c index 9d2c873838..3b9d8be96c 100644 --- a/src/soc/mediatek/common/display.c +++ b/src/soc/mediatek/common/display.c @@ -90,7 +90,7 @@ static void display_logo(struct panel_description *panel, .panel_orientation = panel->orientation, .halignment = FW_SPLASH_HALIGNMENT_CENTER, .valignment = FW_SPLASH_VALIGNMENT_CENTER, - .logo_bottom_margin = 100, + .logo_bottom_margin = CONFIG(FRAMEBUFFER_SPLASH_TEXT) ? 200 : 100, }; render_logo_to_framebuffer(&config); From 6a1b0161842cbc53035877c73f1ae9a2f6f65810 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sun, 22 Feb 2026 17:08:27 +0100 Subject: [PATCH 563/789] nb/intel/haswell: Tidy up memory info prints Be consistent when printing the channel assignment, and use unsigned printf specifiers since the values themselves are unsigned. Change-Id: I66b93233707dec73dc7a25423789a24770ac678f Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91376 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Paul Menzel Reviewed-by: Benjamin Doron --- src/northbridge/intel/haswell/raminit_shared.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/northbridge/intel/haswell/raminit_shared.c b/src/northbridge/intel/haswell/raminit_shared.c index 6fcb0ec98a..1e6394da77 100644 --- a/src/northbridge/intel/haswell/raminit_shared.c +++ b/src/northbridge/intel/haswell/raminit_shared.c @@ -36,7 +36,7 @@ void report_memory_config(void) printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n", DIV_ROUND_CLOSEST(mchbar_read32(MC_BIOS_DATA) * 13333 * 2, 100)); - printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n", + printk(BIOS_DEBUG, "memcfg channel assignment: A: %u, B: %u, C: %u\n", (addr_decoder_common >> 0) & 3, (addr_decoder_common >> 2) & 3, (addr_decoder_common >> 4) & 3); @@ -44,7 +44,7 @@ void report_memory_config(void) for (unsigned int i = 0; i < NUM_CHANNELS; i++) { const uint32_t ch_conf = mchbar_read32(MAD_DIMM(i)); - printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n", i, ch_conf); + printk(BIOS_DEBUG, "memcfg channel[%u] config (%8.8x):\n", i, ch_conf); printk(BIOS_DEBUG, " ECC %s\n", ecc_decoder[(ch_conf >> 24) & 3]); printk(BIOS_DEBUG, " enhanced interleave mode %s\n", ((ch_conf >> 22) & 1) ? "on" : "off"); @@ -52,13 +52,13 @@ void report_memory_config(void) printk(BIOS_DEBUG, " rank interleave %s\n", ((ch_conf >> 21) & 1) ? "on" : "off"); - printk(BIOS_DEBUG, " DIMMA %d MB width %s %s rank%s\n", + printk(BIOS_DEBUG, " DIMMA %u MB width %s %s rank%s\n", ((ch_conf >> 0) & 0xff) * 256, ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32", ((ch_conf >> 17) & 1) ? "dual" : "single", ((ch_conf >> 16) & 1) ? "" : ", selected"); - printk(BIOS_DEBUG, " DIMMB %d MB width %s %s rank%s\n", + printk(BIOS_DEBUG, " DIMMB %u MB width %s %s rank%s\n", ((ch_conf >> 8) & 0xff) * 256, ((ch_conf >> 20) & 1) ? "x16" : "x8 or x32", ((ch_conf >> 18) & 1) ? "dual" : "single", From d9bc4740da9fbd945790fa618c0ae3ee6e6760b2 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sun, 22 Feb 2026 16:46:12 +0100 Subject: [PATCH 564/789] nb/intel/haswell: Fix DDR frequency reporting DDR frequency (in MHz) was doubled for no reason, then doubled again to convert it to MT/s. Moreover, the calculations assume a reference clock of 133 MHz, but a 100 MHz reference clock also exists. Add two functions: `is_100_mhz_refclk()` to check whether the reference clock is 100 MHz, and `get_ddr_freq_mhz()` to get the DDR frequency, in MHz. Use both functions in `report_memory_config()` to show the correct DDR ref. clock and frequency, and use one in `setup_sdram_meminfo()` so that SMBIOS tables contain the correct memory speed. Tested on ASRock Z97 Extreme6 with four DDR3-1600 sticks, DDR frequency is correctly reported as 800 MHz with either reference clock frequency: Default 133 MHz reference clock: memcfg DDR3 ref clock 133 MHz memcfg DDR3 clock 800 MHz After forcing 100 MHz ref clock for 800 MHz (edit NRI's `init_mpll.c`): memcfg DDR3 ref clock 100 MHz memcfg DDR3 clock 800 MHz Also, SMBIOS type 17 correctly reports memory speeds of 1600 MT/s: $ sudo dmidecode --type 17 | grep -i speed Speed: 1600 MT/s Configured Memory Speed: 1600 MT/s Speed: 1600 MT/s Configured Memory Speed: 1600 MT/s Speed: 1600 MT/s Configured Memory Speed: 1600 MT/s Speed: 1600 MT/s Configured Memory Speed: 1600 MT/s It is expected that behaviour using either MRC binary is the same since the `MC_BIOS_REQ` and `MC_BIOS_DATA` registers have to be programmed in order for the DDR clock to start running. The decision to test with NRI is because one can easily change the chosen reference clock to 100 MHz. Resolves: https://ticket.coreboot.org/issues/624 Change-Id: Idead9cd55b453d3ff4695c977dee763ff50830f8 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91375 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Benjamin Doron Reviewed-by: Matt DeVillier --- .../intel/haswell/raminit_shared.c | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/northbridge/intel/haswell/raminit_shared.c b/src/northbridge/intel/haswell/raminit_shared.c index 1e6394da77..5e3602c31e 100644 --- a/src/northbridge/intel/haswell/raminit_shared.c +++ b/src/northbridge/intel/haswell/raminit_shared.c @@ -28,13 +28,28 @@ static const char *const ecc_decoder[] = { "active", }; +static bool is_100_mhz_refclk(void) +{ + return mchbar_read32(MC_BIOS_REQ) & (1 << 4); +} + +static unsigned int get_ddr_freq_mhz(void) +{ + /* Use KHz to minimise rounding errors */ + const unsigned int refclk_khz = is_100_mhz_refclk() ? 100000 : 133333; + const unsigned int multiplier = mchbar_read32(MC_BIOS_DATA) & 0xf; + + return DIV_ROUND_CLOSEST(multiplier * refclk_khz, 1000); +} + /* Print out the memory controller configuration, as per the values in its registers. */ void report_memory_config(void) { const uint32_t addr_decoder_common = mchbar_read32(MAD_CHNL); - printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n", - DIV_ROUND_CLOSEST(mchbar_read32(MC_BIOS_DATA) * 13333 * 2, 100)); + const unsigned int refclk_mhz = is_100_mhz_refclk() ? 100 : 133; + printk(BIOS_DEBUG, "memcfg DDR3 ref clock %u MHz\n", refclk_mhz); + printk(BIOS_DEBUG, "memcfg DDR3 clock %u MHz\n", get_ddr_freq_mhz()); printk(BIOS_DEBUG, "memcfg channel assignment: A: %u, B: %u, C: %u\n", (addr_decoder_common >> 0) & 3, @@ -113,8 +128,7 @@ void setup_sdram_meminfo(const uint8_t *spd_data[NUM_CHANNELS][NUM_SLOTS]) memset(mem_info, 0, sizeof(struct memory_info)); - /* TODO: This looks like an open-coded DIV_ROUND_CLOSEST() */ - const uint32_t ddr_freq_mhz = (mchbar_read32(MC_BIOS_DATA) * 13333 * 2 + 50) / 100; + const uint32_t ddr_freq_mhz = get_ddr_freq_mhz(); unsigned int dimm_cnt = 0; for (unsigned int channel = 0; channel < NUM_CHANNELS; channel++) { From f96644e7743c26fb33dd99745675507f90ab285f Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sun, 22 Feb 2026 15:54:39 +0100 Subject: [PATCH 565/789] nb/intel/haswell: Do not print ME status twice The `intel_early_me_init_done()` function prints the ME status. In order to see the ME status once in all paths, have the aforementioned function only call `intel_early_me_status()` before handling a reset request. Change-Id: I42ad1b25889a21047b7cf55e7940293e73794d8b Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91374 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Benjamin Doron Reviewed-by: Matt DeVillier --- src/southbridge/intel/lynxpoint/early_me.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/southbridge/intel/lynxpoint/early_me.c b/src/southbridge/intel/lynxpoint/early_me.c index 07013c5539..6dab65238e 100644 --- a/src/southbridge/intel/lynxpoint/early_me.c +++ b/src/southbridge/intel/lynxpoint/early_me.c @@ -159,9 +159,6 @@ int intel_early_me_init_done(u8 status) printk(BIOS_NOTICE, "ME: Requested BIOS Action: %s\n", me_ack_values[hfs.ack_data]); - /* Check status after acknowledgement */ - intel_early_me_status(); - reset = 0; switch (hfs.ack_data) { case ME_HFS_ACK_CONTINUE: @@ -190,6 +187,9 @@ int intel_early_me_init_done(u8 status) /* Perform the requested reset */ if (reset) { + /* Show ME status before resetting */ + intel_early_me_status(); + outb(reset, 0xcf9); halt(); } From fd2cdf206d10d05353b852174ab39f9ae42084cf Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Fri, 30 Jan 2026 15:19:59 +0100 Subject: [PATCH 566/789] cpu/intel/smm/gen1: Optimize cpu_has_alternative_smrr For most targets it's known if the CPU supports alternative SMRR registers or not. Only on model_6fx runtime detection is necessary. On all platforms this allows the compiler to optimize the code and thus shrink the code size if alternative SMRR aren't supported. TEST=On Lenovo X220 the ramstage is 308 bytes smaller. Change-Id: I3a965d142f79ad587b8cedc9b4646b05e2a45f8b Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/91014 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/cpu/intel/model_1067x/mp_init.c | 2 +- src/cpu/intel/smm/gen1/smmrelocate.c | 19 ++++++++----------- src/include/cpu/intel/smm_reloc.h | 2 -- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/cpu/intel/model_1067x/mp_init.c b/src/cpu/intel/model_1067x/mp_init.c index bc53214310..8f04bf9ccc 100644 --- a/src/cpu/intel/model_1067x/mp_init.c +++ b/src/cpu/intel/model_1067x/mp_init.c @@ -48,7 +48,7 @@ static void pre_mp_smm_init(void) static void per_cpu_smm_trigger(void) { msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR); - if (cpu_has_alternative_smrr() && mtrr_cap.lo & SMRR_SUPPORTED) { + if (mtrr_cap.lo & SMRR_SUPPORTED) { set_feature_ctrl_vmx(); msr_t ia32_ft_ctrl = rdmsr(IA32_FEATURE_CONTROL); /* We don't care if the lock is already setting diff --git a/src/cpu/intel/smm/gen1/smmrelocate.c b/src/cpu/intel/smm/gen1/smmrelocate.c index c57a661ef7..6f3806dede 100644 --- a/src/cpu/intel/smm/gen1/smmrelocate.c +++ b/src/cpu/intel/smm/gen1/smmrelocate.c @@ -28,20 +28,17 @@ /* On model_6fx, model_1067x and model_106cx SMRR functions slightly differently. The MSR are at different location from the rest and need to be explicitly enabled in IA32_FEATURE_CONTROL MSR. */ -bool cpu_has_alternative_smrr(void) +static inline bool cpu_has_alternative_smrr(void) { - struct cpuinfo_x86 c; - get_fms(&c, cpuid_eax(1)); - if (c.x86 != 6) - return false; - switch (c.x86_model) { - case 0xf: - case 0x17: /* core2 */ - case 0x1c: /* Bonnell */ + if (CONFIG(CPU_INTEL_MODEL_1067X) || + CONFIG(CPU_INTEL_MODEL_106CX)) return true; - default: + if (!CONFIG(CPU_INTEL_MODEL_6FX)) return false; - } + /* Runtime detection as model_6fx also supports Fam 6 Model 16h */ + struct cpuinfo_x86 c; + get_fms(&c, cpuid_eax(1)); + return c.x86 == 6 && c.x86_model == 0xf; } static void write_smrr_alt(struct smm_relocation_params *relo_params) diff --git a/src/include/cpu/intel/smm_reloc.h b/src/include/cpu/intel/smm_reloc.h index 6b1a525d6c..2b25c75705 100644 --- a/src/include/cpu/intel/smm_reloc.h +++ b/src/include/cpu/intel/smm_reloc.h @@ -51,8 +51,6 @@ void smm_initialize(void); void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, size_t *smm_save_state_size); void smm_relocation_handler(int cpu, uintptr_t curr_smbase, uintptr_t staggered_smbase); -bool cpu_has_alternative_smrr(void); - #define MSR_PRMRR_PHYS_BASE 0x1f4 #define MSR_PRMRR_PHYS_MASK 0x1f5 #define MSR_UNCORE_PRMRR_PHYS_BASE 0x2f4 From dfcd63370daceefca8394524f47ac298c4dcf8c0 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Fri, 30 Jan 2026 15:26:51 +0100 Subject: [PATCH 567/789] cpu/intel: Use existing defines for MTRR_CAP_MSR Use existing define for SMRR and PMRR support instead of redefining it in various places. TEST=No functional change, thus untested. Change-Id: Ie366a9d695800acd9713bd4e8393201a1f0a5ab2 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/91015 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/cpu/intel/haswell/haswell.h | 4 ---- src/cpu/intel/haswell/smmrelocate.c | 4 ++-- src/cpu/intel/model_1067x/mp_init.c | 4 +--- src/cpu/intel/smm/gen1/smmrelocate.c | 4 +--- src/soc/intel/common/block/cpu/smmrelocate.c | 2 +- src/soc/intel/common/block/include/intelblocks/msr.h | 2 -- 6 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/cpu/intel/haswell/haswell.h b/src/cpu/intel/haswell/haswell.h index f42199de0a..d24cbe1975 100644 --- a/src/cpu/intel/haswell/haswell.h +++ b/src/cpu/intel/haswell/haswell.h @@ -103,10 +103,6 @@ #define SMBASE_MSR 0xc20 #define IEDBASE_MSR 0xc22 -/* MTRR_CAP_MSR bit definitions */ -#define SMRR_SUPPORTED (1 << 11) -#define PRMRR_SUPPORTED (1 << 12) - /* Intel suggested latency times in units of 1024ns. */ #define C_STATE_LATENCY_CONTROL_0_LIMIT 0x42 #define C_STATE_LATENCY_CONTROL_1_LIMIT 0x73 diff --git a/src/cpu/intel/haswell/smmrelocate.c b/src/cpu/intel/haswell/smmrelocate.c index 47946e8401..6ce41965d1 100644 --- a/src/cpu/intel/haswell/smmrelocate.c +++ b/src/cpu/intel/haswell/smmrelocate.c @@ -124,10 +124,10 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase, /* Write PRMRR and SMRR MSRs based on indicated support. */ mtrr_cap = rdmsr(MTRR_CAP_MSR); - if (mtrr_cap.lo & SMRR_SUPPORTED) + if (mtrr_cap.lo & MTRR_CAP_SMRR) write_smrr(relo_params); - if (mtrr_cap.lo & PRMRR_SUPPORTED) { + if (mtrr_cap.lo & MTRR_CAP_PRMRR) { write_prmrr(relo_params); /* UNCORE_PRMRR msrs are package level. Therefore, only * configure these MSRs on the BSP. */ diff --git a/src/cpu/intel/model_1067x/mp_init.c b/src/cpu/intel/model_1067x/mp_init.c index 8f04bf9ccc..def136e689 100644 --- a/src/cpu/intel/model_1067x/mp_init.c +++ b/src/cpu/intel/model_1067x/mp_init.c @@ -43,12 +43,10 @@ static void pre_mp_smm_init(void) smm_initialize(); } -#define SMRR_SUPPORTED (1 << 11) - static void per_cpu_smm_trigger(void) { msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR); - if (mtrr_cap.lo & SMRR_SUPPORTED) { + if (mtrr_cap.lo & MTRR_CAP_SMRR) { set_feature_ctrl_vmx(); msr_t ia32_ft_ctrl = rdmsr(IA32_FEATURE_CONTROL); /* We don't care if the lock is already setting diff --git a/src/cpu/intel/smm/gen1/smmrelocate.c b/src/cpu/intel/smm/gen1/smmrelocate.c index 6f3806dede..1408a67469 100644 --- a/src/cpu/intel/smm/gen1/smmrelocate.c +++ b/src/cpu/intel/smm/gen1/smmrelocate.c @@ -17,8 +17,6 @@ #include #include -#define SMRR_SUPPORTED (1 << 11) - #define D_OPEN (1 << 6) #define D_CLS (1 << 5) #define D_LCK (1 << 4) @@ -180,7 +178,7 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase, /* Write EMRR and SMRR MSRs based on indicated support. */ mtrr_cap = rdmsr(MTRR_CAP_MSR); - if (!(mtrr_cap.lo & SMRR_SUPPORTED)) + if (!(mtrr_cap.lo & MTRR_CAP_SMRR)) return; if (cpu_has_alternative_smrr()) diff --git a/src/soc/intel/common/block/cpu/smmrelocate.c b/src/soc/intel/common/block/cpu/smmrelocate.c index e510c96f99..fa4c8963a1 100644 --- a/src/soc/intel/common/block/cpu/smmrelocate.c +++ b/src/soc/intel/common/block/cpu/smmrelocate.c @@ -164,7 +164,7 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase, relo_params->smrr_mask.lo |= SMRR_PHYS_MASK_LOCK; /* Write SMRRs if supported */ - if (mtrr_cap.lo & SMRR_SUPPORTED) + if (mtrr_cap.lo & MTRR_CAP_SMRR) write_smrr(relo_params); } diff --git a/src/soc/intel/common/block/include/intelblocks/msr.h b/src/soc/intel/common/block/include/intelblocks/msr.h index 4bdd90c536..1965b36d59 100644 --- a/src/soc/intel/common/block/include/intelblocks/msr.h +++ b/src/soc/intel/common/block/include/intelblocks/msr.h @@ -110,8 +110,6 @@ #define MSR_L2_QOS_MASK(reg) (0xd10 + reg) /* MTRR_CAP_MSR bits */ -#define SMRR_SUPPORTED (1<<11) -#define PRMRR_SUPPORTED (1<<12) #define SMRR_LOCK_SUPPORTED (1<<14) #define SGX_SUPPORTED (1<<2) From 44fcbf84b32bfbc2566b5b08a4681fc29b14285f Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Fri, 30 Jan 2026 09:46:52 +0100 Subject: [PATCH 568/789] soc/intel/snowridge: Move defines to soc/pci_devs.h Move the defines for PCI register SMM_FEATURE_CONTROL to the header soc/pci_devs.h like it's done on other server platforms as well. While on it add BIT1 that will be used in the following commit. TEST=Not a function change, thus untested. Change-Id: Ib05bb129f069ab1a6f4752a2dac829b3b7b41ec9 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/91016 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons Reviewed-by: Paul Menzel --- src/soc/intel/snowridge/include/soc/pci_devs.h | 6 ++++++ src/soc/intel/snowridge/lockdown.c | 4 ---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/soc/intel/snowridge/include/soc/pci_devs.h b/src/soc/intel/snowridge/include/soc/pci_devs.h index ca50bf8eb1..09336c0724 100644 --- a/src/soc/intel/snowridge/include/soc/pci_devs.h +++ b/src/soc/intel/snowridge/include/soc/pci_devs.h @@ -68,6 +68,12 @@ /* Stack U0. */ #define UBOX_DEV_RACU _UBOX0_DEV(0x00, 1) + +#define SMM_FEATURE_CONTROL 0x8c +#define SMM_CODE_CHK_EN BIT(2) +#define SMM_FC_CPU_SAVE_EN BIT(1) +#define SMM_FEATURE_CONTROL_LOCK BIT(0) + #define UBOX_DEV_NCDECS _UBOX0_DEV(0x00, 2) /* Stack U1. */ diff --git a/src/soc/intel/snowridge/lockdown.c b/src/soc/intel/snowridge/lockdown.c index b74b74ca4b..485d3413d3 100644 --- a/src/soc/intel/snowridge/lockdown.c +++ b/src/soc/intel/snowridge/lockdown.c @@ -8,10 +8,6 @@ #include #include -#define SMM_FEATURE_CONTROL 0x8c -#define SMM_CODE_CHK_EN (1 << 2) -#define SMM_FEATURE_CONTROL_LOCK (1 << 0) - static void pmc_lockdown_cfg(int chipset_lockdown) { pmc_or_mmio32(PMSYNC_TPR_CFG, PCH2CPU_TPR_CFG_LOCK); From 38baf0c5f6081367355b969af281432d8b8f4f46 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 19 Feb 2026 07:43:35 -0800 Subject: [PATCH 569/789] soc/intel/meteorlake: Use common UART device list driver Remove platform-specific uart.c and switch to the common UART device list driver. This eliminates duplicate code. The meteorlake uart.c simply defined uart_devices[] array. The common driver now handles this using the SOC_UART_DEVFN(n) macro defined in pci_devs.h which uses token concatenation to map to platform-specific PCI_DEVFN_UARTn definitions. This commit: - Selects SOC_INTEL_COMMON_FEATURE and SOC_INTEL_COMMON_FEATURE_UART_DEVICES in Kconfig - Removes uart.c and updates Makefile.mk Change-Id: Ic791eaa2521a44aba330e149fb0185094dd9ccf7 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91243 Reviewed-by: Kim, Wonkyu Reviewed-by: Werner Zeh Tested-by: build bot (Jenkins) --- src/soc/intel/meteorlake/Kconfig | 2 ++ src/soc/intel/meteorlake/Makefile.mk | 2 -- src/soc/intel/meteorlake/uart.c | 12 ------------ 3 files changed, 2 insertions(+), 14 deletions(-) delete mode 100644 src/soc/intel/meteorlake/uart.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index a0e648a856..b223fa01d2 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -86,6 +86,8 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_BLOCK_THERMAL_BEHIND_PMC select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_BASECODE select SOC_INTEL_COMMON_BASECODE_RAMTOP select SOC_INTEL_COMMON_FSP_RESET diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index 2ef53f5395..81be9ff856 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -10,7 +10,6 @@ all-y += gspi.c all-y += i2c.c all-y += pmutil.c all-y += spi.c -all-y += uart.c all-y += gpio.c bootblock-y += bootblock/bootblock.c @@ -55,7 +54,6 @@ smm-y += p2sb.c smm-y += pmutil.c smm-y += smihandler.c smm-y += soc_info.c -smm-y += uart.c smm-y += xhci.c CPPFLAGS_common += -I$(src)/soc/intel/meteorlake diff --git a/src/soc/intel/meteorlake/uart.c b/src/soc/intel/meteorlake/uart.c deleted file mode 100644 index 9f549c5ae8..0000000000 --- a/src/soc/intel/meteorlake/uart.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const unsigned int uart_devices[] = { - PCI_DEVFN_UART0, - PCI_DEVFN_UART1, - PCI_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); From 61dc1e04e05f264fe579a68fa7ffcc5ef5533d9d Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 19 Feb 2026 07:43:36 -0800 Subject: [PATCH 570/789] soc/intel/tigerlake: Use common UART device list driver Remove platform-specific uart.c and switch to the common UART device list driver. This eliminates duplicate code. The tigerlake uart.c simply defined uart_devices[] array. The common driver now handles this using the PCI_UART_DEVFNn macros defined in pci_devs.h. This commit: - Adds PCI_DEVFN_UART* aliases pointing to PCH_DEVFN_UART* for naming consistency with common code - Selects SOC_INTEL_COMMON_FEATURE and SOC_INTEL_COMMON_FEATURE_UART_DEVICES in Kconfig - Removes uart.c and updates Makefile.mk Change-Id: I9520bd3f4dd9ccf777e34c79a8c8237adb8b0fed Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91245 Reviewed-by: Werner Zeh Tested-by: build bot (Jenkins) --- src/soc/intel/tigerlake/Kconfig | 2 ++ src/soc/intel/tigerlake/Makefile.mk | 2 -- src/soc/intel/tigerlake/include/soc/pci_devs.h | 5 +++++ src/soc/intel/tigerlake/uart.c | 18 ------------------ 4 files changed, 7 insertions(+), 20 deletions(-) delete mode 100644 src/soc/intel/tigerlake/uart.c diff --git a/src/soc/intel/tigerlake/Kconfig b/src/soc/intel/tigerlake/Kconfig index d76ddec335..1d6c21e06f 100644 --- a/src/soc/intel/tigerlake/Kconfig +++ b/src/soc/intel/tigerlake/Kconfig @@ -72,6 +72,8 @@ config SOC_INTEL_TIGERLAKE select SOC_INTEL_COMMON_BLOCK_USB4_PCIE select SOC_INTEL_COMMON_BLOCK_USB4_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_RESET diff --git a/src/soc/intel/tigerlake/Makefile.mk b/src/soc/intel/tigerlake/Makefile.mk index 27e07a99b4..19b504362f 100644 --- a/src/soc/intel/tigerlake/Makefile.mk +++ b/src/soc/intel/tigerlake/Makefile.mk @@ -10,7 +10,6 @@ all-y += gspi.c all-y += i2c.c all-y += pmutil.c all-y += spi.c -all-y += uart.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c @@ -47,7 +46,6 @@ ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog_lib.c smm-y += p2sb.c smm-y += pmutil.c smm-y += smihandler.c -smm-y += uart.c smm-y += elog.c smm-y += xhci.c diff --git a/src/soc/intel/tigerlake/include/soc/pci_devs.h b/src/soc/intel/tigerlake/include/soc/pci_devs.h index d93c97f3c3..c615f3bc70 100644 --- a/src/soc/intel/tigerlake/include/soc/pci_devs.h +++ b/src/soc/intel/tigerlake/include/soc/pci_devs.h @@ -245,4 +245,9 @@ #define PCH_DEV_GBE _PCH_DEV(ESPI, 6) #define PCH_DEV_TRACEHUB _PCH_DEV(ESPI, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 + #endif diff --git a/src/soc/intel/tigerlake/uart.c b/src/soc/intel/tigerlake/uart.c deleted file mode 100644 index fa4760c118..0000000000 --- a/src/soc/intel/tigerlake/uart.c +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Tiger Lake Processor PCH Datasheet - * Document number: 575857 - * Chapter number: 9 - */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); From bb95093b8f0b5ae3dfc4f2447f93aa5b11dca855 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 19 Feb 2026 07:43:36 -0800 Subject: [PATCH 571/789] soc/intel/jasperlake: Use common UART device list driver Remove platform-specific uart.c and switch to the common UART device list driver. This eliminates duplicate code. The jasperlake uart.c simply defined uart_devices[] array. The common driver now handles this using the PCI_UART_DEVFNn macro defined in pci_devs.h. This commit: - Adds PCI_DEVFN_UART* aliases pointing to PCH_DEVFN_UART* for naming consistency with common code - Selects SOC_INTEL_COMMON_FEATURE and SOC_INTEL_COMMON_FEATURE_UART_DEVICES in Kconfig - Removes uart.c and updates Makefile.mk Change-Id: I8f7c68c8c44dd9ccf7cb49af8a3561a47d4aacc2 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91246 Tested-by: build bot (Jenkins) Reviewed-by: Werner Zeh --- src/soc/intel/jasperlake/Kconfig | 2 ++ src/soc/intel/jasperlake/Makefile.mk | 2 -- src/soc/intel/jasperlake/include/soc/pci_devs.h | 5 +++++ src/soc/intel/jasperlake/uart.c | 12 ------------ 4 files changed, 7 insertions(+), 14 deletions(-) delete mode 100644 src/soc/intel/jasperlake/uart.c diff --git a/src/soc/intel/jasperlake/Kconfig b/src/soc/intel/jasperlake/Kconfig index e80028ae80..6de9931de3 100644 --- a/src/soc/intel/jasperlake/Kconfig +++ b/src/soc/intel/jasperlake/Kconfig @@ -55,6 +55,8 @@ config SOC_INTEL_JASPERLAKE select SOC_INTEL_COMMON_BLOCK_POWER_LIMIT select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_RESET diff --git a/src/soc/intel/jasperlake/Makefile.mk b/src/soc/intel/jasperlake/Makefile.mk index 1377fff9e0..6346f2d3d2 100644 --- a/src/soc/intel/jasperlake/Makefile.mk +++ b/src/soc/intel/jasperlake/Makefile.mk @@ -10,7 +10,6 @@ all-y += gspi.c all-y += i2c.c all-y += pmutil.c all-y += spi.c -all-y += uart.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c @@ -47,7 +46,6 @@ smm-y += gpio.c smm-y += p2sb.c smm-y += pmutil.c smm-y += smihandler.c -smm-y += uart.c smm-y += elog.c smm-y += xhci.c diff --git a/src/soc/intel/jasperlake/include/soc/pci_devs.h b/src/soc/intel/jasperlake/include/soc/pci_devs.h index e3276458bf..2d2b96a09e 100644 --- a/src/soc/intel/jasperlake/include/soc/pci_devs.h +++ b/src/soc/intel/jasperlake/include/soc/pci_devs.h @@ -193,4 +193,9 @@ #define PCH_DEV_GBE _PCH_DEV(ESPI, 6) #define PCH_DEV_TRACEHUB _PCH_DEV(ESPI, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 + #endif diff --git a/src/soc/intel/jasperlake/uart.c b/src/soc/intel/jasperlake/uart.c deleted file mode 100644 index 9946880263..0000000000 --- a/src/soc/intel/jasperlake/uart.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); From 7b4fb78e34c95ad62b5f4b257cd9bbd09071166c Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 19 Feb 2026 07:43:36 -0800 Subject: [PATCH 572/789] soc/intel/elkhartlake: Use common UART device list driver Remove platform-specific uart.c and switch to the common UART device list driver. This eliminates duplicate code. The elkhartlake uart.c simply defined uart_devices[] array. The common driver now handles this using the PCI_UART_DEVFNn macro defined in pci_devs.h. This commit: - Adds PCI_DEVFN_UART* aliases pointing to PCH_DEVFN_UART* for naming consistency with common code - Selects SOC_INTEL_COMMON_FEATURE and SOC_INTEL_COMMON_FEATURE_UART_DEVICES in Kconfig - Removes uart.c and updates Makefile.mk Change-Id: I778faf19128f41509f70d324dd9ccf71d93cab0b Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91247 Tested-by: build bot (Jenkins) Reviewed-by: Werner Zeh --- src/soc/intel/elkhartlake/Kconfig | 2 ++ src/soc/intel/elkhartlake/Makefile.mk | 2 -- src/soc/intel/elkhartlake/include/soc/pci_devs.h | 5 +++++ src/soc/intel/elkhartlake/uart.c | 12 ------------ 4 files changed, 7 insertions(+), 14 deletions(-) delete mode 100644 src/soc/intel/elkhartlake/uart.c diff --git a/src/soc/intel/elkhartlake/Kconfig b/src/soc/intel/elkhartlake/Kconfig index 6fb4f52d61..79e57e6894 100644 --- a/src/soc/intel/elkhartlake/Kconfig +++ b/src/soc/intel/elkhartlake/Kconfig @@ -55,6 +55,8 @@ config SOC_INTEL_ELKHARTLAKE select SOC_INTEL_COMMON_BLOCK_SCS select SOC_INTEL_COMMON_BLOCK_SMM select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_RESET diff --git a/src/soc/intel/elkhartlake/Makefile.mk b/src/soc/intel/elkhartlake/Makefile.mk index b5f5f2ad74..393a90d17c 100644 --- a/src/soc/intel/elkhartlake/Makefile.mk +++ b/src/soc/intel/elkhartlake/Makefile.mk @@ -10,7 +10,6 @@ all-y += gspi.c all-y += i2c.c all-y += pmutil.c all-y += spi.c -all-y += uart.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c @@ -45,7 +44,6 @@ smm-y += gpio.c smm-y += p2sb.c smm-y += pmutil.c smm-y += smihandler.c -smm-y += uart.c verstage-y += gpio.c diff --git a/src/soc/intel/elkhartlake/include/soc/pci_devs.h b/src/soc/intel/elkhartlake/include/soc/pci_devs.h index 8cf193829c..743c3a8cd6 100644 --- a/src/soc/intel/elkhartlake/include/soc/pci_devs.h +++ b/src/soc/intel/elkhartlake/include/soc/pci_devs.h @@ -247,4 +247,9 @@ #define PCH_DEV_SPI _PCH_DEV(ESPI, 5) #define PCH_DEV_TRACEHUB _PCH_DEV(ESPI, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 + #endif diff --git a/src/soc/intel/elkhartlake/uart.c b/src/soc/intel/elkhartlake/uart.c deleted file mode 100644 index 9946880263..0000000000 --- a/src/soc/intel/elkhartlake/uart.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); From e31d32443e84204ed0be0990380b3cf199ad0aa6 Mon Sep 17 00:00:00 2001 From: Pranava Y N Date: Wed, 25 Feb 2026 15:09:03 +0530 Subject: [PATCH 573/789] Revert "mb/google/fatcat: Fix Gen4 SSD power sequencing" This reverts commit 970201012365bad68b1a6d71fcbc10f44694007d. Fatcat RVP is sometimes unable to boot when non-serial image is flashed. Reverting this CL until permanent verified fix is landed. BUG=b:487523987 TEST=Able to boot fatcat to OS from Gen4 SSD slot Change-Id: I5c61879cfb6e5f54d439284d1f75db5bfceddd1d Signed-off-by: Pranava Y N Reviewed-on: https://review.coreboot.org/c/coreboot/+/91422 Reviewed-by: Reviewed-by: Avi Uday Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik Reviewed-by: Jayvik Desai --- .../google/fatcat/variants/fatcat/fw_config.c | 15 ++++----------- .../google/fatcat/variants/fatcat/gpio.c | 2 ++ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/mainboard/google/fatcat/variants/fatcat/fw_config.c b/src/mainboard/google/fatcat/variants/fatcat/fw_config.c index 25f9a339df..ccece4647f 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/fw_config.c +++ b/src/mainboard/google/fatcat/variants/fatcat/fw_config.c @@ -285,17 +285,14 @@ static const struct pad_config wwan_disable_pads[] = { }; /* Gen4 NVME: at the top M.2 slot */ -static const struct pad_config pre_mem_gen4_ssd_pwr_seq1_pads[] = { +static const struct pad_config pre_mem_gen4_ssd_pwr_pads[] = { /* GPP_B10: GEN4_SSD_PWREN */ PAD_CFG_GPO(GPP_B10, 0, PLTRST), }; -static const struct pad_config pre_mem_gen4_ssd_pwr_seq2_pads[] = { +static const struct pad_config gen4_ssd_pads[] = { /* GPP_B10: GEN4_SSD_PWREN */ PAD_CFG_GPO(GPP_B10, 1, PLTRST), -}; - -static const struct pad_config gen4_ssd_pads[] = { /* GPP_B09: M2_GEN4_SSD_RESET_N */ PAD_CFG_GPO(GPP_B09, 1, PLTRST), }; @@ -621,11 +618,11 @@ void fw_config_configure_pre_mem_gpio(void) GPIO_CONFIGURE_PADS(pre_mem_wwan_pwr_seq1_pads); if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN4))) { - GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_seq1_pads); + GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_pads); } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN5))) { GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads); } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_UNKNOWN))) { - GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_seq1_pads); + GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_pads); GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads); } @@ -648,10 +645,6 @@ void fw_config_configure_pre_mem_gpio(void) if (fw_config_probe(FW_CONFIG(FP, FP_PRESENT))) GPIO_CONFIGURE_PADS(pre_mem_fp_enable_pads); - if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN4)) || - fw_config_probe(FW_CONFIG(STORAGE, STORAGE_UNKNOWN))) { - GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_seq2_pads); - } } void fw_config_gpio_padbased_override(struct pad_config *padbased_table) diff --git a/src/mainboard/google/fatcat/variants/fatcat/gpio.c b/src/mainboard/google/fatcat/variants/fatcat/gpio.c index 696fb8ba4d..13e6bbe1e3 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/gpio.c +++ b/src/mainboard/google/fatcat/variants/fatcat/gpio.c @@ -57,6 +57,8 @@ static const struct pad_config gpio_table[] = { PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_B03, NONE, DEEP, NF3), /* GPP_B09: M2_GEN4_SSD_RESET_N */ PAD_CFG_GPO(GPP_B09, 1, PLTRST), + /* GPP_B10: GEN4_SSD_PWREN */ + PAD_CFG_GPO(GPP_B10, 1, PLTRST), /* GPP_B11: MOD_TCSS1_DISP_HPD3 */ PAD_CFG_NF(GPP_B11, NONE, DEEP, NF2), /* GPP_B12: PM_SLP_S0_N */ From a69d537e61c6dee7e19d29d9bd44405e652746f3 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 19 Feb 2026 07:43:36 -0800 Subject: [PATCH 574/789] soc/intel/cannonlake: Use common UART device list driver Remove platform-specific uart.c and switch to the common UART device list driver. This eliminates duplicate code. The cannonlake uart.c simply defined uart_devices[] array. The common driver now handles this using the PCI_UART_DEVFNn macro defined in pci_devs.h. This commit: - Adds PCI_DEVFN_UART* aliases pointing to PCH_DEVFN_UART* for naming consistency with common code - Selects SOC_INTEL_COMMON_FEATURE and SOC_INTEL_COMMON_FEATURE_UART_DEVICES in Kconfig - Removes uart.c and updates Makefile.mk Change-Id: I819dc9853b4b44eb97238c1d5ad464dd9ccf7f9a Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91248 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/Kconfig | 2 ++ src/soc/intel/cannonlake/Makefile.mk | 6 ------ src/soc/intel/cannonlake/include/soc/pci_devs.h | 5 +++++ src/soc/intel/cannonlake/uart.c | 12 ------------ 4 files changed, 7 insertions(+), 18 deletions(-) delete mode 100644 src/soc/intel/cannonlake/uart.c diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index 738371bc1b..d7075d0d0d 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -59,6 +59,8 @@ config SOC_INTEL_CANNONLAKE_BASE select SOC_INTEL_COMMON_BLOCK_THERMAL_PCI_DEV select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_NHLT select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/cannonlake/Makefile.mk b/src/soc/intel/cannonlake/Makefile.mk index 96c02074ef..fc51fa0067 100644 --- a/src/soc/intel/cannonlake/Makefile.mk +++ b/src/soc/intel/cannonlake/Makefile.mk @@ -15,7 +15,6 @@ bootblock-y += i2c.c bootblock-y += spi.c bootblock-y += lpc.c bootblock-y += p2sb.c -bootblock-y += uart.c romstage-y += cnl_memcfg_init.c romstage-y += gspi.c @@ -25,7 +24,6 @@ romstage-y += pcie_rp.c romstage-y += pmutil.c romstage-y += reset.c romstage-y += spi.c -romstage-y += uart.c ramstage-y += acpi.c ramstage-y += chip.c @@ -46,7 +44,6 @@ ramstage-y += pmutil.c ramstage-y += reset.c ramstage-y += spi.c ramstage-y += systemagent.c -ramstage-y += uart.c ramstage-y += vr_config.c ramstage-y += sd.c ramstage-y += xhci.c @@ -55,20 +52,17 @@ smm-y += elog.c smm-y += p2sb.c smm-y += pmutil.c smm-y += smihandler.c -smm-y += uart.c smm-y += xhci.c postcar-y += pmutil.c postcar-y += i2c.c postcar-y += gspi.c postcar-y += spi.c -postcar-y += uart.c verstage-y += gspi.c verstage-y += i2c.c verstage-y += pmutil.c verstage-y += spi.c -verstage-y += uart.c ifeq ($(CONFIG_SOC_INTEL_CANNONLAKE_PCH_H),y) bootblock-y += gpio_cnp_h.c diff --git a/src/soc/intel/cannonlake/include/soc/pci_devs.h b/src/soc/intel/cannonlake/include/soc/pci_devs.h index 6998eb1022..d5aa36b554 100644 --- a/src/soc/intel/cannonlake/include/soc/pci_devs.h +++ b/src/soc/intel/cannonlake/include/soc/pci_devs.h @@ -204,4 +204,9 @@ #define PCH_DEV_GBE _PCH_DEV(LPC, 6) #define PCH_DEV_TRACEHUB _PCH_DEV(LPC, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 + #endif diff --git a/src/soc/intel/cannonlake/uart.c b/src/soc/intel/cannonlake/uart.c deleted file mode 100644 index 9946880263..0000000000 --- a/src/soc/intel/cannonlake/uart.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); From acd8f42410c3204e0ea1a7e4f4b8be1c5d0e489e Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 19 Feb 2026 08:23:33 -0800 Subject: [PATCH 575/789] soc/intel/skylake: Use common UART device list driver Remove platform-specific uart.c and switch to the common UART device list driver. This eliminates 12 lines of duplicate code. The Skylake uart.c simply defined uart_devices[] array. The common driver now handles this using the PCI_DEVFN_UARTn macros defined in pci_devs.h. This commit: - Adds PCI_DEVFN_UART* aliases pointing to PCH_DEVFN_UART* for naming consistency with common code - Selects SOC_INTEL_COMMON_FEATURE and SOC_INTEL_COMMON_FEATURE_UART_DEVICES in Kconfig - Removes uart.c and updates Makefile.mk Change-Id: Id686de6bb4dd9ccf78644817881b2abfb5ae0352 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91249 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/soc/intel/skylake/Kconfig | 2 ++ src/soc/intel/skylake/Makefile.mk | 6 ------ src/soc/intel/skylake/include/soc/pci_devs.h | 5 +++++ src/soc/intel/skylake/uart.c | 12 ------------ 4 files changed, 7 insertions(+), 18 deletions(-) delete mode 100644 src/soc/intel/skylake/uart.c diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index 7c530f2c75..aa64511249 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -58,6 +58,8 @@ config SOC_INTEL_COMMON_SKYLAKE_BASE select SOC_INTEL_COMMON_BLOCK_THERMAL_PCI_DEV select SOC_INTEL_COMMON_BLOCK_UART select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_NHLT diff --git a/src/soc/intel/skylake/Makefile.mk b/src/soc/intel/skylake/Makefile.mk index 04ba96b7dd..de251f2de3 100644 --- a/src/soc/intel/skylake/Makefile.mk +++ b/src/soc/intel/skylake/Makefile.mk @@ -17,14 +17,12 @@ bootblock-y += p2sb.c bootblock-y += pmutil.c bootblock-y += spi.c bootblock-y += lpc.c -bootblock-y += uart.c verstage-y += gpio.c verstage-y += gspi.c verstage-y += pmutil.c verstage-y += i2c.c verstage-y += spi.c -verstage-y += uart.c romstage-y += gpio.c romstage-y += gspi.c @@ -34,7 +32,6 @@ romstage-y += pcie_rp.c romstage-y += pmutil.c romstage-y += reset.c romstage-y += spi.c -romstage-y += uart.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c ramstage-y += chip.c @@ -58,7 +55,6 @@ ramstage-y += reset.c ramstage-y += sd.c ramstage-y += spi.c ramstage-y += systemagent.c -ramstage-y += uart.c ramstage-y += vr_config.c ramstage-y += xhci.c @@ -67,13 +63,11 @@ smm-y += gpio.c smm-y += p2sb.c smm-y += pmutil.c smm-y += smihandler.c -smm-y += uart.c smm-y += xhci.c postcar-y += gspi.c postcar-y += spi.c postcar-y += i2c.c -postcar-y += uart.c ifeq ($(CONFIG_SKYLAKE_SOC_PCH_H),y) ifeq ($(CONFIG_MAINBOARD_SUPPORTS_SKYLAKE_CPU),y) diff --git a/src/soc/intel/skylake/include/soc/pci_devs.h b/src/soc/intel/skylake/include/soc/pci_devs.h index 661ed5cd65..b1e5208523 100644 --- a/src/soc/intel/skylake/include/soc/pci_devs.h +++ b/src/soc/intel/skylake/include/soc/pci_devs.h @@ -187,4 +187,9 @@ #define PCH_DEV_GBE _PCH_DEV(LPC, 6) #define PCH_DEV_TRACEHUB _PCH_DEV(LPC, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 + #endif diff --git a/src/soc/intel/skylake/uart.c b/src/soc/intel/skylake/uart.c deleted file mode 100644 index 9946880263..0000000000 --- a/src/soc/intel/skylake/uart.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); From 61ce86ea3edfbae4c3470778c6d43e4fa37a07d1 Mon Sep 17 00:00:00 2001 From: Uwe Poeche Date: Tue, 3 Feb 2026 15:31:25 +0100 Subject: [PATCH 576/789] mb/siemens/mc_ehl6: Reduce clock rate for I2C1 Signal integrity measurement on I2C1 bus showed not optimal rise time. Therefore the clock frequency is reduced from 400kHz to 100kHz to reach optimal signal integrity also during coreboot runtime. TEST=Signal integrity measurement during coreboot runtime. Change-Id: I9721ede7aa645b2ca46f377bbe557f78c36581f6 Signed-off-by: Uwe Poeche Reviewed-on: https://review.coreboot.org/c/coreboot/+/91079 Reviewed-by: Mario Scheithauer Tested-by: build bot (Jenkins) --- src/mainboard/siemens/mc_ehl/variants/mc_ehl6/devicetree.cb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/devicetree.cb index 5180770908..f47fde0cab 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/devicetree.cb +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/devicetree.cb @@ -111,6 +111,12 @@ chip soc/intel/elkhartlake [PchSerialIoIndexI2C6] = 1, }" + register "common_soc_config" = "{ + .i2c[1] = { + .speed = I2C_SPEED_STANDARD, + }, + }" + register "SerialIoUartMode" = "{ [PchSerialIoIndexUART0] = PchSerialIoPci, [PchSerialIoIndexUART1] = PchSerialIoPci, From 5ac3e402820475a55e03836ad9e77872d9d7d2e8 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Mon, 23 Feb 2026 16:19:11 +0800 Subject: [PATCH 577/789] mb/google/brox/var/caboc: Probe LGD touchscreen by fw_config 1. Probe with fw_config TOUCH_LGD_HID_I2C. 2. Update slave address to 0x10. BUG=b:483588481 TEST=build brox coreboot image Change-Id: I1286679f840b8335ab1877bf1c4e8f72d5704586 Signed-off-by: Tony Huang Reviewed-on: https://review.coreboot.org/c/coreboot/+/91384 Reviewed-by: Wisley Chen Tested-by: build bot (Jenkins) --- src/mainboard/google/brox/variants/caboc/overridetree.cb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/brox/variants/caboc/overridetree.cb b/src/mainboard/google/brox/variants/caboc/overridetree.cb index 0587d16324..cded4fd875 100644 --- a/src/mainboard/google/brox/variants/caboc/overridetree.cb +++ b/src/mainboard/google/brox/variants/caboc/overridetree.cb @@ -23,6 +23,7 @@ fw_config option TOUCH_UNKNOWN 0 option TOUCH_ELAN_HID_I2C 1 option TOUCH_G2TOUCH_HID_I2C 2 + option TOUCH_LGD_HID_I2C 3 end end @@ -432,7 +433,9 @@ chip soc/intel/alderlake register "generic.has_power_resource" = "1" register "generic.use_gpio_for_status" = "true" register "hid_desc_reg_offset" = "0x00" - device i2c 34 on end + device i2c 10 on + probe PANEL TOUCH_LGD_HID_I2C + end end end device ref gspi1 on From c069dc3eb17db88a6fb60da7aedf91d0eb2ce404 Mon Sep 17 00:00:00 2001 From: Luca Lai Date: Tue, 24 Feb 2026 16:08:13 +0800 Subject: [PATCH 578/789] mb/google/fatcat/var/ruby: Add settings for resolving EE noise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because of EE noise issue, so add acoustic mitigation items. Acoustic Noise Mitigation → Enable Slow Slew Rate for IAcore Domain → Slow Slew Rate for GT Domain → Slow Slew Rate for Ecore Domain → IAcore Disable Fast Package C-state ramp → True GT Disable Fast Package C-state ramp → True Ecore Disable Fast Package C-state ramp → True P-Core Hysteresis → <3> E-Core Hysteresis → <3> BUG=b:479695733 TEST=Build and boot to OS, check EE noise are resolved. Change-Id: I5d96cb3e87e9e5a2260b278746b7fce72be4fb59 Signed-off-by: Luca Lai Reviewed-on: https://review.coreboot.org/c/coreboot/+/91412 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- .../google/fatcat/variants/ruby/overridetree.cb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mainboard/google/fatcat/variants/ruby/overridetree.cb b/src/mainboard/google/fatcat/variants/ruby/overridetree.cb index 1c1399dc21..6b37f24a0f 100644 --- a/src/mainboard/google/fatcat/variants/ruby/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/ruby/overridetree.cb @@ -73,6 +73,20 @@ chip soc/intel/pantherlake [VR_DOMAIN_SA] = 38 * 4 }" + # Acoustic Noise settings and slew rate configuration: + register "enable_acoustic_noise_mitigation" = "true" + # Slew rate for IA Domain: Fast/4 + register "slow_slew_rate_config[VR_DOMAIN_IA]" = "SLEW_FAST_4" + # Slew rate for GT Domain: Fast/2 + register "slow_slew_rate_config[VR_DOMAIN_GT]" = "SLEW_FAST_2" + # Slew rate for ATOM Domain: Fast/4 + register "slow_slew_rate_config[VR_DOMAIN_ATOM]" = "SLEW_FAST_4" + register "disable_fast_pkgc_ramp[VR_DOMAIN_IA]" = "true" + register "disable_fast_pkgc_ramp[VR_DOMAIN_GT]" = "true" + register "disable_fast_pkgc_ramp[VR_DOMAIN_ATOM]" = "true" + register "pcore_hysteresis_window_ms" = "3" + register "ecore_hysteresis_window_ms" = "3" + register "usb2_ports[0]" = "USB2_PORT_TYPE_C(OC_SKIP)" # USB2_C0 register "usb2_ports[1]" = "USB2_PORT_TYPE_C(OC_SKIP)" # USB2_C1 register "usb2_ports[2]" = "USB2_PORT_MID(OC_SKIP)" # USB HUB (USB2 Camera) From 57e30e6b9db19d21bfbb56f09bbc32c17e89ab1f Mon Sep 17 00:00:00 2001 From: Kenneth Chan Date: Wed, 4 Feb 2026 18:15:01 +0800 Subject: [PATCH 579/789] mb/google/brask/var/moxoe: Switch memory to DDR5 Moxoe uses DDR5 SODIMM. Configure the board to support DDR5. BUG=b:481186489 TEST=Builds successfully for moxoe. Change-Id: Ic2f35dab77c24863cf63f6672ba14cbb560edf14 Signed-off-by: Kenneth Chan Reviewed-on: https://review.coreboot.org/c/coreboot/+/91089 Reviewed-by: Ren Kuo Tested-by: build bot (Jenkins) --- .../google/brya/variants/moxoe/Makefile.mk | 1 + .../google/brya/variants/moxoe/memory.c | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/mainboard/google/brya/variants/moxoe/memory.c diff --git a/src/mainboard/google/brya/variants/moxoe/Makefile.mk b/src/mainboard/google/brya/variants/moxoe/Makefile.mk index e31aaa1707..2b274c69e2 100644 --- a/src/mainboard/google/brya/variants/moxoe/Makefile.mk +++ b/src/mainboard/google/brya/variants/moxoe/Makefile.mk @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only bootblock-y += gpio.c +romstage-y += memory.c romstage-y += gpio.c ramstage-y += gpio.c diff --git a/src/mainboard/google/brya/variants/moxoe/memory.c b/src/mainboard/google/brya/variants/moxoe/memory.c new file mode 100644 index 0000000000..742ce7fe3a --- /dev/null +++ b/src/mainboard/google/brya/variants/moxoe/memory.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +static const struct mb_cfg ddr5_mem_config = { + .type = MEM_TYPE_DDR5, + + .rcomp = { + /* Baseboard uses only 100ohm Rcomp resistors */ + .resistor = 100, + + /* Baseboard Rcomp target values */ + .targets = {50, 20, 25, 25, 25}, + }, + + .LpDdrDqDqsReTraining = 1, + + .ect = 1, /* Early Command Training */ + + .UserBd = BOARD_TYPE_MOBILE, + + .ddr_config = { + .dq_pins_interleaved = false, + }, +}; + +const struct mb_cfg *__weak variant_memory_params(void) +{ + return &ddr5_mem_config; +} + +bool __weak variant_is_half_populated(void) +{ + return false; +} + +void __weak variant_get_spd_info(struct mem_spd *spd_info) +{ + spd_info->topo = MEM_TOPO_DIMM_MODULE; + spd_info->smbus[0].addr_dimm[0] = 0x50; + spd_info->smbus[1].addr_dimm[0] = 0x52; +} From 800db242bd4247c4726307752335ede9e4e4d712 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 17:50:12 +0100 Subject: [PATCH 580/789] {soc,sb}/intel: Drop named object from ASL `GPLD` method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Creation of named objects within a method is highly inefficient, as per IASL's remarks during DSDT compilation. But it is possible to use local variables instead of named objects to store a package. Update the `GPLD` method to use a local variable, instead of creating a named object. While at it, unify cosmetics of the several copies of the method across the codebase. TEST: Build coreboot for the ASRock Z97 Extreme6 (Lynx Point) and run: - acpiexec -b "Evaluate _SB.PCI0.XHCI.HUB7.GPLD 0" build/dsdt.aml - acpiexec -b "Evaluate _SB.PCI0.XHCI.HUB7.GPLD 1" build/dsdt.aml Observe return value is the same before and after this change. Change-Id: Id66322150c90309f42f574584728c6b1db353c0c Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91390 Reviewed-by: Jérémy Compostella Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/soc/intel/baytrail/acpi/xhci.asl | 14 +++---- src/soc/intel/broadwell/pch/acpi/xhci.asl | 10 ++--- src/soc/intel/skylake/acpi/xhci.asl | 20 ++++------ src/southbridge/intel/bd82x6x/acpi/usb.asl | 40 ++++++++----------- src/southbridge/intel/lynxpoint/acpi/xhci.asl | 10 ++--- 5 files changed, 41 insertions(+), 53 deletions(-) diff --git a/src/soc/intel/baytrail/acpi/xhci.asl b/src/soc/intel/baytrail/acpi/xhci.asl index 368f34faad..4e1be831b9 100644 --- a/src/soc/intel/baytrail/acpi/xhci.asl +++ b/src/soc/intel/baytrail/acpi/xhci.asl @@ -12,18 +12,18 @@ Device (XHCI) // GPLD: Generate Port Location Data (PLD) Method (GPLD, 1, Serialized) { - Name (PCKG, Package (0x01) { + Local0 = Package () { Buffer (0x10) {} - }) + } - // REV: Revision 0x02 for ACPI 5.0 - CreateField (DerefOf (PCKG[0]), 0, 0x07, REV) - REV = 0x02 + // REV: Revision 2 for ACPI 5.0 + CreateField (DerefOf (Local0[0]), 0, 7, REV) + REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG[0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - Return (PCKG) + Return (Local0) } Device (PRT1) { Name (_ADR, 1) } diff --git a/src/soc/intel/broadwell/pch/acpi/xhci.asl b/src/soc/intel/broadwell/pch/acpi/xhci.asl index 0656a6cf2a..e98bd42637 100644 --- a/src/soc/intel/broadwell/pch/acpi/xhci.asl +++ b/src/soc/intel/broadwell/pch/acpi/xhci.asl @@ -330,18 +330,18 @@ Device (XHCI) // GPLD: Generate Port Location Data (PLD) Method (GPLD, 1, Serialized) { - Name (PCKG, Package () { + Local0 = Package () { Buffer (0x10) {} - }) + } // REV: Revision 2 for ACPI 5.0 - CreateField (DerefOf (PCKG [0]), 0, 7, REV) + CreateField (DerefOf (Local0[0]), 0, 7, REV) REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG [0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - Return (PCKG) + Return (Local0) } Device (PRT1) { Name (_ADR, 1) } // USB Port 0 diff --git a/src/soc/intel/skylake/acpi/xhci.asl b/src/soc/intel/skylake/acpi/xhci.asl index bfe6c6df77..5ce7b0d809 100644 --- a/src/soc/intel/skylake/acpi/xhci.asl +++ b/src/soc/intel/skylake/acpi/xhci.asl @@ -159,23 +159,19 @@ Device (XHCI) Name (_ADR, 0) // GPLD: Generate Port Location Data (PLD) - Method (GPLD, 1, Serialized) - { - - Name (PCKG, Package (0x01) - { + Method (GPLD, 1, Serialized) { + Local0 = Package () { Buffer (0x10) {} - }) + } - // REV: Revision 0x02 for ACPI 5.0 - CreateField (DerefOf (PCKG[0]), 0, 0x07, REV) - REV = 0x02 + // REV: Revision 2 for ACPI 5.0 + CreateField (DerefOf (Local0[0]), 0, 7, REV) + REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG[0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - - Return (PCKG) + Return (Local0) } /* USB2 */ diff --git a/src/southbridge/intel/bd82x6x/acpi/usb.asl b/src/southbridge/intel/bd82x6x/acpi/usb.asl index 3e2ba78db4..4d80c40e1b 100644 --- a/src/southbridge/intel/bd82x6x/acpi/usb.asl +++ b/src/southbridge/intel/bd82x6x/acpi/usb.asl @@ -26,25 +26,20 @@ Device (EHC1) { Name (_ADR, 0x00000000) - // GPLD: Generate Port Location Data (PLD) - Method (GPLD, 1, Serialized) - { - - Name (PCKG, Package (0x01) - { + Method (GPLD, 1, Serialized) { + Local0 = Package () { Buffer (0x10) {} - }) + } - // REV: Revision 0x02 for ACPI 5.0 - CreateField (DerefOf (PCKG [0]), 0, 0x07, REV) - REV = 0x02 + // REV: Revision 2 for ACPI 5.0 + CreateField (DerefOf (Local0[0]), 0, 7, REV) + REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG [0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - - Return (PCKG) + Return (Local0) } // How many are there? @@ -82,22 +77,19 @@ Device (EHC2) Name (_ADR, 0x00000000) // GPLD: Generate Port Location Data (PLD) - Method (GPLD, 1, Serialized) - { - Name (PCKG, Package (0x01) - { + Method (GPLD, 1, Serialized) { + Local0 = Package () { Buffer (0x10) {} - }) + } - // REV: Revision 0x02 for ACPI 5.0 - CreateField (DerefOf (PCKG [0]), 0, 0x07, REV) - REV = 0x02 + // REV: Revision 2 for ACPI 5.0 + CreateField (DerefOf (Local0[0]), 0, 7, REV) + REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG [0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - - Return (PCKG) + Return (Local0) } // How many are there? diff --git a/src/southbridge/intel/lynxpoint/acpi/xhci.asl b/src/southbridge/intel/lynxpoint/acpi/xhci.asl index c7b0c181ed..d059e08815 100644 --- a/src/southbridge/intel/lynxpoint/acpi/xhci.asl +++ b/src/southbridge/intel/lynxpoint/acpi/xhci.asl @@ -364,18 +364,18 @@ Device (XHCI) // GPLD: Generate Port Location Data (PLD) Method (GPLD, 1, Serialized) { - Name (PCKG, Package () { + Local0 = Package () { Buffer (0x10) {} - }) + } // REV: Revision 2 for ACPI 5.0 - CreateField (DerefOf (PCKG [0]), 0, 7, REV) + CreateField (DerefOf (Local0[0]), 0, 7, REV) REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG [0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - Return (PCKG) + Return (Local0) } Device (PRT1) { Name (_ADR, 1) } // USB Port 0 From 4028996c9d085de94b2a246317fb523356f655c8 Mon Sep 17 00:00:00 2001 From: Luca Lai Date: Thu, 12 Feb 2026 14:41:07 +0800 Subject: [PATCH 581/789] mb/google/nissa/var/pujjoquince: Add support for Micron MT62F1G32D2DS-031RF Add Micron MT62F1G32D2DS-031RF memory part to mem_parts_used.txt and generate corresponding SPD ID entry. BUG=b:483845259 TEST=Use part_id_gen to generate related settings Change-Id: I0476c4dcc55204b8fc278d969fa0f09462671b8c Signed-off-by: Luca Lai Reviewed-on: https://review.coreboot.org/c/coreboot/+/91172 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik Reviewed-by: Paul Menzel --- src/mainboard/google/brya/variants/pujjolo/memory/Makefile.mk | 1 + .../google/brya/variants/pujjolo/memory/dram_id.generated.txt | 1 + .../google/brya/variants/pujjolo/memory/mem_parts_used.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/src/mainboard/google/brya/variants/pujjolo/memory/Makefile.mk b/src/mainboard/google/brya/variants/pujjolo/memory/Makefile.mk index b4d593dccf..b1092e4170 100644 --- a/src/mainboard/google/brya/variants/pujjolo/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/pujjolo/memory/Makefile.mk @@ -8,3 +8,4 @@ SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 0(0b0000) Parts = K3KL6L60GM SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 1(0b0001) Parts = K3KL8L80CM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 2(0b0010) Parts = H58G56CK8BX146 SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 3(0b0011) Parts = H9JCNNNBK3MLYR-N6E +SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 4(0b0100) Parts = MT62F1G32D2DS-031RF WT:C diff --git a/src/mainboard/google/brya/variants/pujjolo/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/pujjolo/memory/dram_id.generated.txt index 3d03fa66a3..a29454e5b5 100644 --- a/src/mainboard/google/brya/variants/pujjolo/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/pujjolo/memory/dram_id.generated.txt @@ -8,3 +8,4 @@ K3KL6L60GM-MGCT 0 (0000) K3KL8L80CM-MGCT 1 (0001) H58G56CK8BX146 2 (0010) H9JCNNNBK3MLYR-N6E 3 (0011) +MT62F1G32D2DS-031RF WT:C 4 (0100) diff --git a/src/mainboard/google/brya/variants/pujjolo/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/pujjolo/memory/mem_parts_used.txt index e1102d6c26..a1fac3fa94 100644 --- a/src/mainboard/google/brya/variants/pujjolo/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/pujjolo/memory/mem_parts_used.txt @@ -13,3 +13,4 @@ K3KL6L60GM-MGCT K3KL8L80CM-MGCT H58G56CK8BX146 H9JCNNNBK3MLYR-N6E +MT62F1G32D2DS-031RF WT:C From 5f9a1ad962a316ae3fb8c5537bfdbc00e316a02b Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 23 Feb 2026 09:00:28 +0530 Subject: [PATCH 582/789] ec/google/chromeec: Add API to turn off lightbar Implement google_chromeec_lightbar_off() to allow the host to explicitly disable the Chrome EC lightbar. This is achieved by sending the LIGHTBAR_CMD_OFF sub-command via the multiplexed EC_CMD_LIGHTBAR_CMD host command. This API is useful for power-saving scenarios or UI synchronization during specific boot modes, such as low-battery or off-mode charging. BUG=None TEST=Verified that the lightbar turns off when this function is called on supported hardware. Change-Id: Ic118dbd5e9af64d06490dd16aa115aca2c1df3a5 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91377 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/ec/google/chromeec/ec.c | 25 +++++++++++++++++++++++++ src/ec/google/chromeec/ec.h | 10 ++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index e6de2c9810..5fe90c8e39 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -1982,6 +1982,31 @@ int google_chromeec_set_lightbar_rgb(unsigned int led, int red, int green, return google_chromeec_command(&cmd); } +/* + * Sends a command to turn off the Chrome EC lightbar. + * + * This function packages a LIGHTBAR_CMD_OFF sub-command into a standard + * EC_CMD_LIGHTBAR_CMD packet. + * + * @return 0 on success, non-zero error code from the EC transport on failure. + */ +int google_chromeec_lightbar_off(void) +{ + const struct ec_params_lightbar req = { + .cmd = LIGHTBAR_CMD_OFF, + }; + + struct chromeec_command cmd = { + .cmd_code = EC_CMD_LIGHTBAR_CMD, + .cmd_size_out = 0, + .cmd_data_out = NULL, + .cmd_size_in = sizeof(req), + .cmd_data_in = &req, + }; + + return google_chromeec_command(&cmd); +} + /* * Check if the battery is critically low and not currently charging. * diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index 075694bd4a..79aa69bcf8 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -562,6 +562,16 @@ int google_chromeec_read_batt_state_of_charge(uint32_t *state); int google_chromeec_set_lightbar_rgb(unsigned int led, int red, int green, int blue); +/* + * Sends a command to turn off the Chrome EC lightbar. + * + * This function packages a LIGHTBAR_CMD_OFF sub-command into a standard + * EC_CMD_LIGHTBAR_CMD packet. + * + * @return 0 on success, non-zero error code from the EC transport on failure. + */ +int google_chromeec_lightbar_off(void); + /* * Check if the battery is critically low and AC is not present. * From b68ba242440894f12dcddfe23455fe8bac17de33 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 23 Feb 2026 10:35:10 +0530 Subject: [PATCH 583/789] ec/google/chromeec: Add API to turn on lightbar Implement google_chromeec_lightbar_on() to allow the host to explicitly enable the Chrome EC lightbar. This function sends the LIGHTBAR_CMD_ON sub-command through the EC_CMD_LIGHTBAR_CMD host command. BUG=None TEST=Verified lightbar can be re-enabled after being turned off on supported hardware. Change-Id: I838525ba091281fefb3b6a33b9974037d06706d4 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91381 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/ec/google/chromeec/ec.c | 26 ++++++++++++++++++++++++++ src/ec/google/chromeec/ec.h | 10 ++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index 5fe90c8e39..ab4df3dde2 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -2007,6 +2007,32 @@ int google_chromeec_lightbar_off(void) return google_chromeec_command(&cmd); } +/* + * Sends a command to enable the Chrome EC lightbar. + * + * This function wraps the LIGHTBAR_CMD_ON sub-command into a standard + * EC_CMD_LIGHTBAR_CMD host command. + * + * @return 0 on success, or a non-zero EC transport error code on failure. + */ +int google_chromeec_lightbar_on(void) +{ + const struct ec_params_lightbar req = { + .cmd = LIGHTBAR_CMD_ON, + }; + + struct chromeec_command cmd = { + .cmd_code = EC_CMD_LIGHTBAR_CMD, + .cmd_size_out = 0, + .cmd_data_out = NULL, + .cmd_size_in = sizeof(req), + .cmd_data_in = &req, + }; + + return google_chromeec_command(&cmd); +} + + /* * Check if the battery is critically low and not currently charging. * diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index 79aa69bcf8..73ec3eeda8 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -572,6 +572,16 @@ int google_chromeec_set_lightbar_rgb(unsigned int led, int red, int green, */ int google_chromeec_lightbar_off(void); +/* + * Sends a command to enable the Chrome EC lightbar. + * + * This function wraps the LIGHTBAR_CMD_ON sub-command into a standard + * EC_CMD_LIGHTBAR_CMD host command. + * + * @return 0 on success, or a non-zero EC transport error code on failure. + */ +int google_chromeec_lightbar_on(void); + /* * Check if the battery is critically low and AC is not present. * From d39f406f55dd5f80f30a762fd4401f92390e09bb Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 23 Feb 2026 09:01:32 +0530 Subject: [PATCH 584/789] mb/google/bluey: Disable lightbar during low-power charging boot Turn off the lightbar when the system boots into Low-Battery with Charger or Off-Mode Charging states. This ensures that the external lightbar does not provide conflicting visual signals while the built-in display is showing the charging animation. Additionally, this prevents unnecessary power consumption from the lightbar in these power-restricted modes. BUG=b:477531197 TEST=Boot bluey in off-mode charging; verify lightbar is disabled. Boot bluey normally; verify lightbar functions as expected. Change-Id: Ice64d700aee82c780f872a3cb18f8a873e9189f5 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91378 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/mainboard.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 099f825344..89a2a2a0eb 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -184,9 +184,16 @@ static void mainboard_init(struct device *dev) if (get_boot_mode() == LB_BOOT_MODE_LOW_BATTERY) trigger_critical_battery_shutdown(); - /* Skip mainboard initialization if boot mode is "low-battery" or "off-mode charging"*/ - if (is_low_power_boot_with_charger()) + /* Skip mainboard initialization if boot mode is "low-battery" or "off-mode charging" */ + if (is_low_power_boot_with_charger()) { + /* Disable the lightbar for Low-Battery or Off-Mode charging sequences. + * This maintains visual consistency between the built-in display + * indicators and the external lightbar. + */ + if (CONFIG(EC_GOOGLE_CHROMEEC)) + google_chromeec_lightbar_off(); return; + } gpi_firmware_load(QUP_0_GSI_BASE); gpi_firmware_load(QUP_1_GSI_BASE); From 2a821d8db63aee0556024e143f71f5e4e0198680 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 24 Feb 2026 09:35:16 +0530 Subject: [PATCH 585/789] mb/google/bluey: Early enablement of lightbar Initialize and turn on the Chrome EC lightbar during the early romstage initialization phase. This ensures that the lightbar is active and ready to provide visual feedback as early as possible in the boot process. This covers edge cases where the lightbar was left in an OFF state by AP firmware and no EC reset occurred to restore defaults. BUG=b:477531197 TEST=Boot bluey and verify the lightbar turns on during the early romstage. Change-Id: I9336acc83d0455c21378ef7cb77939d4d5d54250 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91382 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/romstage.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index a3806668b7..a415228e8b 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -126,6 +126,14 @@ static void early_setup_usb(void) void platform_romstage_main(void) { + /* + * Early initialization of the Chrome EC lightbar. + * Ensures visual continuity if the AP firmware disabled the lightbar + * in a previous boot without a subsequent EC reset. + */ + if (CONFIG(EC_GOOGLE_CHROMEEC)) + google_chromeec_lightbar_on(); + /* * Only alert the user (set LED to red in color) if the lid is closed and the battery * is critically low without AC power. From 086d3a32324ac37be26da5f14108d7facc3ba50f Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 24 Feb 2026 09:40:36 +0530 Subject: [PATCH 586/789] mb/google/fatcat: Enable ChromeOS EC LEDs in romstage Initialize the ChromeOS EC LEDs during the bootblock phase for the fatcat mainboard. This ensures the LEDs are powered on early in the boot process to provide visual feedback to the user. This covers edge cases where the lightbar was left in an OFF state by AP firmware and no EC reset occurred to restore defaults. TEST=Boot moonstome and verify the LEDs turns on during the bootblock stage. Change-Id: I24ce78e4a30ea8fce7d7a90e01525c328db7e325 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91392 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/fatcat/romstage.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mainboard/google/fatcat/romstage.c b/src/mainboard/google/fatcat/romstage.c index 9cece34bf6..5098cd3d8b 100644 --- a/src/mainboard/google/fatcat/romstage.c +++ b/src/mainboard/google/fatcat/romstage.c @@ -48,6 +48,14 @@ void mainboard_memory_init_params(FSPM_UPD *memupd) void platform_romstage_pre_mem(void) { + /* + * Early initialization of the Chrome EC lightbar. + * Ensures visual continuity if the AP firmware disabled the lightbar + * in a previous boot without a subsequent EC reset. + */ + if (CONFIG(EC_GOOGLE_CHROMEEC)) + google_chromeec_lightbar_on(); + /* * Only alert the user (set LED to red in color) if the lid is closed and the battery * is critically low without AC power. From 5c44e689ee763608c5db9fe51a8c075483383f9d Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 24 Feb 2026 12:35:30 +0530 Subject: [PATCH 587/789] vc/google/chromeos: Add platform hook for emergency battery shutdown Introduce platform_handle_emergency_low_battery() to handle the pre-shutdown sequence when battery levels are critical. This hook ensures: 1. Visual feedback is provided (Lightbar set to red). 2. The event is logged to ELOG for post-mortem analysis. 3. A delay is enforced to ensure logs are committed and the user notices the alert before the AP powers off. BUG=none BRANCH=none TEST=Verified lightbar turns red and ELOG is recorded on low battery boot. Change-Id: I3f1b2757002d7a2a76dfb51d24a04e2d81b061bb Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91409 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/include/bootsplash.h | 7 +++++++ src/vendorcode/google/chromeos/battery.c | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/include/bootsplash.h b/src/include/bootsplash.h index cd02f7382e..67b3a405a1 100644 --- a/src/include/bootsplash.h +++ b/src/include/bootsplash.h @@ -191,8 +191,15 @@ void bmp_release_logo(void); */ #if CONFIG(PLATFORM_HAS_LOW_BATTERY_INDICATOR) bool platform_is_low_battery_shutdown_needed(void); +/* + * Platform hooks for system shutdown due to critical battery levels. + * Provides visual feedback via the Lightbar/LEDs and logs the event + * to non-volatile storage before signaling to cut power. + */ +void platform_handle_emergency_low_battery(void); #else static inline bool platform_is_low_battery_shutdown_needed(void) { return false; } +static inline void platform_handle_emergency_low_battery(void) { /* nop */ } #endif /* diff --git a/src/vendorcode/google/chromeos/battery.c b/src/vendorcode/google/chromeos/battery.c index 438098256b..0e676b3f2a 100644 --- a/src/vendorcode/google/chromeos/battery.c +++ b/src/vendorcode/google/chromeos/battery.c @@ -2,6 +2,8 @@ #include #include +#include +#include /* * Check if low battery shutdown is needed @@ -32,3 +34,25 @@ bool platform_is_low_battery_shutdown_needed(void) return result; } + +/* + * Platform hooks for system shutdown due to critical battery levels. + * Provides visual feedback via the Lightbar/LEDs and logs the event + * to non-volatile storage before signaling to cut power. + */ +void platform_handle_emergency_low_battery(void) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC)) + return; + + /* Visual alert: Set Lightbar to solid Red */ + google_chromeec_set_lightbar_rgb(0xff, 0xff, 0x00, 0x00); + + /* Record the event for post-mortem diagnostics (stored in CMOS/Flash) */ + elog_add_event_byte(ELOG_TYPE_LOW_BATTERY_INDICATOR, ELOG_FW_ISSUE_SHUTDOWN); + + /* * Pause briefly to ensure the user perceives the LED change and + * the event log is safely committed to storage. + */ + delay(CONFIG_PLATFORM_POST_RENDER_DELAY_SEC); +} From a96f1a464b4863adb8fdaa22604c61f72d198c0a Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 24 Feb 2026 12:39:06 +0530 Subject: [PATCH 588/789] mb/google/bluey: Use common platform hook for emergency shutdown Refactor trigger_critical_battery_shutdown() to use the newly implemented platform_handle_emergency_low_battery() hook. This removes duplicate logic from the Bluey mainboard directory and ensures consistency with the ChromeOS common battery handling code for visual alerts and ELOG recording. BUG=none BRANCH=none TEST=Build and boot on Bluey; verify emergency shutdown still triggers red LEDs and logs ELOG events correctly. Change-Id: I28da29eb3f0033abe524f7ee12d6b823392e9766 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91410 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/mainboard.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 89a2a2a0eb..2fc8cfdde9 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -11,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -159,14 +159,7 @@ static void trigger_critical_battery_shutdown(void) if (!CONFIG(EC_GOOGLE_CHROMEEC)) return; - /* Set LED to Red to alert the user visually */ - google_chromeec_set_lightbar_rgb(0xff, 0xff, 0x00, 0x00); - - /* Log the event to CMOS/Flash for post-mortem analysis */ - elog_add_event_byte(ELOG_TYPE_LOW_BATTERY_INDICATOR, ELOG_FW_ISSUE_SHUTDOWN); - - /* Allow time for the log to flush and the user to see the LED change */ - delay(CONFIG_PLATFORM_POST_RENDER_DELAY_SEC); + platform_handle_emergency_low_battery(); google_chromeec_ap_poweroff(); } From b50c219557d0ea99571aaf2f939e1c5c6c99ecfb Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 24 Feb 2026 12:42:46 +0530 Subject: [PATCH 589/789] soc/intel: Use centralized emergency battery shutdown hook Migrate the low-battery power-off sequence in Intel common reset logic to use platform_handle_emergency_low_battery(). This ensures that all Intel-based boards benefit from the unified ChromeOS battery alert flow (LED notification and ELOG recording) without duplicating the logic in the SOC layer. BUG=none BRANCH=none TEST=Verified that low-battery shutdown on Intel platforms still correctly logs ELOG and triggers visual alerts via the new hook. Change-Id: I37c15a1f7dd5acee10389c0521e8c9b2f2d90d42 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91411 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/soc/intel/common/reset.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/soc/intel/common/reset.c b/src/soc/intel/common/reset.c index 40cea6bccc..14a32c1697 100644 --- a/src/soc/intel/common/reset.c +++ b/src/soc/intel/common/reset.c @@ -1,10 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include -#include -#include #include #include @@ -26,10 +25,7 @@ void do_board_reset(void) void do_low_battery_poweroff(void) { - if (CONFIG(PLATFORM_HAS_LOW_BATTERY_INDICATOR)) { - elog_add_event_byte(ELOG_TYPE_LOW_BATTERY_INDICATOR, ELOG_FW_ISSUE_SHUTDOWN); - delay(CONFIG_PLATFORM_POST_RENDER_DELAY_SEC); - } + platform_handle_emergency_low_battery(); poweroff(); halt(); From 34c156427dcac5311eb2e96dd847e624cf200809 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 12 Feb 2026 07:11:47 +0100 Subject: [PATCH 590/789] soc/intel/common/block/lpc: Fix AMASK decoding in window detection Commit 339ef9b5c929 ("soc/intel/common/block/lpc: Improve automatic window opening") introduced a bug in the decoding of existing LPC I/O window sizes from the LGIR (LPC Generic I/O Range) registers. The AMASK field in the LGIR register stores bits [7:2] of the address mask, with bits [1:0] implicitly always set to 1 (representing 4-byte granularity). The original implementation incorrectly calculated the window size as: exist_size = 1 + ((reg32 & LPC_LGIR_AMASK_MASK) >> 16) This fails to restore the implicit lower bits [1:0] of the mask. For example, a window programmed with size 8 bytes: - Stored mask: (8-1) & 0xfc = 0x4 (bits [7:2] only) - Incorrectly decoded: 0x4 + 1 = 5 bytes (WRONG) - Correctly decoded: (0x4 | 0x3) + 1 = 8 bytes (CORRECT) This bug caused failures on Panther Lake boards where existing windows were not recognized as covering requested ranges, leading to: [ERROR] LPC: Cannot open IO window: 800 size 8 [ERROR] No more IO windows The fix properly reconstructs the full mask by OR-ing in the implicit bits [1:0] before calculating the size: exist_size = ((amask_raw & 0xfc) | 0x3) + 1 BUG=b:486133237 TEST=Boot Panther Lake Fatcat board, verify no LPC window errors Change-Id: I0b5f95c01da6ce84924a038106edec600e3b97f8 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91418 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N --- src/soc/intel/common/block/lpc/lpc_lib.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/common/block/lpc/lpc_lib.c b/src/soc/intel/common/block/lpc/lpc_lib.c index 337a098848..18cf1670af 100644 --- a/src/soc/intel/common/block/lpc/lpc_lib.c +++ b/src/soc/intel/common/block/lpc/lpc_lib.c @@ -176,8 +176,16 @@ void lpc_open_pmio_window(uint16_t base, uint16_t size) const u32 reg32 = pci_read_config32(PCH_DEV_LPC, LPC_GENERIC_IO_RANGE(i)); if (!(reg32 & LPC_LGIR_EN)) continue; - const struct region exist = region_create(reg32 & LPC_LGIR_ADDR_MASK, - 1 + ((reg32 & LPC_LGIR_AMASK_MASK) >> 16)); + + /* The AMASK field stores bits [7:2] of the address mask. + * Bits [1:0] are always set (4-byte granularity). + * To decode: mask = (amask_raw & 0xfc) | 0x3 + * size = mask + 1 + */ + const u32 exist_base = reg32 & LPC_LGIR_ADDR_MASK; + const u32 amask_raw = (reg32 & LPC_LGIR_AMASK_MASK) >> 16; + const u32 exist_size = ((amask_raw & 0xfc) | 0x3) + 1; + const struct region exist = region_create(exist_base, exist_size); if (region_is_subregion(&exist, &win)) return; From b21e861ab5975fd8e5cbcb45728313be16d67530 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 23 Feb 2026 07:18:19 -0800 Subject: [PATCH 591/789] soc/intel/common/feature/i2c: Add common devfn mapping Introduce a common implementation for I2C device function to bus number mapping that can be shared across multiple Intel SoC platforms. The implementation uses: - CONFIG_SOC_INTEL_I2C_DEV_MAX: Kconfig value for max I2C controllers - SOC_I2C_DEVFN(n): SoC-specific macro for I2C devfn names This eliminates duplicate code across platforms that follow the standard I2C controller numbering scheme. Change-Id: Ib242d7a839ccb26394794382098cecb658adf698 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91258 Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- src/soc/intel/common/feature/i2c/Kconfig | 8 ++ src/soc/intel/common/feature/i2c/Makefile.mk | 4 + src/soc/intel/common/feature/i2c/i2c_devfn.c | 79 ++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 src/soc/intel/common/feature/i2c/Kconfig create mode 100644 src/soc/intel/common/feature/i2c/Makefile.mk create mode 100644 src/soc/intel/common/feature/i2c/i2c_devfn.c diff --git a/src/soc/intel/common/feature/i2c/Kconfig b/src/soc/intel/common/feature/i2c/Kconfig new file mode 100644 index 0000000000..5dede903d3 --- /dev/null +++ b/src/soc/intel/common/feature/i2c/Kconfig @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + bool + help + Common I2C device function to bus mapping implementation. + SoCs using this must define SOC_I2C_DEVFN(n) macro in their + pci_devs.h and CONFIG_SOC_INTEL_I2C_DEV_MAX in their Kconfig. diff --git a/src/soc/intel/common/feature/i2c/Makefile.mk b/src/soc/intel/common/feature/i2c/Makefile.mk new file mode 100644 index 0000000000..2b4a6ab6fb --- /dev/null +++ b/src/soc/intel/common/feature/i2c/Makefile.mk @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_I2C_DEVFN) += i2c_devfn.c +smm-$(CONFIG_SOC_INTEL_COMMON_FEATURE_I2C_DEVFN) += i2c_devfn.c diff --git a/src/soc/intel/common/feature/i2c/i2c_devfn.c b/src/soc/intel/common/feature/i2c/i2c_devfn.c new file mode 100644 index 0000000000..e8adb2fe4b --- /dev/null +++ b/src/soc/intel/common/feature/i2c/i2c_devfn.c @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +/* + * SoC-specific I2C device function to bus number mapping. + * + * Each SoC must define: + * - CONFIG_SOC_INTEL_I2C_DEV_MAX: Maximum number of I2C controllers + * - SOC_I2C_DEVFN(n): Macro that expands to the SoC-specific I2C device + * function name (e.g., PCH_DEVFN_I2Cn or PCI_DEVFN_I2Cn) + */ + +_Static_assert(CONFIG_SOC_INTEL_I2C_DEV_MAX <= 8, + "CONFIG_SOC_INTEL_I2C_DEV_MAX greater than 8 is not supported."); + +int dw_i2c_soc_devfn_to_bus(unsigned int devfn) +{ + switch (devfn) { + case SOC_I2C_DEVFN(0): + return 0; + case SOC_I2C_DEVFN(1): + return 1; + case SOC_I2C_DEVFN(2): + return 2; + case SOC_I2C_DEVFN(3): + return 3; +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 4 + case SOC_I2C_DEVFN(4): + return 4; +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 5 + case SOC_I2C_DEVFN(5): + return 5; +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 6 + case SOC_I2C_DEVFN(6): + return 6; +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 7 + case SOC_I2C_DEVFN(7): + return 7; +#endif + } + return -1; +} + +int dw_i2c_soc_bus_to_devfn(unsigned int bus) +{ + switch (bus) { + case 0: + return SOC_I2C_DEVFN(0); + case 1: + return SOC_I2C_DEVFN(1); + case 2: + return SOC_I2C_DEVFN(2); + case 3: + return SOC_I2C_DEVFN(3); +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 4 + case 4: + return SOC_I2C_DEVFN(4); +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 5 + case 5: + return SOC_I2C_DEVFN(5); +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 6 + case 6: + return SOC_I2C_DEVFN(6); +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 7 + case 7: + return SOC_I2C_DEVFN(7); +#endif + } + return -1; +} From 749bae2f94ce1116a95e0ac4342cf30eeebd2cf4 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 23 Feb 2026 07:46:06 -0800 Subject: [PATCH 592/789] soc/intel/alderlake: Use common I2C devfn mapping Replace platform-specific i2c.c with common implementation. Defines SOC_I2C_DEVFN(n) macro and uses existing CONFIG_SOC_INTEL_I2C_DEV_MAX Kconfig. Change-Id: I5d8420231d1252986b8b7274a4c8c2f6d41f759d Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91259 Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- src/soc/intel/alderlake/Kconfig | 1 + src/soc/intel/alderlake/Makefile.mk | 1 - src/soc/intel/alderlake/i2c.c | 57 ------------------- .../intel/alderlake/include/soc/pci_devs.h | 3 + 4 files changed, 4 insertions(+), 58 deletions(-) delete mode 100644 src/soc/intel/alderlake/i2c.c diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 9034f5d252..c78a09076d 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -85,6 +85,7 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index eafba3cbd6..2e97718bc2 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -6,7 +6,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += gspi.c -all-y += i2c.c all-y += pmutil.c all-y += spi.c diff --git a/src/soc/intel/alderlake/i2c.c b/src/soc/intel/alderlake/i2c.c deleted file mode 100644 index 5fcca2a9e7..0000000000 --- a/src/soc/intel/alderlake/i2c.c +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 13 - */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - case PCH_DEVFN_I2C6: - return 6; - case PCH_DEVFN_I2C7: - return 7; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - case 6: - return PCH_DEVFN_I2C6; - case 7: - return PCH_DEVFN_I2C7; - } - return -1; -} diff --git a/src/soc/intel/alderlake/include/soc/pci_devs.h b/src/soc/intel/alderlake/include/soc/pci_devs.h index 9876397219..13cea6d2fc 100644 --- a/src/soc/intel/alderlake/include/soc/pci_devs.h +++ b/src/soc/intel/alderlake/include/soc/pci_devs.h @@ -284,3 +284,6 @@ #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #endif + +/* for common code */ +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n From fe728d62c92bfb79d7b5102d75db2dca713f5989 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 23 Feb 2026 07:46:06 -0800 Subject: [PATCH 593/789] soc/intel/elkhartlake: Use common I2C devfn mapping Replace platform-specific i2c.c with common implementation. Defines SOC_I2C_DEVFN(n) macro and uses existing CONFIG_SOC_INTEL_I2C_DEV_MAX Kconfig. Change-Id: I09aec87fbac0861d3b50d26f475016fdd5aa6fb7 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91260 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/elkhartlake/Kconfig | 1 + src/soc/intel/elkhartlake/Makefile.mk | 1 - src/soc/intel/elkhartlake/i2c.c | 51 ------------------- .../intel/elkhartlake/include/soc/pci_devs.h | 3 ++ 4 files changed, 4 insertions(+), 52 deletions(-) delete mode 100644 src/soc/intel/elkhartlake/i2c.c diff --git a/src/soc/intel/elkhartlake/Kconfig b/src/soc/intel/elkhartlake/Kconfig index 79e57e6894..4e5b9bc99c 100644 --- a/src/soc/intel/elkhartlake/Kconfig +++ b/src/soc/intel/elkhartlake/Kconfig @@ -56,6 +56,7 @@ config SOC_INTEL_ELKHARTLAKE select SOC_INTEL_COMMON_BLOCK_SMM select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/elkhartlake/Makefile.mk b/src/soc/intel/elkhartlake/Makefile.mk index 393a90d17c..b457a2a53b 100644 --- a/src/soc/intel/elkhartlake/Makefile.mk +++ b/src/soc/intel/elkhartlake/Makefile.mk @@ -7,7 +7,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += gspi.c -all-y += i2c.c all-y += pmutil.c all-y += spi.c diff --git a/src/soc/intel/elkhartlake/i2c.c b/src/soc/intel/elkhartlake/i2c.c deleted file mode 100644 index 78ee37b72d..0000000000 --- a/src/soc/intel/elkhartlake/i2c.c +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - case PCH_DEVFN_I2C6: - return 6; - case PCH_DEVFN_I2C7: - return 7; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - case 6: - return PCH_DEVFN_I2C6; - case 7: - return PCH_DEVFN_I2C7; - } - return -1; -} diff --git a/src/soc/intel/elkhartlake/include/soc/pci_devs.h b/src/soc/intel/elkhartlake/include/soc/pci_devs.h index 743c3a8cd6..885ebac506 100644 --- a/src/soc/intel/elkhartlake/include/soc/pci_devs.h +++ b/src/soc/intel/elkhartlake/include/soc/pci_devs.h @@ -253,3 +253,6 @@ #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #endif + +/* for common code */ +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n From 83325f354b1cc2e82972ab3f29d24d8a38ee0dff Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 23 Feb 2026 07:46:06 -0800 Subject: [PATCH 594/789] soc/intel/tigerlake: Use common I2C devfn mapping Replace platform-specific i2c.c with common implementation. Defines SOC_I2C_DEVFN(n) macro and uses existing CONFIG_SOC_INTEL_I2C_DEV_MAX Kconfig. Change-Id: Id8ac536813cadedc8d49ccb922d583a678436d2e Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91261 Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- src/soc/intel/tigerlake/Kconfig | 1 + src/soc/intel/tigerlake/Makefile.mk | 1 - src/soc/intel/tigerlake/i2c.c | 49 ------------------- .../intel/tigerlake/include/soc/pci_devs.h | 3 ++ 4 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 src/soc/intel/tigerlake/i2c.c diff --git a/src/soc/intel/tigerlake/Kconfig b/src/soc/intel/tigerlake/Kconfig index 1d6c21e06f..48cf447bd1 100644 --- a/src/soc/intel/tigerlake/Kconfig +++ b/src/soc/intel/tigerlake/Kconfig @@ -73,6 +73,7 @@ config SOC_INTEL_TIGERLAKE select SOC_INTEL_COMMON_BLOCK_USB4_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/tigerlake/Makefile.mk b/src/soc/intel/tigerlake/Makefile.mk index 19b504362f..53a5d9580f 100644 --- a/src/soc/intel/tigerlake/Makefile.mk +++ b/src/soc/intel/tigerlake/Makefile.mk @@ -7,7 +7,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += gspi.c -all-y += i2c.c all-y += pmutil.c all-y += spi.c diff --git a/src/soc/intel/tigerlake/i2c.c b/src/soc/intel/tigerlake/i2c.c deleted file mode 100644 index 5b4e0cb214..0000000000 --- a/src/soc/intel/tigerlake/i2c.c +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Tiger Lake Processor PCH Datasheet - * Document number: 575857 - * Chapter number: 13 - */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/tigerlake/include/soc/pci_devs.h b/src/soc/intel/tigerlake/include/soc/pci_devs.h index c615f3bc70..29216f5670 100644 --- a/src/soc/intel/tigerlake/include/soc/pci_devs.h +++ b/src/soc/intel/tigerlake/include/soc/pci_devs.h @@ -251,3 +251,6 @@ #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #endif + +/* for common code */ +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n From a0ba812a096d1683297b0e7622514d1a7d22b774 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 23 Feb 2026 07:46:06 -0800 Subject: [PATCH 595/789] soc/intel/jasperlake: Use common I2C devfn mapping Replace platform-specific i2c.c with common implementation. Defines SOC_I2C_DEVFN(n) macro and uses existing CONFIG_SOC_INTEL_I2C_DEV_MAX Kconfig. Change-Id: Ia98748818fde9d1048355d4a144211a327c453ba Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91262 Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- src/soc/intel/jasperlake/Kconfig | 1 + src/soc/intel/jasperlake/Makefile.mk | 1 - src/soc/intel/jasperlake/i2c.c | 43 ------------------- .../intel/jasperlake/include/soc/pci_devs.h | 3 ++ 4 files changed, 4 insertions(+), 44 deletions(-) delete mode 100644 src/soc/intel/jasperlake/i2c.c diff --git a/src/soc/intel/jasperlake/Kconfig b/src/soc/intel/jasperlake/Kconfig index 6de9931de3..b1257a76a0 100644 --- a/src/soc/intel/jasperlake/Kconfig +++ b/src/soc/intel/jasperlake/Kconfig @@ -56,6 +56,7 @@ config SOC_INTEL_JASPERLAKE select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/jasperlake/Makefile.mk b/src/soc/intel/jasperlake/Makefile.mk index 6346f2d3d2..875cc76a9c 100644 --- a/src/soc/intel/jasperlake/Makefile.mk +++ b/src/soc/intel/jasperlake/Makefile.mk @@ -7,7 +7,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += gspi.c -all-y += i2c.c all-y += pmutil.c all-y += spi.c diff --git a/src/soc/intel/jasperlake/i2c.c b/src/soc/intel/jasperlake/i2c.c deleted file mode 100644 index c13a1a6099..0000000000 --- a/src/soc/intel/jasperlake/i2c.c +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/jasperlake/include/soc/pci_devs.h b/src/soc/intel/jasperlake/include/soc/pci_devs.h index 2d2b96a09e..5e9107003e 100644 --- a/src/soc/intel/jasperlake/include/soc/pci_devs.h +++ b/src/soc/intel/jasperlake/include/soc/pci_devs.h @@ -199,3 +199,6 @@ #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #endif + +/* for common code */ +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n From 7f922438be7d5a1e592550095ad195375820d0e3 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 23 Feb 2026 07:46:06 -0800 Subject: [PATCH 596/789] soc/intel/cannonlake: Use common I2C devfn mapping Replace platform-specific i2c.c with common implementation. Defines SOC_I2C_DEVFN(n) macro and uses existing CONFIG_SOC_INTEL_I2C_DEV_MAX Kconfig. Change-Id: I0117a418d35cea3e7c0442c8c3ea27d17b8bdf06 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91263 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/cannonlake/Kconfig | 1 + src/soc/intel/cannonlake/Makefile.mk | 5 --- src/soc/intel/cannonlake/i2c.c | 43 ------------------- .../intel/cannonlake/include/soc/pci_devs.h | 3 ++ 4 files changed, 4 insertions(+), 48 deletions(-) delete mode 100644 src/soc/intel/cannonlake/i2c.c diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index d7075d0d0d..be788ae527 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -60,6 +60,7 @@ config SOC_INTEL_CANNONLAKE_BASE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_NHLT diff --git a/src/soc/intel/cannonlake/Makefile.mk b/src/soc/intel/cannonlake/Makefile.mk index fc51fa0067..2f0c7c1a40 100644 --- a/src/soc/intel/cannonlake/Makefile.mk +++ b/src/soc/intel/cannonlake/Makefile.mk @@ -11,14 +11,12 @@ bootblock-y += bootblock/pch.c bootblock-y += pmutil.c bootblock-y += bootblock/report_platform.c bootblock-y += gspi.c -bootblock-y += i2c.c bootblock-y += spi.c bootblock-y += lpc.c bootblock-y += p2sb.c romstage-y += cnl_memcfg_init.c romstage-y += gspi.c -romstage-y += i2c.c romstage-y += lpc.c romstage-y += pcie_rp.c romstage-y += pmutil.c @@ -33,7 +31,6 @@ ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c ramstage-y += gspi.c -ramstage-y += i2c.c ramstage-y += lockdown.c ramstage-y += lpc.c ramstage-y += nhlt.c @@ -55,12 +52,10 @@ smm-y += smihandler.c smm-y += xhci.c postcar-y += pmutil.c -postcar-y += i2c.c postcar-y += gspi.c postcar-y += spi.c verstage-y += gspi.c -verstage-y += i2c.c verstage-y += pmutil.c verstage-y += spi.c diff --git a/src/soc/intel/cannonlake/i2c.c b/src/soc/intel/cannonlake/i2c.c deleted file mode 100644 index c13a1a6099..0000000000 --- a/src/soc/intel/cannonlake/i2c.c +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/cannonlake/include/soc/pci_devs.h b/src/soc/intel/cannonlake/include/soc/pci_devs.h index d5aa36b554..607733c98e 100644 --- a/src/soc/intel/cannonlake/include/soc/pci_devs.h +++ b/src/soc/intel/cannonlake/include/soc/pci_devs.h @@ -210,3 +210,6 @@ #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #endif + +/* for common code */ +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n From f703f2800cd0038e39104a6e4c04c6c0244def95 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 23 Feb 2026 07:46:07 -0800 Subject: [PATCH 597/789] soc/intel/skylake: Use common I2C devfn mapping Replace platform-specific i2c.c with common implementation. Defines SOC_I2C_DEVFN(n) macro and uses existing CONFIG_SOC_INTEL_I2C_DEV_MAX Kconfig. Change-Id: I9ae46e252c599e4ee82a60c03a8d83f874a8da98 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91264 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/skylake/Kconfig | 1 + src/soc/intel/skylake/Makefile.mk | 5 --- src/soc/intel/skylake/i2c.c | 44 -------------------- src/soc/intel/skylake/include/soc/pci_devs.h | 3 ++ 4 files changed, 4 insertions(+), 49 deletions(-) delete mode 100644 src/soc/intel/skylake/i2c.c diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index aa64511249..d3bdd4c8c3 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -59,6 +59,7 @@ config SOC_INTEL_COMMON_SKYLAKE_BASE select SOC_INTEL_COMMON_BLOCK_UART select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/skylake/Makefile.mk b/src/soc/intel/skylake/Makefile.mk index de251f2de3..c8513eaf73 100644 --- a/src/soc/intel/skylake/Makefile.mk +++ b/src/soc/intel/skylake/Makefile.mk @@ -8,7 +8,6 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo bootblock-y += bootblock/bootblock.c -bootblock-y += i2c.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c bootblock-y += gpio.c @@ -21,12 +20,10 @@ bootblock-y += lpc.c verstage-y += gpio.c verstage-y += gspi.c verstage-y += pmutil.c -verstage-y += i2c.c verstage-y += spi.c romstage-y += gpio.c romstage-y += gspi.c -romstage-y += i2c.c romstage-y += me.c romstage-y += pcie_rp.c romstage-y += pmutil.c @@ -41,7 +38,6 @@ ramstage-y += fadt.c ramstage-y += finalize.c ramstage-y += gpio.c ramstage-y += gspi.c -ramstage-y += i2c.c ramstage-y += graphics.c ramstage-y += irq.c ramstage-y += lockdown.c @@ -67,7 +63,6 @@ smm-y += xhci.c postcar-y += gspi.c postcar-y += spi.c -postcar-y += i2c.c ifeq ($(CONFIG_SKYLAKE_SOC_PCH_H),y) ifeq ($(CONFIG_MAINBOARD_SUPPORTS_SKYLAKE_CPU),y) diff --git a/src/soc/intel/skylake/i2c.c b/src/soc/intel/skylake/i2c.c deleted file mode 100644 index 521fcb0dd7..0000000000 --- a/src/soc/intel/skylake/i2c.c +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/skylake/include/soc/pci_devs.h b/src/soc/intel/skylake/include/soc/pci_devs.h index b1e5208523..2f6f649542 100644 --- a/src/soc/intel/skylake/include/soc/pci_devs.h +++ b/src/soc/intel/skylake/include/soc/pci_devs.h @@ -193,3 +193,6 @@ #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #endif + +/* for common code */ +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n From 78e36f8c78f9b1188d7f5bc734b254ad62caecc9 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 23 Feb 2026 07:46:07 -0800 Subject: [PATCH 598/789] soc/intel/meteorlake: Use common I2C devfn mapping Replace platform-specific i2c.c with common implementation. Defines SOC_I2C_DEVFN(n) macro and uses existing CONFIG_SOC_INTEL_I2C_DEV_MAX Kconfig. Change-Id: Ifab488ada515656a5108aee5a6f481abda6a9c0d Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91265 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/meteorlake/Kconfig | 1 + src/soc/intel/meteorlake/Makefile.mk | 1 - src/soc/intel/meteorlake/i2c.c | 43 ------------------- .../intel/meteorlake/include/soc/pci_devs.h | 1 + 4 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 src/soc/intel/meteorlake/i2c.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index b223fa01d2..7d7d2df513 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -87,6 +87,7 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_BASECODE select SOC_INTEL_COMMON_BASECODE_RAMTOP diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index 81be9ff856..1e9a1fc93d 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -7,7 +7,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += gspi.c -all-y += i2c.c all-y += pmutil.c all-y += spi.c all-y += gpio.c diff --git a/src/soc/intel/meteorlake/i2c.c b/src/soc/intel/meteorlake/i2c.c deleted file mode 100644 index 50ab4a73eb..0000000000 --- a/src/soc/intel/meteorlake/i2c.c +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCI_DEVFN_I2C0: - return 0; - case PCI_DEVFN_I2C1: - return 1; - case PCI_DEVFN_I2C2: - return 2; - case PCI_DEVFN_I2C3: - return 3; - case PCI_DEVFN_I2C4: - return 4; - case PCI_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCI_DEVFN_I2C0; - case 1: - return PCI_DEVFN_I2C1; - case 2: - return PCI_DEVFN_I2C2; - case 3: - return PCI_DEVFN_I2C3; - case 4: - return PCI_DEVFN_I2C4; - case 5: - return PCI_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/meteorlake/include/soc/pci_devs.h b/src/soc/intel/meteorlake/include/soc/pci_devs.h index 0e55da24bb..034f5e6b6c 100644 --- a/src/soc/intel/meteorlake/include/soc/pci_devs.h +++ b/src/soc/intel/meteorlake/include/soc/pci_devs.h @@ -241,5 +241,6 @@ #define SA_DEVFN_TCSS_DMA1 PCI_DEVFN_TCSS_DMA1 #define SA_DEV_IGD PCI_DEV_IGD #define SA_DEVFN_IGD PCI_DEVFN_IGD +#define SOC_I2C_DEVFN(n) PCI_DEVFN_I2C##n #endif // _SOC_METEORLAKE_PCI_DEVS_H_ From d5161611a4b36acd3e82c4bc764c7539616446a2 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 23 Feb 2026 07:46:07 -0800 Subject: [PATCH 599/789] soc/intel/pantherlake: Use common I2C devfn mapping Replace platform-specific i2c.c with common implementation. Defines SOC_I2C_DEVFN(n) macro and uses existing CONFIG_SOC_INTEL_I2C_DEV_MAX Kconfig. Change-Id: I9200c41bf459dfef29599cc1c736e14e8cbd36b9 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91266 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/pantherlake/Kconfig | 1 + src/soc/intel/pantherlake/Makefile.mk | 1 - src/soc/intel/pantherlake/i2c.c | 43 ------------------- .../intel/pantherlake/include/soc/pci_devs.h | 1 + 4 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 src/soc/intel/pantherlake/i2c.c diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index a67b2410ad..2e1bc2ef10 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -97,6 +97,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index fd9760a965..dadba99ccd 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -8,7 +8,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += gspi.c -all-y += i2c.c all-y += pmutil.c all-y += spi.c all-y += gpio.c diff --git a/src/soc/intel/pantherlake/i2c.c b/src/soc/intel/pantherlake/i2c.c deleted file mode 100644 index 50ab4a73eb..0000000000 --- a/src/soc/intel/pantherlake/i2c.c +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCI_DEVFN_I2C0: - return 0; - case PCI_DEVFN_I2C1: - return 1; - case PCI_DEVFN_I2C2: - return 2; - case PCI_DEVFN_I2C3: - return 3; - case PCI_DEVFN_I2C4: - return 4; - case PCI_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCI_DEVFN_I2C0; - case 1: - return PCI_DEVFN_I2C1; - case 2: - return PCI_DEVFN_I2C2; - case 3: - return PCI_DEVFN_I2C3; - case 4: - return PCI_DEVFN_I2C4; - case 5: - return PCI_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/pantherlake/include/soc/pci_devs.h b/src/soc/intel/pantherlake/include/soc/pci_devs.h index 25468ab39a..a1ef4f4c32 100644 --- a/src/soc/intel/pantherlake/include/soc/pci_devs.h +++ b/src/soc/intel/pantherlake/include/soc/pci_devs.h @@ -256,5 +256,6 @@ #define SA_DEVFN_TCSS_DMA1 PCI_DEVFN_TCSS_DMA1 #define SA_DEV_IGD PCI_DEV_IGD #define SA_DEVFN_IGD PCI_DEVFN_IGD +#define SOC_I2C_DEVFN(n) PCI_DEVFN_I2C##n #endif // _SOC_PANTHERLAKE_PCI_DEVS_H_ From a59ddda11ed165c2420a1233b6b1eb98aff8be13 Mon Sep 17 00:00:00 2001 From: Purdea Andrei Date: Sun, 14 Sep 2025 17:17:32 +0300 Subject: [PATCH 600/789] Doc/mb/protectli/fw6: describe revisions and more variants - Add documentation about Old/New motherboard revisions - Mention that FW6A/B/C exist as both Old and New Revision - Mention that the current codebase only supports the Old Revision - Add documentation about FW6D and FW6E variants, currently unsupported Signed-off-by: Purdea Andrei Change-Id: Ifdf1624c8d206326c64163382b31c6001300b4df Reviewed-on: https://review.coreboot.org/c/coreboot/+/88226 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- Documentation/mainboard/protectli/fw6.md | 82 +++++++++++++++++++++--- 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/Documentation/mainboard/protectli/fw6.md b/Documentation/mainboard/protectli/fw6.md index df61ee364b..2f55d8566e 100644 --- a/Documentation/mainboard/protectli/fw6.md +++ b/Documentation/mainboard/protectli/fw6.md @@ -57,8 +57,13 @@ This chip is located on the bottom side of the case (the radiator side). One has to remove all screws (in order): 4 top cover screws, 4 side cover screws (one side is enough), 4 mainboard screws, 4 CPU screws (under DIMMs). Lift up the mainboard and turn around it. The flash chip is near the SoC on the DIMM -slots side. Use a clip (or solder the wires) to program the chip. Specifically, -it's a Macronix MX25L6406E (3.3V) -[datasheet][MX25L6406E]. +slots side. Desolder and reprogram the chip, or use a clip (or solder the +wires) to program the chip. Specifically, it's a Macronix MX25L6406E (3.3V) +-[datasheet][MX25L6406E], while on some other boards it's a Macronix MX25L6436F. + +At least on some revisions of the motherboard, it's not possible to reprogram +the chip with a clip, while the board is powered off, because there's no diode +to prevent backfeeding power to other components on the board. ## Known issues @@ -99,8 +104,26 @@ the cables or not being populated on the board case. ## Technology -There are 3 variants of FW6 boards: FW6A, FW6B and FW6C. They differ only in -used SoC. +There are 5 variants of FW6 boards: FW6A, FW6B, FW6C, FW6D and FW6E. They differ +in used SoC. + +There are two revisions of the motherboard, hereby called Old Revision +(using IT8772E Super I/O chip), and New Revision (using IT8613E Super I/O chip). +Besides the different Super I/O chip, they also differ in component placement, +and available internal motherboard headers. The Old Revision motherboards are +marked with silkscreen "YL-SK1L6-V1", while the New Revision motherboards are +marked with silkscreen "KBR6LAV20". + +WARNING: The current code base only supports the Old Revision motherboards. + +To compare the two motherboard +revisions one may compare the [New Revision FW6A Datasheet] to the +[Old Revision FW6 Series Hardware Overview]. + +The FW6A/FW6B/FW6C variants are known to have been produced with both +motherboard revisions. + +The FW6D/FW6E variants are only known to exist with the new motherboard revision. - FW6A: @@ -110,10 +133,12 @@ used SoC. +------------------+--------------------------------------------------+ | PCH | Kaby Lake U w/ iHDCP2.2 Base | +------------------+--------------------------------------------------+ -| Super I/O, EC | ITE IT8772E | +| Super I/O, EC | Old revision: ITE IT8772E, New rev.: ITE IT8613E | +------------------+--------------------------------------------------+ | Coprocessor | Intel Management Engine | +------------------+--------------------------------------------------+ +| Support | Currently only the Old Revision is supported | ++------------------+--------------------------------------------------+ ``` - FW6B: @@ -124,10 +149,12 @@ used SoC. +------------------+--------------------------------------------------+ | PCH | Kaby Lake U w/ iHDCP2.2 Premium | +------------------+--------------------------------------------------+ -| Super I/O, EC | ITE IT8772E | +| Super I/O, EC | Old revision: ITE IT8772E, New rev.: ITE IT8613E | +------------------+--------------------------------------------------+ | Coprocessor | Intel Management Engine | +------------------+--------------------------------------------------+ +| Support | Currently only the Old Revision is supported | ++------------------+--------------------------------------------------+ ``` - FW6C: @@ -138,21 +165,58 @@ used SoC. +------------------+--------------------------------------------------+ | PCH | Kaby Lake U w/ iHDCP2.2 Premium | +------------------+--------------------------------------------------+ -| Super I/O, EC | ITE IT8772E | +| Super I/O, EC | Old revision: ITE IT8772E, New rev.: ITE IT8613E | +------------------+--------------------------------------------------+ | Coprocessor | Intel Management Engine | +------------------+--------------------------------------------------+ +| Support | Currently only the Old Revision is supported | ++------------------+--------------------------------------------------+ +``` + +- FW6D: + +```{eval-rst} ++------------------+--------------------------------------------------+ +| CPU | Intel Core i5-8250U | ++------------------+--------------------------------------------------+ +| PCH | Kaby Lake U w/ iHDCP2.2 Premium | ++------------------+--------------------------------------------------+ +| Super I/O, EC | ITE IT8613E | ++------------------+--------------------------------------------------+ +| Coprocessor | Intel Management Engine | ++------------------+--------------------------------------------------+ +| Support | Currently not supported | ++------------------+--------------------------------------------------+ +``` + +- FW6E: + +```{eval-rst} ++------------------+--------------------------------------------------+ +| CPU | Intel Core i7-8550U | ++------------------+--------------------------------------------------+ +| PCH | Kaby Lake U w/ iHDCP2.2 Premium | ++------------------+--------------------------------------------------+ +| Super I/O, EC | ITE IT8613E | ++------------------+--------------------------------------------------+ +| Coprocessor | Intel Management Engine | ++------------------+--------------------------------------------------+ +| Support | Currently not supported | ++------------------+--------------------------------------------------+ ``` ## Other compatible boards As Protectli licenses and uses [Yanling] appliances with no modifications to the actual hardware, any compatible [Yanling] appliances would work. -Specifically, look for hardware with the same CPU and NIC and coreboot -should be able to compile and boot with no modifications required. +Specifically, look for hardware with the same CPU, NIC, and Super I/O chip +and coreboot should be able to compile and boot with no modifications +required. [Protectli FW6]: https://protectli.com/vault-6-port/ [website]: https://protectli.com/kb/coreboot-on-the-vault/ [MX25L6406E]: https://www.macronix.com/Lists/Datasheet/Attachments/7370/MX25L6406E,%203V,%2064Mb,%20v1.9.pdf [flashrom]: https://flashrom.org/ [Yanling]: http://www.ylgkdn.cn/ +[New Revision FW6A Datasheet]: https://kb.protectli.com/wp-content/uploads/sites/9/2025/04/FW6A-Datasheet-20250204.pdf +[Old Revision FW6 Series Hardware Overview]: https://kb.protectli.com/kb/fw6-hardware-overview/ From 3cde265c2821556a0080a584eaa08f0094462357 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 19:07:03 +0100 Subject: [PATCH 601/789] sb/intel/lynxpoint/acpi/xhci.asl: Drop redundant writes Setting `SWAI` and `SAIP` is already done in the LPT-H and LPT-LP specific branches, so there's no need to do it again. WPT-LP does NOT need these writes. Change-Id: Ib5156fab1384cdc531fc1d49dd61e5fc4600e894 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91391 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/southbridge/intel/lynxpoint/acpi/xhci.asl | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/southbridge/intel/lynxpoint/acpi/xhci.asl b/src/southbridge/intel/lynxpoint/acpi/xhci.asl index d059e08815..d5b97d03e3 100644 --- a/src/southbridge/intel/lynxpoint/acpi/xhci.asl +++ b/src/southbridge/intel/lynxpoint/acpi/xhci.asl @@ -256,12 +256,6 @@ Device (XHCI) ^SAIP = 0 #endif - // Clear PCI CFG offset 0x40[11] - ^SWAI = 0 - - // Clear PCI CFG offset 0x44[13:12] - ^SAIP = 0 - Return () } @@ -332,12 +326,6 @@ Device (XHCI) ^SAIP = 1 #endif - // Set PCI CFG offset 0x40[11] - ^SWAI = 1 - - // Set PCI CFG offset 0x44[13:12] - ^SAIP = 1 - // Put device in D3 ^D0D3 = 3 From 813edbbde879e4db365435f3fb025985a0cdfec8 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 20:43:45 +0100 Subject: [PATCH 602/789] sb/intel/lynxpoint/acpi/xhci.asl: Use macros for constants Declaring named objects for constants is not ideal, especially when done inside of a method (it is highly inefficient). Instead, use preprocessor defines. Change-Id: I1143f2aa09a2ed04da92edcf6ae9d832c0b5e2fa Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91393 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/southbridge/intel/lynxpoint/acpi/xhci.asl | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/southbridge/intel/lynxpoint/acpi/xhci.asl b/src/southbridge/intel/lynxpoint/acpi/xhci.asl index d5b97d03e3..9c7bb2c1ac 100644 --- a/src/southbridge/intel/lynxpoint/acpi/xhci.asl +++ b/src/southbridge/intel/lynxpoint/acpi/xhci.asl @@ -6,9 +6,6 @@ Device (XHCI) { Name (_ADR, 0x00140000) - Name (PLSD, 5) // Port Link State - RxDetect - Name (PLSP, 7) // Port Link State - Polling - OperationRegion (XPRT, PCI_Config, 0, 0x100) Field (XPRT, AnyAcc, NoLock, Preserve) { @@ -57,27 +54,24 @@ Device (XHCI) PSC3, 32, } - // Port Enabled/Disabled (Bit 1) - Name (PEDB, 1 << 1) - - // Change Status (Bits 23:17) - Name (CHST, 0x7f << 17) +#define PSC_PORT_ENABLED (1 << 1) +#define PSC_PORT_CHANGE_BITS (0x7f << 17) // Port 0 - Local0 = PSC0 & ~PEDB - PSC0 = Local0 | CHST + Local0 = PSC0 & ~PSC_PORT_ENABLED + PSC0 = Local0 | PSC_PORT_CHANGE_BITS // Port 1 - Local0 = PSC1 & ~PEDB - PSC1 = Local0 | CHST + Local0 = PSC1 & ~PSC_PORT_ENABLED + PSC1 = Local0 | PSC_PORT_CHANGE_BITS // Port 2 - Local0 = PSC2 & ~PEDB - PSC2 = Local0 | CHST + Local0 = PSC2 & ~PSC_PORT_ENABLED + PSC2 = Local0 | PSC_PORT_CHANGE_BITS // Port 3 - Local0 = PSC3 & ~PEDB - PSC3 = Local0 | CHST + Local0 = PSC3 & ~PSC_PORT_ENABLED + PSC3 = Local0 | PSC_PORT_CHANGE_BITS } Method (LPS0, 0, Serialized) @@ -127,10 +121,12 @@ Device (XHCI) WPR4, 1, // [31] Warm Port Reset } +#define PLS_POLLING 7 + // Wait for all powered ports to finish polling Local0 = 10 - While ((PPR1 == 1 && PLS1 == PLSP || PPR2 == 1 && PLS2 == PLSP) || - (PPR3 == 1 && PLS3 == PLSP || PPR4 == 1 && PLS4 == PLSP)) + While ((PPR1 == 1 && PLS1 == PLS_POLLING || PPR2 == 1 && PLS2 == PLS_POLLING) || + (PPR3 == 1 && PLS3 == PLS_POLLING || PPR4 == 1 && PLS4 == PLS_POLLING)) { If (Local0 == 0) { Break @@ -151,19 +147,21 @@ Device (XHCI) Local3 = 0 Local4 = 0 - If (PLS1 == PLSD && (CSC1 == 0 && PPR1 == 1)) { +#define PLS_RX_DETECT 5 + + If (PLS1 == PLS_RX_DETECT && (CSC1 == 0 && PPR1 == 1)) { WPR1 = 1 // Issue warm reset Local1 = 1 } - If (PLS2 == PLSD && (CSC2 == 0 && PPR2 == 1)) { + If (PLS2 == PLS_RX_DETECT && (CSC2 == 0 && PPR2 == 1)) { WPR2 = 1 // Issue warm reset Local2 = 1 } - If (PLS3 == PLSD && (CSC3 == 0 && PPR3 == 1)) { + If (PLS3 == PLS_RX_DETECT && (CSC3 == 0 && PPR3 == 1)) { WPR3 = 1 // Issue warm reset Local3 = 1 } - If (PLS4 == PLSD && (CSC4 == 0 && PPR4 == 1)) { + If (PLS4 == PLS_RX_DETECT && (CSC4 == 0 && PPR4 == 1)) { WPR4 = 1 // Issue warm reset Local4 = 1 } From 72ecebf0c3a9cc1fba650fa1165aae4a0a7c8e6f Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 20:48:41 +0100 Subject: [PATCH 603/789] soc/intel/broadwell/acpi/xhci.asl: Use macros for constants Declaring named objects for constants is not ideal, especially when done inside of a method (it is highly inefficient). Instead, use preprocessor defines. Change-Id: I2d9d17b820ee72ba628b44ae508a7c467c023dd9 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91394 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Paul Menzel --- src/soc/intel/broadwell/pch/acpi/xhci.asl | 42 +++++++++++------------ 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/soc/intel/broadwell/pch/acpi/xhci.asl b/src/soc/intel/broadwell/pch/acpi/xhci.asl index e98bd42637..d040201e5b 100644 --- a/src/soc/intel/broadwell/pch/acpi/xhci.asl +++ b/src/soc/intel/broadwell/pch/acpi/xhci.asl @@ -6,9 +6,6 @@ Device (XHCI) { Name (_ADR, 0x00140000) - Name (PLSD, 5) // Port Link State - RxDetect - Name (PLSP, 7) // Port Link State - Polling - OperationRegion (XPRT, PCI_Config, 0, 0x100) Field (XPRT, AnyAcc, NoLock, Preserve) { @@ -57,27 +54,24 @@ Device (XHCI) PSC3, 32, } - // Port Enabled/Disabled (Bit 1) - Name (PEDB, 1 << 1) - - // Change Status (Bits 23:17) - Name (CHST, 0x7f << 17) +#define PSC_PORT_ENABLED (1 << 1) +#define PSC_PORT_CHANGE_BITS (0x7f << 17) // Port 0 - Local0 = PSC0 & ~PEDB - PSC0 = Local0 | CHST + Local0 = PSC0 & ~PSC_PORT_ENABLED + PSC0 = Local0 | PSC_PORT_CHANGE_BITS // Port 1 - Local0 = PSC1 & ~PEDB - PSC1 = Local0 | CHST + Local0 = PSC1 & ~PSC_PORT_ENABLED + PSC1 = Local0 | PSC_PORT_CHANGE_BITS // Port 2 - Local0 = PSC2 & ~PEDB - PSC2 = Local0 | CHST + Local0 = PSC2 & ~PSC_PORT_ENABLED + PSC2 = Local0 | PSC_PORT_CHANGE_BITS // Port 3 - Local0 = PSC3 & ~PEDB - PSC3 = Local0 | CHST + Local0 = PSC3 & ~PSC_PORT_ENABLED + PSC3 = Local0 | PSC_PORT_CHANGE_BITS } Method (LPS0, 0, Serialized) @@ -127,10 +121,12 @@ Device (XHCI) WPR4, 1, // [31] Warm Port Reset } +#define PLS_POLLING 7 + // Wait for all powered ports to finish polling Local0 = 10 - While ((PPR1 == 1 && PLS1 == PLSP || PPR2 == 1 && PLS2 == PLSP) || - (PPR3 == 1 && PLS3 == PLSP || PPR4 == 1 && PLS4 == PLSP)) + While ((PPR1 == 1 && PLS1 == PLS_POLLING || PPR2 == 1 && PLS2 == PLS_POLLING) || + (PPR3 == 1 && PLS3 == PLS_POLLING || PPR4 == 1 && PLS4 == PLS_POLLING)) { If (Local0 == 0) { Break @@ -151,19 +147,21 @@ Device (XHCI) Local3 = 0 Local4 = 0 - If (PLS1 == PLSD && (CSC1 == 0 && PPR1 == 1)) { +#define PLS_RX_DETECT 5 + + If (PLS1 == PLS_RX_DETECT && (CSC1 == 0 && PPR1 == 1)) { WPR1 = 1 // Issue warm reset Local1 = 1 } - If (PLS2 == PLSD && (CSC2 == 0 && PPR2 == 1)) { + If (PLS2 == PLS_RX_DETECT && (CSC2 == 0 && PPR2 == 1)) { WPR2 = 1 // Issue warm reset Local2 = 1 } - If (PLS3 == PLSD && (CSC3 == 0 && PPR3 == 1)) { + If (PLS3 == PLS_RX_DETECT && (CSC3 == 0 && PPR3 == 1)) { WPR3 = 1 // Issue warm reset Local3 = 1 } - If (PLS4 == PLSD && (CSC4 == 0 && PPR4 == 1)) { + If (PLS4 == PLS_RX_DETECT && (CSC4 == 0 && PPR4 == 1)) { WPR4 = 1 // Issue warm reset Local4 = 1 } From 253689aebb5b59f22d11a65182c33da5a6a24547 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 20:50:31 +0100 Subject: [PATCH 604/789] sb/intel/lynxpoint/acpi/xhci.asl: Guard PCH-LP methods The `LPCL` and `LPS0` methods are specific to PCH-LP, and are not used at all on PCH-H. To prevent accidental use and to reduce the DSDT size on PCH-H builds, add some preprocessor guards around those methods. For the ASRock Z97 Extreme, `build/dsdt.aml` size goes from 8538 bytes down to 7904 bytes, a reduction of about 7%. Change-Id: I775dcde4932f6039ba7d5673364e495837a386da Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91395 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Paul Menzel --- src/southbridge/intel/lynxpoint/acpi/xhci.asl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/southbridge/intel/lynxpoint/acpi/xhci.asl b/src/southbridge/intel/lynxpoint/acpi/xhci.asl index 9c7bb2c1ac..c38a592372 100644 --- a/src/southbridge/intel/lynxpoint/acpi/xhci.asl +++ b/src/southbridge/intel/lynxpoint/acpi/xhci.asl @@ -38,6 +38,7 @@ Device (XHCI) PR3M, 32, // USB3PRM } +#if CONFIG(INTEL_LYNXPOINT_LP) // Clear status bits Method (LPCL, 0, Serialized) { @@ -181,6 +182,7 @@ Device (XHCI) // Clear status bits in all ports LPCL () } +#endif Method (_PSC, 0, NotSerialized) { From a4bc3131a5fa0787b7024e5115ff3f9ec33ad291 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 10:33:14 -0800 Subject: [PATCH 605/789] soc/intel/common/feature/gspi: Add common devfn mapping Add a common implementation of gspi_soc_bus_to_devfn() to reduce code duplication across multiple Intel SoC platforms. This implementation uses the SOC_GSPI_DEVFN(n) macro which must be defined by each platform in their soc/pci_devs.h header to map GSPI bus numbers to PCI device and function values. This change enables consolidation of nearly identical gspi.c files from Alder Lake, Meteor Lake, Panther Lake, Tiger Lake, Jasper Lake, Elkhart Lake, Cannon Lake, and Skylake platforms. The implementation leverages the existing CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX Kconfig option and includes compile-time assertions to ensure the configuration is within supported limits (up to 7 GSPI controllers). Change-Id: I776cebd70968fd4b8bbab176bca0a446a0cc76ab Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91322 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/common/feature/gspi/Kconfig | 9 ++++ src/soc/intel/common/feature/gspi/Makefile.mk | 3 ++ .../intel/common/feature/gspi/gspi_devfn.c | 44 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 src/soc/intel/common/feature/gspi/Kconfig create mode 100644 src/soc/intel/common/feature/gspi/Makefile.mk create mode 100644 src/soc/intel/common/feature/gspi/gspi_devfn.c diff --git a/src/soc/intel/common/feature/gspi/Kconfig b/src/soc/intel/common/feature/gspi/Kconfig new file mode 100644 index 0000000000..4ac4e47693 --- /dev/null +++ b/src/soc/intel/common/feature/gspi/Kconfig @@ -0,0 +1,9 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + bool + help + Common GSPI device function to bus mapping implementation. + SoCs using this must define SOC_GSPI_DEVFN(n) macro in their + pci_devs.h and CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX in their + Kconfig. diff --git a/src/soc/intel/common/feature/gspi/Makefile.mk b/src/soc/intel/common/feature/gspi/Makefile.mk new file mode 100644 index 0000000000..6ac84bac54 --- /dev/null +++ b/src/soc/intel/common/feature/gspi/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN) += gspi_devfn.c diff --git a/src/soc/intel/common/feature/gspi/gspi_devfn.c b/src/soc/intel/common/feature/gspi/gspi_devfn.c new file mode 100644 index 0000000000..23cdaaaf14 --- /dev/null +++ b/src/soc/intel/common/feature/gspi/gspi_devfn.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include + +/* + * Ensure the platform defines SOC_GSPI_DEVFN(n) macro to map GSPI bus numbers + * to their PCI device/function values. The macro should be defined in the + * platform's soc/pci_devs.h header. + */ + +_Static_assert(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX <= 7, + "CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX greater than 7 is not supported."); + +int gspi_soc_bus_to_devfn(unsigned int gspi_bus) +{ + switch (gspi_bus) { + case 0: + return SOC_GSPI_DEVFN(0); + case 1: + return SOC_GSPI_DEVFN(1); +#if CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX > 2 + case 2: + return SOC_GSPI_DEVFN(2); +#endif +#if CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX > 3 + case 3: + return SOC_GSPI_DEVFN(3); +#endif +#if CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX > 4 + case 4: + return SOC_GSPI_DEVFN(4); +#endif +#if CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX > 5 + case 5: + return SOC_GSPI_DEVFN(5); +#endif +#if CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX > 6 + case 6: + return SOC_GSPI_DEVFN(6); +#endif + } + return -1; +} From 039f21b5e36d1010ff4c61def737556ce31714ca Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 10:44:17 -0800 Subject: [PATCH 606/789] soc/intel/alderlake: Use common GSPI devfn mapping Replace platform-specific gspi.c with the common GSPI device function mapping implementation. Changes: - Select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN in Kconfig - Define SOC_GSPI_DEVFN(n) macro in pci_devs.h - Remove platform-specific gspi.c file Change-Id: Ia1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91314 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/alderlake/Kconfig | 1 + src/soc/intel/alderlake/Makefile.mk | 1 - src/soc/intel/alderlake/gspi.c | 25 ------------------- .../intel/alderlake/include/soc/pci_devs.h | 1 + 4 files changed, 2 insertions(+), 26 deletions(-) delete mode 100644 src/soc/intel/alderlake/gspi.c diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index c78a09076d..4ab0b1c820 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -85,6 +85,7 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index 2e97718bc2..35f84a5cb4 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -5,7 +5,6 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c all-y += pmutil.c all-y += spi.c diff --git a/src/soc/intel/alderlake/gspi.c b/src/soc/intel/alderlake/gspi.c deleted file mode 100644 index dd07b07f1a..0000000000 --- a/src/soc/intel/alderlake/gspi.c +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 11 - */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - case 2: - return PCH_DEVFN_GSPI2; - case 3: - return PCH_DEVFN_GSPI3; - } - return -1; -} diff --git a/src/soc/intel/alderlake/include/soc/pci_devs.h b/src/soc/intel/alderlake/include/soc/pci_devs.h index 13cea6d2fc..15ec661870 100644 --- a/src/soc/intel/alderlake/include/soc/pci_devs.h +++ b/src/soc/intel/alderlake/include/soc/pci_devs.h @@ -282,6 +282,7 @@ #define PCI_DEVFN_UART0 PCH_DEVFN_UART0 #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n #endif From 6459039b76c14e04ea79c6b025ddc73a502d58be Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 10:44:17 -0800 Subject: [PATCH 607/789] soc/intel/meteorlake: Use common GSPI devfn mapping Replace platform-specific gspi.c with the common GSPI device function mapping implementation. Changes: - Select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN in Kconfig - Define SOC_GSPI_DEVFN(n) macro in pci_devs.h - Remove platform-specific gspi.c file Change-Id: Ib2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91315 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/meteorlake/Kconfig | 1 + src/soc/intel/meteorlake/Makefile.mk | 1 - src/soc/intel/meteorlake/gspi.c | 17 ----------------- src/soc/intel/meteorlake/include/soc/pci_devs.h | 1 + 4 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 src/soc/intel/meteorlake/gspi.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 7d7d2df513..1d341d1484 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -87,6 +87,7 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_BASECODE diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index 1e9a1fc93d..60044f376f 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -6,7 +6,6 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c all-y += pmutil.c all-y += spi.c all-y += gpio.c diff --git a/src/soc/intel/meteorlake/gspi.c b/src/soc/intel/meteorlake/gspi.c deleted file mode 100644 index 387d3e3949..0000000000 --- a/src/soc/intel/meteorlake/gspi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCI_DEVFN_GSPI0; - case 1: - return PCI_DEVFN_GSPI1; - case 2: - return PCI_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/meteorlake/include/soc/pci_devs.h b/src/soc/intel/meteorlake/include/soc/pci_devs.h index 034f5e6b6c..17f4526538 100644 --- a/src/soc/intel/meteorlake/include/soc/pci_devs.h +++ b/src/soc/intel/meteorlake/include/soc/pci_devs.h @@ -242,5 +242,6 @@ #define SA_DEV_IGD PCI_DEV_IGD #define SA_DEVFN_IGD PCI_DEVFN_IGD #define SOC_I2C_DEVFN(n) PCI_DEVFN_I2C##n +#define SOC_GSPI_DEVFN(n) PCI_DEVFN_GSPI##n #endif // _SOC_METEORLAKE_PCI_DEVS_H_ From 3c92c8402acf163379ddd0ec91d4a9bb39d41f9d Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 10:44:17 -0800 Subject: [PATCH 608/789] soc/intel/pantherlake: Use common GSPI devfn mapping Replace platform-specific gspi.c with the common GSPI device function mapping implementation. Changes: - Select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN in Kconfig - Define SOC_GSPI_DEVFN(n) macro in pci_devs.h - Remove platform-specific gspi.c file TEST=Panther Lake Fatcat OS boots properly Change-Id: Ic3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91316 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/Kconfig | 1 + src/soc/intel/pantherlake/Makefile.mk | 1 - src/soc/intel/pantherlake/gspi.c | 17 ----------------- .../intel/pantherlake/include/soc/pci_devs.h | 1 + 4 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 src/soc/intel/pantherlake/gspi.c diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index 2e1bc2ef10..133a0b8684 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -97,6 +97,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index dadba99ccd..5f956db228 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -7,7 +7,6 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c all-y += pmutil.c all-y += spi.c all-y += gpio.c diff --git a/src/soc/intel/pantherlake/gspi.c b/src/soc/intel/pantherlake/gspi.c deleted file mode 100644 index 387d3e3949..0000000000 --- a/src/soc/intel/pantherlake/gspi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCI_DEVFN_GSPI0; - case 1: - return PCI_DEVFN_GSPI1; - case 2: - return PCI_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/pantherlake/include/soc/pci_devs.h b/src/soc/intel/pantherlake/include/soc/pci_devs.h index a1ef4f4c32..3a41280a26 100644 --- a/src/soc/intel/pantherlake/include/soc/pci_devs.h +++ b/src/soc/intel/pantherlake/include/soc/pci_devs.h @@ -257,5 +257,6 @@ #define SA_DEV_IGD PCI_DEV_IGD #define SA_DEVFN_IGD PCI_DEVFN_IGD #define SOC_I2C_DEVFN(n) PCI_DEVFN_I2C##n +#define SOC_GSPI_DEVFN(n) PCI_DEVFN_GSPI##n #endif // _SOC_PANTHERLAKE_PCI_DEVS_H_ From 66a6c25ef8cc1e0248d8f8cf0938397578d99bcc Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 10:44:18 -0800 Subject: [PATCH 609/789] soc/intel/tigerlake: Use common GSPI devfn mapping Replace platform-specific gspi.c with the common GSPI device function mapping implementation. Changes: - Select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN in Kconfig - Define SOC_GSPI_DEVFN(n) macro in pci_devs.h - Remove platform-specific gspi.c file Change-Id: Id4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91317 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/tigerlake/Kconfig | 1 + src/soc/intel/tigerlake/Makefile.mk | 1 - src/soc/intel/tigerlake/gspi.c | 23 ------------------- .../intel/tigerlake/include/soc/pci_devs.h | 1 + 4 files changed, 2 insertions(+), 24 deletions(-) delete mode 100644 src/soc/intel/tigerlake/gspi.c diff --git a/src/soc/intel/tigerlake/Kconfig b/src/soc/intel/tigerlake/Kconfig index 48cf447bd1..38c1e8125c 100644 --- a/src/soc/intel/tigerlake/Kconfig +++ b/src/soc/intel/tigerlake/Kconfig @@ -73,6 +73,7 @@ config SOC_INTEL_TIGERLAKE select SOC_INTEL_COMMON_BLOCK_USB4_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET diff --git a/src/soc/intel/tigerlake/Makefile.mk b/src/soc/intel/tigerlake/Makefile.mk index 53a5d9580f..895395d362 100644 --- a/src/soc/intel/tigerlake/Makefile.mk +++ b/src/soc/intel/tigerlake/Makefile.mk @@ -6,7 +6,6 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c all-y += pmutil.c all-y += spi.c diff --git a/src/soc/intel/tigerlake/gspi.c b/src/soc/intel/tigerlake/gspi.c deleted file mode 100644 index 83552f9435..0000000000 --- a/src/soc/intel/tigerlake/gspi.c +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * This file is created based on Intel Tiger Lake Processor PCH Datasheet - * Document number: 575857 - * Chapter number: 11 - */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - case 2: - return PCH_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/tigerlake/include/soc/pci_devs.h b/src/soc/intel/tigerlake/include/soc/pci_devs.h index 29216f5670..2f36bd159c 100644 --- a/src/soc/intel/tigerlake/include/soc/pci_devs.h +++ b/src/soc/intel/tigerlake/include/soc/pci_devs.h @@ -249,6 +249,7 @@ #define PCI_DEVFN_UART0 PCH_DEVFN_UART0 #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n #endif From 78ef2d0433fc98ffd2469ec25bb8201d0c325cd8 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 10:44:18 -0800 Subject: [PATCH 610/789] soc/intel/jasperlake: Use common GSPI devfn mapping Replace platform-specific gspi.c with the common GSPI device function mapping implementation. Changes: - Select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN in Kconfig - Define SOC_GSPI_DEVFN(n) macro in pci_devs.h - Remove platform-specific gspi.c file Change-Id: Ie5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91318 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/soc/intel/jasperlake/Kconfig | 1 + src/soc/intel/jasperlake/Makefile.mk | 1 - src/soc/intel/jasperlake/gspi.c | 17 ----------------- src/soc/intel/jasperlake/include/soc/pci_devs.h | 1 + 4 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 src/soc/intel/jasperlake/gspi.c diff --git a/src/soc/intel/jasperlake/Kconfig b/src/soc/intel/jasperlake/Kconfig index b1257a76a0..7f6831e9c1 100644 --- a/src/soc/intel/jasperlake/Kconfig +++ b/src/soc/intel/jasperlake/Kconfig @@ -56,6 +56,7 @@ config SOC_INTEL_JASPERLAKE select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET diff --git a/src/soc/intel/jasperlake/Makefile.mk b/src/soc/intel/jasperlake/Makefile.mk index 875cc76a9c..73765deb13 100644 --- a/src/soc/intel/jasperlake/Makefile.mk +++ b/src/soc/intel/jasperlake/Makefile.mk @@ -6,7 +6,6 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c all-y += pmutil.c all-y += spi.c diff --git a/src/soc/intel/jasperlake/gspi.c b/src/soc/intel/jasperlake/gspi.c deleted file mode 100644 index 61ad2608db..0000000000 --- a/src/soc/intel/jasperlake/gspi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - case 2: - return PCH_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/jasperlake/include/soc/pci_devs.h b/src/soc/intel/jasperlake/include/soc/pci_devs.h index 5e9107003e..f2e6dd4e7d 100644 --- a/src/soc/intel/jasperlake/include/soc/pci_devs.h +++ b/src/soc/intel/jasperlake/include/soc/pci_devs.h @@ -197,6 +197,7 @@ #define PCI_DEVFN_UART0 PCH_DEVFN_UART0 #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n #endif From 4aae5fb66d69f4a8342e18a871c115e952f0b4ae Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 10:44:18 -0800 Subject: [PATCH 611/789] soc/intel/elkhartlake: Use common GSPI devfn mapping Replace platform-specific gspi.c with the common GSPI device function mapping implementation. Changes: - Select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN in Kconfig - Define SOC_GSPI_DEVFN(n) macro in pci_devs.h - Remove platform-specific gspi.c file Change-Id: If6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91319 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/elkhartlake/Kconfig | 1 + src/soc/intel/elkhartlake/Makefile.mk | 1 - src/soc/intel/elkhartlake/gspi.c | 17 ----------------- .../intel/elkhartlake/include/soc/pci_devs.h | 1 + 4 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 src/soc/intel/elkhartlake/gspi.c diff --git a/src/soc/intel/elkhartlake/Kconfig b/src/soc/intel/elkhartlake/Kconfig index 4e5b9bc99c..a15833346e 100644 --- a/src/soc/intel/elkhartlake/Kconfig +++ b/src/soc/intel/elkhartlake/Kconfig @@ -56,6 +56,7 @@ config SOC_INTEL_ELKHARTLAKE select SOC_INTEL_COMMON_BLOCK_SMM select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET diff --git a/src/soc/intel/elkhartlake/Makefile.mk b/src/soc/intel/elkhartlake/Makefile.mk index b457a2a53b..ee2204300c 100644 --- a/src/soc/intel/elkhartlake/Makefile.mk +++ b/src/soc/intel/elkhartlake/Makefile.mk @@ -6,7 +6,6 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c all-y += pmutil.c all-y += spi.c diff --git a/src/soc/intel/elkhartlake/gspi.c b/src/soc/intel/elkhartlake/gspi.c deleted file mode 100644 index 61ad2608db..0000000000 --- a/src/soc/intel/elkhartlake/gspi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - case 2: - return PCH_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/elkhartlake/include/soc/pci_devs.h b/src/soc/intel/elkhartlake/include/soc/pci_devs.h index 885ebac506..e4e899b881 100644 --- a/src/soc/intel/elkhartlake/include/soc/pci_devs.h +++ b/src/soc/intel/elkhartlake/include/soc/pci_devs.h @@ -251,6 +251,7 @@ #define PCI_DEVFN_UART0 PCH_DEVFN_UART0 #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n #endif From 45d3ab84a89db62d301cbfc2fb35a99f20af6450 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 10:44:18 -0800 Subject: [PATCH 612/789] soc/intel/cannonlake: Use common GSPI devfn mapping Replace platform-specific gspi.c with the common GSPI device function mapping implementation. Changes: - Select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN in Kconfig - Define SOC_GSPI_DEVFN(n) macro in pci_devs.h - Remove platform-specific gspi.c file Change-Id: Ia6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91320 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/Kconfig | 1 + src/soc/intel/cannonlake/Makefile.mk | 5 ----- src/soc/intel/cannonlake/gspi.c | 17 ----------------- src/soc/intel/cannonlake/include/soc/pci_devs.h | 1 + 4 files changed, 2 insertions(+), 22 deletions(-) delete mode 100644 src/soc/intel/cannonlake/gspi.c diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index be788ae527..0389d58f9c 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -60,6 +60,7 @@ config SOC_INTEL_CANNONLAKE_BASE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET diff --git a/src/soc/intel/cannonlake/Makefile.mk b/src/soc/intel/cannonlake/Makefile.mk index 2f0c7c1a40..a281068425 100644 --- a/src/soc/intel/cannonlake/Makefile.mk +++ b/src/soc/intel/cannonlake/Makefile.mk @@ -10,13 +10,11 @@ bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += pmutil.c bootblock-y += bootblock/report_platform.c -bootblock-y += gspi.c bootblock-y += spi.c bootblock-y += lpc.c bootblock-y += p2sb.c romstage-y += cnl_memcfg_init.c -romstage-y += gspi.c romstage-y += lpc.c romstage-y += pcie_rp.c romstage-y += pmutil.c @@ -30,7 +28,6 @@ ramstage-y += elog.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c -ramstage-y += gspi.c ramstage-y += lockdown.c ramstage-y += lpc.c ramstage-y += nhlt.c @@ -52,10 +49,8 @@ smm-y += smihandler.c smm-y += xhci.c postcar-y += pmutil.c -postcar-y += gspi.c postcar-y += spi.c -verstage-y += gspi.c verstage-y += pmutil.c verstage-y += spi.c diff --git a/src/soc/intel/cannonlake/gspi.c b/src/soc/intel/cannonlake/gspi.c deleted file mode 100644 index 61ad2608db..0000000000 --- a/src/soc/intel/cannonlake/gspi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - case 2: - return PCH_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/cannonlake/include/soc/pci_devs.h b/src/soc/intel/cannonlake/include/soc/pci_devs.h index 607733c98e..c2d7b411ba 100644 --- a/src/soc/intel/cannonlake/include/soc/pci_devs.h +++ b/src/soc/intel/cannonlake/include/soc/pci_devs.h @@ -208,6 +208,7 @@ #define PCI_DEVFN_UART0 PCH_DEVFN_UART0 #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n #endif From 0668959a929f3c3ef7eb278a7c14c40b1d725be1 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 10:44:18 -0800 Subject: [PATCH 613/789] soc/intel/skylake: Use common GSPI devfn mapping Replace platform-specific gspi.c with the common GSPI device function mapping implementation. Changes: - Select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN in Kconfig - Define SOC_GSPI_DEVFN(n) macro in pci_devs.h - Remove platform-specific gspi.c file Change-Id: Ib7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91321 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/soc/intel/skylake/Kconfig | 1 + src/soc/intel/skylake/Makefile.mk | 5 ----- src/soc/intel/skylake/gspi.c | 14 -------------- src/soc/intel/skylake/include/soc/pci_devs.h | 1 + 4 files changed, 2 insertions(+), 19 deletions(-) delete mode 100644 src/soc/intel/skylake/gspi.c diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index d3bdd4c8c3..e0d2c4d222 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -59,6 +59,7 @@ config SOC_INTEL_COMMON_SKYLAKE_BASE select SOC_INTEL_COMMON_BLOCK_UART select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET diff --git a/src/soc/intel/skylake/Makefile.mk b/src/soc/intel/skylake/Makefile.mk index c8513eaf73..73479d95bc 100644 --- a/src/soc/intel/skylake/Makefile.mk +++ b/src/soc/intel/skylake/Makefile.mk @@ -11,19 +11,16 @@ bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c bootblock-y += gpio.c -bootblock-y += gspi.c bootblock-y += p2sb.c bootblock-y += pmutil.c bootblock-y += spi.c bootblock-y += lpc.c verstage-y += gpio.c -verstage-y += gspi.c verstage-y += pmutil.c verstage-y += spi.c romstage-y += gpio.c -romstage-y += gspi.c romstage-y += me.c romstage-y += pcie_rp.c romstage-y += pmutil.c @@ -37,7 +34,6 @@ ramstage-y += elog.c ramstage-y += fadt.c ramstage-y += finalize.c ramstage-y += gpio.c -ramstage-y += gspi.c ramstage-y += graphics.c ramstage-y += irq.c ramstage-y += lockdown.c @@ -61,7 +57,6 @@ smm-y += pmutil.c smm-y += smihandler.c smm-y += xhci.c -postcar-y += gspi.c postcar-y += spi.c ifeq ($(CONFIG_SKYLAKE_SOC_PCH_H),y) diff --git a/src/soc/intel/skylake/gspi.c b/src/soc/intel/skylake/gspi.c deleted file mode 100644 index 4952dffc7d..0000000000 --- a/src/soc/intel/skylake/gspi.c +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - } - return -1; -} diff --git a/src/soc/intel/skylake/include/soc/pci_devs.h b/src/soc/intel/skylake/include/soc/pci_devs.h index 2f6f649542..557dc58c55 100644 --- a/src/soc/intel/skylake/include/soc/pci_devs.h +++ b/src/soc/intel/skylake/include/soc/pci_devs.h @@ -191,6 +191,7 @@ #define PCI_DEVFN_UART0 PCH_DEVFN_UART0 #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n #endif From 91520ab096b7468273802559ecfaf4990393f6f9 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 10:44:45 -0800 Subject: [PATCH 614/789] soc/intel/common/feature/spi: Add common SPI device function driver Add a common driver for SPI device function to bus mapping. This eliminates code duplication across Intel SoC platforms by providing a generic implementation that can be configured via platform-specific macros. The driver provides: - spi_soc_devfn_to_bus(): Convert device function to bus number using platform-defined SOC_SPI_DEVFN(n) macros - soc_get_spi_psf_destination_id(): Optional PSF destination ID support for platforms that need it Platforms must define SOC_SPI_DEVFN(n) in soc/pci_devs.h. Platforms must define the following Kconfig: - SOC_INTEL_SPI_DEV_MAX: Number of SPI controllers available on the platform. - SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF: To enable PSF designation, the ID must be provided with SOC_INTEL_SPI_PSF_DESTINATION_ID. - SOC_INTEL_SPI_PSF_DESTINATION_ID: (optional) PSF destination ID for SPI controller. Change-Id: I07ded6e6d2156a02eef7b4fea86ac1c8fa5ff3ce Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91323 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/common/feature/spi/Kconfig | 36 ++++++++++++++ src/soc/intel/common/feature/spi/Makefile.mk | 4 ++ src/soc/intel/common/feature/spi/spi_devfn.c | 50 ++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 src/soc/intel/common/feature/spi/Kconfig create mode 100644 src/soc/intel/common/feature/spi/Makefile.mk create mode 100644 src/soc/intel/common/feature/spi/spi_devfn.c diff --git a/src/soc/intel/common/feature/spi/Kconfig b/src/soc/intel/common/feature/spi/Kconfig new file mode 100644 index 0000000000..4f09abbd03 --- /dev/null +++ b/src/soc/intel/common/feature/spi/Kconfig @@ -0,0 +1,36 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + bool + default n + depends on SOC_INTEL_COMMON_BLOCK_SPI + help + Use common SPI device function to bus mapping. SoCs must define + CONFIG_SOC_INTEL_SPI_DEV_MAX and SOC_GSPI_DEVFN(n) macro in + soc/pci_devs.h. + +config SOC_INTEL_SPI_DEV_MAX + int + default 0 + depends on SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + help + Number of SPI controllers available on the platform. This is used + for SPI device function to bus number mapping. Platforms should + override this with the actual count of SPI controllers. + +config SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF + bool + default n + depends on SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + help + SoC provides soc_get_spi_psf_destination_id() via common driver. + Platforms must define CONFIG_SOC_INTEL_SPI_PSF_DESTINATION_ID. + +config SOC_INTEL_SPI_PSF_DESTINATION_ID + hex + default 0x0 + depends on SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF + help + PSF destination ID for SPI controller. This value is platform-specific + and is used for PSF programming. Platforms should override this with + the correct value from their hardware specification. diff --git a/src/soc/intel/common/feature/spi/Makefile.mk b/src/soc/intel/common/feature/spi/Makefile.mk new file mode 100644 index 0000000000..798c7ec12e --- /dev/null +++ b/src/soc/intel/common/feature/spi/Makefile.mk @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_SPI_DEVFN) += spi_devfn.c +smm-$(CONFIG_SOC_INTEL_COMMON_FEATURE_SPI_DEVFN) += spi_devfn.c diff --git a/src/soc/intel/common/feature/spi/spi_devfn.c b/src/soc/intel/common/feature/spi/spi_devfn.c new file mode 100644 index 0000000000..eb39c5dfca --- /dev/null +++ b/src/soc/intel/common/feature/spi/spi_devfn.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include + +/* + * Ensure the platform defines SOC_GSPI_DEVFN(n) macro to map GSPI bus numbers + * to their PCI device/function values. The macro should be defined in the + * platform's soc/pci_devs.h header. + */ + +_Static_assert(CONFIG_SOC_INTEL_SPI_DEV_MAX <= 5, + "CONFIG_SOC_INTEL_SPI_DEV_MAX greater than 5 is not supported."); + +int spi_soc_devfn_to_bus(unsigned int devfn) +{ + switch (devfn) { +#if CONFIG_SOC_INTEL_SPI_DEV_MAX > 0 + case SOC_GSPI_DEVFN(0): + return 1; +#endif +#if CONFIG_SOC_INTEL_SPI_DEV_MAX > 1 + case SOC_GSPI_DEVFN(1): + return 2; +#endif +#if CONFIG_SOC_INTEL_SPI_DEV_MAX > 2 + case SOC_GSPI_DEVFN(2): + return 3; +#endif +#if CONFIG_SOC_INTEL_SPI_DEV_MAX > 3 + case SOC_GSPI_DEVFN(3): + return 4; +#endif +#if CONFIG_SOC_INTEL_SPI_DEV_MAX > 4 + case SOC_GSPI_DEVFN(4): + return 5; +#endif + } + return -1; +} + +#if CONFIG(SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF) +uint32_t soc_get_spi_psf_destination_id(void) +{ + return CONFIG_SOC_INTEL_SPI_PSF_DESTINATION_ID; +} +#endif From 47f3e7e3cca3719a10bb00c1c22f5c48c1561d37 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 11:00:07 -0800 Subject: [PATCH 615/789] soc/intel/jasperlake: Use common SPI device function driver Switch to the common SPI device function driver implementation. This eliminates platform-specific SPI code by leveraging the common driver with platform-specific Kconfig and macros. This commit: - Selects SOC_INTEL_COMMON_FEATURE_SPI_DEVFN in Kconfig - Adds CONFIG_SOC_INTEL_SPI_DEV_MAX=3 - Removes src/soc/intel/jasperlake/spi.c - Updates Makefile.mk to remove spi.c compilation Note: This platform does not use PSF destination ID. The common code uses SOC_GSPI_DEVFN(n) macro directly. Change-Id: If42aa1f955bc0aae2698aac35dbe23b79c68bf09 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91324 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/jasperlake/Kconfig | 5 +++++ src/soc/intel/jasperlake/Makefile.mk | 1 - src/soc/intel/jasperlake/spi.c | 17 ----------------- 3 files changed, 5 insertions(+), 18 deletions(-) delete mode 100644 src/soc/intel/jasperlake/spi.c diff --git a/src/soc/intel/jasperlake/Kconfig b/src/soc/intel/jasperlake/Kconfig index 7f6831e9c1..df65e73a78 100644 --- a/src/soc/intel/jasperlake/Kconfig +++ b/src/soc/intel/jasperlake/Kconfig @@ -57,6 +57,7 @@ config SOC_INTEL_JASPERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET @@ -215,4 +216,8 @@ config INTEL_GMA_BCLM_OFFSET config INTEL_GMA_BCLM_WIDTH default 32 + +config SOC_INTEL_SPI_DEV_MAX + int + default 3 endif diff --git a/src/soc/intel/jasperlake/Makefile.mk b/src/soc/intel/jasperlake/Makefile.mk index 73765deb13..cb3ebfacd2 100644 --- a/src/soc/intel/jasperlake/Makefile.mk +++ b/src/soc/intel/jasperlake/Makefile.mk @@ -7,7 +7,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += pmutil.c -all-y += spi.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c diff --git a/src/soc/intel/jasperlake/spi.c b/src/soc/intel/jasperlake/spi.c deleted file mode 100644 index 8a7ed73b47..0000000000 --- a/src/soc/intel/jasperlake/spi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int spi_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_GSPI0: - return 1; - case PCH_DEVFN_GSPI1: - return 2; - case PCH_DEVFN_GSPI2: - return 3; - } - return -1; -} From 0aea05411dda6441a1a050012c63acea3fa63e21 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 11:00:07 -0800 Subject: [PATCH 616/789] soc/intel/tigerlake: Use common SPI device function driver Switch to the common SPI device function driver implementation. This eliminates platform-specific SPI code by leveraging the common driver with platform-specific Kconfig and macros. This commit: - Selects SOC_INTEL_COMMON_FEATURE_SPI_DEVFN and SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF in Kconfig - Adds CONFIG_SOC_INTEL_SPI_DEV_MAX=3 - Adds CONFIG_SOC_INTEL_SPI_PSF_DESTINATION_ID (0x23b0 for PCH-H, 0x23a8 default) - Removes src/soc/intel/tigerlake/spi.c - Updates Makefile.mk to remove spi.c compilation The common code uses SOC_GSPI_DEVFN(n) macro directly. Change-Id: Ib195ffcc0d46f7e95eba2d0a2c66fbcdcca615a2 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91325 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/soc/intel/tigerlake/Kconfig | 11 +++++++++ src/soc/intel/tigerlake/Makefile.mk | 1 - src/soc/intel/tigerlake/spi.c | 35 ----------------------------- 3 files changed, 11 insertions(+), 36 deletions(-) delete mode 100644 src/soc/intel/tigerlake/spi.c diff --git a/src/soc/intel/tigerlake/Kconfig b/src/soc/intel/tigerlake/Kconfig index 38c1e8125c..5168546661 100644 --- a/src/soc/intel/tigerlake/Kconfig +++ b/src/soc/intel/tigerlake/Kconfig @@ -74,6 +74,8 @@ config SOC_INTEL_TIGERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET @@ -304,4 +306,13 @@ config INTEL_GMA_BCLM_OFFSET config INTEL_GMA_BCLM_WIDTH default 32 +config SOC_INTEL_SPI_DEV_MAX + int + default 3 + +config SOC_INTEL_SPI_PSF_DESTINATION_ID + hex + default 0x23b0 if SOC_INTEL_TIGERLAKE_PCH_H + default 0x23a8 + endif diff --git a/src/soc/intel/tigerlake/Makefile.mk b/src/soc/intel/tigerlake/Makefile.mk index 895395d362..074f172d38 100644 --- a/src/soc/intel/tigerlake/Makefile.mk +++ b/src/soc/intel/tigerlake/Makefile.mk @@ -7,7 +7,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += pmutil.c -all-y += spi.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c diff --git a/src/soc/intel/tigerlake/spi.c b/src/soc/intel/tigerlake/spi.c deleted file mode 100644 index 47b3b33ce2..0000000000 --- a/src/soc/intel/tigerlake/spi.c +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * This file is created based on Intel Tiger Lake Processor PCH Datasheet - * Document number: 575857 - * Chapter number: 7 - */ - -#include -#include -#include -#include - -#define PSF_SPI_DESTINATION_ID_H 0x23b0 -#define PSF_SPI_DESTINATION_ID 0x23a8 - -int spi_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_GSPI0: - return 1; - case PCH_DEVFN_GSPI1: - return 2; - case PCH_DEVFN_GSPI2: - return 3; - } - return -1; -} - -uint32_t soc_get_spi_psf_destination_id(void) -{ - if (CONFIG(SOC_INTEL_TIGERLAKE_PCH_H)) - return PSF_SPI_DESTINATION_ID_H; - return PSF_SPI_DESTINATION_ID; -} From 8ecff12528a33eb2388fd39bc84b4bdc6d9894e5 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 11:00:08 -0800 Subject: [PATCH 617/789] soc/intel/alderlake: Use common SPI device function driver Switch to the common SPI device function driver implementation. This eliminates platform-specific SPI code by leveraging the common driver with platform-specific Kconfig and macros. This commit: - Selects SOC_INTEL_COMMON_FEATURE_SPI_DEVFN and SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF in Kconfig - Adds CONFIG_SOC_INTEL_SPI_DEV_MAX=4 - Adds CONFIG_SOC_INTEL_SPI_PSF_DESTINATION_ID=0x23a8 - Removes src/soc/intel/alderlake/spi.c - Updates Makefile.mk to remove spi.c compilation The common code uses SOC_GSPI_DEVFN(n) macro directly. Change-Id: I346e6c6cbe95c8608009e5f9fc53dbcff5edba4e Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91326 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/alderlake/Kconfig | 10 +++++++++ src/soc/intel/alderlake/Makefile.mk | 1 - src/soc/intel/alderlake/spi.c | 33 ----------------------------- 3 files changed, 10 insertions(+), 34 deletions(-) delete mode 100644 src/soc/intel/alderlake/spi.c diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 4ab0b1c820..52c3d84dca 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -86,6 +86,8 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET @@ -574,4 +576,12 @@ config SOC_INTEL_COMMON_BLOCK_ACPI_SLP_S0_FREQ_HZ help slp_s0_residency granularity in 122us ticks (i.e. ~8.2KHz). +config SOC_INTEL_SPI_DEV_MAX + int + default 4 + +config SOC_INTEL_SPI_PSF_DESTINATION_ID + hex + default 0x23a8 + endif diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index 35f84a5cb4..f287e91322 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -6,7 +6,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += pmutil.c -all-y += spi.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c diff --git a/src/soc/intel/alderlake/spi.c b/src/soc/intel/alderlake/spi.c deleted file mode 100644 index 1149425101..0000000000 --- a/src/soc/intel/alderlake/spi.c +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 7 - */ - -#include -#include -#include - -#define PSF_SPI_DESTINATION_ID 0x23a8 - -int spi_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_GSPI0: - return 1; - case PCH_DEVFN_GSPI1: - return 2; - case PCH_DEVFN_GSPI2: - return 3; - case PCH_DEVFN_GSPI3: - return 4; - } - return -1; -} - -uint32_t soc_get_spi_psf_destination_id(void) -{ - return PSF_SPI_DESTINATION_ID; -} From 4bdeb7363542b0d33d3be651a0f7b0639c87bb02 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 11:00:08 -0800 Subject: [PATCH 618/789] soc/intel/meteorlake: Use common SPI device function driver Switch to the common SPI device function driver implementation. This eliminates platform-specific SPI code by leveraging the common driver with platform-specific Kconfig and macros. This commit: - Selects SOC_INTEL_COMMON_FEATURE_SPI_DEVFN and SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF in Kconfig - Adds CONFIG_SOC_INTEL_SPI_DEV_MAX=3 - Adds CONFIG_SOC_INTEL_SPI_PSF_DESTINATION_ID=0x5140 - Removes src/soc/intel/meteorlake/spi.c - Updates Makefile.mk to remove spi.c compilation The common code uses SOC_GSPI_DEVFN(n) macro directly. Change-Id: I6ac7bdf4c9eeaab2d0d0ecbe8cd2ea2bf7f9ea19 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91327 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/soc/intel/meteorlake/Kconfig | 10 ++++++++++ src/soc/intel/meteorlake/Makefile.mk | 1 - src/soc/intel/meteorlake/spi.c | 25 ------------------------- 3 files changed, 10 insertions(+), 26 deletions(-) delete mode 100644 src/soc/intel/meteorlake/spi.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 1d341d1484..566bc05bda 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -88,6 +88,8 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_BASECODE @@ -478,4 +480,12 @@ config SKIP_SEND_CONNECT_TOPOLOGY_CMD config TME_KEY_REGENERATION_ON_WARM_BOOT default y if INTEL_TME +config SOC_INTEL_SPI_DEV_MAX + int + default 3 + +config SOC_INTEL_SPI_PSF_DESTINATION_ID + hex + default 0x5140 + endif diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index 60044f376f..d2192c0483 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -7,7 +7,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += pmutil.c -all-y += spi.c all-y += gpio.c bootblock-y += bootblock/bootblock.c diff --git a/src/soc/intel/meteorlake/spi.c b/src/soc/intel/meteorlake/spi.c deleted file mode 100644 index f7d751f98e..0000000000 --- a/src/soc/intel/meteorlake/spi.c +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include -#include - -#define PSF_SPI_DESTINATION_ID 0x5140 - -int spi_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCI_DEVFN_GSPI0: - return 1; - case PCI_DEVFN_GSPI1: - return 2; - case PCI_DEVFN_GSPI2: - return 3; - } - return -1; -} - -uint32_t soc_get_spi_psf_destination_id(void) -{ - return PSF_SPI_DESTINATION_ID; -} From 56ede20f103fd30307447f66c26e630382e2205f Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 25 Feb 2026 11:00:08 -0800 Subject: [PATCH 619/789] soc/intel/pantherlake: Use common SPI device function driver Switch to the common SPI device function driver implementation. This eliminates platform-specific SPI code by leveraging the common driver with platform-specific Kconfig and macros. This commit: - Selects SOC_INTEL_COMMON_FEATURE_SPI_DEVFN and SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF in Kconfig - Adds CONFIG_SOC_INTEL_SPI_DEV_MAX=3 - Adds CONFIG_SOC_INTEL_SPI_PSF_DESTINATION_ID=0x5140 - Removes src/soc/intel/pantherlake/spi.c - Updates Makefile.mk to remove spi.c compilation The common code uses SOC_GSPI_DEVFN(n) macro directly. TEST=Panther Lake Fatcat OS boots properly Change-Id: Id7462deeb80c1efe32accf0ab7fc9fa68494ddfd Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91328 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/Kconfig | 10 ++++++++++ src/soc/intel/pantherlake/Makefile.mk | 1 - src/soc/intel/pantherlake/spi.c | 25 ------------------------- 3 files changed, 10 insertions(+), 26 deletions(-) delete mode 100644 src/soc/intel/pantherlake/spi.c diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index 133a0b8684..33a592cb07 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -98,6 +98,8 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET @@ -479,4 +481,12 @@ config RAMSTAGE_CBFS_CACHE_SIZE config CBFS_CACHE_ALIGN default 1024 +config SOC_INTEL_SPI_DEV_MAX + int + default 3 + +config SOC_INTEL_SPI_PSF_DESTINATION_ID + hex + default 0x5140 + endif diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index 5f956db228..857e7ab648 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -8,7 +8,6 @@ subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) all-y += pmutil.c -all-y += spi.c all-y += gpio.c bootblock-y += bootblock/bootblock.c diff --git a/src/soc/intel/pantherlake/spi.c b/src/soc/intel/pantherlake/spi.c deleted file mode 100644 index f7d751f98e..0000000000 --- a/src/soc/intel/pantherlake/spi.c +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include -#include - -#define PSF_SPI_DESTINATION_ID 0x5140 - -int spi_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCI_DEVFN_GSPI0: - return 1; - case PCI_DEVFN_GSPI1: - return 2; - case PCI_DEVFN_GSPI2: - return 3; - } - return -1; -} - -uint32_t soc_get_spi_psf_destination_id(void) -{ - return PSF_SPI_DESTINATION_ID; -} From cf5d6f1c885a5508c85bda1f574aff71de0cb58e Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Wed, 18 Feb 2026 14:49:51 -0800 Subject: [PATCH 620/789] soc/intel/common/block/gspi: Simplify Makefile using all-$() Replace individual stage-specific lines with all-$() for each file. This simplifies the Makefile from 6 lines to 2 lines while maintaining identical functionality. The all-$() variable automatically includes the file in all build stages (bootblock, verstage, romstage, postcar, ramstage, smm), which is exactly what the original code was doing manually for each stage. Change-Id: Ie89ba86a545c548fcc4ad0eb48a5cbb33733b541 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91358 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/soc/intel/common/block/gspi/Makefile.mk | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/soc/intel/common/block/gspi/Makefile.mk b/src/soc/intel/common/block/gspi/Makefile.mk index a820866ceb..5b52f2146f 100644 --- a/src/soc/intel/common/block/gspi/Makefile.mk +++ b/src/soc/intel/common/block/gspi/Makefile.mk @@ -1,6 +1,2 @@ ## SPDX-License-Identifier: GPL-2.0-only -bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c -romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c -ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c -verstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c -postcar-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c +all-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c From f4825e5c12fe1129c7862a61b91bb7e60f1e9b45 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 5 Jun 2025 09:12:24 +0200 Subject: [PATCH 621/789] soc/amd/common: Add I3C driver Add an I3C driver that allows to use the I3C HW from the OS. It does: - Power on/off the I3C HW - Configures the IOMUX Add the SoC specific AOAC devices and GPIO pins to reconfigure the GPIO for I3C HW. New log messages are seen in coreboot: [DEBUG] MMIO: fedd2000 disabled TEST: The I3C driver loads on amd/glinda using Ubuntu 25.04. Change-Id: Ibca20e2a4f0cb0e6006cfa47fd4addbe27504645 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/87960 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Felix Held --- src/soc/amd/common/block/i2c/i3c.c | 86 ++++++++++++++++--- .../amd/common/block/include/amdblocks/i2c.h | 1 + src/soc/amd/genoa_poc/i3c.c | 9 +- src/soc/amd/glinda/i3c.c | 9 +- src/soc/amd/mendocino/i3c.c | 9 +- src/soc/amd/phoenix/i3c.c | 9 +- src/soc/amd/turin_poc/i3c.c | 9 +- 7 files changed, 101 insertions(+), 31 deletions(-) diff --git a/src/soc/amd/common/block/i2c/i3c.c b/src/soc/amd/common/block/i2c/i3c.c index 43eae71b67..4fbe6ae37b 100644 --- a/src/soc/amd/common/block/i2c/i3c.c +++ b/src/soc/amd/common/block/i2c/i3c.c @@ -1,28 +1,57 @@ /* SPDX-License-Identifier: GPL-2.0-only */ - +#include #include +#include #include #include #include #include -#if CONFIG(HAVE_ACPI_TABLES) -static const char *i3c_acpi_name(const struct device *dev) +static int get_i3c_bus_for_dev(const struct device *dev, + const struct soc_i3c_ctrlr_info *ctrlr, + const size_t num_ctrlrs) { - size_t i; - size_t num_ctrlrs; - const struct soc_i3c_ctrlr_info *ctrlr = soc_get_i3c_ctrlr_info(&num_ctrlrs); + if (!dev || !ctrlr) + return -1; if (!(uintptr_t)dev->path.mmio.addr) { printk(BIOS_ERR, "NULL MMIO address at %s\n", __func__); - return NULL; + return -1; } - for (i = 0; i < num_ctrlrs; i++) { - if ((uintptr_t)dev->path.mmio.addr == ctrlr[i].bar) - return ctrlr[i].acpi_name; + for (int i = 0; i < num_ctrlrs; i++) { + if (dev->path.mmio.addr != ctrlr[i].bar) + continue; + return i; } - printk(BIOS_ERR, "%s: Could not find %lu\n", __func__, (uintptr_t)dev->path.mmio.addr); + printk(BIOS_ERR, "%s: Could not find i3c bus for %s\n", __func__, dev_path(dev)); + + return -1; +} + +static const struct soc_i3c_ctrlr_info * +get_i3c_info_for_dev(const struct device *dev) +{ + size_t num_ctrlrs; + const struct soc_i3c_ctrlr_info *ctrlr = soc_get_i3c_ctrlr_info(&num_ctrlrs); + const int bus = get_i3c_bus_for_dev(dev, ctrlr, num_ctrlrs); + + if (ctrlr && bus >= 0 && bus < num_ctrlrs) + return &ctrlr[bus]; + + printk(BIOS_ERR, "%s: Could not find soc_i3c_ctrlr_info for %s\n", __func__, dev_path(dev)); + + return NULL; +} + +#if CONFIG(HAVE_ACPI_TABLES) +static const char *i3c_acpi_name(const struct device *dev) +{ + const struct soc_i3c_ctrlr_info *info = get_i3c_info_for_dev(dev); + if (info) + return info->acpi_name; + + printk(BIOS_ERR, "%s: Could not find soc_i3c_ctrlr_info for %s\n", __func__, dev_path(dev)); return NULL; } @@ -34,12 +63,47 @@ static void i3c_acpi_fill_ssdt(const struct device *dev) } #endif +/* Even though this is called enable, it gets called for both enabled and disabled devices. */ +static void i3c_enable(struct device *dev) +{ + const struct soc_i3c_ctrlr_info *info = get_i3c_info_for_dev(dev); + if (!info) + return; + + if (dev->enabled) { + power_on_aoac_device(info->aoac_device); + wait_for_aoac_enabled(info->aoac_device); + } else { + power_off_aoac_device(info->aoac_device); + } +} + +static void i3c_init(struct device *dev) +{ + size_t num_ctrlrs, num_buses; + const struct soc_i3c_ctrlr_info *ctrlr = soc_get_i3c_ctrlr_info(&num_ctrlrs); + const int bus = get_i3c_bus_for_dev(dev, ctrlr, num_ctrlrs); + if (bus < 0) + return; + + const struct dw_i2c_bus_config *cfg = soc_get_i2c_bus_config(&num_buses); + + if (cfg) + soc_i2c_misc_init(bus, cfg); +} + static void i3c_read_resources(struct device *dev) { mmio_range(dev, 0, dev->path.mmio.addr, 4 * KiB); } +/* + * Currently there's no I3C driver, thus the I3C hardware cannot be used pre ramstage. + * It's sufficient to power switch the I3C controllers in the enable method. + */ struct device_operations soc_amd_i3c_mmio_ops = { + .enable = i3c_enable, + .init = i3c_init, .read_resources = i3c_read_resources, .set_resources = noop_set_resources, #if CONFIG(HAVE_ACPI_TABLES) diff --git a/src/soc/amd/common/block/include/amdblocks/i2c.h b/src/soc/amd/common/block/include/amdblocks/i2c.h index fc1a03217a..553561b7fc 100644 --- a/src/soc/amd/common/block/include/amdblocks/i2c.h +++ b/src/soc/amd/common/block/include/amdblocks/i2c.h @@ -74,6 +74,7 @@ struct i2c_pad_control { struct soc_i3c_ctrlr_info { uintptr_t bar; const char *acpi_name; + unsigned int aoac_device; }; void fch_i2c_pad_init(unsigned int bus, diff --git a/src/soc/amd/genoa_poc/i3c.c b/src/soc/amd/genoa_poc/i3c.c index e694623177..0e041942b6 100644 --- a/src/soc/amd/genoa_poc/i3c.c +++ b/src/soc/amd/genoa_poc/i3c.c @@ -1,14 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include static const struct soc_i3c_ctrlr_info i3c_ctrlr[I3C_CTRLR_COUNT] = { - { APU_I3C0_BASE, "I3C0" }, - { APU_I3C1_BASE, "I3C1" }, - { APU_I3C2_BASE, "I3C2" }, - { APU_I3C3_BASE, "I3C3" } + { APU_I3C0_BASE, "I3C0", FCH_AOAC_DEV_I3C0}, + { APU_I3C1_BASE, "I3C1", FCH_AOAC_DEV_I3C1}, + { APU_I3C2_BASE, "I3C2", FCH_AOAC_DEV_I3C2}, + { APU_I3C3_BASE, "I3C3", FCH_AOAC_DEV_I3C3} }; const struct soc_i3c_ctrlr_info *soc_get_i3c_ctrlr_info(size_t *num_ctrlrs) diff --git a/src/soc/amd/glinda/i3c.c b/src/soc/amd/glinda/i3c.c index e694623177..0e041942b6 100644 --- a/src/soc/amd/glinda/i3c.c +++ b/src/soc/amd/glinda/i3c.c @@ -1,14 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include static const struct soc_i3c_ctrlr_info i3c_ctrlr[I3C_CTRLR_COUNT] = { - { APU_I3C0_BASE, "I3C0" }, - { APU_I3C1_BASE, "I3C1" }, - { APU_I3C2_BASE, "I3C2" }, - { APU_I3C3_BASE, "I3C3" } + { APU_I3C0_BASE, "I3C0", FCH_AOAC_DEV_I3C0}, + { APU_I3C1_BASE, "I3C1", FCH_AOAC_DEV_I3C1}, + { APU_I3C2_BASE, "I3C2", FCH_AOAC_DEV_I3C2}, + { APU_I3C3_BASE, "I3C3", FCH_AOAC_DEV_I3C3} }; const struct soc_i3c_ctrlr_info *soc_get_i3c_ctrlr_info(size_t *num_ctrlrs) diff --git a/src/soc/amd/mendocino/i3c.c b/src/soc/amd/mendocino/i3c.c index e694623177..0e041942b6 100644 --- a/src/soc/amd/mendocino/i3c.c +++ b/src/soc/amd/mendocino/i3c.c @@ -1,14 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include static const struct soc_i3c_ctrlr_info i3c_ctrlr[I3C_CTRLR_COUNT] = { - { APU_I3C0_BASE, "I3C0" }, - { APU_I3C1_BASE, "I3C1" }, - { APU_I3C2_BASE, "I3C2" }, - { APU_I3C3_BASE, "I3C3" } + { APU_I3C0_BASE, "I3C0", FCH_AOAC_DEV_I3C0}, + { APU_I3C1_BASE, "I3C1", FCH_AOAC_DEV_I3C1}, + { APU_I3C2_BASE, "I3C2", FCH_AOAC_DEV_I3C2}, + { APU_I3C3_BASE, "I3C3", FCH_AOAC_DEV_I3C3} }; const struct soc_i3c_ctrlr_info *soc_get_i3c_ctrlr_info(size_t *num_ctrlrs) diff --git a/src/soc/amd/phoenix/i3c.c b/src/soc/amd/phoenix/i3c.c index e694623177..0e041942b6 100644 --- a/src/soc/amd/phoenix/i3c.c +++ b/src/soc/amd/phoenix/i3c.c @@ -1,14 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include static const struct soc_i3c_ctrlr_info i3c_ctrlr[I3C_CTRLR_COUNT] = { - { APU_I3C0_BASE, "I3C0" }, - { APU_I3C1_BASE, "I3C1" }, - { APU_I3C2_BASE, "I3C2" }, - { APU_I3C3_BASE, "I3C3" } + { APU_I3C0_BASE, "I3C0", FCH_AOAC_DEV_I3C0}, + { APU_I3C1_BASE, "I3C1", FCH_AOAC_DEV_I3C1}, + { APU_I3C2_BASE, "I3C2", FCH_AOAC_DEV_I3C2}, + { APU_I3C3_BASE, "I3C3", FCH_AOAC_DEV_I3C3} }; const struct soc_i3c_ctrlr_info *soc_get_i3c_ctrlr_info(size_t *num_ctrlrs) diff --git a/src/soc/amd/turin_poc/i3c.c b/src/soc/amd/turin_poc/i3c.c index e694623177..0e041942b6 100644 --- a/src/soc/amd/turin_poc/i3c.c +++ b/src/soc/amd/turin_poc/i3c.c @@ -1,14 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include static const struct soc_i3c_ctrlr_info i3c_ctrlr[I3C_CTRLR_COUNT] = { - { APU_I3C0_BASE, "I3C0" }, - { APU_I3C1_BASE, "I3C1" }, - { APU_I3C2_BASE, "I3C2" }, - { APU_I3C3_BASE, "I3C3" } + { APU_I3C0_BASE, "I3C0", FCH_AOAC_DEV_I3C0}, + { APU_I3C1_BASE, "I3C1", FCH_AOAC_DEV_I3C1}, + { APU_I3C2_BASE, "I3C2", FCH_AOAC_DEV_I3C2}, + { APU_I3C3_BASE, "I3C3", FCH_AOAC_DEV_I3C3} }; const struct soc_i3c_ctrlr_info *soc_get_i3c_ctrlr_info(size_t *num_ctrlrs) From b1e8f87b301da9d7a1c43bb78006aba8856ebb0a Mon Sep 17 00:00:00 2001 From: Jarried Lin Date: Mon, 9 Feb 2026 13:26:00 +0800 Subject: [PATCH 622/789] mb/google/rauru: Enable MEDIATEK_WDT_RESET_BY_SW For MT8196p, watchdog external reset is enabled by kernel configuration, and EC ignores the reset signal AP_PMIC_WDTRST_L. Therefore, enable MEDIATEK_WDT_RESET_BY_SW to allow triggering the secondary watchdog reset via software instead of watchdog hardware. BUG=b:481854714 TEST=cbmem logs preserved on WDT timeout Change-Id: Ib6b1ddbe28b0cd2aac2043f18dcd15caf4cac37a Signed-off-by: Jarried Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/91420 Reviewed-by: Yidi Lin Tested-by: build bot (Jenkins) --- src/mainboard/google/rauru/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/google/rauru/Kconfig b/src/mainboard/google/rauru/Kconfig index 486e273874..c13149aefe 100644 --- a/src/mainboard/google/rauru/Kconfig +++ b/src/mainboard/google/rauru/Kconfig @@ -40,6 +40,7 @@ config BOARD_SPECIFIC_OPTIONS select FW_CONFIG_SOURCE_CHROMEEC_CBI select RTC select MIPI_PANEL_BOE_NS130069_M00 if BOARD_GOOGLE_SAPPHIRE + select MEDIATEK_WDT_RESET_BY_SW if BOARD_GOOGLE_SAPPHIRE config MAINBOARD_DIR string From 7b205808e464a369ddffb49cb15cd2f13e59862d Mon Sep 17 00:00:00 2001 From: Jarried Lin Date: Mon, 9 Feb 2026 13:24:20 +0800 Subject: [PATCH 623/789] mb/google/rauru: Disable CHROMEOS_USE_EC_WATCHDOG_FLAG Now that we use the WATCHDOG_TOMBSTONE section to store the watchdog event magic, there is no need to ask EC for the last reset reason. In fact, with MEDIATEK_WDT_RESET_BY_SW enabled, EC doesn't even record the watchdog reset reason. Enable CHROMEOS_USE_EC_WATCHDOG_FLAG only if MEDIATEK_WDT_RESET_BY_SW is disabled. BUG=b:481854714 TEST= After triggering WDT timeout, the following log can be observed: [NOTE ] coreboot-coreboot-unknown.9999.782bb84 Mon Feb 23 06:42:21 UTC 2026 aarch64 bootblock starting (log level: 8) [DEBUG] ARM64: Exception handlers installed. [DEBUG] ARM64: Testing exception [DEBUG] ARM64: Done test exception [DEBUG] [booker_init] AP hash rule: 0xbe00 [INFO ] mtk_cksys_init = 0x1 [INFO ] WDT: Status = 0x20000 [INFO ] WDT: Last reset was other reset type: 0x00020000 [INFO ] mtk_wdt_swreset() called! [INFO ] board_reset() called! And "elogtool list" contained "Hardware watchdog reset". Change-Id: I44a940d88948897e6727fad5c87f364e3ba9ac61 Signed-off-by: Jarried Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/91421 Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- src/mainboard/google/rauru/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/rauru/Kconfig b/src/mainboard/google/rauru/Kconfig index c13149aefe..dbbfcfb360 100644 --- a/src/mainboard/google/rauru/Kconfig +++ b/src/mainboard/google/rauru/Kconfig @@ -26,7 +26,7 @@ config BOARD_SPECIFIC_OPTIONS select SPI_FLASH_INCLUDE_ALL_DRIVERS select MAINBOARD_HAS_NATIVE_VGA_INIT select HAVE_LINEAR_FRAMEBUFFER - select CHROMEOS_USE_EC_WATCHDOG_FLAG if CHROMEOS + select CHROMEOS_USE_EC_WATCHDOG_FLAG if CHROMEOS && !MEDIATEK_WDT_RESET_BY_SW select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_BOARDID select EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC if BOARD_GOOGLE_SAPPHIRE From 098a5cf16e5a972216833fedd57d594185668b15 Mon Sep 17 00:00:00 2001 From: Sowmya V Date: Tue, 17 Feb 2026 17:06:57 +0530 Subject: [PATCH 624/789] mb/google/ocelot: Configure CDCLK frequency for display Configure the Core Display Clock (CDCLK) frequency selection by setting the 'vga_cd_clk_freq_sel' register to CD_CLK_461MHZ in the ocelot baseboard devicetree. This ensures the display engine operates at the required frequency for the panel to meet the hardware configuration. TEST=Build and boot ocelot, verify display initialization. Change-Id: Ic2f8fccc4391febd342f8f140014c5f3e09472c4 Signed-off-by: Sowmya V Reviewed-on: https://review.coreboot.org/c/coreboot/+/91312 Reviewed-by: Avi Uday Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- .../google/ocelot/variants/baseboard/ocelot/devicetree.cb | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb b/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb index 23b276e15a..b53380c2ee 100644 --- a/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb +++ b/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb @@ -95,6 +95,7 @@ chip soc/intel/pantherlake register "pch_hda_idisp_codec_enable" = "true" register "disable_progress_bar" = "true" + register "vga_cd_clk_freq_sel" = "CD_CLK_461MHZ" device domain 0 on device ref dtt on end From 08f2f3a21bcbb3ea32ad25fa3af788ebbf447b6d Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Wed, 10 Sep 2025 16:30:34 +0200 Subject: [PATCH 625/789] Haswell NRI: Implement 1D margin training Implement an algorithm that performs a simple 1D margin training. This algorithm is generic, i.e. it can be used with multiple margin params. Use this algorithm to train three margin parameters: RdT, WrT and RdV. This algorithm also does per-bit calibration, but only for RdT and WrT since Haswell does not have per-rank per-bit RdV (c.f. `RX_OFFSET_VDQ` register). Still, implement support in `change_margin()` for all three types of per-bit margins (WrTBit, RdTBit, RdVBit) for completeness. Tested on Asrock Z97 Extreme6 with 2 DIMMs per channel (1R + 2R): - NRI finishes successfully, board still boots to Arch Linux. - Both fast training as well as S3 suspend/resume still work. Change-Id: I382cea8e230aee46a0dc66248f1e678d8a9a0090 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/89314 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- .../intel/haswell/native_raminit/Makefile.mk | 1 + .../haswell/native_raminit/change_margin.c | 122 ++++++- .../haswell/native_raminit/raminit_main.c | 3 + .../haswell/native_raminit/raminit_native.h | 59 ++++ .../intel/haswell/native_raminit/reut.c | 9 + .../haswell/native_raminit/train_1d_margins.c | 305 ++++++++++++++++++ .../intel/haswell/registers/mchbar.h | 5 + 7 files changed, 496 insertions(+), 8 deletions(-) create mode 100644 src/northbridge/intel/haswell/native_raminit/train_1d_margins.c diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk index 4bd668a2d6..c7a5f4ba5a 100644 --- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk +++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk @@ -18,6 +18,7 @@ romstage-y += setup_wdb.c romstage-y += spd_bitmunching.c romstage-y += testing_io.c romstage-y += timings_refresh.c +romstage-y += train_1d_margins.c romstage-y += train_jedec_write_leveling.c romstage-y += train_read_mpr.c romstage-y += train_receive_enable.c diff --git a/src/northbridge/intel/haswell/native_raminit/change_margin.c b/src/northbridge/intel/haswell/native_raminit/change_margin.c index 517ddc23a6..2ef8712bf8 100644 --- a/src/northbridge/intel/haswell/native_raminit/change_margin.c +++ b/src/northbridge/intel/haswell/native_raminit/change_margin.c @@ -200,18 +200,109 @@ static void update_data_offset_train( } } -static uint32_t get_max_margin(const enum margin_parameter param) +static uint16_t get_per_bit_reg( + const enum margin_parameter param, + const bool multicast, + const uint8_t channel, + const uint8_t rank, + const uint8_t byte) +{ + switch (param) { + case RdTBit: + if (multicast) { + return DDR_DATA_RX_PER_BIT_RANK(rank); + } else { + return RX_PER_BIT(channel, rank, byte); + } + case WrTBit: + if (multicast) { + return DDR_DATA_TX_PER_BIT_RANK(rank); + } else { + return TX_PER_BIT(channel, rank, byte); + } + case RdVBit: + /** TODO: Broadwell has per-rank RX_OFFSET_VDQ registers **/ + if (multicast) { + return DDR_DATA_RX_OFFSET_VDQ; + } else { + return RX_OFFSET_VDQ(channel, byte); + } + default: + die("%s: Invalid margin parameter %d\n", __func__, param); + } +} + +static void update_per_bit_margin( + struct sysinfo *ctrl, + const enum margin_parameter param, + const uint8_t channel, + const uint8_t rank, + const uint8_t byte, + const uint32_t value) +{ + for (uint8_t bit = 0; bit < NUM_BITS; bit++) { + const uint8_t v_bit = value >> (4 * bit) & 0xf; + switch (param) { + case RdTBit: + ctrl->rxdqpb[channel][rank][byte][bit].center = v_bit; + break; + case WrTBit: + ctrl->txdqpb[channel][rank][byte][bit].center = v_bit; + break; + case RdVBit: + ctrl->rxdqvrefpb[channel][rank][byte][bit].center = v_bit; + break; + default: + break; + } + } +} + +static void change_per_bit_margin( + struct sysinfo *ctrl, + const enum margin_parameter param, + const bool multicast, + const uint8_t in_channel, + const uint8_t rank, + const uint8_t in_byte, + const bool update_ctrl, + const uint32_t value, + const enum regfile_mode regfile) +{ + const bool is_rd = param == RdTBit || param == RdVBit; + const bool is_wr = param == WrTBit; + const uint16_t reg = get_per_bit_reg(param, multicast, in_channel, rank, in_byte); + mchbar_write32(reg, value); + if (multicast) { + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!does_ch_exist(ctrl, channel)) + continue; + + download_regfile(ctrl, channel, true, rank, regfile, 0, is_rd, is_wr); + if (!update_ctrl) + continue; + + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { + update_per_bit_margin(ctrl, param, channel, rank, byte, value); + } + } + } else { + download_regfile(ctrl, in_channel, false, rank, regfile, in_byte, is_rd, is_wr); + if (!update_ctrl) + return; + + update_per_bit_margin(ctrl, param, in_channel, rank, in_byte, value); + } +} + +uint32_t get_max_margin_for_param(const enum margin_parameter param) { switch (param) { - case RcvEna: - case RdT: - case WrT: - case WrDqsT: - return MAX_POSSIBLE_TIME; case RdV: + case WrV: return MAX_POSSIBLE_VREF; default: - die("%s: Invalid margin parameter %u\n", __func__, param); + return MAX_POSSIBLE_TIME; } } @@ -233,7 +324,22 @@ void change_margin( if (!en_multicast && !does_ch_exist(ctrl, channel)) die("%s: Tried to change margin of empty channel %u\n", __func__, channel); - const uint32_t max_value = get_max_margin(param); + /* Per-bit margins are handled differently */ + if (param == WrTBit || param == RdTBit || param == RdVBit) { + change_per_bit_margin( + ctrl, + param, + en_multicast, + channel, + rank, + byte, + update_ctrl, + (uint32_t)value0, + regfile); + return; + } + + const uint32_t max_value = get_max_margin_for_param(param); const int32_t v0 = clamp_s32(-max_value, value0, max_value); union ddr_data_offset_train_reg ddr_data_offset_train = { diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c index 84db33ebdf..91c1920725 100644 --- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c +++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c @@ -129,6 +129,9 @@ static const struct task_entry cold_boot[] = { { train_receive_enable, true, "RCVET", }, { train_read_mpr, true, "RDMPRT", }, { train_jedec_write_leveling, true, "JWRL", }, + { train_write_timing_centering, true, "WRTC1D", }, + { train_read_timing_centering, true, "RDTC1D", }, + { train_read_voltage_centering, true, "RDVC1D", }, { optimise_comp, true, "OPTCOMP", }, { post_training, true, "POSTTRAIN", }, { activate_mc, true, "ACTIVATE", }, diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h index 53dbe4df28..123f579a76 100644 --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h @@ -68,6 +68,29 @@ enum margin_parameter { WrT, WrDqsT, RdV, + WrV, + WrLevel, + WrTBit, + RdTBit, + RdVBit, + INVALID_MARGIN, +}; + +/* + * This enum is used to index an array of margin results. Those are + * used to keep track of available margin in more advanced training + * algorithms (optimisation), c.f. margin_result member in sysinfo. + */ +enum last_margin_param { + LastRxV, + LastRxT, + LastTxV, + LastTxT, + LastRcvEna, + LastWrLevel, + LastCmdT, + LastCmdV, + MAX_RESULT_TYPE, }; enum opt_param { @@ -232,6 +255,7 @@ enum raminit_status { RAMINIT_STATUS_SUCCESS = 0, RAMINIT_STATUS_NO_MEMORY_INSTALLED, RAMINIT_STATUS_UNSUPPORTED_MEMORY, + RAMINIT_STATUS_INVALID_PARAMETER, RAMINIT_STATUS_MPLL_INIT_FAILURE, RAMINIT_STATUS_POLL_TIMEOUT, RAMINIT_STATUS_REUT_ERROR, @@ -239,6 +263,7 @@ enum raminit_status { RAMINIT_STATUS_RCVEN_FAILURE, RAMINIT_STATUS_RMPR_FAILURE, RAMINIT_STATUS_JWRL_FAILURE, + RAMINIT_STATUS_1D_MARGINING_FAILURE, RAMINIT_STATUS_INVALID_CACHE, RAMINIT_STATUS_UNSPECIFIED_ERROR, /** TODO: Deprecated in favor of specific values **/ }; @@ -261,12 +286,32 @@ struct raminit_dimm_info { bool valid; }; +struct last_margin { + uint32_t start; + uint32_t end; +}; + +struct time_margin { + uint8_t left; + uint8_t center; + uint8_t right; +}; + struct vref_margin { uint8_t low; uint8_t center; uint8_t high; }; +union raw_bitlane_errors { + struct { + uint32_t lower; + uint32_t upper; + uint8_t ecc; + }; + uint8_t per_byte[NUM_LANES]; +}; + struct sysinfo { enum raminit_boot_mode bootmode; enum generic_stepping stepping; @@ -355,6 +400,9 @@ struct sysinfo { uint8_t rxdqsn[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES]; int8_t rxvref[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES]; + struct time_margin rxdqpb[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES][NUM_BITS]; + struct time_margin txdqpb[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES][NUM_BITS]; + struct vref_margin rxdqvrefpb[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES][NUM_BITS]; uint8_t clk_pi_code[NUM_CHANNELS][NUM_SLOTRANKS]; @@ -365,6 +413,11 @@ struct sysinfo { uint8_t cmd_north_pi_code[NUM_CHANNELS][NUM_GROUPS]; uint8_t cmd_south_pi_code[NUM_CHANNELS][NUM_GROUPS]; + /* + * BIG WARNING: The slotrank comes before the channel! + */ + struct last_margin results[MAX_RESULT_TYPE][NUM_SLOTRANKS][NUM_CHANNELS][NUM_LANES]; + union tc_bank_reg tc_bank[NUM_CHANNELS]; union tc_bank_rank_a_reg tc_bankrank_a[NUM_CHANNELS]; union tc_bank_rank_b_reg tc_bankrank_b[NUM_CHANNELS]; @@ -488,6 +541,9 @@ enum raminit_status train_sense_amp_offset(struct sysinfo *ctrl); enum raminit_status train_receive_enable(struct sysinfo *ctrl); enum raminit_status train_read_mpr(struct sysinfo *ctrl); enum raminit_status train_jedec_write_leveling(struct sysinfo *ctrl); +enum raminit_status train_read_timing_centering(struct sysinfo *ctrl); +enum raminit_status train_write_timing_centering(struct sysinfo *ctrl); +enum raminit_status train_read_voltage_centering(struct sysinfo *ctrl); enum raminit_status optimise_comp(struct sysinfo *ctrl); enum raminit_status save_training_values(struct sysinfo *ctrl); enum raminit_status restore_training_values(struct sysinfo *ctrl); @@ -536,6 +592,7 @@ void reut_issue_mrs_all( const uint16_t val[NUM_SLOTS]); enum raminit_status reut_issue_zq(struct sysinfo *ctrl, uint8_t chanmask, uint8_t zq_type); +union raw_bitlane_errors get_bitlane_errors(const uint8_t channel); void write_wdb_fixed_pat( const struct sysinfo *ctrl, @@ -604,6 +661,8 @@ void download_regfile( bool read_rf_rd, bool read_rf_wr); +uint32_t get_max_margin_for_param(const enum margin_parameter param); + void change_margin( struct sysinfo *ctrl, const enum margin_parameter param, diff --git a/src/northbridge/intel/haswell/native_raminit/reut.c b/src/northbridge/intel/haswell/native_raminit/reut.c index 31019f74a1..10fb8cc1c3 100644 --- a/src/northbridge/intel/haswell/native_raminit/reut.c +++ b/src/northbridge/intel/haswell/native_raminit/reut.c @@ -194,3 +194,12 @@ enum raminit_status reut_issue_zq(struct sysinfo *ctrl, uint8_t chanmask, uint8_ return status; } + +union raw_bitlane_errors get_bitlane_errors(const uint8_t channel) +{ + return (union raw_bitlane_errors) { + .lower = mchbar_read32(REUT_ch_ERR_DATA_STATUS(channel) + 0), + .upper = mchbar_read32(REUT_ch_ERR_DATA_STATUS(channel) + 4), + .ecc = mchbar_read8(REUT_ch_ERR_MISC_STATUS(channel)), + }; +} diff --git a/src/northbridge/intel/haswell/native_raminit/train_1d_margins.c b/src/northbridge/intel/haswell/native_raminit/train_1d_margins.c new file mode 100644 index 0000000000..bea17f2f1a --- /dev/null +++ b/src/northbridge/intel/haswell/native_raminit/train_1d_margins.c @@ -0,0 +1,305 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "raminit_native.h" +#include "ranges.h" + +#define MAX_BITLANE_LINES (2 * MAX_POSSIBLE_BOTH + 1) +#define MARGIN_MIN_WIDTH 8 + +#define MARGIN_1D_PLOT RAM_DEBUG + +static void print_bitlane( + struct sysinfo *ctrl, + const uint8_t channel, + const int32_t m_start, + const int32_t m_step, + const int32_t m_stop, + const union raw_bitlane_errors bit_failures[NUM_CHANNELS][MAX_BITLANE_LINES]) +{ + for (int32_t offset = m_start; offset <= m_stop; offset += m_step) { + const uint32_t index = offset + MAX_POSSIBLE_BOTH; + const union raw_bitlane_errors *failures = &bit_failures[channel][index]; + printk(MARGIN_1D_PLOT, "\n% 5d\t", offset); + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { + const uint8_t byte_errors = failures->per_byte[byte]; + for (uint8_t bit = 0; bit < NUM_BITS; bit++) + printk(MARGIN_1D_PLOT, byte_errors & BIT(bit) ? "#" : "."); + } + } +} + +static enum raminit_status apply_dq_offsets( + struct sysinfo *ctrl, + const uint8_t channel, + const uint8_t rank, + const enum margin_parameter param, + enum raminit_status status, + const struct linear_train_data chan_data[]) +{ + printk(BIOS_DEBUG, "\nC%u.R%u: Left\tRight\tWidth\tCenter\n", channel, rank); + + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { + const struct linear_train_data *const curr_data = &chan_data[byte]; + const int32_t lwidth = range_width(curr_data->largest); + const int32_t center = range_center(curr_data->largest); + printk(BIOS_DEBUG, " B%u: %d\t%d\t%d\t%d", + byte, + curr_data->largest.start, + curr_data->largest.end, + lwidth, + center); + if (lwidth < MARGIN_MIN_WIDTH) { + printk(BIOS_ERR, + "\t1D eye too small! channel: %u byte: %u width: %d\n", + channel, byte, lwidth); + status = RAMINIT_STATUS_1D_MARGINING_FAILURE; + } else { + printk(BIOS_DEBUG, "\n"); + } + const struct last_margin margin = { + .start = ABS(curr_data->largest.start - center) * 10, + .end = ABS(curr_data->largest.end - center) * 10, + }; + switch (param) { + case RdT: + ctrl->rxdqsp[channel][rank][byte] += center; + ctrl->rxdqsn[channel][rank][byte] += center; + update_rxt(ctrl, channel, rank, byte, RXT_RESTORE, 0); + ctrl->results[LastRxT][rank][channel][byte] = margin; + break; + case WrT: + ctrl->tx_dq[channel][rank][byte] += center; + update_txt(ctrl, channel, rank, byte, TXT_RESTORE, 0); + ctrl->results[LastTxT][rank][channel][byte] = margin; + break; + case RdV: + /* RdV training uses half steps */ + ctrl->rxvref[channel][rank][byte] += center / 2; + update_rxt(ctrl, channel, rank, byte, RXT_RESTORE, 0); + ctrl->results[LastRxV][rank][channel][byte] = margin; + break; + default: + break; + } + } + return status; +} + +static const char *const get_delay_string(const enum margin_parameter param) +{ + switch (param) { + case RdT: return "RdDqsDelay"; + case WrT: return "WrDqsDelay"; + case RdV: return "RdVoltage"; + default: return NULL; + } +} + +static enum margin_parameter get_per_bit_margin_param(const enum margin_parameter param) +{ + switch (param) { + case RdT: return RdTBit; + case WrT: return WrTBit; + case RdV: return RdVBit; + default: return INVALID_MARGIN; + } +} + +static enum raminit_status train_1d_margin( + struct sysinfo *ctrl, + const uint8_t chanmask_in, + const enum margin_parameter param, + const bool reset_per_bit, + const uint8_t loopcount) +{ + const char *const delay_string = get_delay_string(param); + if (!delay_string) { + printk(BIOS_ERR, "%s: Invalid margin parameter %u\n", __func__, param); + return RAMINIT_STATUS_INVALID_PARAMETER; + } + setup_io_test_basic_va(ctrl, chanmask_in, loopcount, NSOE); + + const enum margin_parameter param_bit = get_per_bit_margin_param(param); + if (reset_per_bit && param_bit == INVALID_MARGIN) { + printk(BIOS_ERR, "%s: Invalid per-bit margin for param %u\n", __func__, param); + return RAMINIT_STATUS_INVALID_PARAMETER; + } + + const int32_t m_stop = get_max_margin_for_param(param); + const int32_t m_start = -m_stop; + const int32_t m_step = 1; + enum raminit_status status = 0; + for (uint8_t rank = 0; rank < NUM_SLOTRANKS; rank++) { + if (!does_rank_exist(ctrl, rank)) + continue; + + /* Hell thinks this should be resetting the currently selected rank */ + if (reset_per_bit) { + change_1d_margin_multicast( + ctrl, + param_bit, + 0x88888888, + rank, + true, + REG_FILE_USE_RANK); + } + printk(BIOS_DEBUG, "Rank %u\n", rank); + printk(MARGIN_1D_PLOT, "Channel"); + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!rank_in_ch(ctrl, rank, channel)) + continue; + + printk(MARGIN_1D_PLOT, "\t%u\t\t", channel); + } + printk(MARGIN_1D_PLOT, "\nByte"); + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!rank_in_ch(ctrl, rank, channel)) + continue; + + printk(MARGIN_1D_PLOT, "\t"); + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) + printk(MARGIN_1D_PLOT, "%u ", byte); + } + uint8_t chanmask = 0; + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + chanmask |= select_reut_ranks(ctrl, channel, BIT(rank)); + if (!(BIT(channel) & chanmask)) + continue; + + /* Update rank timing to middle value */ + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { + if (param == RdT) { + ctrl->rxdqsp[channel][rank][byte] = 32; + ctrl->rxdqsn[channel][rank][byte] = 32; + update_rxt(ctrl, channel, rank, byte, RXT_RESTORE, 0); + } else if (param == WrT) { + /* + * Put TxDq in the middle of the strobe and ensure + * there is enough room to sweep to the right. + */ + uint16_t tx_dq = ctrl->txdqs[channel][rank][byte] + 32; + if ((tx_dq + m_stop) > 511) + tx_dq = 511 - m_stop; + + ctrl->tx_dq[channel][rank][byte] = tx_dq; + update_txt(ctrl, channel, rank, byte, TXT_RESTORE, 0); + } else if (param == RdV) { + ctrl->rxvref[channel][rank][byte] = 0; + update_rxt(ctrl, channel, rank, byte, RXT_RESTORE, 0); + } + } + + /* Set up REUT error counters to count errors per channel */ + mchbar_write32(REUT_ch_ERR_COUNTER_CTL_x(channel, 0), 0); + } + if (!chanmask) + continue; + + clear_data_offset_train_all(ctrl); + printk(MARGIN_1D_PLOT, "\n%s", delay_string); + struct linear_train_data region_data[NUM_CHANNELS][NUM_LANES] = { 0 }; + union raw_bitlane_errors bit_errors[NUM_CHANNELS][MAX_BITLANE_LINES] = { 0 }; + for (int32_t offset = m_start; offset <= m_stop; offset += m_step) { + printk(MARGIN_1D_PLOT, "\n% 5d", offset); + change_1d_margin_multicast( + ctrl, + param, + offset, + 0, + false, + REG_FILE_USE_START); + + run_io_test(ctrl, chanmask, ctrl->dq_pat, 1); + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!(chanmask & BIT(channel))) + continue; + + /* Read out byte group error results and update limit */ + const uint16_t result = get_byte_group_errors(channel); + bit_errors[channel][offset + MAX_POSSIBLE_BOTH] = + get_bitlane_errors(channel); + printk(MARGIN_1D_PLOT, "\t"); + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { + const bool pass = !(result & BIT(byte)); + printk(MARGIN_1D_PLOT, pass ? ". " : "# "); + linear_record_pass( + ®ion_data[channel][byte], + pass, + offset, + m_start, + m_step); + } + } + } + printk(MARGIN_1D_PLOT, "\n\nBit lane information"); + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!(chanmask & BIT(channel))) + continue; + + printk(MARGIN_1D_PLOT, "\nChannel %u\nByte ", channel); + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) + printk(MARGIN_1D_PLOT, "%u ", byte); + + printk(MARGIN_1D_PLOT, "\nBit "); + for (uint8_t bit_count = 0; bit_count < ctrl->lanes * 8; bit_count++) + printk(MARGIN_1D_PLOT, "%u", bit_count % 8); + + printk(MARGIN_1D_PLOT, "\n%s", delay_string); + print_bitlane( + ctrl, + channel, + m_start, + m_step, + m_stop, + bit_errors); + + printk(MARGIN_1D_PLOT, "\n"); + } + change_1d_margin_multicast( + ctrl, + param, + 0, + 0, + false, + REG_FILE_USE_CURRENT); + + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!(chanmask & BIT(channel))) + continue; + + status = apply_dq_offsets( + ctrl, + channel, + rank, + param, + status, + region_data[channel]); + } + printk(BIOS_DEBUG, "\n"); + } + + return status; +} + +#define DATA_TRAIN_LOOP_COUNT 15 + +enum raminit_status train_read_timing_centering(struct sysinfo *ctrl) +{ + return train_1d_margin(ctrl, ctrl->chanmap, RdT, true, DATA_TRAIN_LOOP_COUNT); +} + +enum raminit_status train_write_timing_centering(struct sysinfo *ctrl) +{ + return train_1d_margin(ctrl, ctrl->chanmap, WrT, true, DATA_TRAIN_LOOP_COUNT); +} + +enum raminit_status train_read_voltage_centering(struct sysinfo *ctrl) +{ + /* + * We do not reset per-bit RdV. Haswell only has one RX_OFFSET_VDQ register + * per rank, so this would require combining training results for all ranks + * somehow. While Broadwell and newer platforms have per-rank RX_OFFSET_VDQ + * registers, we can keep using sense amp offset training results, for now. + */ + return train_1d_margin(ctrl, ctrl->chanmap, RdV, false, DATA_TRAIN_LOOP_COUNT); +} diff --git a/src/northbridge/intel/haswell/registers/mchbar.h b/src/northbridge/intel/haswell/registers/mchbar.h index a944e12625..5be398734c 100644 --- a/src/northbridge/intel/haswell/registers/mchbar.h +++ b/src/northbridge/intel/haswell/registers/mchbar.h @@ -16,7 +16,9 @@ /* DDR DATA per-channel per-bytelane */ #define RX_TRAIN_ch_r_b(ch, rank, byte) _DDRIO_C_R_B(0x0000, ch, rank, byte) +#define RX_PER_BIT(ch, rank, byte) _DDRIO_C_R_B(0x0010, ch, rank, byte) #define TX_TRAIN_ch_r_b(ch, rank, byte) _DDRIO_C_R_B(0x0020, ch, rank, byte) +#define TX_PER_BIT(ch, rank, byte) _DDRIO_C_R_B(0x0030, ch, rank, byte) #define RX_OFFSET_VDQ(ch, byte) _DDRIO_C_R_B(0x004c, ch, 0, byte) @@ -126,8 +128,11 @@ #define REUT_ch_ERR_DATA_MASK(ch) _MCMAIN_C(0x40d8, ch) +#define REUT_ch_ERR_DATA_STATUS(ch) _MCMAIN_C(0x40e0, ch) #define REUT_ch_ERR_MISC_STATUS(ch) _MCMAIN_C(0x40e8, ch) +#define REUT_ch_ERR_COUNTER_CTL_x(ch, byte) _MCMAIN_C_X(0x40f0, ch, byte) + #define REUT_ch_MISC_CKE_CTRL(ch) _MCMAIN_C(0x4190, ch) #define REUT_ch_MISC_ODT_CTRL(ch) _MCMAIN_C(0x4194, ch) #define REUT_ch_MISC_PAT_CADB_CTRL(ch) _MCMAIN_C(0x4198, ch) From 5e46ac13648e30b5aea8ecc5b7a8403f39fc1b26 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 23 Feb 2026 09:20:14 +0530 Subject: [PATCH 626/789] mb/google/bluey: Resize WP_RO and add RW_UNUSED region Modify the flash map (fmd) to reduce the Write-Protected RO (WP_RO) section from 12M to 8M. The recovered 4M of space is reallocated to a new RW_UNUSED region positioned before RW_LEGACY. BUG=None TEST=Build bluey image and verify FMAP table with 'fmap_decode'. Ensure resulting layout matches the intended offsets. Change-Id: I6dde5fac5ba3be5fb28f2cd46c5518d87082c067 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91379 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/chromeos-nogsc.fmd | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/bluey/chromeos-nogsc.fmd b/src/mainboard/google/bluey/chromeos-nogsc.fmd index 6ffe1d335c..85ef0fe673 100644 --- a/src/mainboard/google/bluey/chromeos-nogsc.fmd +++ b/src/mainboard/google/bluey/chromeos-nogsc.fmd @@ -1,7 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only FLASH@0x0 CONFIG_ROM_SIZE { - WP_RO 12M { + WP_RO 8M { RO_SECTION { BOOTBLOCK 512K FMAP 4K @@ -37,5 +37,7 @@ FLASH@0x0 CONFIG_ROM_SIZE { RW_FWID_B 256 } + RW_UNUSED 4M + RW_LEGACY(CBFS) } From 523242b2b933d4e4c12c6fd11dc130780ce28486 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 23 Feb 2026 09:22:25 +0530 Subject: [PATCH 627/789] google/bluey: Add RW_CDT region to flash map Carve out 256K from the RW_UNUSED region to create a new RW_CDT section at the end of the flash. The RW_UNUSED region is reduced from 4096K (4M) to 3840K to maintain the existing flash offset for the start of the unused block. The RW_CDT region will be used to store Configuration Data Tables, allowing for platform-specific configuration binary blobs to be stored and updated in the RW section of the flash. BUG=b:483194720 TEST=Build bluey and verify the FMAP layout using 'dump_fmap'. Ensure RW_CDT exists at the expected offset. dump_fmap -h ../../out/build/bluey/firmware/image-bluey.serial.bin RW_CDT 01fc0000 02000000 00040000 RW_UNUSED 01c00000 01fc0000 003c0000 RW_LEGACY 0192e000 01c00000 002d2000 RW_SECTION_B 010ae000 0192e000 00880000 RW_FWID_B 0192df00 0192e000 00000100 FW_MAIN_B 010b0000 0192df00 0087df00 VBLOCK_B 010ae000 010b0000 00002000 RW_SECTION_A 0082e000 010ae000 00880000 RW_FWID_A 010adf00 010ae000 00000100 FW_MAIN_A 00830000 010adf00 0087df00 VBLOCK_A 0082e000 00830000 00002000 RW_MISC 00800000 0082e000 0002e000 RW_NVRAM 0082a000 0082e000 00004000 RW_VPD 00822000 0082a000 00008000 RW_SHARED 00821000 00822000 00001000 SHARED_DATA 00821000 00822000 00001000 RW_ELOG 00820000 00821000 00001000 UNIFIED_MRC_CACHE 00800000 00820000 00020000 RW_MRC_CACHE 00810000 00820000 00010000 RECOVERY_MRC_CACHE 00800000 00810000 00010000 WP_RO 00000000 00800000 00800000 RO_VPD 007fc000 00800000 00004000 RO_GSCVD 007fa000 007fc000 00002000 RO_SECTION 00000000 007fa000 007fa000 RO_FRID 007f9f00 007fa000 00000100 GBB 007f7000 007f9f00 00002f00 COREBOOT 00081000 007f7000 00776000 FMAP 00080000 00081000 00001000 BOOTBLOCK 00000000 00080000 00080000 Change-Id: I7d305647731862e61871e781ad7bfb7cd430b699 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91380 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/chromeos-nogsc.fmd | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/bluey/chromeos-nogsc.fmd b/src/mainboard/google/bluey/chromeos-nogsc.fmd index 85ef0fe673..cd3caa84f2 100644 --- a/src/mainboard/google/bluey/chromeos-nogsc.fmd +++ b/src/mainboard/google/bluey/chromeos-nogsc.fmd @@ -37,7 +37,9 @@ FLASH@0x0 CONFIG_ROM_SIZE { RW_FWID_B 256 } - RW_UNUSED 4M - RW_LEGACY(CBFS) + + RW_UNUSED 3840K + + RW_CDT 256K } From 08dcaf404cf8a0ff84148abc02dff08aa3f92718 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Tue, 24 Feb 2026 15:09:24 +0800 Subject: [PATCH 628/789] mb/google/nissa/var/yavilla: Add micron memory to RAM ID table DRAM Part Name ID to assign MT62F1G32D2DS-031RF WT:C 2 (0010) MT62F2G32D4DS-031RF WT:C 5 (0101) BUG=b:487113903 TEST=build nissa coreboot Change-Id: I5b49ec3513fd1878942c96bc8b5375d79e049898 Signed-off-by: Tony Huang Reviewed-on: https://review.coreboot.org/c/coreboot/+/91406 Reviewed-by: Wisley Chen Tested-by: build bot (Jenkins) --- src/mainboard/google/brya/variants/yavilla/memory/Makefile.mk | 4 ++-- .../google/brya/variants/yavilla/memory/dram_id.generated.txt | 2 ++ .../google/brya/variants/yavilla/memory/mem_parts_used.txt | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/brya/variants/yavilla/memory/Makefile.mk b/src/mainboard/google/brya/variants/yavilla/memory/Makefile.mk index 26c31d4ef3..99061e1d12 100644 --- a/src/mainboard/google/brya/variants/yavilla/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/yavilla/memory/Makefile.mk @@ -6,9 +6,9 @@ SPD_SOURCES = SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 0(0b0000) Parts = MT62F512M32D2DR-031 WT:B, H9JCNNNBK3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-10.hex # ID = 1(0b0001) Parts = H58G66CK8BX147 -SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = H58G56AK6BX069, K3LKBKB0BM-MGCP +SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = H58G56AK6BX069, K3LKBKB0BM-MGCP, MT62F1G32D2DS-031RF WT:C SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = H58G56BK7BX068, MT62F1G32D2DS-026 WT:B, K3KL8L80CM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-8.hex # ID = 4(0b0100) Parts = H58G66BK7BX067, MT62F2G32D4DS-026 WT:B, K3KL9L90CM-MGCT -SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = H58G66AK6BX070 +SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = H58G66AK6BX070, MT62F2G32D4DS-031RF WT:C SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 6(0b0110) Parts = K3KL6L60GM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 7(0b0111) Parts = H58G56CK8BX146 diff --git a/src/mainboard/google/brya/variants/yavilla/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/yavilla/memory/dram_id.generated.txt index 1264f20e91..6b938ba8dd 100644 --- a/src/mainboard/google/brya/variants/yavilla/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/yavilla/memory/dram_id.generated.txt @@ -18,3 +18,5 @@ K3KL9L90CM-MGCT 4 (0100) H58G66AK6BX070 5 (0101) K3KL6L60GM-MGCT 6 (0110) H58G56CK8BX146 7 (0111) +MT62F1G32D2DS-031RF WT:C 2 (0010) +MT62F2G32D4DS-031RF WT:C 5 (0101) diff --git a/src/mainboard/google/brya/variants/yavilla/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/yavilla/memory/mem_parts_used.txt index 76efa2cd44..d0add1f65a 100644 --- a/src/mainboard/google/brya/variants/yavilla/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/yavilla/memory/mem_parts_used.txt @@ -23,3 +23,5 @@ K3KL9L90CM-MGCT H58G66AK6BX070 K3KL6L60GM-MGCT H58G56CK8BX146 +MT62F1G32D2DS-031RF WT:C +MT62F2G32D4DS-031RF WT:C From e84415b8f8c479be0d4f10dda421976ca7e4acc6 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Tue, 24 Feb 2026 15:10:20 +0800 Subject: [PATCH 629/789] mb/google/nissa/var/yaviks: Add micron memory to RAM ID table DRAM Part Name ID to assign MT62F1G32D2DS-031RF WT:C 2 (0010) MT62F2G32D4DS-031RF WT:C 5 (0101) BUG=b:487113903 TEST=build nissa coreboot Change-Id: I171d2cdfcd4ec41562b09705dab64f00ce51c6a2 Signed-off-by: Tony Huang Reviewed-on: https://review.coreboot.org/c/coreboot/+/91407 Tested-by: build bot (Jenkins) Reviewed-by: Wisley Chen --- src/mainboard/google/brya/variants/yaviks/memory/Makefile.mk | 4 ++-- .../google/brya/variants/yaviks/memory/dram_id.generated.txt | 2 ++ .../google/brya/variants/yaviks/memory/mem_parts_used.txt | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/brya/variants/yaviks/memory/Makefile.mk b/src/mainboard/google/brya/variants/yaviks/memory/Makefile.mk index 8f38bca9de..ccd34e882d 100644 --- a/src/mainboard/google/brya/variants/yaviks/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/yaviks/memory/Makefile.mk @@ -6,9 +6,9 @@ SPD_SOURCES = SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 0(0b0000) Parts = MT62F512M32D2DR-031 WT:B, H9JCNNNBK3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 1(0b0001) Parts = MT62F1G32D4DR-031 WT:B -SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = H58G56AK6BX069, K3LKBKB0BM-MGCP +SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = H58G56AK6BX069, K3LKBKB0BM-MGCP, MT62F1G32D2DS-031RF WT:C SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = H58G56BK7BX068, MT62F1G32D2DS-026 WT:B, K3KL8L80CM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-8.hex # ID = 4(0b0100) Parts = H58G66BK7BX067, MT62F2G32D4DS-026 WT:B, K3KL9L90CM-MGCT -SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = H58G66AK6BX070 +SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = H58G66AK6BX070, MT62F2G32D4DS-031RF WT:C SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 6(0b0110) Parts = K3KL6L60GM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 7(0b0111) Parts = H58G56CK8BX146 diff --git a/src/mainboard/google/brya/variants/yaviks/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/yaviks/memory/dram_id.generated.txt index d0e3dfe8de..4dbb10bc33 100644 --- a/src/mainboard/google/brya/variants/yaviks/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/yaviks/memory/dram_id.generated.txt @@ -18,3 +18,5 @@ K3KL9L90CM-MGCT 4 (0100) H58G66AK6BX070 5 (0101) K3KL6L60GM-MGCT 6 (0110) H58G56CK8BX146 7 (0111) +MT62F1G32D2DS-031RF WT:C 2 (0010) +MT62F2G32D4DS-031RF WT:C 5 (0101) diff --git a/src/mainboard/google/brya/variants/yaviks/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/yaviks/memory/mem_parts_used.txt index d9e4129cba..3a13bb4951 100644 --- a/src/mainboard/google/brya/variants/yaviks/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/yaviks/memory/mem_parts_used.txt @@ -23,3 +23,5 @@ K3KL9L90CM-MGCT H58G66AK6BX070 K3KL6L60GM-MGCT H58G56CK8BX146 +MT62F1G32D2DS-031RF WT:C +MT62F2G32D4DS-031RF WT:C From 38988a727e9e15bbc675929205db3ba682575fcc Mon Sep 17 00:00:00 2001 From: Jarried Lin Date: Mon, 9 Feb 2026 13:17:18 +0800 Subject: [PATCH 630/789] util/mediatek: Reduce non-boot related BROM settings Reduce BROM settings that are not related to boot to save boot time. BUG=b:480810041 TEST= 0:1st timestamp reduce from 400ms to 250ms Change-Id: Ia97a78515d80a141b9b409407f6e41a07261cad9 Signed-off-by: Jarried Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/91423 Tested-by: build bot (Jenkins) Reviewed-by: Chen-Tsung Hsieh Reviewed-by: Yidi Lin --- util/mediatek/gen-bl-img.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/mediatek/gen-bl-img.py b/util/mediatek/gen-bl-img.py index 7cd7dbb079..a98b1ea845 100755 --- a/util/mediatek/gen-bl-img.py +++ b/util/mediatek/gen-bl-img.py @@ -43,7 +43,7 @@ def gen_gfh_info(chip, data): 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00006400, 0x00001388, + 0x00000000, 0x52000000, 0x00006400, 0x00001388, 0x00000000, 0x00000000, 0x00000000, 0x00000000) return gfh From 8ba58ef800aa899feada62c0562f3f64857934cf Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Thu, 26 Feb 2026 08:20:05 -0600 Subject: [PATCH 631/789] mb/samsung/lumpy: Correct NID 0x08 HDA pin config macro usage Commit eb504eb49ab7 ("mb/samsung/lumpy: Fix HDA pin configuration issues") incorrectly used AZALIA_PIN_CFG_NC(0) as a standalone entry for NID 0x08. Change to AZALIA_PIN_CFG(0, 0x08, AZALIA_PIN_CFG_NC(0)) so the verb for NID 0x08 is emitted correctly. Change-Id: Iaf23b6e8791a352758189d92ad9c89414fc5a22d Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/91442 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/mainboard/samsung/lumpy/hda_verb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/samsung/lumpy/hda_verb.c b/src/mainboard/samsung/lumpy/hda_verb.c index aedd7b6ce2..e6ed443a95 100644 --- a/src/mainboard/samsung/lumpy/hda_verb.c +++ b/src/mainboard/samsung/lumpy/hda_verb.c @@ -56,7 +56,7 @@ const u32 cim_verb_data[] = { )), /* Pin Complex (NID 0x08) - Unused (NC) */ - AZALIA_PIN_CFG_NC(0), + AZALIA_PIN_CFG(0, 0x08, AZALIA_PIN_CFG_NC(0)), /* Pin Complex (NID 0x09) - Internal Digital Mic */ AZALIA_PIN_CFG(0, 0x09, AZALIA_PIN_DESC( From c57b88d74ddd6e7296b60a8e327a2d2c22ac725c Mon Sep 17 00:00:00 2001 From: Rui Zhou Date: Thu, 26 Feb 2026 09:28:08 +0800 Subject: [PATCH 632/789] mb/google/brox/var/lotso: delete mb_get_channel_disable_mask We found that the lotso project has already used variant_is_half_populated. If we continue to use the mb_get_channel_disable_mask API, it will reduce the memory of each DDR by half. In reality, we are reducing the number of DDR modules (from 4 to 2), so we should remove mb_get_channel_disable_mask to ensure proper DIMM identification. BUG=b:468889066 BRANCH=None TEST=boot to kernel success, and the log shows that the RAM ID is correct. Change-Id: Ia7fc4610b3257bc20a871080f52f02e089b8531c Signed-off-by: Rui Zhou Reviewed-on: https://review.coreboot.org/c/coreboot/+/91426 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/mainboard/google/brox/Kconfig | 1 - src/mainboard/google/brox/variants/lotso/memory.c | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/src/mainboard/google/brox/Kconfig b/src/mainboard/google/brox/Kconfig index bb4d3746b2..8847f33e72 100644 --- a/src/mainboard/google/brox/Kconfig +++ b/src/mainboard/google/brox/Kconfig @@ -81,7 +81,6 @@ config BOARD_GOOGLE_BROX_EC_ISH config BOARD_GOOGLE_LOTSO select BOARD_GOOGLE_BASEBOARD_BROX select CHROMEOS_WIFI_SAR if CHROMEOS - select ENFORCE_MEM_CHANNEL_DISABLE select MAINBOARD_HAS_GOOGLE_STRAUSS_KEYBOARD select USE_UNIFIED_AP_FIRMWARE_FOR_UFS_AND_NON_UFS diff --git a/src/mainboard/google/brox/variants/lotso/memory.c b/src/mainboard/google/brox/variants/lotso/memory.c index 0997707e9f..84b9f4a70d 100644 --- a/src/mainboard/google/brox/variants/lotso/memory.c +++ b/src/mainboard/google/brox/variants/lotso/memory.c @@ -99,19 +99,6 @@ bool variant_is_half_populated(void) return gpio_get(GPP_S0); } -uint8_t mb_get_channel_disable_mask(void) -{ - /* - * GPP_S0 High -> One RAM Chip - * GPP_S0 Low -> Two RAM Chip - * Disable all other channels except first two on each controller - */ - if (gpio_get(GPP_S0)) - return (BIT(2) | BIT(3)); - - return 0; -} - void variant_get_spd_info(struct mem_spd *spd_info) { spd_info->topo = MEM_TOPO_MEMORY_DOWN; From f9f43d862db83745996f4587487902d70f9d280a Mon Sep 17 00:00:00 2001 From: Hualin Wei Date: Thu, 12 Feb 2026 12:38:36 +0800 Subject: [PATCH 633/789] spd/lp5: Add Micron memory part Add Micron memory part MT62F2G32D4DS-023 to LP5 global list. BUG=b:488228474 TEST=emerge-fatcat coreboot, rework by EE flash it and boot normal. Change-Id: I5c628f35ae789a20688a761c09c1c04578e40f1f Signed-off-by: Hualin Wei Reviewed-on: https://review.coreboot.org/c/coreboot/+/91451 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) Reviewed-by: Weimin Wu Reviewed-by: Pranava Y N --- spd/lp5/memory_parts.json | 11 +++++++++++ spd/lp5/set-0/parts_spd_manifest.generated.txt | 1 + spd/lp5/set-1/parts_spd_manifest.generated.txt | 1 + 3 files changed, 13 insertions(+) diff --git a/spd/lp5/memory_parts.json b/spd/lp5/memory_parts.json index 033d001b70..4c21c7bb28 100644 --- a/spd/lp5/memory_parts.json +++ b/spd/lp5/memory_parts.json @@ -445,6 +445,17 @@ "speedMbps": 7500, "lp5x": true } + }, + { + "name": "MT62F2G32D4DS-020 WT:D", + "attribs": { + "densityPerDieGb": 16, + "diesPerPackage": 4, + "bitWidthPerChannel": 16, + "ranksPerChannel": 2, + "speedMbps": 8533, + "lp5x": true + } } ] } diff --git a/spd/lp5/set-0/parts_spd_manifest.generated.txt b/spd/lp5/set-0/parts_spd_manifest.generated.txt index 0401c008e0..11221ec42c 100644 --- a/spd/lp5/set-0/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-0/parts_spd_manifest.generated.txt @@ -43,3 +43,4 @@ MT62F1G32D2DS-031RF WT:C,spd-3.hex MT62F2G32D4DS-031RF WT:C,spd-6.hex RS1G32LO5D2FDB-23BT,spd-11.hex BWMYAX32P8A-32G,spd-7.hex +MT62F2G32D4DS-020 WT:D,spd-10.hex diff --git a/spd/lp5/set-1/parts_spd_manifest.generated.txt b/spd/lp5/set-1/parts_spd_manifest.generated.txt index 0401c008e0..11221ec42c 100644 --- a/spd/lp5/set-1/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-1/parts_spd_manifest.generated.txt @@ -43,3 +43,4 @@ MT62F1G32D2DS-031RF WT:C,spd-3.hex MT62F2G32D4DS-031RF WT:C,spd-6.hex RS1G32LO5D2FDB-23BT,spd-11.hex BWMYAX32P8A-32G,spd-7.hex +MT62F2G32D4DS-020 WT:D,spd-10.hex From 8718db133af1f5abe789e6160460aeac37310219 Mon Sep 17 00:00:00 2001 From: Hualin Wei Date: Thu, 12 Feb 2026 12:45:53 +0800 Subject: [PATCH 634/789] mb/google/fatcat/var/lapis: Add 2 Micron modules to RAM id table Add Micron MT62F1G32D2DS-020 WT:D as id 1, and add Micron MT62F2G32D4DS-020 WT:D as id 0, resulting in the list below: DRAM Part Name ID to assign H58G66CK8BX147 0 (0000) K3KL9L90EM-MGCU 0 (0000) MT62F2G32D4DS-023 WT:C 0 (0000) H58G56CK8BX146 1 (0001) K3KL8L80EM-MGCU 1 (0001) MT62F1G32D2DS-023 WT:C 1 (0001) K3KLALA0EM-MGCU 2 (0010) MT62F1G32D2DS-020 WT:D 1 (0001) MT62F2G32D4DS-020 WT:D 0 (0000) BUG=b:488228474 TEST=emerge-fatcat coreboot, rework by EE flash it and boot normal. Change-Id: I23ee56fe7e8f2e2ade75eaaf1fa19b91e784030f Signed-off-by: Hualin Wei Reviewed-on: https://review.coreboot.org/c/coreboot/+/91452 Reviewed-by: Subrata Banik Reviewed-by: Weimin Wu Reviewed-by: Pranava Y N Tested-by: build bot (Jenkins) --- src/mainboard/google/fatcat/variants/lapis/memory/Makefile.mk | 4 ++-- .../google/fatcat/variants/lapis/memory/dram_id.generated.txt | 2 ++ .../google/fatcat/variants/lapis/memory/mem_parts_used.txt | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/fatcat/variants/lapis/memory/Makefile.mk b/src/mainboard/google/fatcat/variants/lapis/memory/Makefile.mk index 3580f944f9..05fac1eb69 100644 --- a/src/mainboard/google/fatcat/variants/lapis/memory/Makefile.mk +++ b/src/mainboard/google/fatcat/variants/lapis/memory/Makefile.mk @@ -4,6 +4,6 @@ # util/spd_tools/bin/part_id_gen PTL lp5 src/mainboard/google/fatcat/variants/lapis/memory src/mainboard/google/fatcat/variants/lapis/memory/mem_parts_used.txt SPD_SOURCES = -SPD_SOURCES += spd/lp5/set-0/spd-10.hex # ID = 0(0b0000) Parts = H58G66CK8BX147, K3KL9L90EM-MGCU, MT62F2G32D4DS-023 WT:C -SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 1(0b0001) Parts = H58G56CK8BX146, K3KL8L80EM-MGCU, MT62F1G32D2DS-023 WT:C +SPD_SOURCES += spd/lp5/set-0/spd-10.hex # ID = 0(0b0000) Parts = H58G66CK8BX147, K3KL9L90EM-MGCU, MT62F2G32D4DS-023 WT:C, MT62F2G32D4DS-020 WT:D +SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 1(0b0001) Parts = H58G56CK8BX146, K3KL8L80EM-MGCU, MT62F1G32D2DS-023 WT:C, MT62F1G32D2DS-020 WT:D SPD_SOURCES += spd/lp5/set-0/spd-13.hex # ID = 2(0b0010) Parts = K3KLALA0EM-MGCU diff --git a/src/mainboard/google/fatcat/variants/lapis/memory/dram_id.generated.txt b/src/mainboard/google/fatcat/variants/lapis/memory/dram_id.generated.txt index 9d1f695535..cbb2a992c8 100644 --- a/src/mainboard/google/fatcat/variants/lapis/memory/dram_id.generated.txt +++ b/src/mainboard/google/fatcat/variants/lapis/memory/dram_id.generated.txt @@ -11,3 +11,5 @@ H58G56CK8BX146 1 (0001) K3KL8L80EM-MGCU 1 (0001) MT62F1G32D2DS-023 WT:C 1 (0001) K3KLALA0EM-MGCU 2 (0010) +MT62F1G32D2DS-020 WT:D 1 (0001) +MT62F2G32D4DS-020 WT:D 0 (0000) diff --git a/src/mainboard/google/fatcat/variants/lapis/memory/mem_parts_used.txt b/src/mainboard/google/fatcat/variants/lapis/memory/mem_parts_used.txt index 332be8dc20..87fdf46aa6 100644 --- a/src/mainboard/google/fatcat/variants/lapis/memory/mem_parts_used.txt +++ b/src/mainboard/google/fatcat/variants/lapis/memory/mem_parts_used.txt @@ -16,3 +16,5 @@ H58G56CK8BX146 K3KL8L80EM-MGCU MT62F1G32D2DS-023 WT:C K3KLALA0EM-MGCU +MT62F1G32D2DS-020 WT:D +MT62F2G32D4DS-020 WT:D From 6be9ee7ce496afadc70f50e3b6864fa04b0aa909 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 25 Feb 2026 08:02:09 -0600 Subject: [PATCH 635/789] mb/google/link: Use AZALIA_PIN_DESC macros for pin widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the Creative CA0132 Pin Widget Verb Table from raw hex config values to AZALIA_PIN_DESC for NIDs 0x0B–0x13, and use AZALIA_PIN_CFG_NC(0) for N/C pins (0x0C–0x0F). Mapping generated by hda-decoder utility. TEST=build/boot LINK Change-Id: Ia1c9bce2bf0a71aa3a60678828cbc6bc55f7bfc1 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/91443 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/mainboard/google/link/hda_verb.c | 53 +++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/mainboard/google/link/hda_verb.c b/src/mainboard/google/link/hda_verb.c index d3309cd6d7..07f88be305 100644 --- a/src/mainboard/google/link/hda_verb.c +++ b/src/mainboard/google/link/hda_verb.c @@ -72,31 +72,66 @@ const u32 cim_verb_data[] = { AZALIA_SUBVENDOR(0, 0x10280550), /* Pin Complex (NID 0x0B) Port-G Analog Unknown Speaker at Int N/A */ - AZALIA_PIN_CFG(0, 0x0b, 0x901700f0), + AZALIA_PIN_CFG(0, 0x0b, AZALIA_PIN_DESC( + AZALIA_INTEGRATED, + AZALIA_INTERNAL, + AZALIA_SPEAKER, + AZALIA_OTHER_ANALOG, + AZALIA_COLOR_UNKNOWN, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0)), /* Pin Complex (NID 0x0C) N/C */ - AZALIA_PIN_CFG(0, 0x0c, 0x70f000f0), + AZALIA_PIN_CFG(0, 0x0c, AZALIA_PIN_CFG_NC(0)), /* Pin Complex (NID 0x0D) N/C */ - AZALIA_PIN_CFG(0, 0x0d, 0x70f000f0), + AZALIA_PIN_CFG(0, 0x0d, AZALIA_PIN_CFG_NC(0)), /* Pin Complex (NID 0x0E) N/C */ - AZALIA_PIN_CFG(0, 0x0e, 0x70f000f0), + AZALIA_PIN_CFG(0, 0x0e, AZALIA_PIN_CFG_NC(0)), /* Pin Complex (NID 0x0F) N/C */ - AZALIA_PIN_CFG(0, 0x0f, 0x70f000f0), + AZALIA_PIN_CFG(0, 0x0f, AZALIA_PIN_CFG_NC(0)), /* Pin Complex (NID 0x10) Port-D 1/8 Black HP Out at Ext Left */ - AZALIA_PIN_CFG(0, 0x10, 0x032110f0), + AZALIA_PIN_CFG(0, 0x10, AZALIA_PIN_DESC( + AZALIA_JACK, + AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_LEFT, + AZALIA_HP_OUT, + AZALIA_STEREO_MONO_1_8, + AZALIA_BLACK, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0)), /* Pin Complex (NID 0x11) Port-B Click Mic */ - AZALIA_PIN_CFG(0, 0x11, 0x90a700f0), + AZALIA_PIN_CFG(0, 0x11, AZALIA_PIN_DESC( + AZALIA_INTEGRATED, + AZALIA_INTERNAL, + AZALIA_MIC_IN, + AZALIA_OTHER_ANALOG, + AZALIA_COLOR_UNKNOWN, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0)), /* Pin Complex (NID 0x12) Port-C Combo Jack Mic or D-Mic */ - AZALIA_PIN_CFG(0, 0x12, 0x03a110f0), + AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_DESC( + AZALIA_JACK, + AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_LEFT, + AZALIA_MIC_IN, + AZALIA_STEREO_MONO_1_8, + AZALIA_BLACK, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0)), /* Pin Complex (NID 0x13) What you hear */ - AZALIA_PIN_CFG(0, 0x13, 0x90d600f0), + AZALIA_PIN_CFG(0, 0x13, AZALIA_PIN_DESC( + AZALIA_INTEGRATED, + AZALIA_INTERNAL, + AZALIA_DIGITAL_OTHER_IN, + AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0)), /* coreboot specific header */ 0x80862806, // Codec Vendor / Device ID: Intel CougarPoint HDMI From 57f96b83fe5fd58a72c29dba63d8dec96796f026 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 25 Feb 2026 08:08:55 -0600 Subject: [PATCH 636/789] mb/google/link/hda_verb: Remove presence detect flag from internal sources The pin widgets for the internal speakers and microphone should not have the presence detect flag set, as this causes the jack detect to fail on some distros, leading to headphone output not working. TEST=build/boot LINK Change-Id: I798d0cc4a0f4de65ebe51f1dafaeeb12728d2f40 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/91444 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/mainboard/google/link/hda_verb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/link/hda_verb.c b/src/mainboard/google/link/hda_verb.c index 07f88be305..7199e5a6f1 100644 --- a/src/mainboard/google/link/hda_verb.c +++ b/src/mainboard/google/link/hda_verb.c @@ -78,7 +78,7 @@ const u32 cim_verb_data[] = { AZALIA_SPEAKER, AZALIA_OTHER_ANALOG, AZALIA_COLOR_UNKNOWN, - AZALIA_JACK_PRESENCE_DETECT, + AZALIA_NO_JACK_PRESENCE_DETECT, 15, 0)), /* Pin Complex (NID 0x0C) N/C */ @@ -110,7 +110,7 @@ const u32 cim_verb_data[] = { AZALIA_MIC_IN, AZALIA_OTHER_ANALOG, AZALIA_COLOR_UNKNOWN, - AZALIA_JACK_PRESENCE_DETECT, + AZALIA_NO_JACK_PRESENCE_DETECT, 15, 0)), /* Pin Complex (NID 0x12) Port-C Combo Jack Mic or D-Mic */ From 416875e93ee71bcc53079146873ebb5635497c70 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 15 Feb 2026 12:54:31 +0100 Subject: [PATCH 637/789] mb/lenovo/t430|t530: Reduces differences in code Make the T430 look like the T530 codebase by reordering includes, update the ACPI code and update the CMOS defaults file. Should have not influence on functionality, but changes the TIMELESS build artifacts. Change-Id: I2c300ecbf44fa950183ee5e05ba1e05cdf5ff00d Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/91281 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/mainboard/lenovo/t430/cmos.default | 2 +- src/mainboard/lenovo/t430/cmos.layout | 1 + src/mainboard/lenovo/t430/dsdt.asl | 17 +++++++++++------ src/mainboard/lenovo/t430/smihandler.c | 2 +- src/mainboard/lenovo/t530/early_init.c | 5 ++--- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/mainboard/lenovo/t430/cmos.default b/src/mainboard/lenovo/t430/cmos.default index c896eadec1..4857f92f67 100644 --- a/src/mainboard/lenovo/t430/cmos.default +++ b/src/mainboard/lenovo/t430/cmos.default @@ -15,6 +15,6 @@ fn_ctrl_swap=Disable sticky_fn=Disable trackpoint=Enable backlight=Both -usb_always_on=Disable hybrid_graphics_mode=Integrated Only +usb_always_on=Disable me_state=Normal diff --git a/src/mainboard/lenovo/t430/cmos.layout b/src/mainboard/lenovo/t430/cmos.layout index 3e48df5584..d109a61b4e 100644 --- a/src/mainboard/lenovo/t430/cmos.layout +++ b/src/mainboard/lenovo/t430/cmos.layout @@ -41,6 +41,7 @@ entries # coreboot config options: northbridge 432 3 e 11 gfx_uma_size 435 2 e 12 hybrid_graphics_mode + 440 8 h 0 volume # VBOOT diff --git a/src/mainboard/lenovo/t430/dsdt.asl b/src/mainboard/lenovo/t430/dsdt.asl index 795f9a1ee9..1134782675 100644 --- a/src/mainboard/lenovo/t430/dsdt.asl +++ b/src/mainboard/lenovo/t430/dsdt.asl @@ -11,24 +11,29 @@ DefinitionBlock( ACPI_DSDT_REV_2, OEM_ID, ACPI_TABLE_CREATOR, - 0x20141018 // OEM revision + 0x20110725 // OEM revision ) { #include - #include "acpi/platform.asl" - #include #include - /* global NVS and variables. */ + + #include "acpi/platform.asl" + + // global NVS and variables #include - #include + + #include Scope (\_SB) { Device (PCI0) { #include - #include #include + + #include } } + + #include #include } diff --git a/src/mainboard/lenovo/t430/smihandler.c b/src/mainboard/lenovo/t430/smihandler.c index 81cbc487f6..03c899e0d9 100644 --- a/src/mainboard/lenovo/t430/smihandler.c +++ b/src/mainboard/lenovo/t430/smihandler.c @@ -5,8 +5,8 @@ #include #include #include -#include #include +#include #define GPE_EC_SCI 1 #define GPE_EC_WAKE 13 diff --git a/src/mainboard/lenovo/t530/early_init.c b/src/mainboard/lenovo/t530/early_init.c index b7bc35adbb..d982660856 100644 --- a/src/mainboard/lenovo/t530/early_init.c +++ b/src/mainboard/lenovo/t530/early_init.c @@ -1,12 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include #include #include +#include #include -#include #include +#include static void hybrid_graphics_init(void) { From 3a5e4660bbf735dd2a2b65cc6032828b8dbfe00a Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 15 Feb 2026 13:39:44 +0100 Subject: [PATCH 638/789] mb/lenovo/t530: Unify GEN_DEC entries Use the same GEN_DEC ranges as on t430. This makes the code look more similar, but doesn't change the functionality. It changes the TIMELESS build artifact. Change-Id: Ibfac61f615fba2b91101125a2187b45af6dadd19 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/91283 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/mainboard/lenovo/t530/devicetree.cb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mainboard/lenovo/t530/devicetree.cb b/src/mainboard/lenovo/t530/devicetree.cb index 13c40d91d4..944de3dd49 100644 --- a/src/mainboard/lenovo/t530/devicetree.cb +++ b/src/mainboard/lenovo/t530/devicetree.cb @@ -35,9 +35,9 @@ chip northbridge/intel/sandybridge # Set max SATA speed to 6.0 Gb/s register "sata_interface_speed_support" = "0x3" - register "gen1_dec" = "0x7c1601" - register "gen2_dec" = "0x0c15e1" - register "gen4_dec" = "0x0c06a1" + register "gen1_dec" = "0x00c15e1" + register "gen2_dec" = "0x07c1601" + register "gen3_dec" = "0x00c06a1" # Enable zero-based linear PCIe root port functions register "pcie_port_coalesce" = "true" From 091ae533b9fdb5b78a5edbc2b68c2faee083f1dd Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 15 Feb 2026 13:23:02 +0100 Subject: [PATCH 639/789] mb/lenovo/t430: Merge into t430 into t530 Both models are quite similar, so reuse existing code and reduce code duplication. TEST=TIMELESS build shows identical devicetree.cb, DSDT, cmos layout, bootblock, romstage and postcar stages. ramstage shows minor differences as static.c is now build before hda_verb.c, resulting in different location of data symbols. Binary analysis shows that the data itself didn't change, just the position in the final binary. Change-Id: I2e7cf67c9e2542a199b11257e7349a55e0518aac Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/91285 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/mainboard/lenovo/t430/Kconfig | 80 --------- src/mainboard/lenovo/t430/Kconfig.name | 4 - src/mainboard/lenovo/t430/Makefile.mk | 8 - src/mainboard/lenovo/t430/acpi/ec.asl | 4 - src/mainboard/lenovo/t430/acpi/platform.asl | 23 --- src/mainboard/lenovo/t430/acpi/superio.asl | 3 - src/mainboard/lenovo/t430/acpi_tables.c | 15 -- src/mainboard/lenovo/t430/board_info.txt | 6 - src/mainboard/lenovo/t430/cmos.default | 20 --- src/mainboard/lenovo/t430/cmos.layout | 108 ------------ src/mainboard/lenovo/t430/devicetree.cb | 166 ------------------ src/mainboard/lenovo/t430/dsdt.asl | 39 ---- src/mainboard/lenovo/t430/early_init.c | 40 ----- src/mainboard/lenovo/t430/gma-mainboard.ads | 22 --- src/mainboard/lenovo/t430/mainboard.c | 15 -- src/mainboard/lenovo/t430/smihandler.c | 68 ------- .../lenovo/t430/vboot-ro-me_clean.fmd | 21 --- src/mainboard/lenovo/t430/vboot-ro.fmd | 21 --- src/mainboard/lenovo/t430/vboot-rwab.fmd | 35 ---- src/mainboard/lenovo/t530/Kconfig | 7 + src/mainboard/lenovo/t530/Kconfig.name | 3 + src/mainboard/lenovo/t530/Makefile.mk | 1 + .../lenovo/{ => t530/variants}/t430/data.vbt | Bin .../lenovo/{ => t530/variants}/t430/gpio.c | 0 .../{ => t530/variants}/t430/hda_verb.c | 0 .../lenovo/t530/variants/t430/overridetree.cb | 58 ++++++ .../t530/{ => variants/t530}/hda_verb.c | 0 .../lenovo/t530/variants/w530/hda_verb.c | 75 ++++++++ 28 files changed, 144 insertions(+), 698 deletions(-) delete mode 100644 src/mainboard/lenovo/t430/Kconfig delete mode 100644 src/mainboard/lenovo/t430/Kconfig.name delete mode 100644 src/mainboard/lenovo/t430/Makefile.mk delete mode 100644 src/mainboard/lenovo/t430/acpi/ec.asl delete mode 100644 src/mainboard/lenovo/t430/acpi/platform.asl delete mode 100644 src/mainboard/lenovo/t430/acpi/superio.asl delete mode 100644 src/mainboard/lenovo/t430/acpi_tables.c delete mode 100644 src/mainboard/lenovo/t430/board_info.txt delete mode 100644 src/mainboard/lenovo/t430/cmos.default delete mode 100644 src/mainboard/lenovo/t430/cmos.layout delete mode 100644 src/mainboard/lenovo/t430/devicetree.cb delete mode 100644 src/mainboard/lenovo/t430/dsdt.asl delete mode 100644 src/mainboard/lenovo/t430/early_init.c delete mode 100644 src/mainboard/lenovo/t430/gma-mainboard.ads delete mode 100644 src/mainboard/lenovo/t430/mainboard.c delete mode 100644 src/mainboard/lenovo/t430/smihandler.c delete mode 100644 src/mainboard/lenovo/t430/vboot-ro-me_clean.fmd delete mode 100644 src/mainboard/lenovo/t430/vboot-ro.fmd delete mode 100644 src/mainboard/lenovo/t430/vboot-rwab.fmd rename src/mainboard/lenovo/{ => t530/variants}/t430/data.vbt (100%) rename src/mainboard/lenovo/{ => t530/variants}/t430/gpio.c (100%) rename src/mainboard/lenovo/{ => t530/variants}/t430/hda_verb.c (100%) create mode 100644 src/mainboard/lenovo/t530/variants/t430/overridetree.cb rename src/mainboard/lenovo/t530/{ => variants/t530}/hda_verb.c (100%) create mode 100644 src/mainboard/lenovo/t530/variants/w530/hda_verb.c diff --git a/src/mainboard/lenovo/t430/Kconfig b/src/mainboard/lenovo/t430/Kconfig deleted file mode 100644 index 2b6eb17e9c..0000000000 --- a/src/mainboard/lenovo/t430/Kconfig +++ /dev/null @@ -1,80 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -if BOARD_LENOVO_THINKPAD_T430 - -config BOARD_SPECIFIC_OPTIONS - def_bool y - select AZALIA_USE_LEGACY_VERB_TABLE - select BOARD_ROMSIZE_KB_12288 - select DRIVERS_LENOVO_HYBRID_GRAPHICS - select DRIVER_LENOVO_SERIALS - select DRIVER_LENOVO_SERIALS_EARLY_LOCK - select DRIVERS_RICOH_RCE822 - select EC_LENOVO_H8 - select EC_LENOVO_PMH7 - select GFX_GMA_PANEL_1_ON_LVDS - select H8_HAS_BAT_THRESHOLDS_IMPL - select H8_HAS_BDC_GPIO_DETECTION - select H8_HAS_WWAN_GPIO_DETECTION - select HAVE_ACPI_RESUME - select HAVE_ACPI_TABLES - select HAVE_CMOS_DEFAULT - select HAVE_OPTION_TABLE - select INTEL_GMA_HAVE_VBT - select INTEL_INT15 - select MAINBOARD_HAS_LIBGFXINIT - select MAINBOARD_HAS_TPM1 - select MAINBOARD_USES_IFD_GBE_REGION - select MEMORY_MAPPED_TPM - select NO_UART_ON_SUPERIO - select NORTHBRIDGE_INTEL_SANDYBRIDGE - select SERIRQ_CONTINUOUS_MODE - select SOUTHBRIDGE_INTEL_C216 - select SYSTEM_TYPE_LAPTOP - select USE_NATIVE_RAMINIT - -config VBOOT - select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC - select GBB_FLAG_DISABLE_FWMP - select GBB_FLAG_DISABLE_LID_SHUTDOWN - select GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC - select HAS_RECOVERY_MRC_CACHE - select VBOOT_VBNV_FLASH - -config VBOOT_SLOTS_RW_AB - default y - -config CBFS_SIZE - default 0x700000 - -config FMDFILE - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT - -config MAINBOARD_DIR - default "lenovo/t430" - -config MAINBOARD_PART_NUMBER - default "ThinkPad T430" - -config VGA_BIOS_ID - string - default "8086,0166" - -config DRAM_RESET_GATE_GPIO - int - default 10 - -config USBDEBUG_HCD_INDEX - int - default 2 - -config PS2K_EISAID - default "PNP0303" - -config PS2M_EISAID - default "LEN0015" - -config THINKPADEC_HKEY_EISAID - default "LEN0068" - -endif diff --git a/src/mainboard/lenovo/t430/Kconfig.name b/src/mainboard/lenovo/t430/Kconfig.name deleted file mode 100644 index f14a1a2d78..0000000000 --- a/src/mainboard/lenovo/t430/Kconfig.name +++ /dev/null @@ -1,4 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -config BOARD_LENOVO_THINKPAD_T430 - bool "ThinkPad T430" diff --git a/src/mainboard/lenovo/t430/Makefile.mk b/src/mainboard/lenovo/t430/Makefile.mk deleted file mode 100644 index e4b6fbf0f0..0000000000 --- a/src/mainboard/lenovo/t430/Makefile.mk +++ /dev/null @@ -1,8 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -bootblock-y += gpio.c -romstage-y += gpio.c - -ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads -bootblock-y += early_init.c -romstage-y += early_init.c diff --git a/src/mainboard/lenovo/t430/acpi/ec.asl b/src/mainboard/lenovo/t430/acpi/ec.asl deleted file mode 100644 index 987593e919..0000000000 --- a/src/mainboard/lenovo/t430/acpi/ec.asl +++ /dev/null @@ -1,4 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include diff --git a/src/mainboard/lenovo/t430/acpi/platform.asl b/src/mainboard/lenovo/t430/acpi/platform.asl deleted file mode 100644 index 9dee90edc3..0000000000 --- a/src/mainboard/lenovo/t430/acpi/platform.asl +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* The _PTS method (Prepare To Sleep) is called before the OS is - * entering a sleep state. The sleep state number is passed in Arg0 - */ - -Method(_PTS,1) -{ - \_SB.PCI0.LPCB.EC.MUTE(1) - \_SB.PCI0.LPCB.EC.USBP(0) - \_SB.PCI0.LPCB.EC.RADI(0) -} - -/* The _WAK method is called on system wakeup */ - -Method(_WAK,1) -{ - /* Wake the HKEY to init BT/WWAN */ - \_SB.PCI0.LPCB.EC.HKEY.WAKE (Arg0) - - /* Not implemented. */ - Return(Package(){0,0}) -} diff --git a/src/mainboard/lenovo/t430/acpi/superio.asl b/src/mainboard/lenovo/t430/acpi/superio.asl deleted file mode 100644 index ee2eabeb75..0000000000 --- a/src/mainboard/lenovo/t430/acpi/superio.asl +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include diff --git a/src/mainboard/lenovo/t430/acpi_tables.c b/src/mainboard/lenovo/t430/acpi_tables.c deleted file mode 100644 index 36d3e85c1e..0000000000 --- a/src/mainboard/lenovo/t430/acpi_tables.c +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -void mainboard_fill_gnvs(struct global_nvs *gnvs) -{ - /* The lid is open by default */ - gnvs->lids = 1; - - /* Temperature at which OS will shutdown */ - gnvs->tcrt = 100; - /* Temperature at which OS will throttle CPU */ - gnvs->tpsv = 90; -} diff --git a/src/mainboard/lenovo/t430/board_info.txt b/src/mainboard/lenovo/t430/board_info.txt deleted file mode 100644 index 09ddde1f85..0000000000 --- a/src/mainboard/lenovo/t430/board_info.txt +++ /dev/null @@ -1,6 +0,0 @@ -Category: laptop -ROM package: SOIC-8 -ROM protocol: SPI -ROM socketed: n -Flashrom support: n -Release year: 2012 diff --git a/src/mainboard/lenovo/t430/cmos.default b/src/mainboard/lenovo/t430/cmos.default deleted file mode 100644 index 4857f92f67..0000000000 --- a/src/mainboard/lenovo/t430/cmos.default +++ /dev/null @@ -1,20 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -boot_option=Fallback -debug_level=Debug -power_on_after_fail=Disable -nmi=Enable -volume=0x3 -first_battery=Primary -bluetooth=Enable -wwan=Enable -wlan=Enable -touchpad=Enable -sata_mode=AHCI -fn_ctrl_swap=Disable -sticky_fn=Disable -trackpoint=Enable -backlight=Both -hybrid_graphics_mode=Integrated Only -usb_always_on=Disable -me_state=Normal diff --git a/src/mainboard/lenovo/t430/cmos.layout b/src/mainboard/lenovo/t430/cmos.layout deleted file mode 100644 index d109a61b4e..0000000000 --- a/src/mainboard/lenovo/t430/cmos.layout +++ /dev/null @@ -1,108 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# RTC_BOOT_BYTE (coreboot hardcoded) -384 1 e 4 boot_option -388 4 h 0 reboot_counter - -# ----------------------------------------------------------------- -# coreboot config options: console -395 4 e 6 debug_level - -#400 8 r 0 reserved for century byte - -# coreboot config options: southbridge -408 1 e 1 nmi -409 2 e 7 power_on_after_fail - -# coreboot config options: EC -411 1 e 8 first_battery -412 1 e 1 bluetooth -413 1 e 1 wwan -414 1 e 1 touchpad -415 1 e 1 wlan -416 1 e 1 trackpoint -417 1 e 1 fn_ctrl_swap -418 1 e 1 sticky_fn -419 2 e 13 usb_always_on -421 1 e 9 sata_mode -422 2 e 10 backlight - -# coreboot config options: ME -424 1 e 14 me_state -425 2 h 0 me_state_prev - -# coreboot config options: northbridge -432 3 e 11 gfx_uma_size -435 2 e 12 hybrid_graphics_mode - -440 8 h 0 volume - -# VBOOT -448 128 r 0 vbnv - -# SandyBridge MRC Scrambler Seed values -896 32 r 0 mrc_scrambler_seed -928 32 r 0 mrc_scrambler_seed_s3 -960 16 r 0 mrc_scrambler_seed_chk - -# coreboot config options: check sums -984 16 h 0 check_sum - -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable -2 0 Enable -2 1 Disable -4 0 Fallback -4 1 Normal -6 0 Emergency -6 1 Alert -6 2 Critical -6 3 Error -6 4 Warning -6 5 Notice -6 6 Info -6 7 Debug -6 8 Spew -7 0 Disable -7 1 Enable -7 2 Keep -8 0 Secondary -8 1 Primary -9 0 AHCI -9 1 Compatible -10 0 Both -10 1 Keyboard only -10 2 Thinklight only -10 3 None -11 0 32M -11 1 64M -11 2 96M -11 3 128M -11 4 160M -11 5 192M -11 6 224M -12 0 Integrated Only -12 1 Discrete Only -12 2 Dual Graphics -13 0 Disable -13 1 AC and battery -13 2 AC only -14 0 Normal -14 1 Disabled - -# ----------------------------------------------------------------- -checksums - -checksum 392 447 984 diff --git a/src/mainboard/lenovo/t430/devicetree.cb b/src/mainboard/lenovo/t430/devicetree.cb deleted file mode 100644 index 198900b399..0000000000 --- a/src/mainboard/lenovo/t430/devicetree.cb +++ /dev/null @@ -1,166 +0,0 @@ -chip northbridge/intel/sandybridge - register "gfx" = "GMA_STATIC_DISPLAYS(1)" - - # Enable DisplayPort Hotplug with 6ms pulse - register "gpu_dp_d_hotplug" = "0x06" - - # Enable Panel as LVDS and configure power delays - register "gpu_panel_port_select" = "PANEL_PORT_LVDS" - register "gpu_panel_power_cycle_delay" = "6" # T7: 500ms - register "gpu_panel_power_up_delay" = "100" # T1+T2: 10ms - register "gpu_panel_power_down_delay" = "100" # T5+T6: 10ms - register "gpu_panel_power_backlight_on_delay" = "2100" # T3: 210ms - register "gpu_panel_power_backlight_off_delay" = "2100" # T4: 210ms - register "gpu_cpu_backlight" = "0x1155" - register "gpu_pch_backlight" = "0x11551155" - - register "spd_addresses" = "{0x50, 0, 0x51, 0}" - - device domain 0 on - subsystemid 0x17aa 0x21f3 inherit - - chip southbridge/intel/bd82x6x # Intel Series 6 Cougar Point PCH - register "docking_supported" = "true" - register "gen1_dec" = "0x000c15e1" - register "gen2_dec" = "0x007c1601" - register "gen3_dec" = "0x000c06a1" - register "gpi13_routing" = "2" - register "gpi1_routing" = "2" - register "pcie_hotplug_map" = "{ 0, 0, 1, 0, 0, 0, 0, 0 }" - register "pcie_port_coalesce" = "true" - register "sata_interface_speed_support" = "0x3" - register "sata_port_map" = "0x17" - - # Do not enable xHCI Port 4 since WWAN USB is EHCI-only - register "superspeed_capable_ports" = "0x7" - register "xhci_switchable_ports" = "0x7" - register "usb_port_config" = "{ - { 1, 1, 0 }, - { 1, 1, 1 }, - { 1, 2, 3 }, - { 1, 1, -1 }, - { 1, 1, 2 }, - { 1, 0, -1 }, - { 0, 0, -1 }, - { 1, 2, -1 }, - { 1, 0, -1 }, - { 1, 1, 5 }, - { 1, 0, -1 }, - { 1, 0, -1 }, - { 1, 3, -1 }, - { 1, 1, -1 } - }" - - # device specific SPI configuration - register "spi_uvscc" = "0x2005" - register "spi_lvscc" = "0x2005" - - device ref xhci on end # USB 3.0 Controller - device ref mei1 on end # Management Engine Interface 1 - device ref mei2 off end # Management Engine Interface 2 - device ref me_ide_r off end # Management Engine IDE-R - device ref me_kt off end # Management Engine KT - device ref gbe on end # Intel Gigabit Ethernet - device ref ehci2 on end # USB2 EHCI #2 - device ref hda on end # High Definition Audio controller - device ref pcie_rp1 on # PCIe Port #1 - chip drivers/ricoh/rce822 # Ricoh cardreader - register "disable_mask" = "0x87" - register "sdwppol" = "1" - device pci 00.0 on end # Ricoh SD card reader - end - end - device ref pcie_rp2 on end # PCIe Port #2 - device ref pcie_rp3 on # PCIe Port #3 - smbios_slot_desc "7" "3" "ExpressCard Slot" "8" - end - device ref pcie_rp4 off end # PCIe Port #4 - device ref pcie_rp5 off end # PCIe Port #5 - device ref pcie_rp6 off end # PCIe Port #6 - device ref pcie_rp7 off end # PCIe Port #7 - device ref pcie_rp8 off end # PCIe Port #8 - device ref ehci1 on end # USB2 EHCI #1 - device ref pci_bridge off end # PCI bridge - device ref lpc on # LPC bridge PCI-LPC bridge - chip ec/lenovo/pmh7 - register "backlight_enable" = "true" - register "dock_event_enable" = "true" - device pnp ff.1 on end # dummy - end - chip drivers/pc80/tpm - device pnp 0c31.0 on end - end - chip ec/lenovo/h8 - device pnp ff.2 on # dummy - io 0x60 = 0x62 - io 0x62 = 0x66 - io 0x64 = 0x1600 - io 0x66 = 0x1604 - end - register "config0" = "0xa7" - register "config1" = "0x01" - register "config2" = "0xa0" - register "config3" = "0xe2" - - register "has_keyboard_backlight" = "0" - - register "beepmask0" = "0x02" - register "beepmask1" = "0x86" - register "has_power_management_beeps" = "1" - register "event2_enable" = "0xff" - register "event3_enable" = "0xff" - register "event4_enable" = "0xf0" - register "event5_enable" = "0x3c" - register "event6_enable" = "0x00" - register "event7_enable" = "0xa1" - register "event8_enable" = "0x7b" - register "event9_enable" = "0xff" - register "eventa_enable" = "0x00" - register "eventb_enable" = "0x00" - register "eventc_enable" = "0xff" - register "eventd_enable" = "0xff" - register "evente_enable" = "0x0d" - - register "bdc_gpio_num" = "54" - register "bdc_gpio_lvl" = "0" - - register "wwan_gpio_num" = "70" - register "wwan_gpio_lvl" = "0" - end - chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy - - register "detect_gpio" = "21" - - register "has_panel_hybrid_gpio" = "true" - register "panel_hybrid_gpio" = "52" - register "panel_integrated_lvl" = "true" - - register "has_backlight_gpio" = "false" - register "has_dgpu_power_gpio" = "false" - - register "has_thinker1" = "true" - end - end - device ref sata1 on end # SATA Controller 1 - device ref smbus on # SMBus - chip drivers/i2c/at24rf08c # eeprom, 8 virtual devices, same chip - device i2c 54 on end - device i2c 55 on end - device i2c 56 on end - device i2c 57 on end - device i2c 5c on end - device i2c 5d on end - device i2c 5e on end - device i2c 5f on end - end - end - device ref sata2 off end # SATA Controller 2 - device ref thermal off end # Thermal - end - device ref host_bridge on end # Host bridge Host bridge - device ref peg10 on end # PCIe Bridge for discrete graphics - device ref igd on end # Internal graphics VGA controller - device ref dev4 off end # Signal processing controller - end -end diff --git a/src/mainboard/lenovo/t430/dsdt.asl b/src/mainboard/lenovo/t430/dsdt.asl deleted file mode 100644 index 1134782675..0000000000 --- a/src/mainboard/lenovo/t430/dsdt.asl +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#define THINKPAD_EC_GPE 17 -#define BRIGHTNESS_UP \_SB.PCI0.GFX0.INCB -#define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.DECB - -#include -DefinitionBlock( - "dsdt.aml", - "DSDT", - ACPI_DSDT_REV_2, - OEM_ID, - ACPI_TABLE_CREATOR, - 0x20110725 // OEM revision -) -{ - #include - #include - - #include "acpi/platform.asl" - - // global NVS and variables - #include - - #include - - Scope (\_SB) { - Device (PCI0) - { - #include - #include - - #include - } - } - - #include - #include -} diff --git a/src/mainboard/lenovo/t430/early_init.c b/src/mainboard/lenovo/t430/early_init.c deleted file mode 100644 index d982660856..0000000000 --- a/src/mainboard/lenovo/t430/early_init.c +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include - -static void hybrid_graphics_init(void) -{ - bool peg, igd; - u32 reg32; - - early_hybrid_graphics(&igd, &peg); - - if (peg && igd) - return; - - /* Hide disabled devices */ - reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN); - reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); - - if (peg) - reg32 |= DEVEN_PEG10; - - if (igd) - reg32 |= DEVEN_IGD; - else - /* Disable IGD VGA decode, no GTT or GFX stolen */ - pci_write_config16(PCI_DEV(0, 0, 0), GGC, 2); - - pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, reg32); -} - -void mainboard_early_init(bool s3resume) -{ - hybrid_graphics_init(); - lenovo_mainboard_eeprom_lock(); -} diff --git a/src/mainboard/lenovo/t430/gma-mainboard.ads b/src/mainboard/lenovo/t430/gma-mainboard.ads deleted file mode 100644 index 3df1e37f3e..0000000000 --- a/src/mainboard/lenovo/t430/gma-mainboard.ads +++ /dev/null @@ -1,22 +0,0 @@ --- SPDX-License-Identifier: GPL-2.0-or-later - -with HW.GFX.GMA; -with HW.GFX.GMA.Display_Probing; - -use HW.GFX.GMA; -use HW.GFX.GMA.Display_Probing; - -private package GMA.Mainboard is - - ports : constant Port_List := - (DP1, - DP2, - DP3, - HDMI1, - HDMI2, - HDMI3, - Analog, - LVDS, - others => Disabled); - -end GMA.Mainboard; diff --git a/src/mainboard/lenovo/t430/mainboard.c b/src/mainboard/lenovo/t430/mainboard.c deleted file mode 100644 index 50c944e341..0000000000 --- a/src/mainboard/lenovo/t430/mainboard.c +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -static void mainboard_enable(struct device *dev) -{ - install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS, - GMA_INT15_PANEL_FIT_DEFAULT, - GMA_INT15_BOOT_DISPLAY_DEFAULT, 0); -} - -struct chip_operations mainboard_ops = { - .enable_dev = mainboard_enable, -}; diff --git a/src/mainboard/lenovo/t430/smihandler.c b/src/mainboard/lenovo/t430/smihandler.c deleted file mode 100644 index 03c899e0d9..0000000000 --- a/src/mainboard/lenovo/t430/smihandler.c +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include - -#define GPE_EC_SCI 1 -#define GPE_EC_WAKE 13 - -static void mainboard_smi_handle_ec_sci(void) -{ - u8 status = inb(EC_SC); - u8 event; - - if (!(status & EC_SCI_EVT)) - return; - - event = ec_query(); - printk(BIOS_DEBUG, "EC event %#02x\n", event); -} - -void mainboard_smi_gpi(u32 gpi_sts) -{ - if (gpi_sts & (1 << GPE_EC_SCI)) - mainboard_smi_handle_ec_sci(); -} - -int mainboard_smi_apmc(u8 data) -{ - switch (data) { - case APM_CNT_ACPI_ENABLE: - /* use 0x1600/0x1604 to prevent races with userspace */ - ec_set_ports(0x1604, 0x1600); - /* route EC_SCI to SCI */ - gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SCI); - /* discard all events, and enable attention */ - ec_write(0x80, 0x01); - break; - case APM_CNT_ACPI_DISABLE: - /* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't - provide a EC query function */ - ec_set_ports(0x66, 0x62); - /* route EC_SCI to SMI */ - gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SMI); - /* discard all events, and enable attention */ - ec_write(0x80, 0x01); - break; - default: - break; - } - return 0; -} - -void mainboard_smi_sleep(u8 slp_typ) -{ - if (slp_typ == 3) { - u8 ec_wake = ec_read(0x32); - /* If EC wake events are enabled, enable wake on EC WAKE GPE. */ - if (ec_wake & 0x14) { - /* Redirect EC WAKE GPE to SCI. */ - gpi_route_interrupt(GPE_EC_WAKE, GPI_IS_SCI); - } - } -} diff --git a/src/mainboard/lenovo/t430/vboot-ro-me_clean.fmd b/src/mainboard/lenovo/t430/vboot-ro-me_clean.fmd deleted file mode 100644 index 5101caa59c..0000000000 --- a/src/mainboard/lenovo/t430/vboot-ro-me_clean.fmd +++ /dev/null @@ -1,21 +0,0 @@ -FLASH 0xc00000 { - SI_ALL 0x20000 { - SI_DESC 0x1000 - SI_GBE 0x2000 - SI_ME - } - SI_BIOS 0xbe0000 { - UNIFIED_MRC_CACHE 0x20000 { - RECOVERY_MRC_CACHE 0x10000 - RW_MRC_CACHE 0x10000 - } - - WP_RO { - FMAP 0x800 - RO_FRID 0x40 - RO_PADDING 0x7c0 - GBB 0x1e000 - COREBOOT(CBFS) - } - } -} diff --git a/src/mainboard/lenovo/t430/vboot-ro.fmd b/src/mainboard/lenovo/t430/vboot-ro.fmd deleted file mode 100644 index 027849bfe9..0000000000 --- a/src/mainboard/lenovo/t430/vboot-ro.fmd +++ /dev/null @@ -1,21 +0,0 @@ -FLASH 0xc00000 { - SI_ALL 0x500000 { - SI_DESC 0x1000 - SI_GBE 0x2000 - SI_ME - } - SI_BIOS 0x700000 { - UNIFIED_MRC_CACHE 0x20000 { - RECOVERY_MRC_CACHE 0x10000 - RW_MRC_CACHE 0x10000 - } - - WP_RO { - FMAP 0x800 - RO_FRID 0x40 - RO_PADDING 0x7c0 - GBB 0x1e000 - COREBOOT(CBFS) - } - } -} diff --git a/src/mainboard/lenovo/t430/vboot-rwab.fmd b/src/mainboard/lenovo/t430/vboot-rwab.fmd deleted file mode 100644 index 8819959dfe..0000000000 --- a/src/mainboard/lenovo/t430/vboot-rwab.fmd +++ /dev/null @@ -1,35 +0,0 @@ -FLASH 0xc00000 { - SI_ALL@0x0 0x500000 { - SI_DESC@0x0 0x1000 - SI_GBE@0x1000 0x2000 - SI_ME - } - SI_BIOS@0x500000 0x700000 { - RW_SECTION_A 0x280000 { - VBLOCK_A 0x10000 - FW_MAIN_A(CBFS) - RW_FWID_A 0x40 - } - RW_SECTION_B 0x280000 { - VBLOCK_B 0x10000 - FW_MAIN_B(CBFS) - RW_FWID_B 0x40 - } - UNIFIED_MRC_CACHE@0x500000 0x20000 { - RECOVERY_MRC_CACHE@0x0 0x10000 - RW_MRC_CACHE@0x10000 0x10000 - } - RW_VPD(PRESERVE) 0x1000 - SMMSTORE(PRESERVE)@0x521000 0x40000 - RW_NVRAM(PRESERVE)@0x561000 0x2000 - - WP_RO { - FMAP 0x800 - RO_FRID 0x40 - RO_PADDING 0x7c0 - RO_VPD(PRESERVE) 0x1000 - GBB 0x1e000 - COREBOOT(CBFS) - } - } -} diff --git a/src/mainboard/lenovo/t530/Kconfig b/src/mainboard/lenovo/t530/Kconfig index 8830c39301..4f0002f536 100644 --- a/src/mainboard/lenovo/t530/Kconfig +++ b/src/mainboard/lenovo/t530/Kconfig @@ -38,6 +38,10 @@ config BOARD_LENOVO_W530 select BOARD_LENOVO_BASEBOARD_T530 select DRIVERS_RICOH_RCE822 +config BOARD_LENOVO_T430 + select BOARD_LENOVO_BASEBOARD_T530 + select DRIVERS_RICOH_RCE822 + if BOARD_LENOVO_BASEBOARD_T530 config VBOOT @@ -60,6 +64,7 @@ config FMDFILE config VARIANT_DIR default "t530" if BOARD_LENOVO_T530 default "w530" if BOARD_LENOVO_W530 + default "t430" if BOARD_LENOVO_T430 config MAINBOARD_DIR default "lenovo/t530" @@ -70,6 +75,7 @@ config OVERRIDE_DEVICETREE config MAINBOARD_PART_NUMBER default "ThinkPad T530" if BOARD_LENOVO_T530 default "ThinkPad W530" if BOARD_LENOVO_W530 + default "ThinkPad T430" if BOARD_LENOVO_T430 config USBDEBUG_HCD_INDEX int @@ -84,6 +90,7 @@ config VGA_BIOS_ID default "8086,0166" config PS2K_EISAID + default "PNP0303" if BOARD_LENOVO_T430 default "LEN0071" config PS2M_EISAID diff --git a/src/mainboard/lenovo/t530/Kconfig.name b/src/mainboard/lenovo/t530/Kconfig.name index d8b1925f65..5b42bd2f89 100644 --- a/src/mainboard/lenovo/t530/Kconfig.name +++ b/src/mainboard/lenovo/t530/Kconfig.name @@ -5,3 +5,6 @@ config BOARD_LENOVO_T530 config BOARD_LENOVO_W530 bool "ThinkPad W530" + +config BOARD_LENOVO_T430 + bool "ThinkPad T430" diff --git a/src/mainboard/lenovo/t530/Makefile.mk b/src/mainboard/lenovo/t530/Makefile.mk index 69ef08873b..1c72bfe045 100644 --- a/src/mainboard/lenovo/t530/Makefile.mk +++ b/src/mainboard/lenovo/t530/Makefile.mk @@ -5,3 +5,4 @@ romstage-y += variants/$(VARIANT_DIR)/gpio.c ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads bootblock-y += early_init.c romstage-y += early_init.c +ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c diff --git a/src/mainboard/lenovo/t430/data.vbt b/src/mainboard/lenovo/t530/variants/t430/data.vbt similarity index 100% rename from src/mainboard/lenovo/t430/data.vbt rename to src/mainboard/lenovo/t530/variants/t430/data.vbt diff --git a/src/mainboard/lenovo/t430/gpio.c b/src/mainboard/lenovo/t530/variants/t430/gpio.c similarity index 100% rename from src/mainboard/lenovo/t430/gpio.c rename to src/mainboard/lenovo/t530/variants/t430/gpio.c diff --git a/src/mainboard/lenovo/t430/hda_verb.c b/src/mainboard/lenovo/t530/variants/t430/hda_verb.c similarity index 100% rename from src/mainboard/lenovo/t430/hda_verb.c rename to src/mainboard/lenovo/t530/variants/t430/hda_verb.c diff --git a/src/mainboard/lenovo/t530/variants/t430/overridetree.cb b/src/mainboard/lenovo/t530/variants/t430/overridetree.cb new file mode 100644 index 0000000000..72cc6b54e1 --- /dev/null +++ b/src/mainboard/lenovo/t530/variants/t430/overridetree.cb @@ -0,0 +1,58 @@ +chip northbridge/intel/sandybridge + register "gpu_panel_power_backlight_on_delay" = "2100" # T3: 210ms + register "gpu_panel_power_backlight_off_delay" = "2100" # T4: 210ms + + register "spd_addresses" = "{0x50, 0, 0x51, 0}" + device domain 0 on + subsystemid 0x17aa 0x21f3 inherit + chip southbridge/intel/bd82x6x # Intel Series 7 Panther Point PCH + register "sata_interface_speed_support" = "0x3" + register "sata_port_map" = "0x17" + + # Do not enable xHCI Port 4 since WWAN USB is EHCI-only + register "superspeed_capable_ports" = "0x7" + register "xhci_switchable_ports" = "0x7" + register "usb_port_config" = "{ + { 1, 1, 0 }, + { 1, 1, 1 }, + { 1, 2, 3 }, + { 1, 1, -1 }, + { 1, 1, 2 }, + { 1, 0, -1 }, + { 0, 0, -1 }, + { 1, 2, -1 }, + { 1, 0, -1 }, + { 1, 1, 5 }, + { 1, 0, -1 }, + { 1, 0, -1 }, + { 1, 3, -1 }, + { 1, 1, -1 } + }" + + device ref pcie_rp1 on # PCIe Port #1 + chip drivers/ricoh/rce822 # Ricoh cardreader + register "disable_mask" = "0x87" + register "sdwppol" = "1" + device pci 00.0 on end # Ricoh SD card reader + end + end + device ref lpc on + chip ec/lenovo/h8 + device pnp ff.2 on end # dummy + register "wwan_gpio_num" = "70" + register "wwan_gpio_lvl" = "0" + register "config1" = "0x01" + register "config3" = "0xe2" + register "has_keyboard_backlight" = "0" + register "beepmask0" = "0x02" + register "has_power_management_beeps" = "1" + register "event4_enable" = "0xf0" + register "event5_enable" = "0x3c" + register "event7_enable" = "0xa1" + register "eventa_enable" = "0x00" + end + end + device ref thermal off end # Thermal + end + end +end diff --git a/src/mainboard/lenovo/t530/hda_verb.c b/src/mainboard/lenovo/t530/variants/t530/hda_verb.c similarity index 100% rename from src/mainboard/lenovo/t530/hda_verb.c rename to src/mainboard/lenovo/t530/variants/t530/hda_verb.c diff --git a/src/mainboard/lenovo/t530/variants/w530/hda_verb.c b/src/mainboard/lenovo/t530/variants/w530/hda_verb.c new file mode 100644 index 0000000000..564aff2d77 --- /dev/null +++ b/src/mainboard/lenovo/t530/variants/w530/hda_verb.c @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Bits 31:28 - Codec Address */ +/* Bits 27:20 - NID */ +/* Bits 19:8 - Verb ID */ +/* Bits 7:0 - Payload */ + +#include + +const u32 cim_verb_data[] = { + 0x10ec0269, /* Codec Vendor / Device ID: Realtek ALC269VC */ + 0x17aa21fa, /* Subsystem ID */ + 18, /* Number of 4 dword sets */ + AZALIA_SUBVENDOR(0, 0x17aa21fa), + + /* Ext. Microphone Connector: External,Right; MicIn,3.5mm; Black,JD; DA,Seq */ + AZALIA_PIN_CFG(0, 0x0a, 0x04a11020), + + /* Headphones Connector: External,Right; HP,3.5mm; Black,JD; DA,Seq */ + AZALIA_PIN_CFG(0, 0x0b, 0x0421101f), + + /* Not connected: N/A,N/A; Other,Unknown; Unknown,JD; DA,Seq */ + AZALIA_PIN_CFG(0, 0x0c, 0x40f000f0), + + /* Internal Speakers Fixed,Int; Speaker,Other Analog; Unknown,nJD; DA,Seq */ + AZALIA_PIN_CFG(0, 0x0d, 0x90170110), + + /* Not connected */ + AZALIA_PIN_CFG(0, 0x0f, 0x40f000f0), + + /* Internal Microphone: Fixed,Int,Top; Mic In,ATIPI; Unknown,nJD; DA,Seq */ + AZALIA_PIN_CFG(0, 0x11, 0xd5a30140), + AZALIA_PIN_CFG(0, 0x12, 0x90a60140), + AZALIA_PIN_CFG(0, 0x14, 0x90170110), + AZALIA_PIN_CFG(0, 0x15, 0x03211020), + AZALIA_PIN_CFG(0, 0x18, 0x03a11830), + AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_CFG_NC(0)), + + 0x01970804, + 0x01870803, + 0x01470740, + 0x00970600, + + AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1d, 0x40138205), + AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), + + /* Misc entries */ + 0x00370600, + 0x00270600, + 0x00b707C0, /* Enable PortB as Output with HP amp */ + 0x00d70740, /* Enable PortD as Output */ + 0x0017a200, /* Disable ClkEn of PortSenseTst */ + 0x0017c621, /* Slave Port - Port A used as microphone input for + combo Jack + Master Port - Port B used for Jack Presence Detect + Enable Combo Jack Detection */ + 0x0017a208, /* Enable ClkEn of PortSenseTst */ + 0x00170500, /* Set power state to D0 */ + + /* --- Codec #3 --- */ + 0x80862806, /* Codec Vendor / Device ID: Intel PantherPoint HDMI */ + 0x80860101, /* Subsystem ID */ + 4, /* Number of 4 dword sets */ + AZALIA_SUBVENDOR(3, 0x80860101), + AZALIA_PIN_CFG(3, 0x05, 0x18560010), + AZALIA_PIN_CFG(3, 0x06, 0x18560020), + AZALIA_PIN_CFG(3, 0x07, 0x18560030), +}; + +const u32 pc_beep_verbs[] = { + 0x02177a00, /* Digital PCBEEP Gain: 0h=-9db, 1h=-6db ... 4h=+3db, 5h=+6db */ +}; + +AZALIA_ARRAY_SIZES; From 7847a54eed29d26696163d3ff4bb241221d21e5e Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 26 Feb 2026 14:44:39 +0100 Subject: [PATCH 640/789] mb/lenovo: Convert PNP device to generic device Convert the hybrid graphics mux into a generic device and give it an alias so that the driver can reference it by name. Change-Id: Icbf6f298cab9e11acc9363daba68f9fbc613e79d Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/91440 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/drivers/lenovo/hybrid_graphics/chip.h | 4 ---- src/drivers/lenovo/hybrid_graphics/romstage.c | 7 ++++--- src/mainboard/lenovo/t400/variants/t400/overridetree.cb | 2 +- src/mainboard/lenovo/t410/devicetree.cb | 2 +- src/mainboard/lenovo/t420/devicetree.cb | 2 +- src/mainboard/lenovo/t420s/devicetree.cb | 2 +- src/mainboard/lenovo/t520/devicetree.cb | 2 +- src/mainboard/lenovo/t530/devicetree.cb | 2 +- 8 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/drivers/lenovo/hybrid_graphics/chip.h b/src/drivers/lenovo/hybrid_graphics/chip.h index 4a17138552..81d3552e98 100644 --- a/src/drivers/lenovo/hybrid_graphics/chip.h +++ b/src/drivers/lenovo/hybrid_graphics/chip.h @@ -3,10 +3,6 @@ #ifndef _LENOVO_HYBRID_GRAPHICS_CHIP_H_ #define _LENOVO_HYBRID_GRAPHICS_CHIP_H_ -#define HYBRID_GRAPHICS_PORT 0xff - -#define HYBRID_GRAPHICS_DEVICE 0xf - enum hybrid_graphics_req { HYBRID_GRAPHICS_INTEGRATED = 0, HYBRID_GRAPHICS_DISCRETE = 1, diff --git a/src/drivers/lenovo/hybrid_graphics/romstage.c b/src/drivers/lenovo/hybrid_graphics/romstage.c index 10f94439f8..6860c958f3 100644 --- a/src/drivers/lenovo/hybrid_graphics/romstage.c +++ b/src/drivers/lenovo/hybrid_graphics/romstage.c @@ -5,11 +5,14 @@ #include #include #include +#include #include #include "hybrid_graphics.h" #include "chip.h" +WEAK_DEV_PTR(hg_mux); + /* * Returns the hybrid graphics presence and user's card preferences. */ @@ -19,9 +22,7 @@ void early_hybrid_graphics(bool *enable_igd, bool *enable_peg) const struct device *dev; enum hybrid_graphics_req mode; - /* TODO: Use generic device instead of dummy PNP device */ - dev = dev_find_slot_pnp(HYBRID_GRAPHICS_PORT, HYBRID_GRAPHICS_DEVICE); - + dev = DEV_PTR(hg_mux); if (!dev || !dev->chip_info) { printk(BIOS_ERR, "Hybrid graphics: ERROR\n"); *enable_igd = true; diff --git a/src/mainboard/lenovo/t400/variants/t400/overridetree.cb b/src/mainboard/lenovo/t400/variants/t400/overridetree.cb index c3c3b082a5..1e0c3fe100 100644 --- a/src/mainboard/lenovo/t400/variants/t400/overridetree.cb +++ b/src/mainboard/lenovo/t400/variants/t400/overridetree.cb @@ -4,7 +4,7 @@ chip northbridge/intel/gm45 device pci 1f.0 on # LPC bridge subsystemid 0x17aa 0x20f5 chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t410/devicetree.cb b/src/mainboard/lenovo/t410/devicetree.cb index 9ba70d79e8..d4af8253e6 100644 --- a/src/mainboard/lenovo/t410/devicetree.cb +++ b/src/mainboard/lenovo/t410/devicetree.cb @@ -134,7 +134,7 @@ chip northbridge/intel/ironlake register "evente_enable" = "0x2d" end chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t420/devicetree.cb b/src/mainboard/lenovo/t420/devicetree.cb index 37ac884eb3..4e4d4a0d8e 100644 --- a/src/mainboard/lenovo/t420/devicetree.cb +++ b/src/mainboard/lenovo/t420/devicetree.cb @@ -153,7 +153,7 @@ chip northbridge/intel/sandybridge register "bdc_gpio_lvl" = "0" end chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t420s/devicetree.cb b/src/mainboard/lenovo/t420s/devicetree.cb index 335e025c72..4ae67ec3f8 100644 --- a/src/mainboard/lenovo/t420s/devicetree.cb +++ b/src/mainboard/lenovo/t420s/devicetree.cb @@ -145,7 +145,7 @@ chip northbridge/intel/sandybridge register "bdc_gpio_lvl" = "0" end chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t520/devicetree.cb b/src/mainboard/lenovo/t520/devicetree.cb index 74605ca081..9456f85bd4 100644 --- a/src/mainboard/lenovo/t520/devicetree.cb +++ b/src/mainboard/lenovo/t520/devicetree.cb @@ -141,7 +141,7 @@ chip northbridge/intel/sandybridge register "bdc_gpio_lvl" = "0" end chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t530/devicetree.cb b/src/mainboard/lenovo/t530/devicetree.cb index 944de3dd49..3ca79999f1 100644 --- a/src/mainboard/lenovo/t530/devicetree.cb +++ b/src/mainboard/lenovo/t530/devicetree.cb @@ -121,7 +121,7 @@ chip northbridge/intel/sandybridge register "bdc_gpio_lvl" = "0" end chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" From c2eea0c96c6ea050396ab82049517afb0f6d87cc Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Thu, 26 Feb 2026 21:38:06 +0000 Subject: [PATCH 641/789] mainboard/starlabs/adl: add Bluetooth RTD3 CFR option Expose the existing bluetooth_rtd3 CFR option on ADL boards. BUG=None TEST=BUILD_TIMELESS=1 build BOARD_STARLABS_ADL_HORIZON Signed-off-by: Sean Rhodes Change-Id: I2d2f0abe6f9230f3744d3d7e100eda923b0aabc6 Reviewed-on: https://review.coreboot.org/c/coreboot/+/91447 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/adl/cfr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/starlabs/adl/cfr.c b/src/mainboard/starlabs/adl/cfr.c index 634f945f6e..43d064f90f 100644 --- a/src/mainboard/starlabs/adl/cfr.c +++ b/src/mainboard/starlabs/adl/cfr.c @@ -113,6 +113,7 @@ static struct sm_obj_form wireless_group = { .ui_name = "Wireless", .obj_list = (const struct sm_object *[]) { &bluetooth, + &bluetooth_rtd3, &wifi, NULL }, From ce5c91534485c8181425449a6c2a286076c6d18c Mon Sep 17 00:00:00 2001 From: Nicholas Chin Date: Tue, 24 Feb 2026 23:29:17 -0700 Subject: [PATCH 642/789] drivers/spi/flashconsole.c: Fix flashconsole Commit 1f2408f57300 ("console: Fix flushing for slow consoles") fixed a typo related to some refactoring of the CBMEM fast code path. However, this also seems to have indirectly broken the SPI flash console, causing only the console header messages at the beginning of each stage to be stored. This is caused by multiple calls to flashconsole_tx_flush() without a call to flashconsole_tx_byte() in between them. Data is accumulated in a buffer during calls to flashconsole_tx_byte(), which is then written to the flash during a flush. If no tx calls occur between flushes, the second call will try to write data of length 0, which seems to cause rdev_writeat() to return -1. This causes an early return, since the return value of rdev_writeat() must match the data length in order for the rest of the flashconsole_tx_flush to run. The flush function contains a busy flag to prevent recursive calls to itself, and the early return prevents it from being reset. Thus, the busy flag remains set for the remainder of the stage, blocking all future flushes. The multiple flushes occur because vprintk flushes console drivers after the string has been sent, but flashconsole_tx_byte() also calls a flush whenever a newline is encountered. Because of this, flushes are disabled for the remainder of each stage after the first printk call containing a newline is stored to the flash console. Although this newline check could be omitted, flashconsole_tx_byte() also invokes a flush when its data buffer is full, which shouldn't be avoided. Prior to the mentioned commit, the incorrect logic happened to prevent the flush in vprintk, preventing the double flush issue from occurring. The mentioned commit inverted the logic, allowing the double flush to occur. Address this by returning early if len = 0. While we're here, consolidate the early returns into a single check and change the busy flag to a bool instead of an int. TEST=Console messages are not missing in the flashconsole. Tested on the Lenovo ThinkCentre M900 SFF. Change-Id: Ic6c2418f04a687610df020df117f7be90b1724b9 Signed-off-by: Nicholas Chin Reviewed-on: https://review.coreboot.org/c/coreboot/+/91428 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Julius Werner --- src/drivers/spi/flashconsole.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/drivers/spi/flashconsole.c b/src/drivers/spi/flashconsole.c index 679c814dff..878cef0ce3 100644 --- a/src/drivers/spi/flashconsole.c +++ b/src/drivers/spi/flashconsole.c @@ -87,18 +87,20 @@ void flashconsole_tx_flush(void) { size_t len = line_offset; size_t region_size; - static int busy; /* Prevent any recursive loops in case the spi flash driver * calls printk (in case of transaction timeout or * any other error while writing) */ - if (busy) - return; + static bool busy; - if (!rdev_ptr) + /* In addition to being an obvious runtime optimization, checking for + * len = 0 also prevents false disabling of the driver, as rdev_writeat + * seems to return -1 if len is zero even though this should be a + * recoverable condition. */ + if (busy || !rdev_ptr || len == 0) return; - busy = 1; + busy = true; region_size = region_device_sz(rdev_ptr); if (offset + len >= region_size) len = region_size - offset; @@ -113,5 +115,5 @@ void flashconsole_tx_flush(void) offset += len; line_offset = 0; - busy = 0; + busy = false; } From e0c26a05d435f76005c05d0fac7d66ef9daf679d Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Thu, 26 Feb 2026 12:39:12 +0000 Subject: [PATCH 643/789] ec/starlabs/merlin: fix OSFG suspend comment OSFG is toggled from _PTS/_WAK via MPTS/MWAK and therefore runs for all supported sleep states. Update the suspend/resume comments to match the unguarded behavior. Signed-off-by: Sean Rhodes Change-Id: I613efd68ed2770798c2754a1c59f802f47986795 Reviewed-on: https://review.coreboot.org/c/coreboot/+/91439 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/ec/starlabs/merlin/acpi/suspend.asl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ec/starlabs/merlin/acpi/suspend.asl b/src/ec/starlabs/merlin/acpi/suspend.asl index 2039b34c47..966362f8a4 100644 --- a/src/ec/starlabs/merlin/acpi/suspend.asl +++ b/src/ec/starlabs/merlin/acpi/suspend.asl @@ -66,7 +66,7 @@ Method (RPTS, 1, Serialized) /* * Disable ACPI support. - * This should always be the last action before entering S4 or S5. + * This should always be the last action before entering a sleep state. */ \_SB.PCI0.LPCB.EC.ECWR(0x00, RefOf(\_SB.PCI0.LPCB.EC.OSFG)) } @@ -75,7 +75,7 @@ Method (RWAK, 1, Serialized) { /* * Enable ACPI support. - * This should always be the first action when exiting S4 or S5. + * This should always be the first action when exiting a sleep state. */ \_SB.PCI0.LPCB.EC.ECWR(0x01, RefOf(\_SB.PCI0.LPCB.EC.OSFG)) From 50e92c9cf11226e9c7be14fade8d0d88d03125dc Mon Sep 17 00:00:00 2001 From: Tom Hiller Date: Thu, 4 Dec 2025 19:54:36 -0500 Subject: [PATCH 644/789] mb/lenovo/m920q: Rename to reflect use for m720q variant as well The m920q and m720q are the same board, so rename the m920q to reflect that Change-Id: Ieef22530207ad4c35ac3cb4255d2ad65e62b65bf Signed-off-by: Tom Hiller Reviewed-on: https://review.coreboot.org/c/coreboot/+/90374 Reviewed-by: Evie (Ivi) Ballou Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/lenovo/{m920q => m720q_m920q}/Kconfig | 10 ++++++---- .../lenovo/{m920q => m720q_m920q}/Kconfig.name | 3 +++ .../lenovo/{m920q => m720q_m920q}/Makefile.mk | 0 .../lenovo/{m920q => m720q_m920q}/acpi/ec.asl | 0 .../{m920q => m720q_m920q}/acpi/mainboard.asl | 0 .../lenovo/{m920q => m720q_m920q}/acpi/superio.asl | 0 .../lenovo/{m920q => m720q_m920q}/board_info.txt | 4 ++-- .../lenovo/{m920q => m720q_m920q}/bootblock.c | 0 .../lenovo/{m920q => m720q_m920q}/cmos.default | 0 .../lenovo/{m920q => m720q_m920q}/cmos.layout | 0 .../lenovo/{m920q => m720q_m920q}/data.vbt | Bin .../lenovo/{m920q => m720q_m920q}/devicetree.cb | 0 .../lenovo/{m920q => m720q_m920q}/dsdt.asl | 0 .../lenovo/{m920q => m720q_m920q}/gma-mainboard.ads | 0 src/mainboard/lenovo/{m920q => m720q_m920q}/gpio.c | 0 .../lenovo/{m920q => m720q_m920q}/hda_verb.c | 0 .../{m920q => m720q_m920q}/include/mainboard/gpio.h | 0 .../lenovo/{m920q => m720q_m920q}/ramstage.c | 0 .../lenovo/{m920q => m720q_m920q}/romstage.c | 0 19 files changed, 11 insertions(+), 6 deletions(-) rename src/mainboard/lenovo/{m920q => m720q_m920q}/Kconfig (68%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/Kconfig.name (62%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/Makefile.mk (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/acpi/ec.asl (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/acpi/mainboard.asl (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/acpi/superio.asl (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/board_info.txt (51%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/bootblock.c (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/cmos.default (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/cmos.layout (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/data.vbt (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/devicetree.cb (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/dsdt.asl (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/gma-mainboard.ads (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/gpio.c (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/hda_verb.c (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/include/mainboard/gpio.h (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/ramstage.c (100%) rename src/mainboard/lenovo/{m920q => m720q_m920q}/romstage.c (100%) diff --git a/src/mainboard/lenovo/m920q/Kconfig b/src/mainboard/lenovo/m720q_m920q/Kconfig similarity index 68% rename from src/mainboard/lenovo/m920q/Kconfig rename to src/mainboard/lenovo/m720q_m920q/Kconfig index 53d74b821a..40641c211f 100644 --- a/src/mainboard/lenovo/m920q/Kconfig +++ b/src/mainboard/lenovo/m720q_m920q/Kconfig @@ -1,11 +1,12 @@ # SPDX-License-Identifier: GPL-2.0-only -if BOARD_LENOVO_M920Q +if BOARD_LENOVO_M920Q || BOARD_LENOVO_M720Q config BOARD_SPECIFIC_OPTIONS def_bool y select AZALIA_USE_LEGACY_VERB_TABLE - select BOARD_ROMSIZE_KB_24576 + select BOARD_ROMSIZE_KB_16384 if BOARD_LENOVO_M720Q + select BOARD_ROMSIZE_KB_24576 if BOARD_LENOVO_M920Q select DRIVERS_UART_8250IO select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES @@ -22,10 +23,11 @@ config BOARD_SPECIFIC_OPTIONS select SUPERIO_NUVOTON_NCT6687D config MAINBOARD_DIR - default "lenovo/m920q" + default "lenovo/m720q_m920q" config MAINBOARD_PART_NUMBER - default "ThinkCentre M920 Tiny" + default "ThinkCentre M720 Tiny" if BOARD_LENOVO_M720Q + default "ThinkCentre M920 Tiny" if BOARD_LENOVO_M920Q config CBFS_SIZE default 0x900000 diff --git a/src/mainboard/lenovo/m920q/Kconfig.name b/src/mainboard/lenovo/m720q_m920q/Kconfig.name similarity index 62% rename from src/mainboard/lenovo/m920q/Kconfig.name rename to src/mainboard/lenovo/m720q_m920q/Kconfig.name index ccdd21a237..6f5110366a 100644 --- a/src/mainboard/lenovo/m920q/Kconfig.name +++ b/src/mainboard/lenovo/m720q_m920q/Kconfig.name @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only +config BOARD_LENOVO_M720Q + bool "ThinkCentre M720 Tiny" + config BOARD_LENOVO_M920Q bool "ThinkCentre M920 Tiny" diff --git a/src/mainboard/lenovo/m920q/Makefile.mk b/src/mainboard/lenovo/m720q_m920q/Makefile.mk similarity index 100% rename from src/mainboard/lenovo/m920q/Makefile.mk rename to src/mainboard/lenovo/m720q_m920q/Makefile.mk diff --git a/src/mainboard/lenovo/m920q/acpi/ec.asl b/src/mainboard/lenovo/m720q_m920q/acpi/ec.asl similarity index 100% rename from src/mainboard/lenovo/m920q/acpi/ec.asl rename to src/mainboard/lenovo/m720q_m920q/acpi/ec.asl diff --git a/src/mainboard/lenovo/m920q/acpi/mainboard.asl b/src/mainboard/lenovo/m720q_m920q/acpi/mainboard.asl similarity index 100% rename from src/mainboard/lenovo/m920q/acpi/mainboard.asl rename to src/mainboard/lenovo/m720q_m920q/acpi/mainboard.asl diff --git a/src/mainboard/lenovo/m920q/acpi/superio.asl b/src/mainboard/lenovo/m720q_m920q/acpi/superio.asl similarity index 100% rename from src/mainboard/lenovo/m920q/acpi/superio.asl rename to src/mainboard/lenovo/m720q_m920q/acpi/superio.asl diff --git a/src/mainboard/lenovo/m920q/board_info.txt b/src/mainboard/lenovo/m720q_m920q/board_info.txt similarity index 51% rename from src/mainboard/lenovo/m920q/board_info.txt rename to src/mainboard/lenovo/m720q_m920q/board_info.txt index 02e3e322eb..8420ecc448 100644 --- a/src/mainboard/lenovo/m920q/board_info.txt +++ b/src/mainboard/lenovo/m720q_m920q/board_info.txt @@ -1,7 +1,7 @@ Category: desktop -Board URL: https://psref.lenovo.com/Product/ThinkCentre_M920_Tiny +Board URL: ThinkCentre M720q/M920q ROM package: SOIC-8 ROM protocol: SPI ROM socketed: n Flashrom support: y -Release year: 2021 +Release year: 2018 diff --git a/src/mainboard/lenovo/m920q/bootblock.c b/src/mainboard/lenovo/m720q_m920q/bootblock.c similarity index 100% rename from src/mainboard/lenovo/m920q/bootblock.c rename to src/mainboard/lenovo/m720q_m920q/bootblock.c diff --git a/src/mainboard/lenovo/m920q/cmos.default b/src/mainboard/lenovo/m720q_m920q/cmos.default similarity index 100% rename from src/mainboard/lenovo/m920q/cmos.default rename to src/mainboard/lenovo/m720q_m920q/cmos.default diff --git a/src/mainboard/lenovo/m920q/cmos.layout b/src/mainboard/lenovo/m720q_m920q/cmos.layout similarity index 100% rename from src/mainboard/lenovo/m920q/cmos.layout rename to src/mainboard/lenovo/m720q_m920q/cmos.layout diff --git a/src/mainboard/lenovo/m920q/data.vbt b/src/mainboard/lenovo/m720q_m920q/data.vbt similarity index 100% rename from src/mainboard/lenovo/m920q/data.vbt rename to src/mainboard/lenovo/m720q_m920q/data.vbt diff --git a/src/mainboard/lenovo/m920q/devicetree.cb b/src/mainboard/lenovo/m720q_m920q/devicetree.cb similarity index 100% rename from src/mainboard/lenovo/m920q/devicetree.cb rename to src/mainboard/lenovo/m720q_m920q/devicetree.cb diff --git a/src/mainboard/lenovo/m920q/dsdt.asl b/src/mainboard/lenovo/m720q_m920q/dsdt.asl similarity index 100% rename from src/mainboard/lenovo/m920q/dsdt.asl rename to src/mainboard/lenovo/m720q_m920q/dsdt.asl diff --git a/src/mainboard/lenovo/m920q/gma-mainboard.ads b/src/mainboard/lenovo/m720q_m920q/gma-mainboard.ads similarity index 100% rename from src/mainboard/lenovo/m920q/gma-mainboard.ads rename to src/mainboard/lenovo/m720q_m920q/gma-mainboard.ads diff --git a/src/mainboard/lenovo/m920q/gpio.c b/src/mainboard/lenovo/m720q_m920q/gpio.c similarity index 100% rename from src/mainboard/lenovo/m920q/gpio.c rename to src/mainboard/lenovo/m720q_m920q/gpio.c diff --git a/src/mainboard/lenovo/m920q/hda_verb.c b/src/mainboard/lenovo/m720q_m920q/hda_verb.c similarity index 100% rename from src/mainboard/lenovo/m920q/hda_verb.c rename to src/mainboard/lenovo/m720q_m920q/hda_verb.c diff --git a/src/mainboard/lenovo/m920q/include/mainboard/gpio.h b/src/mainboard/lenovo/m720q_m920q/include/mainboard/gpio.h similarity index 100% rename from src/mainboard/lenovo/m920q/include/mainboard/gpio.h rename to src/mainboard/lenovo/m720q_m920q/include/mainboard/gpio.h diff --git a/src/mainboard/lenovo/m920q/ramstage.c b/src/mainboard/lenovo/m720q_m920q/ramstage.c similarity index 100% rename from src/mainboard/lenovo/m920q/ramstage.c rename to src/mainboard/lenovo/m720q_m920q/ramstage.c diff --git a/src/mainboard/lenovo/m920q/romstage.c b/src/mainboard/lenovo/m720q_m920q/romstage.c similarity index 100% rename from src/mainboard/lenovo/m920q/romstage.c rename to src/mainboard/lenovo/m720q_m920q/romstage.c From 69242d5bb10e014c6c80bfb489e9574cab0db931 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Thu, 26 Feb 2026 12:37:55 -0600 Subject: [PATCH 645/789] drivers/usb/acpi: Add DSM function 3 support for Intel Bluetooth The Linux btintel driver requires DSM function 3 (DSM_SET_RESET_METHOD) to be supported before it will use the ACPI _PRR/_RST reset path. Without it, the driver falls back to GPIO or USB reset. Add set_reset_method callback that returns success. coreboot only supports WDISABLE2 (GPIO); the _RST method already implements the toggle. Update the capability buffer (0x03 -> 0x0b) to advertise function 3 support. Change RDLY default from 105 to 160 ms to match the Linux driver. Change-Id: I6a7c9289dcffbbbd769ab3fb4e59765d2fef7598 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/91445 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- src/drivers/usb/acpi/intel_bluetooth.c | 32 ++++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/drivers/usb/acpi/intel_bluetooth.c b/src/drivers/usb/acpi/intel_bluetooth.c index 2ccb13bfe8..151f2bb18c 100644 --- a/src/drivers/usb/acpi/intel_bluetooth.c +++ b/src/drivers/usb/acpi/intel_bluetooth.c @@ -14,16 +14,20 @@ * * Arg2 == 1: Set the reset delay based on Arg3 * - * Arg2 == 3: Set the reset method based on Arg3 (Not supported by this driver) - * WDISABLE2 (BT_RF_KILL_N) - * VSEC (PCI Config Space) + * Arg2 == 2: Reserved + * + * Arg2 == 3: Set the reset method based on Arg3 (required by Linux driver) + * Arg3 is a 4-byte buffer: [0x01, 0x00, type, 0x00] + * type 0 = WDISABLE2 (BT_RF_KILL_N) - supported by this driver + * type 1 = VSEC (PCI Config Space) - not supported */ static void check_reset_delay(void *arg) { acpigen_write_if_lequal_op_int(ARG1_OP, 0); { - acpigen_write_return_singleton_buffer(0x03); + /* Bits 0, 1, 3: other funcs, reset timing, set reset method (Linux) */ + acpigen_write_return_singleton_buffer(0x0b); } acpigen_write_else(); { @@ -37,12 +41,26 @@ static void set_reset_delay(void *arg) acpigen_write_store_op_to_namestr(ARG3_OP, "RDLY"); } +static void set_reset_method(void *arg) +{ + /* + * coreboot only supports WDISABLE2 (GPIO). Linux sends type in Arg3[2]. + * Accept and return success - _RST already implements GPIO toggle. + */ + acpigen_write_return_singleton_buffer(0x01); +} + static void not_supported(void *arg) { acpigen_write_return_singleton_buffer(0x00); } -void (*reset_supported[])(void *) = { check_reset_delay, set_reset_delay }; +void (*reset_supported[])(void *) = { + check_reset_delay, /* 0: capability query */ + set_reset_delay, /* 1: set delay */ + not_supported, /* 2: reserved */ + set_reset_method, /* 3: set reset method (required by Linux) */ +}; void (*reset_unsupported[])(void *) = { not_supported }; void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, @@ -55,9 +73,9 @@ void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, acpigen_write_name_integer("_S0W", ACPI_DEVICE_SLEEP_D2); /* - * Name (RDLY, 0x69) + * Name (RDLY, 160) // ms, matches Linux driver default */ - acpigen_write_name_integer("RDLY", 0x69); + acpigen_write_name_integer("RDLY", 160); /* * Method (_DSM, 4, Serialized) From f8494fbeae6bdde1b2f5bf1d93e9c7a2be79354b Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Sun, 15 Feb 2026 21:12:13 +0000 Subject: [PATCH 646/789] lib: Add devtree_update bootstate hook Provide a weak devtree_update() hook and invoke it early in ramstage at BS_PRE_DEVICE. Mainboards can override devtree_update() to enable/disable devices at runtime based on CMOS/NVRAM settings. Signed-off-by: Sean Rhodes Change-Id: Ic84ddb25e1da050543c230ea457042b8a8a3061f Reviewed-on: https://review.coreboot.org/c/coreboot/+/91250 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Angel Pons --- src/include/devtree_update.h | 14 ++++++++++++++ src/lib/Makefile.mk | 1 + src/lib/devtree_update.c | 16 ++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 src/include/devtree_update.h create mode 100644 src/lib/devtree_update.c diff --git a/src/include/devtree_update.h b/src/include/devtree_update.h new file mode 100644 index 0000000000..b99b689b99 --- /dev/null +++ b/src/include/devtree_update.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __DEVTREE_UPDATE_H__ +#define __DEVTREE_UPDATE_H__ + +/* + * Optional mainboard hook to update devicetree runtime enable/disable state + * based on CMOS/NVRAM settings. + * + * This function is called early in ramstage at BS_PRE_DEVICE. + */ +void devtree_update(void); + +#endif /* __DEVTREE_UPDATE_H__ */ diff --git a/src/lib/Makefile.mk b/src/lib/Makefile.mk index 3ffdfa807c..0dc41ce921 100644 --- a/src/lib/Makefile.mk +++ b/src/lib/Makefile.mk @@ -155,6 +155,7 @@ ramstage-$(CONFIG_BOOTSPLASH) += bootsplash.c ramstage-$(CONFIG_BOOTSPLASH) += jpeg.c ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c ramstage-$(CONFIG_COVERAGE) += libgcov.c +ramstage-y += devtree_update.c ramstage-y += dp_aux.c ramstage-y += framebuffer_info.c ramstage-y += edid.c diff --git a/src/lib/devtree_update.c b/src/lib/devtree_update.c new file mode 100644 index 0000000000..1b454a2580 --- /dev/null +++ b/src/lib/devtree_update.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +__weak void devtree_update(void) +{ +} + +static void run_devtree_update(void *unused) +{ + devtree_update(); +} + +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, run_devtree_update, NULL); From 7bee4f5efbcad847e175e83c192017a4eec48bce Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Sun, 15 Feb 2026 21:13:00 +0000 Subject: [PATCH 647/789] mb/starlabs: Drop explicit devtree_update calls devtree_update() is invoked automatically at BS_PRE_DEVICE. Remove the per-board init_mainboard() calls and associated includes. Signed-off-by: Sean Rhodes Change-Id: Ifb44080dc2e785a8554f5404902540daa9e872d1 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90990 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/byte_adl/mainboard.c | 3 --- src/mainboard/starlabs/lite/mainboard.c | 2 -- src/mainboard/starlabs/starbook/mainboard.c | 2 -- src/mainboard/starlabs/starfighter/mainboard.c | 3 --- src/mainboard/starlabs/starlite_adl/mainboard.c | 12 +++--------- 5 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/mainboard/starlabs/byte_adl/mainboard.c b/src/mainboard/starlabs/byte_adl/mainboard.c index 60e65ee8c4..cd46529c0f 100644 --- a/src/mainboard/starlabs/byte_adl/mainboard.c +++ b/src/mainboard/starlabs/byte_adl/mainboard.c @@ -2,7 +2,6 @@ #include #include -#include #include static void init_mainboard(void *chip_info) @@ -12,8 +11,6 @@ static void init_mainboard(void *chip_info) pads = variant_gpio_table(&num); gpio_configure_pads(pads, num); - - devtree_update(); } struct chip_operations mainboard_ops = { diff --git a/src/mainboard/starlabs/lite/mainboard.c b/src/mainboard/starlabs/lite/mainboard.c index 04537094d0..cd46529c0f 100644 --- a/src/mainboard/starlabs/lite/mainboard.c +++ b/src/mainboard/starlabs/lite/mainboard.c @@ -11,8 +11,6 @@ static void init_mainboard(void *chip_info) pads = variant_gpio_table(&num); gpio_configure_pads(pads, num); - - devtree_update(); } struct chip_operations mainboard_ops = { diff --git a/src/mainboard/starlabs/starbook/mainboard.c b/src/mainboard/starlabs/starbook/mainboard.c index 772e32cc1c..f392ed8759 100644 --- a/src/mainboard/starlabs/starbook/mainboard.c +++ b/src/mainboard/starlabs/starbook/mainboard.c @@ -13,8 +13,6 @@ static void init_mainboard(void *chip_info) pads = variant_gpio_table(&num); gpio_configure_pads(pads, num); - - devtree_update(); } struct chip_operations mainboard_ops = { diff --git a/src/mainboard/starlabs/starfighter/mainboard.c b/src/mainboard/starlabs/starfighter/mainboard.c index 60e65ee8c4..cd46529c0f 100644 --- a/src/mainboard/starlabs/starfighter/mainboard.c +++ b/src/mainboard/starlabs/starfighter/mainboard.c @@ -2,7 +2,6 @@ #include #include -#include #include static void init_mainboard(void *chip_info) @@ -12,8 +11,6 @@ static void init_mainboard(void *chip_info) pads = variant_gpio_table(&num); gpio_configure_pads(pads, num); - - devtree_update(); } struct chip_operations mainboard_ops = { diff --git a/src/mainboard/starlabs/starlite_adl/mainboard.c b/src/mainboard/starlabs/starlite_adl/mainboard.c index b82e2c0eba..1583ad9094 100644 --- a/src/mainboard/starlabs/starlite_adl/mainboard.c +++ b/src/mainboard/starlabs/starlite_adl/mainboard.c @@ -3,7 +3,6 @@ #include #include #include -#include #include static void init_mainboard(void *chip_info) @@ -13,18 +12,13 @@ static void init_mainboard(void *chip_info) pads = variant_gpio_table(&num); gpio_configure_pads(pads, num); - - devtree_update(); } static void mainboard_fill_ssdt(const struct device *dev) { - enum ps2_action_key ps2_action_keys[2] = { - PS2_KEY_VOL_DOWN, - PS2_KEY_VOL_UP - }; - acpigen_ps2_keyboard_dsd("_SB.PCI0.PS2K", ARRAY_SIZE(ps2_action_keys), - ps2_action_keys, false, false, false, false, false); + enum ps2_action_key ps2_action_keys[2] = {PS2_KEY_VOL_DOWN, PS2_KEY_VOL_UP}; + acpigen_ps2_keyboard_dsd("_SB.PCI0.PS2K", ARRAY_SIZE(ps2_action_keys), ps2_action_keys, + false, false, false, false, false); } static void enable_mainboard(struct device *dev) From 74d4fac21048dac022914f2744bc8b63624448c4 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:16:06 -0800 Subject: [PATCH 648/789] soc/intel/common/feature/soundwire: Add common SoundWire driver Add a common implementation of soc_fill_soundwire_controller() to reduce code duplication across multiple Intel SoC platforms. This implementation consolidates identical SoundWire link configuration code from Alder Lake, Meteor Lake, Panther Lake, and Tiger Lake platforms. The common driver uses platform-specific Kconfig options: - SOC_SOUNDWIRE_ACPI_ADDRESS: ACPI address for the controller (default 0x40000000) - SOC_SOUNDWIRE_MASTER_COUNT: Number of SoundWire master links (default 4) Platforms can override these defaults in their Kconfig if needed. This change enables consolidation of nearly identical soundwire.c files across four platforms, reducing duplication by approximately 210 lines. Change-Id: I5e188b0b60da91a33cf0325caefbbcabef0ebcba Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91276 Reviewed-by: Huang, Cliff Tested-by: build bot (Jenkins) --- .../intel/common/feature/soundwire/Kconfig | 24 +++++++ .../common/feature/soundwire/Makefile.mk | 3 + .../common/feature/soundwire/soundwire.c | 71 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 src/soc/intel/common/feature/soundwire/Kconfig create mode 100644 src/soc/intel/common/feature/soundwire/Makefile.mk create mode 100644 src/soc/intel/common/feature/soundwire/soundwire.c diff --git a/src/soc/intel/common/feature/soundwire/Kconfig b/src/soc/intel/common/feature/soundwire/Kconfig new file mode 100644 index 0000000000..c53b0e39b8 --- /dev/null +++ b/src/soc/intel/common/feature/soundwire/Kconfig @@ -0,0 +1,24 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_SOUNDWIRE + bool + help + Intel Processor Common SoundWire support. This provides a common + implementation of soc_fill_soundwire_controller() for platforms + that use the same SoundWire link configuration. The platform must + define SOC_SOUNDWIRE_ACPI_ADDRESS and SOC_SOUNDWIRE_MASTER_COUNT + in their Kconfig. + +config SOC_SOUNDWIRE_ACPI_ADDRESS + hex + default 0x40000000 + depends on SOC_INTEL_COMMON_FEATURE_SOUNDWIRE + help + ACPI address for the SoundWire controller. + +config SOC_SOUNDWIRE_MASTER_COUNT + int + default 4 + depends on SOC_INTEL_COMMON_FEATURE_SOUNDWIRE + help + Number of SoundWire master interfaces supported by the platform. diff --git a/src/soc/intel/common/feature/soundwire/Makefile.mk b/src/soc/intel/common/feature/soundwire/Makefile.mk new file mode 100644 index 0000000000..a668fdbaa9 --- /dev/null +++ b/src/soc/intel/common/feature/soundwire/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_SOC_INTEL_COMMON_FEATURE_SOUNDWIRE) += soundwire.c diff --git a/src/soc/intel/common/feature/soundwire/soundwire.c b/src/soc/intel/common/feature/soundwire/soundwire.c new file mode 100644 index 0000000000..d9528df1a7 --- /dev/null +++ b/src/soc/intel/common/feature/soundwire/soundwire.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct soundwire_link link_xtal_38_4 = { + .clock_stop_mode0_supported = 1, + .clock_stop_mode1_supported = 1, + .clock_frequencies_supported_count = 1, + .clock_frequencies_supported = { 4800 * KHz }, + .default_frame_rate = 48 * KHz, + .default_frame_row_size = 50, + .default_frame_col_size = 4, + .dynamic_frame_shape = 1, + .command_error_threshold = 16, +}; + +static const struct soundwire_link link_xtal_24 = { + .clock_stop_mode0_supported = 1, + .clock_stop_mode1_supported = 1, + .clock_frequencies_supported_count = 1, + .clock_frequencies_supported = { 6 * MHz }, + .default_frame_rate = 48 * KHz, + .default_frame_row_size = 125, + .default_frame_col_size = 2, + .dynamic_frame_shape = 1, + .command_error_threshold = 16, +}; + +static struct intel_soundwire_controller intel_controller = { + .acpi_address = CONFIG_SOC_SOUNDWIRE_ACPI_ADDRESS, + .sdw = { + .master_list_count = CONFIG_SOC_SOUNDWIRE_MASTER_COUNT + } +}; + +int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller) +{ + const struct soundwire_link *link; + enum pch_pmc_xtal xtal = pmc_get_xtal_freq(); + size_t i; + + /* Select link config based on XTAL frequency and set IP clock. */ + switch (xtal) { + case XTAL_24_MHZ: + link = &link_xtal_24; + intel_controller.ip_clock = 24 * MHz; + break; + case XTAL_38_4_MHZ: + link = &link_xtal_38_4; + intel_controller.ip_clock = 38400 * KHz; + break; + case XTAL_19_2_MHZ: + default: + printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal); + return -1; + } + + /* Fill link config in controller map based on selected XTAL. */ + for (i = 0; i < intel_controller.sdw.master_list_count; i++) + memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link)); + + *controller = &intel_controller; + return 0; +} From ef364d623d06c12858acb321e1e81c6f25cdc068 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:16:31 -0800 Subject: [PATCH 649/789] soc/intel/alderlake: Use common SoundWire driver Migrate Alder Lake to use the common SoundWire driver implementation from the Intel common feature code. This change eliminates platform- specific code by leveraging the shared soundwire.c driver. This commit: - Selects SOC_INTEL_COMMON_FEATURE_SOUNDWIRE Kconfig - Removes src/soc/intel/alderlake/soundwire.c - Updates Makefile to remove soundwire.c compilation Alder Lake uses the default values (4 SoundWire master links with ACPI address 0x40000000). Change-Id: Idf21d32d0cab9e3c6ca35e2b9f20c42c0455b5bb Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91277 Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/alderlake/Kconfig | 1 + src/soc/intel/alderlake/Makefile.mk | 1 - src/soc/intel/alderlake/soundwire.c | 71 ----------------------------- 3 files changed, 1 insertion(+), 72 deletions(-) delete mode 100644 src/soc/intel/alderlake/soundwire.c diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 52c3d84dca..be44a9eabb 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -86,6 +86,7 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index f287e91322..5d604a994a 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -35,7 +35,6 @@ ramstage-y += pcie_rp.c ramstage-y += pmc.c ramstage-y += reset.c ramstage-$(CONFIG_SOC_INTEL_ALDERLAKE_TCSS_USB4_SUPPORT) += retimer.c -ramstage-y += soundwire.c ramstage-y += systemagent.c ramstage-y += tcss.c ramstage-y += vr_config.c diff --git a/src/soc/intel/alderlake/soundwire.c b/src/soc/intel/alderlake/soundwire.c deleted file mode 100644 index 1fbdb4418e..0000000000 --- a/src/soc/intel/alderlake/soundwire.c +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static const struct soundwire_link link_xtal_38_4 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 4800 * KHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 50, - .default_frame_col_size = 4, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static const struct soundwire_link link_xtal_24 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 6 * MHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 125, - .default_frame_col_size = 2, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static struct intel_soundwire_controller intel_controller = { - .acpi_address = 0x40000000, - .sdw = { - .master_list_count = 4 - } -}; - -int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller) -{ - const struct soundwire_link *link; - enum pch_pmc_xtal xtal = pmc_get_xtal_freq(); - size_t i; - - /* Select link config based on XTAL frequency and set IP clock. */ - switch (xtal) { - case XTAL_24_MHZ: - link = &link_xtal_24; - intel_controller.ip_clock = 24 * MHz; - break; - case XTAL_38_4_MHZ: - link = &link_xtal_38_4; - intel_controller.ip_clock = 38400 * KHz; - break; - case XTAL_19_2_MHZ: - default: - printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal); - return -1; - } - - /* Fill link config in controller map based on selected XTAL. */ - for (i = 0; i < intel_controller.sdw.master_list_count; i++) - memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link)); - - *controller = &intel_controller; - return 0; -} From ffc67b2938b494271738b49b86577ef280a893bc Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:16:49 -0800 Subject: [PATCH 650/789] soc/intel/meteorlake: Use common SoundWire driver Migrate Meteor Lake to use the common SoundWire driver implementation from the Intel common feature code. This change eliminates platform- specific code by leveraging the shared soundwire.c driver. This commit: - Selects SOC_INTEL_COMMON_FEATURE_SOUNDWIRE Kconfig - Removes src/soc/intel/meteorlake/soundwire.c - Updates Makefile to remove soundwire.c compilation Meteor Lake uses the default values (4 SoundWire master links with ACPI address 0x40000000). Change-Id: Ib6d412b22cce78caf56ca2d09fcf74e57f54d09c Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91278 Reviewed-by: Huang, Cliff Tested-by: build bot (Jenkins) --- src/soc/intel/meteorlake/Kconfig | 1 + src/soc/intel/meteorlake/Makefile.mk | 1 - src/soc/intel/meteorlake/soundwire.c | 72 ---------------------------- 3 files changed, 1 insertion(+), 73 deletions(-) delete mode 100644 src/soc/intel/meteorlake/soundwire.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 566bc05bda..8601557650 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -88,6 +88,7 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index d2192c0483..3b3a2d7703 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -39,7 +39,6 @@ ramstage-y += pcie_rp.c ramstage-y += pmc.c ramstage-y += reset.c ramstage-y += retimer.c -ramstage-y += soundwire.c ramstage-y += systemagent.c ramstage-y += tcss.c ramstage-y += xhci.c diff --git a/src/soc/intel/meteorlake/soundwire.c b/src/soc/intel/meteorlake/soundwire.c deleted file mode 100644 index c3ff05d2e3..0000000000 --- a/src/soc/intel/meteorlake/soundwire.c +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const struct soundwire_link link_xtal_38_4 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 4800 * KHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 50, - .default_frame_col_size = 4, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static const struct soundwire_link link_xtal_24 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 6 * MHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 125, - .default_frame_col_size = 2, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static struct intel_soundwire_controller intel_controller = { - .acpi_address = 0x40000000, - .sdw = { - .master_list_count = 4 - } -}; - -int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller) -{ - const struct soundwire_link *link; - enum pch_pmc_xtal xtal = pmc_get_xtal_freq(); - size_t i; - - /* Select link config based on XTAL frequency and set IP clock. */ - switch (xtal) { - case XTAL_24_MHZ: - link = &link_xtal_24; - intel_controller.ip_clock = 24 * MHz; - break; - case XTAL_38_4_MHZ: - link = &link_xtal_38_4; - intel_controller.ip_clock = 38400 * KHz; - break; - case XTAL_19_2_MHZ: - default: - printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal); - return -1; - } - - /* Fill link config in controller map based on selected XTAL. */ - for (i = 0; i < intel_controller.sdw.master_list_count; i++) - memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link)); - - *controller = &intel_controller; - return 0; -} From 620a33f1c85d0b9534592e51e2d13918c406c120 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:17:08 -0800 Subject: [PATCH 651/789] soc/intel/pantherlake: Use common SoundWire driver Migrate Panther Lake to use the common SoundWire driver implementation from the Intel common feature code. This change eliminates platform- specific code by leveraging the shared soundwire.c driver. This commit: - Selects SOC_INTEL_COMMON_FEATURE_SOUNDWIRE Kconfig - Removes src/soc/intel/pantherlake/soundwire.c - Updates Makefile to remove soundwire.c compilation Panther Lake uses the default values (4 SoundWire master links with ACPI address 0x40000000). TEST=Build and boot to the OS on a Fatcat device Change-Id: Iaebb27ddc44da536c8e6a6aece1dfee3a4ac7bac Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91279 Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/pantherlake/Kconfig | 1 + src/soc/intel/pantherlake/Makefile.mk | 1 - src/soc/intel/pantherlake/soundwire.c | 72 --------------------------- 3 files changed, 1 insertion(+), 73 deletions(-) delete mode 100644 src/soc/intel/pantherlake/soundwire.c diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index 33a592cb07..243b9fa41f 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -98,6 +98,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index 857e7ab648..361b583839 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -37,7 +37,6 @@ ramstage-y += pcie_rp.c ramstage-y += pmc.c ramstage-y += reset.c ramstage-y += retimer.c -ramstage-y += soundwire.c ramstage-y += systemagent.c ramstage-y += tcss.c ramstage-y += tdp.c diff --git a/src/soc/intel/pantherlake/soundwire.c b/src/soc/intel/pantherlake/soundwire.c deleted file mode 100644 index ab1d0bc683..0000000000 --- a/src/soc/intel/pantherlake/soundwire.c +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const struct soundwire_link link_xtal_38_4 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 4800 * KHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 50, - .default_frame_col_size = 4, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static const struct soundwire_link link_xtal_24 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 6 * MHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 125, - .default_frame_col_size = 2, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static struct intel_soundwire_controller intel_controller = { - .acpi_address = 0x40000000, /* Custom address for SNDW driver */ - .sdw = { - .master_list_count = 4 - } -}; - -int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller) -{ - const struct soundwire_link *link; - enum pch_pmc_xtal xtal = pmc_get_xtal_freq(); - size_t i; - - /* Select link config based on XTAL frequency and set IP clock. */ - switch (xtal) { - case XTAL_24_MHZ: - link = &link_xtal_24; - intel_controller.ip_clock = 24 * MHz; - break; - case XTAL_38_4_MHZ: - link = &link_xtal_38_4; - intel_controller.ip_clock = 38400 * KHz; - break; - case XTAL_19_2_MHZ: - default: - printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal); - return -1; - } - - /* Fill link config in controller map based on selected XTAL. */ - for (i = 0; i < intel_controller.sdw.master_list_count; i++) - memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link)); - - *controller = &intel_controller; - return 0; -} From f780b7c576bc7df13b706c649ac8b6879c9e4958 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:17:26 -0800 Subject: [PATCH 652/789] soc/intel/tigerlake: Use common SoundWire driver Migrate Tiger Lake to use the common SoundWire driver implementation from the Intel common feature code. This change eliminates platform- specific code by leveraging the shared soundwire.c driver. This commit: - Selects SOC_INTEL_COMMON_FEATURE_SOUNDWIRE Kconfig - Removes src/soc/intel/tigerlake/soundwire.c - Updates Makefile to remove soundwire.c compilation Tiger Lake uses the default values (4 SoundWire master links with ACPI address 0x40000000). Change-Id: Ife743d28c8760d9de3f593f7d8caafd7a73efe3a Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91280 Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/tigerlake/Kconfig | 1 + src/soc/intel/tigerlake/Makefile.mk | 1 - src/soc/intel/tigerlake/soundwire.c | 70 ----------------------------- 3 files changed, 1 insertion(+), 71 deletions(-) delete mode 100644 src/soc/intel/tigerlake/soundwire.c diff --git a/src/soc/intel/tigerlake/Kconfig b/src/soc/intel/tigerlake/Kconfig index 5168546661..b136c3354b 100644 --- a/src/soc/intel/tigerlake/Kconfig +++ b/src/soc/intel/tigerlake/Kconfig @@ -74,6 +74,7 @@ config SOC_INTEL_TIGERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN diff --git a/src/soc/intel/tigerlake/Makefile.mk b/src/soc/intel/tigerlake/Makefile.mk index 074f172d38..973ad0f015 100644 --- a/src/soc/intel/tigerlake/Makefile.mk +++ b/src/soc/intel/tigerlake/Makefile.mk @@ -34,7 +34,6 @@ ramstage-y += pcie_rp.c ramstage-y += pmc.c ramstage-y += reset.c ramstage-y += retimer.c -ramstage-y += soundwire.c ramstage-y += systemagent.c ramstage-y += tcss.c ramstage-y += xhci.c diff --git a/src/soc/intel/tigerlake/soundwire.c b/src/soc/intel/tigerlake/soundwire.c deleted file mode 100644 index 878ce1973c..0000000000 --- a/src/soc/intel/tigerlake/soundwire.c +++ /dev/null @@ -1,70 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include - -static const struct soundwire_link link_xtal_38_4 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 4800 * KHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 50, - .default_frame_col_size = 4, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static const struct soundwire_link link_xtal_24 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 6 * MHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 125, - .default_frame_col_size = 2, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static struct intel_soundwire_controller intel_controller = { - .acpi_address = 0x40000000, - .sdw = { - .master_list_count = 4 - } -}; - -int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller) -{ - const struct soundwire_link *link; - enum pch_pmc_xtal xtal = pmc_get_xtal_freq(); - size_t i; - - /* Select link config based on XTAL frequency and set IP clock. */ - switch (xtal) { - case XTAL_24_MHZ: - link = &link_xtal_24; - intel_controller.ip_clock = 24 * MHz; - break; - case XTAL_38_4_MHZ: - link = &link_xtal_38_4; - intel_controller.ip_clock = 38400 * KHz; - break; - case XTAL_19_2_MHZ: - default: - printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal); - return -1; - } - - /* Fill link config in controller map based on selected XTAL. */ - for (i = 0; i < intel_controller.sdw.master_list_count; i++) - memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link)); - - *controller = &intel_controller; - return 0; -} From 0464f1032aec2b74fb595fbfcd0c49090bf0e8cb Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:38:05 -0800 Subject: [PATCH 653/789] soc/intel/common/feature/espi: Add common eSPI/LPC initialization This introduces a common implementation for eSPI/LPC initialization that handles generic IO decode range configuration and standard interrupt setup. This code is nearly identical across multiple Intel client platforms. The implementation includes: - soc_get_gen_io_dec_range(): Configures generic IO decode ranges from devicetree (gen1_dec through gen4_dec) - lpc_soc_init(): Performs legacy ISA/DMA initialization, enables CLKRUN for power gating, configures Serial IRQ mode, and sets up the interrupt controllers (IOAPIC, PIRQ, i8259) Platform-specific configuration is handled through the config_t typedef that each platform defines via its soc_chip.h header, eliminating the need for preprocessor conditionals. The common driver is enabled via the SOC_INTEL_COMMON_FEATURE_ESPI Kconfig option and works across bootblock, romstage, and ramstage. Platforms that will use this common implementation: - Alder Lake - Meteor Lake - Panther Lake - Tiger Lake - Jasper Lake - Elkhart Lake Change-Id: Idbdecff1cef44dae90afb35ff6e2afca011ea5b4 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91216 Reviewed-by: Huang, Cliff Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- src/soc/intel/common/feature/espi/Kconfig | 8 ++++ src/soc/intel/common/feature/espi/Makefile.mk | 5 ++ src/soc/intel/common/feature/espi/espi.c | 46 +++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 src/soc/intel/common/feature/espi/Kconfig create mode 100644 src/soc/intel/common/feature/espi/Makefile.mk create mode 100644 src/soc/intel/common/feature/espi/espi.c diff --git a/src/soc/intel/common/feature/espi/Kconfig b/src/soc/intel/common/feature/espi/Kconfig new file mode 100644 index 0000000000..521c7bbe5c --- /dev/null +++ b/src/soc/intel/common/feature/espi/Kconfig @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_ESPI + bool + help + Select this if the platform supports common eSPI/LPC initialization + with generic IO decode range configuration and standard interrupt + setup. This is applicable for most modern Intel client platforms. diff --git a/src/soc/intel/common/feature/espi/Makefile.mk b/src/soc/intel/common/feature/espi/Makefile.mk new file mode 100644 index 0000000000..69542218b3 --- /dev/null +++ b/src/soc/intel/common/feature/espi/Makefile.mk @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-$(CONFIG_SOC_INTEL_COMMON_FEATURE_ESPI) += espi.c +romstage-$(CONFIG_SOC_INTEL_COMMON_FEATURE_ESPI) += espi.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_FEATURE_ESPI) += espi.c diff --git a/src/soc/intel/common/feature/espi/espi.c b/src/soc/intel/common/feature/espi/espi.c new file mode 100644 index 0000000000..b0620c683d --- /dev/null +++ b/src/soc/intel/common/feature/espi/espi.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) +{ + const config_t *config = config_of_soc(); + + gen_io_dec[0] = config->gen1_dec; + gen_io_dec[1] = config->gen2_dec; + gen_io_dec[2] = config->gen3_dec; + gen_io_dec[3] = config->gen4_dec; +} + +void lpc_soc_init(struct device *dev) +{ + /* Legacy initialization */ + isa_dma_init(); + pch_misc_init(); + + /* Enable CLKRUN_EN for power gating ESPI */ + lpc_enable_pci_clk_cntl(); + + /* Set ESPI Serial IRQ mode */ + if (CONFIG(SERIRQ_CONTINUOUS_MODE)) + lpc_set_serirq_mode(SERIRQ_CONTINUOUS); + else + lpc_set_serirq_mode(SERIRQ_QUIET); + + /* Interrupt configuration */ + pch_enable_ioapic(); + pch_pirq_init(); + setup_i8259(); + i8259_configure_irq_trigger(9, 1); +} From 34be3842a18f70ee60ef3055ce3a2064f87ee25b Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:38:28 -0800 Subject: [PATCH 654/789] soc/intel/alderlake: Switch to common eSPI/LPC initialization Replace platform-specific espi.c with the common eSPI/LPC initialization driver. Changes: - Remove src/soc/intel/alderlake/espi.c - Enable SOC_INTEL_COMMON_FEATURE_ESPI in Kconfig - Update Makefile.mk to remove espi.c from build The eSPI/LPC initialization was nearly identical across platforms, differing only in minor header inclusions and ENV_RAMSTAGE wrapper usage. The common implementation uses the config_t typedef that each platform defines, providing clean abstraction without preprocessor conditionals. Change-Id: Ifacdd480a9cfd59d9e54faebad82e1cc2db8a8ed Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91217 Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- src/soc/intel/alderlake/Kconfig | 1 + src/soc/intel/alderlake/Makefile.mk | 3 -- src/soc/intel/alderlake/espi.c | 56 ----------------------------- 3 files changed, 1 insertion(+), 59 deletions(-) delete mode 100644 src/soc/intel/alderlake/espi.c diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index be44a9eabb..30be64a3e9 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -85,6 +85,7 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index 5d604a994a..83ae0a8c14 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -10,12 +10,10 @@ all-y += pmutil.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c -bootblock-y += espi.c bootblock-y += p2sb.c bootblock-$(CONFIG_ALDERLAKE_CONFIGURE_DESCRIPTOR) += bootblock/update_descriptor.c romstage-$(CONFIG_SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY) += cse_telemetry.c -romstage-y += espi.c romstage-y += meminit.c romstage-y += pcie_rp.c romstage-y += reset.c @@ -24,7 +22,6 @@ ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c ramstage-y += elog.c -ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c diff --git a/src/soc/intel/alderlake/espi.c b/src/soc/intel/alderlake/espi.c deleted file mode 100644 index bdc41a6a30..0000000000 --- a/src/soc/intel/alderlake/espi.c +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 2 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const config_t *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -#if ENV_RAMSTAGE -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} -#endif From 4fe7e7fa364a2a07a3a987abae9424c94f0eb711 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:38:49 -0800 Subject: [PATCH 655/789] soc/intel/meteorlake: Switch to common eSPI/LPC initialization Replace platform-specific espi.c with the common eSPI/LPC initialization driver. Changes: - Remove src/soc/intel/meteorlake/espi.c - Enable SOC_INTEL_COMMON_FEATURE_ESPI in Kconfig - Update Makefile.mk to remove espi.c from build The eSPI/LPC initialization was nearly identical across platforms, differing only in minor header inclusions and ENV_RAMSTAGE wrapper usage. The common implementation uses the config_t typedef that each platform defines, providing clean abstraction without preprocessor conditionals. Change-Id: Ifb198964c5eda1fceaec6111cd7fba374bacf1b6 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91218 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/meteorlake/Kconfig | 1 + src/soc/intel/meteorlake/Makefile.mk | 3 -- src/soc/intel/meteorlake/espi.c | 48 ---------------------------- 3 files changed, 1 insertion(+), 51 deletions(-) delete mode 100644 src/soc/intel/meteorlake/espi.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 8601557650..6ec4c9aaa7 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -87,6 +87,7 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index 3b3a2d7703..a6c77a8bdd 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -13,11 +13,9 @@ bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/ioe_die.c bootblock-y += bootblock/report_platform.c bootblock-y += bootblock/soc_die.c -bootblock-y += espi.c bootblock-y += soc_info.c romstage-$(CONFIG_SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY) += cse_telemetry.c -romstage-y += espi.c romstage-y += meminit.c romstage-y += pcie_rp.c romstage-y += reset.c @@ -29,7 +27,6 @@ ramstage-y += cpu.c ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c ramstage-y += ioe_pmc.c ramstage-y += elog.c -ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c diff --git a/src/soc/intel/meteorlake/espi.c b/src/soc/intel/meteorlake/espi.c deleted file mode 100644 index 98fd9fc045..0000000000 --- a/src/soc/intel/meteorlake/espi.c +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const config_t *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} From 7278030fa61489fa3325e95547302f0f53578faa Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:38:57 -0800 Subject: [PATCH 656/789] soc/intel/pantherlake: Switch to common eSPI/LPC initialization Replace platform-specific espi.c with the common eSPI/LPC initialization driver. Changes: - Remove src/soc/intel/pantherlake/espi.c - Enable SOC_INTEL_COMMON_FEATURE_ESPI in Kconfig - Update Makefile.mk to remove espi.c from build The eSPI/LPC initialization was nearly identical across platforms, differing only in minor header inclusions and ENV_RAMSTAGE wrapper usage. The common implementation uses the config_t typedef that each platform defines, providing clean abstraction without preprocessor conditionals. TEST=Build and boot to the OS on a Fatcat device Change-Id: If5f2de9faa209ff30f986f34b1816ffa6d5fc683 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91219 Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/Kconfig | 1 + src/soc/intel/pantherlake/Makefile.mk | 3 -- src/soc/intel/pantherlake/espi.c | 48 --------------------------- 3 files changed, 1 insertion(+), 51 deletions(-) delete mode 100644 src/soc/intel/pantherlake/espi.c diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index 243b9fa41f..75f5ac463b 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -97,6 +97,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index 361b583839..8fc9cb543c 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -13,10 +13,8 @@ all-y += gpio.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pcd.c bootblock-y += bootblock/report_platform.c -bootblock-y += espi.c romstage-$(CONFIG_SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY) += cse_telemetry.c -romstage-y += espi.c romstage-y += meminit.c romstage-y += pcie_rp.c romstage-y += reset.c @@ -28,7 +26,6 @@ ramstage-y += chip.c ramstage-y += cpu.c ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c ramstage-y += elog.c -ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += lockdown.c diff --git a/src/soc/intel/pantherlake/espi.c b/src/soc/intel/pantherlake/espi.c deleted file mode 100644 index d5b5cf93c9..0000000000 --- a/src/soc/intel/pantherlake/espi.c +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const struct soc_intel_pantherlake_config *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} From 05006995b62a79962567370502564f935b7819e2 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:39:04 -0800 Subject: [PATCH 657/789] soc/intel/tigerlake: Switch to common eSPI/LPC initialization Replace platform-specific espi.c with the common eSPI/LPC initialization driver. Changes: - Remove src/soc/intel/tigerlake/espi.c - Enable SOC_INTEL_COMMON_FEATURE_ESPI in Kconfig - Update Makefile.mk to remove espi.c from build The eSPI/LPC initialization was nearly identical across platforms, differing only in minor header inclusions and ENV_RAMSTAGE wrapper usage. The common implementation uses the config_t typedef that each platform defines, providing clean abstraction without preprocessor conditionals. Change-Id: I65f8af8f5abccff25ec0dead4f7def7ce16d3081 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91220 Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- src/soc/intel/tigerlake/Kconfig | 1 + src/soc/intel/tigerlake/Makefile.mk | 3 -- src/soc/intel/tigerlake/espi.c | 58 ----------------------------- 3 files changed, 1 insertion(+), 61 deletions(-) delete mode 100644 src/soc/intel/tigerlake/espi.c diff --git a/src/soc/intel/tigerlake/Kconfig b/src/soc/intel/tigerlake/Kconfig index b136c3354b..a470d7cde5 100644 --- a/src/soc/intel/tigerlake/Kconfig +++ b/src/soc/intel/tigerlake/Kconfig @@ -73,6 +73,7 @@ config SOC_INTEL_TIGERLAKE select SOC_INTEL_COMMON_BLOCK_USB4_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN diff --git a/src/soc/intel/tigerlake/Makefile.mk b/src/soc/intel/tigerlake/Makefile.mk index 973ad0f015..cf6cdc2ec2 100644 --- a/src/soc/intel/tigerlake/Makefile.mk +++ b/src/soc/intel/tigerlake/Makefile.mk @@ -11,10 +11,8 @@ all-y += pmutil.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c -bootblock-y += espi.c bootblock-y += p2sb.c -romstage-y += espi.c romstage-y += meminit.c romstage-y += pcie_rp.c romstage-y += reset.c @@ -23,7 +21,6 @@ ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c ramstage-y += elog.c -ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c diff --git a/src/soc/intel/tigerlake/espi.c b/src/soc/intel/tigerlake/espi.c deleted file mode 100644 index 3b56e290d1..0000000000 --- a/src/soc/intel/tigerlake/espi.c +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Tiger Lake Processor PCH Datasheet - * Document number: 575857 - * Chapter number: 2 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const config_t *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -#if ENV_RAMSTAGE -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} - -#endif From aeb9db4467a450a3bb1477d50dfe2612a570dab0 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:39:11 -0800 Subject: [PATCH 658/789] soc/intel/jasperlake: Switch to common eSPI/LPC initialization Replace platform-specific espi.c with the common eSPI/LPC initialization driver. Changes: - Remove src/soc/intel/jasperlake/espi.c - Enable SOC_INTEL_COMMON_FEATURE_ESPI in Kconfig - Update Makefile.mk to remove espi.c from build The eSPI/LPC initialization was nearly identical across platforms, differing only in minor header inclusions and ENV_RAMSTAGE wrapper usage. The common implementation uses the config_t typedef that each platform defines, providing clean abstraction without preprocessor conditionals. Change-Id: Ied29a5f2dabdebe0afedd1d69e4a817d6606a82d Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91221 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/jasperlake/Kconfig | 1 + src/soc/intel/jasperlake/Makefile.mk | 3 -- src/soc/intel/jasperlake/espi.c | 52 ---------------------------- 3 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 src/soc/intel/jasperlake/espi.c diff --git a/src/soc/intel/jasperlake/Kconfig b/src/soc/intel/jasperlake/Kconfig index df65e73a78..7bcd734887 100644 --- a/src/soc/intel/jasperlake/Kconfig +++ b/src/soc/intel/jasperlake/Kconfig @@ -56,6 +56,7 @@ config SOC_INTEL_JASPERLAKE select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN diff --git a/src/soc/intel/jasperlake/Makefile.mk b/src/soc/intel/jasperlake/Makefile.mk index cb3ebfacd2..05288ee8a1 100644 --- a/src/soc/intel/jasperlake/Makefile.mk +++ b/src/soc/intel/jasperlake/Makefile.mk @@ -11,11 +11,9 @@ all-y += pmutil.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c -bootblock-y += espi.c bootblock-y += gpio.c bootblock-y += p2sb.c -romstage-y += espi.c romstage-y += gpio.c romstage-y += meminit.c romstage-y += pcie_rp.c @@ -25,7 +23,6 @@ ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c ramstage-y += elog.c -ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += gpio.c diff --git a/src/soc/intel/jasperlake/espi.c b/src/soc/intel/jasperlake/espi.c deleted file mode 100644 index dfa3b19f9a..0000000000 --- a/src/soc/intel/jasperlake/espi.c +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const config_t *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -#if ENV_RAMSTAGE -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} - -#endif From 189f8d1a8634ac947c6fe30f2748d69d8e68edd3 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 09:39:19 -0800 Subject: [PATCH 659/789] soc/intel/elkhartlake: Switch to common eSPI/LPC initialization Replace platform-specific espi.c with the common eSPI/LPC initialization driver. Changes: - Remove src/soc/intel/elkhartlake/espi.c - Enable SOC_INTEL_COMMON_FEATURE_ESPI in Kconfig - Update Makefile.mk to remove espi.c from build The eSPI/LPC initialization was nearly identical across platforms, differing only in minor header inclusions and ENV_RAMSTAGE wrapper usage. The common implementation uses the config_t typedef that each platform defines, providing clean abstraction without preprocessor conditionals. Change-Id: I59d9cb1b37bca2c682e2bf87fc3f5b24c34fb920 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91222 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/elkhartlake/Kconfig | 1 + src/soc/intel/elkhartlake/Makefile.mk | 3 -- src/soc/intel/elkhartlake/espi.c | 52 --------------------------- 3 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 src/soc/intel/elkhartlake/espi.c diff --git a/src/soc/intel/elkhartlake/Kconfig b/src/soc/intel/elkhartlake/Kconfig index a15833346e..e8629039a2 100644 --- a/src/soc/intel/elkhartlake/Kconfig +++ b/src/soc/intel/elkhartlake/Kconfig @@ -56,6 +56,7 @@ config SOC_INTEL_ELKHARTLAKE select SOC_INTEL_COMMON_BLOCK_SMM select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES diff --git a/src/soc/intel/elkhartlake/Makefile.mk b/src/soc/intel/elkhartlake/Makefile.mk index ee2204300c..e46946f0bb 100644 --- a/src/soc/intel/elkhartlake/Makefile.mk +++ b/src/soc/intel/elkhartlake/Makefile.mk @@ -12,11 +12,9 @@ all-y += spi.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c -bootblock-y += espi.c bootblock-y += gpio.c bootblock-y += p2sb.c -romstage-y += espi.c romstage-y += gpio.c romstage-y += meminit.c romstage-y += pcie_rp.c @@ -25,7 +23,6 @@ romstage-y += reset.c ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c -ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += gpio.c diff --git a/src/soc/intel/elkhartlake/espi.c b/src/soc/intel/elkhartlake/espi.c deleted file mode 100644 index de2a84f8f0..0000000000 --- a/src/soc/intel/elkhartlake/espi.c +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const config_t *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -#if ENV_RAMSTAGE -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} - -#endif From cc31cc0ab26fd772be536ee4fb707be4c174c8eb Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 10:00:38 -0800 Subject: [PATCH 660/789] soc/intel/common/feature/pmutil: Add common pmutil driver This adds a common PM utility driver for modern Intel platforms that share consistent PM register layouts. The driver consolidates power management utility functions that were previously duplicated across multiple Intel SoC platforms. This includes functions for: - SMI/TCO/GPE status bit decoding - PMC MMIO base address access - RTC failure detection - Sleep state management - Power state structure population - After-G3 power state configuration - GPE configuration retrieval using generic config_t The GPE configuration function (soc_get_gpi_gpe_configs) uses the generic config_t typedef that each platform defines, allowing complete code reuse without platform-specific shims. This common driver is controlled by the Kconfig option SOC_INTEL_COMMON_FEATURE_PMUTIL and is built for all boot stages. Change-Id: I45b829b7c18ee66474457df5523069f930806b35 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91237 Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/common/feature/pmutil/Kconfig | 10 + .../intel/common/feature/pmutil/Makefile.mk | 4 + src/soc/intel/common/feature/pmutil/pmutil.c | 287 ++++++++++++++++++ 3 files changed, 301 insertions(+) create mode 100644 src/soc/intel/common/feature/pmutil/Kconfig create mode 100644 src/soc/intel/common/feature/pmutil/Makefile.mk create mode 100644 src/soc/intel/common/feature/pmutil/pmutil.c diff --git a/src/soc/intel/common/feature/pmutil/Kconfig b/src/soc/intel/common/feature/pmutil/Kconfig new file mode 100644 index 0000000000..e0934a5e4e --- /dev/null +++ b/src/soc/intel/common/feature/pmutil/Kconfig @@ -0,0 +1,10 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_PMUTIL + bool + help + Select this if the platform supports common PMC utility driver + for modern Intel platforms that share consistent PM register + layouts. This consolidates power management utility functions + including SMI/TCO/GPE status handling, PMC MMIO access, RTC + failure detection, sleep state management, and GPE configuration. diff --git a/src/soc/intel/common/feature/pmutil/Makefile.mk b/src/soc/intel/common/feature/pmutil/Makefile.mk new file mode 100644 index 0000000000..3bda095d2a --- /dev/null +++ b/src/soc/intel/common/feature/pmutil/Makefile.mk @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_PMUTIL) += pmutil.c +smm-$(CONFIG_SOC_INTEL_COMMON_FEATURE_PMUTIL) += pmutil.c diff --git a/src/soc/intel/common/feature/pmutil/pmutil.c b/src/soc/intel/common/feature/pmutil/pmutil.c new file mode 100644 index 0000000000..5d7db19f74 --- /dev/null +++ b/src/soc/intel/common/feature/pmutil/pmutil.c @@ -0,0 +1,287 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * Common helper functions for dealing with power management registers + * for modern Intel platforms. + * + * This driver consolidates PM utility functions that were duplicated + * across multiple Intel SoC platforms. + */ + +#define __SIMPLE_DEVICE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * SMI + */ +const char *const *soc_smi_sts_array(size_t *a) +{ + static const char *const smi_sts_bits[] = { + [BIOS_STS_BIT] = "BIOS", + [LEGACY_USB_STS_BIT] = "LEGACY_USB", + [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI", + [APM_STS_BIT] = "APM", + [SWSMI_TMR_STS_BIT] = "SWSMI_TMR", + [PM1_STS_BIT] = "PM1", + [GPE0_STS_BIT] = "GPE0", + [GPIO_STS_BIT] = "GPI", + [MCSMI_STS_BIT] = "MCSMI", + [DEVMON_STS_BIT] = "DEVMON", + [TCO_STS_BIT] = "TCO", + [PERIODIC_STS_BIT] = "PERIODIC", + [SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI", + [SMBUS_SMI_STS_BIT] = "SMBUS_SMI", + [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI", + [MONITOR_STS_BIT] = "MONITOR", + [SPI_SMI_STS_BIT] = "SPI", + [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK", + [ESPI_SMI_STS_BIT] = "ESPI_SMI", + }; + + *a = ARRAY_SIZE(smi_sts_bits); + return smi_sts_bits; +} + +/* + * TCO + */ +const char *const *soc_tco_sts_array(size_t *a) +{ + static const char *const tco_sts_bits[] = { + [0] = "NMI2SMI", + [1] = "SW_TCO", + [2] = "TCO_INT", + [3] = "TIMEOUT", + [7] = "NEWCENTURY", + [8] = "BIOSWR", + [9] = "DMISCI", + [10] = "DMISMI", + [12] = "DMISERR", + [13] = "SLVSEL", + [16] = "INTRD_DET", + [17] = "SECOND_TO", + [18] = "BOOT", + [20] = "SMLINK_SLV" + }; + + *a = ARRAY_SIZE(tco_sts_bits); + return tco_sts_bits; +} + +/* + * GPE0 + */ +const char *const *soc_std_gpe_sts_array(size_t *a) +{ + static const char *const gpe_sts_bits[] = { + [1] = "HOTPLUG", + [2] = "SWGPE", + [6] = "TCO_SCI", + [7] = "SMB_WAK", + [9] = "PCI_EXP", + [10] = "BATLOW", + [11] = "PME", + [12] = "ME", + [13] = "PME_B0", + [14] = "eSPI", + [15] = "GPIO Tier-2", + [16] = "LAN_WAKE", + [18] = "WADT" + }; + + *a = ARRAY_SIZE(gpe_sts_bits); + return gpe_sts_bits; +} + +void pmc_set_disb(void) +{ + /* Set the DISB after DRAM init */ + uint8_t disb_val; + /* Only care about bits [23:16] of register GEN_PMCON_A */ + uint8_t *addr = (uint8_t *)(pmc_mmio_regs() + GEN_PMCON_A + 2); + + disb_val = read8(addr); + disb_val |= (DISB >> 16); + + /* Don't clear bits that are write-1-to-clear */ + disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16); + write8(addr, disb_val); +} + +/* + * PMC controller gets hidden from PCI bus + * during FSP-Silicon init call. Hence PWRMBASE + * can't be accessible using PCI configuration space + * read/write. + */ +uint8_t *pmc_mmio_regs(void) +{ + return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS; +} + +uintptr_t soc_read_pmc_base(void) +{ + return (uintptr_t)pmc_mmio_regs(); +} + +uint32_t *soc_pmc_etr_addr(void) +{ + return (uint32_t *)(soc_read_pmc_base() + ETR); +} + +static void pmc_gpe0_different_values(const config_t *config) +{ + bool all_zero = (config->pmc_gpe0_dw0 == 0) && + (config->pmc_gpe0_dw1 == 0) && + (config->pmc_gpe0_dw2 == 0); + + /* Check if all values are different AND not all zero */ + bool all_different = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) && + (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) && + (config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2); + + assert(all_different || all_zero); +} + +void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) +{ + DEVTREE_CONST config_t *config; + + config = config_of_soc(); + if (config == NULL) { + printk(BIOS_ERR, "Configuration could not be retrieved.\n"); + return; + } + + pmc_gpe0_different_values(config); + + /* Assign to out variable */ + *dw0 = config->pmc_gpe0_dw0; + *dw1 = config->pmc_gpe0_dw1; + *dw2 = config->pmc_gpe0_dw2; +} + +static int rtc_failed(uint32_t gen_pmcon_b) +{ + return !!(gen_pmcon_b & RTC_BATTERY_DEAD); +} + +int soc_get_rtc_failed(void) +{ + const struct chipset_power_state *ps; + + if (acpi_fetch_pm_state(&ps, PS_CLAIMER_RTC) < 0) + return 1; + + return rtc_failed(ps->gen_pmcon_b); +} + +int vbnv_cmos_failed(void) +{ + return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B)); +} + +static inline int deep_s3_enabled(void) +{ + uint32_t deep_s3_pol; + + deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL); + return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS)); +} + +/* Return 0, 3, or 5 to indicate the previous sleep state. */ +int soc_prev_sleep_state(const struct chipset_power_state *ps, int prev_sleep_state) +{ + /* + * Check for any power failure to determine if this a wake from + * S5 because the PCH does not set the WAK_STS bit when waking + * from a true G3 state. + */ + if (!(ps->pm1_sts & WAK_STS) && (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR))) + prev_sleep_state = ACPI_S5; + + /* + * If waking from S3 determine if deep S3 is enabled. If not, + * need to check both deep sleep well and normal suspend well. + * Otherwise just check deep sleep well. + */ + if (prev_sleep_state == ACPI_S3) { + /* PWR_FLR represents deep sleep power well loss. */ + uint32_t mask = PWR_FLR; + + /* If deep s3 isn't enabled check the suspend well too. */ + if (!deep_s3_enabled()) + mask |= SUS_PWR_FLR; + + if (ps->gen_pmcon_a & mask) + prev_sleep_state = ACPI_S5; + } + + return prev_sleep_state; +} + +void soc_fill_power_state(struct chipset_power_state *ps) +{ + uint8_t *pmc; + + ps->tco1_sts = tco_read_reg(TCO1_STS); + ps->tco2_sts = tco_read_reg(TCO2_STS); + + printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", ps->tco1_sts, ps->tco2_sts); + + pmc = pmc_mmio_regs(); + ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A); + ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B); + ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); + ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); + ps->hpr_cause0 = read32(pmc + HPR_CAUSE0); + + printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", + ps->gen_pmcon_a, ps->gen_pmcon_b); + + printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", + ps->gblrst_cause[0], ps->gblrst_cause[1]); + + printk(BIOS_DEBUG, "HPR_CAUSE0: %08x\n", ps->hpr_cause0); +} + +/* STM Support */ +uint16_t get_pmbase(void) +{ + return (uint16_t)ACPI_BASE_ADDRESS; +} + +/* + * Set which power state system will be after reapplying + * the power (from G3 State) + */ +void pmc_soc_set_afterg3_en(const bool on) +{ + uint8_t reg8; + uint8_t *const pmcbase = pmc_mmio_regs(); + + reg8 = read8(pmcbase + GEN_PMCON_A); + if (on) + reg8 &= ~SLEEP_AFTER_POWER_FAIL; + else + reg8 |= SLEEP_AFTER_POWER_FAIL; + write8(pmcbase + GEN_PMCON_A, reg8); +} From 2b70ce3fbfa58947c2abb35fa25c44ebc6580114 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 10:01:06 -0800 Subject: [PATCH 661/789] soc/intel/alderlake: Use common pmutil driver Migrate Alder Lake to use the common PMC utility driver instead of maintaining platform-specific pmutil.c code. This change: - Enables SOC_INTEL_COMMON_FEATURE_PMUTIL in Kconfig - Removes platform-specific pmutil.c - Removes pmutil.c from Makefile.mk The common driver provides all necessary functionality through the generic config_t interface, eliminating ~290 lines of duplicated code. Change-Id: Ieb62ffac95550a0ae8607a3a9ae76e0f6ff0ac35 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91238 Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/alderlake/Kconfig | 1 + src/soc/intel/alderlake/Makefile.mk | 2 - src/soc/intel/alderlake/pmutil.c | 290 ---------------------------- 3 files changed, 1 insertion(+), 292 deletions(-) delete mode 100644 src/soc/intel/alderlake/pmutil.c diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 30be64a3e9..1568e5b595 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -87,6 +87,7 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_PMUTIL select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index 83ae0a8c14..210d84592d 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -5,7 +5,6 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += pmutil.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c @@ -40,7 +39,6 @@ ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c smm-y += elog.c smm-y += p2sb.c -smm-y += pmutil.c smm-y += smihandler.c smm-y += xhci.c diff --git a/src/soc/intel/alderlake/pmutil.c b/src/soc/intel/alderlake/pmutil.c deleted file mode 100644 index c4591007e7..0000000000 --- a/src/soc/intel/alderlake/pmutil.c +++ /dev/null @@ -1,290 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * Helper functions for dealing with power management registers - * and the differences between PCH variants. - */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 4 - */ - -#define __SIMPLE_DEVICE__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * SMI - */ - -const char *const *soc_smi_sts_array(size_t *a) -{ - static const char *const smi_sts_bits[] = { - [BIOS_STS_BIT] = "BIOS", - [LEGACY_USB_STS_BIT] = "LEGACY_USB", - [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI", - [APM_STS_BIT] = "APM", - [SWSMI_TMR_STS_BIT] = "SWSMI_TMR", - [PM1_STS_BIT] = "PM1", - [GPE0_STS_BIT] = "GPE0", - [GPIO_STS_BIT] = "GPI", - [MCSMI_STS_BIT] = "MCSMI", - [DEVMON_STS_BIT] = "DEVMON", - [TCO_STS_BIT] = "TCO", - [PERIODIC_STS_BIT] = "PERIODIC", - [SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI", - [SMBUS_SMI_STS_BIT] = "SMBUS_SMI", - [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI", - [MONITOR_STS_BIT] = "MONITOR", - [SPI_SMI_STS_BIT] = "SPI", - [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK", - [ESPI_SMI_STS_BIT] = "ESPI_SMI", - }; - - *a = ARRAY_SIZE(smi_sts_bits); - return smi_sts_bits; -} - -/* - * TCO - */ - -const char *const *soc_tco_sts_array(size_t *a) -{ - static const char *const tco_sts_bits[] = { - [0] = "NMI2SMI", - [1] = "SW_TCO", - [2] = "TCO_INT", - [3] = "TIMEOUT", - [7] = "NEWCENTURY", - [8] = "BIOSWR", - [9] = "DMISCI", - [10] = "DMISMI", - [12] = "DMISERR", - [13] = "SLVSEL", - [16] = "INTRD_DET", - [17] = "SECOND_TO", - [18] = "BOOT", - [20] = "SMLINK_SLV" - }; - - *a = ARRAY_SIZE(tco_sts_bits); - return tco_sts_bits; -} - -/* - * GPE0 - */ - -const char *const *soc_std_gpe_sts_array(size_t *a) -{ - static const char *const gpe_sts_bits[] = { - [1] = "HOTPLUG", - [2] = "SWGPE", - [6] = "TCO_SCI", - [7] = "SMB_WAK", - [9] = "PCI_EXP", - [10] = "BATLOW", - [11] = "PME", - [12] = "ME", - [13] = "PME_B0", - [14] = "eSPI", - [15] = "GPIO Tier-2", - [16] = "LAN_WAKE", - [18] = "WADT" - }; - - *a = ARRAY_SIZE(gpe_sts_bits); - return gpe_sts_bits; -} - -void pmc_set_disb(void) -{ - /* Set the DISB after DRAM init */ - uint8_t disb_val; - /* Only care about bits [23:16] of register GEN_PMCON_A */ - uint8_t *addr = (uint8_t *)(pmc_mmio_regs() + GEN_PMCON_A + 2); - - disb_val = read8(addr); - disb_val |= (DISB >> 16); - - /* Don't clear bits that are write-1-to-clear */ - disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16); - write8(addr, disb_val); -} - -/* - * PMC controller gets hidden from PCI bus - * during FSP-Silicon init call. Hence PWRMBASE - * can't be accessible using PCI configuration space - * read/write. - */ -uint8_t *pmc_mmio_regs(void) -{ - return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS; -} - -uintptr_t soc_read_pmc_base(void) -{ - return (uintptr_t)pmc_mmio_regs(); -} - -uint32_t *soc_pmc_etr_addr(void) -{ - return (uint32_t *)(soc_read_pmc_base() + ETR); -} - -static void pmc_gpe0_different_values(const struct soc_intel_alderlake_config *config) -{ - bool all_zero = (config->pmc_gpe0_dw0 == 0) && - (config->pmc_gpe0_dw1 == 0) && - (config->pmc_gpe0_dw2 == 0); - - /* Check if all values are different AND not all zero */ - bool all_different = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) && - (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) && - (config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2); - - assert(all_different || all_zero); -} - -void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) -{ - DEVTREE_CONST struct soc_intel_alderlake_config *config; - - config = config_of_soc(); - - pmc_gpe0_different_values(config); - - /* Assign to out variable */ - *dw0 = config->pmc_gpe0_dw0; - *dw1 = config->pmc_gpe0_dw1; - *dw2 = config->pmc_gpe0_dw2; -} - -static int rtc_failed(uint32_t gen_pmcon_b) -{ - return !!(gen_pmcon_b & RTC_BATTERY_DEAD); -} - -int soc_get_rtc_failed(void) -{ - const struct chipset_power_state *ps; - - if (acpi_fetch_pm_state(&ps, PS_CLAIMER_RTC) < 0) - return 1; - - return rtc_failed(ps->gen_pmcon_b); -} - -int vbnv_cmos_failed(void) -{ - return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B)); -} - -static inline int deep_s3_enabled(void) -{ - uint32_t deep_s3_pol; - - deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL); - return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS)); -} - -/* Return 0, 3, or 5 to indicate the previous sleep state. */ -int soc_prev_sleep_state(const struct chipset_power_state *ps, int prev_sleep_state) -{ - /* - * Check for any power failure to determine if this a wake from - * S5 because the PCH does not set the WAK_STS bit when waking - * from a true G3 state. - */ - if (!(ps->pm1_sts & WAK_STS) && (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR))) - prev_sleep_state = ACPI_S5; - - /* - * If waking from S3 determine if deep S3 is enabled. If not, - * need to check both deep sleep well and normal suspend well. - * Otherwise just check deep sleep well. - */ - if (prev_sleep_state == ACPI_S3) { - /* PWR_FLR represents deep sleep power well loss. */ - uint32_t mask = PWR_FLR; - - /* If deep s3 isn't enabled check the suspend well too. */ - if (!deep_s3_enabled()) - mask |= SUS_PWR_FLR; - - if (ps->gen_pmcon_a & mask) - prev_sleep_state = ACPI_S5; - } - - return prev_sleep_state; -} - -void soc_fill_power_state(struct chipset_power_state *ps) -{ - uint8_t *pmc; - - ps->tco1_sts = tco_read_reg(TCO1_STS); - ps->tco2_sts = tco_read_reg(TCO2_STS); - - printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", ps->tco1_sts, ps->tco2_sts); - - pmc = pmc_mmio_regs(); - ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A); - ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B); - ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); - ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); - ps->hpr_cause0 = read32(pmc + HPR_CAUSE0); - - printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", - ps->gen_pmcon_a, ps->gen_pmcon_b); - - printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", - ps->gblrst_cause[0], ps->gblrst_cause[1]); - - printk(BIOS_DEBUG, "HPR_CAUSE0: %08x\n", ps->hpr_cause0); -} - -/* STM Support */ -uint16_t get_pmbase(void) -{ - return (uint16_t)ACPI_BASE_ADDRESS; -} - -/* - * Set which power state system will be after reapplying - * the power (from G3 State) - */ -void pmc_soc_set_afterg3_en(const bool on) -{ - uint8_t reg8; - uint8_t *const pmcbase = pmc_mmio_regs(); - - reg8 = read8(pmcbase + GEN_PMCON_A); - if (on) - reg8 &= ~SLEEP_AFTER_POWER_FAIL; - else - reg8 |= SLEEP_AFTER_POWER_FAIL; - write8(pmcbase + GEN_PMCON_A, reg8); -} From f0be882d9f0238e24a1c56b27d78c9560b2986d9 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 10:01:21 -0800 Subject: [PATCH 662/789] soc/intel/pantherlake: Use common pmutil driver Migrate Panther Lake to use the common PMC utility driver instead of maintaining platform-specific pmutil.c code. This change: - Enables SOC_INTEL_COMMON_FEATURE_PMUTIL in Kconfig - Removes platform-specific pmutil.c - Removes pmutil.c from Makefile.mk The common driver provides all necessary functionality through the generic config_t interface, eliminating ~290 lines of duplicated code. TEST=Build and boot to the OS on a Fatcat device Change-Id: I3ee9630a6b15d7b02776ff633a3cff0766a8915b Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91239 Reviewed-by: Huang, Cliff Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/Kconfig | 1 + src/soc/intel/pantherlake/Makefile.mk | 2 - src/soc/intel/pantherlake/pmutil.c | 285 -------------------------- 3 files changed, 1 insertion(+), 287 deletions(-) delete mode 100644 src/soc/intel/pantherlake/pmutil.c diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index 75f5ac463b..937fb36a6b 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -99,6 +99,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_PMUTIL select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index 8fc9cb543c..417d27d6d0 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -7,7 +7,6 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += pmutil.c all-y += gpio.c bootblock-y += bootblock/bootblock.c @@ -43,7 +42,6 @@ ramstage-$(CONFIG_DRIVERS_INTEL_TOUCH) += touch.c smm-y += elog.c smm-y += gpio.c smm-y += p2sb.c -smm-y += pmutil.c smm-y += smihandler.c smm-y += xhci.c CPPFLAGS_common += -I$(src)/soc/intel/pantherlake diff --git a/src/soc/intel/pantherlake/pmutil.c b/src/soc/intel/pantherlake/pmutil.c deleted file mode 100644 index 7ce1dacfa3..0000000000 --- a/src/soc/intel/pantherlake/pmutil.c +++ /dev/null @@ -1,285 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * Helper functions for dealing with power management registers - * and the differences between PCH variants. - */ - -#define __SIMPLE_DEVICE__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * SMI - */ -const char *const *soc_smi_sts_array(size_t *a) -{ - static const char *const smi_sts_bits[] = { - [BIOS_STS_BIT] = "BIOS", - [LEGACY_USB_STS_BIT] = "LEGACY_USB", - [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI", - [APM_STS_BIT] = "APM", - [SWSMI_TMR_STS_BIT] = "SWSMI_TMR", - [PM1_STS_BIT] = "PM1", - [GPE0_STS_BIT] = "GPE0", - [GPIO_STS_BIT] = "GPI", - [MCSMI_STS_BIT] = "MCSMI", - [DEVMON_STS_BIT] = "DEVMON", - [TCO_STS_BIT] = "TCO", - [PERIODIC_STS_BIT] = "PERIODIC", - [SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI", - [SMBUS_SMI_STS_BIT] = "SMBUS_SMI", - [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI", - [MONITOR_STS_BIT] = "MONITOR", - [SPI_SMI_STS_BIT] = "SPI", - [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK", - [ESPI_SMI_STS_BIT] = "ESPI_SMI", - }; - - *a = ARRAY_SIZE(smi_sts_bits); - return smi_sts_bits; -} - -/* - * TCO - */ -const char *const *soc_tco_sts_array(size_t *a) -{ - static const char *const tco_sts_bits[] = { - [0] = "NMI2SMI", - [1] = "SW_TCO", - [2] = "TCO_INT", - [3] = "TIMEOUT", - [7] = "NEWCENTURY", - [8] = "BIOSWR", - [9] = "DMISCI", - [10] = "DMISMI", - [12] = "DMISERR", - [13] = "SLVSEL", - [16] = "INTRD_DET", - [17] = "SECOND_TO", - [18] = "BOOT", - [20] = "SMLINK_SLV" - }; - - *a = ARRAY_SIZE(tco_sts_bits); - return tco_sts_bits; -} - -/* - * GPE0 - */ -const char *const *soc_std_gpe_sts_array(size_t *a) -{ - static const char *const gpe_sts_bits[] = { - [1] = "HOTPLUG", - [2] = "SWGPE", - [6] = "TCO_SCI", - [7] = "SMB_WAK", - [9] = "PCI_EXP", - [10] = "BATLOW", - [11] = "PME", - [12] = "ME", - [13] = "PME_B0", - [14] = "eSPI", - [15] = "GPIO Tier-2", - [16] = "LAN_WAKE", - [18] = "WADT" - }; - - *a = ARRAY_SIZE(gpe_sts_bits); - return gpe_sts_bits; -} - -void pmc_set_disb(void) -{ - /* Set the DISB after DRAM init */ - uint8_t disb_val; - /* Only care about bits [23:16] of register GEN_PMCON_A */ - uint8_t *addr = (uint8_t *)(pmc_mmio_regs() + GEN_PMCON_A + 2); - - disb_val = read8(addr); - disb_val |= (DISB >> 16); - - /* Don't clear bits that are write-1-to-clear */ - disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16); - write8(addr, disb_val); -} - -/* - * PMC controller gets hidden from PCI bus - * during FSP-Silicon init call. Hence PWRMBASE - * can't be accessible using PCI configuration space - * read/write. - */ -uint8_t *pmc_mmio_regs(void) -{ - return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS; -} - -uintptr_t soc_read_pmc_base(void) -{ - return (uintptr_t)pmc_mmio_regs(); -} - -uint32_t *soc_pmc_etr_addr(void) -{ - return (uint32_t *)(soc_read_pmc_base() + ETR); -} - -static void pmc_gpe0_different_values(const struct soc_intel_pantherlake_config *config) -{ - bool all_zero = (config->pmc_gpe0_dw0 == 0) && - (config->pmc_gpe0_dw1 == 0) && - (config->pmc_gpe0_dw2 == 0); - - /* Check if all values are different AND not all zero */ - bool all_different = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) && - (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) && - (config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2); - - assert(all_different || all_zero); -} - -void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) -{ - DEVTREE_CONST struct soc_intel_pantherlake_config *config; - - config = config_of_soc(); - if (config == NULL) { - printk(BIOS_ERR, "Configuration could not be retrieved.\n"); - return; - } - - pmc_gpe0_different_values(config); - - /* Assign to out variable */ - *dw0 = config->pmc_gpe0_dw0; - *dw1 = config->pmc_gpe0_dw1; - *dw2 = config->pmc_gpe0_dw2; -} - -static int rtc_failed(uint32_t gen_pmcon_b) -{ - return !!(gen_pmcon_b & RTC_BATTERY_DEAD); -} - -int soc_get_rtc_failed(void) -{ - const struct chipset_power_state *ps; - - if (acpi_fetch_pm_state(&ps, PS_CLAIMER_RTC) < 0) - return 1; - - return rtc_failed(ps->gen_pmcon_b); -} - -int vbnv_cmos_failed(void) -{ - return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B)); -} - -static inline int deep_s3_enabled(void) -{ - uint32_t deep_s3_pol; - - deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL); - return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS)); -} - -/* Return 0, 3, or 5 to indicate the previous sleep state. */ -int soc_prev_sleep_state(const struct chipset_power_state *ps, int prev_sleep_state) -{ - /* - * Check for any power failure to determine if this a wake from - * S5 because the PCH does not set the WAK_STS bit when waking - * from a true G3 state. - */ - if (!(ps->pm1_sts & WAK_STS) && (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR))) - prev_sleep_state = ACPI_S5; - - /* - * If waking from S3 determine if deep S3 is enabled. If not, - * need to check both deep sleep well and normal suspend well. - * Otherwise just check deep sleep well. - */ - if (prev_sleep_state == ACPI_S3) { - /* PWR_FLR represents deep sleep power well loss. */ - uint32_t mask = PWR_FLR; - - /* If deep s3 isn't enabled check the suspend well too. */ - if (!deep_s3_enabled()) - mask |= SUS_PWR_FLR; - - if (ps->gen_pmcon_a & mask) - prev_sleep_state = ACPI_S5; - } - - return prev_sleep_state; -} - -void soc_fill_power_state(struct chipset_power_state *ps) -{ - uint8_t *pmc; - - ps->tco1_sts = tco_read_reg(TCO1_STS); - ps->tco2_sts = tco_read_reg(TCO2_STS); - - printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", ps->tco1_sts, ps->tco2_sts); - - pmc = pmc_mmio_regs(); - ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A); - ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B); - ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); - ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); - ps->hpr_cause0 = read32(pmc + HPR_CAUSE0); - - printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", - ps->gen_pmcon_a, ps->gen_pmcon_b); - - printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", - ps->gblrst_cause[0], ps->gblrst_cause[1]); - - printk(BIOS_DEBUG, "HPR_CAUSE0: %08x\n", ps->hpr_cause0); -} - -/* STM Support */ -uint16_t get_pmbase(void) -{ - return (uint16_t)ACPI_BASE_ADDRESS; -} - -/* - * Set which power state system will be after reapplying - * the power (from G3 State) - */ -void pmc_soc_set_afterg3_en(const bool on) -{ - uint8_t reg8; - uint8_t *const pmcbase = pmc_mmio_regs(); - - reg8 = read8(pmcbase + GEN_PMCON_A); - if (on) - reg8 &= ~SLEEP_AFTER_POWER_FAIL; - else - reg8 |= SLEEP_AFTER_POWER_FAIL; - write8(pmcbase + GEN_PMCON_A, reg8); -} From 2eb37453e56f3c0dc2dd7c1f23c26af080cdac7c Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 10:01:36 -0800 Subject: [PATCH 663/789] soc/intel/meteorlake: Use common pmutil driver Migrate Meteor Lake to use the common PMC utility driver instead of maintaining platform-specific pmutil.c code. This change: - Enables SOC_INTEL_COMMON_FEATURE_PMUTIL in Kconfig - Removes platform-specific pmutil.c - Removes pmutil.c from Makefile.mk The common driver provides all necessary functionality through the generic config_t interface, eliminating ~290 lines of duplicated code. Change-Id: I1c46a517420c8ea7410c4ed7e8e7b761d4399cf9 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91240 Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/meteorlake/Kconfig | 1 + src/soc/intel/meteorlake/Makefile.mk | 2 - src/soc/intel/meteorlake/include/soc/pm.h | 3 - src/soc/intel/meteorlake/ioe_pmc.c | 5 + src/soc/intel/meteorlake/pmutil.c | 286 ---------------------- 5 files changed, 6 insertions(+), 291 deletions(-) delete mode 100644 src/soc/intel/meteorlake/pmutil.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 6ec4c9aaa7..1ec20d25de 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -89,6 +89,7 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_PMUTIL select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index a6c77a8bdd..19ffa96d0e 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -6,7 +6,6 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += pmutil.c all-y += gpio.c bootblock-y += bootblock/bootblock.c @@ -44,7 +43,6 @@ ramstage-y += soc_info.c smm-y += elog.c smm-y += gpio.c smm-y += p2sb.c -smm-y += pmutil.c smm-y += smihandler.c smm-y += soc_info.c smm-y += xhci.c diff --git a/src/soc/intel/meteorlake/include/soc/pm.h b/src/soc/intel/meteorlake/include/soc/pm.h index 7474cdd8bc..c486232e7d 100644 --- a/src/soc/intel/meteorlake/include/soc/pm.h +++ b/src/soc/intel/meteorlake/include/soc/pm.h @@ -150,9 +150,6 @@ struct chipset_power_state { /* Get base address PMC memory mapped registers. */ uint8_t *pmc_mmio_regs(void); -/* Get base address IOE.PMC memory mapped registers. */ -uint8_t *ioe_pmc_mmio_regs(void); - /* Get base address of TCO I/O registers. */ uint16_t smbus_tco_regs(void); diff --git a/src/soc/intel/meteorlake/ioe_pmc.c b/src/soc/intel/meteorlake/ioe_pmc.c index 418c4a5535..e2fb49be4d 100644 --- a/src/soc/intel/meteorlake/ioe_pmc.c +++ b/src/soc/intel/meteorlake/ioe_pmc.c @@ -5,6 +5,11 @@ #include #include +static uint8_t *ioe_pmc_mmio_regs(void) +{ + return (void *)(uintptr_t)IOE_PWRM_BASE_ADDRESS; +} + static void ioe_pmc_read_resources(struct device *dev) { /* Add the fixed MMIO resource */ diff --git a/src/soc/intel/meteorlake/pmutil.c b/src/soc/intel/meteorlake/pmutil.c deleted file mode 100644 index a0bba92f11..0000000000 --- a/src/soc/intel/meteorlake/pmutil.c +++ /dev/null @@ -1,286 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * Helper functions for dealing with power management registers - * and the differences between PCH variants. - */ - -#define __SIMPLE_DEVICE__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * SMI - */ -const char *const *soc_smi_sts_array(size_t *a) -{ - static const char *const smi_sts_bits[] = { - [BIOS_STS_BIT] = "BIOS", - [LEGACY_USB_STS_BIT] = "LEGACY_USB", - [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI", - [APM_STS_BIT] = "APM", - [SWSMI_TMR_STS_BIT] = "SWSMI_TMR", - [PM1_STS_BIT] = "PM1", - [GPE0_STS_BIT] = "GPE0", - [GPIO_STS_BIT] = "GPI", - [MCSMI_STS_BIT] = "MCSMI", - [DEVMON_STS_BIT] = "DEVMON", - [TCO_STS_BIT] = "TCO", - [PERIODIC_STS_BIT] = "PERIODIC", - [SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI", - [SMBUS_SMI_STS_BIT] = "SMBUS_SMI", - [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI", - [MONITOR_STS_BIT] = "MONITOR", - [SPI_SMI_STS_BIT] = "SPI", - [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK", - [ESPI_SMI_STS_BIT] = "ESPI_SMI", - }; - - *a = ARRAY_SIZE(smi_sts_bits); - return smi_sts_bits; -} - -/* - * TCO - */ -const char *const *soc_tco_sts_array(size_t *a) -{ - static const char *const tco_sts_bits[] = { - [0] = "NMI2SMI", - [1] = "SW_TCO", - [2] = "TCO_INT", - [3] = "TIMEOUT", - [7] = "NEWCENTURY", - [8] = "BIOSWR", - [9] = "DMISCI", - [10] = "DMISMI", - [12] = "DMISERR", - [13] = "SLVSEL", - [16] = "INTRD_DET", - [17] = "SECOND_TO", - [18] = "BOOT", - [20] = "SMLINK_SLV" - }; - - *a = ARRAY_SIZE(tco_sts_bits); - return tco_sts_bits; -} - -/* - * GPE0 - */ -const char *const *soc_std_gpe_sts_array(size_t *a) -{ - static const char *const gpe_sts_bits[] = { - [1] = "HOTPLUG", - [2] = "SWGPE", - [6] = "TCO_SCI", - [7] = "SMB_WAK", - [9] = "PCI_EXP", - [10] = "BATLOW", - [11] = "PME", - [12] = "ME", - [13] = "PME_B0", - [14] = "eSPI", - [15] = "GPIO Tier-2", - [16] = "LAN_WAKE", - [18] = "WADT" - }; - - *a = ARRAY_SIZE(gpe_sts_bits); - return gpe_sts_bits; -} - -void pmc_set_disb(void) -{ - /* Set the DISB after DRAM init */ - uint8_t disb_val; - /* Only care about bits [23:16] of register GEN_PMCON_A */ - uint8_t *addr = (uint8_t *)(pmc_mmio_regs() + GEN_PMCON_A + 2); - - disb_val = read8(addr); - disb_val |= (DISB >> 16); - - /* Don't clear bits that are write-1-to-clear */ - disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16); - write8(addr, disb_val); -} - -/* - * PMC controller gets hidden from PCI bus - * during FSP-Silicon init call. Hence PWRMBASE - * can't be accessible using PCI configuration space - * read/write. - */ -uint8_t *pmc_mmio_regs(void) -{ - return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS; -} - -uint8_t *ioe_pmc_mmio_regs(void) -{ - return (void *)(uintptr_t)IOE_PWRM_BASE_ADDRESS; -} - -uintptr_t soc_read_pmc_base(void) -{ - return (uintptr_t)pmc_mmio_regs(); -} - -uint32_t *soc_pmc_etr_addr(void) -{ - return (uint32_t *)(soc_read_pmc_base() + ETR); -} - -static void pmc_gpe0_different_values(const struct soc_intel_meteorlake_config *config) -{ - bool all_zero = (config->pmc_gpe0_dw0 == 0) && - (config->pmc_gpe0_dw1 == 0) && - (config->pmc_gpe0_dw2 == 0); - - /* Check if all values are different AND not all zero */ - bool all_different = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) && - (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) && - (config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2); - - assert(all_different || all_zero); -} - -void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) -{ - DEVTREE_CONST struct soc_intel_meteorlake_config *config; - - config = config_of_soc(); - - pmc_gpe0_different_values(config); - - /* Assign to out variable */ - *dw0 = config->pmc_gpe0_dw0; - *dw1 = config->pmc_gpe0_dw1; - *dw2 = config->pmc_gpe0_dw2; -} - -static int rtc_failed(uint32_t gen_pmcon_b) -{ - return !!(gen_pmcon_b & RTC_BATTERY_DEAD); -} - -int soc_get_rtc_failed(void) -{ - const struct chipset_power_state *ps; - - if (acpi_fetch_pm_state(&ps, PS_CLAIMER_RTC) < 0) - return 1; - - return rtc_failed(ps->gen_pmcon_b); -} - -int vbnv_cmos_failed(void) -{ - return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B)); -} - -static inline int deep_s3_enabled(void) -{ - uint32_t deep_s3_pol; - - deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL); - return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS)); -} - -/* Return 0, 3, or 5 to indicate the previous sleep state. */ -int soc_prev_sleep_state(const struct chipset_power_state *ps, int prev_sleep_state) -{ - /* - * Check for any power failure to determine if this a wake from - * S5 because the PCH does not set the WAK_STS bit when waking - * from a true G3 state. - */ - if (!(ps->pm1_sts & WAK_STS) && (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR))) - prev_sleep_state = ACPI_S5; - - /* - * If waking from S3 determine if deep S3 is enabled. If not, - * need to check both deep sleep well and normal suspend well. - * Otherwise just check deep sleep well. - */ - if (prev_sleep_state == ACPI_S3) { - /* PWR_FLR represents deep sleep power well loss. */ - uint32_t mask = PWR_FLR; - - /* If deep s3 isn't enabled check the suspend well too. */ - if (!deep_s3_enabled()) - mask |= SUS_PWR_FLR; - - if (ps->gen_pmcon_a & mask) - prev_sleep_state = ACPI_S5; - } - - return prev_sleep_state; -} - -void soc_fill_power_state(struct chipset_power_state *ps) -{ - uint8_t *pmc; - - ps->tco1_sts = tco_read_reg(TCO1_STS); - ps->tco2_sts = tco_read_reg(TCO2_STS); - - printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", ps->tco1_sts, ps->tco2_sts); - - pmc = pmc_mmio_regs(); - ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A); - ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B); - ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); - ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); - ps->hpr_cause0 = read32(pmc + HPR_CAUSE0); - - printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", - ps->gen_pmcon_a, ps->gen_pmcon_b); - - printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", - ps->gblrst_cause[0], ps->gblrst_cause[1]); - - printk(BIOS_DEBUG, "HPR_CAUSE0: %08x\n", ps->hpr_cause0); -} - -/* STM Support */ -uint16_t get_pmbase(void) -{ - return (uint16_t)ACPI_BASE_ADDRESS; -} - -/* - * Set which power state system will be after reapplying - * the power (from G3 State) - */ -void pmc_soc_set_afterg3_en(const bool on) -{ - uint8_t reg8; - uint8_t *const pmcbase = pmc_mmio_regs(); - - reg8 = read8(pmcbase + GEN_PMCON_A); - if (on) - reg8 &= ~SLEEP_AFTER_POWER_FAIL; - else - reg8 |= SLEEP_AFTER_POWER_FAIL; - write8(pmcbase + GEN_PMCON_A, reg8); -} From 4b73479c3821ae14d7811c4b5870042d8b238d00 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 10:21:09 -0800 Subject: [PATCH 664/789] soc/intel/common/feature/smihandler: Add common PCH client SMI handler Add a common implementation of SMI handler code for PCH client platforms to reduce code duplication across Alder Lake, Meteor Lake, Panther Lake, and Tiger Lake platforms. This implementation consolidates: - smihandler_soc_disable_busmaster(): Skip disabling PMC bus master - southbridge_smi array: Standard SMI handler mappings The common driver uses a platform-specific macro that must be defined in each platform's soc/pci_devs.h header: - SOC_PMC_DEV: PMC PCI device identifier This change enables consolidation of nearly identical smihandler.c files across four platforms, reducing duplication by approximately 100+ lines. Change-Id: I9ecb65b7ea4feafb8acbaf5798bbeaeb80b7c24a Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91293 Reviewed-by: Huang, Cliff Tested-by: build bot (Jenkins) --- .../intel/common/feature/smihandler/Kconfig | 9 ++++++ .../common/feature/smihandler/Makefile.mk | 3 ++ .../common/feature/smihandler/smihandler.c | 29 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 src/soc/intel/common/feature/smihandler/Kconfig create mode 100644 src/soc/intel/common/feature/smihandler/Makefile.mk create mode 100644 src/soc/intel/common/feature/smihandler/smihandler.c diff --git a/src/soc/intel/common/feature/smihandler/Kconfig b/src/soc/intel/common/feature/smihandler/Kconfig new file mode 100644 index 0000000000..a927e1828e --- /dev/null +++ b/src/soc/intel/common/feature/smihandler/Kconfig @@ -0,0 +1,9 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_SMIHANDLER + bool + help + Select this if the platform supports common PCH client SMI handler + implementation. This consolidates SMI handler code for PCH client + platforms including PMC bus master control and standard SMI handler + mappings. The platform must define SOC_PMC_DEV in soc/pci_devs.h. diff --git a/src/soc/intel/common/feature/smihandler/Makefile.mk b/src/soc/intel/common/feature/smihandler/Makefile.mk new file mode 100644 index 0000000000..cda860ed0b --- /dev/null +++ b/src/soc/intel/common/feature/smihandler/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +smm-$(CONFIG_SOC_INTEL_COMMON_FEATURE_SMIHANDLER) += smihandler.c diff --git a/src/soc/intel/common/feature/smihandler/smihandler.c b/src/soc/intel/common/feature/smihandler/smihandler.c new file mode 100644 index 0000000000..35726049d0 --- /dev/null +++ b/src/soc/intel/common/feature/smihandler/smihandler.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +int smihandler_soc_disable_busmaster(pci_devfn_t dev) +{ + /* Skip disabling PMC bus master to keep IO decode enabled */ + if (dev == SOC_PMC_DEV) + return 0; + return 1; +} + +const smi_handler_t southbridge_smi[SMI_STS_BITS] = { + [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep, + [APM_STS_BIT] = smihandler_southbridge_apmc, + [PM1_STS_BIT] = smihandler_southbridge_pm1, + [GPE0_STS_BIT] = smihandler_southbridge_gpe0, + [GPIO_STS_BIT] = smihandler_southbridge_gpi, + [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi, + [MCSMI_STS_BIT] = smihandler_southbridge_mc, +#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE) + [TCO_STS_BIT] = smihandler_southbridge_tco, +#endif + [PERIODIC_STS_BIT] = smihandler_southbridge_periodic, + [MONITOR_STS_BIT] = smihandler_southbridge_monitor, +}; From f0021f84ec0526f82ba871f134c073605351196a Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 10:46:33 -0800 Subject: [PATCH 665/789] soc/intel/alderlake: Use common PCH client SMI handler Migrate Alder Lake to use the common PCH client SMI handler implementation from the Intel common feature code. This change eliminates platform-specific code by leveraging the shared smihandler.c driver. This commit: - Adds SOC_PMC_DEV macro definition to soc/pci_devs.h - Selects SOC_INTEL_COMMON_FEATURE_SMIHANDLER Kconfig - Removes src/soc/intel/alderlake/smihandler.c - Updates Makefile to remove smihandler.c compilation Alder Lake uses PCH_DEV_PMC as the PMC device identifier. Change-Id: Icbbc7af25e73e952c9b5f811cf0bbe01efe3ae94 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91294 Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/alderlake/Kconfig | 1 + src/soc/intel/alderlake/Makefile.mk | 1 - .../intel/alderlake/include/soc/pci_devs.h | 1 + src/soc/intel/alderlake/smihandler.c | 30 ------------------- 4 files changed, 2 insertions(+), 31 deletions(-) delete mode 100644 src/soc/intel/alderlake/smihandler.c diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 1568e5b595..a925cf09a0 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -88,6 +88,7 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_PMUTIL + select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index 210d84592d..45c374849d 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -39,7 +39,6 @@ ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c smm-y += elog.c smm-y += p2sb.c -smm-y += smihandler.c smm-y += xhci.c ifeq ($(CONFIG_SOC_INTEL_ALDERLAKE_PCH_S),y) diff --git a/src/soc/intel/alderlake/include/soc/pci_devs.h b/src/soc/intel/alderlake/include/soc/pci_devs.h index 15ec661870..27134c74a5 100644 --- a/src/soc/intel/alderlake/include/soc/pci_devs.h +++ b/src/soc/intel/alderlake/include/soc/pci_devs.h @@ -283,6 +283,7 @@ #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_PMC_DEV PCH_DEV_PMC #endif diff --git a/src/soc/intel/alderlake/smihandler.c b/src/soc/intel/alderlake/smihandler.c deleted file mode 100644 index e1fc5a03ad..0000000000 --- a/src/soc/intel/alderlake/smihandler.c +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -int smihandler_soc_disable_busmaster(pci_devfn_t dev) -{ - /* Skip disabling PMC bus master to keep IO decode enabled */ - if (dev == PCH_DEV_PMC) - return 0; - return 1; -} - -const smi_handler_t southbridge_smi[SMI_STS_BITS] = { - [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep, - [APM_STS_BIT] = smihandler_southbridge_apmc, - [PM1_STS_BIT] = smihandler_southbridge_pm1, - [GPE0_STS_BIT] = smihandler_southbridge_gpe0, - [GPIO_STS_BIT] = smihandler_southbridge_gpi, - [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi, - [MCSMI_STS_BIT] = smihandler_southbridge_mc, -#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE) - [TCO_STS_BIT] = smihandler_southbridge_tco, -#endif - [PERIODIC_STS_BIT] = smihandler_southbridge_periodic, - [MONITOR_STS_BIT] = smihandler_southbridge_monitor, -}; From eb205e379ac0c46eb9fce1d037add0d55a1710e5 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 10:47:16 -0800 Subject: [PATCH 666/789] soc/intel/meteorlake: Use common PCH client SMI handler Migrate Meteor Lake to use the common PCH client SMI handler implementation from the Intel common feature code. This change eliminates platform-specific code by leveraging the shared smihandler.c driver. This commit: - Adds SOC_PMC_DEV macro definition to soc/pci_devs.h - Selects SOC_INTEL_COMMON_FEATURE_SMIHANDLER Kconfig - Removes src/soc/intel/meteorlake/smihandler.c - Updates Makefile to remove smihandler.c compilation Meteor Lake uses PCI_DEV_PMC as the PMC device identifier. Change-Id: Ia21a6ee0c6fbee6d4ffcfce5fdbe9b3bdf5fcece Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91295 Reviewed-by: Huang, Cliff Tested-by: build bot (Jenkins) --- src/soc/intel/meteorlake/Kconfig | 1 + src/soc/intel/meteorlake/Makefile.mk | 1 - .../intel/meteorlake/include/soc/pci_devs.h | 1 + src/soc/intel/meteorlake/smihandler.c | 30 ------------------- 4 files changed, 2 insertions(+), 31 deletions(-) delete mode 100644 src/soc/intel/meteorlake/smihandler.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 1ec20d25de..25d9d68e44 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -90,6 +90,7 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_PMUTIL + select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index 19ffa96d0e..b2c2429476 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -43,7 +43,6 @@ ramstage-y += soc_info.c smm-y += elog.c smm-y += gpio.c smm-y += p2sb.c -smm-y += smihandler.c smm-y += soc_info.c smm-y += xhci.c diff --git a/src/soc/intel/meteorlake/include/soc/pci_devs.h b/src/soc/intel/meteorlake/include/soc/pci_devs.h index 17f4526538..61485fc450 100644 --- a/src/soc/intel/meteorlake/include/soc/pci_devs.h +++ b/src/soc/intel/meteorlake/include/soc/pci_devs.h @@ -243,5 +243,6 @@ #define SA_DEVFN_IGD PCI_DEVFN_IGD #define SOC_I2C_DEVFN(n) PCI_DEVFN_I2C##n #define SOC_GSPI_DEVFN(n) PCI_DEVFN_GSPI##n +#define SOC_PMC_DEV PCI_DEV_PMC #endif // _SOC_METEORLAKE_PCI_DEVS_H_ diff --git a/src/soc/intel/meteorlake/smihandler.c b/src/soc/intel/meteorlake/smihandler.c deleted file mode 100644 index 6a21f0a757..0000000000 --- a/src/soc/intel/meteorlake/smihandler.c +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -int smihandler_soc_disable_busmaster(pci_devfn_t dev) -{ - /* Skip disabling PMC bus master to keep IO decode enabled */ - if (dev == PCI_DEV_PMC) - return 0; - return 1; -} - -const smi_handler_t southbridge_smi[SMI_STS_BITS] = { - [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep, - [APM_STS_BIT] = smihandler_southbridge_apmc, - [PM1_STS_BIT] = smihandler_southbridge_pm1, - [GPE0_STS_BIT] = smihandler_southbridge_gpe0, - [GPIO_STS_BIT] = smihandler_southbridge_gpi, - [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi, - [MCSMI_STS_BIT] = smihandler_southbridge_mc, -#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE) - [TCO_STS_BIT] = smihandler_southbridge_tco, -#endif - [PERIODIC_STS_BIT] = smihandler_southbridge_periodic, - [MONITOR_STS_BIT] = smihandler_southbridge_monitor, -}; From 402da237bcc855811079f356e6c047b82884ce9b Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 10:47:44 -0800 Subject: [PATCH 667/789] soc/intel/pantherlake: Use common PCH client SMI handler Migrate Panther Lake to use the common PCH client SMI handler implementation from the Intel common feature code. This change eliminates platform-specific code by leveraging the shared smihandler.c driver. This commit: - Adds SOC_PMC_DEV macro definition to soc/pci_devs.h - Selects SOC_INTEL_COMMON_FEATURE_SMIHANDLER Kconfig - Removes src/soc/intel/pantherlake/smihandler.c - Updates Makefile to remove smihandler.c compilation Panther Lake uses PCI_DEV_PMC as the PMC device identifier. TEST=Build and boot to the OS on a Fatcat device Change-Id: I32bf4b678e7edda598319086acccc4983edcbe3e Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91296 Reviewed-by: Huang, Cliff Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/Kconfig | 1 + src/soc/intel/pantherlake/Makefile.mk | 1 - .../intel/pantherlake/include/soc/pci_devs.h | 1 + src/soc/intel/pantherlake/smihandler.c | 30 ------------------- 4 files changed, 2 insertions(+), 31 deletions(-) delete mode 100644 src/soc/intel/pantherlake/smihandler.c diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index 937fb36a6b..decd4c84c6 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -100,6 +100,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_PMUTIL + select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index 417d27d6d0..7349987e28 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -42,7 +42,6 @@ ramstage-$(CONFIG_DRIVERS_INTEL_TOUCH) += touch.c smm-y += elog.c smm-y += gpio.c smm-y += p2sb.c -smm-y += smihandler.c smm-y += xhci.c CPPFLAGS_common += -I$(src)/soc/intel/pantherlake CPPFLAGS_common += -I$(src)/soc/intel/pantherlake/include diff --git a/src/soc/intel/pantherlake/include/soc/pci_devs.h b/src/soc/intel/pantherlake/include/soc/pci_devs.h index 3a41280a26..1834dec9a5 100644 --- a/src/soc/intel/pantherlake/include/soc/pci_devs.h +++ b/src/soc/intel/pantherlake/include/soc/pci_devs.h @@ -258,5 +258,6 @@ #define SA_DEVFN_IGD PCI_DEVFN_IGD #define SOC_I2C_DEVFN(n) PCI_DEVFN_I2C##n #define SOC_GSPI_DEVFN(n) PCI_DEVFN_GSPI##n +#define SOC_PMC_DEV PCI_DEV_PMC #endif // _SOC_PANTHERLAKE_PCI_DEVS_H_ diff --git a/src/soc/intel/pantherlake/smihandler.c b/src/soc/intel/pantherlake/smihandler.c deleted file mode 100644 index 6a21f0a757..0000000000 --- a/src/soc/intel/pantherlake/smihandler.c +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -int smihandler_soc_disable_busmaster(pci_devfn_t dev) -{ - /* Skip disabling PMC bus master to keep IO decode enabled */ - if (dev == PCI_DEV_PMC) - return 0; - return 1; -} - -const smi_handler_t southbridge_smi[SMI_STS_BITS] = { - [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep, - [APM_STS_BIT] = smihandler_southbridge_apmc, - [PM1_STS_BIT] = smihandler_southbridge_pm1, - [GPE0_STS_BIT] = smihandler_southbridge_gpe0, - [GPIO_STS_BIT] = smihandler_southbridge_gpi, - [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi, - [MCSMI_STS_BIT] = smihandler_southbridge_mc, -#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE) - [TCO_STS_BIT] = smihandler_southbridge_tco, -#endif - [PERIODIC_STS_BIT] = smihandler_southbridge_periodic, - [MONITOR_STS_BIT] = smihandler_southbridge_monitor, -}; From d03957e10fe0645b52a59b652226925d11b300cb Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 10:48:14 -0800 Subject: [PATCH 668/789] soc/intel/tigerlake: Use common PCH client SMI handler Migrate Tiger Lake to use the common PCH client SMI handler implementation from the Intel common feature code. This change eliminates platform-specific code by leveraging the shared smihandler.c driver. This commit: - Adds SOC_PMC_DEV macro definition to soc/pci_devs.h - Selects SOC_INTEL_COMMON_FEATURE_SMIHANDLER Kconfig - Removes src/soc/intel/tigerlake/smihandler.c - Updates Makefile to remove smihandler.c compilation Tiger Lake uses PCH_DEV_PMC as the PMC device identifier. Change-Id: Ibe06e4d100b2715aeccfe0ff85dc944ab6cd80fc Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91297 Reviewed-by: Huang, Cliff Tested-by: build bot (Jenkins) --- src/soc/intel/tigerlake/Kconfig | 1 + src/soc/intel/tigerlake/Makefile.mk | 1 - .../intel/tigerlake/include/soc/pci_devs.h | 1 + src/soc/intel/tigerlake/smihandler.c | 30 ------------------- 4 files changed, 2 insertions(+), 31 deletions(-) delete mode 100644 src/soc/intel/tigerlake/smihandler.c diff --git a/src/soc/intel/tigerlake/Kconfig b/src/soc/intel/tigerlake/Kconfig index a470d7cde5..192444ec11 100644 --- a/src/soc/intel/tigerlake/Kconfig +++ b/src/soc/intel/tigerlake/Kconfig @@ -75,6 +75,7 @@ config SOC_INTEL_TIGERLAKE select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF diff --git a/src/soc/intel/tigerlake/Makefile.mk b/src/soc/intel/tigerlake/Makefile.mk index cf6cdc2ec2..5caff77277 100644 --- a/src/soc/intel/tigerlake/Makefile.mk +++ b/src/soc/intel/tigerlake/Makefile.mk @@ -38,7 +38,6 @@ ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog_lib.c smm-y += p2sb.c smm-y += pmutil.c -smm-y += smihandler.c smm-y += elog.c smm-y += xhci.c diff --git a/src/soc/intel/tigerlake/include/soc/pci_devs.h b/src/soc/intel/tigerlake/include/soc/pci_devs.h index 2f36bd159c..8b49773354 100644 --- a/src/soc/intel/tigerlake/include/soc/pci_devs.h +++ b/src/soc/intel/tigerlake/include/soc/pci_devs.h @@ -250,6 +250,7 @@ #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_PMC_DEV PCH_DEV_PMC #endif diff --git a/src/soc/intel/tigerlake/smihandler.c b/src/soc/intel/tigerlake/smihandler.c deleted file mode 100644 index e1fc5a03ad..0000000000 --- a/src/soc/intel/tigerlake/smihandler.c +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -int smihandler_soc_disable_busmaster(pci_devfn_t dev) -{ - /* Skip disabling PMC bus master to keep IO decode enabled */ - if (dev == PCH_DEV_PMC) - return 0; - return 1; -} - -const smi_handler_t southbridge_smi[SMI_STS_BITS] = { - [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep, - [APM_STS_BIT] = smihandler_southbridge_apmc, - [PM1_STS_BIT] = smihandler_southbridge_pm1, - [GPE0_STS_BIT] = smihandler_southbridge_gpe0, - [GPIO_STS_BIT] = smihandler_southbridge_gpi, - [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi, - [MCSMI_STS_BIT] = smihandler_southbridge_mc, -#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE) - [TCO_STS_BIT] = smihandler_southbridge_tco, -#endif - [PERIODIC_STS_BIT] = smihandler_southbridge_periodic, - [MONITOR_STS_BIT] = smihandler_southbridge_monitor, -}; From c940d20696b4200bfa47c48f3f86a6d8f9ff6147 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Thu, 26 Feb 2026 11:03:57 -0800 Subject: [PATCH 669/789] soc/intel: Consolidate common code macro definitions in pci_devs.h Move the SOC_I2C_DEVFN(n) macro definitions that were duplicated in a separate "for common code" section at the end of multiple platform pci_devs.h files. Platforms affected: - Alder Lake - Cannon Lake - Elkhart Lake - Jasper Lake - Skylake - Tiger Lake Change-Id: Ie3b3e6a25b0dba1beeadad1ab9acf59cafdbcf4a Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91446 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/alderlake/include/soc/pci_devs.h | 4 +--- src/soc/intel/cannonlake/include/soc/pci_devs.h | 4 +--- src/soc/intel/elkhartlake/include/soc/pci_devs.h | 4 +--- src/soc/intel/jasperlake/include/soc/pci_devs.h | 4 +--- src/soc/intel/skylake/include/soc/pci_devs.h | 4 +--- src/soc/intel/tigerlake/include/soc/pci_devs.h | 4 +--- 6 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/soc/intel/alderlake/include/soc/pci_devs.h b/src/soc/intel/alderlake/include/soc/pci_devs.h index 27134c74a5..a3f1d7520d 100644 --- a/src/soc/intel/alderlake/include/soc/pci_devs.h +++ b/src/soc/intel/alderlake/include/soc/pci_devs.h @@ -284,8 +284,6 @@ #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n #define SOC_PMC_DEV PCH_DEV_PMC +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n #endif - -/* for common code */ -#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n diff --git a/src/soc/intel/cannonlake/include/soc/pci_devs.h b/src/soc/intel/cannonlake/include/soc/pci_devs.h index c2d7b411ba..a099294cf2 100644 --- a/src/soc/intel/cannonlake/include/soc/pci_devs.h +++ b/src/soc/intel/cannonlake/include/soc/pci_devs.h @@ -209,8 +209,6 @@ #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n #endif - -/* for common code */ -#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n diff --git a/src/soc/intel/elkhartlake/include/soc/pci_devs.h b/src/soc/intel/elkhartlake/include/soc/pci_devs.h index e4e899b881..1dd6d6c678 100644 --- a/src/soc/intel/elkhartlake/include/soc/pci_devs.h +++ b/src/soc/intel/elkhartlake/include/soc/pci_devs.h @@ -252,8 +252,6 @@ #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n #endif - -/* for common code */ -#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n diff --git a/src/soc/intel/jasperlake/include/soc/pci_devs.h b/src/soc/intel/jasperlake/include/soc/pci_devs.h index f2e6dd4e7d..4267d9bfdf 100644 --- a/src/soc/intel/jasperlake/include/soc/pci_devs.h +++ b/src/soc/intel/jasperlake/include/soc/pci_devs.h @@ -198,8 +198,6 @@ #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n #endif - -/* for common code */ -#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n diff --git a/src/soc/intel/skylake/include/soc/pci_devs.h b/src/soc/intel/skylake/include/soc/pci_devs.h index 557dc58c55..876170cfce 100644 --- a/src/soc/intel/skylake/include/soc/pci_devs.h +++ b/src/soc/intel/skylake/include/soc/pci_devs.h @@ -192,8 +192,6 @@ #define PCI_DEVFN_UART1 PCH_DEVFN_UART1 #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n #endif - -/* for common code */ -#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n diff --git a/src/soc/intel/tigerlake/include/soc/pci_devs.h b/src/soc/intel/tigerlake/include/soc/pci_devs.h index 8b49773354..66eff3490c 100644 --- a/src/soc/intel/tigerlake/include/soc/pci_devs.h +++ b/src/soc/intel/tigerlake/include/soc/pci_devs.h @@ -251,8 +251,6 @@ #define PCI_DEVFN_UART2 PCH_DEVFN_UART2 #define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n #define SOC_PMC_DEV PCH_DEV_PMC +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n #endif - -/* for common code */ -#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n From 19df8826d751cc82a7ec1fb9a679b7ebdfbb22f5 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 17 Feb 2026 08:55:51 +0000 Subject: [PATCH 670/789] mb/starlabs/starlite_adl: Disable the card reader by default As the card reader isn't on a dedicated USB interface for all variants for the StarLite, default to disable to ensure that an unused USB port isn't enabled. Change-Id: I2176fd6556797e468012c98f7e482b9573b5e3f7 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/91496 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/common/include/common/cfr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/starlabs/common/include/common/cfr.h b/src/mainboard/starlabs/common/include/common/cfr.h index b62b39701e..0deb7eeb7e 100644 --- a/src/mainboard/starlabs/common/include/common/cfr.h +++ b/src/mainboard/starlabs/common/include/common/cfr.h @@ -37,7 +37,7 @@ static const struct sm_object card_reader = SM_DECLARE_BOOL({ .opt_name = "card_reader", .ui_name = "Card Reader", .ui_helptext = "Enable or disable the built-in card reader", - .default_value = true, + .default_value = !CONFIG(BOARD_STARLABS_LITE_ADL), }, WITH_CALLBACK(cfr_card_reader_update)); static const struct sm_object display_native_res = SM_DECLARE_BOOL({ From 56f588eec69a81f44b58a5ad180f380115085cf6 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 17 Feb 2026 20:20:33 +0000 Subject: [PATCH 671/789] mb/starlabs/*: Don't consider fan presence for default power profile Set the default power profile to Performance, regardless of whether there is a fan present. Change-Id: Id1d624355f9f08b5abb154e26026e70675322ddb Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/91497 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/common/include/common/cfr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/starlabs/common/include/common/cfr.h b/src/mainboard/starlabs/common/include/common/cfr.h index 0deb7eeb7e..89405fd2b7 100644 --- a/src/mainboard/starlabs/common/include/common/cfr.h +++ b/src/mainboard/starlabs/common/include/common/cfr.h @@ -103,7 +103,7 @@ static const struct sm_object power_profile = SM_DECLARE_ENUM({ .opt_name = "power_profile", .ui_name = "Power Profile", .ui_helptext = "Select whether to maximize performance, battery life or both.", - .default_value = CONFIG(EC_STARLABS_FAN) ? PP_PERFORMANCE : PP_BALANCED, + .default_value = PP_PERFORMANCE, .values = (const struct sm_enum_value[]) { { "Power Saver", PP_POWER_SAVER }, { "Balanced", PP_BALANCED }, From 3ea94fb2dc6d0bde9878967205da2094a5a2b1ca Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Tue, 17 Feb 2026 20:29:09 +0000 Subject: [PATCH 672/789] mb/starlabs/starfighter: Enable the card reader Enable the card reader USB port, along with ACPI driver info and the CFR option to control it. Change-Id: I30dd26438f0a7b355061a45b9ffb7f447c89a751 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/91498 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/starfighter/cfr.c | 1 + .../starlabs/starfighter/variants/mtl/devicetree.cb | 11 ++++++++++- .../starlabs/starfighter/variants/rpl/devicetree.cb | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/mainboard/starlabs/starfighter/cfr.c b/src/mainboard/starlabs/starfighter/cfr.c index cb092cae33..6cdd98b189 100644 --- a/src/mainboard/starlabs/starfighter/cfr.c +++ b/src/mainboard/starlabs/starfighter/cfr.c @@ -40,6 +40,7 @@ static struct sm_obj_form display_group = { static struct sm_obj_form io_expansion_group = { .ui_name = "I/O / Expansion", .obj_list = (const struct sm_object *[]) { + &card_reader, &thunderbolt, NULL }, diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb b/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb index 23ad639cc2..b7b8cedf85 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb +++ b/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb @@ -160,6 +160,9 @@ chip soc/intel/meteorlake register "usb2_ports[6]" = "USB2_PORT_SHORT(OC_SKIP)" register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" + # Card Reader + register "usb2_ports[3]" = "USB2_PORT_SHORT(OC_SKIP)" + # Internal Webcam 9070 mil register "usb2_ports[CONFIG_CCD_PORT]" = "USB2_PORT_MID(OC_SKIP)" @@ -207,9 +210,15 @@ chip soc/intel/meteorlake device ref usb3_port2 on end end chip drivers/usb/acpi - register "desc" = ""Internal Webcam"" + register "desc" = ""Card Reader"" register "type" = "UPC_TYPE_INTERNAL" register "group" = "ACPI_PLD_GROUP(0, 4)" + device ref usb2_port4 on end + end + chip drivers/usb/acpi + register "desc" = ""Internal Webcam"" + register "type" = "UPC_TYPE_INTERNAL" + register "group" = "ACPI_PLD_GROUP(0, 5)" device ref usb2_port5 on end end chip drivers/usb/acpi diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb b/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb index c911b05a4b..080bde0a19 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb +++ b/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb @@ -139,6 +139,9 @@ chip soc/intel/alderlake register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" + # Card Reader + register "usb2_ports[3]" = "USB2_PORT_SHORT(OC_SKIP)" + # Internal Bluetooth register "usb2_ports[9]" = "USB2_PORT_MID(OC_SKIP)" @@ -182,6 +185,12 @@ chip soc/intel/alderlake register "group" = "ACPI_PLD_GROUP(0, 3)" device ref usb3_port2 on end end + chip drivers/usb/acpi + register "desc" = ""Card Reader"" + register "type" = "UPC_TYPE_INTERNAL" + register "group" = "ACPI_PLD_GROUP(0, 4)" + device ref usb2_port4 on end + end chip drivers/usb/acpi register "desc" = ""Internal Webcam"" register "group" = "ACPI_PLD_GROUP(0, 4)" From e02dc13b87e2ab32a5736ca464b6c6847c7c2274 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Sun, 15 Feb 2026 21:18:19 +0000 Subject: [PATCH 673/789] mainboard/starlabs: move Byte under adl/ Move the Star Labs Byte (Mk II / Mk III) into the ADL grouping under src/mainboard/starlabs/adl/. Like StarBook Horizon, model differences live under src/mainboard/starlabs/adl/variants/ using SKU-style variant directories to share common configuration. Byte Mk II (ADL) and Byte Mk III (TWL) share a single "y2" variant directory. Update MAINBOARD_DIR and CMOS layout handling so binary blob paths and NVRAM options continue to resolve correctly. Update the documentation to reflect the new blobs path. Note that BUILD_TIMELESS ROM hashes change since MAINBOARD_DIR is embedded in the CBFS config file. BUG=None TEST=BUILD_TIMELESS=1 build STARLABS_BYTE_ADL Change-Id: I4b6be115a4ab2316d5ca4cc8e656e3643518273e Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/91255 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- Documentation/mainboard/index.md | 2 +- .../starlabs/{byte_adl.md => byte.md} | 8 +- src/mainboard/starlabs/adl/Kconfig | 109 +++++++++++----- src/mainboard/starlabs/adl/Kconfig.name | 8 +- src/mainboard/starlabs/adl/board_info.txt | 2 +- src/mainboard/starlabs/adl/cfr.c | 12 ++ src/mainboard/starlabs/adl/dsdt.asl | 5 +- .../adl/{ => variants/hz}/cmos.layout | 0 .../mk_ii => adl/variants/y2}/Makefile.mk | 2 + .../mk_ii => adl/variants/y2}/board.fmd | 0 .../{byte_adl => adl/variants/y2}/cmos.layout | 0 .../mk_ii => adl/variants/y2}/data.vbt | Bin .../mk_ii => adl/variants/y2}/devicetree.cb | 0 .../mk_ii => adl/variants/y2}/devtree.c | 0 .../variants/mk_ii => adl/variants/y2}/gpio.c | 2 +- .../mk_ii => adl/variants/y2}/hda_verb.c | 0 .../mk_ii => adl/variants/y2}/ramstage.c | 0 .../mk_ii => adl/variants/y2}/romstage.c | 0 .../variants/y2}/smihandler.c | 0 .../mk_ii => adl/variants/y2}/vboot.fmd | 0 src/mainboard/starlabs/byte_adl/Kconfig | 116 ------------------ src/mainboard/starlabs/byte_adl/Kconfig.name | 7 -- src/mainboard/starlabs/byte_adl/Makefile.mk | 13 -- src/mainboard/starlabs/byte_adl/acpi/ec.asl | 1 - .../starlabs/byte_adl/acpi/mainboard.asl | 5 - .../starlabs/byte_adl/acpi/sleep.asl | 11 -- .../starlabs/byte_adl/acpi/superio.asl | 1 - .../starlabs/byte_adl/board_info.txt | 6 - src/mainboard/starlabs/byte_adl/bootblock.c | 14 --- src/mainboard/starlabs/byte_adl/cfr.c | 100 --------------- src/mainboard/starlabs/byte_adl/dsdt.asl | 42 ------- .../starlabs/byte_adl/include/variants.h | 17 --- src/mainboard/starlabs/byte_adl/mainboard.c | 18 --- src/mainboard/starlabs/byte_adl/vboot.c | 8 -- 34 files changed, 111 insertions(+), 398 deletions(-) rename Documentation/mainboard/starlabs/{byte_adl.md => byte.md} (86%) rename src/mainboard/starlabs/adl/{ => variants/hz}/cmos.layout (100%) rename src/mainboard/starlabs/{byte_adl/variants/mk_ii => adl/variants/y2}/Makefile.mk (79%) rename src/mainboard/starlabs/{byte_adl/variants/mk_ii => adl/variants/y2}/board.fmd (100%) rename src/mainboard/starlabs/{byte_adl => adl/variants/y2}/cmos.layout (100%) rename src/mainboard/starlabs/{byte_adl/variants/mk_ii => adl/variants/y2}/data.vbt (100%) rename src/mainboard/starlabs/{byte_adl/variants/mk_ii => adl/variants/y2}/devicetree.cb (100%) rename src/mainboard/starlabs/{byte_adl/variants/mk_ii => adl/variants/y2}/devtree.c (100%) rename src/mainboard/starlabs/{byte_adl/variants/mk_ii => adl/variants/y2}/gpio.c (99%) rename src/mainboard/starlabs/{byte_adl/variants/mk_ii => adl/variants/y2}/hda_verb.c (100%) rename src/mainboard/starlabs/{byte_adl/variants/mk_ii => adl/variants/y2}/ramstage.c (100%) rename src/mainboard/starlabs/{byte_adl/variants/mk_ii => adl/variants/y2}/romstage.c (100%) rename src/mainboard/starlabs/{byte_adl => adl/variants/y2}/smihandler.c (100%) rename src/mainboard/starlabs/{byte_adl/variants/mk_ii => adl/variants/y2}/vboot.fmd (100%) delete mode 100644 src/mainboard/starlabs/byte_adl/Kconfig delete mode 100644 src/mainboard/starlabs/byte_adl/Kconfig.name delete mode 100644 src/mainboard/starlabs/byte_adl/Makefile.mk delete mode 100644 src/mainboard/starlabs/byte_adl/acpi/ec.asl delete mode 100644 src/mainboard/starlabs/byte_adl/acpi/mainboard.asl delete mode 100644 src/mainboard/starlabs/byte_adl/acpi/sleep.asl delete mode 100644 src/mainboard/starlabs/byte_adl/acpi/superio.asl delete mode 100644 src/mainboard/starlabs/byte_adl/board_info.txt delete mode 100644 src/mainboard/starlabs/byte_adl/bootblock.c delete mode 100644 src/mainboard/starlabs/byte_adl/cfr.c delete mode 100644 src/mainboard/starlabs/byte_adl/dsdt.asl delete mode 100644 src/mainboard/starlabs/byte_adl/include/variants.h delete mode 100644 src/mainboard/starlabs/byte_adl/mainboard.c delete mode 100644 src/mainboard/starlabs/byte_adl/vboot.c diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index 92aec1173f..a90e3f2396 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -359,7 +359,7 @@ StarBook Mk VI StarBook Mk VII (N200) StarBook Mk VII (165H) StarBook Horizon -Byte Mk II +Byte Mk II StarFighter Mk I StarFighter Mk II diff --git a/Documentation/mainboard/starlabs/byte_adl.md b/Documentation/mainboard/starlabs/byte.md similarity index 86% rename from Documentation/mainboard/starlabs/byte_adl.md rename to Documentation/mainboard/starlabs/byte.md index 7805bb5737..4c9a86cb1a 100644 --- a/Documentation/mainboard/starlabs/byte_adl.md +++ b/Documentation/mainboard/starlabs/byte.md @@ -34,7 +34,7 @@ ## Building coreboot -Please follow the [Star Labs build instructions](common/building.md) to build coreboot, using `config.starlabs_byte_adl` as config file. +Please follow the [Star Labs build instructions](common/building.md) to build coreboot, using `config.starlabs_byte_adl` (Byte Mk II) or `config.starlabs_byte_twl` (Byte Mk III) as config file. ### Preliminaries @@ -46,6 +46,10 @@ Prior to building coreboot the following files are required: The files listed below are optional: - Splash screen image in Windows 3.1 BMP format (Logo.bmp) +coreboot expects these binaries under +`3rdparty/blobs/mainboard/starlabs/adl//`, where `` +matches `CONFIG_VARIANT_DIR` (default: `y2`). + These files exist in the correct location in the StarLabsLtd/blobs repo on GitHub which is used in place of the standard 3rdparty/blobs repo. ### Build @@ -55,6 +59,8 @@ The following commands will build a working image: ```bash make distclean make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_byte_adl +# or +make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_byte_twl make ``` diff --git a/src/mainboard/starlabs/adl/Kconfig b/src/mainboard/starlabs/adl/Kconfig index adfa25bb8d..8b5c5d8b64 100644 --- a/src/mainboard/starlabs/adl/Kconfig +++ b/src/mainboard/starlabs/adl/Kconfig @@ -1,23 +1,17 @@ config BOARD_STARLABS_ADL_SERIES def_bool n select AZALIA_USE_LEGACY_VERB_TABLE + select BOARD_ROMSIZE_KB_16384 select CSE_DEFAULT_CFR_OPTION_STATE_DISABLED select DRIVERS_EFI_VARIABLE_STORE - select DRIVERS_GFX_GENERIC - select DRIVERS_I2C_HID select DRIVERS_INTEL_PMC select DRIVERS_OPTION_CFR_ENABLED select EC_STARLABS_MERLIN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES - select HAVE_CMOS_DEFAULT - select HAVE_HDA_DMIC select HAVE_OPTION_TABLE - select HAVE_SPD_IN_CBFS select INTEL_GMA_HAVE_VBT select INTEL_LPSS_UART_FOR_CONSOLE - select MAINBOARD_HAS_TPM2 - select MEMORY_MAPPED_TPM select NO_UART_ON_SUPERIO select PMC_IPC_ACPI_INTERFACE select SOC_INTEL_ALDERLAKE @@ -26,21 +20,43 @@ config BOARD_STARLABS_ADL_SERIES select SOC_INTEL_CRASHLOG select SPD_READ_BY_WORD select SPI_FLASH_WINBOND - select SYSTEM_TYPE_LAPTOP select TPM2 - select TPM_MEASURED_BOOT select VALIDATE_INTEL_DESCRIPTOR config BOARD_STARLABS_ADL_HORIZON - select BOARD_ROMSIZE_KB_16384 select BOARD_STARLABS_ADL_SERIES + select DRIVERS_GFX_GENERIC + select DRIVERS_I2C_HID + select HAVE_CMOS_DEFAULT + select HAVE_HDA_DMIC + select HAVE_SPD_IN_CBFS + select MAINBOARD_HAS_TPM2 + select MEMORY_MAPPED_TPM + select SOC_INTEL_ALDERLAKE_PCH_N + select SYSTEM_TYPE_LAPTOP + select TPM_MEASURED_BOOT + +config BOARD_STARLABS_BYTE_ADL + select BOARD_STARLABS_ADL_SERIES + select CRB_TPM + select DRIVERS_PCIE_GENERIC + select EC_STARLABS_FAN + select HAVE_INTEL_PTT select SOC_INTEL_ALDERLAKE_PCH_N + select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES + select SYSTEM_TYPE_MINIPC -if BOARD_STARLABS_ADL_HORIZON +config BOARD_STARLABS_BYTE_TWL + select BOARD_STARLABS_ADL_SERIES + select CRB_TPM + select DRIVERS_PCIE_GENERIC + select EC_STARLABS_FAN + select HAVE_INTEL_PTT + select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES + select SOC_INTEL_TWINLAKE + select SYSTEM_TYPE_MINIPC -config CCD_PORT - int - default 4 +if BOARD_STARLABS_ADL_SERIES config CONSOLE_SERIAL default n if !EDK2_DEBUG @@ -58,20 +74,12 @@ config EDK2_BOOTSPLASH_FILE string default "3rdparty/blobs/mainboard/starlabs/Logo.bmp" -config EC_STARLABS_BATTERY_MODEL - default "U5266122PV-2S1P" - -config EC_STARLABS_BATTERY_TYPE - default "LION" - -config EC_STARLABS_BATTERY_OEM - default "Shenzhen Utility Energy Co., Ltd" - config EC_STARLABS_ITE_BIN_PATH string default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/ec.bin" config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/vboot.fmd" if VBOOT default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" config IFD_BIN_PATH @@ -83,13 +91,18 @@ config MAINBOARD_DIR config MAINBOARD_FAMILY string - default "HZ" + default "HZ" if BOARD_STARLABS_ADL_HORIZON + default "Y3" if BOARD_STARLABS_BYTE_TWL + default "Y2" if BOARD_STARLABS_BYTE_ADL config MAINBOARD_PART_NUMBER - default "StarBook Horizon" + default "StarBook Horizon" if BOARD_STARLABS_ADL_HORIZON + default "Byte Mk III" if BOARD_STARLABS_BYTE_TWL + default "Byte Mk II" if BOARD_STARLABS_BYTE_ADL config MAINBOARD_SMBIOS_PRODUCT_NAME - default "StarBook Horizon" + default "StarBook Horizon" if BOARD_STARLABS_ADL_HORIZON + default "Byte" if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL config ME_BIN_PATH string @@ -101,10 +114,6 @@ config POWER_STATE_DEFAULT_ON_AFTER_FAILURE config SOC_INTEL_CSE_SEND_EOP_EARLY default n -config TPM_PIRQ - depends on MAINBOARD_HAS_TPM2 - default 0x28 - config UART_FOR_CONSOLE default 0 @@ -112,6 +121,42 @@ config USE_PM_ACPI_TIMER default n config VARIANT_DIR - default "hz" + default "hz" if BOARD_STARLABS_ADL_HORIZON + default "y2" if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL + +config CMOS_LAYOUT_FILE + default "src/mainboard/\$(MAINBOARDDIR)/variants/\$(CONFIG_VARIANT_DIR)/cmos.layout" + +if BOARD_STARLABS_ADL_HORIZON + +config CCD_PORT + int + default 4 + +config EC_STARLABS_BATTERY_MODEL + default "U5266122PV-2S1P" + +config EC_STARLABS_BATTERY_TYPE + default "LION" + +config EC_STARLABS_BATTERY_OEM + default "Shenzhen Utility Energy Co., Ltd" + +config TPM_PIRQ + depends on MAINBOARD_HAS_TPM2 + default 0x28 + +endif # BOARD_STARLABS_ADL_HORIZON + +if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL + +config PL4_WATTS + int + default 65 + +config VBOOT + select VBOOT_VBNV_FLASH + +endif # BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL -endif +endif # BOARD_STARLABS_ADL_SERIES diff --git a/src/mainboard/starlabs/adl/Kconfig.name b/src/mainboard/starlabs/adl/Kconfig.name index e9af44560e..cfd423e8e5 100644 --- a/src/mainboard/starlabs/adl/Kconfig.name +++ b/src/mainboard/starlabs/adl/Kconfig.name @@ -1,4 +1,10 @@ -comment "Star Labs StarLite Series" +comment "Star Labs ADL Series" config BOARD_STARLABS_ADL_HORIZON bool "Star Labs StarBook Horizon (N305)" + +config BOARD_STARLABS_BYTE_ADL + bool "Star Labs Byte Mk II (N200)" + +config BOARD_STARLABS_BYTE_TWL + bool "Star Labs Byte Mk III (N355)" diff --git a/src/mainboard/starlabs/adl/board_info.txt b/src/mainboard/starlabs/adl/board_info.txt index 5416db044b..c3772dc3d5 100644 --- a/src/mainboard/starlabs/adl/board_info.txt +++ b/src/mainboard/starlabs/adl/board_info.txt @@ -1,5 +1,5 @@ Vendor name: Star Labs -Board name: StarBook Horizon +Board name: ADL Series Category: laptop ROM protocol: SPI ROM socketed: n diff --git a/src/mainboard/starlabs/adl/cfr.c b/src/mainboard/starlabs/adl/cfr.c index 43d064f90f..39386132df 100644 --- a/src/mainboard/starlabs/adl/cfr.c +++ b/src/mainboard/starlabs/adl/cfr.c @@ -10,8 +10,10 @@ static struct sm_obj_form battery_group = { .ui_name = "Battery", .obj_list = (const struct sm_object *[]) { +#if CONFIG(SYSTEM_TYPE_LAPTOP) &charging_speed, &max_charge, +#endif &power_on_after_fail_bool, NULL }, @@ -25,6 +27,7 @@ static struct sm_obj_form debug_group = { }, }; +#if CONFIG(SYSTEM_TYPE_LAPTOP) static struct sm_obj_form leds_group = { .ui_name = "LEDs", .obj_list = (const struct sm_object *[]) { @@ -59,6 +62,7 @@ static struct sm_obj_form display_group = { NULL }, }; +#endif static struct sm_obj_form pcie_power_management_group = { .ui_name = "PCIe Power Management", @@ -75,7 +79,9 @@ static struct sm_obj_form performance_group = { .obj_list = (const struct sm_object *[]) { &fan_mode, &gna, +#if CONFIG(SYSTEM_TYPE_LAPTOP) &memory_speed, +#endif &power_profile, NULL }, @@ -95,7 +101,9 @@ static struct sm_obj_form security_group = { static struct sm_obj_form suspend_lid_group = { .ui_name = "Suspend & Lid", .obj_list = (const struct sm_object *[]) { +#if CONFIG(SYSTEM_TYPE_LAPTOP) &lid_switch, +#endif &s0ix_enable, NULL }, @@ -120,12 +128,16 @@ static struct sm_obj_form wireless_group = { }; static struct sm_obj_form *sm_root[] = { +#if CONFIG(SYSTEM_TYPE_LAPTOP) &audio_video_group, +#endif &battery_group, &debug_group, +#if CONFIG(SYSTEM_TYPE_LAPTOP) &display_group, &keyboard_group, &leds_group, +#endif &pcie_power_management_group, &performance_group, &security_group, diff --git a/src/mainboard/starlabs/adl/dsdt.asl b/src/mainboard/starlabs/adl/dsdt.asl index b7783eae63..3a68c43aa3 100644 --- a/src/mainboard/starlabs/adl/dsdt.asl +++ b/src/mainboard/starlabs/adl/dsdt.asl @@ -21,12 +21,13 @@ DefinitionBlock( #include #include - #include - #include +#if CONFIG(SYSTEM_TYPE_LAPTOP) + #include /* PS/2 Keyboard */ #include +#endif } #include diff --git a/src/mainboard/starlabs/adl/cmos.layout b/src/mainboard/starlabs/adl/variants/hz/cmos.layout similarity index 100% rename from src/mainboard/starlabs/adl/cmos.layout rename to src/mainboard/starlabs/adl/variants/hz/cmos.layout diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/Makefile.mk b/src/mainboard/starlabs/adl/variants/y2/Makefile.mk similarity index 79% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/Makefile.mk rename to src/mainboard/starlabs/adl/variants/y2/Makefile.mk index 9abc069b38..05782dbcc6 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/Makefile.mk +++ b/src/mainboard/starlabs/adl/variants/y2/Makefile.mk @@ -2,6 +2,8 @@ bootblock-y += gpio.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c + romstage-y += romstage.c ramstage-y += devtree.c diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/board.fmd b/src/mainboard/starlabs/adl/variants/y2/board.fmd similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/board.fmd rename to src/mainboard/starlabs/adl/variants/y2/board.fmd diff --git a/src/mainboard/starlabs/byte_adl/cmos.layout b/src/mainboard/starlabs/adl/variants/y2/cmos.layout similarity index 100% rename from src/mainboard/starlabs/byte_adl/cmos.layout rename to src/mainboard/starlabs/adl/variants/y2/cmos.layout diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/data.vbt b/src/mainboard/starlabs/adl/variants/y2/data.vbt similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/data.vbt rename to src/mainboard/starlabs/adl/variants/y2/data.vbt diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb b/src/mainboard/starlabs/adl/variants/y2/devicetree.cb similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb rename to src/mainboard/starlabs/adl/variants/y2/devicetree.cb diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c b/src/mainboard/starlabs/adl/variants/y2/devtree.c similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c rename to src/mainboard/starlabs/adl/variants/y2/devtree.c diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c b/src/mainboard/starlabs/adl/variants/y2/gpio.c similarity index 99% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c rename to src/mainboard/starlabs/adl/variants/y2/gpio.c index 0c0173cb40..12d9bcb472 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c +++ b/src/mainboard/starlabs/adl/variants/y2/gpio.c @@ -86,7 +86,7 @@ const struct pad_config gpio_table[] = { PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* Data */ PAD_CFG_GPO(GPP_E8, 1, DEEP), /* DRAM Sleep */ - /* Config Straps [ Low / High ] */ + /* Config Straps [ Low / High ] */ PAD_CFG_GPO(GPP_B14, 0, PLTRST), /* Top Swap [ Disabled / Enabled ] */ PAD_CFG_GPO(GPP_B18, 0, PLTRST), /* Reboot Support [ Enabled / Disabled ] */ PAD_CFG_GPO(GPP_C2, 1, PLTRST), /* TLS Confidentiality [ Disabled / Enabled ] */ diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/hda_verb.c b/src/mainboard/starlabs/adl/variants/y2/hda_verb.c similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/hda_verb.c rename to src/mainboard/starlabs/adl/variants/y2/hda_verb.c diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/ramstage.c b/src/mainboard/starlabs/adl/variants/y2/ramstage.c similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/ramstage.c rename to src/mainboard/starlabs/adl/variants/y2/ramstage.c diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/romstage.c b/src/mainboard/starlabs/adl/variants/y2/romstage.c similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/romstage.c rename to src/mainboard/starlabs/adl/variants/y2/romstage.c diff --git a/src/mainboard/starlabs/byte_adl/smihandler.c b/src/mainboard/starlabs/adl/variants/y2/smihandler.c similarity index 100% rename from src/mainboard/starlabs/byte_adl/smihandler.c rename to src/mainboard/starlabs/adl/variants/y2/smihandler.c diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/vboot.fmd b/src/mainboard/starlabs/adl/variants/y2/vboot.fmd similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/vboot.fmd rename to src/mainboard/starlabs/adl/variants/y2/vboot.fmd diff --git a/src/mainboard/starlabs/byte_adl/Kconfig b/src/mainboard/starlabs/byte_adl/Kconfig deleted file mode 100644 index d8524a9ceb..0000000000 --- a/src/mainboard/starlabs/byte_adl/Kconfig +++ /dev/null @@ -1,116 +0,0 @@ -config BOARD_STARLABS_BYTE_SERIES - def_bool n - select AZALIA_USE_LEGACY_VERB_TABLE - select BOARD_ROMSIZE_KB_16384 - select CRB_TPM - select CSE_DEFAULT_CFR_OPTION_STATE_DISABLED - select DRIVERS_EFI_VARIABLE_STORE - select DRIVERS_INTEL_PMC - select DRIVERS_OPTION_CFR_ENABLED - select DRIVERS_PCIE_GENERIC - select EC_STARLABS_FAN - select EC_STARLABS_MERLIN - select HAVE_ACPI_RESUME - select HAVE_ACPI_TABLES - select HAVE_INTEL_PTT - select HAVE_OPTION_TABLE - select INTEL_GMA_HAVE_VBT - select INTEL_LPSS_UART_FOR_CONSOLE - select NO_UART_ON_SUPERIO - select PMC_IPC_ACPI_INTERFACE - select SOC_INTEL_COMMON_BLOCK_HDA_VERB - select SOC_INTEL_COMMON_BLOCK_TCSS - select SOC_INTEL_CRASHLOG - select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES - select SPD_READ_BY_WORD - select SPI_FLASH_WINBOND - select SYSTEM_TYPE_MINIPC - select TPM2 - select VALIDATE_INTEL_DESCRIPTOR - -config BOARD_STARLABS_BYTE_ADL - select BOARD_STARLABS_BYTE_SERIES - select SOC_INTEL_ALDERLAKE - select SOC_INTEL_ALDERLAKE_PCH_N - -config BOARD_STARLABS_BYTE_TWL - select BOARD_STARLABS_BYTE_SERIES - select SOC_INTEL_ALDERLAKE - select SOC_INTEL_TWINLAKE - -if BOARD_STARLABS_BYTE_SERIES - -config CONSOLE_SERIAL - default n if !EDK2_DEBUG - -config D3COLD_SUPPORT - default n - -config DEVICETREE - default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" - -config DIMM_SPD_SIZE - default 512 - -config EC_STARLABS_ITE_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/ec.bin" - -config FMDFILE - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/vboot.fmd" if VBOOT - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" - -config IFD_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/flashdescriptor.bin" - -config MAINBOARD_DIR - default "starlabs/byte_adl" - -config MAINBOARD_FAMILY - string - default "Y3" if BOARD_STARLABS_BYTE_TWL - default "Y2" - -config MAINBOARD_PART_NUMBER - default "Byte Mk III" if BOARD_STARLABS_BYTE_TWL - default "Byte Mk II" - -config MAINBOARD_SMBIOS_PRODUCT_NAME - default "Byte" - -config ME_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/intel_me.bin" - -config PL4_WATTS - int - default 65 - -config POWER_STATE_DEFAULT_ON_AFTER_FAILURE - default n - -config EDK2_BOOTSPLASH_FILE - string - default "3rdparty/blobs/mainboard/starlabs/Logo.bmp" - -config SOC_INTEL_CSE_SEND_EOP_EARLY - default n - -config TJ_MAX - int - default 105 - -config UART_FOR_CONSOLE - default 0 - -config USE_PM_ACPI_TIMER - default n - -config VBOOT - select VBOOT_VBNV_FLASH - -config VARIANT_DIR - default "mk_ii" - -endif diff --git a/src/mainboard/starlabs/byte_adl/Kconfig.name b/src/mainboard/starlabs/byte_adl/Kconfig.name deleted file mode 100644 index bb393c0daa..0000000000 --- a/src/mainboard/starlabs/byte_adl/Kconfig.name +++ /dev/null @@ -1,7 +0,0 @@ -comment "Star Labs Byte Series" - -config BOARD_STARLABS_BYTE_ADL - bool "Star Labs Byte Mk II (N200)" - -config BOARD_STARLABS_BYTE_TWL - bool "Star Labs Byte Mk III (N355)" diff --git a/src/mainboard/starlabs/byte_adl/Makefile.mk b/src/mainboard/starlabs/byte_adl/Makefile.mk deleted file mode 100644 index 678662b55d..0000000000 --- a/src/mainboard/starlabs/byte_adl/Makefile.mk +++ /dev/null @@ -1,13 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include -subdirs-y += variants/$(VARIANT_DIR) - -bootblock-y += bootblock.c - -verstage-$(CONFIG_VBOOT) += vboot.c - -romstage-$(CONFIG_VBOOT) += vboot.c - -ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += cfr.c -ramstage-y += mainboard.c diff --git a/src/mainboard/starlabs/byte_adl/acpi/ec.asl b/src/mainboard/starlabs/byte_adl/acpi/ec.asl deleted file mode 100644 index 853b0877b3..0000000000 --- a/src/mainboard/starlabs/byte_adl/acpi/ec.asl +++ /dev/null @@ -1 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/src/mainboard/starlabs/byte_adl/acpi/mainboard.asl b/src/mainboard/starlabs/byte_adl/acpi/mainboard.asl deleted file mode 100644 index 34b90af325..0000000000 --- a/src/mainboard/starlabs/byte_adl/acpi/mainboard.asl +++ /dev/null @@ -1,5 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -Scope (\_SB) { - #include "sleep.asl" -} diff --git a/src/mainboard/starlabs/byte_adl/acpi/sleep.asl b/src/mainboard/starlabs/byte_adl/acpi/sleep.asl deleted file mode 100644 index 7ed74e3514..0000000000 --- a/src/mainboard/starlabs/byte_adl/acpi/sleep.asl +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -Method (MPTS, 1, NotSerialized) -{ - RPTS (Arg0) -} - -Method (MWAK, 1, NotSerialized) -{ - RWAK (Arg0) -} diff --git a/src/mainboard/starlabs/byte_adl/acpi/superio.asl b/src/mainboard/starlabs/byte_adl/acpi/superio.asl deleted file mode 100644 index 853b0877b3..0000000000 --- a/src/mainboard/starlabs/byte_adl/acpi/superio.asl +++ /dev/null @@ -1 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/src/mainboard/starlabs/byte_adl/board_info.txt b/src/mainboard/starlabs/byte_adl/board_info.txt deleted file mode 100644 index 86a76f6126..0000000000 --- a/src/mainboard/starlabs/byte_adl/board_info.txt +++ /dev/null @@ -1,6 +0,0 @@ -Vendor name: Star Labs -Board name: Byte -Category: desktop -ROM protocol: SPI -ROM socketed: n -Flashrom support: y diff --git a/src/mainboard/starlabs/byte_adl/bootblock.c b/src/mainboard/starlabs/byte_adl/bootblock.c deleted file mode 100644 index ca48bb1ab2..0000000000 --- a/src/mainboard/starlabs/byte_adl/bootblock.c +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -void bootblock_mainboard_init(void) -{ - const struct pad_config *pads; - size_t num; - - pads = variant_early_gpio_table(&num); - gpio_configure_pads(pads, num); -} diff --git a/src/mainboard/starlabs/byte_adl/cfr.c b/src/mainboard/starlabs/byte_adl/cfr.c deleted file mode 100644 index bf658a4249..0000000000 --- a/src/mainboard/starlabs/byte_adl/cfr.c +++ /dev/null @@ -1,100 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include - -static struct sm_obj_form battery_group = { - .ui_name = "Battery", - .obj_list = (const struct sm_object *[]) { - &power_on_after_fail_bool, - NULL - }, -}; - -static struct sm_obj_form debug_group = { - .ui_name = "Debug", - .obj_list = (const struct sm_object *[]) { - &debug_level, - NULL - }, -}; - -static struct sm_obj_form pcie_power_management_group = { - .ui_name = "PCIe Power Management", - .obj_list = (const struct sm_object *[]) { - &pciexp_aspm, - &pciexp_clk_pm, - &pciexp_l1ss, - NULL - }, -}; - -static struct sm_obj_form performance_group = { - .ui_name = "Performance", - .obj_list = (const struct sm_object *[]) { - &fan_mode, - &gna, - &power_profile, - NULL - }, -}; - -static struct sm_obj_form security_group = { - .ui_name = "Security", - .obj_list = (const struct sm_object *[]) { - &bios_lock, - &intel_tme, - &me_state, - &me_state_counter, - NULL - }, -}; - -static struct sm_obj_form suspend_lid_group = { - .ui_name = "Suspend & Lid", - .obj_list = (const struct sm_object *[]) { - &s0ix_enable, - NULL - }, -}; - -static struct sm_obj_form virtualization_group = { - .ui_name = "Virtualization", - .obj_list = (const struct sm_object *[]) { - &vtd, - NULL - }, -}; - -static struct sm_obj_form wireless_group = { - .ui_name = "Wireless", - .obj_list = (const struct sm_object *[]) { - &bluetooth, - &bluetooth_rtd3, - &wifi, - NULL - }, -}; - -static struct sm_obj_form *sm_root[] = { - &battery_group, - &debug_group, - &pcie_power_management_group, - &performance_group, - &security_group, - &suspend_lid_group, - &virtualization_group, - &wireless_group, - NULL -}; - -void mb_cfr_setup_menu(struct lb_cfr *cfr_root) -{ - starlabs_cfr_register_overrides(); - cfr_write_setup_menu(cfr_root, sm_root); -} diff --git a/src/mainboard/starlabs/byte_adl/dsdt.asl b/src/mainboard/starlabs/byte_adl/dsdt.asl deleted file mode 100644 index c0936a74ba..0000000000 --- a/src/mainboard/starlabs/byte_adl/dsdt.asl +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -DefinitionBlock( - "dsdt.aml", - "DSDT", - ACPI_DSDT_REV_2, - OEM_ID, - ACPI_TABLE_CREATOR, - 0x20220930 -) -{ - #include - #include - #include - #include - - Device (\_SB.PCI0) - { - #include - #include - #include - - #include - } - - #include - - /* Star Labs EC */ - #include - - Scope (\_SB) - { - /* HID Driver */ - #include - - /* Suspend Methods */ - #include - } - - #include "acpi/mainboard.asl" -} diff --git a/src/mainboard/starlabs/byte_adl/include/variants.h b/src/mainboard/starlabs/byte_adl/include/variants.h deleted file mode 100644 index c95d15bd72..0000000000 --- a/src/mainboard/starlabs/byte_adl/include/variants.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _BASEBOARD_VARIANTS_H_ -#define _BASEBOARD_VARIANTS_H_ - -#include - -/* - * The next set of functions return the gpio table and fill in the number of - * entries for each table. - */ -const struct pad_config *variant_gpio_table(size_t *num); -const struct pad_config *variant_early_gpio_table(size_t *num); - -void devtree_update(void); - -#endif /* _BASEBOARD_VARIANTS_H_ */ diff --git a/src/mainboard/starlabs/byte_adl/mainboard.c b/src/mainboard/starlabs/byte_adl/mainboard.c deleted file mode 100644 index cd46529c0f..0000000000 --- a/src/mainboard/starlabs/byte_adl/mainboard.c +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -static void init_mainboard(void *chip_info) -{ - const struct pad_config *pads; - size_t num; - - pads = variant_gpio_table(&num); - gpio_configure_pads(pads, num); -} - -struct chip_operations mainboard_ops = { - .init = init_mainboard, -}; diff --git a/src/mainboard/starlabs/byte_adl/vboot.c b/src/mainboard/starlabs/byte_adl/vboot.c deleted file mode 100644 index 8511825004..0000000000 --- a/src/mainboard/starlabs/byte_adl/vboot.c +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -int get_recovery_mode_switch(void) -{ - return 0; -} From 7f02993393573914e6139dd278f61b9239ba345b Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Sun, 15 Feb 2026 21:20:09 +0000 Subject: [PATCH 674/789] mainboard/starlabs: move starlite under adl/ Move StarLite Mk V (Lite ADL) into the ADL grouping under src/mainboard/starlabs/adl/. Like StarBook Horizon, keep common code in the ADL directory and place model-specific data under src/mainboard/starlabs/adl/variants/ using the SKU-style variant directory (i5). Update MAINBOARD_DIR and related paths so binary blobs, SPD data and CMOS layout continue to resolve correctly, and update documentation to reflect the new blobs path. Note that BUILD_TIMELESS ROM hashes change since MAINBOARD_DIR is embedded in the CBFS config file. BUG=None TEST=BUILD_TIMELESS=1 build STARLABS_LITE_ADL Change-Id: Ib367bc65ad63e848d9e20e7d55f542f135b3c1d5 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/91256 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- Documentation/mainboard/starlabs/lite_adl.md | 11 +- src/mainboard/starlabs/adl/Kconfig | 46 ++++- src/mainboard/starlabs/adl/Kconfig.name | 3 + src/mainboard/starlabs/adl/acpi/mainboard.asl | 10 + src/mainboard/starlabs/adl/cfr.c | 190 +++++++++++------- src/mainboard/starlabs/adl/dsdt.asl | 2 +- src/mainboard/starlabs/adl/mainboard.c | 23 +++ src/mainboard/starlabs/adl/spd/Makefile.mk | 6 + .../spd/mt62f2g64d8-5500.spd.hex | 0 .../spd/mt62f2g64d8-6400.spd.hex | 0 .../spd/mt62f2g64d8-7500.spd.hex | 0 .../mk_v => adl/variants/i5}/Makefile.mk | 0 .../mk_v => adl/variants/i5}/board.fmd | 0 .../variants/i5}/cmos.layout | 0 .../mk_v => adl/variants/i5}/data.vbt | Bin .../variants/i5}/data_native_res.vbt | Bin .../mk_v => adl/variants/i5}/devicetree.cb | 0 .../mk_v => adl/variants/i5}/devtree.c | 0 .../variants/mk_v => adl/variants/i5}/gpio.c | 117 +++++------ .../starlabs/adl/variants/i5/hda_verb.c | 77 +++++++ .../mk_v => adl/variants/i5}/ramstage.c | 0 .../mk_v => adl/variants/i5}/romstage.c | 0 .../mk_v => adl/variants/i5}/vboot.fmd | 0 src/mainboard/starlabs/starlite_adl/Kconfig | 123 ------------ .../starlabs/starlite_adl/Kconfig.name | 4 - .../starlabs/starlite_adl/Makefile.mk | 14 -- .../starlabs/starlite_adl/acpi/ec.asl | 1 - .../starlabs/starlite_adl/acpi/mainboard.asl | 13 -- .../starlabs/starlite_adl/acpi/sleep.asl | 11 - .../starlabs/starlite_adl/acpi/superio.asl | 1 - .../starlabs/starlite_adl/board_info.txt | 6 - .../starlabs/starlite_adl/bootblock.c | 14 -- src/mainboard/starlabs/starlite_adl/cfr.c | 169 ---------------- src/mainboard/starlabs/starlite_adl/dsdt.asl | 47 ----- .../starlabs/starlite_adl/include/variants.h | 17 -- .../starlabs/starlite_adl/mainboard.c | 32 --- .../starlabs/starlite_adl/spd/Makefile.mk | 5 - .../starlite_adl/variants/mk_v/hda_verb.c | 98 --------- src/mainboard/starlabs/starlite_adl/vboot.c | 8 - 39 files changed, 337 insertions(+), 711 deletions(-) rename src/mainboard/starlabs/{starlite_adl => adl}/spd/mt62f2g64d8-5500.spd.hex (100%) rename src/mainboard/starlabs/{starlite_adl => adl}/spd/mt62f2g64d8-6400.spd.hex (100%) rename src/mainboard/starlabs/{starlite_adl => adl}/spd/mt62f2g64d8-7500.spd.hex (100%) rename src/mainboard/starlabs/{starlite_adl/variants/mk_v => adl/variants/i5}/Makefile.mk (100%) rename src/mainboard/starlabs/{starlite_adl/variants/mk_v => adl/variants/i5}/board.fmd (100%) rename src/mainboard/starlabs/{starlite_adl => adl/variants/i5}/cmos.layout (100%) rename src/mainboard/starlabs/{starlite_adl/variants/mk_v => adl/variants/i5}/data.vbt (100%) rename src/mainboard/starlabs/{starlite_adl/variants/mk_v => adl/variants/i5}/data_native_res.vbt (100%) rename src/mainboard/starlabs/{starlite_adl/variants/mk_v => adl/variants/i5}/devicetree.cb (100%) rename src/mainboard/starlabs/{starlite_adl/variants/mk_v => adl/variants/i5}/devtree.c (100%) rename src/mainboard/starlabs/{starlite_adl/variants/mk_v => adl/variants/i5}/gpio.c (56%) create mode 100644 src/mainboard/starlabs/adl/variants/i5/hda_verb.c rename src/mainboard/starlabs/{starlite_adl/variants/mk_v => adl/variants/i5}/ramstage.c (100%) rename src/mainboard/starlabs/{starlite_adl/variants/mk_v => adl/variants/i5}/romstage.c (100%) rename src/mainboard/starlabs/{starlite_adl/variants/mk_v => adl/variants/i5}/vboot.fmd (100%) delete mode 100644 src/mainboard/starlabs/starlite_adl/Kconfig delete mode 100644 src/mainboard/starlabs/starlite_adl/Kconfig.name delete mode 100644 src/mainboard/starlabs/starlite_adl/Makefile.mk delete mode 100644 src/mainboard/starlabs/starlite_adl/acpi/ec.asl delete mode 100644 src/mainboard/starlabs/starlite_adl/acpi/mainboard.asl delete mode 100644 src/mainboard/starlabs/starlite_adl/acpi/sleep.asl delete mode 100644 src/mainboard/starlabs/starlite_adl/acpi/superio.asl delete mode 100644 src/mainboard/starlabs/starlite_adl/board_info.txt delete mode 100644 src/mainboard/starlabs/starlite_adl/bootblock.c delete mode 100644 src/mainboard/starlabs/starlite_adl/cfr.c delete mode 100644 src/mainboard/starlabs/starlite_adl/dsdt.asl delete mode 100644 src/mainboard/starlabs/starlite_adl/include/variants.h delete mode 100644 src/mainboard/starlabs/starlite_adl/mainboard.c delete mode 100644 src/mainboard/starlabs/starlite_adl/spd/Makefile.mk delete mode 100644 src/mainboard/starlabs/starlite_adl/variants/mk_v/hda_verb.c delete mode 100644 src/mainboard/starlabs/starlite_adl/vboot.c diff --git a/Documentation/mainboard/starlabs/lite_adl.md b/Documentation/mainboard/starlabs/lite_adl.md index b6e7cb37e7..f914652b5a 100644 --- a/Documentation/mainboard/starlabs/lite_adl.md +++ b/Documentation/mainboard/starlabs/lite_adl.md @@ -1,4 +1,4 @@ -# StarBook Mk V +# StarLite Mk V ## Specs @@ -33,7 +33,8 @@ ## Building coreboot -Please follow the [Star Labs build instructions](common/building.md) to build coreboot, using `config.starlabs_starbook_adl` as config file. +Please follow the [Star Labs build instructions](common/building.md) to build +coreboot, using `config.starlabs_lite_adl` as config file. ### Preliminaries @@ -45,6 +46,10 @@ Prior to building coreboot the following files are required: The files listed below are optional: - Splash screen image in Windows 3.1 BMP format (Logo.bmp) +coreboot expects these binaries under +`3rdparty/blobs/mainboard/starlabs/adl//`, where `` +matches `CONFIG_VARIANT_DIR` (default: `i5`). + These files exist in the correct location in the StarLabsLtd/blobs repo on GitHub which is used in place of the standard 3rdparty/blobs repo. ### Build @@ -53,7 +58,7 @@ The following commands will build a working image: ```bash make distclean -make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_byte_adl +make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_lite_adl make ``` diff --git a/src/mainboard/starlabs/adl/Kconfig b/src/mainboard/starlabs/adl/Kconfig index 8b5c5d8b64..569274f9e6 100644 --- a/src/mainboard/starlabs/adl/Kconfig +++ b/src/mainboard/starlabs/adl/Kconfig @@ -36,6 +36,17 @@ config BOARD_STARLABS_ADL_HORIZON select SYSTEM_TYPE_LAPTOP select TPM_MEASURED_BOOT +config BOARD_STARLABS_LITE_ADL + select BOARD_STARLABS_ADL_SERIES + select CRB_TPM + select DRIVERS_GFX_GENERIC + select DRIVERS_I2C_HID + select HAVE_HDA_DMIC + select HAVE_INTEL_PTT + select HAVE_SPD_IN_CBFS + select SOC_INTEL_ALDERLAKE_PCH_N + select SYSTEM_TYPE_DETACHABLE + config BOARD_STARLABS_BYTE_ADL select BOARD_STARLABS_ADL_SERIES select CRB_TPM @@ -92,16 +103,19 @@ config MAINBOARD_DIR config MAINBOARD_FAMILY string default "HZ" if BOARD_STARLABS_ADL_HORIZON + default "I5" if BOARD_STARLABS_LITE_ADL default "Y3" if BOARD_STARLABS_BYTE_TWL default "Y2" if BOARD_STARLABS_BYTE_ADL config MAINBOARD_PART_NUMBER default "StarBook Horizon" if BOARD_STARLABS_ADL_HORIZON + default "StarLite Mk V" if BOARD_STARLABS_LITE_ADL default "Byte Mk III" if BOARD_STARLABS_BYTE_TWL default "Byte Mk II" if BOARD_STARLABS_BYTE_ADL config MAINBOARD_SMBIOS_PRODUCT_NAME default "StarBook Horizon" if BOARD_STARLABS_ADL_HORIZON + default "StarLite" if BOARD_STARLABS_LITE_ADL default "Byte" if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL config ME_BIN_PATH @@ -122,41 +136,53 @@ config USE_PM_ACPI_TIMER config VARIANT_DIR default "hz" if BOARD_STARLABS_ADL_HORIZON + default "i5" if BOARD_STARLABS_LITE_ADL default "y2" if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL config CMOS_LAYOUT_FILE default "src/mainboard/\$(MAINBOARDDIR)/variants/\$(CONFIG_VARIANT_DIR)/cmos.layout" -if BOARD_STARLABS_ADL_HORIZON +if BOARD_STARLABS_ADL_HORIZON || BOARD_STARLABS_LITE_ADL config CCD_PORT int - default 4 + default 4 if BOARD_STARLABS_ADL_HORIZON + default 5 if BOARD_STARLABS_LITE_ADL config EC_STARLABS_BATTERY_MODEL - default "U5266122PV-2S1P" + default "U5266122PV-2S1P" if BOARD_STARLABS_ADL_HORIZON + default "AEC3756153-2S1P-N" if BOARD_STARLABS_LITE_ADL config EC_STARLABS_BATTERY_TYPE default "LION" config EC_STARLABS_BATTERY_OEM - default "Shenzhen Utility Energy Co., Ltd" + default "Shenzhen Utility Energy Co., Ltd" if BOARD_STARLABS_ADL_HORIZON + default "Apower Electronics" if BOARD_STARLABS_LITE_ADL + +if MAINBOARD_HAS_TPM2 config TPM_PIRQ - depends on MAINBOARD_HAS_TPM2 - default 0x28 + default 0x28 if BOARD_STARLABS_ADL_HORIZON -endif # BOARD_STARLABS_ADL_HORIZON +endif # MAINBOARD_HAS_TPM2 -if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL +endif # BOARD_STARLABS_ADL_HORIZON || BOARD_STARLABS_LITE_ADL + +if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL || BOARD_STARLABS_LITE_ADL config PL4_WATTS int - default 65 + default 65 if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL + default 37 if BOARD_STARLABS_LITE_ADL + +config TJ_MAX + int + default 105 if BOARD_STARLABS_LITE_ADL config VBOOT select VBOOT_VBNV_FLASH -endif # BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL +endif # BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL || BOARD_STARLABS_LITE_ADL endif # BOARD_STARLABS_ADL_SERIES diff --git a/src/mainboard/starlabs/adl/Kconfig.name b/src/mainboard/starlabs/adl/Kconfig.name index cfd423e8e5..373ed84cea 100644 --- a/src/mainboard/starlabs/adl/Kconfig.name +++ b/src/mainboard/starlabs/adl/Kconfig.name @@ -8,3 +8,6 @@ config BOARD_STARLABS_BYTE_ADL config BOARD_STARLABS_BYTE_TWL bool "Star Labs Byte Mk III (N355)" + +config BOARD_STARLABS_LITE_ADL + bool "Star Labs Lite Mk V (N200/N350)" diff --git a/src/mainboard/starlabs/adl/acpi/mainboard.asl b/src/mainboard/starlabs/adl/acpi/mainboard.asl index 34b90af325..702d37f353 100644 --- a/src/mainboard/starlabs/adl/acpi/mainboard.asl +++ b/src/mainboard/starlabs/adl/acpi/mainboard.asl @@ -3,3 +3,13 @@ Scope (\_SB) { #include "sleep.asl" } + +#if CONFIG(BOARD_STARLABS_LITE_ADL) +Scope (_GPE) +{ + Method (_E0F, 0, NotSerialized) + { + \_SB.PCI0.LPCB.EC.VBTN.UPDK() + } +} +#endif diff --git a/src/mainboard/starlabs/adl/cfr.c b/src/mainboard/starlabs/adl/cfr.c index 39386132df..74106c295c 100644 --- a/src/mainboard/starlabs/adl/cfr.c +++ b/src/mainboard/starlabs/adl/cfr.c @@ -5,137 +5,176 @@ #include #include #include +#if CONFIG(BOARD_STARLABS_LITE_ADL) +#include +#include +#include +#include +#include +#endif #include +#if CONFIG(BOARD_STARLABS_LITE_ADL) +void cfr_card_reader_update(struct sm_object *new_obj) +{ + struct device *mxc_accel = DEV_PTR(mxc6655); + + if (!i2c_dev_detect(i2c_busdev(mxc_accel), mxc_accel->path.i2c.device)) + new_obj->sm_bool.flags = CFR_OPTFLAG_SUPPRESS; +} + +void cfr_touchscreen_update(struct sm_object *new_obj) +{ + if (get_uint_option("accelerometer", 1) == 0) + new_obj->sm_bool.flags = CFR_OPTFLAG_SUPPRESS; +} +#endif + +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) +static struct sm_obj_form audio_video_group = { + .ui_name = "Audio/Video", + .obj_list = (const struct sm_object *[]){ + µphone, + &webcam, + NULL, + }, +}; +#endif + static struct sm_obj_form battery_group = { .ui_name = "Battery", - .obj_list = (const struct sm_object *[]) { -#if CONFIG(SYSTEM_TYPE_LAPTOP) - &charging_speed, - &max_charge, + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(EC_STARLABS_CHARGING_SPEED) + &charging_speed, #endif - &power_on_after_fail_bool, - NULL - }, +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) + &max_charge, +#endif + &power_on_after_fail_bool, NULL}, }; static struct sm_obj_form debug_group = { .ui_name = "Debug", - .obj_list = (const struct sm_object *[]) { - &debug_level, - NULL - }, + .obj_list = (const struct sm_object *[]){&debug_level, NULL}, }; -#if CONFIG(SYSTEM_TYPE_LAPTOP) +#if CONFIG(EC_STARLABS_POWER_LED) || CONFIG(EC_STARLABS_CHARGE_LED) static struct sm_obj_form leds_group = { .ui_name = "LEDs", - .obj_list = (const struct sm_object *[]) { - &charge_led, - &power_led, - NULL - }, + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(EC_STARLABS_CHARGE_LED) + &charge_led, +#endif +#if CONFIG(EC_STARLABS_POWER_LED) + &power_led, +#endif + NULL, }, }; +#endif +#if CONFIG(SYSTEM_TYPE_LAPTOP) static struct sm_obj_form keyboard_group = { .ui_name = "Keyboard", - .obj_list = (const struct sm_object *[]) { - &fn_ctrl_swap, - &kbl_timeout, - NULL - }, -}; - -static struct sm_obj_form audio_video_group = { - .ui_name = "Audio/Video", - .obj_list = (const struct sm_object *[]) { - µphone, - &webcam, - NULL - }, + .obj_list = (const struct sm_object *[]){&fn_ctrl_swap, &kbl_timeout, NULL}, }; +#endif +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) static struct sm_obj_form display_group = { .ui_name = "Display", - .obj_list = (const struct sm_object *[]) { - &display_native_res, - NULL - }, + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(BOARD_STARLABS_LITE_ADL) + &accelerometer, +#endif + &display_native_res, +#if CONFIG(BOARD_STARLABS_LITE_ADL) + &touchscreen, +#endif + NULL, }, +}; +#endif + +#if CONFIG(BOARD_STARLABS_LITE_ADL) +static struct sm_obj_form io_expansion_group = { + .ui_name = "I/O / Expansion", + .obj_list = + (const struct sm_object *[]){ + &card_reader, + NULL, }, }; #endif static struct sm_obj_form pcie_power_management_group = { .ui_name = "PCIe Power Management", - .obj_list = (const struct sm_object *[]) { - &pciexp_aspm, - &pciexp_clk_pm, - &pciexp_l1ss, - NULL - }, + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(SOC_INTEL_COMMON_BLOCK_ASPM) + &pciexp_aspm, + &pciexp_clk_pm, + &pciexp_l1ss, +#endif + NULL, }, }; static struct sm_obj_form performance_group = { .ui_name = "Performance", - .obj_list = (const struct sm_object *[]) { - &fan_mode, - &gna, -#if CONFIG(SYSTEM_TYPE_LAPTOP) - &memory_speed, + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(EC_STARLABS_FAN) + &fan_mode, #endif - &power_profile, - NULL - }, + &gna, +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) + &memory_speed, +#endif + &power_profile, NULL}, }; static struct sm_obj_form security_group = { .ui_name = "Security", - .obj_list = (const struct sm_object *[]) { - &bios_lock, - &intel_tme, - &me_state, - &me_state_counter, - NULL - }, + .obj_list = (const struct sm_object *[]){&bios_lock, &intel_tme, &me_state, + &me_state_counter, NULL}, }; static struct sm_obj_form suspend_lid_group = { .ui_name = "Suspend & Lid", - .obj_list = (const struct sm_object *[]) { -#if CONFIG(SYSTEM_TYPE_LAPTOP) - &lid_switch, + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(EC_STARLABS_LID_SWITCH) + &lid_switch, #endif - &s0ix_enable, - NULL - }, + &s0ix_enable, NULL}, }; static struct sm_obj_form virtualization_group = { .ui_name = "Virtualization", - .obj_list = (const struct sm_object *[]) { - &vtd, - NULL - }, + .obj_list = (const struct sm_object *[]){&vtd, NULL}, }; static struct sm_obj_form wireless_group = { .ui_name = "Wireless", - .obj_list = (const struct sm_object *[]) { - &bluetooth, - &bluetooth_rtd3, - &wifi, - NULL - }, + .obj_list = (const struct sm_object *[]){&bluetooth, &bluetooth_rtd3, &wifi, NULL}, }; static struct sm_obj_form *sm_root[] = { -#if CONFIG(SYSTEM_TYPE_LAPTOP) +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) &audio_video_group, #endif &battery_group, &debug_group, -#if CONFIG(SYSTEM_TYPE_LAPTOP) +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) &display_group, +#endif +#if CONFIG(BOARD_STARLABS_LITE_ADL) + &io_expansion_group, +#endif +#if CONFIG(SYSTEM_TYPE_LAPTOP) &keyboard_group, +#endif +#if CONFIG(EC_STARLABS_POWER_LED) || CONFIG(EC_STARLABS_CHARGE_LED) &leds_group, #endif &pcie_power_management_group, @@ -144,8 +183,7 @@ static struct sm_obj_form *sm_root[] = { &suspend_lid_group, &virtualization_group, &wireless_group, - NULL -}; + NULL}; void mb_cfr_setup_menu(struct lb_cfr *cfr_root) { diff --git a/src/mainboard/starlabs/adl/dsdt.asl b/src/mainboard/starlabs/adl/dsdt.asl index 3a68c43aa3..367d6af038 100644 --- a/src/mainboard/starlabs/adl/dsdt.asl +++ b/src/mainboard/starlabs/adl/dsdt.asl @@ -22,7 +22,7 @@ DefinitionBlock( #include #include -#if CONFIG(SYSTEM_TYPE_LAPTOP) +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) #include /* PS/2 Keyboard */ diff --git a/src/mainboard/starlabs/adl/mainboard.c b/src/mainboard/starlabs/adl/mainboard.c index 1d2fceae53..8a3dadbc48 100644 --- a/src/mainboard/starlabs/adl/mainboard.c +++ b/src/mainboard/starlabs/adl/mainboard.c @@ -1,5 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#if CONFIG(BOARD_STARLABS_LITE_ADL) +#include +#include +#endif + #include #include #include @@ -17,6 +22,24 @@ static void init_mainboard(void *chip_info) devtree_update(); } +#if CONFIG(BOARD_STARLABS_LITE_ADL) +static void mainboard_fill_ssdt(const struct device *dev) +{ + enum ps2_action_key ps2_action_keys[2] = {PS2_KEY_VOL_DOWN, PS2_KEY_VOL_UP}; + + acpigen_ps2_keyboard_dsd("_SB.PCI0.PS2K", ARRAY_SIZE(ps2_action_keys), ps2_action_keys, + false, false, false, false, false); +} +#endif + +static void enable_mainboard(struct device *dev) +{ +#if CONFIG(BOARD_STARLABS_LITE_ADL) + dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt; +#endif +} + struct chip_operations mainboard_ops = { .init = init_mainboard, + .enable_dev = enable_mainboard, }; diff --git a/src/mainboard/starlabs/adl/spd/Makefile.mk b/src/mainboard/starlabs/adl/spd/Makefile.mk index f979c5a066..f02db92001 100644 --- a/src/mainboard/starlabs/adl/spd/Makefile.mk +++ b/src/mainboard/starlabs/adl/spd/Makefile.mk @@ -1,5 +1,11 @@ ## SPDX-License-Identifier: GPL-2.0-only +ifeq ($(VARIANT_DIR),hz) SPD_SOURCES = rs4g32l05d8fdb-5500 SPD_SOURCES += rs4g32l05d8fdb-6400 SPD_SOURCES += rs4g32l05d8fdb-7500 +else ifeq ($(VARIANT_DIR),i5) +SPD_SOURCES = mt62f2g64d8-5500 +SPD_SOURCES += mt62f2g64d8-6400 +SPD_SOURCES += mt62f2g64d8-7500 +endif diff --git a/src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-5500.spd.hex b/src/mainboard/starlabs/adl/spd/mt62f2g64d8-5500.spd.hex similarity index 100% rename from src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-5500.spd.hex rename to src/mainboard/starlabs/adl/spd/mt62f2g64d8-5500.spd.hex diff --git a/src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-6400.spd.hex b/src/mainboard/starlabs/adl/spd/mt62f2g64d8-6400.spd.hex similarity index 100% rename from src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-6400.spd.hex rename to src/mainboard/starlabs/adl/spd/mt62f2g64d8-6400.spd.hex diff --git a/src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-7500.spd.hex b/src/mainboard/starlabs/adl/spd/mt62f2g64d8-7500.spd.hex similarity index 100% rename from src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-7500.spd.hex rename to src/mainboard/starlabs/adl/spd/mt62f2g64d8-7500.spd.hex diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/Makefile.mk b/src/mainboard/starlabs/adl/variants/i5/Makefile.mk similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/Makefile.mk rename to src/mainboard/starlabs/adl/variants/i5/Makefile.mk diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd b/src/mainboard/starlabs/adl/variants/i5/board.fmd similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd rename to src/mainboard/starlabs/adl/variants/i5/board.fmd diff --git a/src/mainboard/starlabs/starlite_adl/cmos.layout b/src/mainboard/starlabs/adl/variants/i5/cmos.layout similarity index 100% rename from src/mainboard/starlabs/starlite_adl/cmos.layout rename to src/mainboard/starlabs/adl/variants/i5/cmos.layout diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/data.vbt b/src/mainboard/starlabs/adl/variants/i5/data.vbt similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/data.vbt rename to src/mainboard/starlabs/adl/variants/i5/data.vbt diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/data_native_res.vbt b/src/mainboard/starlabs/adl/variants/i5/data_native_res.vbt similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/data_native_res.vbt rename to src/mainboard/starlabs/adl/variants/i5/data_native_res.vbt diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devicetree.cb b/src/mainboard/starlabs/adl/variants/i5/devicetree.cb similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/devicetree.cb rename to src/mainboard/starlabs/adl/variants/i5/devicetree.cb diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c b/src/mainboard/starlabs/adl/variants/i5/devtree.c similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c rename to src/mainboard/starlabs/adl/variants/i5/devtree.c diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/gpio.c b/src/mainboard/starlabs/adl/variants/i5/gpio.c similarity index 56% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/gpio.c rename to src/mainboard/starlabs/adl/variants/i5/gpio.c index 8c1b7cf79f..e6c03fd9c0 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/gpio.c +++ b/src/mainboard/starlabs/adl/variants/i5/gpio.c @@ -5,8 +5,8 @@ /* Early pad configuration in bootblock */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ - PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ - PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ + PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ }; const struct pad_config *variant_early_gpio_table(size_t *num) @@ -18,12 +18,12 @@ const struct pad_config *variant_early_gpio_table(size_t *num) /* Pad configuration in ramstage. */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ - PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ - PAD_CFG_NF(GPD1, NONE, DEEP, NF1), /* Charger Connected */ - PAD_CFG_NF(GPD3, UP_20K, DEEP, NF1), /* Power Button */ - PAD_CFG_NF(GPD4, NONE, DEEP, NF1), /* Sleep S3 */ - PAD_CFG_NF(GPD5, NONE, DEEP, NF1), /* Sleep S4 */ - PAD_CFG_NF(GPD8, NONE, DEEP, NF1), /* Bluetooth Suspend */ + PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ + PAD_CFG_NF(GPD1, NONE, DEEP, NF1), /* Charger Connected */ + PAD_CFG_NF(GPD3, UP_20K, DEEP, NF1), /* Power Button */ + PAD_CFG_NF(GPD4, NONE, DEEP, NF1), /* Sleep S3 */ + PAD_CFG_NF(GPD5, NONE, DEEP, NF1), /* Sleep S4 */ + PAD_CFG_NF(GPD8, NONE, DEEP, NF1), /* Bluetooth Suspend */ /* eSPI - Configure automatically on reset */ // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A0, UP_20K, DEEP, NF1), /* eSPI IO 0 */ @@ -35,74 +35,75 @@ const struct pad_config gpio_table[] = { // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A10, NONE, DEEP, NF1), /* eSPI Reset */ /* Touchpanel */ - PAD_CFG_NF(GPP_B5, NONE, DEEP, NF2), /* Data */ - PAD_CFG_NF(GPP_B6, NONE, DEEP, NF2), /* Clock */ - PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ - PAD_CFG_GPO(GPP_F17, 1, PLTRST), /* Reset */ - PAD_CFG_GPI_APIC(GPP_F18, NONE, PLTRST, LEVEL, INVERT), /* Interrupt */ + PAD_CFG_NF(GPP_B5, NONE, DEEP, NF2), /* Data */ + PAD_CFG_NF(GPP_B6, NONE, DEEP, NF2), /* Clock */ + PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ + PAD_CFG_GPO(GPP_F17, 1, PLTRST), /* Reset */ + PAD_CFG_GPI_APIC(GPP_F18, NONE, PLTRST, LEVEL, INVERT), /* Interrupt */ /* Accelerometer */ - PAD_CFG_NF(GPP_H4, NONE, DEEP, NF1), /* Data */ - PAD_CFG_NF(GPP_H5, NONE, DEEP, NF1), /* Clock */ + PAD_CFG_NF(GPP_H4, NONE, DEEP, NF1), /* Data */ + PAD_CFG_NF(GPP_H5, NONE, DEEP, NF1), /* Clock */ /* Keyboard */ - PAD_CFG_GPI_SMI_LOW(GPP_F15, NONE, DEEP, EDGE_BOTH), /* Detect */ + PAD_CFG_GPI_SMI_LOW(GPP_F15, NONE, DEEP, EDGE_BOTH), /* Detect */ /* SSD */ - PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ /* Wireless */ - PAD_CFG_NF(GPP_F0, NONE, DEEP, NF1), /* BRI Data */ - PAD_CFG_NF(GPP_F1, UP_20K, DEEP, NF1), /* BRI Response */ - PAD_CFG_NF(GPP_F2, NONE, DEEP, NF1), /* RGI Data */ - PAD_CFG_NF(GPP_F3, UP_20K, DEEP, NF1), /* RGI Response */ - PAD_CFG_NF(GPP_F4, NONE, DEEP, NF1), /* RF Reset */ - PAD_CFG_NF(GPP_F5, NONE, DEEP, NF2), /* Modem Clock Request */ - PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ - PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ + PAD_CFG_NF(GPP_F0, NONE, DEEP, NF1), /* BRI Data */ + PAD_CFG_NF(GPP_F1, UP_20K, DEEP, NF1), /* BRI Response */ + PAD_CFG_NF(GPP_F2, NONE, DEEP, NF1), /* RGI Data */ + PAD_CFG_NF(GPP_F3, UP_20K, DEEP, NF1), /* RGI Response */ + PAD_CFG_NF(GPP_F4, NONE, DEEP, NF1), /* RF Reset */ + PAD_CFG_NF(GPP_F5, NONE, DEEP, NF2), /* Modem Clock Request */ + PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ - PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* eDP Hot Plug */ - PAD_CFG_NF(GPP_A18, NONE, DEEP, NF1), /* HDMI Hot Plug */ - PAD_CFG_NF(GPP_H15, NONE, DEEP, NF1), /* HDMI Clock */ - PAD_CFG_NF(GPP_H17, NONE, DEEP, NF1), /* HDMI Data */ - PAD_CFG_NF(GPP_A19, NONE, DEEP, NF1), /* TCP0 Hot Plug */ - PAD_CFG_NF(GPP_A20, NONE, DEEP, NF1), /* TCP0 Hot Plug */ + PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* eDP Hot Plug */ + PAD_CFG_NF(GPP_A18, NONE, DEEP, NF1), /* HDMI Hot Plug */ + PAD_CFG_NF(GPP_H15, NONE, DEEP, NF1), /* HDMI Clock */ + PAD_CFG_NF(GPP_H17, NONE, DEEP, NF1), /* HDMI Data */ + PAD_CFG_NF(GPP_A19, NONE, DEEP, NF1), /* TCP0 Hot Plug */ + PAD_CFG_NF(GPP_A20, NONE, DEEP, NF1), /* TCP0 Hot Plug */ /* High-Definition Audio */ - PAD_CFG_NF(GPP_R0, NATIVE, DEEP, NF1), /* Clock */ - PAD_CFG_NF(GPP_R1, NATIVE, DEEP, NF1), /* Sync */ - PAD_CFG_NF(GPP_R2, NATIVE, DEEP, NF1), /* Data Output */ - PAD_CFG_NF(GPP_R3, NATIVE, DEEP, NF1), /* Data Input */ - PAD_CFG_NF(GPP_R4, NATIVE, DEEP, NF1), /* Reset */ + PAD_CFG_NF(GPP_R0, NATIVE, DEEP, NF1), /* Clock */ + PAD_CFG_NF(GPP_R1, NATIVE, DEEP, NF1), /* Sync */ + PAD_CFG_NF(GPP_R2, NATIVE, DEEP, NF1), /* Data Output */ + PAD_CFG_NF(GPP_R3, NATIVE, DEEP, NF1), /* Data Input */ + PAD_CFG_NF(GPP_R4, NATIVE, DEEP, NF1), /* Reset */ /* PCH */ - PAD_CFG_NF(GPP_H18, NONE, DEEP, NF1), /* C10 Gate */ - PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), /* Platform Reset */ - PAD_CFG_NF(GPP_B0, NONE, DEEP, NF1), /* Vendor ID 0 */ - PAD_CFG_NF(GPP_B1, NONE, DEEP, NF1), /* Vendor ID 1 */ - PAD_CFG_GPI_SCI(GPP_B2, NONE, PLTRST, EDGE_SINGLE, INVERT), /* Processor Hot */ + PAD_CFG_NF(GPP_H18, NONE, DEEP, NF1), /* C10 Gate */ + PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), /* Platform Reset */ + PAD_CFG_NF(GPP_B0, NONE, DEEP, NF1), /* Vendor ID 0 */ + PAD_CFG_NF(GPP_B1, NONE, DEEP, NF1), /* Vendor ID 1 */ + PAD_CFG_GPI_SCI(GPP_B2, NONE, PLTRST, EDGE_SINGLE, INVERT), /* Processor Hot */ /* SMBus */ - PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* Clock */ - PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* Data */ - PAD_CFG_GPO(GPP_E8, 1, DEEP), /* DRAM Sleep */ + PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* Clock */ + PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* Data */ + PAD_CFG_GPO(GPP_E8, 1, DEEP), /* DRAM Sleep */ /* Config Straps [ Low / High ] */ - PAD_CFG_GPO(GPP_B14, 0, PLTRST), /* Top Swap [ Disabled / Enabled ] */ - PAD_CFG_GPO(GPP_B18, 0, PLTRST), /* Reboot Support [ Enabled / Disabled ] */ - PAD_CFG_GPO(GPP_C2, 1, PLTRST), /* TLS Confidentiality [ Disabled / Enabled ] */ - PAD_CFG_GPO(GPP_C5, 0, PLTRST), /* eSPI [ Enabled / Disabled ] */ - PAD_CFG_GPO(GPP_E6, 0, PLTRST), /* JTAG ODT [ Disabled / Enabled ] */ - PAD_CFG_GPO(GPP_H1, 0, PLTRST), /* BFX Strap 2 Bit 3 [ Disabled / Enabled ] */ - PAD_CFG_GPO(GPP_E19, 0, PLTRST), /* TBT LSX #0 [ 1.8V / 3.3V ] */ - PAD_CFG_GPO(GPP_E21, 0, PLTRST), /* TBT LSX #1 [ 1.8V / 3.3V ] */ - PAD_CFG_GPO(GPP_D10, 0, PLTRST), /* TBT LSX #2 [ 1.8V / 3.3V ] */ - PAD_CFG_GPO(GPP_D12, 0, PLTRST), /* TBT LSX #3 [ 1.8V / 3.3V ] */ - PAD_CFG_GPO(GPP_F7, 0, PLTRST), /* MCRO LDO [ Disabled / Bypass ] */ - PAD_CFG_GPO(GPD7, 0, PLTRST), /* RTC Clock Delay [ Disabled / 95ms ] */ + PAD_CFG_GPO(GPP_B14, 0, PLTRST), /* Top Swap [ Disabled / Enabled ] */ + PAD_CFG_GPO(GPP_B18, 0, PLTRST), /* Reboot Support [ Enabled / Disabled ] */ + PAD_CFG_GPO(GPP_C2, 1, PLTRST), /* TLS Confidentiality [ Disabled / Enabled ] */ + PAD_CFG_GPO(GPP_C5, 0, + PLTRST), /* eSPI [ Enabled / Disabled ] */ + PAD_CFG_GPO(GPP_E6, 0, PLTRST), /* JTAG ODT [ Disabled / Enabled ] */ + PAD_CFG_GPO(GPP_H1, 0, PLTRST), /* BFX Strap 2 Bit 3 [ Disabled / Enabled ] */ + PAD_CFG_GPO(GPP_E19, 0, PLTRST), /* TBT LSX #0 [ 1.8V / 3.3V ] */ + PAD_CFG_GPO(GPP_E21, 0, PLTRST), /* TBT LSX #1 [ 1.8V / 3.3V ] */ + PAD_CFG_GPO(GPP_D10, 0, PLTRST), /* TBT LSX #2 [ 1.8V / 3.3V ] */ + PAD_CFG_GPO(GPP_D12, 0, PLTRST), /* TBT LSX #3 [ 1.8V / 3.3V ] */ + PAD_CFG_GPO(GPP_F7, 0, PLTRST), /* MCRO LDO [ Disabled / Bypass ] */ + PAD_CFG_GPO(GPD7, 0, PLTRST), /* RTC Clock Delay [ Disabled / 95ms ] */ PAD_NC(GPD2, NONE), PAD_NC(GPD6, NONE), diff --git a/src/mainboard/starlabs/adl/variants/i5/hda_verb.c b/src/mainboard/starlabs/adl/variants/i5/hda_verb.c new file mode 100644 index 0000000000..f7529371d6 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/i5/hda_verb.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +const u32 cim_verb_data[] = { + /* coreboot specific header */ + 0x10ec0269, /* Codec Vendor / Device ID: Realtek ALC269 */ + 0x1e507038, /* Subsystem ID */ + 18, /* Number of jacks (NID entries) */ + + /* Reset Codec First */ + AZALIA_RESET(0x1), + + /* HDA Codec Subsystem ID */ + AZALIA_SUBVENDOR(0, 0x1e507038), + + /* Pin Widget Verb-table */ + AZALIA_PIN_CFG(0, ALC269_DMIC12, + AZALIA_PIN_DESC(AZALIA_INTEGRATED, AZALIA_INTERNAL | AZALIA_FRONT, + AZALIA_MIC_IN, AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, AZALIA_NO_JACK_PRESENCE_DETECT, 3, + 0)), + + AZALIA_PIN_CFG(0, ALC269_SPEAKERS, + AZALIA_PIN_DESC(AZALIA_INTEGRATED, AZALIA_INTERNAL | AZALIA_FRONT, + AZALIA_SPEAKER, AZALIA_OTHER_ANALOG, + AZALIA_COLOR_UNKNOWN, AZALIA_NO_JACK_PRESENCE_DETECT, 1, + 0)), + AZALIA_PIN_CFG(0, ALC269_VC_HP_OUT, + AZALIA_PIN_DESC(AZALIA_JACK, + AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, + AZALIA_HP_OUT, AZALIA_STEREO_MONO_1_8, AZALIA_BLACK, + AZALIA_JACK_PRESENCE_DETECT, 2, 0)), + AZALIA_PIN_CFG(0, ALC269_MIC1, + AZALIA_PIN_DESC(AZALIA_JACK, + AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, + AZALIA_MIC_IN, AZALIA_STEREO_MONO_1_8, AZALIA_BLACK, + AZALIA_JACK_PRESENCE_DETECT, 4, 0)), + AZALIA_PIN_CFG(0, ALC269_MONO, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_MIC2, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_LINE1, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_LINE2, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_PC_BEEP, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_SPDIF_OUT, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_VB_HP_OUT, AZALIA_PIN_CFG_NC(0)), + + /* ALC269 Default 1 */ + 0x02050018, + 0x02040184, + 0x0205001c, + 0x02044800, + /* ALC269 Default 2 */ + 0x02050024, + 0x02040000, + 0x02050004, + 0x02040080, + /* ALC269 Default 3 */ + 0x02050008, + 0x02040000, + 0x0205000c, + 0x02043f00, + /* ALC269 Default 4 */ + 0x02050015, + 0x02048002, + 0x02050015, + 0x02048002, + /* Widget 0x0c */ + 0x00c37080, + 0x00270610, + 0x00d37080, + 0x00370610, +}; + +const u32 pc_beep_verbs[] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/ramstage.c b/src/mainboard/starlabs/adl/variants/i5/ramstage.c similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/ramstage.c rename to src/mainboard/starlabs/adl/variants/i5/ramstage.c diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/romstage.c b/src/mainboard/starlabs/adl/variants/i5/romstage.c similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/romstage.c rename to src/mainboard/starlabs/adl/variants/i5/romstage.c diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/vboot.fmd b/src/mainboard/starlabs/adl/variants/i5/vboot.fmd similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/vboot.fmd rename to src/mainboard/starlabs/adl/variants/i5/vboot.fmd diff --git a/src/mainboard/starlabs/starlite_adl/Kconfig b/src/mainboard/starlabs/starlite_adl/Kconfig deleted file mode 100644 index 00c2a4ecb5..0000000000 --- a/src/mainboard/starlabs/starlite_adl/Kconfig +++ /dev/null @@ -1,123 +0,0 @@ -config BOARD_STARLABS_STARLITE_SERIES - def_bool n - select AZALIA_USE_LEGACY_VERB_TABLE - select BOARD_ROMSIZE_KB_16384 - select CRB_TPM - select CSE_DEFAULT_CFR_OPTION_STATE_DISABLED - select DRIVERS_EFI_VARIABLE_STORE - select DRIVERS_GFX_GENERIC - select DRIVERS_I2C_HID - select DRIVERS_INTEL_PMC - select DRIVERS_OPTION_CFR_ENABLED - select EC_STARLABS_MERLIN - select HAVE_ACPI_RESUME - select HAVE_ACPI_TABLES - select HAVE_HDA_DMIC - select HAVE_INTEL_PTT - select HAVE_OPTION_TABLE - select HAVE_SPD_IN_CBFS - select INTEL_GMA_HAVE_VBT - select INTEL_LPSS_UART_FOR_CONSOLE - select NO_UART_ON_SUPERIO - select PMC_IPC_ACPI_INTERFACE - select SOC_INTEL_ALDERLAKE - select SOC_INTEL_ALDERLAKE_PCH_N - select SOC_INTEL_COMMON_BLOCK_HDA_VERB - select SOC_INTEL_COMMON_BLOCK_TCSS - select SOC_INTEL_CRASHLOG - select SPD_READ_BY_WORD - select SPI_FLASH_WINBOND - select SYSTEM_TYPE_DETACHABLE - select TPM2 - select VALIDATE_INTEL_DESCRIPTOR - -config BOARD_STARLABS_LITE_ADL - select BOARD_STARLABS_STARLITE_SERIES - -if BOARD_STARLABS_STARLITE_SERIES - -config CCD_PORT - int - default 5 - -config CONSOLE_SERIAL - default n if !EDK2_DEBUG - -config D3COLD_SUPPORT - default n - -config DEVICETREE - default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" - -config DIMM_SPD_SIZE - default 512 - -config EC_STARLABS_BATTERY_MODEL - default "AEC3756153-2S1P-N" - -config EC_STARLABS_BATTERY_TYPE - default "LION" - -config EC_STARLABS_BATTERY_OEM - default "Apower Electronics" - -config EC_STARLABS_ITE_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/ec.bin" - -config FMDFILE - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/vboot.fmd" if VBOOT - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" - -config IFD_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/flashdescriptor.bin" - -config MAINBOARD_DIR - default "starlabs/starlite_adl" - -config MAINBOARD_FAMILY - string - default "I5" - -config MAINBOARD_PART_NUMBER - default "StarLite Mk V" - -config MAINBOARD_SMBIOS_PRODUCT_NAME - default "StarLite" - -config ME_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/intel_me.bin" - -config POWER_STATE_DEFAULT_ON_AFTER_FAILURE - default n - -config EDK2_BOOTSPLASH_FILE - string - default "3rdparty/blobs/mainboard/starlabs/Logo.bmp" - -config SOC_INTEL_CSE_SEND_EOP_EARLY - default n - -config TJ_MAX - int - default 105 - -config PL4_WATTS - int - default 37 - -config UART_FOR_CONSOLE - default 0 - -config USE_PM_ACPI_TIMER - default n - -config VBOOT - select VBOOT_VBNV_FLASH - -config VARIANT_DIR - default "mk_v" - -endif diff --git a/src/mainboard/starlabs/starlite_adl/Kconfig.name b/src/mainboard/starlabs/starlite_adl/Kconfig.name deleted file mode 100644 index 071490084b..0000000000 --- a/src/mainboard/starlabs/starlite_adl/Kconfig.name +++ /dev/null @@ -1,4 +0,0 @@ -comment "Star Labs StarLite Series" - -config BOARD_STARLABS_LITE_ADL - bool "Star Labs Lite Mk V (N200/N355)" diff --git a/src/mainboard/starlabs/starlite_adl/Makefile.mk b/src/mainboard/starlabs/starlite_adl/Makefile.mk deleted file mode 100644 index 14842f76e4..0000000000 --- a/src/mainboard/starlabs/starlite_adl/Makefile.mk +++ /dev/null @@ -1,14 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include -subdirs-$(CONFIG_HAVE_SPD_IN_CBFS) += ./spd -subdirs-y += variants/$(VARIANT_DIR) - -bootblock-y += bootblock.c - -verstage-$(CONFIG_VBOOT) += vboot.c - -romstage-$(CONFIG_VBOOT) += vboot.c - -ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += cfr.c -ramstage-y += mainboard.c diff --git a/src/mainboard/starlabs/starlite_adl/acpi/ec.asl b/src/mainboard/starlabs/starlite_adl/acpi/ec.asl deleted file mode 100644 index 853b0877b3..0000000000 --- a/src/mainboard/starlabs/starlite_adl/acpi/ec.asl +++ /dev/null @@ -1 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/src/mainboard/starlabs/starlite_adl/acpi/mainboard.asl b/src/mainboard/starlabs/starlite_adl/acpi/mainboard.asl deleted file mode 100644 index f9d095244a..0000000000 --- a/src/mainboard/starlabs/starlite_adl/acpi/mainboard.asl +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -Scope (\_SB) { - #include "sleep.asl" -} - -Scope (_GPE) -{ - Method (_E0F, 0, NotSerialized) - { - \_SB.PCI0.LPCB.EC.VBTN.UPDK() - } -} diff --git a/src/mainboard/starlabs/starlite_adl/acpi/sleep.asl b/src/mainboard/starlabs/starlite_adl/acpi/sleep.asl deleted file mode 100644 index 7ed74e3514..0000000000 --- a/src/mainboard/starlabs/starlite_adl/acpi/sleep.asl +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -Method (MPTS, 1, NotSerialized) -{ - RPTS (Arg0) -} - -Method (MWAK, 1, NotSerialized) -{ - RWAK (Arg0) -} diff --git a/src/mainboard/starlabs/starlite_adl/acpi/superio.asl b/src/mainboard/starlabs/starlite_adl/acpi/superio.asl deleted file mode 100644 index 853b0877b3..0000000000 --- a/src/mainboard/starlabs/starlite_adl/acpi/superio.asl +++ /dev/null @@ -1 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/src/mainboard/starlabs/starlite_adl/board_info.txt b/src/mainboard/starlabs/starlite_adl/board_info.txt deleted file mode 100644 index 77f1b9b0d5..0000000000 --- a/src/mainboard/starlabs/starlite_adl/board_info.txt +++ /dev/null @@ -1,6 +0,0 @@ -Vendor name: Star Labs -Board name: StarLite -Category: laptop -ROM protocol: SPI -ROM socketed: n -Flashrom support: y diff --git a/src/mainboard/starlabs/starlite_adl/bootblock.c b/src/mainboard/starlabs/starlite_adl/bootblock.c deleted file mode 100644 index ca48bb1ab2..0000000000 --- a/src/mainboard/starlabs/starlite_adl/bootblock.c +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -void bootblock_mainboard_init(void) -{ - const struct pad_config *pads; - size_t num; - - pads = variant_early_gpio_table(&num); - gpio_configure_pads(pads, num); -} diff --git a/src/mainboard/starlabs/starlite_adl/cfr.c b/src/mainboard/starlabs/starlite_adl/cfr.c deleted file mode 100644 index 0cf911b9f2..0000000000 --- a/src/mainboard/starlabs/starlite_adl/cfr.c +++ /dev/null @@ -1,169 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void cfr_card_reader_update(struct sm_object *new_obj) -{ - struct device *mxc_accel = DEV_PTR(mxc6655); - - if (!i2c_dev_detect(i2c_busdev(mxc_accel), mxc_accel->path.i2c.device)) - new_obj->sm_bool.flags = CFR_OPTFLAG_SUPPRESS; -} - -void cfr_touchscreen_update(struct sm_object *new_obj) -{ - if (get_uint_option("accelerometer", 1) == 0) - new_obj->sm_bool.flags = CFR_OPTFLAG_SUPPRESS; -} - -static struct sm_obj_form audio_video_group = { - .ui_name = "Audio/Video", - .obj_list = (const struct sm_object *[]) { - µphone, - &webcam, - NULL - }, -}; - -static struct sm_obj_form battery_group = { - .ui_name = "Battery", - .obj_list = (const struct sm_object *[]) { - #if CONFIG(EC_STARLABS_CHARGING_SPEED) - &charging_speed, - #endif - &max_charge, - &power_on_after_fail_bool, - NULL - }, -}; - -static struct sm_obj_form debug_group = { - .ui_name = "Debug", - .obj_list = (const struct sm_object *[]) { - &debug_level, - NULL - }, -}; - -static struct sm_obj_form display_group = { - .ui_name = "Display", - .obj_list = (const struct sm_object *[]) { - &accelerometer, - &display_native_res, - &touchscreen, - NULL - }, -}; - -static struct sm_obj_form io_expansion_group = { - .ui_name = "I/O / Expansion", - .obj_list = (const struct sm_object *[]) { - &card_reader, - NULL - }, -}; - -static struct sm_obj_form leds_group = { - .ui_name = "LEDs", - .obj_list = (const struct sm_object *[]) { - &charge_led, - &power_led, - NULL - }, -}; - -static struct sm_obj_form pcie_power_management_group = { - .ui_name = "PCIe Power Management", - .obj_list = (const struct sm_object *[]) { - #if CONFIG(SOC_INTEL_COMMON_BLOCK_ASPM) - &pciexp_aspm, - &pciexp_clk_pm, - &pciexp_l1ss, - #endif - NULL - }, -}; - -static struct sm_obj_form performance_group = { - .ui_name = "Performance", - .obj_list = (const struct sm_object *[]) { - #if CONFIG(SOC_INTEL_TIGERLAKE) || CONFIG(SOC_INTEL_ALDERLAKE) || CONFIG(SOC_INTEL_RAPTORLAKE) - &gna, - #endif - &memory_speed, - &power_profile, - NULL - }, -}; - -static struct sm_obj_form security_group = { - .ui_name = "Security", - .obj_list = (const struct sm_object *[]) { - &bios_lock, - &intel_tme, - &me_state, - &me_state_counter, - NULL - }, -}; - -static struct sm_obj_form suspend_lid_group = { - .ui_name = "Suspend & Lid", - .obj_list = (const struct sm_object *[]) { - #if CONFIG(EC_STARLABS_LID_SWITCH) - &lid_switch, - #endif - &s0ix_enable, - NULL - }, -}; - -static struct sm_obj_form virtualization_group = { - .ui_name = "Virtualization", - .obj_list = (const struct sm_object *[]) { - &vtd, - NULL - }, -}; - -static struct sm_obj_form wireless_group = { - .ui_name = "Wireless", - .obj_list = (const struct sm_object *[]) { - &bluetooth, - &bluetooth_rtd3, - &wifi, - NULL - }, -}; - -static struct sm_obj_form *sm_root[] = { - &audio_video_group, - &battery_group, - &debug_group, - &display_group, - &io_expansion_group, - &leds_group, - &pcie_power_management_group, - &performance_group, - &security_group, - &suspend_lid_group, - &virtualization_group, - &wireless_group, - NULL -}; - -void mb_cfr_setup_menu(struct lb_cfr *cfr_root) -{ - starlabs_cfr_register_overrides(); - cfr_write_setup_menu(cfr_root, sm_root); -} diff --git a/src/mainboard/starlabs/starlite_adl/dsdt.asl b/src/mainboard/starlabs/starlite_adl/dsdt.asl deleted file mode 100644 index b7783eae63..0000000000 --- a/src/mainboard/starlabs/starlite_adl/dsdt.asl +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -DefinitionBlock( - "dsdt.aml", - "DSDT", - ACPI_DSDT_REV_2, - OEM_ID, - ACPI_TABLE_CREATOR, - 0x20220930 -) -{ - #include - #include - #include - #include - - Device (\_SB.PCI0) - { - #include - #include - #include - - #include - - #include - - /* PS/2 Keyboard */ - #include - } - - #include - - /* Star Labs EC */ - #include - - Scope (\_SB) - { - /* HID Driver */ - #include - - /* Suspend Methods */ - #include - } - - #include "acpi/mainboard.asl" -} diff --git a/src/mainboard/starlabs/starlite_adl/include/variants.h b/src/mainboard/starlabs/starlite_adl/include/variants.h deleted file mode 100644 index c95d15bd72..0000000000 --- a/src/mainboard/starlabs/starlite_adl/include/variants.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _BASEBOARD_VARIANTS_H_ -#define _BASEBOARD_VARIANTS_H_ - -#include - -/* - * The next set of functions return the gpio table and fill in the number of - * entries for each table. - */ -const struct pad_config *variant_gpio_table(size_t *num); -const struct pad_config *variant_early_gpio_table(size_t *num); - -void devtree_update(void); - -#endif /* _BASEBOARD_VARIANTS_H_ */ diff --git a/src/mainboard/starlabs/starlite_adl/mainboard.c b/src/mainboard/starlabs/starlite_adl/mainboard.c deleted file mode 100644 index 1583ad9094..0000000000 --- a/src/mainboard/starlabs/starlite_adl/mainboard.c +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -static void init_mainboard(void *chip_info) -{ - const struct pad_config *pads; - size_t num; - - pads = variant_gpio_table(&num); - gpio_configure_pads(pads, num); -} - -static void mainboard_fill_ssdt(const struct device *dev) -{ - enum ps2_action_key ps2_action_keys[2] = {PS2_KEY_VOL_DOWN, PS2_KEY_VOL_UP}; - acpigen_ps2_keyboard_dsd("_SB.PCI0.PS2K", ARRAY_SIZE(ps2_action_keys), ps2_action_keys, - false, false, false, false, false); -} - -static void enable_mainboard(struct device *dev) -{ - dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt; -} - -struct chip_operations mainboard_ops = { - .init = init_mainboard, - .enable_dev = enable_mainboard, -}; diff --git a/src/mainboard/starlabs/starlite_adl/spd/Makefile.mk b/src/mainboard/starlabs/starlite_adl/spd/Makefile.mk deleted file mode 100644 index 7c50cd736a..0000000000 --- a/src/mainboard/starlabs/starlite_adl/spd/Makefile.mk +++ /dev/null @@ -1,5 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -SPD_SOURCES = mt62f2g64d8-5500 -SPD_SOURCES += mt62f2g64d8-6400 -SPD_SOURCES += mt62f2g64d8-7500 diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/hda_verb.c b/src/mainboard/starlabs/starlite_adl/variants/mk_v/hda_verb.c deleted file mode 100644 index 24d23ae55d..0000000000 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/hda_verb.c +++ /dev/null @@ -1,98 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const u32 cim_verb_data[] = { - /* coreboot specific header */ - 0x10ec0269, /* Codec Vendor / Device ID: Realtek ALC269 */ - 0x1e507038, /* Subsystem ID */ - 18, /* Number of jacks (NID entries) */ - - /* Reset Codec First */ - AZALIA_RESET(0x1), - - /* HDA Codec Subsystem ID */ - AZALIA_SUBVENDOR(0, 0x1e507038), - - /* Pin Widget Verb-table */ - AZALIA_PIN_CFG(0, ALC269_DMIC12, AZALIA_PIN_DESC( - AZALIA_INTEGRATED, - AZALIA_INTERNAL | AZALIA_FRONT, - AZALIA_MIC_IN, - AZALIA_OTHER_DIGITAL, - AZALIA_COLOR_UNKNOWN, - AZALIA_NO_JACK_PRESENCE_DETECT, - 3, - 0 - )), - - AZALIA_PIN_CFG(0, ALC269_SPEAKERS, AZALIA_PIN_DESC( - AZALIA_INTEGRATED, - AZALIA_INTERNAL | AZALIA_FRONT, - AZALIA_SPEAKER, - AZALIA_OTHER_ANALOG, - AZALIA_COLOR_UNKNOWN, - AZALIA_NO_JACK_PRESENCE_DETECT, - 1, - 0 - )), - AZALIA_PIN_CFG(0, ALC269_VC_HP_OUT, AZALIA_PIN_DESC( - AZALIA_JACK, - AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, - AZALIA_HP_OUT, - AZALIA_STEREO_MONO_1_8, - AZALIA_BLACK, - AZALIA_JACK_PRESENCE_DETECT, - 2, - 0 - )), - AZALIA_PIN_CFG(0, ALC269_MIC1, AZALIA_PIN_DESC( - AZALIA_JACK, - AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, - AZALIA_MIC_IN, - AZALIA_STEREO_MONO_1_8, - AZALIA_BLACK, - AZALIA_JACK_PRESENCE_DETECT, - 4, - 0 - )), - AZALIA_PIN_CFG(0, ALC269_MONO, AZALIA_PIN_CFG_NC(0)), - AZALIA_PIN_CFG(0, ALC269_MIC2, AZALIA_PIN_CFG_NC(0)), - AZALIA_PIN_CFG(0, ALC269_LINE1, AZALIA_PIN_CFG_NC(0)), - AZALIA_PIN_CFG(0, ALC269_LINE2, AZALIA_PIN_CFG_NC(0)), - AZALIA_PIN_CFG(0, ALC269_PC_BEEP, AZALIA_PIN_CFG_NC(0)), - AZALIA_PIN_CFG(0, ALC269_SPDIF_OUT, AZALIA_PIN_CFG_NC(0)), - AZALIA_PIN_CFG(0, ALC269_VB_HP_OUT, AZALIA_PIN_CFG_NC(0)), - - /* ALC269 Default 1 */ - 0x02050018, - 0x02040184, - 0x0205001c, - 0x02044800, - /* ALC269 Default 2 */ - 0x02050024, - 0x02040000, - 0x02050004, - 0x02040080, - /* ALC269 Default 3 */ - 0x02050008, - 0x02040000, - 0x0205000c, - 0x02043f00, - /* ALC269 Default 4 */ - 0x02050015, - 0x02048002, - 0x02050015, - 0x02048002, - /* Widget 0x0c */ - 0x00c37080, - 0x00270610, - 0x00d37080, - 0x00370610, -}; - -const u32 pc_beep_verbs[] = { -}; - -AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/starlabs/starlite_adl/vboot.c b/src/mainboard/starlabs/starlite_adl/vboot.c deleted file mode 100644 index 8511825004..0000000000 --- a/src/mainboard/starlabs/starlite_adl/vboot.c +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -int get_recovery_mode_switch(void) -{ - return 0; -} From 14fcb3baf8935cde85e617f5c0afffb04d7b5e4e Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Fri, 27 Feb 2026 21:55:50 +0000 Subject: [PATCH 675/789] mainboard/starlabs/adl: move CFR callbacks to variant Move the i5 variant-specific CFR callbacks out of the baseboard CFR menu and compile them from the variant directory. This reduces preprocessor usage in the common file. Change-Id: Ic03ec18aed100a95d347c49c2b1deecf1c3fd961 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/91458 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/adl/Makefile.mk | 1 + src/mainboard/starlabs/adl/cfr.c | 23 -------------------- src/mainboard/starlabs/adl/variants/i5/cfr.c | 21 ++++++++++++++++++ 3 files changed, 22 insertions(+), 23 deletions(-) create mode 100644 src/mainboard/starlabs/adl/variants/i5/cfr.c diff --git a/src/mainboard/starlabs/adl/Makefile.mk b/src/mainboard/starlabs/adl/Makefile.mk index ad15bbd510..f42ebef3ab 100644 --- a/src/mainboard/starlabs/adl/Makefile.mk +++ b/src/mainboard/starlabs/adl/Makefile.mk @@ -7,4 +7,5 @@ subdirs-y += variants/$(VARIANT_DIR) bootblock-y += bootblock.c ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += cfr.c +ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += $(wildcard variants/$(VARIANT_DIR)/cfr.c) ramstage-y += mainboard.c diff --git a/src/mainboard/starlabs/adl/cfr.c b/src/mainboard/starlabs/adl/cfr.c index 74106c295c..cd4a27c302 100644 --- a/src/mainboard/starlabs/adl/cfr.c +++ b/src/mainboard/starlabs/adl/cfr.c @@ -5,31 +5,8 @@ #include #include #include -#if CONFIG(BOARD_STARLABS_LITE_ADL) -#include -#include -#include -#include -#include -#endif #include -#if CONFIG(BOARD_STARLABS_LITE_ADL) -void cfr_card_reader_update(struct sm_object *new_obj) -{ - struct device *mxc_accel = DEV_PTR(mxc6655); - - if (!i2c_dev_detect(i2c_busdev(mxc_accel), mxc_accel->path.i2c.device)) - new_obj->sm_bool.flags = CFR_OPTFLAG_SUPPRESS; -} - -void cfr_touchscreen_update(struct sm_object *new_obj) -{ - if (get_uint_option("accelerometer", 1) == 0) - new_obj->sm_bool.flags = CFR_OPTFLAG_SUPPRESS; -} -#endif - #if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) static struct sm_obj_form audio_video_group = { .ui_name = "Audio/Video", diff --git a/src/mainboard/starlabs/adl/variants/i5/cfr.c b/src/mainboard/starlabs/adl/variants/i5/cfr.c new file mode 100644 index 0000000000..5593cb5531 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/i5/cfr.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +void cfr_card_reader_update(struct sm_object *new_obj) +{ + struct device *mxc_accel = DEV_PTR(mxc6655); + + if (!i2c_dev_detect(i2c_busdev(mxc_accel), mxc_accel->path.i2c.device)) + new_obj->sm_bool.flags |= CFR_OPTFLAG_SUPPRESS; +} + +void cfr_touchscreen_update(struct sm_object *new_obj) +{ + if (get_uint_option("accelerometer", 1) == 0) + new_obj->sm_bool.flags |= CFR_OPTFLAG_SUPPRESS; +} From ffad2454c43030832993495bc85733524441cdac Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Fri, 27 Feb 2026 21:56:53 +0000 Subject: [PATCH 676/789] mainboard/starlabs/adl: drop redundant ASPM CFR guard All Star Labs ADL boards select SOC_INTEL_COMMON_BLOCK_ASPM, so the additional preprocessor guard in the PCIe CFR form is redundant. Signed-off-by: Sean Rhodes Change-Id: Id7cd4911666c02f88a9c1c5f074ac996744be23d Reviewed-on: https://review.coreboot.org/c/coreboot/+/91459 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/adl/cfr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mainboard/starlabs/adl/cfr.c b/src/mainboard/starlabs/adl/cfr.c index cd4a27c302..8c8f5f601f 100644 --- a/src/mainboard/starlabs/adl/cfr.c +++ b/src/mainboard/starlabs/adl/cfr.c @@ -88,11 +88,9 @@ static struct sm_obj_form pcie_power_management_group = { .ui_name = "PCIe Power Management", .obj_list = (const struct sm_object *[]){ -#if CONFIG(SOC_INTEL_COMMON_BLOCK_ASPM) &pciexp_aspm, &pciexp_clk_pm, &pciexp_l1ss, -#endif NULL, }, }; From 5156ec45330744654f6b5a0fa19bec44ddab2034 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Fri, 27 Feb 2026 21:57:29 +0000 Subject: [PATCH 677/789] mainboard/starlabs/adl: move SSDT hook to variant Replace the BOARD_STARLABS_LITE_ADL preprocessor hook with a weak baseboard function and provide the StarLite-specific SSDT generator from the i5 variant directory. Change-Id: Iea1a27fe1bf86bf970bd7021135760d8a1bc75a1 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/91460 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/adl/include/variants.h | 3 +++ src/mainboard/starlabs/adl/mainboard.c | 19 +++---------------- .../starlabs/adl/variants/i5/Makefile.mk | 1 + .../starlabs/adl/variants/i5/mainboard_ssdt.c | 16 ++++++++++++++++ 4 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 src/mainboard/starlabs/adl/variants/i5/mainboard_ssdt.c diff --git a/src/mainboard/starlabs/adl/include/variants.h b/src/mainboard/starlabs/adl/include/variants.h index c95d15bd72..536ac891ae 100644 --- a/src/mainboard/starlabs/adl/include/variants.h +++ b/src/mainboard/starlabs/adl/include/variants.h @@ -3,6 +3,7 @@ #ifndef _BASEBOARD_VARIANTS_H_ #define _BASEBOARD_VARIANTS_H_ +#include #include /* @@ -14,4 +15,6 @@ const struct pad_config *variant_early_gpio_table(size_t *num); void devtree_update(void); +void starlabs_adl_mainboard_fill_ssdt(const struct device *dev); + #endif /* _BASEBOARD_VARIANTS_H_ */ diff --git a/src/mainboard/starlabs/adl/mainboard.c b/src/mainboard/starlabs/adl/mainboard.c index 8a3dadbc48..f8c9aea3ae 100644 --- a/src/mainboard/starlabs/adl/mainboard.c +++ b/src/mainboard/starlabs/adl/mainboard.c @@ -1,14 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#if CONFIG(BOARD_STARLABS_LITE_ADL) -#include -#include -#endif - #include #include #include -#include #include static void init_mainboard(void *chip_info) @@ -22,21 +16,14 @@ static void init_mainboard(void *chip_info) devtree_update(); } -#if CONFIG(BOARD_STARLABS_LITE_ADL) -static void mainboard_fill_ssdt(const struct device *dev) +void __weak starlabs_adl_mainboard_fill_ssdt(const struct device *dev) { - enum ps2_action_key ps2_action_keys[2] = {PS2_KEY_VOL_DOWN, PS2_KEY_VOL_UP}; - - acpigen_ps2_keyboard_dsd("_SB.PCI0.PS2K", ARRAY_SIZE(ps2_action_keys), ps2_action_keys, - false, false, false, false, false); + (void)dev; } -#endif static void enable_mainboard(struct device *dev) { -#if CONFIG(BOARD_STARLABS_LITE_ADL) - dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt; -#endif + dev->ops->acpi_fill_ssdt = starlabs_adl_mainboard_fill_ssdt; } struct chip_operations mainboard_ops = { diff --git a/src/mainboard/starlabs/adl/variants/i5/Makefile.mk b/src/mainboard/starlabs/adl/variants/i5/Makefile.mk index bfea7ef255..d6e2d5b29d 100644 --- a/src/mainboard/starlabs/adl/variants/i5/Makefile.mk +++ b/src/mainboard/starlabs/adl/variants/i5/Makefile.mk @@ -7,6 +7,7 @@ romstage-y += romstage.c ramstage-y += devtree.c ramstage-y += gpio.c ramstage-y += hda_verb.c +ramstage-y += mainboard_ssdt.c ramstage-y += ramstage.c $(call add_vbt_to_cbfs, vbt_native_res.bin, data_native_res.vbt) diff --git a/src/mainboard/starlabs/adl/variants/i5/mainboard_ssdt.c b/src/mainboard/starlabs/adl/variants/i5/mainboard_ssdt.c new file mode 100644 index 0000000000..a58becd7f6 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/i5/mainboard_ssdt.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void starlabs_adl_mainboard_fill_ssdt(const struct device *dev) +{ + enum ps2_action_key ps2_action_keys[2] = { PS2_KEY_VOL_DOWN, PS2_KEY_VOL_UP }; + + (void)dev; + + acpigen_ps2_keyboard_dsd("_SB.PCI0.PS2K", ARRAY_SIZE(ps2_action_keys), ps2_action_keys, + false, false, false, false, false); +} From 724176a218304c930aa0360bf976b3d000335571 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Fri, 27 Feb 2026 21:58:04 +0000 Subject: [PATCH 678/789] mainboard/starlabs: namespace PL4 powercap setting Rename the PL4 powercap Kconfig symbol to MB_STARLABS_PL4_WATTS and update the common powercap logic to use the namespaced option. Change-Id: If36d087accc13a03eac4715948a4ca47bd70c3c4 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/91461 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/adl/Kconfig | 2 +- src/mainboard/starlabs/common/powercap/powercap.c | 2 +- src/mainboard/starlabs/lite/Kconfig | 2 +- src/mainboard/starlabs/starbook/Kconfig | 2 +- src/mainboard/starlabs/starfighter/Kconfig | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mainboard/starlabs/adl/Kconfig b/src/mainboard/starlabs/adl/Kconfig index 569274f9e6..ebe225fd76 100644 --- a/src/mainboard/starlabs/adl/Kconfig +++ b/src/mainboard/starlabs/adl/Kconfig @@ -171,7 +171,7 @@ endif # BOARD_STARLABS_ADL_HORIZON || BOARD_STARLABS_LITE_ADL if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL || BOARD_STARLABS_LITE_ADL -config PL4_WATTS +config MB_STARLABS_PL4_WATTS int default 65 if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL default 37 if BOARD_STARLABS_LITE_ADL diff --git a/src/mainboard/starlabs/common/powercap/powercap.c b/src/mainboard/starlabs/common/powercap/powercap.c index 2bc7705136..21b879f5cf 100644 --- a/src/mainboard/starlabs/common/powercap/powercap.c +++ b/src/mainboard/starlabs/common/powercap/powercap.c @@ -45,7 +45,7 @@ void update_power_limits(config_t *cfg) struct soc_power_limits_config *entry = &limits[i]; uint16_t tdp, pl1, pl2; - entry->tdp_pl4 = (uint16_t)CONFIG_PL4_WATTS; + entry->tdp_pl4 = (uint16_t)CONFIG_MB_STARLABS_PL4_WATTS; tdp = entry->tdp_pl1_override; if (!tdp) diff --git a/src/mainboard/starlabs/lite/Kconfig b/src/mainboard/starlabs/lite/Kconfig index e68e84b397..440b2723fe 100644 --- a/src/mainboard/starlabs/lite/Kconfig +++ b/src/mainboard/starlabs/lite/Kconfig @@ -87,7 +87,7 @@ config TJ_MAX int default 100 -config PL4_WATTS +config MB_STARLABS_PL4_WATTS int default 45 diff --git a/src/mainboard/starlabs/starbook/Kconfig b/src/mainboard/starlabs/starbook/Kconfig index 063a7c6410..9e517008f7 100644 --- a/src/mainboard/starlabs/starbook/Kconfig +++ b/src/mainboard/starlabs/starbook/Kconfig @@ -203,7 +203,7 @@ config TJ_MAX default 105 if BOARD_STARLABS_STARBOOK_ADL_N default 110 -config PL4_WATTS +config MB_STARLABS_PL4_WATTS int default 45 if BOARD_STARLABS_LABTOP_KBL || BOARD_STARLABS_LABTOP_CML default 65 diff --git a/src/mainboard/starlabs/starfighter/Kconfig b/src/mainboard/starlabs/starfighter/Kconfig index 5709ced88c..78c2667832 100644 --- a/src/mainboard/starlabs/starfighter/Kconfig +++ b/src/mainboard/starlabs/starfighter/Kconfig @@ -126,7 +126,7 @@ config TJ_MAX int default 110 -config PL4_WATTS +config MB_STARLABS_PL4_WATTS int default 80 From dde872911a06d868e0643379e2f8532c141308f3 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Fri, 27 Feb 2026 21:58:27 +0000 Subject: [PATCH 679/789] mainboard/starlabs: drop unused TJ_MAX option The TJ_MAX Kconfig option isn't referenced anywhere in-tree. Drop the\nunused setting to avoid confusion and keep the Kconfig clean. Change-Id: I56a5c287be5ed61094b4c006a9661ee9b46b6d36 Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/91462 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/adl/Kconfig | 4 ---- src/mainboard/starlabs/lite/Kconfig | 4 ---- src/mainboard/starlabs/starbook/Kconfig | 6 ------ src/mainboard/starlabs/starfighter/Kconfig | 4 ---- 4 files changed, 18 deletions(-) diff --git a/src/mainboard/starlabs/adl/Kconfig b/src/mainboard/starlabs/adl/Kconfig index ebe225fd76..50d56bfa98 100644 --- a/src/mainboard/starlabs/adl/Kconfig +++ b/src/mainboard/starlabs/adl/Kconfig @@ -176,10 +176,6 @@ config MB_STARLABS_PL4_WATTS default 65 if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL default 37 if BOARD_STARLABS_LITE_ADL -config TJ_MAX - int - default 105 if BOARD_STARLABS_LITE_ADL - config VBOOT select VBOOT_VBNV_FLASH diff --git a/src/mainboard/starlabs/lite/Kconfig b/src/mainboard/starlabs/lite/Kconfig index 440b2723fe..1b03c054b2 100644 --- a/src/mainboard/starlabs/lite/Kconfig +++ b/src/mainboard/starlabs/lite/Kconfig @@ -83,10 +83,6 @@ config MAINBOARD_SMBIOS_PRODUCT_NAME config POWER_STATE_DEFAULT_ON_AFTER_FAILURE default n -config TJ_MAX - int - default 100 - config MB_STARLABS_PL4_WATTS int default 45 diff --git a/src/mainboard/starlabs/starbook/Kconfig b/src/mainboard/starlabs/starbook/Kconfig index 9e517008f7..cb9bccd3a4 100644 --- a/src/mainboard/starlabs/starbook/Kconfig +++ b/src/mainboard/starlabs/starbook/Kconfig @@ -197,12 +197,6 @@ config POWER_STATE_DEFAULT_ON_AFTER_FAILURE config SOC_INTEL_CSE_SEND_EOP_EARLY default n -config TJ_MAX - int - default 100 if BOARD_STARLABS_LABTOP_KBL || BOARD_STARLABS_LABTOP_CML || BOARD_STARLABS_STARBOOK_TGL - default 105 if BOARD_STARLABS_STARBOOK_ADL_N - default 110 - config MB_STARLABS_PL4_WATTS int default 45 if BOARD_STARLABS_LABTOP_KBL || BOARD_STARLABS_LABTOP_CML diff --git a/src/mainboard/starlabs/starfighter/Kconfig b/src/mainboard/starlabs/starfighter/Kconfig index 78c2667832..f32a9a8153 100644 --- a/src/mainboard/starlabs/starfighter/Kconfig +++ b/src/mainboard/starlabs/starfighter/Kconfig @@ -122,10 +122,6 @@ config SOC_INTEL_CSE_SEND_EOP_EARLY config TME_KEY_REGENERATION_ON_WARM_BOOT default n -config TJ_MAX - int - default 110 - config MB_STARLABS_PL4_WATTS int default 80 From 0a6142dfbe4b81442e4e307ccd087759aae5a4a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Tue, 16 Sep 2025 08:22:41 +0200 Subject: [PATCH 680/789] soc/amd/turin_poc: Add SPI TPM SoC-specific initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the SoC hook to initialize SPI TPM decoding. Without the additional programming an attempt to talk to SPI TPM hangs the platform when the TPM_MEASURED_BOOT_INIT_BOOTBLOCK is set. If TPM is initialized in ramstage, the OpenSIL programs the SPI TPM decoding properly and the issue is not observed. TEST=Select TPM_MEASURED_BOOT_INIT_BOOTBLOCK and enable TPM_MEASURED_BOOT on Gigabyte MZ33-AR1, and observe the platform does not hang in bootblock. Change-Id: I2e6c0aad31fd0335e0d16111ed4894a12d2ba497 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/89192 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Patrick Rudolph --- src/soc/amd/turin_poc/Makefile.mk | 3 +++ src/soc/amd/turin_poc/lpc.c | 11 +++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/soc/amd/turin_poc/lpc.c diff --git a/src/soc/amd/turin_poc/Makefile.mk b/src/soc/amd/turin_poc/Makefile.mk index 68144574c2..5cbcbea405 100644 --- a/src/soc/amd/turin_poc/Makefile.mk +++ b/src/soc/amd/turin_poc/Makefile.mk @@ -8,6 +8,9 @@ all-y += i2c.c all-y += i3c.c all-y += uart.c +all-y += lpc.c +smm-y += lpc.c + bootblock-y += early_fch.c bootblock-y += aoac.c diff --git a/src/soc/amd/turin_poc/lpc.c b/src/soc/amd/turin_poc/lpc.c new file mode 100644 index 0000000000..23a32f5de3 --- /dev/null +++ b/src/soc/amd/turin_poc/lpc.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void soc_lpc_tpm_decode_spi(void) +{ + /* SoC-specific SPI TPM setting */ + pci_or_config32(SOC_LPC_DEV, 0xdc, 1); +} From 6de3d04c4e57e5ffc49d6e9a37366adc4e3e7af2 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Sat, 28 Feb 2026 17:16:16 +0530 Subject: [PATCH 681/789] Kconfig: Add Kconfig for signed secure blobs Adds QC_SECURE_BOOT_BLOBS to enable inclusion of OEM-signed components for fused Qualcomm hardware. Depends on USE_QC_BLOBS. BUG=b:488573654 TEST=Able to build google/quenbih. Change-Id: Id08d83fc82c9441560b1afaa333b3b7fd5a9bfca Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91475 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/Kconfig | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Kconfig b/src/Kconfig index 2dad082a08..dfd703630c 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -360,6 +360,25 @@ config USE_QC_BLOBS mainboards cannot be built and will be hidden from the "Mainboards" section. +config QC_SECURE_BOOT_BLOBS + bool "Enable Qualcomm secure/signed blobs for fused SoCs" + depends on USE_QC_BLOBS + help + This option enables the inclusion of OEM-signed binaries and + secure-world components required for booting fused Qualcomm SoCs. + + When enabled, the build system will look for signed versions of + QcLib, QC-SEC, and secondary bootloader stages that match the + Root of Trust (RoT) fused into the SoC. + + Select this if you are building firmware for production hardware + or "fused" development units that enforce OEM signature + verification at the hardware level. + + Note: Using this option without the correct signing keys or + signed blobs will result in a bricked boot process on fused + hardware. + config COVERAGE bool "Code coverage support" depends on COMPILER_GCC From 125d9c8643928e924e3cc890d96350743aff4b6b Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Sat, 28 Feb 2026 17:17:39 +0530 Subject: [PATCH 682/789] soc/qualcomm/x1p42100: Add logic for secure boot blob paths Differentiate between secure and non-secure X1P42100 blobs in the Makefile. Uses CONFIG_QC_SECURE_BOOT_BLOBS to select the appropriate binary directory `BLOB_VARIANT`. BUG=b:488573654 TEST=Able to build google/quenbih. Change-Id: I149960b8b6b1f823df78acccfbd0ff9d3f9124e0 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91476 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/soc/qualcomm/x1p42100/Makefile.mk | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/soc/qualcomm/x1p42100/Makefile.mk b/src/soc/qualcomm/x1p42100/Makefile.mk index 2881e90350..68eff9a46b 100644 --- a/src/soc/qualcomm/x1p42100/Makefile.mk +++ b/src/soc/qualcomm/x1p42100/Makefile.mk @@ -67,9 +67,14 @@ CPPFLAGS_common += -Isrc/soc/qualcomm/common/include # look for QC blobs if QC SoC blobs are only available in upstream else ignore ifeq ($(CONFIG_QC_BLOBS_UPSTREAM),y) ifeq ($(CONFIG_USE_QC_BLOBS),y) -# TODO: Upload X1P42100 SoC blobs X1P42100_BLOB := $(top)/3rdparty/qc_blobs/x1p42100 +ifeq ($(CONFIG_QC_SECURE_BOOT_BLOBS),y) +BLOB_VARIANT := secure +else +BLOB_VARIANT := non_secure +endif + ifeq ($(CONFIG_SOC_QUALCOMM_HAMOA),y) DTB_DCB_BLOB_PATH := hamoa else @@ -94,9 +99,9 @@ cbfs-files-y += $(QCSDI_CBFS) endif ################################################################################ -QC_SEC_FILE := $(X1P42100_BLOB)/qc_sec/qc_sec.mbn -TME_SEQ_FILE := $(X1P42100_BLOB)/tme/sequencer_ram.elf -TME_FW_FILE := $(X1P42100_BLOB)/tme/signed_firmware_soc_view.elf +QC_SEC_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/qc_sec/qc_sec.mbn +TME_SEQ_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/tme/sequencer_ram.elf +TME_FW_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/tme/signed_firmware_soc_view.elf $(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw.elf @util/qualcomm/createxbl.py --mbn_version 7 -f $(objcbfs)/bootblock.raw.elf \ @@ -165,7 +170,7 @@ $(I2C_FW_CBFS)-compression := none cbfs-files-y += $(I2C_FW_CBFS) ################################################################################ -AOP_FILE := $(X1P42100_BLOB)/aop/aop.mbn +AOP_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/aop/aop.mbn AOP_CBFS := $(CONFIG_CBFS_PREFIX)/aop $(AOP_CBFS)-file := $(AOP_FILE) $(AOP_CBFS)-type := payload @@ -175,7 +180,7 @@ cbfs-files-y += $(AOP_CBFS) ################################################################################ # Rule to create aop_meta from aop.mbn # This rule depends on aop.mbn built and the extractor script existing. -$(obj)/mainboard/$(MAINBOARDDIR)/aop_meta: $(X1P42100_BLOB)/aop/aop.mbn util/qualcomm/elf_segment_extractor.py +$(obj)/mainboard/$(MAINBOARDDIR)/aop_meta: $(X1P42100_BLOB)/$(BLOB_VARIANT)/aop/aop.mbn util/qualcomm/elf_segment_extractor.py @echo "Extracting ELF headers and hash table segment from $< to $@" @util/qualcomm/elf_segment_extractor.py --eh --pht --hashtable $< $@ @@ -187,7 +192,7 @@ $(AOP_META_CBFS)-compression := $(CBFS_COMPRESS_FLAG) cbfs-files-y += $(AOP_META_CBFS) ################################################################################ -AOP_CFG_FILE := $(X1P42100_BLOB)/aop/aop_devcfg.mbn +AOP_CFG_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/aop/aop_devcfg.mbn AOP_CFG_CBFS := $(CONFIG_CBFS_PREFIX)/aop_cfg $(AOP_CFG_CBFS)-file := $(AOP_CFG_FILE) $(AOP_CFG_CBFS)-type := payload @@ -197,7 +202,7 @@ cbfs-files-y += $(AOP_CFG_CBFS) ################################################################################ # Rule to create aop_meta from aop_devcfg.mbn # This rule depends on aop_devcfg.mbn built and the extractor script existing. -$(obj)/mainboard/$(MAINBOARDDIR)/aop_devcfg_meta: $(X1P42100_BLOB)/aop/aop_devcfg.mbn util/qualcomm/elf_segment_extractor.py +$(obj)/mainboard/$(MAINBOARDDIR)/aop_devcfg_meta: $(X1P42100_BLOB)/$(BLOB_VARIANT)/aop/aop_devcfg.mbn util/qualcomm/elf_segment_extractor.py @echo "Extracting ELF headers and hash table segment from $< to $@" @util/qualcomm/elf_segment_extractor.py --eh --pht --hashtable $< $@ @@ -239,7 +244,7 @@ $(CPUCP_DTBS_CBFS)-compression := $(CBFS_COMPRESS_FLAG) cbfs-files-y += $(CPUCP_DTBS_CBFS) ################################################################################ -SHRM_FILE := $(X1P42100_BLOB)/shrm/shrm.elf +SHRM_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/shrm/shrm.elf SHRM_CBFS := $(CONFIG_CBFS_PREFIX)/shrm $(SHRM_CBFS)-file := $(SHRM_FILE) $(SHRM_CBFS)-type := payload @@ -249,7 +254,7 @@ cbfs-files-y += $(SHRM_CBFS) ################################################################################ # Rule to create shrm_meta from shrm.elf # This rule depends on shrm.elf being built and the extractor script existing. -$(obj)/mainboard/$(MAINBOARDDIR)/shrm_meta: $(X1P42100_BLOB)/shrm/shrm.elf util/qualcomm/elf_segment_extractor.py +$(obj)/mainboard/$(MAINBOARDDIR)/shrm_meta: $(X1P42100_BLOB)/$(BLOB_VARIANT)/shrm/shrm.elf util/qualcomm/elf_segment_extractor.py @echo "Extracting ELF headers and hash table segment from $< to $@" @util/qualcomm/elf_segment_extractor.py --eh --pht --hashtable $< $@ From a1dd5f05b0b17a0c09da936ea1613088f756d476 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Sun, 1 Mar 2026 11:03:09 +0530 Subject: [PATCH 683/789] ec/google/chromeec: Add interface for offmode heartbeat command Implement google_chromeec_offmode_heartbeat() to wrap the EC_CMD_ENABLE_OFFMODE_HEARTBEAT host command. This allows the AP to signal the EC to maintain the power state required for off-mode UI (such as the charging applet) during shutdown or low-power transitions. BUG=b:439819922 BRANCH=none TEST=Build and verify that the charger applet can successfully call this function to enable heartbeat signaling. Change-Id: Ic2ed464bf454e614a098ee5bbbb662adc9d79144 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91484 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) Reviewed-by: Caveh Jalali --- src/ec/google/chromeec/ec.c | 9 +++++++++ src/ec/google/chromeec/ec.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index ab4df3dde2..5b89dac265 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -795,6 +795,15 @@ int rtc_get(struct rtc_time *time) } #endif +int google_chromeec_offmode_heartbeat(void) +{ + struct chromeec_command cmd = { + .cmd_code = EC_CMD_ENABLE_OFFMODE_HEARTBEAT, + }; + + return google_chromeec_command(&cmd); +} + int google_chromeec_reboot(enum ec_reboot_cmd type, uint8_t flags) { const struct ec_params_reboot_ec params = { diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index 73ec3eeda8..aadd51ff22 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -110,6 +110,8 @@ int google_chromeec_reboot(enum ec_reboot_cmd type, uint8_t flags); void google_chromeec_ap_poweroff(void); +int google_chromeec_offmode_heartbeat(void); + /** * Get data from Cros Board Info * From 12710eafff6612a71c5efa9bed0a67e04d7137df Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Sun, 1 Mar 2026 11:04:34 +0530 Subject: [PATCH 684/789] mb/google/bluey: Implement off-mode charging applet Add launch_charger_applet() to handle the system state when booting in off-mode charging or low-power modes with a charger present. Key features: 1. Monitoring: Periodically checks battery current (I-current) via SPMI/PMIC registers. 2. Event Handling: Detects and clears EC power button and lid events. If a manual power-on event is detected, the system triggers a full board reset to ensure a clean boot to the OS (preventing firmware state conflicts like ADSP-lite vs ADSP). 3. Shutdown: If the charger is removed, it signals the EC via off-mode heartbeat and initiates an AP power-off. BUG=b:439819922 BRANCH=None TEST=Verified that the device enters the charging loop when plugged in while off, and transitions to a full boot when the power button is pressed. Change-Id: I152f71eac89f5b522ea7b286517724e213c31e9a Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91485 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/board.h | 4 ++ src/mainboard/google/bluey/charging.c | 94 ++++++++++++++++++++++++-- src/mainboard/google/bluey/mainboard.c | 14 ++-- 3 files changed, 100 insertions(+), 12 deletions(-) diff --git a/src/mainboard/google/bluey/board.h b/src/mainboard/google/bluey/board.h index d5218b469b..98e34fc64b 100644 --- a/src/mainboard/google/bluey/board.h +++ b/src/mainboard/google/bluey/board.h @@ -35,6 +35,9 @@ #define GPIO_PANEL_POWER_ON GPIO(70) #define GPIO_PANEL_HPD GPIO(119) +/* Charging GPIOs */ +#define GPIO_PARALLEL_CHARGING_CFG GPIO(71) + /* SD card specific GPIOs. Only for SD-enabled devices. */ #if CONFIG(MAINBOARD_HAS_SD_CONTROLLER) #define GPIO_SD_CD_L GPIO(71) @@ -56,5 +59,6 @@ void configure_parallel_charging(void); void configure_parallel_charging_late(void); void enable_slow_battery_charging(void); void disable_slow_battery_charging(void); +void launch_charger_applet(void); #endif /* MAINBOARD_GOOGLE_BLUEY_BOARD_H */ diff --git a/src/mainboard/google/bluey/charging.c b/src/mainboard/google/bluey/charging.c index 5252a1e531..f1af963ec2 100644 --- a/src/mainboard/google/bluey/charging.c +++ b/src/mainboard/google/bluey/charging.c @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include "board.h" + +#include +#include +#include #include #include #include @@ -16,16 +20,14 @@ #define SMB2_CHGR_CHRG_EN_CMD ((SMB2_SLAVE_ID << 16) | SCHG_CHGR_CHARGING_ENABLE_CMD) #define SMB1_SCHG_TYPE_C_TYPE_C_DEBUG_ACCESS_SNK_CFG \ ((SMB1_SLAVE_ID << 16) | SCHG_TYPE_C_TYPE_C_DEBUG_ACCESS_SNK_CFG) +#define SCHG_CHGR_CHARGING_FCC 0x260A +#define SMB1_CHGR_CHARGING_FCC ((SMB1_SLAVE_ID << 16) | SCHG_CHGR_CHARGING_FCC) +#define SMB2_CHGR_CHARGING_FCC ((SMB2_SLAVE_ID << 16) | SCHG_CHGR_CHARGING_FCC) #define FCC_1A_STEP_50MA 0x14 #define FCC_DISABLE 0x8c #define EN_DEBUG_ACCESS_SNK 0x1B -enum charging_status { - CHRG_DISABLE, - CHRG_ENABLE, -}; - #define PMC8380F_SLAVE_ID 0x05 #define GPIO07_MODE_CTL 0x8E40 #define GPIO07_DIG_OUT_SOURCE_CTL 0x8E44 @@ -38,7 +40,87 @@ enum charging_status { #define OUTPUT_INVERT 0x80 #define PERPH_EN 0x80 -#define GPIO_PARALLEL_CHARGING_CFG GPIO(71) +#define DELAY_CHARGING_APPLET_MS 2000 /* 2sec */ + +enum charging_status { + CHRG_DISABLE, + CHRG_ENABLE, +}; + +static int get_battery_icurr_ma(void) +{ + /* Read battery i-current value */ + int icurr = spmi_read8(SMB1_CHGR_CHARGING_FCC); + if (icurr <= 0) + icurr = spmi_read8(SMB2_CHGR_CHARGING_FCC); + if (icurr < 0) + icurr = 0; + + icurr *= 50; + return icurr; +} + +static void clear_ec_manual_poweron_event(void) +{ + const uint64_t manual_pwron_event_mask = + (EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON) | + EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)); + google_chromeec_clear_events_b(manual_pwron_event_mask); +} + +static int detect_ec_manual_poweron_event(void) +{ + const uint64_t manual_pwron_event_mask = + (EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON) | + EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)); + uint64_t events = google_chromeec_get_events_b(); + + if (!!(events & manual_pwron_event_mask)) + return 1; + + return 0; +} + +void launch_charger_applet(void) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC)) + return; + + printk(BIOS_INFO, "Inside %s. Initiating charging\n", __func__); + + /* clear any pending power button press and lid open event */ + clear_ec_manual_poweron_event(); + + do { + /* Add static delay before reading the charging applet pre-requisites */ + mdelay(DELAY_CHARGING_APPLET_MS); + + /* + * Issue a shutdown if not charging. + */ + if (!get_battery_icurr_ma()) { + printk(BIOS_INFO, "Issuing power-off due to change in charging state.\n"); + google_chromeec_offmode_heartbeat(); + google_chromeec_ap_poweroff(); + } + + /* + * Exit the charging loop in the event of lid open or power + * button press. + * + * Reset the device to ensure a fresh boot to OS. + * This is required to avoid any kind of tear-down due to ADSP-lite + * being loaded and need some clean up before loading ADSP firmware by + * linux kernel. + */ + if (detect_ec_manual_poweron_event()) { + printk(BIOS_INFO, "Exiting charging applet to boot to OS\n"); + do_board_reset(); + } + + /* TODO: add Tsense support and issue a shutdown in the event of temperature trip */ + } while (true); +} /* * Enable PMC8380F GPIO07 & GPIO09 for parallel charging. diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 2fc8cfdde9..30cf5b13d8 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -121,12 +121,6 @@ void lb_add_boot_mode(struct lb_header *header) mode->tag = LB_TAG_BOOT_MODE; mode->size = sizeof(*mode); mode->boot_mode = get_boot_mode(); - - configure_parallel_charging_late(); - - /* Enable charging only during off-mode or low-battery mode with charger present */ - if (is_low_power_boot_with_charger()) - enable_slow_battery_charging(); } bool mainboard_needs_pcie_init(void) @@ -177,14 +171,22 @@ static void mainboard_init(struct device *dev) if (get_boot_mode() == LB_BOOT_MODE_LOW_BATTERY) trigger_critical_battery_shutdown(); + configure_parallel_charging_late(); + /* Skip mainboard initialization if boot mode is "low-battery" or "off-mode charging" */ if (is_low_power_boot_with_charger()) { + /* TODO: enable fast charging */ + enable_slow_battery_charging(); + /* Disable the lightbar for Low-Battery or Off-Mode charging sequences. * This maintains visual consistency between the built-in display * indicators and the external lightbar. */ if (CONFIG(EC_GOOGLE_CHROMEEC)) google_chromeec_lightbar_off(); + + /* Boot to charging applet */ + launch_charger_applet(); return; } From fe506bfe8494cbfddaa83406deafc4bcc85f600b Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Sat, 28 Feb 2026 19:39:31 +0530 Subject: [PATCH 685/789] ec/google/chromeec: Add Kconfig for AP-controlled LED sync Introduce EC_GOOGLE_CHROMEEC_LED_CONTROL to allow boards to opt-in to manual LED/lightbar synchronization. This ensures that the AP firmware can coordinate the lightbar state with boot animations or specific power states (like critical battery alerts) without forcing the logic on all ChromeEC-based platforms. On Bluey, the lightbar logic is refactored into a helper function `platform_init_lightbar()` to improve readability and is now gated by the new Kconfig. Similar gating is applied to Fatcat's romstage. Summary of changes: - Add EC_GOOGLE_CHROMEEC_LED_CONTROL Kconfig option. - Bluey: Refactor lightbar init into a helper and gate by Kconfig. - Fatcat: Gate early lightbar initialization by Kconfig. Change-Id: I6b0294b73b8b9929a6be0e15bf64f7e688b7da8c Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91477 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/ec/google/chromeec/Kconfig | 6 ++++++ src/mainboard/google/bluey/mainboard.c | 2 +- src/mainboard/google/bluey/romstage.c | 17 ++++++++++++----- src/mainboard/google/fatcat/romstage.c | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/ec/google/chromeec/Kconfig b/src/ec/google/chromeec/Kconfig index b09c64a88c..081f7cb754 100644 --- a/src/ec/google/chromeec/Kconfig +++ b/src/ec/google/chromeec/Kconfig @@ -261,6 +261,12 @@ config EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC which retrieves cached telemetry from the EC rather than triggering a synchronous bus transaction to the battery. +config EC_GOOGLE_CHROMEEC_LED_CONTROL + bool + help + Enable manual AP control over ChromeEC LEDs/lightbars to ensure + visual continuity with AP-side boot animations. + endif # EC_GOOGLE_CHROMEEC source "src/ec/google/chromeec/*/Kconfig" diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 30cf5b13d8..223daf89c8 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -182,7 +182,7 @@ static void mainboard_init(struct device *dev) * This maintains visual consistency between the built-in display * indicators and the external lightbar. */ - if (CONFIG(EC_GOOGLE_CHROMEEC)) + if (CONFIG(EC_GOOGLE_CHROMEEC_LED_CONTROL)) google_chromeec_lightbar_off(); /* Boot to charging applet */ diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index a415228e8b..891809f045 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -124,23 +124,30 @@ static void early_setup_usb(void) early_setup_usb_typec(); } -void platform_romstage_main(void) +static void platform_init_lightbar(void) { + if (!CONFIG(EC_GOOGLE_CHROMEEC_LED_CONTROL)) + return; + /* * Early initialization of the Chrome EC lightbar. * Ensures visual continuity if the AP firmware disabled the lightbar * in a previous boot without a subsequent EC reset. */ - if (CONFIG(EC_GOOGLE_CHROMEEC)) - google_chromeec_lightbar_on(); + google_chromeec_lightbar_on(); /* * Only alert the user (set LED to red in color) if the lid is closed and the battery * is critically low without AC power. */ - if (CONFIG(EC_GOOGLE_CHROMEEC) && CONFIG(VBOOT_LID_SWITCH) && !get_lid_switch() && - google_chromeec_is_critically_low_on_battery()) + if (CONFIG(VBOOT_LID_SWITCH) && !get_lid_switch() && + google_chromeec_is_critically_low_on_battery()) google_chromeec_set_lightbar_rgb(0xff, 0xff, 0x00, 0x00); +} + +void platform_romstage_main(void) +{ + platform_init_lightbar(); /* Setup early USB related config */ early_setup_usb(); diff --git a/src/mainboard/google/fatcat/romstage.c b/src/mainboard/google/fatcat/romstage.c index 5098cd3d8b..04b39c58c4 100644 --- a/src/mainboard/google/fatcat/romstage.c +++ b/src/mainboard/google/fatcat/romstage.c @@ -53,7 +53,7 @@ void platform_romstage_pre_mem(void) * Ensures visual continuity if the AP firmware disabled the lightbar * in a previous boot without a subsequent EC reset. */ - if (CONFIG(EC_GOOGLE_CHROMEEC)) + if (CONFIG(EC_GOOGLE_CHROMEEC_LED_CONTROL)) google_chromeec_lightbar_on(); /* From 270e84e59fee87c0054645c6aab606254147f06c Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Sat, 28 Feb 2026 16:10:48 +0530 Subject: [PATCH 686/789] vc/chromeos: Provide inline fallbacks for Chromebook Plus branding Currently, mainboards that do not support Google TPM must manually define stubs for chromeos_device_branded_plus_hard() and chromeos_device_branded_plus_soft() to satisfy the linker. Move these stubs into vendorcode/google/chromeos/chromeos.h as static inline functions when CONFIG(TPM_GOOGLE) is disabled. This reduces code duplication and allows the removal of redundant stub definitions in the ptlrvp mainboard. Change-Id: If270d4815c687a409fec7058c224f987f9e2741a Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91474 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) --- src/mainboard/intel/ptlrvp/intel.c | 10 ---------- src/vendorcode/google/chromeos/chromeos.h | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/mainboard/intel/ptlrvp/intel.c b/src/mainboard/intel/ptlrvp/intel.c index 600d1b3bb7..5e0358ec86 100644 --- a/src/mainboard/intel/ptlrvp/intel.c +++ b/src/mainboard/intel/ptlrvp/intel.c @@ -23,13 +23,3 @@ int get_recovery_mode_switch(void) { return 0; } - -bool chromeos_device_branded_plus_hard(void) -{ - return false; -} - -bool chromeos_device_branded_plus_soft(void) -{ - return false; -} diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h index 540f3635aa..d8f7e6117c 100644 --- a/src/vendorcode/google/chromeos/chromeos.h +++ b/src/vendorcode/google/chromeos/chromeos.h @@ -34,6 +34,8 @@ void chromeos_set_ramoops(void *ram_oops, size_t size); * Return "UNDEFINED_FACTORY_CONFIG" in case of error. */ uint64_t chromeos_get_factory_config(void); + +#if CONFIG(TPM_GOOGLE) /* * Determines whether a ChromeOS device is branded as a Chromebook-Plus * based on specific bit flags: @@ -57,6 +59,18 @@ bool chromeos_device_branded_plus_hard(void); * To be considered a soft-branded Chromebook-Plus, both of these conditions need to be met. */ bool chromeos_device_branded_plus_soft(void); +#else +/* Inline fallback for platforms without Google TPM */ +static inline bool chromeos_device_branded_plus_hard(void) +{ + return false; +} + +static inline bool chromeos_device_branded_plus_soft(void) +{ + return false; +} +#endif /* * Declaration for mainboards to use to generate ACPI-specific ChromeOS needs. From 10f0a8782433a18d80bc342495f9cad2d744a89f Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 2 Mar 2026 09:46:11 +0530 Subject: [PATCH 687/789] soc/qualcomm/sc7280: Update console message type non-fatal This patch updates console message type non-fatal from BIOS_ERR to BIOS_INFO as appropriate. Change-Id: I7940b5f0457388d6c5786c9cd490078065e953a4 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91501 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/soc/qualcomm/sc7280/display/edp_aux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/qualcomm/sc7280/display/edp_aux.c b/src/soc/qualcomm/sc7280/display/edp_aux.c index 9d330a61d1..0f37c21b47 100644 --- a/src/soc/qualcomm/sc7280/display/edp_aux.c +++ b/src/soc/qualcomm/sc7280/display/edp_aux.c @@ -179,7 +179,7 @@ int edp_read_edid(struct edid *out) } if (edid[EDID_EXTENSION_FLAG]) { - printk(BIOS_ERR, " read EDID ext block.\n"); + printk(BIOS_INFO, " read EDID ext block.\n"); edid_size += EDID_LENGTH; reg_addr = EDID_LENGTH; err = edp_aux_transfer(EDID_I2C_ADDR, DP_AUX_I2C_WRITE, ®_addr, 1); From 2c5840233939e9fc0bf581a295806cca0456a816 Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Mon, 2 Mar 2026 18:53:11 +0530 Subject: [PATCH 688/789] soc/qualcomm/x1p42100: Configure OTG buck for USB host Set the SCHG_DCDC_OTG_CFG register to 0x26 during USB initialization to ensure the OTG buck is correctly configured for host mode. TEST=Verify USB detection in the depthcharge on Google/Quartz. Change-Id: If76be8b7210fc86f473bfd77eb56718f28f19eae Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/91509 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/soc/qualcomm/x1p42100/include/soc/usb/usb.h | 1 + src/soc/qualcomm/x1p42100/usb/usb.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h b/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h index 8284656cb8..f810944542 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h +++ b/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h @@ -114,6 +114,7 @@ #define OTG_STATE_ENABLED 0x02 #define OTG_STATUS_TIMEOUT_MS 20 #define OTG_STATUS_POLL_DELAY_MS 2 +#define OTG_BUCK_CFG 0x26 /* Type-C register offsets */ #define SCHG_TYPE_C_TYPE_C_MISC_STATUS 0x2B0B diff --git a/src/soc/qualcomm/x1p42100/usb/usb.c b/src/soc/qualcomm/x1p42100/usb/usb.c index 5865a35d01..b135b0a0e9 100644 --- a/src/soc/qualcomm/x1p42100/usb/usb.c +++ b/src/soc/qualcomm/x1p42100/usb/usb.c @@ -495,6 +495,15 @@ static bool get_usb_typec_polarity(const struct dwc3_controller_config *config) return (misc_status & CCOUT_INVERT_POLARITY) == CCOUT_INVERT_POLARITY; } +/* + * Configures OTG buck for host mode + * @config: Controller configuration containing SMB slave address + */ +static void usb_configure_otg_buck(const struct dwc3_controller_config *config) +{ + spmi_write8(SPMI_ADDR(config->smb_slave_addr, SCHG_DCDC_OTG_CFG), OTG_BUCK_CFG); +} + /* Initialization of DWC3 Core and PHY */ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) { @@ -587,6 +596,8 @@ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) printk(BIOS_ERR, "SS0 QMP PHY initialization failed\n"); high_speed_only_primary = true; } + /* Configure OTG buck */ + usb_configure_otg_buck(&prim_config); /* Enable VBUS for C0 */ enable_vbus_ss(&prim_config); udelay(50); @@ -618,6 +629,8 @@ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) printk(BIOS_ERR, "SS1 QMP PHY initialization failed\n"); high_speed_only_secondary = true; } + /* Configure OTG buck */ + usb_configure_otg_buck(&sec_config); /* Enable VBUS for C1 */ enable_vbus_ss(&sec_config); udelay(50); From c222118cbf0507eed08e5a911b5531bed877998a Mon Sep 17 00:00:00 2001 From: Kapil Porwal Date: Mon, 2 Mar 2026 12:10:51 +0530 Subject: [PATCH 689/789] soc/qualcomm/x1p42100: Remove redundant VBUS enablement logic The current VBUS enablement logic was found to be unnecessary for USB host functionality on x1p42100. Forcing VBUS power via the PMIC's OTG buck is not required for the current hardware configuration and could lead to incorrect power state management. Remove the enable_vbus_ss() function and associated SCHG DCDC register definitions from the SoC driver. This streamlines the USB initialization path to focus solely on PHY and controller setup. TEST=Verify USB detection in the depthcharge on Google/Quartz. Change-Id: Ie30878802831419f3d70ea921f7f46a262db99bb Signed-off-by: Kapil Porwal Reviewed-on: https://review.coreboot.org/c/coreboot/+/91502 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- .../qualcomm/x1p42100/include/soc/usb/usb.h | 14 ----- src/soc/qualcomm/x1p42100/usb/usb.c | 52 ------------------- 2 files changed, 66 deletions(-) diff --git a/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h b/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h index f810944542..b6d1ff50dd 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h +++ b/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h @@ -103,25 +103,13 @@ #define SMB2_SLAVE_ID 0x0A /* SCHG DCDC register offsets */ -#define SCHG_DCDC_CMD_OTG 0x2740 #define SCHG_DCDC_OTG_CFG 0x2753 -#define SCHG_DCDC_OTG_STATUS 0x270D -#define SCHG_DCDC_ENG_SDCDC_CFG7 0x27C7 -#define SCHG_DCDC_ENG_SDCDC_GM_CLOOP_PD_OTG_BUCK_MASK 0x30 - -/* OTG Status register bit definitions */ -#define OTG_STATE_MASK 0x07 -#define OTG_STATE_ENABLED 0x02 -#define OTG_STATUS_TIMEOUT_MS 20 -#define OTG_STATUS_POLL_DELAY_MS 2 #define OTG_BUCK_CFG 0x26 /* Type-C register offsets */ #define SCHG_TYPE_C_TYPE_C_MISC_STATUS 0x2B0B #define SCHG_TYPE_C_TYPE_C_SRC_STATUS 0x2B08 #define SCHG_TYPE_C_TYPE_C_MODE_CFG 0x2B44 -#define TYPEC_VBUS_STATUS_MASK BIT(5) -#define TYPEC_SNK_SRC_MODE BIT(6) #define CCOUT_INVERT_POLARITY 0x03 /* USB Repeater SPMI Tune register offsets */ @@ -152,8 +140,6 @@ int qcom_enable_usb_clk(void); void enable_clock_tcsr(void); /* Enable TCSR CLKREF */ void usb_update_refclk_for_core(u32 core_num, bool enable); -/* Enables VBUS SuperSpeed for specified USB core */ -void enable_vbus_ss(const struct dwc3_controller_config *config); /* Reads comprehensive Type-C status from PMIC */ void usb_typec_status_check(const struct dwc3_controller_config *config); /* Performs mainboard-specific USB Type-C configuration */ diff --git a/src/soc/qualcomm/x1p42100/usb/usb.c b/src/soc/qualcomm/x1p42100/usb/usb.c index b135b0a0e9..afc44e6a5f 100644 --- a/src/soc/qualcomm/x1p42100/usb/usb.c +++ b/src/soc/qualcomm/x1p42100/usb/usb.c @@ -598,9 +598,6 @@ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) } /* Configure OTG buck */ usb_configure_otg_buck(&prim_config); - /* Enable VBUS for C0 */ - enable_vbus_ss(&prim_config); - udelay(50); usb_typec_status_check(&prim_config); mainboard_usb_typec_configure(0, polarity_prim); @@ -631,9 +628,6 @@ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) } /* Configure OTG buck */ usb_configure_otg_buck(&sec_config); - /* Enable VBUS for C1 */ - enable_vbus_ss(&sec_config); - udelay(50); usb_typec_status_check(&sec_config); mainboard_usb_typec_configure(1, polarity_sec); @@ -685,52 +679,6 @@ void usb_update_refclk_for_core(u32 core_num, bool enable) } } -/* - * enable_vbus_ss - Enables VBUS SuperSpeed for specified USB core - * @config: Controller configuration containing SMB slave address - */ -void enable_vbus_ss(const struct dwc3_controller_config *config) -{ - u8 slave = config->smb_slave_addr; - u8 misc_status, otg_status = 0, otg_state = 0; - struct stopwatch sw; - - printk(BIOS_INFO, "Enabling %s VBUS SuperSpeed\n", config->name); - - /* Configure SDCDC CFG7 register before enabling OTG */ - spmi_write8(SPMI_ADDR(slave, SCHG_DCDC_ENG_SDCDC_CFG7), - SCHG_DCDC_ENG_SDCDC_GM_CLOOP_PD_OTG_BUCK_MASK); - - spmi_write8(SPMI_ADDR(slave, SCHG_DCDC_OTG_CFG), 0x20); - spmi_write8(SPMI_ADDR(slave, SCHG_DCDC_CMD_OTG), 0x1); - - /* Check Type-C mode */ - misc_status = spmi_read8(SPMI_ADDR(slave, SCHG_TYPE_C_TYPE_C_MISC_STATUS)); - - /* Check SNK_SRC_MODE bit (bit 6): 0 = SNK, 1 = SRC */ - if (misc_status & TYPEC_SNK_SRC_MODE) { - /* In SRC mode, poll OTG status until enabled */ - stopwatch_init_msecs_expire(&sw, OTG_STATUS_TIMEOUT_MS); - while (!stopwatch_expired(&sw)) { - otg_status = spmi_read8(SPMI_ADDR(slave, SCHG_DCDC_OTG_STATUS)); - otg_state = otg_status & OTG_STATE_MASK; - - if (otg_state == OTG_STATE_ENABLED) { - printk(BIOS_INFO, "%s in SRC mode - OTG Status: 0x%02x, State: 0x%02x (OTG Enabled)\n", - config->name, otg_status, otg_state); - return; - } - mdelay(OTG_STATUS_POLL_DELAY_MS); - } - - /* Timeout - log final state */ - printk(BIOS_INFO, "%s in SRC mode - OTG Status: 0x%02x, State: 0x%02x - Timeout after %d ms\n", - config->name, otg_status, otg_state, OTG_STATUS_TIMEOUT_MS); - } else { - printk(BIOS_INFO, "%s in SNK mode - skipping OTG status read\n", config->name); - } -} - /* * usb_typec_status_check - Reads comprehensive Type-C status from PMIC * @config: Controller configuration containing SMB slave address From ca9b46d341daa59109f327b32029d57f44abb02e Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Wed, 25 Feb 2026 19:00:41 +0800 Subject: [PATCH 690/789] soc/mediatek: Add common low battery poweroff handling Add a common low battery poweroff implementation in soc/mediatek/common/low_battery.c. This implementation checks if a low battery shutdown is needed and triggers a poweroff via Chrome EC if necessary. Also enable this for mt8196 in ramstage. BUG=b:424707341 TEST=The FW draws low battery indicator and powers off the DUT after 5 seconds. TEST=Use `elogtool list` and see `Low Battery boot | Power Off` Change-Id: I2fcd242fbf26bdebc4acfb477c95c381adf645f5 Signed-off-by: Yidi Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/91431 Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik Reviewed-by: Chen-Tsung Hsieh --- src/soc/mediatek/common/low_battery.c | 28 +++++++++++++++++++++++++++ src/soc/mediatek/mt8196/Makefile.mk | 1 + 2 files changed, 29 insertions(+) create mode 100644 src/soc/mediatek/common/low_battery.c diff --git a/src/soc/mediatek/common/low_battery.c b/src/soc/mediatek/common/low_battery.c new file mode 100644 index 0000000000..7a00341d8e --- /dev/null +++ b/src/soc/mediatek/common/low_battery.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +void __weak poweroff(void) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC)) + return; + google_chromeec_ap_poweroff(); +} + +static void low_battery_poweroff(void *unused) +{ + if (!platform_is_low_battery_shutdown_needed()) + return; + + printk(BIOS_INFO, "%s: powering off...\n", __func__); + + platform_handle_emergency_low_battery(); + poweroff(); +} + +BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, low_battery_poweroff, NULL); diff --git a/src/soc/mediatek/mt8196/Makefile.mk b/src/soc/mediatek/mt8196/Makefile.mk index 47f9592bc8..1a6159079e 100644 --- a/src/soc/mediatek/mt8196/Makefile.mk +++ b/src/soc/mediatek/mt8196/Makefile.mk @@ -69,6 +69,7 @@ ramstage-y += ../common/early_init.c ramstage-y += ../common/emi.c ramstage-y += gpueb.c ramstage-y += l2c_ops.c +ramstage-y += ../common/low_battery.c ramstage-y += ../common/mcu.c mcupm.c ramstage-y += ../common/mmu_operations.c ramstage-y += ../common/mtk_mipi_dphy.c mtk_mipi_dphy.c From fb2e8b5e1e5b5ed1c9926f4304009f207bb51cbc Mon Sep 17 00:00:00 2001 From: Jayvik Desai Date: Mon, 2 Mar 2026 14:42:04 +0530 Subject: [PATCH 691/789] mainboard/google/bluey: Enable charging debug access in common path The charging debug access port was previously only configured during slow battery charging. Move this configuration into a dedicated function, configure_charging_debug_access(), and call it within the common mainboard_init() path. This ensures the debug access port is consistently configured during mainboard initialization, following the same pattern as parallel charging. BUG=b:488143407 TEST=Build Bluey/Quartz Change-Id: Idacffd61834e0700619b240dfe362f3be90badb9 Signed-off-by: Jayvik Desai Reviewed-on: https://review.coreboot.org/c/coreboot/+/91505 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/board.h | 1 + src/mainboard/google/bluey/charging.c | 15 ++++++++++++--- src/mainboard/google/bluey/mainboard.c | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/mainboard/google/bluey/board.h b/src/mainboard/google/bluey/board.h index 98e34fc64b..0544381e69 100644 --- a/src/mainboard/google/bluey/board.h +++ b/src/mainboard/google/bluey/board.h @@ -57,6 +57,7 @@ void setup_chromeos_gpios(void); bool is_off_mode(void); void configure_parallel_charging(void); void configure_parallel_charging_late(void); +void configure_charging_debug_access(void); void enable_slow_battery_charging(void); void disable_slow_battery_charging(void); void launch_charger_applet(void); diff --git a/src/mainboard/google/bluey/charging.c b/src/mainboard/google/bluey/charging.c index f1af963ec2..690f30964f 100644 --- a/src/mainboard/google/bluey/charging.c +++ b/src/mainboard/google/bluey/charging.c @@ -139,6 +139,18 @@ void configure_parallel_charging(void) spmi_write8(SPMI_ADDR(PMC8380F_SLAVE_ID, GPIO09_MODE_CTL), MODE_OUTPUT); } +/* + * Enable SMB1 charging debug access port. + */ +void configure_charging_debug_access(void) +{ + if (!CONFIG(HAVE_CHARGING_DEBUG_ACCESS_PORT)) + return; + + printk(BIOS_INFO, "Enable charging debug access port support\n"); + spmi_write8(SMB1_SCHG_TYPE_C_TYPE_C_DEBUG_ACCESS_SNK_CFG, EN_DEBUG_ACCESS_SNK); +} + /* * Late configuration for parallel charging. */ @@ -161,9 +173,6 @@ void enable_slow_battery_charging(void) spmi_write8(SMB2_CHGR_MAX_FCC_CFG, FCC_1A_STEP_50MA); spmi_write8(SMB1_CHGR_CHRG_EN_CMD, CHRG_ENABLE); spmi_write8(SMB2_CHGR_CHRG_EN_CMD, CHRG_ENABLE); - - if (CONFIG(HAVE_CHARGING_DEBUG_ACCESS_PORT)) - spmi_write8(SMB1_SCHG_TYPE_C_TYPE_C_DEBUG_ACCESS_SNK_CFG, EN_DEBUG_ACCESS_SNK); } /* diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 223daf89c8..64212d0e84 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -161,6 +161,7 @@ static void trigger_critical_battery_shutdown(void) static void mainboard_init(struct device *dev) { configure_parallel_charging(); + configure_charging_debug_access(); display_startup(); From ba6de6c866e714c304aa3e514f90799ebabf38b3 Mon Sep 17 00:00:00 2001 From: Luca Lai Date: Thu, 26 Feb 2026 10:32:13 +0800 Subject: [PATCH 692/789] mb/google/fatcat/var/ruby: Set ISH GP1 gpio pin to NC Because GPP_B05 is not required for EC or ISH interrupts, it should be set to NC in coreboot to minimize power impact. BUG=b:475879711 TEST=Build and boot to OS. Change-Id: Ic56e16ca89968c8e2204d1609812f1d8d3548512 Signed-off-by: Luca Lai Reviewed-on: https://review.coreboot.org/c/coreboot/+/91427 Tested-by: build bot (Jenkins) Reviewed-by: Derek Huang Reviewed-by: Subrata Banik --- src/mainboard/google/fatcat/variants/ruby/gpio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/fatcat/variants/ruby/gpio.c b/src/mainboard/google/fatcat/variants/ruby/gpio.c index 215bf9c61a..9c80074255 100644 --- a/src/mainboard/google/fatcat/variants/ruby/gpio.c +++ b/src/mainboard/google/fatcat/variants/ruby/gpio.c @@ -55,7 +55,8 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_B02, NONE), /* GPP_B03: NC */ PAD_NC(GPP_B03, NONE), - + /* GPP_B05: NONE */ + PAD_NC(GPP_B05, NONE), /* GPP_B06: NC */ PAD_NC(GPP_B06, NONE), /* GPP_B07: NC */ From 08e3ad9e030c492c5a3cc318121a3a7b6f2b9668 Mon Sep 17 00:00:00 2001 From: David Wu Date: Mon, 2 Mar 2026 16:12:12 +0800 Subject: [PATCH 693/789] mb/google/brox/var/juchi: Add 2 memory parts and generate DRAM IDs Add two new memory parts 1. Mircon MT62F1G32D2DS-023 WT:C 2. Samsung K3KL8L80DM-MGCU BUG=b:481602501 TEST=Run part_id_gen tool and check the generated files. Change-Id: Ibce661a09f8ad7daec8582508d775e0d7ac4e51f Signed-off-by: David Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/91504 Reviewed-by: Paul Menzel Reviewed-by: Eric Lai Tested-by: build bot (Jenkins) Reviewed-by: Karthik Ramasubramanian --- src/mainboard/google/brox/variants/juchi/memory/Makefile.mk | 2 +- .../google/brox/variants/juchi/memory/dram_id.generated.txt | 2 ++ .../google/brox/variants/juchi/memory/mem_parts_used.txt | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/brox/variants/juchi/memory/Makefile.mk b/src/mainboard/google/brox/variants/juchi/memory/Makefile.mk index bcb5920648..56f44e554b 100644 --- a/src/mainboard/google/brox/variants/juchi/memory/Makefile.mk +++ b/src/mainboard/google/brox/variants/juchi/memory/Makefile.mk @@ -6,5 +6,5 @@ SPD_SOURCES = SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 0(0b0000) Parts = MT62F512M32D2DR-031 WT:B, H9JCNNNBK3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 1(0b0001) Parts = MT62F1G32D4DR-031 WT:B -SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 2(0b0010) Parts = MT62F1G32D2DS-023 WT:B, H58G56BK8BX068, H58G56CK8BX146 +SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 2(0b0010) Parts = MT62F1G32D2DS-023 WT:B, H58G56BK8BX068, H58G56CK8BX146, MT62F1G32D2DS-023 WT:C, K3KL8L80DM-MGCU SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = K3KL8L80CM-MGCT diff --git a/src/mainboard/google/brox/variants/juchi/memory/dram_id.generated.txt b/src/mainboard/google/brox/variants/juchi/memory/dram_id.generated.txt index 2acaeaed86..0420329929 100644 --- a/src/mainboard/google/brox/variants/juchi/memory/dram_id.generated.txt +++ b/src/mainboard/google/brox/variants/juchi/memory/dram_id.generated.txt @@ -11,3 +11,5 @@ MT62F1G32D2DS-023 WT:B 2 (0010) H58G56BK8BX068 2 (0010) K3KL8L80CM-MGCT 3 (0011) H58G56CK8BX146 2 (0010) +MT62F1G32D2DS-023 WT:C 2 (0010) +K3KL8L80DM-MGCU 2 (0010) diff --git a/src/mainboard/google/brox/variants/juchi/memory/mem_parts_used.txt b/src/mainboard/google/brox/variants/juchi/memory/mem_parts_used.txt index a1a7a9932f..23f29e450a 100644 --- a/src/mainboard/google/brox/variants/juchi/memory/mem_parts_used.txt +++ b/src/mainboard/google/brox/variants/juchi/memory/mem_parts_used.txt @@ -5,3 +5,5 @@ MT62F1G32D2DS-023 WT:B H58G56BK8BX068 K3KL8L80CM-MGCT H58G56CK8BX146 +MT62F1G32D2DS-023 WT:C +K3KL8L80DM-MGCU From ea1a722d2b00bf9ba7fec23208fd43b8924138f9 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 24 Jan 2026 09:56:08 +0100 Subject: [PATCH 694/789] soc/intel/xeon_sp: Move microcode loading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move loading of microcode to pre_mp_init() as found on other Intel CPU drivers. There’s no need to cache the microcode location since intel_microcode_find() already caches it. No function change, thus untested. Change-Id: I05bbb074d189594027916c6a3b04270bd3b6edd1 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/90892 Reviewed-by: Jérémy Compostella Reviewed-by: Sean Rhodes Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/soc/intel/xeon_sp/cpx/cpu.c | 12 +++--------- src/soc/intel/xeon_sp/gnr/cpu.c | 8 +++----- src/soc/intel/xeon_sp/skx/cpu.c | 10 +++------- src/soc/intel/xeon_sp/spr/cpu.c | 8 +++----- 4 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/soc/intel/xeon_sp/cpx/cpu.c b/src/soc/intel/xeon_sp/cpx/cpu.c index 5df399a61b..c6375ecfdb 100644 --- a/src/soc/intel/xeon_sp/cpx/cpu.c +++ b/src/soc/intel/xeon_sp/cpx/cpu.c @@ -25,8 +25,6 @@ #include "chip.h" -static const void *microcode_patch; - static const config_t *chip_config = NULL; bool cpu_soc_is_in_untrusted_mode(void) @@ -167,6 +165,9 @@ static void set_max_turbo_freq(void) */ static void pre_mp_init(void) { + const void *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + x86_setup_mtrrs_with_detect(); x86_mtrr_check(); } @@ -195,13 +196,6 @@ static const struct mp_ops mp_ops = { void mp_init_cpus(struct bus *bus) { - microcode_patch = intel_microcode_find(); - - if (!microcode_patch) - printk(BIOS_ERR, "microcode not found in CBFS!\n"); - - intel_microcode_load_unlocked(microcode_patch); - /* TODO: Handle mp_init_with_smm failure? */ mp_init_with_smm(bus, &mp_ops); diff --git a/src/soc/intel/xeon_sp/gnr/cpu.c b/src/soc/intel/xeon_sp/gnr/cpu.c index 44f466d2e5..2e645a53d7 100644 --- a/src/soc/intel/xeon_sp/gnr/cpu.c +++ b/src/soc/intel/xeon_sp/gnr/cpu.c @@ -13,8 +13,6 @@ #include "chip.h" -static const void *microcode_patch; - static const config_t *chip_config = NULL; bool cpu_soc_is_in_untrusted_mode(void) @@ -59,6 +57,9 @@ static const struct cpu_driver driver __cpu_driver = { */ static void pre_mp_init(void) { + const void *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + x86_setup_mtrrs_with_detect(); x86_mtrr_check(); } @@ -89,9 +90,6 @@ void mp_init_cpus(struct bus *bus) */ chip_config = bus->dev->chip_info; - microcode_patch = intel_microcode_find(); - intel_microcode_load_unlocked(microcode_patch); - enum cb_err ret = mp_init_with_smm(bus, &mp_ops); if (ret != CB_SUCCESS) printk(BIOS_ERR, "MP initialization failure %d.\n", ret); diff --git a/src/soc/intel/xeon_sp/skx/cpu.c b/src/soc/intel/xeon_sp/skx/cpu.c index e829aa988c..48054baada 100644 --- a/src/soc/intel/xeon_sp/skx/cpu.c +++ b/src/soc/intel/xeon_sp/skx/cpu.c @@ -246,6 +246,9 @@ static void pre_mp_init(void) { printk(BIOS_DEBUG, "%s: entry\n", __func__); + const void *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + x86_setup_mtrrs_with_detect(); x86_mtrr_check(); } @@ -279,13 +282,6 @@ void mp_init_cpus(struct bus *bus) { FUNC_ENTER(); - const void *microcode_patch = intel_microcode_find(); - - if (!microcode_patch) - printk(BIOS_ERR, "microcode not found in CBFS!\n"); - - intel_microcode_load_unlocked(microcode_patch); - /* * This gets used in cpu device callback. Other than cpu 0, * rest of the CPU devices do not have diff --git a/src/soc/intel/xeon_sp/spr/cpu.c b/src/soc/intel/xeon_sp/spr/cpu.c index cafdc37970..feaac904a2 100644 --- a/src/soc/intel/xeon_sp/spr/cpu.c +++ b/src/soc/intel/xeon_sp/spr/cpu.c @@ -17,8 +17,6 @@ #include "chip.h" -static const void *microcode_patch; - static const config_t *chip_config = NULL; bool cpu_soc_is_in_untrusted_mode(void) @@ -219,6 +217,9 @@ static void set_max_turbo_freq(void) */ static void pre_mp_init(void) { + const void *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + x86_setup_mtrrs_with_detect(); x86_mtrr_check(); } @@ -255,9 +256,6 @@ void mp_init_cpus(struct bus *bus) */ chip_config = bus->dev->chip_info; - microcode_patch = intel_microcode_find(); - intel_microcode_load_unlocked(microcode_patch); - enum cb_err ret = mp_init_with_smm(bus, &mp_ops); if (ret != CB_SUCCESS) printk(BIOS_ERR, "MP initialization failure %d.\n", ret); From 484e39c0680d8129ef0b1a591340e731eab25097 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 24 Jan 2026 10:37:51 +0100 Subject: [PATCH 695/789] mp_init: Pass microcode size to MPinit Extend get_microcode_info() to return the microcode size. This is being used in the following commit which uses the size to copy the microcode update to RAM in order to speed up MPinit. Depending on the SPI flash interface speed, the microcode size and the number of APs this can improve boot time by seconds. Since microcode size isn't used yet this is not a functional change. Change-Id: I1385e04c56e1411f0847a1c201c17e460c957477 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/90894 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/cpu/intel/haswell/haswell_init.c | 12 +++++++----- src/cpu/intel/model_1067x/mp_init.c | 8 ++++++-- src/cpu/intel/model_2065x/model_2065x_init.c | 8 ++++++-- src/cpu/intel/model_206ax/model_206ax_init.c | 8 ++++++-- src/cpu/intel/model_f2x/mp_init.c | 8 ++++++-- src/cpu/x86/mp_init.c | 3 +++ src/include/cpu/x86/mp.h | 2 +- src/soc/intel/apollolake/cpu.c | 8 ++++++-- src/soc/intel/baytrail/cpu.c | 8 ++++++-- src/soc/intel/braswell/cpu.c | 8 ++++++-- src/soc/intel/common/block/cpu/mp_init.c | 8 ++++++-- .../intel/common/block/include/intelblocks/mp_init.h | 2 +- src/soc/intel/xeon_sp/cpx/cpu.c | 8 ++++++-- src/soc/intel/xeon_sp/gnr/cpu.c | 8 ++++++-- src/soc/intel/xeon_sp/skx/cpu.c | 9 +++++++-- src/soc/intel/xeon_sp/spr/cpu.c | 8 ++++++-- 16 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/cpu/intel/haswell/haswell_init.c b/src/cpu/intel/haswell/haswell_init.c index a54a01ad8f..bd8932a039 100644 --- a/src/cpu/intel/haswell/haswell_init.c +++ b/src/cpu/intel/haswell/haswell_init.c @@ -502,8 +502,6 @@ static void cpu_core_init(struct device *cpu) } /* MP initialization support. */ -static const void *microcode_patch; - static void pre_mp_init(void) { /* Setup MTRRs based on physical address size. */ @@ -534,10 +532,13 @@ static int get_cpu_count(void) return num_threads; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - microcode_patch = intel_microcode_find(); - *microcode = microcode_patch; + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 1; } @@ -547,6 +548,7 @@ static void per_cpu_smm_trigger(void) smm_relocate(); /* After SMM relocation a 2nd microcode load is required. */ + const void *microcode_patch = intel_microcode_find(); intel_microcode_load_unlocked(microcode_patch); } diff --git a/src/cpu/intel/model_1067x/mp_init.c b/src/cpu/intel/model_1067x/mp_init.c index def136e689..f2a702c2ca 100644 --- a/src/cpu/intel/model_1067x/mp_init.c +++ b/src/cpu/intel/model_1067x/mp_init.c @@ -30,9 +30,13 @@ static int get_cpu_count(void) return cores; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/intel/model_2065x/model_2065x_init.c b/src/cpu/intel/model_2065x/model_2065x_init.c index d02c70bdfa..f8fb589159 100644 --- a/src/cpu/intel/model_2065x/model_2065x_init.c +++ b/src/cpu/intel/model_2065x/model_2065x_init.c @@ -129,9 +129,13 @@ static int get_cpu_count(void) return num_threads; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/intel/model_206ax/model_206ax_init.c b/src/cpu/intel/model_206ax/model_206ax_init.c index 162c674e0f..0fdbacbe8d 100644 --- a/src/cpu/intel/model_206ax/model_206ax_init.c +++ b/src/cpu/intel/model_206ax/model_206ax_init.c @@ -509,9 +509,13 @@ static int get_cpu_count(void) return num_threads; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/intel/model_f2x/mp_init.c b/src/cpu/intel/model_f2x/mp_init.c index c8d38c59ff..010b1770c1 100644 --- a/src/cpu/intel/model_f2x/mp_init.c +++ b/src/cpu/intel/model_f2x/mp_init.c @@ -27,9 +27,13 @@ static int get_cpu_count(void) return CONFIG_MAX_CPUS; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index 23880c74c8..ed2005e91e 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -77,6 +77,7 @@ struct mp_params { int num_cpus; /* Total cpus include BSP */ int parallel_microcode_load; const void *microcode_pointer; + size_t microcode_size; /* Flight plan for APs and BSP. */ struct mp_flight_record *flight_plan; int num_records; @@ -1145,9 +1146,11 @@ static enum cb_err do_mp_init_with_smm(struct bus *cpu_bus, const struct mp_ops printk(BIOS_INFO, "Will perform SMM setup.\n"); mp_params.num_cpus = mp_state.cpu_count; + /* Gather microcode information. */ if (mp_state.ops.get_microcode_info != NULL) mp_state.ops.get_microcode_info(&mp_params.microcode_pointer, + &mp_params.microcode_size, &mp_params.parallel_microcode_load); mp_params.flight_plan = &mp_steps[0]; mp_params.num_records = ARRAY_SIZE(mp_steps); diff --git a/src/include/cpu/x86/mp.h b/src/include/cpu/x86/mp.h index dd86dce2c5..ec4297e105 100644 --- a/src/include/cpu/x86/mp.h +++ b/src/include/cpu/x86/mp.h @@ -47,7 +47,7 @@ struct mp_ops { * Optionally fill in pointer to microcode and indicate if the APs * can load the microcode in parallel. */ - void (*get_microcode_info)(const void **microcode, int *parallel); + void (*get_microcode_info)(const void **microcode, size_t *size, int *parallel); /* * Optionally provide a callback prior to the APs starting SMM * relocation or CPU driver initialization. However, note that diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c index 67450b2d5d..ee003805fd 100644 --- a/src/soc/intel/apollolake/cpu.c +++ b/src/soc/intel/apollolake/cpu.c @@ -193,9 +193,13 @@ int get_cpu_count(void) return num_virt_cores; } -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 1; } #endif diff --git a/src/soc/intel/baytrail/cpu.c b/src/soc/intel/baytrail/cpu.c index 2a4616cec3..7408eb7c64 100644 --- a/src/soc/intel/baytrail/cpu.c +++ b/src/soc/intel/baytrail/cpu.c @@ -146,11 +146,15 @@ static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { const struct pattrs *pattrs = pattrs_get(); + const struct microcode *microcode_file = pattrs->microcode_patch; - *microcode = pattrs->microcode_patch; + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/soc/intel/braswell/cpu.c b/src/soc/intel/braswell/cpu.c index 23663c3c71..f5e985396b 100644 --- a/src/soc/intel/braswell/cpu.c +++ b/src/soc/intel/braswell/cpu.c @@ -146,11 +146,15 @@ static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { const struct pattrs *pattrs = pattrs_get(); + const struct microcode *microcode_file = pattrs->microcode_patch; - *microcode = pattrs->microcode_patch; + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/soc/intel/common/block/cpu/mp_init.c b/src/soc/intel/common/block/cpu/mp_init.c index dd8a31592e..12d9b95cbd 100644 --- a/src/soc/intel/common/block/cpu/mp_init.c +++ b/src/soc/intel/common/block/cpu/mp_init.c @@ -137,9 +137,13 @@ int get_cpu_count(void) * sets the argument *parallel to 1, which allows microcode loading in all * APs to occur in parallel during MP Init. */ -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 1; } diff --git a/src/soc/intel/common/block/include/intelblocks/mp_init.h b/src/soc/intel/common/block/include/intelblocks/mp_init.h index 0dd2109e4a..a0579b7db2 100644 --- a/src/soc/intel/common/block/include/intelblocks/mp_init.h +++ b/src/soc/intel/common/block/include/intelblocks/mp_init.h @@ -21,7 +21,7 @@ int get_cpu_count(void); * sets the argument *parallel to 1, which allows microcode loading in all * APs to occur in parallel during MP Init. */ -void get_microcode_info(const void **microcode, int *parallel); +void get_microcode_info(const void **microcode, size_t *size, int *parallel); /* * Perform BSP and AP initialization diff --git a/src/soc/intel/xeon_sp/cpx/cpu.c b/src/soc/intel/xeon_sp/cpx/cpu.c index c6375ecfdb..57f9ea9a29 100644 --- a/src/soc/intel/xeon_sp/cpx/cpu.c +++ b/src/soc/intel/xeon_sp/cpx/cpu.c @@ -66,9 +66,13 @@ static void xeon_configure_mca(void) * the BSP. Loading MCU on AP in parallel seems to fail in 10% of the cases * so do it serialized. */ -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } diff --git a/src/soc/intel/xeon_sp/gnr/cpu.c b/src/soc/intel/xeon_sp/gnr/cpu.c index 2e645a53d7..9969287b3c 100644 --- a/src/soc/intel/xeon_sp/gnr/cpu.c +++ b/src/soc/intel/xeon_sp/gnr/cpu.c @@ -21,9 +21,13 @@ bool cpu_soc_is_in_untrusted_mode(void) return false; } -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } diff --git a/src/soc/intel/xeon_sp/skx/cpu.c b/src/soc/intel/xeon_sp/skx/cpu.c index 48054baada..ddb509bfb4 100644 --- a/src/soc/intel/xeon_sp/skx/cpu.c +++ b/src/soc/intel/xeon_sp/skx/cpu.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -70,9 +71,13 @@ static void xeon_configure_mca(void) * FSP-S updates microcodes serialized, so do the same. * */ -static void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } diff --git a/src/soc/intel/xeon_sp/spr/cpu.c b/src/soc/intel/xeon_sp/spr/cpu.c index feaac904a2..55568cc8ff 100644 --- a/src/soc/intel/xeon_sp/spr/cpu.c +++ b/src/soc/intel/xeon_sp/spr/cpu.c @@ -56,9 +56,13 @@ static void xeon_configure_mca(void) * the BSP. Loading MCU on AP in parallel seems to fail in 10% of the cases * so do it serialized. */ -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } From 3fa3818e411bf80bf7103942ecc163a5bc0a7017 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Mon, 16 Feb 2026 21:30:46 +0000 Subject: [PATCH 696/789] starlabs: add ACPI SMI bridge for EFI options Add a Device NVS (DNVS) protocol and SMM handler to let ACPI read and write a restricted set of coreboot options stored in the UEFI variable store. ACPI fills DNVS and triggers an SMI via APM_CNT (0xB2). SMM performs the requested operation and updates DNVS with status and, for reads, the returned value. Signed-off-by: Sean Rhodes Change-Id: Ice0ac36f6d0e1de88daf7010cb1771453547619e Reviewed-on: https://review.coreboot.org/c/coreboot/+/91303 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/common/Kconfig | 11 +- src/mainboard/starlabs/common/Makefile.mk | 3 + src/mainboard/starlabs/common/gnvs.c | 11 + .../common/include/starlabs/efi_option_smi.h | 38 ++++ src/mainboard/starlabs/common/smihandler.c | 188 ++++++++++++++++++ 5 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 src/mainboard/starlabs/common/gnvs.c create mode 100644 src/mainboard/starlabs/common/include/starlabs/efi_option_smi.h create mode 100644 src/mainboard/starlabs/common/smihandler.c diff --git a/src/mainboard/starlabs/common/Kconfig b/src/mainboard/starlabs/common/Kconfig index adeda59bdf..8a670142c0 100644 --- a/src/mainboard/starlabs/common/Kconfig +++ b/src/mainboard/starlabs/common/Kconfig @@ -17,8 +17,15 @@ config MB_COMMON_DIR string default "starlabs/common" -config SOC_INTEL_COMMON_BLOCK_SMM_TCO_INTRUDER_SMI_ENABLE - default n +config STARLABS_ACPI_EFI_OPTION_SMI + bool "Expose coreboot options to ACPI via SMI (UEFI var store)" + depends on USE_UEFI_VARIABLE_STORE + depends on HAVE_ACPI_TABLES + default y + help + Provide ACPI methods that proxy a restricted set of coreboot options + (e.g. keyboard backlight and trackpad state) to the UEFI variable + store via an SMM APMC SMI handler. source "src/mainboard/starlabs/common/hda/Kconfig" diff --git a/src/mainboard/starlabs/common/Makefile.mk b/src/mainboard/starlabs/common/Makefile.mk index 90c0d94d5a..b12b7610d3 100644 --- a/src/mainboard/starlabs/common/Makefile.mk +++ b/src/mainboard/starlabs/common/Makefile.mk @@ -7,3 +7,6 @@ subdirs-$(CONFIG_VENDOR_STARLABS) += pin_mux subdirs-$(CONFIG_VENDOR_STARLABS) += smbios CPPFLAGS_common += -I$(src)/mainboard/starlabs/common/include + +ramstage-$(CONFIG_STARLABS_ACPI_EFI_OPTION_SMI) += gnvs.c +smm-$(CONFIG_STARLABS_ACPI_EFI_OPTION_SMI) += smihandler.c diff --git a/src/mainboard/starlabs/common/gnvs.c b/src/mainboard/starlabs/common/gnvs.c new file mode 100644 index 0000000000..7e119470ab --- /dev/null +++ b/src/mainboard/starlabs/common/gnvs.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#include +#include + +size_t size_of_dnvs(void) +{ + return sizeof(struct starlabs_dnvs_efiopt); +} diff --git a/src/mainboard/starlabs/common/include/starlabs/efi_option_smi.h b/src/mainboard/starlabs/common/include/starlabs/efi_option_smi.h new file mode 100644 index 0000000000..cdd6bf4a89 --- /dev/null +++ b/src/mainboard/starlabs/common/include/starlabs/efi_option_smi.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef STARLABS_EFI_OPTION_SMI_H +#define STARLABS_EFI_OPTION_SMI_H + +#include + +/* + * ACPI <-> SMM protocol for reading/writing a restricted set of coreboot + * options in the UEFI variable store. + * + * ACPI fills DNVS, then triggers an APMC SMI by writing STARLABS_APMC_CMD + * to the APM_CNT port (0xB2). SMM reads DNVS, performs the operation, and + * updates DNVS with status and (for reads) the returned value. + */ + +#define STARLABS_APMC_CMD_EFI_OPTION 0xE2 + +enum starlabs_efiopt_cmd { + STARLABS_EFIOPT_CMD_GET = 1, + STARLABS_EFIOPT_CMD_SET = 2, +}; + +enum starlabs_efiopt_id { + STARLABS_EFIOPT_ID_FN_LOCK_STATE = 1, + STARLABS_EFIOPT_ID_TRACKPAD_STATE = 2, + STARLABS_EFIOPT_ID_KBL_BRIGHTNESS = 3, + STARLABS_EFIOPT_ID_KBL_STATE = 4, +}; + +struct starlabs_dnvs_efiopt { + uint32_t cmd; + uint32_t id; + uint32_t value; + uint32_t status; +} __packed; + +#endif /* STARLABS_EFI_OPTION_SMI_H */ diff --git a/src/mainboard/starlabs/common/smihandler.c b/src/mainboard/starlabs/common/smihandler.c new file mode 100644 index 0000000000..d74cce1008 --- /dev/null +++ b/src/mainboard/starlabs/common/smihandler.c @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#if CONFIG(SOC_INTEL_COMMON_BLOCK_FAST_SPI) +#include +#include +#include +#include +#endif +#include +#include +#include +#include + +#if CONFIG(SOC_INTEL_COMMON_BLOCK_FAST_SPI) +static void set_insmm_sts(const bool enable_writes) +{ + msr_t msr = { + .lo = read32p(0xfed30880), + .hi = 0, + }; + + if (enable_writes) + msr.lo |= 1; + else + msr.lo &= ~1; + + wrmsr(MSR_SPCL_CHIPSET_USAGE, msr); +} +#endif + +static bool chipset_disable_wp(void) +{ +#if CONFIG(SOC_INTEL_COMMON_BLOCK_FAST_SPI) + const bool wp_enabled = !fast_spi_wpd_status(); + + if (wp_enabled) { + set_insmm_sts(true); + /* + * As per BWG, clearing "SPI_BIOS_CONTROL_SYNC_SS" + * bit is a must prior setting SPI_BIOS_CONTROL_WPD" bit + * to avoid 3-strike error. + */ + fast_spi_clear_sync_smi_status(); + fast_spi_disable_wp(); + } + + return wp_enabled; +#endif + + return false; +} + +static void chipset_enable_wp(void) +{ +#if CONFIG(SOC_INTEL_COMMON_BLOCK_FAST_SPI) + fast_spi_enable_wp(); + set_insmm_sts(false); +#endif +} + +static struct starlabs_dnvs_efiopt *get_starlabs_dnvs_efiopt(void) +{ + if (!gnvs) + return NULL; + + const size_t gnvs_size = ALIGN_UP(sizeof(struct global_nvs), sizeof(uint64_t)); + + uint8_t *base = (uint8_t *)gnvs; + base += gnvs_size; + return (struct starlabs_dnvs_efiopt *)base; +} + +struct starlabs_efiopt_entry { + const char *name; + enum starlabs_efiopt_id id; + uint32_t fallback; +}; + +static const struct starlabs_efiopt_entry *find_efiopt(enum starlabs_efiopt_id id) +{ + static const struct starlabs_efiopt_entry opts[] = { + { + .name = "fn_lock_state", + .id = STARLABS_EFIOPT_ID_FN_LOCK_STATE, + .fallback = LOCKED, + }, + { + .name = "trackpad_state", + .id = STARLABS_EFIOPT_ID_TRACKPAD_STATE, + .fallback = TRACKPAD_ENABLED, + }, + { + .name = "kbl_brightness", + .id = STARLABS_EFIOPT_ID_KBL_BRIGHTNESS, + .fallback = CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON, + }, + { + .name = "kbl_state", + .id = STARLABS_EFIOPT_ID_KBL_STATE, + .fallback = KBL_ENABLED, + }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(opts); i++) { + if (opts[i].id == id) + return &opts[i]; + } + + return NULL; +} + +static enum cb_err normalize_value(enum starlabs_efiopt_id id, uint32_t *value) +{ + if (!value) + return CB_ERR_ARG; + + switch (id) { + case STARLABS_EFIOPT_ID_FN_LOCK_STATE: + if (*value == UNLOCKED || *value == LOCKED) + return CB_SUCCESS; + return CB_ERR_ARG; + case STARLABS_EFIOPT_ID_TRACKPAD_STATE: + /* Normalize "re-enabled" to "enabled". */ + if (*value == 0x11) + *value = TRACKPAD_ENABLED; + if (*value == TRACKPAD_ENABLED || *value == TRACKPAD_DISABLED) + return CB_SUCCESS; + return CB_ERR_ARG; + case STARLABS_EFIOPT_ID_KBL_BRIGHTNESS: + if (*value == KBL_ON || *value == KBL_OFF || *value == KBL_LOW || + *value == KBL_HIGH) + return CB_SUCCESS; + return CB_ERR_ARG; + case STARLABS_EFIOPT_ID_KBL_STATE: + if (*value == KBL_DISABLED || *value == KBL_ENABLED) + return CB_SUCCESS; + return CB_ERR_ARG; + default: + return CB_ERR_ARG; + } +} + +int mainboard_smi_apmc(u8 data) +{ + if (data != STARLABS_APMC_CMD_EFI_OPTION) + return 0; + + struct starlabs_dnvs_efiopt *dnvs = get_starlabs_dnvs_efiopt(); + if (!dnvs) + return 0; + + const enum starlabs_efiopt_cmd cmd = dnvs->cmd; + const enum starlabs_efiopt_id id = dnvs->id; + const struct starlabs_efiopt_entry *opt = find_efiopt(id); + + if (!opt) { + dnvs->status = CB_ERR_ARG; + return 1; + } + + switch (cmd) { + case STARLABS_EFIOPT_CMD_GET: + dnvs->value = get_uint_option(opt->name, opt->fallback); + dnvs->status = CB_SUCCESS; + break; + case STARLABS_EFIOPT_CMD_SET: { + uint32_t value = dnvs->value; + dnvs->status = normalize_value(id, &value); + if (dnvs->status != CB_SUCCESS) + break; + + const bool wp_enabled = chipset_disable_wp(); + dnvs->status = set_uint_option(opt->name, value); + if (wp_enabled) + chipset_enable_wp(); + break; + } + default: + dnvs->status = CB_ERR_ARG; + break; + } + + return 1; +} From 9dac2b9e539cada107b276592d9347b3e4d04d46 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Mon, 16 Feb 2026 21:32:24 +0000 Subject: [PATCH 697/789] ec/starlabs/merlin: persist settings via EFI options When STARLABS_ACPI_EFI_OPTION_SMI is enabled, store and restore trackpad and keyboard backlight state across S4/S5 using the EFI variable store SMI bridge instead of CMOS. Also make the EC init paths treat CMOS as an index mapping and prefer the option backend when CMOS options are not in use. Signed-off-by: Sean Rhodes Change-Id: Ia31ac0440eba1334be48030ce7fe03dc84193ac3 Reviewed-on: https://review.coreboot.org/c/coreboot/+/91304 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/ec/starlabs/merlin/acpi/suspend.asl | 139 +++++++++++++++-- src/ec/starlabs/merlin/ite.c | 189 +++++++----------------- src/ec/starlabs/merlin/nuvoton.c | 161 ++++++++------------ 3 files changed, 246 insertions(+), 243 deletions(-) diff --git a/src/ec/starlabs/merlin/acpi/suspend.asl b/src/ec/starlabs/merlin/acpi/suspend.asl index 966362f8a4..0ccce6f84b 100644 --- a/src/ec/starlabs/merlin/acpi/suspend.asl +++ b/src/ec/starlabs/merlin/acpi/suspend.asl @@ -1,8 +1,75 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#if CONFIG(STARLABS_ACPI_EFI_OPTION_SMI) +Field (\DNVS, ByteAcc, NoLock, Preserve) +{ + EOCM, 32, // EFI option command + EOID, 32, // EFI option ID + EOVL, 32, // EFI option value + EORS, 32, // EFI option status +} + +Name (EOAP, 0xE2) // STARLABS_APMC_CMD_EFI_OPTION + +Name (EOFL, 0x1) // STARLABS_EFIOPT_ID_FN_LOCK_STATE +Name (EOTP, 0x2) // STARLABS_EFIOPT_ID_TRACKPAD_STATE +Name (EOKB, 0x3) // STARLABS_EFIOPT_ID_KBL_BRIGHTNESS +Name (EOKS, 0x4) // STARLABS_EFIOPT_ID_KBL_STATE + +Mutex (EOMX, 0x00) + +Method (EOGT, 1, Serialized) +{ + If (Acquire (EOMX, 1000)) + { + Return (0xFFFFFFFF) + } + + Store (0x01, EOCM) + Store (Arg0, EOID) + Store (0x00, EORS) + Store (EOAP, \_SB.PCI0.LPCB.EC.SMB2) + + Store (EOVL, Local0) + Release (EOMX) + Return (Local0) +} + +Method (EOSV, 2, Serialized) +{ + If (Acquire (EOMX, 1000)) + { + Return (0x01) + } + + Store (0x02, EOCM) + Store (Arg0, EOID) + Store (Arg1, EOVL) + Store (0x00, EORS) + Store (EOAP, \_SB.PCI0.LPCB.EC.SMB2) + + Store (EORS, Local0) + Release (EOMX) + Return (Local0) +} +#endif + Method (RPTS, 1, Serialized) { +#if CONFIG(STARLABS_ACPI_EFI_OPTION_SMI) + /* Store current EC settings in UEFI variable store */ + Store (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.TPLE)), Local0) + If (Local0 == 0x11) + { + Store (0x00, Local0) + } + EOSV (EOTP, Local0) + + EOSV (EOFL, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.FLKE))) + EOSV (EOKS, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLSE))) + EOSV (EOKB, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLBE))) +#else /* Store current EC settings in CMOS */ Switch (ToInteger (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.TPLE)))) { @@ -11,20 +78,19 @@ Method (RPTS, 1, Serialized) // 0x22 == Disabled == 0x01 Case (0x00) { - \_SB.PCI0.LPCB.TPLC = 0x00 + Store (0x00, \_SB.PCI0.LPCB.TPLC) } Case (0x11) { - \_SB.PCI0.LPCB.TPLC = 0x00 + Store (0x00, \_SB.PCI0.LPCB.TPLC) } Case (0x22) { - \_SB.PCI0.LPCB.TPLC = 0x01 + Store (0x01, \_SB.PCI0.LPCB.TPLC) } } - \_SB.PCI0.LPCB.FLKC = - \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.FLKE)) + Store (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.FLKE)), \_SB.PCI0.LPCB.FLKC) Switch (ToInteger (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLSE)))) { @@ -32,11 +98,11 @@ Method (RPTS, 1, Serialized) // 0xdd == Enabled == 0x01 Case (0x00) { - \_SB.PCI0.LPCB.KLSC = 0x00 + Store (0x00, \_SB.PCI0.LPCB.KLSC) } Case (0xdd) { - \_SB.PCI0.LPCB.KLSC = 0x01 + Store (0x01, \_SB.PCI0.LPCB.KLSC) } } @@ -48,27 +114,30 @@ Method (RPTS, 1, Serialized) // 0xaa == High == 0x03 Case (0xdd) { - \_SB.PCI0.LPCB.KLBC = 0x00 + Store (0x00, \_SB.PCI0.LPCB.KLBC) } Case (0xcc) { - \_SB.PCI0.LPCB.KLBC = 0x01 + Store (0x01, \_SB.PCI0.LPCB.KLBC) } Case (0xbb) { - \_SB.PCI0.LPCB.KLBC = 0x02 + Store (0x02, \_SB.PCI0.LPCB.KLBC) } Case (0xaa) { - \_SB.PCI0.LPCB.KLBC = 0x03 + Store (0x03, \_SB.PCI0.LPCB.KLBC) } } +#endif /* * Disable ACPI support. * This should always be the last action before entering a sleep state. */ \_SB.PCI0.LPCB.EC.ECWR(0x00, RefOf(\_SB.PCI0.LPCB.EC.OSFG)) + + Return (Arg0) } Method (RWAK, 1, Serialized) @@ -79,6 +148,51 @@ Method (RWAK, 1, Serialized) */ \_SB.PCI0.LPCB.EC.ECWR(0x01, RefOf(\_SB.PCI0.LPCB.EC.OSFG)) +#if CONFIG(STARLABS_ACPI_EFI_OPTION_SMI) + /* Restore EC settings from UEFI variable store */ + Store (EOGT (EOTP), Local0) + If (Local0 == 0x22) + { + \_SB.PCI0.LPCB.EC.ECWR (0x22, RefOf(\_SB.PCI0.LPCB.EC.TPLE)) + } + Else + { + \_SB.PCI0.LPCB.EC.ECWR (0x00, RefOf(\_SB.PCI0.LPCB.EC.TPLE)) + } + + \_SB.PCI0.LPCB.EC.ECWR (EOGT (EOFL), RefOf(\_SB.PCI0.LPCB.EC.FLKE)) + + Store (EOGT (EOKS), Local0) + If (Local0 == 0xdd) + { + \_SB.PCI0.LPCB.EC.ECWR (0xdd, RefOf(\_SB.PCI0.LPCB.EC.KLSE)) + } + Else + { + \_SB.PCI0.LPCB.EC.ECWR (0x00, RefOf(\_SB.PCI0.LPCB.EC.KLSE)) + } + + Store (EOGT (EOKB), Local0) + Switch (ToInteger (Local0)) + { + Case (0xdd) + { + \_SB.PCI0.LPCB.EC.ECWR (0xdd, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) + } + Case (0xcc) + { + \_SB.PCI0.LPCB.EC.ECWR (0xcc, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) + } + Case (0xbb) + { + \_SB.PCI0.LPCB.EC.ECWR (0xbb, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) + } + Case (0xaa) + { + \_SB.PCI0.LPCB.EC.ECWR (0xaa, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) + } + } +#else /* Restore EC settings from CMOS */ Switch (ToInteger (\_SB.PCI0.LPCB.TPLC)) { @@ -134,4 +248,7 @@ Method (RWAK, 1, Serialized) \_SB.PCI0.LPCB.EC.ECWR (0xaa, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) } } +#endif + + Return (Arg0) } diff --git a/src/ec/starlabs/merlin/ite.c b/src/ec/starlabs/merlin/ite.c index 8ce556a308..4240d7dbef 100644 --- a/src/ec/starlabs/merlin/ite.c +++ b/src/ec/starlabs/merlin/ite.c @@ -12,8 +12,8 @@ #include "option_table.h" #include "ec.h" -#define ITE_IT5570 0x5570 -#define ITE_IT8987 0x8987 +#define ITE_IT5570 0x5570 +#define ITE_IT8987 0x8987 uint16_t ec_get_version(void) { @@ -25,20 +25,17 @@ static uint8_t get_cmos_value(uint32_t bit, uint32_t length) uint32_t byte, byte_bit; uint8_t uchar; - byte = bit / 8; // find the byte where the data starts + byte = bit / 8; // find the byte where the data starts byte_bit = bit % 8; // find the bit in the byte where the data starts uchar = cmos_read(byte); // load the byte - uchar >>= byte_bit; // shift the bits to byte align + uchar >>= byte_bit; // shift the bits to byte align // clear unspecified bits return uchar & ((1U << length) - 1); } -static uint8_t get_ec_value_from_option(const char *name, - uint32_t fallback, - const uint8_t *lut, - size_t lut_size, - uint32_t cmos_start_bit, +static uint8_t get_ec_value_from_option(const char *name, uint32_t fallback, const uint8_t *lut, + size_t lut_size, uint32_t cmos_start_bit, uint32_t cmos_length) { /* @@ -69,8 +66,7 @@ static uint8_t get_ec_value_from_option(const char *name, static uint16_t ec_get_chip_id(unsigned int port) { - return (pnp_read_index(port, ITE_CHIPID1) << 8) | - pnp_read_index(port, ITE_CHIPID2); + return (pnp_read_index(port, ITE_CHIPID1) << 8) | pnp_read_index(port, ITE_CHIPID2); } static void merlin_init(struct device *dev) @@ -122,21 +118,11 @@ static void merlin_init(struct device *dev) * Default: 30 Seconds * */ - const uint8_t kbl_timeout[] = { - SEC_30, - MIN_1, - MIN_3, - MIN_5, - NEVER - }; + const uint8_t kbl_timeout[] = {SEC_30, MIN_1, MIN_3, MIN_5, NEVER}; ec_write(ECRAM_KBL_TIMEOUT, - get_ec_value_from_option("kbl_timeout", - SEC_30, - kbl_timeout, - ARRAY_SIZE(kbl_timeout), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("kbl_timeout", SEC_30, kbl_timeout, + ARRAY_SIZE(kbl_timeout), UINT_MAX, UINT_MAX)); /* * Fn Ctrl Reverse @@ -147,18 +133,11 @@ static void merlin_init(struct device *dev) * Default: Disabled * */ - const uint8_t fn_ctrl_swap[] = { - FN_CTRL, - CTRL_FN - }; + const uint8_t fn_ctrl_swap[] = {FN_CTRL, CTRL_FN}; ec_write(ECRAM_FN_CTRL_REVERSE, - get_ec_value_from_option("fn_ctrl_swap", - FN_CTRL, - fn_ctrl_swap, - ARRAY_SIZE(fn_ctrl_swap), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("fn_ctrl_swap", FN_CTRL, fn_ctrl_swap, + ARRAY_SIZE(fn_ctrl_swap), UINT_MAX, UINT_MAX)); /* * Maximum Charge Level @@ -169,20 +148,12 @@ static void merlin_init(struct device *dev) * Default: 100% * */ - const uint8_t max_charge[] = { - CHARGE_100, - CHARGE_80, - CHARGE_60 - }; + const uint8_t max_charge[] = {CHARGE_100, CHARGE_80, CHARGE_60}; if (CONFIG(EC_STARLABS_MAX_CHARGE)) ec_write(ECRAM_MAX_CHARGE, - get_ec_value_from_option("max_charge", - CHARGE_100, - max_charge, - ARRAY_SIZE(max_charge), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("max_charge", CHARGE_100, max_charge, + ARRAY_SIZE(max_charge), UINT_MAX, UINT_MAX)); /* * Fan Mode @@ -193,21 +164,12 @@ static void merlin_init(struct device *dev) * Default: Normal * */ - const uint8_t fan_mode[] = { - FAN_NORMAL, - FAN_AGGRESSIVE, - FAN_QUIET, - FAN_DISABLED - }; + const uint8_t fan_mode[] = {FAN_NORMAL, FAN_AGGRESSIVE, FAN_QUIET, FAN_DISABLED}; if (CONFIG(EC_STARLABS_FAN)) ec_write(ECRAM_FAN_MODE, - get_ec_value_from_option("fan_mode", - FAN_NORMAL, - fan_mode, - ARRAY_SIZE(fan_mode), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("fan_mode", FAN_NORMAL, fan_mode, + ARRAY_SIZE(fan_mode), UINT_MAX, UINT_MAX)); /* * Function Lock @@ -219,18 +181,13 @@ static void merlin_init(struct device *dev) * */ #ifdef CMOS_VLEN_fn_lock_state - const uint8_t fn_lock_state[] = { - UNLOCKED, - LOCKED - }; + const uint8_t fn_lock_state[] = {UNLOCKED, LOCKED}; ec_write(ECRAM_FN_LOCK_STATE, - get_ec_value_from_option("fn_lock_state", - UNLOCKED, - fn_lock_state, - ARRAY_SIZE(fn_lock_state), - CMOS_VSTART_fn_lock_state, - CMOS_VLEN_fn_lock_state)); + get_ec_value_from_option( + "fn_lock_state", UNLOCKED, fn_lock_state, ARRAY_SIZE(fn_lock_state), + CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_fn_lock_state : UINT_MAX, + CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_fn_lock_state : UINT_MAX)); #endif /* @@ -243,18 +200,14 @@ static void merlin_init(struct device *dev) * */ #ifdef CMOS_VSTART_trackpad_state - const uint8_t trackpad_state[] = { - TRACKPAD_ENABLED, - TRACKPAD_DISABLED - }; + const uint8_t trackpad_state[] = {TRACKPAD_ENABLED, TRACKPAD_DISABLED}; ec_write(ECRAM_TRACKPAD_STATE, - get_ec_value_from_option("trackpad_state", - TRACKPAD_ENABLED, - trackpad_state, - ARRAY_SIZE(trackpad_state), - CMOS_VSTART_trackpad_state, - CMOS_VLEN_trackpad_state)); + get_ec_value_from_option( + "trackpad_state", TRACKPAD_ENABLED, trackpad_state, + ARRAY_SIZE(trackpad_state), + CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_trackpad_state : UINT_MAX, + CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_trackpad_state : UINT_MAX)); #endif /* @@ -267,24 +220,19 @@ static void merlin_init(struct device *dev) * */ #ifdef CMOS_VSTART_kbl_brightness - const uint8_t kbl_brightness[] = { - KBL_ON, - KBL_OFF, - KBL_LOW, - KBL_HIGH - }; + const uint8_t kbl_brightness[] = {KBL_ON, KBL_OFF, KBL_LOW, KBL_HIGH}; ec_write(ECRAM_KBL_BRIGHTNESS, - get_ec_value_from_option("kbl_brightness", - CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0, - kbl_brightness, - ARRAY_SIZE(kbl_brightness), - CMOS_VSTART_kbl_brightness, - CMOS_VLEN_kbl_brightness)); - + get_ec_value_from_option( + "kbl_brightness", + CONFIG(USE_OPTION_TABLE) ? + (CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0) : + (CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON), + kbl_brightness, ARRAY_SIZE(kbl_brightness), + CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_kbl_brightness : UINT_MAX, + CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_kbl_brightness : UINT_MAX)); #endif - /* * Keyboard Backlight State * @@ -308,20 +256,13 @@ static void merlin_init(struct device *dev) * Default: 0.5C * */ - const uint8_t charging_speed[] = { - SPEED_1_0C, - SPEED_0_5C, - SPEED_0_2C - }; + const uint8_t charging_speed[] = {SPEED_1_0C, SPEED_0_5C, SPEED_0_2C}; if (CONFIG(EC_STARLABS_CHARGING_SPEED)) ec_write(ECRAM_CHARGING_SPEED, - get_ec_value_from_option("charging_speed", - SPEED_0_5C, - charging_speed, - ARRAY_SIZE(charging_speed), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("charging_speed", SPEED_0_5C, charging_speed, + ARRAY_SIZE(charging_speed), UINT_MAX, + UINT_MAX)); /* * Lid Switch @@ -332,20 +273,12 @@ static void merlin_init(struct device *dev) * Default: 0 * */ - const uint8_t lid_switch[] = { - SWITCH_NORMAL, - SWITCH_SLEEP_ONLY, - SWITCH_DISABLED - }; + const uint8_t lid_switch[] = {SWITCH_NORMAL, SWITCH_SLEEP_ONLY, SWITCH_DISABLED}; if (CONFIG(EC_STARLABS_LID_SWITCH)) ec_write(ECRAM_LID_SWITCH, - get_ec_value_from_option("lid_switch", - SWITCH_NORMAL, - lid_switch, - ARRAY_SIZE(lid_switch), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("lid_switch", SWITCH_NORMAL, lid_switch, + ARRAY_SIZE(lid_switch), UINT_MAX, UINT_MAX)); /* * Power LED Brightness @@ -356,20 +289,13 @@ static void merlin_init(struct device *dev) * Default: 0 * */ - const uint8_t led_brightness[] = { - LED_NORMAL, - LED_REDUCED, - LED_OFF - }; + const uint8_t led_brightness[] = {LED_NORMAL, LED_REDUCED, LED_OFF}; if (CONFIG(EC_STARLABS_POWER_LED)) ec_write(ECRAM_POWER_LED, - get_ec_value_from_option("power_led", - LED_NORMAL, - led_brightness, - ARRAY_SIZE(led_brightness), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("power_led", LED_NORMAL, led_brightness, + ARRAY_SIZE(led_brightness), UINT_MAX, + UINT_MAX)); /* * Charge LED Brightness @@ -383,18 +309,15 @@ static void merlin_init(struct device *dev) if (CONFIG(EC_STARLABS_CHARGE_LED)) ec_write(ECRAM_CHARGE_LED, - get_ec_value_from_option("charge_led", - LED_NORMAL, - led_brightness, - ARRAY_SIZE(led_brightness), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("charge_led", LED_NORMAL, led_brightness, + ARRAY_SIZE(led_brightness), UINT_MAX, + UINT_MAX)); } static struct device_operations ops = { - .init = merlin_init, - .read_resources = noop_read_resources, - .set_resources = noop_set_resources, + .init = merlin_init, + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, }; static struct pnp_info pnp_dev_info[] = { diff --git a/src/ec/starlabs/merlin/nuvoton.c b/src/ec/starlabs/merlin/nuvoton.c index 6b39fe0ebf..36212f63c4 100644 --- a/src/ec/starlabs/merlin/nuvoton.c +++ b/src/ec/starlabs/merlin/nuvoton.c @@ -12,7 +12,6 @@ #include "option_table.h" #include "ec.h" - uint16_t ec_get_version(void) { return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION); @@ -23,32 +22,43 @@ static uint8_t get_cmos_value(uint32_t bit, uint32_t length) uint32_t byte, byte_bit; uint8_t uchar; - byte = bit / 8; // find the byte where the data starts + byte = bit / 8; // find the byte where the data starts byte_bit = bit % 8; // find the bit in the byte where the data starts uchar = cmos_read(byte); // load the byte - uchar >>= byte_bit; // shift the bits to byte align + uchar >>= byte_bit; // shift the bits to byte align // clear unspecified bits return uchar & ((1U << length) - 1); } -static uint8_t get_ec_value_from_option(const char *name, - uint32_t fallback, - const uint8_t *lut, - size_t lut_size, - uint32_t cmos_start_bit, +static uint8_t get_ec_value_from_option(const char *name, uint32_t fallback, const uint8_t *lut, + size_t lut_size, uint32_t cmos_start_bit, uint32_t cmos_length) { - unsigned int index; + /* + * CMOS-backed EC options store an index (see cmos.layout and ACPI + * RPTS/RWAK mappings), while the option backend stores the EC's raw + * values (e.g. 0xaa/0xbb/0xdd). + */ + if (cmos_start_bit != UINT_MAX) { + unsigned int index = get_cmos_value(cmos_start_bit, cmos_length); + + if (index >= lut_size) + index = fallback; + if (index >= lut_size) + index = 0; - if (cmos_start_bit != UINT_MAX) - index = get_cmos_value(cmos_start_bit, cmos_length); - else - index = get_uint_option(name, fallback); + return lut[index]; + } + + const uint8_t value = get_uint_option(name, fallback); - if (index >= lut_size) - index = fallback; - return lut[index]; + /* Check if the value exists in the LUT array */ + for (size_t i = 0; i < lut_size; i++) + if (lut[i] == value) + return value; + + return fallback; } static uint16_t ec_get_chip_id(unsigned int port) @@ -77,7 +87,7 @@ static void merlin_init(struct device *dev) if (chip_id != NUVOTON_CHIPID_VAL) { printk(BIOS_ERR, "NUVOTON: Expected chip ID 0x%04x, but got 0x%04x instead.\n", - NUVOTON_CHIPID_VAL, chip_id); + NUVOTON_CHIPID_VAL, chip_id); return; } @@ -103,21 +113,11 @@ static void merlin_init(struct device *dev) * Default: 30 Seconds * */ - const uint8_t kbl_timeout[] = { - SEC_30, - MIN_1, - MIN_3, - MIN_5, - NEVER - }; + const uint8_t kbl_timeout[] = {SEC_30, MIN_1, MIN_3, MIN_5, NEVER}; ec_write(ECRAM_KBL_TIMEOUT, - get_ec_value_from_option("kbl_timeout", - 0, - kbl_timeout, - ARRAY_SIZE(kbl_timeout), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("kbl_timeout", 0, kbl_timeout, + ARRAY_SIZE(kbl_timeout), UINT_MAX, UINT_MAX)); /* * Fn Ctrl Reverse @@ -128,18 +128,11 @@ static void merlin_init(struct device *dev) * Default: Disabled * */ - const uint8_t fn_ctrl_swap[] = { - FN_CTRL, - CTRL_FN - }; + const uint8_t fn_ctrl_swap[] = {FN_CTRL, CTRL_FN}; ec_write(ECRAM_FN_CTRL_REVERSE, - get_ec_value_from_option("fn_ctrl_swap", - 0, - fn_ctrl_swap, - ARRAY_SIZE(fn_ctrl_swap), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("fn_ctrl_swap", 0, fn_ctrl_swap, + ARRAY_SIZE(fn_ctrl_swap), UINT_MAX, UINT_MAX)); /* * Maximum Charge Level @@ -150,20 +143,12 @@ static void merlin_init(struct device *dev) * Default: 100% * */ - const uint8_t max_charge[] = { - CHARGE_100, - CHARGE_80, - CHARGE_60 - }; + const uint8_t max_charge[] = {CHARGE_100, CHARGE_80, CHARGE_60}; if (CONFIG(EC_STARLABS_MAX_CHARGE)) ec_write(ECRAM_MAX_CHARGE, - get_ec_value_from_option("max_charge", - 0, - max_charge, - ARRAY_SIZE(max_charge), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("max_charge", 0, max_charge, + ARRAY_SIZE(max_charge), UINT_MAX, UINT_MAX)); /* * Fan Mode @@ -174,20 +159,12 @@ static void merlin_init(struct device *dev) * Default: Normal * */ - const uint8_t fan_mode[] = { - FAN_NORMAL, - FAN_AGGRESSIVE, - FAN_QUIET - }; + const uint8_t fan_mode[] = {FAN_NORMAL, FAN_AGGRESSIVE, FAN_QUIET}; if (CONFIG(EC_STARLABS_FAN)) ec_write(ECRAM_FAN_MODE, - get_ec_value_from_option("fan_mode", - 0, - fan_mode, - ARRAY_SIZE(fan_mode), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("fan_mode", 0, fan_mode, ARRAY_SIZE(fan_mode), + UINT_MAX, UINT_MAX)); /* * Function Lock @@ -199,18 +176,13 @@ static void merlin_init(struct device *dev) * */ #ifdef CMOS_VLEN_fn_lock_state - const uint8_t fn_lock_state[] = { - UNLOCKED, - LOCKED - }; + const uint8_t fn_lock_state[] = {UNLOCKED, LOCKED}; ec_write(ECRAM_FN_LOCK_STATE, - get_ec_value_from_option("fn_lock_state", - 1, - fn_lock_state, - ARRAY_SIZE(fn_lock_state), - CMOS_VSTART_fn_lock_state, - CMOS_VLEN_fn_lock_state)); + get_ec_value_from_option( + "fn_lock_state", 1, fn_lock_state, ARRAY_SIZE(fn_lock_state), + CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_fn_lock_state : UINT_MAX, + CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_fn_lock_state : UINT_MAX)); #endif /* @@ -223,18 +195,13 @@ static void merlin_init(struct device *dev) * */ #ifdef CMOS_VSTART_trackpad_state - const uint8_t trackpad_state[] = { - TRACKPAD_ENABLED, - TRACKPAD_DISABLED - }; + const uint8_t trackpad_state[] = {TRACKPAD_ENABLED, TRACKPAD_DISABLED}; ec_write(ECRAM_TRACKPAD_STATE, - get_ec_value_from_option("trackpad_state", - 0, - trackpad_state, - ARRAY_SIZE(trackpad_state), - CMOS_VSTART_trackpad_state, - CMOS_VLEN_trackpad_state)); + get_ec_value_from_option( + "trackpad_state", 0, trackpad_state, ARRAY_SIZE(trackpad_state), + CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_trackpad_state : UINT_MAX, + CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_trackpad_state : UINT_MAX)); #endif /* @@ -247,24 +214,20 @@ static void merlin_init(struct device *dev) * */ #ifdef CMOS_VSTART_kbl_brightness - const uint8_t kbl_brightness[] = { - KBL_ON, - KBL_OFF, - KBL_LOW, - KBL_HIGH - }; + const uint8_t kbl_brightness[] = {KBL_ON, KBL_OFF, KBL_LOW, KBL_HIGH}; ec_write(ECRAM_KBL_BRIGHTNESS, - get_ec_value_from_option("kbl_brightness", - CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0, - kbl_brightness, - ARRAY_SIZE(kbl_brightness), - CMOS_VSTART_kbl_brightness, - CMOS_VLEN_kbl_brightness)); + get_ec_value_from_option( + "kbl_brightness", + CONFIG(USE_OPTION_TABLE) ? + (CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0) : + (CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON), + kbl_brightness, ARRAY_SIZE(kbl_brightness), + CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_kbl_brightness : UINT_MAX, + CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_kbl_brightness : UINT_MAX)); #endif - /* * Keyboard Backlight State * @@ -281,9 +244,9 @@ static void merlin_init(struct device *dev) } static struct device_operations ops = { - .init = merlin_init, - .read_resources = noop_read_resources, - .set_resources = noop_set_resources, + .init = merlin_init, + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, }; static struct pnp_info pnp_dev_info[] = { @@ -299,7 +262,7 @@ static struct pnp_info pnp_dev_info[] = { { NULL, NUVOTON_PM1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, }, /* Power Management I/F Channel 2 (PMC2) */ { NULL, NUVOTON_PM2, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IRQ0, 0x07fc, - 0x07fc, 0xfff0, }, + 0x07fc, 0xfff0, }, /* Power Management I/F Channel 3 (PMC3) */ { NULL, NUVOTON_PM3, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, }, /* Extended Shared Memory (ESHM) */ From cfbf8f3953add1a1f6280e2e754682b517803c60 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Mon, 2 Mar 2026 10:21:41 +0000 Subject: [PATCH 698/789] starlabs: drop CMOS option tables Remove CMOS option tables and defaults from Star Labs boards now that EC state is persisted through EFI variable store options. Drop remaining Merlin EC CMOS plumbing (RTC reads and ACPI fields) and read settings only via the option backend. Signed-off-by: Sean Rhodes Change-Id: I3cc7f6240adc4b396912d566c7de176d4d2cb92b Reviewed-on: https://review.coreboot.org/c/coreboot/+/91305 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/ec/starlabs/merlin/acpi/cmos.asl | 17 --- src/ec/starlabs/merlin/acpi/ec.asl | 2 - src/ec/starlabs/merlin/acpi/suspend.asl | 116 ------------------ src/ec/starlabs/merlin/ite.c | 83 +++---------- src/ec/starlabs/merlin/nuvoton.c | 74 +++-------- src/mainboard/starlabs/adl/Kconfig | 2 - src/mainboard/starlabs/adl/cmos.default | 6 - .../starlabs/adl/variants/hz/cmos.layout | 46 ------- .../starlabs/adl/variants/i5/cmos.layout | 36 ------ .../starlabs/adl/variants/y2/cmos.layout | 36 ------ src/mainboard/starlabs/lite/Kconfig | 2 - src/mainboard/starlabs/lite/cmos.default | 6 - src/mainboard/starlabs/lite/cmos.layout | 43 ------- src/mainboard/starlabs/starbook/Kconfig | 2 - src/mainboard/starlabs/starbook/cmos.default | 6 - src/mainboard/starlabs/starbook/cmos.layout | 46 ------- src/mainboard/starlabs/starfighter/Kconfig | 2 - .../starlabs/starfighter/cmos.default | 6 - .../starlabs/starfighter/cmos.layout | 46 ------- 19 files changed, 32 insertions(+), 545 deletions(-) delete mode 100644 src/ec/starlabs/merlin/acpi/cmos.asl delete mode 100644 src/mainboard/starlabs/adl/cmos.default delete mode 100644 src/mainboard/starlabs/adl/variants/hz/cmos.layout delete mode 100644 src/mainboard/starlabs/adl/variants/i5/cmos.layout delete mode 100644 src/mainboard/starlabs/adl/variants/y2/cmos.layout delete mode 100644 src/mainboard/starlabs/lite/cmos.default delete mode 100644 src/mainboard/starlabs/lite/cmos.layout delete mode 100644 src/mainboard/starlabs/starbook/cmos.default delete mode 100644 src/mainboard/starlabs/starbook/cmos.layout delete mode 100644 src/mainboard/starlabs/starfighter/cmos.default delete mode 100644 src/mainboard/starlabs/starfighter/cmos.layout diff --git a/src/ec/starlabs/merlin/acpi/cmos.asl b/src/ec/starlabs/merlin/acpi/cmos.asl deleted file mode 100644 index 7ff0102b37..0000000000 --- a/src/ec/starlabs/merlin/acpi/cmos.asl +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -OperationRegion (CMS2, SystemIO, 0x72, 0x2) -Field (CMS2, ByteAcc, NoLock, Preserve) -{ - IND2, 8, - DAT2, 8, -} - -IndexField (IND2, DAT2, ByteAcc, NoLock, Preserve) -{ - Offset (0x80), - FLKC, 8, // Function Lock State - TPLC, 8, // Trackpad State - KLBC, 8, // Keyboard Backlight Brightness - KLSC, 8, // Keyboard Backlight State -} diff --git a/src/ec/starlabs/merlin/acpi/ec.asl b/src/ec/starlabs/merlin/acpi/ec.asl index ae5092772f..84113c343d 100644 --- a/src/ec/starlabs/merlin/acpi/ec.asl +++ b/src/ec/starlabs/merlin/acpi/ec.asl @@ -2,8 +2,6 @@ Scope (\_SB.PCI0.LPCB) { - #include "cmos.asl" - Device (EC) { Name (_HID, EisaId ("PNP0C09")) diff --git a/src/ec/starlabs/merlin/acpi/suspend.asl b/src/ec/starlabs/merlin/acpi/suspend.asl index 0ccce6f84b..9c280dba6f 100644 --- a/src/ec/starlabs/merlin/acpi/suspend.asl +++ b/src/ec/starlabs/merlin/acpi/suspend.asl @@ -69,66 +69,6 @@ Method (RPTS, 1, Serialized) EOSV (EOFL, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.FLKE))) EOSV (EOKS, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLSE))) EOSV (EOKB, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLBE))) -#else - /* Store current EC settings in CMOS */ - Switch (ToInteger (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.TPLE)))) - { - // 0x00 == Enabled == 0x00 - // 0x11 == Re-enabled == 0x00 - // 0x22 == Disabled == 0x01 - Case (0x00) - { - Store (0x00, \_SB.PCI0.LPCB.TPLC) - } - Case (0x11) - { - Store (0x00, \_SB.PCI0.LPCB.TPLC) - } - Case (0x22) - { - Store (0x01, \_SB.PCI0.LPCB.TPLC) - } - } - - Store (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.FLKE)), \_SB.PCI0.LPCB.FLKC) - - Switch (ToInteger (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLSE)))) - { - // 0x00 == Disabled == 0x00 - // 0xdd == Enabled == 0x01 - Case (0x00) - { - Store (0x00, \_SB.PCI0.LPCB.KLSC) - } - Case (0xdd) - { - Store (0x01, \_SB.PCI0.LPCB.KLSC) - } - } - - Switch (ToInteger (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLBE)))) - { - // 0xdd == On == 0x00 - // 0xcc == Off == 0x01 - // 0xbb == Low == 0x02 - // 0xaa == High == 0x03 - Case (0xdd) - { - Store (0x00, \_SB.PCI0.LPCB.KLBC) - } - Case (0xcc) - { - Store (0x01, \_SB.PCI0.LPCB.KLBC) - } - Case (0xbb) - { - Store (0x02, \_SB.PCI0.LPCB.KLBC) - } - Case (0xaa) - { - Store (0x03, \_SB.PCI0.LPCB.KLBC) - } - } #endif /* @@ -192,62 +132,6 @@ Method (RWAK, 1, Serialized) \_SB.PCI0.LPCB.EC.ECWR (0xaa, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) } } -#else - /* Restore EC settings from CMOS */ - Switch (ToInteger (\_SB.PCI0.LPCB.TPLC)) - { - // 0x00 == Enabled == 0x00 - // 0x00 == Re-enabled == 0x11 - // 0x01 == Disabled == 0x22 - Case (0x00) - { - \_SB.PCI0.LPCB.EC.ECWR (0x00, RefOf(\_SB.PCI0.LPCB.EC.TPLE)) - } - Case (0x01) - { - \_SB.PCI0.LPCB.EC.ECWR (0x22, RefOf(\_SB.PCI0.LPCB.EC.TPLE)) - } - } - - \_SB.PCI0.LPCB.EC.ECWR (\_SB.PCI0.LPCB.FLKC, RefOf(\_SB.PCI0.LPCB.EC.FLKE)) - - Switch (ToInteger (\_SB.PCI0.LPCB.KLSC)) - { - // 0x00 == Disabled == 0x00 - // 0x01 == Enabled == 0xdd - Case (0x00) - { - \_SB.PCI0.LPCB.EC.ECWR (0x00, RefOf(\_SB.PCI0.LPCB.EC.KLSE)) - } - Case (0x01) - { - \_SB.PCI0.LPCB.EC.ECWR (0xdd, RefOf(\_SB.PCI0.LPCB.EC.KLSE)) - } - } - - Switch (ToInteger (\_SB.PCI0.LPCB.KLBC)) - { - // 0x00 == On == 0xdd - // 0x01 == Off == 0xcc - // 0x02 == Low == 0xbb - // 0x03 == High == 0xaa - Case (0x00) - { - \_SB.PCI0.LPCB.EC.ECWR (0xdd, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) - } - Case (0x01) - { - \_SB.PCI0.LPCB.EC.ECWR (0xcc, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) - } - Case (0x02) - { - \_SB.PCI0.LPCB.EC.ECWR (0xbb, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) - } - Case (0x03) - { - \_SB.PCI0.LPCB.EC.ECWR (0xaa, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) - } - } #endif Return (Arg0) diff --git a/src/ec/starlabs/merlin/ite.c b/src/ec/starlabs/merlin/ite.c index 4240d7dbef..a3369700c3 100644 --- a/src/ec/starlabs/merlin/ite.c +++ b/src/ec/starlabs/merlin/ite.c @@ -5,11 +5,9 @@ #include #include #include -#include #include #include "ecdefs.h" -#include "option_table.h" #include "ec.h" #define ITE_IT5570 0x5570 @@ -20,40 +18,9 @@ uint16_t ec_get_version(void) return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION); } -static uint8_t get_cmos_value(uint32_t bit, uint32_t length) +static uint8_t get_ec_value_from_option(const char *name, uint8_t fallback, const uint8_t *lut, + size_t lut_size) { - uint32_t byte, byte_bit; - uint8_t uchar; - - byte = bit / 8; // find the byte where the data starts - byte_bit = bit % 8; // find the bit in the byte where the data starts - - uchar = cmos_read(byte); // load the byte - uchar >>= byte_bit; // shift the bits to byte align - // clear unspecified bits - return uchar & ((1U << length) - 1); -} - -static uint8_t get_ec_value_from_option(const char *name, uint32_t fallback, const uint8_t *lut, - size_t lut_size, uint32_t cmos_start_bit, - uint32_t cmos_length) -{ - /* - * CMOS-backed EC options store an index (see cmos.layout and ACPI - * RPTS/RWAK mappings), while the option backend stores the EC's raw - * values (e.g. 0xaa/0xbb/0xdd). - */ - if (cmos_start_bit != UINT_MAX) { - unsigned int index = get_cmos_value(cmos_start_bit, cmos_length); - - if (index >= lut_size) - index = fallback; - if (index >= lut_size) - index = 0; - - return lut[index]; - } - const uint8_t value = get_uint_option(name, fallback); /* Check if the value exists in the LUT array */ @@ -94,7 +61,7 @@ static void merlin_init(struct device *dev) } /* - * Restore settings from CMOS into EC RAM: + * Restore settings from options into EC RAM: * * kbl_timeout * fn_ctrl_swap @@ -122,7 +89,7 @@ static void merlin_init(struct device *dev) ec_write(ECRAM_KBL_TIMEOUT, get_ec_value_from_option("kbl_timeout", SEC_30, kbl_timeout, - ARRAY_SIZE(kbl_timeout), UINT_MAX, UINT_MAX)); + ARRAY_SIZE(kbl_timeout))); /* * Fn Ctrl Reverse @@ -137,7 +104,7 @@ static void merlin_init(struct device *dev) ec_write(ECRAM_FN_CTRL_REVERSE, get_ec_value_from_option("fn_ctrl_swap", FN_CTRL, fn_ctrl_swap, - ARRAY_SIZE(fn_ctrl_swap), UINT_MAX, UINT_MAX)); + ARRAY_SIZE(fn_ctrl_swap))); /* * Maximum Charge Level @@ -153,7 +120,7 @@ static void merlin_init(struct device *dev) if (CONFIG(EC_STARLABS_MAX_CHARGE)) ec_write(ECRAM_MAX_CHARGE, get_ec_value_from_option("max_charge", CHARGE_100, max_charge, - ARRAY_SIZE(max_charge), UINT_MAX, UINT_MAX)); + ARRAY_SIZE(max_charge))); /* * Fan Mode @@ -169,7 +136,7 @@ static void merlin_init(struct device *dev) if (CONFIG(EC_STARLABS_FAN)) ec_write(ECRAM_FAN_MODE, get_ec_value_from_option("fan_mode", FAN_NORMAL, fan_mode, - ARRAY_SIZE(fan_mode), UINT_MAX, UINT_MAX)); + ARRAY_SIZE(fan_mode))); /* * Function Lock @@ -180,15 +147,11 @@ static void merlin_init(struct device *dev) * Default: Locked * */ -#ifdef CMOS_VLEN_fn_lock_state const uint8_t fn_lock_state[] = {UNLOCKED, LOCKED}; ec_write(ECRAM_FN_LOCK_STATE, get_ec_value_from_option( - "fn_lock_state", UNLOCKED, fn_lock_state, ARRAY_SIZE(fn_lock_state), - CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_fn_lock_state : UINT_MAX, - CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_fn_lock_state : UINT_MAX)); -#endif + "fn_lock_state", UNLOCKED, fn_lock_state, ARRAY_SIZE(fn_lock_state))); /* * Trackpad State @@ -199,16 +162,12 @@ static void merlin_init(struct device *dev) * Default: Enabled * */ -#ifdef CMOS_VSTART_trackpad_state const uint8_t trackpad_state[] = {TRACKPAD_ENABLED, TRACKPAD_DISABLED}; ec_write(ECRAM_TRACKPAD_STATE, get_ec_value_from_option( "trackpad_state", TRACKPAD_ENABLED, trackpad_state, - ARRAY_SIZE(trackpad_state), - CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_trackpad_state : UINT_MAX, - CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_trackpad_state : UINT_MAX)); -#endif + ARRAY_SIZE(trackpad_state))); /* * Keyboard Backlight Brightness @@ -219,19 +178,16 @@ static void merlin_init(struct device *dev) * Default: Low * */ -#ifdef CMOS_VSTART_kbl_brightness const uint8_t kbl_brightness[] = {KBL_ON, KBL_OFF, KBL_LOW, KBL_HIGH}; + const uint8_t kbl_brightness_fallback = + CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON; + ec_write(ECRAM_KBL_BRIGHTNESS, get_ec_value_from_option( "kbl_brightness", - CONFIG(USE_OPTION_TABLE) ? - (CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0) : - (CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON), - kbl_brightness, ARRAY_SIZE(kbl_brightness), - CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_kbl_brightness : UINT_MAX, - CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_kbl_brightness : UINT_MAX)); -#endif + kbl_brightness_fallback, + kbl_brightness, ARRAY_SIZE(kbl_brightness))); /* * Keyboard Backlight State @@ -261,8 +217,7 @@ static void merlin_init(struct device *dev) if (CONFIG(EC_STARLABS_CHARGING_SPEED)) ec_write(ECRAM_CHARGING_SPEED, get_ec_value_from_option("charging_speed", SPEED_0_5C, charging_speed, - ARRAY_SIZE(charging_speed), UINT_MAX, - UINT_MAX)); + ARRAY_SIZE(charging_speed))); /* * Lid Switch @@ -278,7 +233,7 @@ static void merlin_init(struct device *dev) if (CONFIG(EC_STARLABS_LID_SWITCH)) ec_write(ECRAM_LID_SWITCH, get_ec_value_from_option("lid_switch", SWITCH_NORMAL, lid_switch, - ARRAY_SIZE(lid_switch), UINT_MAX, UINT_MAX)); + ARRAY_SIZE(lid_switch))); /* * Power LED Brightness @@ -294,8 +249,7 @@ static void merlin_init(struct device *dev) if (CONFIG(EC_STARLABS_POWER_LED)) ec_write(ECRAM_POWER_LED, get_ec_value_from_option("power_led", LED_NORMAL, led_brightness, - ARRAY_SIZE(led_brightness), UINT_MAX, - UINT_MAX)); + ARRAY_SIZE(led_brightness))); /* * Charge LED Brightness @@ -310,8 +264,7 @@ static void merlin_init(struct device *dev) if (CONFIG(EC_STARLABS_CHARGE_LED)) ec_write(ECRAM_CHARGE_LED, get_ec_value_from_option("charge_led", LED_NORMAL, led_brightness, - ARRAY_SIZE(led_brightness), UINT_MAX, - UINT_MAX)); + ARRAY_SIZE(led_brightness))); } static struct device_operations ops = { diff --git a/src/ec/starlabs/merlin/nuvoton.c b/src/ec/starlabs/merlin/nuvoton.c index 36212f63c4..398b12619b 100644 --- a/src/ec/starlabs/merlin/nuvoton.c +++ b/src/ec/starlabs/merlin/nuvoton.c @@ -5,11 +5,9 @@ #include #include #include -#include #include #include "ecdefs.h" -#include "option_table.h" #include "ec.h" uint16_t ec_get_version(void) @@ -17,40 +15,9 @@ uint16_t ec_get_version(void) return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION); } -static uint8_t get_cmos_value(uint32_t bit, uint32_t length) +static uint8_t get_ec_value_from_option(const char *name, uint8_t fallback, const uint8_t *lut, + size_t lut_size) { - uint32_t byte, byte_bit; - uint8_t uchar; - - byte = bit / 8; // find the byte where the data starts - byte_bit = bit % 8; // find the bit in the byte where the data starts - - uchar = cmos_read(byte); // load the byte - uchar >>= byte_bit; // shift the bits to byte align - // clear unspecified bits - return uchar & ((1U << length) - 1); -} - -static uint8_t get_ec_value_from_option(const char *name, uint32_t fallback, const uint8_t *lut, - size_t lut_size, uint32_t cmos_start_bit, - uint32_t cmos_length) -{ - /* - * CMOS-backed EC options store an index (see cmos.layout and ACPI - * RPTS/RWAK mappings), while the option backend stores the EC's raw - * values (e.g. 0xaa/0xbb/0xdd). - */ - if (cmos_start_bit != UINT_MAX) { - unsigned int index = get_cmos_value(cmos_start_bit, cmos_length); - - if (index >= lut_size) - index = fallback; - if (index >= lut_size) - index = 0; - - return lut[index]; - } - const uint8_t value = get_uint_option(name, fallback); /* Check if the value exists in the LUT array */ @@ -92,7 +59,7 @@ static void merlin_init(struct device *dev) } /* - * Restore settings from CMOS into EC RAM: + * Restore settings from options into EC RAM: * * kbl_timeout * fn_ctrl_swap @@ -117,7 +84,7 @@ static void merlin_init(struct device *dev) ec_write(ECRAM_KBL_TIMEOUT, get_ec_value_from_option("kbl_timeout", 0, kbl_timeout, - ARRAY_SIZE(kbl_timeout), UINT_MAX, UINT_MAX)); + ARRAY_SIZE(kbl_timeout))); /* * Fn Ctrl Reverse @@ -132,7 +99,7 @@ static void merlin_init(struct device *dev) ec_write(ECRAM_FN_CTRL_REVERSE, get_ec_value_from_option("fn_ctrl_swap", 0, fn_ctrl_swap, - ARRAY_SIZE(fn_ctrl_swap), UINT_MAX, UINT_MAX)); + ARRAY_SIZE(fn_ctrl_swap))); /* * Maximum Charge Level @@ -148,7 +115,7 @@ static void merlin_init(struct device *dev) if (CONFIG(EC_STARLABS_MAX_CHARGE)) ec_write(ECRAM_MAX_CHARGE, get_ec_value_from_option("max_charge", 0, max_charge, - ARRAY_SIZE(max_charge), UINT_MAX, UINT_MAX)); + ARRAY_SIZE(max_charge))); /* * Fan Mode @@ -163,8 +130,7 @@ static void merlin_init(struct device *dev) if (CONFIG(EC_STARLABS_FAN)) ec_write(ECRAM_FAN_MODE, - get_ec_value_from_option("fan_mode", 0, fan_mode, ARRAY_SIZE(fan_mode), - UINT_MAX, UINT_MAX)); + get_ec_value_from_option("fan_mode", 0, fan_mode, ARRAY_SIZE(fan_mode))); /* * Function Lock @@ -175,15 +141,11 @@ static void merlin_init(struct device *dev) * Default: Locked * */ -#ifdef CMOS_VLEN_fn_lock_state const uint8_t fn_lock_state[] = {UNLOCKED, LOCKED}; ec_write(ECRAM_FN_LOCK_STATE, get_ec_value_from_option( - "fn_lock_state", 1, fn_lock_state, ARRAY_SIZE(fn_lock_state), - CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_fn_lock_state : UINT_MAX, - CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_fn_lock_state : UINT_MAX)); -#endif + "fn_lock_state", 1, fn_lock_state, ARRAY_SIZE(fn_lock_state))); /* * Trackpad State @@ -194,15 +156,11 @@ static void merlin_init(struct device *dev) * Default: Enabled * */ -#ifdef CMOS_VSTART_trackpad_state const uint8_t trackpad_state[] = {TRACKPAD_ENABLED, TRACKPAD_DISABLED}; ec_write(ECRAM_TRACKPAD_STATE, get_ec_value_from_option( - "trackpad_state", 0, trackpad_state, ARRAY_SIZE(trackpad_state), - CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_trackpad_state : UINT_MAX, - CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_trackpad_state : UINT_MAX)); -#endif + "trackpad_state", 0, trackpad_state, ARRAY_SIZE(trackpad_state))); /* * Keyboard Backlight Brightness @@ -213,20 +171,16 @@ static void merlin_init(struct device *dev) * Default: Low * */ -#ifdef CMOS_VSTART_kbl_brightness const uint8_t kbl_brightness[] = {KBL_ON, KBL_OFF, KBL_LOW, KBL_HIGH}; + const uint8_t kbl_brightness_fallback = + CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON; + ec_write(ECRAM_KBL_BRIGHTNESS, get_ec_value_from_option( "kbl_brightness", - CONFIG(USE_OPTION_TABLE) ? - (CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0) : - (CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON), - kbl_brightness, ARRAY_SIZE(kbl_brightness), - CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_kbl_brightness : UINT_MAX, - CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_kbl_brightness : UINT_MAX)); - -#endif + kbl_brightness_fallback, + kbl_brightness, ARRAY_SIZE(kbl_brightness))); /* * Keyboard Backlight State diff --git a/src/mainboard/starlabs/adl/Kconfig b/src/mainboard/starlabs/adl/Kconfig index 50d56bfa98..b39f9c914d 100644 --- a/src/mainboard/starlabs/adl/Kconfig +++ b/src/mainboard/starlabs/adl/Kconfig @@ -9,7 +9,6 @@ config BOARD_STARLABS_ADL_SERIES select EC_STARLABS_MERLIN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES - select HAVE_OPTION_TABLE select INTEL_GMA_HAVE_VBT select INTEL_LPSS_UART_FOR_CONSOLE select NO_UART_ON_SUPERIO @@ -27,7 +26,6 @@ config BOARD_STARLABS_ADL_HORIZON select BOARD_STARLABS_ADL_SERIES select DRIVERS_GFX_GENERIC select DRIVERS_I2C_HID - select HAVE_CMOS_DEFAULT select HAVE_HDA_DMIC select HAVE_SPD_IN_CBFS select MAINBOARD_HAS_TPM2 diff --git a/src/mainboard/starlabs/adl/cmos.default b/src/mainboard/starlabs/adl/cmos.default deleted file mode 100644 index 49faae3e6a..0000000000 --- a/src/mainboard/starlabs/adl/cmos.default +++ /dev/null @@ -1,6 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only -# Functions -fn_lock_state=0x1 -trackpad_state=0x1 -kbl_brightness=0x0 -kbl_state=0x1 diff --git a/src/mainboard/starlabs/adl/variants/hz/cmos.layout b/src/mainboard/starlabs/adl/variants/hz/cmos.layout deleted file mode 100644 index ebba7fbd5d..0000000000 --- a/src/mainboard/starlabs/adl/variants/hz/cmos.layout +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# coreboot config options: ramtop -304 80 h 0 ramtop - -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -1024 8 h 1 fn_lock_state -1032 8 h 1 trackpad_state -1040 8 h 2 kbl_brightness -1048 8 h 1 kbl_state - -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -2 0 Off -2 1 Low -2 2 High -2 3 On - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 diff --git a/src/mainboard/starlabs/adl/variants/i5/cmos.layout b/src/mainboard/starlabs/adl/variants/i5/cmos.layout deleted file mode 100644 index f78701f5d6..0000000000 --- a/src/mainboard/starlabs/adl/variants/i5/cmos.layout +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# coreboot config options: ramtop -304 80 h 0 ramtop - -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 diff --git a/src/mainboard/starlabs/adl/variants/y2/cmos.layout b/src/mainboard/starlabs/adl/variants/y2/cmos.layout deleted file mode 100644 index f78701f5d6..0000000000 --- a/src/mainboard/starlabs/adl/variants/y2/cmos.layout +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# coreboot config options: ramtop -304 80 h 0 ramtop - -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 diff --git a/src/mainboard/starlabs/lite/Kconfig b/src/mainboard/starlabs/lite/Kconfig index 1b03c054b2..a9fcd13ed7 100644 --- a/src/mainboard/starlabs/lite/Kconfig +++ b/src/mainboard/starlabs/lite/Kconfig @@ -9,8 +9,6 @@ config BOARD_STARLABS_LITE_SERIES select DRIVERS_I2C_HID select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES - select HAVE_CMOS_DEFAULT - select HAVE_OPTION_TABLE select HAVE_INTEL_PTT select INTEL_GMA_HAVE_VBT select INTEL_LPSS_UART_FOR_CONSOLE diff --git a/src/mainboard/starlabs/lite/cmos.default b/src/mainboard/starlabs/lite/cmos.default deleted file mode 100644 index 49faae3e6a..0000000000 --- a/src/mainboard/starlabs/lite/cmos.default +++ /dev/null @@ -1,6 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only -# Functions -fn_lock_state=0x1 -trackpad_state=0x1 -kbl_brightness=0x0 -kbl_state=0x1 diff --git a/src/mainboard/starlabs/lite/cmos.layout b/src/mainboard/starlabs/lite/cmos.layout deleted file mode 100644 index 3057effc83..0000000000 --- a/src/mainboard/starlabs/lite/cmos.layout +++ /dev/null @@ -1,43 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -1024 8 h 1 fn_lock_state -1032 8 h 1 trackpad_state -1040 8 h 2 kbl_brightness -1048 8 h 1 kbl_state - -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -2 0 Off -2 1 Low -2 2 High -2 3 On - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 diff --git a/src/mainboard/starlabs/starbook/Kconfig b/src/mainboard/starlabs/starbook/Kconfig index cb9bccd3a4..7dee1e3ecf 100644 --- a/src/mainboard/starlabs/starbook/Kconfig +++ b/src/mainboard/starlabs/starbook/Kconfig @@ -10,9 +10,7 @@ config BOARD_STARLABS_STARBOOK_SERIES select EC_STARLABS_FAN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES - select HAVE_CMOS_DEFAULT select HAVE_HDA_DMIC - select HAVE_OPTION_TABLE select INTEL_GMA_HAVE_VBT select INTEL_LPSS_UART_FOR_CONSOLE select NO_UART_ON_SUPERIO diff --git a/src/mainboard/starlabs/starbook/cmos.default b/src/mainboard/starlabs/starbook/cmos.default deleted file mode 100644 index 49faae3e6a..0000000000 --- a/src/mainboard/starlabs/starbook/cmos.default +++ /dev/null @@ -1,6 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only -# Functions -fn_lock_state=0x1 -trackpad_state=0x1 -kbl_brightness=0x0 -kbl_state=0x1 diff --git a/src/mainboard/starlabs/starbook/cmos.layout b/src/mainboard/starlabs/starbook/cmos.layout deleted file mode 100644 index ebba7fbd5d..0000000000 --- a/src/mainboard/starlabs/starbook/cmos.layout +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# coreboot config options: ramtop -304 80 h 0 ramtop - -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -1024 8 h 1 fn_lock_state -1032 8 h 1 trackpad_state -1040 8 h 2 kbl_brightness -1048 8 h 1 kbl_state - -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -2 0 Off -2 1 Low -2 2 High -2 3 On - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 diff --git a/src/mainboard/starlabs/starfighter/Kconfig b/src/mainboard/starlabs/starfighter/Kconfig index f32a9a8153..07a810ec63 100644 --- a/src/mainboard/starlabs/starfighter/Kconfig +++ b/src/mainboard/starlabs/starfighter/Kconfig @@ -15,9 +15,7 @@ config BOARD_STARLABS_STARFIGHTER_SERIES select EC_STARLABS_MERLIN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES - select HAVE_CMOS_DEFAULT select HAVE_HDA_DMIC - select HAVE_OPTION_TABLE select HAVE_SPD_IN_CBFS select INTEL_GMA_HAVE_VBT select INTEL_LPSS_UART_FOR_CONSOLE diff --git a/src/mainboard/starlabs/starfighter/cmos.default b/src/mainboard/starlabs/starfighter/cmos.default deleted file mode 100644 index 49faae3e6a..0000000000 --- a/src/mainboard/starlabs/starfighter/cmos.default +++ /dev/null @@ -1,6 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only -# Functions -fn_lock_state=0x1 -trackpad_state=0x1 -kbl_brightness=0x0 -kbl_state=0x1 diff --git a/src/mainboard/starlabs/starfighter/cmos.layout b/src/mainboard/starlabs/starfighter/cmos.layout deleted file mode 100644 index ebba7fbd5d..0000000000 --- a/src/mainboard/starlabs/starfighter/cmos.layout +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# coreboot config options: ramtop -304 80 h 0 ramtop - -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -1024 8 h 1 fn_lock_state -1032 8 h 1 trackpad_state -1040 8 h 2 kbl_brightness -1048 8 h 1 kbl_state - -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -2 0 Off -2 1 Low -2 2 High -2 3 On - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 From 0306eb07234858ce1d6be9b4a1ac58a7d44b582d Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Wed, 28 Jan 2026 12:10:00 +0000 Subject: [PATCH 699/789] mb/starlabs/common: add NVMe power sequencing helper Add a shared helper (behind Kconfig) that owns the ramstage bootstate ordering for the Star Labs NVMe/M.2 slot power sequence (PWREN, PERST#, CLKREQ#). Boards/variants provide pad configs for stage 2 and stage 3 either by implementing the `variant_nvme_power_sequence_*()` helpers or by providing pad tables via `variant_nvme_power_sequence_pads()` and `variant_nvme_power_sequence_post_pads()`. Signed-off-by: Sean Rhodes Change-Id: I3d518c35c26f3d3ee1dd72b4a35861d19cdb85ab Reviewed-on: https://review.coreboot.org/c/coreboot/+/90973 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/common/Kconfig | 21 +++++++ src/mainboard/starlabs/common/Makefile.mk | 2 + .../starlabs/common/include/common/nvme_seq.h | 15 +++++ src/mainboard/starlabs/common/nvme_seq.c | 62 +++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 src/mainboard/starlabs/common/include/common/nvme_seq.h create mode 100644 src/mainboard/starlabs/common/nvme_seq.c diff --git a/src/mainboard/starlabs/common/Kconfig b/src/mainboard/starlabs/common/Kconfig index 8a670142c0..5501d43efe 100644 --- a/src/mainboard/starlabs/common/Kconfig +++ b/src/mainboard/starlabs/common/Kconfig @@ -13,6 +13,27 @@ config BOOTMEDIA_SMM_BWP_RUNTIME_OPTION config DRIVERS_EFI_FW_INFO def_bool y +config STARLABS_NVME_POWER_SEQUENCE + bool "Enable NVMe/M.2 slot power sequence" + depends on SOC_INTEL_COMMON_BLOCK_GPIO + default n + help + Enable Fatcat-style 3-stage NVMe/M.2 slot sequencing using PWREN, PERST# + and CLKREQ# pads. + + The sequencing is: + 1) pre-mem: PERST# asserted; PWREN=0; CLKREQ# disabled + 2) BS_PRE_DEVICE exit: PERST# still asserted; PWREN=1; CLKREQ# native + 3) BS_DEV_INIT_CHIPS entry: PERST# deasserted + + Boards selecting this option must provide their own pad configs and + implement stage 1 (pre-mem) in their early pad configuration. + + For stage 2 and stage 3, boards must either implement the + `variant_nvme_power_sequence_*()` helpers or provide pad tables via + `variant_nvme_power_sequence_pads()` and + `variant_nvme_power_sequence_post_pads()`. + config MB_COMMON_DIR string default "starlabs/common" diff --git a/src/mainboard/starlabs/common/Makefile.mk b/src/mainboard/starlabs/common/Makefile.mk index b12b7610d3..6887c47a7d 100644 --- a/src/mainboard/starlabs/common/Makefile.mk +++ b/src/mainboard/starlabs/common/Makefile.mk @@ -6,6 +6,8 @@ subdirs-$(CONFIG_VENDOR_STARLABS) += powercap subdirs-$(CONFIG_VENDOR_STARLABS) += pin_mux subdirs-$(CONFIG_VENDOR_STARLABS) += smbios +ramstage-$(CONFIG_STARLABS_NVME_POWER_SEQUENCE) += nvme_seq.c + CPPFLAGS_common += -I$(src)/mainboard/starlabs/common/include ramstage-$(CONFIG_STARLABS_ACPI_EFI_OPTION_SMI) += gnvs.c diff --git a/src/mainboard/starlabs/common/include/common/nvme_seq.h b/src/mainboard/starlabs/common/include/common/nvme_seq.h new file mode 100644 index 0000000000..fcd1838045 --- /dev/null +++ b/src/mainboard/starlabs/common/include/common/nvme_seq.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _STARLABS_CMN_NVME_SEQ_H_ +#define _STARLABS_CMN_NVME_SEQ_H_ + +#include +#include + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num); +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num); + +void variant_nvme_power_sequence_configure(void); +void variant_nvme_power_sequence_post_gpio_configure(void); + +#endif /* _STARLABS_CMN_NVME_SEQ_H_ */ diff --git a/src/mainboard/starlabs/common/nvme_seq.c b/src/mainboard/starlabs/common/nvme_seq.c new file mode 100644 index 0000000000..5fef80865a --- /dev/null +++ b/src/mainboard/starlabs/common/nvme_seq.c @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +#if ENV_RAMSTAGE +const __weak struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = 0; + return NULL; +} + +const __weak struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = 0; + return NULL; +} + +__weak void variant_nvme_power_sequence_configure(void) +{ + size_t num; + const struct pad_config *pads = variant_nvme_power_sequence_pads(&num); + + if (pads && num) + gpio_configure_pads(pads, num); +} + +__weak void variant_nvme_power_sequence_post_gpio_configure(void) +{ + size_t num; + const struct pad_config *pads = variant_nvme_power_sequence_post_pads(&num); + + if (pads && num) + gpio_configure_pads(pads, num); +} +#endif + +/* + * Star Labs NVMe/M.2 slot power sequence glue. + * + * Boards/variants provide the actual pad configs (PWREN, PERST#, CLKREQ#). + * + * This file only owns the ramstage ordering so the staged overrides happen + * before PCIe enumeration/link training. + */ + +static void starlabs_nvme_power_sequence_step2(void *unused) +{ + /* Stage 2: power on + enable CLKREQ#, keep PERST# asserted. */ + variant_nvme_power_sequence_configure(); +} + +static void starlabs_nvme_power_sequence_step3(void *unused) +{ + /* Stage 3: deassert PERST# after GPIO configuration, before device init. */ + variant_nvme_power_sequence_post_gpio_configure(); +} + +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_EXIT, starlabs_nvme_power_sequence_step2, NULL); +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_ENTRY, starlabs_nvme_power_sequence_step3, NULL); From 279406cd14d9764b54084f8deba8cadc81093589 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Wed, 28 Jan 2026 11:16:01 +0000 Subject: [PATCH 700/789] mb/starlabs/starfighter: Add NVMe port power sequence Implement Fatcat-style 3-stage M.2 NVMe slot sequencing (PWREN, PERST#, CLKREQ#) for StarFighter and apply it to all NVMe-capable ports (both Gen3 and Gen4). This addresses intermittent NVMe detection problems on cold/warm boot and improves PCIe link speed negotiation by ensuring the device is held in reset with clocks gated until slot power is enabled and coreboot is about to initialize devices. Sequence per NVMe port: 1) pre-mem: disable CLKREQ#, assert PERST#, PWREN=0 2) BS_PRE_DEVICE exit: PWREN=1, enable CLKREQ# native, keep PERST# asserted 3) BS_DEV_INIT_CHIPS entry: deassert PERST# Also update the variant gpio_table defaults so PWREN stays off and CLKREQ# stays disconnected until the sequencing code enables them. Signed-off-by: Sean Rhodes Change-Id: Ic34e9e755e167e301348fbe7c75649401300f53b Reviewed-on: https://review.coreboot.org/c/coreboot/+/90974 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/starfighter/Kconfig | 1 + .../starlabs/starfighter/mainboard.c | 9 +-- .../starlabs/starfighter/variants/mtl/gpio.c | 65 +++++++++++++++--- .../starlabs/starfighter/variants/rpl/gpio.c | 67 ++++++++++++++++--- 4 files changed, 120 insertions(+), 22 deletions(-) diff --git a/src/mainboard/starlabs/starfighter/Kconfig b/src/mainboard/starlabs/starfighter/Kconfig index 07a810ec63..b7795cc6aa 100644 --- a/src/mainboard/starlabs/starfighter/Kconfig +++ b/src/mainboard/starlabs/starfighter/Kconfig @@ -32,6 +32,7 @@ config BOARD_STARLABS_STARFIGHTER_SERIES select SYSTEM_TYPE_LAPTOP select TPM_MEASURED_BOOT select VALIDATE_INTEL_DESCRIPTOR + select STARLABS_NVME_POWER_SEQUENCE config BOARD_STARLABS_STARFIGHTER_RPL select BOARD_STARLABS_STARFIGHTER_SERIES diff --git a/src/mainboard/starlabs/starfighter/mainboard.c b/src/mainboard/starlabs/starfighter/mainboard.c index cd46529c0f..e0b6ffae49 100644 --- a/src/mainboard/starlabs/starfighter/mainboard.c +++ b/src/mainboard/starlabs/starfighter/mainboard.c @@ -1,10 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include -static void init_mainboard(void *chip_info) +static void starlabs_configure_gpios(void *unused) { const struct pad_config *pads; size_t num; @@ -13,6 +14,6 @@ static void init_mainboard(void *chip_info) gpio_configure_pads(pads, num); } -struct chip_operations mainboard_ops = { - .init = init_mainboard, -}; +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, starlabs_configure_gpios, NULL); + +struct chip_operations mainboard_ops = {}; diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c b/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c index 63d8218f80..32e7a5f6bc 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c +++ b/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c @@ -1,8 +1,42 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_H07, 1, DEEP), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D20, NONE, PLTRST, NF1), + PAD_CFG_GPO(GPP_A20, 0, PLTRST), + PAD_CFG_GPO(GPP_D22, 1, DEEP), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C10, NONE, PLTRST, NF1), + PAD_CFG_GPO(GPP_H00, 0, PLTRST), + PAD_CFG_GPO(GPP_B19, 1, DEEP), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D21, NONE, PLTRST, NF2), + PAD_CFG_GPO(GPP_H02, 0, PLTRST), +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_A20, 1, PLTRST), + PAD_CFG_GPO(GPP_H00, 1, PLTRST), + PAD_CFG_GPO(GPP_H02, 1, PLTRST), +}; + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), /* RXD */ @@ -17,7 +51,18 @@ const struct pad_config early_gpio_table[] = { PAD_CFG_GPI_LOCK(GPP_B06, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_B07, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_B08, NONE, LOCK_CONFIG), + + PAD_CFG_GPI(GPP_D20, NONE, PLTRST), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_H07, 0, DEEP), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_C10, NONE, PLTRST), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H00, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D22, 0, DEEP), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_D21, NONE, PLTRST), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_B19, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -26,6 +71,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_V00, NONE, DEEP, NF1), /* Battery Low */ @@ -50,19 +96,19 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC(GPP_B00, NONE, DEEP, LEVEL, INVERT), /* Interrupt */ /* SSD (CPU)*/ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D20, NONE, PLTRST, NF1), /* Clock Request 8 */ - PAD_CFG_GPO(GPP_A20, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_H07, 1, DEEP), /* Enable */ + PAD_NC(GPP_D20, NONE), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_H07, 0, DEEP), /* Enable (PWREN off) */ /* SSD (PCH) */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C10, NONE, PLTRST, NF1), /* Clock Request 1 */ - PAD_CFG_GPO(GPP_H00, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D22, 1, DEEP), /* Enable */ + PAD_NC(GPP_C10, NONE), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H00, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D22, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D21, NONE, PLTRST, NF2), /* Clock Request 5 */ - PAD_CFG_GPO(GPP_H02, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_B19, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D21, NONE), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_B19, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_B18, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -252,6 +298,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_D19, NONE), PAD_NC(GPP_D23, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c b/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c index d58121e83a..d1b7f60df6 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c +++ b/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c @@ -1,8 +1,44 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D14, 1, DEEP), + PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_F20, 0, PLTRST), + PAD_CFG_GPO(GPP_D16, 1, PLTRST), + PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_H0, 0, PLTRST), + PAD_CFG_GPO(GPP_E3, 1, DEEP), + PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_H2, 0, PLTRST), +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_F20, 1, PLTRST), + PAD_CFG_GPO(GPP_H0, 1, PLTRST), + PAD_CFG_GPO(GPP_H2, 1, PLTRST), +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ @@ -13,7 +49,18 @@ const struct pad_config early_gpio_table[] = { PAD_CFG_GPI_LOCK(GPP_F13, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_F14, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_F15, NONE, LOCK_CONFIG), + + PAD_CFG_GPI(GPP_D6, NONE, DEEP), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D14, 0, DEEP), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_H19, NONE, DEEP), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_D7, NONE, DEEP), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -22,6 +69,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -46,19 +94,19 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC_LOW(GPP_D11, NONE, PLTRST), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 5 */ - PAD_CFG_GPO(GPP_F20, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D14, 1, DEEP), /* Enable */ + PAD_NC(GPP_D6, NONE), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D14, 0, DEEP), /* Enable (PWREN off) */ /* SSD 2 */ - PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), /* Clock Request 2 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, PLTRST), /* Enable */ + PAD_NC(GPP_H19, NONE), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 1 */ - PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D7, NONE), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -265,6 +313,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_R6, NONE), PAD_NC(GPP_R7, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { From 49a5b949ca5c4e8933fa63356d48674c452b73bc Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Thu, 29 Jan 2026 12:06:46 +0000 Subject: [PATCH 701/789] mb/starlabs/starbook: Add NVMe/WiFi power sequencing Provide staged GPIO pad configuration for the M.2 NVMe SSD and the (discrete) M.2 2230 wireless module on supported StarBook variants. Signed-off-by: Sean Rhodes Change-Id: I6b3b607e73a2b1c437349f31cc6faaf662365da7 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90993 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/starlabs/starbook/Kconfig | 1 + src/mainboard/starlabs/starbook/mainboard.c | 9 +-- .../starlabs/starbook/variants/adl/gpio.c | 58 +++++++++++++++++-- .../starlabs/starbook/variants/adl_n/gpio.c | 58 +++++++++++++++++-- .../starlabs/starbook/variants/mtl/gpio.c | 58 +++++++++++++++++-- .../starlabs/starbook/variants/rpl/gpio.c | 58 +++++++++++++++++-- .../starlabs/starbook/variants/tgl/gpio.c | 42 +++++++++++++- 7 files changed, 253 insertions(+), 31 deletions(-) diff --git a/src/mainboard/starlabs/starbook/Kconfig b/src/mainboard/starlabs/starbook/Kconfig index 7dee1e3ecf..bae92d0239 100644 --- a/src/mainboard/starlabs/starbook/Kconfig +++ b/src/mainboard/starlabs/starbook/Kconfig @@ -16,6 +16,7 @@ config BOARD_STARLABS_STARBOOK_SERIES select NO_UART_ON_SUPERIO select SPD_READ_BY_WORD select SOC_INTEL_COMMON_BLOCK_HDA_VERB + select STARLABS_NVME_POWER_SEQUENCE select SYSTEM_TYPE_LAPTOP select VALIDATE_INTEL_DESCRIPTOR diff --git a/src/mainboard/starlabs/starbook/mainboard.c b/src/mainboard/starlabs/starbook/mainboard.c index f392ed8759..8916dda296 100644 --- a/src/mainboard/starlabs/starbook/mainboard.c +++ b/src/mainboard/starlabs/starbook/mainboard.c @@ -1,12 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include #include #include -static void init_mainboard(void *chip_info) +static void starlabs_configure_gpios(void *unused) { const struct pad_config *pads; size_t num; @@ -15,9 +16,9 @@ static void init_mainboard(void *chip_info) gpio_configure_pads(pads, num); } -struct chip_operations mainboard_ops = { - .init = init_mainboard, -}; +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, starlabs_configure_gpios, NULL); + +struct chip_operations mainboard_ops = {}; const char *mainboard_vbt_filename(void) { diff --git a/src/mainboard/starlabs/starbook/variants/adl/gpio.c b/src/mainboard/starlabs/starbook/variants/adl/gpio.c index f2d33b6458..2bad34dc52 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/gpio.c +++ b/src/mainboard/starlabs/starbook/variants/adl/gpio.c @@ -1,13 +1,57 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + + PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset deasserted */ + PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset deasserted */ +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D6, NONE, DEEP), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ + + /* Wireless */ + PAD_CFG_GPI(GPP_D7, NONE, DEEP), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -16,6 +60,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -40,16 +85,16 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 1 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_NC(GPP_D6, NONE), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ PAD_CFG_NF(GPP_H13, NONE, DEEP, NF5), /* Device Sleep */ PAD_CFG_NF(GPP_A12, NONE, DEEP, NF1), /* PEDET */ /* Wireless */ - PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 2 */ - PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D7, NONE), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -261,6 +306,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_R6, NONE), PAD_NC(GPP_R7, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starbook/variants/adl_n/gpio.c b/src/mainboard/starlabs/starbook/variants/adl_n/gpio.c index fc44208bac..3a8afd2b4d 100644 --- a/src/mainboard/starlabs/starbook/variants/adl_n/gpio.c +++ b/src/mainboard/starlabs/starbook/variants/adl_n/gpio.c @@ -1,13 +1,57 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + + PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset deasserted */ + PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset deasserted */ +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D5, NONE, DEEP), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ + + /* Wireless */ + PAD_CFG_GPI(GPP_D6, NONE, DEEP), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -16,6 +60,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -40,14 +85,14 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_NC(GPP_D5, NONE), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 1 */ - PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D6, NONE), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -258,6 +303,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_R6, NONE), PAD_NC(GPP_R7, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starbook/variants/mtl/gpio.c b/src/mainboard/starlabs/starbook/variants/mtl/gpio.c index 944c1452f8..72c5d637a3 100644 --- a/src/mainboard/starlabs/starbook/variants/mtl/gpio.c +++ b/src/mainboard/starlabs/starbook/variants/mtl/gpio.c @@ -1,8 +1,41 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_H07, 1, DEEP), /* Enable */ + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D20, NONE, PLTRST, NF1), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset asserted */ + + PAD_CFG_GPO(GPP_B19, 1, DEEP), /* WiFi RF Kill */ + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D21, NONE, PLTRST, NF2), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_A20, 1, PLTRST), /* Reset deasserted */ + PAD_CFG_GPO(GPP_H02, 1, PLTRST), /* Reset deasserted */ +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), /* RXD */ @@ -11,7 +44,18 @@ const struct pad_config early_gpio_table[] = { /* SMBus */ PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), /* Clock */ PAD_CFG_NF(GPP_C01, NONE, DEEP, NF1), /* Data */ + + /* SSD */ + PAD_CFG_GPI(GPP_D20, NONE, PLTRST), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_H07, 0, DEEP), /* Enable (PWREN off) */ + + /* Wireless */ + PAD_CFG_GPI(GPP_D21, NONE, PLTRST), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_B19, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -20,6 +64,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_V00, NONE, DEEP, NF1), /* Battery Low */ @@ -44,14 +89,14 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC(GPP_B00, NONE, DEEP, LEVEL, INVERT), /* Interrupt */ /* SSD */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D20, NONE, PLTRST, NF1), /* Clock Request 8 */ - PAD_CFG_GPO(GPP_A20, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_H07, 1, DEEP), /* Enable */ + PAD_NC(GPP_D20, NONE), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_H07, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D21, NONE, PLTRST, NF2), /* Clock Request 5 */ - PAD_CFG_GPO(GPP_H02, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_B19, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D21, NONE), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_B19, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_B18, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -246,6 +291,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_D22, NONE), PAD_NC(GPP_D23, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starbook/variants/rpl/gpio.c b/src/mainboard/starlabs/starbook/variants/rpl/gpio.c index 0625675f10..339e771544 100644 --- a/src/mainboard/starlabs/starbook/variants/rpl/gpio.c +++ b/src/mainboard/starlabs/starbook/variants/rpl/gpio.c @@ -1,13 +1,57 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D14, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), /* Clock Request 4 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset asserted */ + + PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_F20, 1, PLTRST), /* Reset deasserted */ + PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset deasserted */ +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_H19, NONE, DEEP), /* Clock Request 4 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D14, 0, DEEP), /* Enable (PWREN off) */ + + /* Wireless */ + PAD_CFG_GPI(GPP_D7, NONE, DEEP), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -16,6 +60,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -40,14 +85,14 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), /* Clock Request 4 */ - PAD_CFG_GPO(GPP_F20, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D14, 1, DEEP), /* Enable */ + PAD_NC(GPP_H19, NONE), /* Clock Request 4 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D14, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 2 */ - PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D7, NONE), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -260,6 +305,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_R6, NONE), PAD_NC(GPP_R7, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starbook/variants/tgl/gpio.c b/src/mainboard/starlabs/starbook/variants/tgl/gpio.c index 0bf5afba78..58fc4b4664 100644 --- a/src/mainboard/starlabs/starbook/variants/tgl/gpio.c +++ b/src/mainboard/starlabs/starbook/variants/tgl/gpio.c @@ -1,13 +1,47 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, PLTRST), /* Enable */ + PAD_CFG_NF(GPP_D8, NONE, DEEP, NF1), /* Clock Request 3 */ + PAD_CFG_GPO(GPP_A11, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_A11, 1, PLTRST), /* Reset deasserted */ +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* RXD */ PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D8, NONE, DEEP), /* Clock Request 3 */ + PAD_CFG_GPO(GPP_A11, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* Enable (PWREN off) */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -16,6 +50,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -40,9 +75,9 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC(GPP_C8, NONE, DEEP, LEVEL, INVERT), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_D8, NONE, DEEP, NF1), /* Clock Request 3 */ - PAD_CFG_GPO(GPP_A11, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, PLTRST), /* Enable */ + PAD_NC(GPP_D8, NONE), /* Clock Request 3 */ + PAD_CFG_GPO(GPP_A11, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* Enable (PWREN off) */ /* SATA */ PAD_CFG_NF(GPP_A12, UP_20K, DEEP, NF1), /* PEDET */ @@ -250,6 +285,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_U4, NONE), PAD_NC(GPP_U5, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { From baadfed9990a66326c2531fc45bd2a0213bce0de Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Thu, 29 Jan 2026 11:59:36 +0000 Subject: [PATCH 702/789] mb/starlabs/adl: Add NVMe power sequencing Enable STARLABS_NVME_POWER_SEQUENCE and provide staged GPIO pad configuration for the SSD slot (PWREN, PERST#, CLKREQ#). Signed-off-by: Sean Rhodes Change-Id: I22f1f8786db38b2720c544748cef58eb7259f239 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90991 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/adl/Kconfig | 1 + src/mainboard/starlabs/adl/mainboard.c | 6 ++-- src/mainboard/starlabs/adl/variants/hz/gpio.c | 36 +++++++++++++++++-- src/mainboard/starlabs/adl/variants/i5/gpio.c | 36 +++++++++++++++++-- src/mainboard/starlabs/adl/variants/y2/gpio.c | 36 +++++++++++++++++-- 5 files changed, 104 insertions(+), 11 deletions(-) diff --git a/src/mainboard/starlabs/adl/Kconfig b/src/mainboard/starlabs/adl/Kconfig index b39f9c914d..479ec79165 100644 --- a/src/mainboard/starlabs/adl/Kconfig +++ b/src/mainboard/starlabs/adl/Kconfig @@ -19,6 +19,7 @@ config BOARD_STARLABS_ADL_SERIES select SOC_INTEL_CRASHLOG select SPD_READ_BY_WORD select SPI_FLASH_WINBOND + select STARLABS_NVME_POWER_SEQUENCE select TPM2 select VALIDATE_INTEL_DESCRIPTOR diff --git a/src/mainboard/starlabs/adl/mainboard.c b/src/mainboard/starlabs/adl/mainboard.c index f8c9aea3ae..940584b151 100644 --- a/src/mainboard/starlabs/adl/mainboard.c +++ b/src/mainboard/starlabs/adl/mainboard.c @@ -1,11 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include #include -static void init_mainboard(void *chip_info) +static void starlabs_configure_mainboard(void *unused) { const struct pad_config *pads; size_t num; @@ -16,6 +17,8 @@ static void init_mainboard(void *chip_info) devtree_update(); } +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, starlabs_configure_mainboard, NULL); + void __weak starlabs_adl_mainboard_fill_ssdt(const struct device *dev) { (void)dev; @@ -27,6 +30,5 @@ static void enable_mainboard(struct device *dev) } struct chip_operations mainboard_ops = { - .init = init_mainboard, .enable_dev = enable_mainboard, }; diff --git a/src/mainboard/starlabs/adl/variants/hz/gpio.c b/src/mainboard/starlabs/adl/variants/hz/gpio.c index e214a14cec..4cb0af527d 100644 --- a/src/mainboard/starlabs/adl/variants/hz/gpio.c +++ b/src/mainboard/starlabs/adl/variants/hz/gpio.c @@ -1,12 +1,42 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset deasserted */ +}; + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D5, NONE, DEEP), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ }; const struct pad_config *variant_early_gpio_table(size_t *num) @@ -40,9 +70,9 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_NC(GPP_D5, NONE), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ PAD_CFG_NF(GPP_F0, NONE, DEEP, NF1), /* BRI Data */ diff --git a/src/mainboard/starlabs/adl/variants/i5/gpio.c b/src/mainboard/starlabs/adl/variants/i5/gpio.c index e6c03fd9c0..12b61daf05 100644 --- a/src/mainboard/starlabs/adl/variants/i5/gpio.c +++ b/src/mainboard/starlabs/adl/variants/i5/gpio.c @@ -1,12 +1,42 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset deasserted */ +}; + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D5, NONE, DEEP), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ }; const struct pad_config *variant_early_gpio_table(size_t *num) @@ -49,9 +79,9 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_SMI_LOW(GPP_F15, NONE, DEEP, EDGE_BOTH), /* Detect */ /* SSD */ - PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_NC(GPP_D5, NONE), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ PAD_CFG_NF(GPP_F0, NONE, DEEP, NF1), /* BRI Data */ diff --git a/src/mainboard/starlabs/adl/variants/y2/gpio.c b/src/mainboard/starlabs/adl/variants/y2/gpio.c index 12d9bcb472..849daadd57 100644 --- a/src/mainboard/starlabs/adl/variants/y2/gpio.c +++ b/src/mainboard/starlabs/adl/variants/y2/gpio.c @@ -1,12 +1,42 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset deasserted */ +}; + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D5, NONE, DEEP), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ }; const struct pad_config *variant_early_gpio_table(size_t *num) @@ -36,9 +66,9 @@ const struct pad_config gpio_table[] = { // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A10, NONE, DEEP, NF1), /* eSPI Reset */ /* SSD */ - PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_NC(GPP_D5, NONE), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ PAD_CFG_NF(GPP_H13, NONE, DEEP, NF5), /* Device Sleep */ PAD_CFG_NF(GPP_A12, NONE, DEEP, NF1), /* PEDET */ From 61c69ebfa899867a7d0e19b422b53d0a7b75d8e9 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Thu, 29 Jan 2026 12:09:35 +0000 Subject: [PATCH 703/789] mb/starlabs: Drop PCIe detect-timeout/hotplug workarounds With proper staged M.2 slot power sequencing in place, remove the root-port detect-timeout overrides and the StarBook ADL PCI hot-plug CFR option. Signed-off-by: Sean Rhodes Change-Id: I50820c776011508f4d6bfa7053e827d7c53700b6 Reviewed-on: https://review.coreboot.org/c/coreboot/+/90994 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/adl/variants/i5/devicetree.cb | 1 - src/mainboard/starlabs/adl/variants/y2/devicetree.cb | 1 - src/mainboard/starlabs/common/include/common/cfr.h | 8 -------- src/mainboard/starlabs/starbook/cfr.c | 3 --- .../starlabs/starbook/variants/adl/devicetree.cb | 1 - src/mainboard/starlabs/starbook/variants/adl/ramstage.c | 8 -------- .../starlabs/starbook/variants/adl_n/devicetree.cb | 1 - .../starlabs/starfighter/variants/mtl/devicetree.cb | 1 - .../starlabs/starfighter/variants/rpl/devicetree.cb | 1 - 9 files changed, 25 deletions(-) diff --git a/src/mainboard/starlabs/adl/variants/i5/devicetree.cb b/src/mainboard/starlabs/adl/variants/i5/devicetree.cb index b0080bd292..155ed5c08e 100644 --- a/src/mainboard/starlabs/adl/variants/i5/devicetree.cb +++ b/src/mainboard/starlabs/adl/variants/i5/devicetree.cb @@ -199,7 +199,6 @@ chip soc/intel/alderlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 50, }" smbios_slot_desc "SlotTypeM2Socket3" diff --git a/src/mainboard/starlabs/adl/variants/y2/devicetree.cb b/src/mainboard/starlabs/adl/variants/y2/devicetree.cb index 0ea50a4f36..c8d856cc03 100644 --- a/src/mainboard/starlabs/adl/variants/y2/devicetree.cb +++ b/src/mainboard/starlabs/adl/variants/y2/devicetree.cb @@ -189,7 +189,6 @@ chip soc/intel/alderlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 50, }" smbios_slot_desc "SlotTypePciExpressGen3X4" "SlotLengthLong" diff --git a/src/mainboard/starlabs/common/include/common/cfr.h b/src/mainboard/starlabs/common/include/common/cfr.h index 89405fd2b7..de4f108404 100644 --- a/src/mainboard/starlabs/common/include/common/cfr.h +++ b/src/mainboard/starlabs/common/include/common/cfr.h @@ -91,14 +91,6 @@ static const struct sm_object microphone = SM_DECLARE_BOOL({ .default_value = true, }); -static const struct sm_object pci_hot_plug = SM_DECLARE_BOOL({ - .opt_name = "pci_hot_plug", - .ui_name = "Third-Party SSD Support", - .ui_helptext = "Enables PCI Hot Plug, which slows down the SSD initialization. It" - " is required for certain third-party SSDs to be detected.", - .default_value = false, -}); - static const struct sm_object power_profile = SM_DECLARE_ENUM({ .opt_name = "power_profile", .ui_name = "Power Profile", diff --git a/src/mainboard/starlabs/starbook/cfr.c b/src/mainboard/starlabs/starbook/cfr.c index 10263c45fa..d2e8b7c9ae 100644 --- a/src/mainboard/starlabs/starbook/cfr.c +++ b/src/mainboard/starlabs/starbook/cfr.c @@ -50,9 +50,6 @@ static struct sm_obj_form io_expansion_group = { .ui_name = "I/O / Expansion", .obj_list = (const struct sm_object *[]) { &card_reader, - #if CONFIG(BOARD_STARLABS_STARBOOK_ADL) - &pci_hot_plug, - #endif #if CONFIG(DRIVERS_INTEL_USB4_RETIMER) &thunderbolt, #endif diff --git a/src/mainboard/starlabs/starbook/variants/adl/devicetree.cb b/src/mainboard/starlabs/starbook/variants/adl/devicetree.cb index 675cc27d3b..55cc2d5cb5 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/devicetree.cb +++ b/src/mainboard/starlabs/starbook/variants/adl/devicetree.cb @@ -199,7 +199,6 @@ chip soc/intel/alderlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 50, }" smbios_slot_desc "SlotTypeM2Socket3" diff --git a/src/mainboard/starlabs/starbook/variants/adl/ramstage.c b/src/mainboard/starlabs/starbook/variants/adl/ramstage.c index 1dbad4fc98..3e9cfb13c4 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/ramstage.c +++ b/src/mainboard/starlabs/starbook/variants/adl/ramstage.c @@ -1,17 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include #include #include void mainboard_silicon_init_params(FSP_S_CONFIG *supd) { configure_pin_mux(supd); - - /* - * Enable Hot Plug on RP5 to slow down coreboot so that - * third-party drives are detected. - */ - if (get_uint_option("pci_hot_plug", 0) == 1) - supd->PcieRpHotPlug[8] = 1; } diff --git a/src/mainboard/starlabs/starbook/variants/adl_n/devicetree.cb b/src/mainboard/starlabs/starbook/variants/adl_n/devicetree.cb index f0f16c4337..ca436a0d40 100644 --- a/src/mainboard/starlabs/starbook/variants/adl_n/devicetree.cb +++ b/src/mainboard/starlabs/starbook/variants/adl_n/devicetree.cb @@ -184,7 +184,6 @@ chip soc/intel/alderlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 50, }" smbios_slot_desc "SlotTypeM2Socket3" diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb b/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb index b7b8cedf85..11384b8f13 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb +++ b/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb @@ -250,7 +250,6 @@ chip soc/intel/meteorlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 15, }" smbios_slot_desc "SlotTypeM2Socket3" diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb b/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb index 080bde0a19..20d2e3ba67 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb +++ b/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb @@ -253,7 +253,6 @@ chip soc/intel/alderlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 50, }" smbios_slot_desc "SlotTypeM2Socket3" From f5c9c1c166577c1eaf324a9de16b0adb395f5a86 Mon Sep 17 00:00:00 2001 From: Venkateshwar S Date: Wed, 18 Feb 2026 04:01:58 -0800 Subject: [PATCH 704/789] mb/google/bluey: Move ADSP QUP-I2C init to normal boot path The ADSP I2C initialization for charger/fuel-gauge is needed in both normal boot and the off-mode/low-battery charging path. This patch moves it before the conditional mainboard initialization skip, so it runs in all cases. BUG=b:436391478 TEST=Able to build and boot google/bluey. Change-Id: I7a5c4e9c2a066a2ae43d57a87902528c93faecc5 Signed-off-by: Venkateshwar S Reviewed-on: https://review.coreboot.org/c/coreboot/+/91365 Reviewed-by: Kapil Porwal Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/mainboard/google/bluey/mainboard.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 64212d0e84..ac80ceef80 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -172,6 +172,9 @@ static void mainboard_init(struct device *dev) if (get_boot_mode() == LB_BOOT_MODE_LOW_BATTERY) trigger_critical_battery_shutdown(); + /* ADSP I2C (Charger/Fuel gauge) */ + qupv3_se_fw_load_and_init(QUPV3_2_SE4, SE_PROTOCOL_I2C, MIXED); + configure_parallel_charging_late(); /* Skip mainboard initialization if boot mode is "low-battery" or "off-mode charging" */ @@ -206,10 +209,6 @@ static void mainboard_init(struct device *dev) qupv3_se_fw_load_and_init(QUPV3_1_SE6, SE_PROTOCOL_UART, FIFO); /* BT UART */ qupv3_se_fw_load_and_init(QUPV3_0_SE0, SE_PROTOCOL_I2C, MIXED); /* Trackpad I2C */ - /* ADSP I2C (Charger/Fuel gauge) */ - qupv3_se_fw_load_and_init(QUPV3_2_SE4, SE_PROTOCOL_I2C, MIXED); - - if (CONFIG(MAINBOARD_HAS_PS8820_RETIMER)) { i2c_init(QUPV3_0_SE3, I2C_SPEED_FAST); /* USB-C0 Re-Timer I2C */ i2c_init(QUPV3_0_SE7, I2C_SPEED_FAST); /* USB-C1 Re-Timer I2C */ From 036af49b1db1d45ed5d5ada4efbae2de4fbde071 Mon Sep 17 00:00:00 2001 From: "Evie (Ivi) Ballou" Date: Sun, 1 Feb 2026 01:44:40 +0200 Subject: [PATCH 705/789] mb/emul/qemu-q35: Add a _DIS method for gsi_link devices This solves the remark: ``` dsdt.asl 430-437: Device(GSIA-H) { Name(_HID, EISAID("PNP0C0F")) Name(_UID, 0) Name(_PRS, ResourceTemplate() { Interrupt(, Level, ActiveHigh, Shared) { 0x17 } }) Name(_CRS, ResourceTemplate() { Interrupt(, Level, ActiveHigh, Shared) { 0x17 } }) Method(_SRS, 1, NotSerialized [*** iASL: Very long input line, message below refers to column 13 ***] Remark 2141 - Missing dependency (Device has a _SRS, no corresponding _DIS) ``` Change-Id: I5c30ed8e7eef324373c3cec6bf16ddcc056c055b Signed-off-by: Evie (Ivi) Ballou Reviewed-on: https://review.coreboot.org/c/coreboot/+/91034 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/mainboard/emulation/qemu-q35/dsdt.asl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/emulation/qemu-q35/dsdt.asl b/src/mainboard/emulation/qemu-q35/dsdt.asl index d65f2de0ec..3fb615050a 100644 --- a/src/mainboard/emulation/qemu-q35/dsdt.asl +++ b/src/mainboard/emulation/qemu-q35/dsdt.asl @@ -350,6 +350,8 @@ DefinitionBlock ( }) \ Method(_SRS, 1, NotSerialized) { \ } \ + Method(_DIS, 0, NotSerialized) { \ + } \ } define_gsi_link(GSIA, 0, 0x10) From 93444a0ce0652750c7c457229a38b5a1845fe772 Mon Sep 17 00:00:00 2001 From: "Evie (Ivi) Ballou" Date: Sat, 31 Jan 2026 23:04:42 +0200 Subject: [PATCH 706/789] mb/emul/qemu-[q35,i440fx]: Create ICQR interrupt resource locally and use defined offset This changes out the PRR0 named object for a method local variable and avoids the use of a hardcoded offset This solves the remark: ``` dsdt.asl 415: Name(PRR0, ResourceTemplate() { Remark 2173 - ^ Creation of named objects within a method is highly inefficient, use globals or method local variables instead (\_SB.IQCR) ``` The IQCR function was tested, by evaluating it in the new `dsdt.aml` file, as well as the old one with `acpiexec`: `acpiexec -b "Evaluate _SB.IQCR $4bit_num_dec" dsdt.aml`, where `$4bit_num_in_dec`, is a number between 0 and 15. Expected output: ``` Evaluation of \_SB.IQCR returned object 0x5648f23cedd0, external buffer length 28 [Buffer] Length 0B = 0000: 89 06 00 09 01 $4bit_num_hex 00 00 00 79 00 // .........y. ``` Change-Id: I007d6b8df4eef4e8cb13cef45b95da7659d62cef Signed-off-by: Evie (Ivi) Ballou Reviewed-on: https://review.coreboot.org/c/coreboot/+/91033 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/mainboard/emulation/qemu-i440fx/dsdt.asl | 13 +++++++------ src/mainboard/emulation/qemu-q35/dsdt.asl | 13 +++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/mainboard/emulation/qemu-i440fx/dsdt.asl b/src/mainboard/emulation/qemu-i440fx/dsdt.asl index 749ecfe664..89f9d5fad0 100644 --- a/src/mainboard/emulation/qemu-i440fx/dsdt.asl +++ b/src/mainboard/emulation/qemu-i440fx/dsdt.asl @@ -218,16 +218,17 @@ DefinitionBlock ( } Return (0x0B) } + Method(IQCR, 1, Serialized) { // _CRS method - get current settings - Name(PRR0, ResourceTemplate() { - Interrupt(, Level, ActiveHigh, Shared) { 0 } - }) - CreateDWordField(PRR0, 0x05, PRRI) + Local0 = ResourceTemplate() { + Interrupt(, Level, ActiveHigh, Shared,,, IRQ0) { 0 } + } + CreateDWordField(Local0, IRQ0._INT, IRQV) If (Arg0 < 0x80) { - PRRI = Arg0 + IRQV = Arg0 } - Return (PRR0) + Return (Local0) } #define define_link(link, uid, reg) \ diff --git a/src/mainboard/emulation/qemu-q35/dsdt.asl b/src/mainboard/emulation/qemu-q35/dsdt.asl index 3fb615050a..da809d6e61 100644 --- a/src/mainboard/emulation/qemu-q35/dsdt.asl +++ b/src/mainboard/emulation/qemu-q35/dsdt.asl @@ -291,14 +291,15 @@ DefinitionBlock ( } Return (0x0B) } + Method(IQCR, 1, Serialized) { // _CRS method - get current settings - Name(PRR0, ResourceTemplate() { - Interrupt(, Level, ActiveHigh, Shared) { 0 } - }) - CreateDWordField(PRR0, 0x05, PRRI) - PRRI = Arg0 & 0x0F - Return (PRR0) + Local0 = ResourceTemplate() { + Interrupt(, Level, ActiveHigh, Shared,,, IRQ0) { 0 } + } + CreateDWordField(Local0, IRQ0._INT, IRQV) + IRQV = Arg0 & 0x0F + Return (Local0) } #define define_link(link, uid, reg) \ From 26006cc2176a8478414f5264d08b6755b4d52931 Mon Sep 17 00:00:00 2001 From: "Evie (Ivi) Ballou" Date: Tue, 27 Jan 2026 03:18:20 +0200 Subject: [PATCH 707/789] util/ifdtool: show overlapping region name and range details When updating regions using a flashrom file with overlapping regions the error message now shows overlapping region names and their ranges. e.g: Regions would overlap: IE : 7fff000-7ffffff 10GbE_0 : 7fff000-7ffffff Change-Id: Ie2417e477924f0085839306a8a51d1241e20a338 Signed-off-by: Evie (Ivi) Ballou Reviewed-on: https://review.coreboot.org/c/coreboot/+/90940 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- util/ifdtool/ifdtool.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c index 0592785bf6..c741e1d7c5 100644 --- a/util/ifdtool/ifdtool.c +++ b/util/ifdtool/ifdtool.c @@ -2094,7 +2094,18 @@ static void new_layout(const char *filename, char *image, int size, for (j = i + 1; j < max_regions; j++) { if (regions_collide(&new_regions[i], &new_regions[j])) { - fprintf(stderr, "Regions would overlap.\n"); + fprintf(stderr, "Regions would overlap:\n"); + + /* See which string is longer and make sure we pad the shorter one */ + int region_name_len_i = strlen(region_name(i)); + int region_name_len_j = strlen(region_name(j)); + int padding = MAX(region_name_len_i, region_name_len_j); + + /* Print the regions that overlap, and where each region is */ + fprintf(stderr, " %*s : %x-%x\n", padding, region_name(i), + new_regions[i].base, new_regions[i].limit); + fprintf(stderr, " %*s : %x-%x\n", padding, region_name(j), + new_regions[j].base, new_regions[j].limit); exit(EXIT_FAILURE); } } From 343f439801225353201d8157b17e2eaa30da85ee Mon Sep 17 00:00:00 2001 From: Ivi Ballou Date: Wed, 25 Feb 2026 17:58:50 +0200 Subject: [PATCH 708/789] util/inteltool: set amb registers dumping error print to stdout Set the "Error: Dumping AMBs on this MCH is not (yet) supported." message to stdout. All other "dumping ... not (yet) supported" errors use stdout, which makes them usable with pagers like less. The current behavior prints the AMB dumping error in stderr, which breaks pagers. This change aims to fix this discrepancy. Change-Id: I502e9f8d5c71953e844bdc7174b3c7bd2987d00f Signed-off-by: Ivi Ballou Reviewed-on: https://review.coreboot.org/c/coreboot/+/91419 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- util/inteltool/amb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/inteltool/amb.c b/util/inteltool/amb.c index 961c0abf36..b01ea4326b 100644 --- a/util/inteltool/amb.c +++ b/util/inteltool/amb.c @@ -431,7 +431,7 @@ int print_ambs(struct pci_dev *dev, struct pci_access *pacc) break; default: - fprintf(stderr, "Error: Dumping AMBs on this MCH is not (yet) supported.\n"); + printf("Error: Dumping AMBs on this MCH is not (yet) supported.\n"); return 1; } From 8998999eb31a35efbc987d5bc597156fb5c50042 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sat, 28 Feb 2026 20:22:49 +0100 Subject: [PATCH 709/789] Haswell NRI: Add dumping of CAPID registers If `CONFIG(DEBUG_RAM_SETUP)`, dump the values of the CAPID0_A and CAPID0_B registers to the log. This is useful debugging information. Dump the CAPID registers' values before native chipset init, because dynamic fusing changes the CAPID values. Tested on ASRock Z97 Extreme6 with a PCIe card plugged into the PCIE4 slot (forcing PEG to be bifurcated as x8+x8). The CPU and PCH are: CPU id(306c3) ucode:00000028 Intel(R) Core(TM) i7-4770S CPU @ 3.10GHz AES supported, TXT supported, VT supported PCH type: Z97, device id: 8cc4, rev id 0 CAPID values before dynamic fusing are shown below: CAPID0_A: 0x6204e861 DDR3L 1.35V: Yes DDR Write Vref: No OC enabled (DSKU): No DDR overclock: No Compatibility RID: 0x6 Capability DID: Desktop DID override: No Integrated GPU: No Dual channel: Yes X2APIC support: Yes DIMMs per channel: 1 Camarillo device: No Full ULT info: Yes DDR 1N mode: Yes PCIe ratio: No Max channel size: 16 GiB PEG Gen2 support: Yes DMI Gen2 support: Yes VT-d support: Yes ECC forced: No ECC supported: No DMI width: x4 Width upconfig: Yes PEG function 0: Yes PEG function 1: No PEG function 2: No Disp HD audio: Yes CAPID0_B: 0x565400d0 PEG for GFX single: Unlimited width PEG for GFX multi: Unlimited width 133 MHz ref clock: Up to DDR3-1600 Silicon mode: Production HDCP capable: Yes Num PEG lanes: 16 Add. GFX capable: Yes Add. GFX enable: Yes CPU Package Type: 0 PEG Gen3 support: No 100 MHz ref clock: Up to DDR3-1600 Soft Bin capable: No Cache size: 3 SMT support: Yes OC enabled (SSKU): No OC controlled by: SSKU CAPID values after dynamic fusing are shown below, with manually added arrows to indicate which values have changed: CAPID0_A: 0x4204a06d DDR3L 1.35V: Yes DDR Write Vref: No OC enabled (DSKU): Yes <----- DDR overclock: Yes <----- Compatibility RID: 0x6 Capability DID: Desktop DID override: No Integrated GPU: Yes <----- Dual channel: Yes X2APIC support: Yes DIMMs per channel: 2 <----- Camarillo device: No Full ULT info: Yes DDR 1N mode: Yes PCIe ratio: No Max channel size: 16 GiB PEG Gen2 support: Yes DMI Gen2 support: Yes VT-d support: Yes ECC forced: No ECC supported: No DMI width: x4 Width upconfig: Yes PEG function 0: Yes PEG function 1: Yes <----- PEG function 2: No Disp HD audio: Yes CAPID0_B: 0x564400d0 PEG for GFX single: Unlimited width PEG for GFX multi: Unlimited width 133 MHz ref clock: Up to DDR3-1600 Silicon mode: Production HDCP capable: Yes Num PEG lanes: 16 Add. GFX capable: Yes Add. GFX enable: Yes CPU Package Type: 0 PEG Gen3 support: Yes <----- 100 MHz ref clock: Up to DDR3-1600 Soft Bin capable: No Cache size: 3 SMT support: Yes OC enabled (SSKU): No OC controlled by: SSKU Change-Id: I46f27c54a7ec7fd9fc79fdabaa59a44a591168b8 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91478 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- .../intel/haswell/native_raminit/Makefile.mk | 2 + .../intel/haswell/native_raminit/info_dumps.c | 115 ++++++++++++++++++ .../haswell/native_raminit/raminit_native.c | 5 + .../haswell/native_raminit/raminit_native.h | 2 + .../haswell/native_raminit/reg_structs.h | 59 +++++++++ 5 files changed, 183 insertions(+) create mode 100644 src/northbridge/intel/haswell/native_raminit/info_dumps.c diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk index c7a5f4ba5a..7a3346ca78 100644 --- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk +++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk @@ -23,3 +23,5 @@ romstage-y += train_jedec_write_leveling.c romstage-y += train_read_mpr.c romstage-y += train_receive_enable.c romstage-y += train_sense_amp_offset.c + +romstage-$(CONFIG_DEBUG_RAM_SETUP) += info_dumps.c diff --git a/src/northbridge/intel/haswell/native_raminit/info_dumps.c b/src/northbridge/intel/haswell/native_raminit/info_dumps.c new file mode 100644 index 0000000000..5ff6306e7e --- /dev/null +++ b/src/northbridge/intel/haswell/native_raminit/info_dumps.c @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +#include "raminit_native.h" + +void dump_capid_values(void) +{ + static const char *const no_yes[] = { + [0] = "No", + [1] = "Yes", + }; + static const char *const cdid_decoder[] = { + [0] = "Desktop", + [1] = "Server", + [2] = "Mobile", + [3] = "Marketing Spare", + }; + static const char *const ddrsz_lut[] = { + [0] = "16", + [1] = "8", + [2] = "2", + [3] = "0.5", + }; + static const char *const pegfx1_lut[] = { + [0] = "Unlimited width", + [1] = "Limited to x1", + }; + static const char *const dmfc_lut[] = { + [0] = "Unlimited", + [1] = "Up to DDR3-2667", + [2] = "Up to DDR3-2400", + [3] = "Up to DDR3-2133", + [4] = "Up to DDR3-1867", + [5] = "Up to DDR3-1600", + [6] = "Up to DDR3-1333", + [7] = "Up to DDR3-1067", + }; + static const char *const ddd_lut[] = { + [0] = "Debug", + [1] = "Production", + }; + static const char *const pll100_lut[] = { + [0] = "Not supported", + [1] = "Up to DDR3-1400", + [2] = "Up to DDR3-1600", + [3] = "Up to DDR3-1800", + [4] = "Up to DDR3-2000", + [5] = "Up to DDR3-2200", + [6] = "Up to DDR3-2400", + [7] = "Unlimited", + }; + static const char *const occtl_lut[] = { + [0] = "DSKU", + [1] = "SSKU", + }; + + const union pci_capid0_a_reg capid0_a = { + .raw = pci_read_config32(HOST_BRIDGE, CAPID0_A) + }; + const union pci_capid0_b_reg capid0_b = { + .raw = pci_read_config32(HOST_BRIDGE, CAPID0_B) + }; + printk(BIOS_DEBUG, "\n"); + printk(BIOS_DEBUG, "CAPID0_A: 0x%08x\n", capid0_a.raw); + printk(BIOS_DEBUG, " DDR3L 1.35V: %s\n", no_yes[capid0_a.DDR3L_EN]); + printk(BIOS_DEBUG, " DDR Write Vref: %s\n", no_yes[capid0_a.DDR_WRTVREF]); + printk(BIOS_DEBUG, " OC enabled (DSKU): %s\n", no_yes[capid0_a.OC_ENABLED_DSKU]); + printk(BIOS_DEBUG, " DDR overclock: %s\n", no_yes[capid0_a.DDR_OVERCLOCK]); + printk(BIOS_DEBUG, " Compatibility RID: 0x%01x\n", capid0_a.CRID); + printk(BIOS_DEBUG, " Capability DID: %s\n", cdid_decoder[capid0_a.CDID]); + printk(BIOS_DEBUG, " DID override: %s\n", no_yes[capid0_a.DIDOE]); + printk(BIOS_DEBUG, " Integrated GPU: %s\n", no_yes[!capid0_a.IGD]); + printk(BIOS_DEBUG, " Dual channel: %s\n", no_yes[!capid0_a.PDCD]); + printk(BIOS_DEBUG, " X2APIC support: %s\n", no_yes[capid0_a.X2APIC_EN]); + printk(BIOS_DEBUG, " DIMMs per channel: %u\n", capid0_a.DDPCD ? 1 : 2); + printk(BIOS_DEBUG, " Camarillo device: %s\n", no_yes[!capid0_a.CDD]); + printk(BIOS_DEBUG, " Full ULT info: %s\n", no_yes[!capid0_a.FUFRD]); + printk(BIOS_DEBUG, " DDR 1N mode: %s\n", no_yes[!capid0_a.D1NM]); + printk(BIOS_DEBUG, " PCIe ratio: %s\n", no_yes[!capid0_a.PCIE_RATIO_DIS]); + printk(BIOS_DEBUG, " Max channel size: %s GiB\n", ddrsz_lut[capid0_a.DDRSZ]); + printk(BIOS_DEBUG, " PEG Gen2 support: %s\n", no_yes[!capid0_a.PEGG2DIS]); + printk(BIOS_DEBUG, " DMI Gen2 support: %s\n", no_yes[!capid0_a.DMIG2DIS]); + printk(BIOS_DEBUG, " VT-d support: %s\n", no_yes[!capid0_a.VTDD]); + printk(BIOS_DEBUG, " ECC forced: %s\n", no_yes[capid0_a.FDEE]); + printk(BIOS_DEBUG, " ECC supported: %s\n", no_yes[!capid0_a.ECCDIS]); + printk(BIOS_DEBUG, " DMI width: x%u\n", capid0_a.DW ? 2 : 4); + printk(BIOS_DEBUG, " Width upconfig: %s\n", no_yes[!capid0_a.PELWUD]); + printk(BIOS_DEBUG, " PEG function 0: %s\n", no_yes[!capid0_a.PEG10D]); + printk(BIOS_DEBUG, " PEG function 1: %s\n", no_yes[!capid0_a.PEG11D]); + printk(BIOS_DEBUG, " PEG function 2: %s\n", no_yes[!capid0_a.PEG12D]); + printk(BIOS_DEBUG, " Disp HD audio: %s\n", no_yes[!capid0_a.DHDAD]); + printk(BIOS_DEBUG, "\n"); + printk(BIOS_DEBUG, "CAPID0_B: 0x%08x\n", capid0_b.raw); + printk(BIOS_DEBUG, " PEG for GFX single: %s\n", pegfx1_lut[capid0_b.SPEGFX1]); + printk(BIOS_DEBUG, " PEG for GFX multi: %s\n", pegfx1_lut[capid0_b.DPEGFX1]); + printk(BIOS_DEBUG, " 133 MHz ref clock: %s\n", dmfc_lut[capid0_b.DMFC]); + printk(BIOS_DEBUG, " Silicon mode: %s\n", ddd_lut[capid0_b.DDD]); + printk(BIOS_DEBUG, " HDCP capable: %s\n", no_yes[!capid0_b.HDCPD]); + printk(BIOS_DEBUG, " Num PEG lanes: %u\n", capid0_b.PEGX16D ? 8 : 16); + printk(BIOS_DEBUG, " Add. GFX capable: %s\n", no_yes[!capid0_b.ADDGFXCAP]); + printk(BIOS_DEBUG, " Add. GFX enable: %s\n", no_yes[capid0_b.ADDGFXEN]); + printk(BIOS_DEBUG, " CPU Package Type: %u\n", capid0_b.PKGTYP); + printk(BIOS_DEBUG, " PEG Gen3 support: %s\n", no_yes[!capid0_b.PEGG3_DIS]); + printk(BIOS_DEBUG, " 100 MHz ref clock: %s\n", pll100_lut[capid0_b.PLL_REF100_CFG]); + printk(BIOS_DEBUG, " Soft Bin capable: %s\n", no_yes[capid0_b.SOFTBIN]); + printk(BIOS_DEBUG, " Cache size: %u\n", capid0_b.CACHESZ); + printk(BIOS_DEBUG, " SMT support: %s\n", no_yes[capid0_b.SMT]); + printk(BIOS_DEBUG, " OC enabled (SSKU): %s\n", no_yes[capid0_b.OC_ENABLED_SSKU]); + printk(BIOS_DEBUG, " OC controlled by: %s\n", occtl_lut[capid0_b.OC_CTL_DSKU_DIS]); + printk(BIOS_DEBUG, "\n"); +} diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c index d5b5c117d6..ab1e4ff1a3 100644 --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c @@ -171,6 +171,11 @@ void perform_raminit(const bool s3resume) */ const enum raminit_boot_mode orig_bootmode = get_boot_mode(); + if (CONFIG(DEBUG_RAM_SETUP)) { + /* Log CAPID values before dynamic fusing takes place */ + dump_capid_values(); + } + const bool cpu_replaced = early_init_native(s3resume ? BOOTMODE_S3 : orig_bootmode); wait_txt_clear(); diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h index 123f579a76..59dee35abe 100644 --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h @@ -703,4 +703,6 @@ uint8_t get_tCWL(uint32_t mem_clock_mhz); uint32_t get_tREFI(uint32_t mem_clock_mhz); uint32_t get_tXP(uint32_t mem_clock_mhz); +void dump_capid_values(void); + #endif diff --git a/src/northbridge/intel/haswell/native_raminit/reg_structs.h b/src/northbridge/intel/haswell/native_raminit/reg_structs.h index b0a121fa1a..9a64b2903a 100644 --- a/src/northbridge/intel/haswell/native_raminit/reg_structs.h +++ b/src/northbridge/intel/haswell/native_raminit/reg_structs.h @@ -3,6 +3,65 @@ #ifndef HASWELL_RAMINIT_REG_STRUCTS_H #define HASWELL_RAMINIT_REG_STRUCTS_H +union pci_capid0_a_reg { + struct __packed { + uint32_t DDR3L_EN : 1; // Bits 0:0 + uint32_t DDR_WRTVREF : 1; // Bits 1:1 + uint32_t OC_ENABLED_DSKU : 1; // Bits 2:2 + uint32_t DDR_OVERCLOCK : 1; // Bits 3:3 + uint32_t CRID : 4; // Bits 7:4 + uint32_t CDID : 2; // Bits 9:8 + uint32_t DIDOE : 1; // Bits 10:10 + uint32_t IGD : 1; // Bits 11:11 + uint32_t PDCD : 1; // Bits 12:12 + uint32_t X2APIC_EN : 1; // Bits 13:13 + uint32_t DDPCD : 1; // Bits 14:14 + uint32_t CDD : 1; // Bits 15:15 + uint32_t FUFRD : 1; // Bits 16:16 + uint32_t D1NM : 1; // Bits 17:17 + uint32_t PCIE_RATIO_DIS : 1; // Bits 18:18 + uint32_t DDRSZ : 2; // Bits 20:19 + uint32_t PEGG2DIS : 1; // Bits 21:21 + uint32_t DMIG2DIS : 1; // Bits 22:22 + uint32_t VTDD : 1; // Bits 23:23 + uint32_t FDEE : 1; // Bits 24:24 + uint32_t ECCDIS : 1; // Bits 25:25 + uint32_t DW : 1; // Bits 26:26 + uint32_t PELWUD : 1; // Bits 27:27 + uint32_t PEG10D : 1; // Bits 28:28 + uint32_t PEG11D : 1; // Bits 29:29 + uint32_t PEG12D : 1; // Bits 30:30 + uint32_t DHDAD : 1; // Bits 31:31 + }; + uint32_t raw; +}; + +union pci_capid0_b_reg { + struct __packed { + uint32_t SPEGFX1 : 1; // Bits 0:0 + uint32_t DPEGFX1 : 1; // Bits 1:1 + uint32_t : 2; // Bits 3:2 + uint32_t DMFC : 3; // Bits 6:4 + uint32_t DDD : 1; // Bits 7:7 + uint32_t : 3; // Bits 10:8 + uint32_t HDCPD : 1; // Bits 11:11 + uint32_t : 4; // Bits 15:12 + uint32_t PEGX16D : 1; // Bits 16:16 + uint32_t ADDGFXCAP : 1; // Bits 17:17 + uint32_t ADDGFXEN : 1; // Bits 18:18 + uint32_t PKGTYP : 1; // Bits 19:19 + uint32_t PEGG3_DIS : 1; // Bits 20:20 + uint32_t PLL_REF100_CFG : 3; // Bits 23:21 + uint32_t SOFTBIN : 1; // Bits 24:24 + uint32_t CACHESZ : 3; // Bits 27:25 + uint32_t SMT : 1; // Bits 28:28 + uint32_t OC_ENABLED_SSKU : 1; // Bits 29:29 + uint32_t OC_CTL_DSKU_DIS : 1; // Bits 30:30 + uint32_t : 1; // Bits 31:31 + }; + uint32_t raw; +}; + union ddr_data_rx_train_rank_reg { struct __packed { uint32_t rcven : 9; // Bits 8:0 From 56e645d942572c1580d4546be843971f953e3291 Mon Sep 17 00:00:00 2001 From: Cliff Huang Date: Fri, 20 Feb 2026 15:26:21 -0800 Subject: [PATCH 710/789] mb/google/fatcat: Change Gen4 and Gen5 NVMe power sequence Turn off Gen4 and Gen5 NVMe power at bootblock and turn on at romstage to address device enumeration and link speed issues observed after power cycles and warm/cold reboots. This change specifically resolves issues seen with certain NVMe devices, particularly the Micron 3500, where improper power sequencing can cause enumeration failures or incorrect link speed negotiation. BUG=none TEST=Boot Fatcat board with Micron 3500 NVMe in Gen4/Gen5 M.2 slots. Perform multiple power cycles and warm/cold reboots. Verify consistent NVMe enumeration and proper link speed using lspci output. Signed-off-by: Cliff Huang Change-Id: Ie929a3010acd74237d29a77c7582f1cae837a2e2 Reviewed-on: https://review.coreboot.org/c/coreboot/+/91369 Reviewed-by: Pranava Y N Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- .../google/fatcat/variants/fatcat/fw_config.c | 23 ++++++++----------- .../google/fatcat/variants/fatcat/gpio.c | 5 ++++ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/mainboard/google/fatcat/variants/fatcat/fw_config.c b/src/mainboard/google/fatcat/variants/fatcat/fw_config.c index ccece4647f..329df7e09a 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/fw_config.c +++ b/src/mainboard/google/fatcat/variants/fatcat/fw_config.c @@ -287,12 +287,10 @@ static const struct pad_config wwan_disable_pads[] = { /* Gen4 NVME: at the top M.2 slot */ static const struct pad_config pre_mem_gen4_ssd_pwr_pads[] = { /* GPP_B10: GEN4_SSD_PWREN */ - PAD_CFG_GPO(GPP_B10, 0, PLTRST), + PAD_CFG_GPO(GPP_B10, 1, PLTRST), }; static const struct pad_config gen4_ssd_pads[] = { - /* GPP_B10: GEN4_SSD_PWREN */ - PAD_CFG_GPO(GPP_B10, 1, PLTRST), /* GPP_B09: M2_GEN4_SSD_RESET_N */ PAD_CFG_GPO(GPP_B09, 1, PLTRST), }; @@ -300,7 +298,7 @@ static const struct pad_config gen4_ssd_pads[] = { /* Gen5 NVME: at the bottom M.2 slot */ static const struct pad_config pre_mem_gen5_ssd_pwr_pads[] = { /* GPP_B16: GEN5_SSD_PWREN */ - PAD_CFG_GPO(GPP_B16, 0, PLTRST), + PAD_CFG_GPO(GPP_B16, 1, PLTRST), }; static const struct pad_config gen5_ssd_pads[] = { @@ -617,15 +615,6 @@ void fw_config_configure_pre_mem_gpio(void) if (!fw_config_probe(FW_CONFIG(CELLULAR, CELLULAR_ABSENT))) GPIO_CONFIGURE_PADS(pre_mem_wwan_pwr_seq1_pads); - if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN4))) { - GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_pads); - } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN5))) { - GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads); - } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_UNKNOWN))) { - GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_pads); - GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads); - } - if (!fw_config_probe(FW_CONFIG(SD, SD_NONE))) GPIO_CONFIGURE_PADS(pre_mem_x1slot_pads); @@ -645,6 +634,14 @@ void fw_config_configure_pre_mem_gpio(void) if (fw_config_probe(FW_CONFIG(FP, FP_PRESENT))) GPIO_CONFIGURE_PADS(pre_mem_fp_enable_pads); + if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN4))) { + GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_pads); + } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN5))) { + GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads); + } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_UNKNOWN))) { + GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_pads); + GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads); + } } void fw_config_gpio_padbased_override(struct pad_config *padbased_table) diff --git a/src/mainboard/google/fatcat/variants/fatcat/gpio.c b/src/mainboard/google/fatcat/variants/fatcat/gpio.c index 13e6bbe1e3..1d12f5629f 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/gpio.c +++ b/src/mainboard/google/fatcat/variants/fatcat/gpio.c @@ -366,6 +366,11 @@ static const struct pad_config early_gpio_table[] = { PAD_CFG_NF(GPP_H07, NONE, DEEP, NF1), /* GPP_D15: SPI_TPM_INT_N */ PAD_CFG_GPI_APIC(GPP_D15, NONE, PLTRST, LEVEL, INVERT), + + /* GPP_B10: GEN4_SSD_PWREN */ + PAD_CFG_GPO(GPP_B10, 0, PLTRST), + /* GPP_B16: GEN5_SSD_PWREN */ + PAD_CFG_GPO(GPP_B16, 0, PLTRST), }; /* Pad configuration in romstage */ From 13bf2d95665bfa338b31920b51e5320249195e5f Mon Sep 17 00:00:00 2001 From: Bora Guvendik Date: Fri, 27 Feb 2026 13:18:58 -0800 Subject: [PATCH 711/789] mb/google/fatcat: Enable C1 and package C-state auto-demotion Remove explicit overrides for disable_c1_state_auto_demotion and disable_package_c_state_demotion, reverting to the SoC default behavior which allows the hardware to autonomously demote C1 and package C-states. BUG=b:455612673 TEST=Boot to OS on Google fatcat Change-Id: Ica9348e668c64ac2b27f3970b23f963ba0a2e753 Signed-off-by: Bora Guvendik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91457 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- .../google/fatcat/variants/baseboard/fatcat/devicetree.cb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/mainboard/google/fatcat/variants/baseboard/fatcat/devicetree.cb b/src/mainboard/google/fatcat/variants/baseboard/fatcat/devicetree.cb index c9b9ddb293..14dbd34db6 100644 --- a/src/mainboard/google/fatcat/variants/baseboard/fatcat/devicetree.cb +++ b/src/mainboard/google/fatcat/variants/baseboard/fatcat/devicetree.cb @@ -62,11 +62,6 @@ chip soc/intel/pantherlake # Setting TCC of 100C = Tj max (110) - TCC_Offset (10) register "tcc_offset" = "10" - # Disable C1 C-state auto-demotion - register "disable_c1_state_auto_demotion" = "true" - # Disable PKGC-state auto-demotion - register "disable_package_c_state_demotion" = "true" - # Enable Energy Reporting register "pch_pm_energy_report_enable" = "true" From b6ebb24a48d0658b75d9fa967fb052ef145abea7 Mon Sep 17 00:00:00 2001 From: Bora Guvendik Date: Thu, 22 Jan 2026 08:17:08 -0800 Subject: [PATCH 712/789] util/spd_tools/src/spd_gen/lp5.go: Support LP5X 9600Mbps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for LP5X 9600Mbps in SPD tool. BUG=None TEST=util/spd_tools/bin/spd_gen spd/lp5/memory_parts.json lp5 Change-Id: I1425fe08e3891f4a0a0627c8ab429ec72c06ffc5 Signed-off-by: Bora Guvendik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90867 Reviewed-by: Paul Menzel Reviewed-by: Ma, Zhixing Tested-by: build bot (Jenkins) Reviewed-by: Jérémy Compostella --- util/spd_tools/src/spd_gen/lp5.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/util/spd_tools/src/spd_gen/lp5.go b/util/spd_tools/src/spd_gen/lp5.go index f3586c7539..acb10abc66 100644 --- a/util/spd_tools/src/spd_gen/lp5.go +++ b/util/spd_tools/src/spd_gen/lp5.go @@ -209,6 +209,7 @@ var LP5SetInfo = map[int]LP5Set{ * = 1 / (speed grade / 2 / WCK:CK) // "double data rate" */ speedToTCKMinPs: map[int]int{ + 9600: 833, /* 1 / (9600 / 2 / 4) */ 8533: 937, /* 1 / (8533 / 2 / 4) */ 7500: 1066, /* 1 / (7500 / 2 / 4) */ 6400: 1250, /* 1 / (6400 / 2 / 4) */ @@ -374,6 +375,10 @@ var LP5BankArchToSPDEncoding = map[int]LP5BankArchParams{ * From Table 220 of JESD209-5B, using a 4:1 WCK:CK ratio and Set 0. */ var LP5SpeedMbpsToSPDEncoding = map[int]LP5SpeedParams{ + 9600: { + defaultTCKMinPs: 208, /* 1 / (9600 / 2) */ + MaxCASLatency: 26, + }, 8533: { defaultTCKMinPs: 234, /* 1 / (8533 / 2) */ MaxCASLatency: 23, From bce8d28a59b64e2d02ce804989955cf663770964 Mon Sep 17 00:00:00 2001 From: Nicholas Chin Date: Sun, 1 Mar 2026 09:56:00 -0700 Subject: [PATCH 713/789] MAINTAINERS: Add Nicholas Chin for autoport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I do push patches for autoport somewhat often (by autoport standards) and have reviewed many patches for it in the past couple of years, so add myself as a maintainer. Change-Id: I897032eea898ff254d02df4d100e27966a6fc6ae Signed-off-by: Nicholas Chin Reviewed-on: https://review.coreboot.org/c/coreboot/+/91493 Tested-by: build bot (Jenkins) Reviewed-by: Jan Philipp Groß Reviewed-by: Angel Pons Reviewed-by: Paul Menzel --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ce9b93d949..bd26cac7f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1040,6 +1040,11 @@ M: Martin Roth S: Supported F: util/abuild/ +AUTOPORT +M: Nicholas Chin +S: Maintained +F: util/autoport/ + BOARD STATUS F: util/board_status/ From e0715bc0f9c707877891604aad14d6f75f67c387 Mon Sep 17 00:00:00 2001 From: Simon Yang Date: Tue, 2 Dec 2025 14:42:12 +0800 Subject: [PATCH 714/789] soc/intel/pantherlake: Disable PCIe PM in compliance test mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When SOC_INTEL_COMPLIANCE_TEST_MODE is enabled, disable PCIe clock gating and power gating to prevent the controller from entering power management states that would interfere with PCIe compliance testing. This ensures stable operation during PCIe TX compliance tests by keeping the PCIe controller in an active state throughout the test process. Affected/Verified Platforms: - PTL: Lapis, Ruby - WCL: Matsu, Ocicat, Kodkod BUG=b:451560515 TEST="Run PCIe Compliance TX test successfully" Change-Id: I92f442d24219af78310ce04b782735beed9c58e6 Signed-off-by: Simon Yang Reviewed-on: https://review.coreboot.org/c/coreboot/+/90325 Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/fsp_params.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/soc/intel/pantherlake/fsp_params.c b/src/soc/intel/pantherlake/fsp_params.c index d447879475..226ae1677a 100644 --- a/src/soc/intel/pantherlake/fsp_params.c +++ b/src/soc/intel/pantherlake/fsp_params.c @@ -589,6 +589,10 @@ static void fill_fsps_pcie_params(FSP_S_CONFIG *s_cfg, uint32_t enable_mask = pcie_rp_enable_mask(get_pcie_rp_table()); for (size_t i = 0; i < CONFIG_MAX_ROOT_PORTS; i++) { + if (CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE)) { + s_cfg->PcieClockGating[i] = 0; + s_cfg->PciePowerGating[i] = 0; + } if (!(enable_mask & BIT(i))) continue; const struct pcie_rp_config *rp_cfg = &config->pcie_rp[i]; From 0e9c2f53b0128c0802b70d4f89dd68352665155f Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Fri, 27 Feb 2026 20:08:11 +0100 Subject: [PATCH 715/789] haswell/broadwell: Move CPU bus ops to CPU code Commit 4c4bd3cd973f ("soc/intel/broadwell: Hook up PCI domain and CPU cluster ops to devicetree") and commit 600fa266bdc8 ("nb/intel/haswell: Hook up PCI domain and CPU cluster ops to devicetree") decoupled the CPU bus device operations from northbridge code. Since Haswell and Broadwell both use the same CPU code, move the CPU bus ops to CPU code in order to deduplicate them. Change-Id: I11cbff3d87e233f40a40f2fc70840f6bf35b0cb9 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91463 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/cpu/intel/haswell/haswell_init.c | 7 +++++++ src/mainboard/google/auron/devicetree.cb | 2 +- src/mainboard/google/jecht/devicetree.cb | 2 +- src/mainboard/hp/elitebook_820_g2/devicetree.cb | 2 +- src/mainboard/intel/wtm2/devicetree.cb | 2 +- src/mainboard/purism/librem_bdw/devicetree.cb | 2 +- src/northbridge/intel/haswell/northbridge.c | 7 ------- src/soc/intel/broadwell/northbridge.c | 7 ------- 8 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/cpu/intel/haswell/haswell_init.c b/src/cpu/intel/haswell/haswell_init.c index bd8932a039..c21f3c09f8 100644 --- a/src/cpu/intel/haswell/haswell_init.c +++ b/src/cpu/intel/haswell/haswell_init.c @@ -606,6 +606,13 @@ static const struct cpu_device_id cpu_table[] = { CPU_TABLE_END }; +struct device_operations haswell_cpu_bus_ops = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, + .init = mp_cpu_bus_init, + .acpi_fill_ssdt = generate_cpu_entries, +}; + static const struct cpu_driver driver __cpu_driver = { .ops = &cpu_dev_ops, .id_table = cpu_table, diff --git a/src/mainboard/google/auron/devicetree.cb b/src/mainboard/google/auron/devicetree.cb index 49db518760..6d42e1f810 100644 --- a/src/mainboard/google/auron/devicetree.cb +++ b/src/mainboard/google/auron/devicetree.cb @@ -15,7 +15,7 @@ chip soc/intel/broadwell register "ec_present" = "true" chip cpu/intel/haswell - device cpu_cluster 0 on ops broadwell_cpu_bus_ops end + device cpu_cluster 0 on ops haswell_cpu_bus_ops end register "s0ix_enable" = "true" end diff --git a/src/mainboard/google/jecht/devicetree.cb b/src/mainboard/google/jecht/devicetree.cb index ba8167cda2..cdde70f503 100644 --- a/src/mainboard/google/jecht/devicetree.cb +++ b/src/mainboard/google/jecht/devicetree.cb @@ -12,7 +12,7 @@ chip soc/intel/broadwell register "dq_pins_interleaved" = "true" chip cpu/intel/haswell - device cpu_cluster 0 on ops broadwell_cpu_bus_ops end + device cpu_cluster 0 on ops haswell_cpu_bus_ops end end device domain 0 on diff --git a/src/mainboard/hp/elitebook_820_g2/devicetree.cb b/src/mainboard/hp/elitebook_820_g2/devicetree.cb index d6cb2ed016..626e6d56a7 100644 --- a/src/mainboard/hp/elitebook_820_g2/devicetree.cb +++ b/src/mainboard/hp/elitebook_820_g2/devicetree.cb @@ -2,7 +2,7 @@ chip soc/intel/broadwell chip cpu/intel/haswell - device cpu_cluster 0 on ops broadwell_cpu_bus_ops end + device cpu_cluster 0 on ops haswell_cpu_bus_ops end end device domain 0 on ops broadwell_pci_domain_ops diff --git a/src/mainboard/intel/wtm2/devicetree.cb b/src/mainboard/intel/wtm2/devicetree.cb index 3b3a9750aa..9e1e8a03cb 100644 --- a/src/mainboard/intel/wtm2/devicetree.cb +++ b/src/mainboard/intel/wtm2/devicetree.cb @@ -10,7 +10,7 @@ chip soc/intel/broadwell register "gpu_dp_b_hotplug" = "0x06" chip cpu/intel/haswell - device cpu_cluster 0 on ops broadwell_cpu_bus_ops end + device cpu_cluster 0 on ops haswell_cpu_bus_ops end end device domain 0 on ops broadwell_pci_domain_ops diff --git a/src/mainboard/purism/librem_bdw/devicetree.cb b/src/mainboard/purism/librem_bdw/devicetree.cb index 45350b6c13..f663afdd4c 100644 --- a/src/mainboard/purism/librem_bdw/devicetree.cb +++ b/src/mainboard/purism/librem_bdw/devicetree.cb @@ -21,7 +21,7 @@ chip soc/intel/broadwell }" chip cpu/intel/haswell - device cpu_cluster 0 on ops broadwell_cpu_bus_ops end + device cpu_cluster 0 on ops haswell_cpu_bus_ops end end device domain 0 on ops broadwell_pci_domain_ops diff --git a/src/northbridge/intel/haswell/northbridge.c b/src/northbridge/intel/haswell/northbridge.c index c544ad3c38..e819838175 100644 --- a/src/northbridge/intel/haswell/northbridge.c +++ b/src/northbridge/intel/haswell/northbridge.c @@ -534,13 +534,6 @@ static const struct pci_driver mc_driver_hsw __pci_driver = { .devices = mc_pci_device_ids, }; -struct device_operations haswell_cpu_bus_ops = { - .read_resources = noop_read_resources, - .set_resources = noop_set_resources, - .init = mp_cpu_bus_init, - .acpi_fill_ssdt = generate_cpu_entries, -}; - struct chip_operations northbridge_intel_haswell_ops = { .name = "Intel Haswell integrated Northbridge", }; diff --git a/src/soc/intel/broadwell/northbridge.c b/src/soc/intel/broadwell/northbridge.c index 3d2574ba6d..c869b31035 100644 --- a/src/soc/intel/broadwell/northbridge.c +++ b/src/soc/intel/broadwell/northbridge.c @@ -406,13 +406,6 @@ struct device_operations broadwell_pci_domain_ops = { #endif }; -struct device_operations broadwell_cpu_bus_ops = { - .read_resources = noop_read_resources, - .set_resources = noop_set_resources, - .init = mp_cpu_bus_init, - .acpi_fill_ssdt = generate_cpu_entries, -}; - static void broadwell_init_pre_device(void *chip_info) { broadwell_run_reference_code(); From 6953c591bacc93f1fc210f0d5b9e0791bbc0d7b6 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Fri, 27 Feb 2026 21:51:57 +0100 Subject: [PATCH 716/789] sb/intel/lynxpoint/acpi/serialio.asl: Add more _PS0/_PS3 methods Implementation taken from Wildcat Point (Broadwell) code. This reduces differences between both platforms. Change-Id: Id3b6efcbc416929245fcaf329521d49fee0b457f Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91464 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- .../intel/lynxpoint/acpi/serialio.asl | 130 +++++++++++++----- 1 file changed, 96 insertions(+), 34 deletions(-) diff --git a/src/southbridge/intel/lynxpoint/acpi/serialio.asl b/src/southbridge/intel/lynxpoint/acpi/serialio.asl index 845949ce98..4d26152d97 100644 --- a/src/southbridge/intel/lynxpoint/acpi/serialio.asl +++ b/src/southbridge/intel/lynxpoint/acpi/serialio.asl @@ -16,6 +16,28 @@ External (\S5EN) External (\S6EN) External (\S7EN) +// Put SerialIO device in D0 state +// Arg0 - Ref to offset 0x84 of device's PCI config space +Method (LPD0, 1, Serialized) +{ + Arg0 = DeRefOf (Arg0) & 0xFFFFFFFC + Local0 = DeRefOf (Arg0) // Read back after writing + + // Use Local0 to avoid iasl warning: Method Local is set but never used + Local0 &= Ones +} + +// Put SerialIO device in D3 state +// Arg0 - Ref to offset 0x84 of device's PCI config space +Method (LPD3, 1, Serialized) +{ + Arg0 = DeRefOf (Arg0) | 0x3 + Local0 = DeRefOf (Arg0) // Read back after writing + + // Use Local0 to avoid iasl warning: Method Local is set but never used + Local0 &= Ones +} + // Serial IO Resource Consumption for BAR1 Device (SIOR) { @@ -193,32 +215,20 @@ Device (I2C0) } } - // Access to PCI Config in ACPI mode - OperationRegion (KEYS, SystemMemory, \S1B1, 0x100) - Field (KEYS, DWordAcc, NoLock, Preserve) + OperationRegion (SPRT, SystemMemory, \S1B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) { - Offset (0x84), - PSAT, 32, + SPCS, 32 } - // Put controller in D0 state Method (_PS0, 0, Serialized) { - ^PSAT &= 0xfffffffc - Local0 = ^PSAT // Read back after writing - - // Use Local0 to avoid iasl warning: Method Local is set but never used - Local0 &= Ones + ^^LPD0 (RefOf (SPCS)) } - // Put controller in D3Hot state Method (_PS3, 0, Serialized) { - ^PSAT |= 0x00000003 - Local0 = ^PSAT // Read back after writing - - // Use Local0 to avoid iasl warning: Method Local is set but never used - Local0 &= Ones + ^^LPD3 (RefOf (SPCS)) } } @@ -273,32 +283,20 @@ Device (I2C1) } } - // Access to PCI Config in ACPI mode - OperationRegion (KEYS, SystemMemory, \S2B1, 0x100) - Field (KEYS, DWordAcc, NoLock, Preserve) + OperationRegion (SPRT, SystemMemory, \S2B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) { - Offset (0x84), - PSAT, 32, + SPCS, 32 } - // Put controller in D0 state Method (_PS0, 0, Serialized) { - ^PSAT &= 0xfffffffc - Local0 = ^PSAT // Read back after writing - - // Use Local0 to avoid iasl warning: Method Local is set but never used - Local0 &= Ones + ^^LPD0 (RefOf (SPCS)) } - // Put controller in D3Hot state Method (_PS3, 0, Serialized) { - ^PSAT |= 0x00000003 - Local0 = ^PSAT // Read back after writing - - // Use Local0 to avoid iasl warning: Method Local is set but never used - Local0 &= Ones + ^^LPD3 (RefOf (SPCS)) } } @@ -337,6 +335,22 @@ Device (SPI0) Return (0xF) } } + + OperationRegion (SPRT, SystemMemory, \S3B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) + { + SPCS, 32 + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (RefOf (SPCS)) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (RefOf (SPCS)) + } } Device (SPI1) @@ -386,6 +400,22 @@ Device (SPI1) Return (0xF) } } + + OperationRegion (SPRT, SystemMemory, \S4B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) + { + SPCS, 32 + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (RefOf (SPCS)) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (RefOf (SPCS)) + } } Device (UAR0) @@ -435,6 +465,22 @@ Device (UAR0) Return (0xF) } } + + OperationRegion (SPRT, SystemMemory, \S5B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) + { + SPCS, 32 + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (RefOf (SPCS)) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (RefOf (SPCS)) + } } Device (UAR1) @@ -472,6 +518,22 @@ Device (UAR1) Return (0xF) } } + + OperationRegion (SPRT, SystemMemory, \S6B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) + { + SPCS, 32 + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (RefOf (SPCS)) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (RefOf (SPCS)) + } } Device (SDIO) From 381ce51ec4546e690e8760a825de0876a14a3b4b Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Fri, 27 Feb 2026 20:58:06 +0100 Subject: [PATCH 717/789] sb/intel/lynxpoint/acpi: Add HIDs for Wildcat Point Prepare to unify ACPI code for Lynx Point and Wildcat Point. Change-Id: I0d70e5c8ca585d0225227831d18874cdd2cbf09d Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91465 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/southbridge/intel/lynxpoint/acpi/gpio.asl | 10 ++- .../intel/lynxpoint/acpi/serialio.asl | 70 +++++++++++++++++-- 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/southbridge/intel/lynxpoint/acpi/gpio.asl b/src/southbridge/intel/lynxpoint/acpi/gpio.asl index a673b25604..f18c5486d9 100644 --- a/src/southbridge/intel/lynxpoint/acpi/gpio.asl +++ b/src/southbridge/intel/lynxpoint/acpi/gpio.asl @@ -3,7 +3,15 @@ Device (GPIO) { // GPIO Controller - Name (_HID, "INT33C7") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3437") + } + // LynxPoint-LP + Return ("INT33C7") + } Name (_CID, "INT33C7") Name (_UID, 1) diff --git a/src/southbridge/intel/lynxpoint/acpi/serialio.asl b/src/southbridge/intel/lynxpoint/acpi/serialio.asl index 4d26152d97..95a3466709 100644 --- a/src/southbridge/intel/lynxpoint/acpi/serialio.asl +++ b/src/southbridge/intel/lynxpoint/acpi/serialio.asl @@ -167,7 +167,15 @@ Device (SDMA) Device (I2C0) { // Serial IO I2C0 Controller - Name (_HID, "INT33C2") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3432") + } + // LynxPoint-LP + Return ("INT33C2") + } Name (_CID, "INT33C2") Name (_UID, 1) @@ -235,7 +243,15 @@ Device (I2C0) Device (I2C1) { // Serial IO I2C1 Controller - Name (_HID, "INT33C3") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3433") + } + // LynxPoint-LP + Return ("INT33C3") + } Name (_CID, "INT33C3") Name (_UID, 1) @@ -303,7 +319,15 @@ Device (I2C1) Device (SPI0) { // Serial IO SPI0 Controller - Name (_HID, "INT33C0") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3430") + } + // LynxPoint-LP + Return ("INT33C0") + } Name (_CID, "INT33C0") Name (_UID, 1) @@ -356,7 +380,15 @@ Device (SPI0) Device (SPI1) { // Serial IO SPI1 Controller - Name (_HID, "INT33C1") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3431") + } + // LynxPoint-LP + Return ("INT33C1") + } Name (_CID, "INT33C1") Name (_UID, 1) @@ -421,7 +453,15 @@ Device (SPI1) Device (UAR0) { // Serial IO UART0 Controller - Name (_HID, "INT33C4") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3434") + } + // LynxPoint-LP + Return ("INT33C4") + } Name (_CID, "INT33C4") Name (_UID, 1) @@ -486,7 +526,15 @@ Device (UAR0) Device (UAR1) { // Serial IO UART1 Controller - Name (_HID, "INT33C5") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3435") + } + // LynxPoint-LP + Return ("INT33C5") + } Name (_CID, "INT33C5") Name (_UID, 1) @@ -539,7 +587,15 @@ Device (UAR1) Device (SDIO) { // Serial IO SDIO Controller - Name (_HID, "INT33C6") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3436") + } + // LynxPoint-LP + Return ("INT33C6") + } Name (_CID, "PNP0D40") Name (_UID, 1) From 8b69dcccb2f93a974e80dad82220d802a11c6d42 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sat, 28 Feb 2026 00:15:31 +0100 Subject: [PATCH 718/789] sb/intel/lynxpoint/pcie.c: Add additional disable steps Taken from Wildcat Point and checked against version 1.9.1 of PCH reference code. Note down a few TODOs to be done after Lynx Point and Wildcat Point code has been unified. Change-Id: I91aa3f0a5ea67bd43a625f37527c9d41c277b990 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91466 Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/southbridge/intel/lynxpoint/pcie.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/southbridge/intel/lynxpoint/pcie.c b/src/southbridge/intel/lynxpoint/pcie.c index 7aff60895c..19a1bcf203 100644 --- a/src/southbridge/intel/lynxpoint/pcie.c +++ b/src/southbridge/intel/lynxpoint/pcie.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -326,6 +327,26 @@ static void root_port_commit_config(void) pci_and_config16(dev, PCI_COMMAND, ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO)); + /* 8.2 Configuration of PCI Express Root Ports */ + /* TODO: This should not be done if a card is detected */ + pci_or_config32(dev, 0x338, 1 << 26); + + /* TODO: BWG specifies 50 ms timeout */ + int n = 0; + do { + u32 reg32 = pci_read_config32(dev, 0x328); + n++; + if (((reg32 & 0xff000000) == 0x01000000) || (n > 50)) + break; + udelay(100); + } while (1); + + if (n > 50) + printk(BIOS_DEBUG, "%s: Timeout waiting for 328h\n", + dev_path(dev)); + + pci_or_config32(dev, 0x408, 1 << 27); + /* Disable this device if possible */ pch_disable_devfn(dev); } From 0d2a0512fd28c179e4807d87b2860a5341fc0ab8 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sat, 28 Feb 2026 00:56:34 +0100 Subject: [PATCH 719/789] sb/intel/lynxpoint: Configure IOSF Port and Grant Count Based on Wildcat Point and checked against version 1.9.1 of PCH reference code. Note that this runs later in the init sequence, compared to Wildcat Point, as it is easier to get the values of the STRPFUSECFG registers this way. Change-Id: I0fadd33d043e66c10d29dcf8ba9724723ad70a9b Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91467 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/southbridge/intel/lynxpoint/pcie.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/southbridge/intel/lynxpoint/pcie.c b/src/southbridge/intel/lynxpoint/pcie.c index 19a1bcf203..969095207d 100644 --- a/src/southbridge/intel/lynxpoint/pcie.c +++ b/src/southbridge/intel/lynxpoint/pcie.c @@ -132,6 +132,29 @@ static void update_num_ports(void) rpc.num_ports); } +static u16 get_port_grant(u32 strpfusecfg) +{ + switch ((strpfusecfg >> 14) & 0x3) { + case 1: /* 2+1+1 */ + case 3: /* 4 */ + return 0x02; + case 2: /* 2+2 */ + return 0x22; + case 0: /* 1+1+1+1 */ + default: + return 0x00; + } +} + +static void set_iosf_port_grant_count(void) +{ + u16 reg16 = get_port_grant(rpc.strpfusecfg1) << 0; + if (!pch_is_lp()) + reg16 |= get_port_grant(rpc.strpfusecfg2) << 8; + + RCBA16(0x103c) = reg16; +} + static void root_port_init_config(struct device *dev) { int rp; @@ -308,6 +331,9 @@ static void root_port_commit_config(void) /* Perform clock gating configuration. */ pcie_enable_clock_gating(); + /* 8.13 IOSF Port Configuration and Grant Count Programming */ + set_iosf_port_grant_count(); + for (i = 0; i < rpc.num_ports; i++) { struct device *dev; From d740cee2d9bd25c7d6f003e4b611218f0f37d5dd Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 21:17:38 +0100 Subject: [PATCH 720/789] soc/intel/broadwell/pch: Move to sb/intel/wildcatpoint The PCH split was done many moons ago, in order to unify two codebases with overlapping hardware support: Haswell + Lynx Point and Broadwell. The on-package PCH found in Broadwell ULT/ULX CPUs is Wildcat Point. This change only moves the files, and does the minimal amount of edits so that boards still build. Most of those edits boil down to "find and replace". Change-Id: I29235b47970f81b5db6717801f2ab771ff980476 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91396 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/google/auron/devicetree.cb | 2 +- src/mainboard/google/auron/dsdt.asl | 4 +- .../variants/auron_paine/overridetree.cb | 2 +- .../auron/variants/auron_yuna/overridetree.cb | 2 +- .../auron/variants/buddy/overridetree.cb | 2 +- .../auron/variants/gandof/overridetree.cb | 2 +- .../auron/variants/lulu/overridetree.cb | 2 +- .../auron/variants/samus/overridetree.cb | 2 +- src/mainboard/google/jecht/devicetree.cb | 2 +- src/mainboard/google/jecht/dsdt.asl | 4 +- .../hp/elitebook_820_g2/devicetree.cb | 2 +- src/mainboard/hp/elitebook_820_g2/dsdt.asl | 4 +- src/mainboard/intel/wtm2/devicetree.cb | 2 +- src/mainboard/intel/wtm2/dsdt.asl | 4 +- src/mainboard/purism/librem_bdw/devicetree.cb | 2 +- src/mainboard/purism/librem_bdw/dsdt.asl | 4 +- .../variants/librem13v1/overridetree.cb | 2 +- .../variants/librem15v2/overridetree.cb | 2 +- src/soc/intel/broadwell/Kconfig | 4 +- src/soc/intel/broadwell/pch/Makefile.mk | 45 ----------------- .../intel/wildcatpoint}/Kconfig | 11 +++- .../intel/wildcatpoint/Makefile.mk | 50 +++++++++++++++++++ .../intel/wildcatpoint}/acpi/adsp.asl | 0 .../intel/wildcatpoint}/acpi/globalnvs.asl | 0 .../intel/wildcatpoint}/acpi/gpio.asl | 0 .../intel/wildcatpoint}/acpi/lpc.asl | 0 .../intel/wildcatpoint}/acpi/pch.asl | 0 .../intel/wildcatpoint}/acpi/pci_irqs.asl | 0 .../intel/wildcatpoint}/acpi/serialio.asl | 0 .../intel/wildcatpoint}/acpi/xhci.asl | 0 .../intel/wildcatpoint}/adsp.c | 4 +- .../intel/wildcatpoint}/bootblock.c | 0 .../intel/wildcatpoint}/chip.h | 2 +- .../intel/wildcatpoint}/early_pch.c | 4 +- .../intel/wildcatpoint}/elog.c | 0 .../intel/wildcatpoint}/fadt.c | 0 .../intel/wildcatpoint}/finalize.c | 0 .../intel/wildcatpoint}/hda.c | 0 .../intel/wildcatpoint}/lpc.c | 8 +-- .../intel/wildcatpoint}/me.c | 4 +- .../intel/wildcatpoint}/me_status.c | 0 .../intel/wildcatpoint}/pch.c | 2 +- .../intel/wildcatpoint}/pcie.c | 6 +-- .../intel/wildcatpoint}/pmutil.c | 0 .../intel/wildcatpoint}/power_state.c | 0 .../intel/wildcatpoint}/ramstage.c | 0 .../intel/wildcatpoint}/sata.c | 6 +-- .../intel/wildcatpoint}/serialio.c | 4 +- .../intel/wildcatpoint}/smi.c | 0 .../intel/wildcatpoint}/smihandler.c | 0 .../intel/wildcatpoint}/usb_debug.c | 0 .../intel/wildcatpoint}/usb_ehci.c | 0 .../intel/wildcatpoint}/usb_xhci.c | 0 53 files changed, 104 insertions(+), 92 deletions(-) delete mode 100644 src/soc/intel/broadwell/pch/Makefile.mk rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/Kconfig (93%) create mode 100644 src/southbridge/intel/wildcatpoint/Makefile.mk rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/acpi/adsp.asl (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/acpi/globalnvs.asl (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/acpi/gpio.asl (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/acpi/lpc.asl (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/acpi/pch.asl (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/acpi/pci_irqs.asl (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/acpi/serialio.asl (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/acpi/xhci.asl (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/adsp.c (96%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/bootblock.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/chip.h (97%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/early_pch.c (95%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/elog.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/fadt.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/finalize.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/hda.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/lpc.c (98%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/me.c (99%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/me_status.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/pch.c (98%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/pcie.c (98%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/pmutil.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/power_state.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/ramstage.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/sata.c (97%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/serialio.c (98%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/smi.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/smihandler.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/usb_debug.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/usb_ehci.c (100%) rename src/{soc/intel/broadwell/pch => southbridge/intel/wildcatpoint}/usb_xhci.c (100%) diff --git a/src/mainboard/google/auron/devicetree.cb b/src/mainboard/google/auron/devicetree.cb index 6d42e1f810..ff179c2ceb 100644 --- a/src/mainboard/google/auron/devicetree.cb +++ b/src/mainboard/google/auron/devicetree.cb @@ -26,7 +26,7 @@ chip soc/intel/broadwell device pci 02.0 on end # vga controller device pci 03.0 on end # mini-hd audio - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # EC range is 0x800-0x9ff register "gen1_dec" = "0x00fc0801" register "gen2_dec" = "0x00fc0901" diff --git a/src/mainboard/google/auron/dsdt.asl b/src/mainboard/google/auron/dsdt.asl index ba7f1e4324..c6453e9a24 100644 --- a/src/mainboard/google/auron/dsdt.asl +++ b/src/mainboard/google/auron/dsdt.asl @@ -17,7 +17,7 @@ DefinitionBlock( #include "acpi/thermal.asl" // global NVS and variables - #include + #include // CPU #include @@ -26,7 +26,7 @@ DefinitionBlock( Device (PCI0) { #include - #include + #include #include } } diff --git a/src/mainboard/google/auron/variants/auron_paine/overridetree.cb b/src/mainboard/google/auron/variants/auron_paine/overridetree.cb index 62e42b1718..b968ddb6bd 100644 --- a/src/mainboard/google/auron/variants/auron_paine/overridetree.cb +++ b/src/mainboard/google/auron/variants/auron_paine/overridetree.cb @@ -10,7 +10,7 @@ chip soc/intel/broadwell }" device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # DTLE DATA / EDGE values register "sata_port0_gen3_dtle" = "0x5" register "sata_port1_gen3_dtle" = "0x5" diff --git a/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb b/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb index 174463d0b7..c9d9078c46 100644 --- a/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb +++ b/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb @@ -10,7 +10,7 @@ chip soc/intel/broadwell }" device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # DTLE DATA / EDGE values register "sata_port0_gen3_dtle" = "0x7" register "sata_port1_gen3_dtle" = "0x5" diff --git a/src/mainboard/google/auron/variants/buddy/overridetree.cb b/src/mainboard/google/auron/variants/buddy/overridetree.cb index d1e217b8aa..e1bf686cc8 100644 --- a/src/mainboard/google/auron/variants/buddy/overridetree.cb +++ b/src/mainboard/google/auron/variants/buddy/overridetree.cb @@ -18,7 +18,7 @@ chip soc/intel/broadwell end device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint register "sata_devslp_disable" = "0x1" register "sio_i2c0_voltage" = "1" # 1.8V diff --git a/src/mainboard/google/auron/variants/gandof/overridetree.cb b/src/mainboard/google/auron/variants/gandof/overridetree.cb index ca5d616659..ddb7a35dfa 100644 --- a/src/mainboard/google/auron/variants/gandof/overridetree.cb +++ b/src/mainboard/google/auron/variants/gandof/overridetree.cb @@ -10,7 +10,7 @@ chip soc/intel/broadwell }" device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # DTLE DATA / EDGE values register "sata_port0_gen3_dtle" = "0x5" register "sata_port1_gen3_dtle" = "0x5" diff --git a/src/mainboard/google/auron/variants/lulu/overridetree.cb b/src/mainboard/google/auron/variants/lulu/overridetree.cb index 62e42b1718..b968ddb6bd 100644 --- a/src/mainboard/google/auron/variants/lulu/overridetree.cb +++ b/src/mainboard/google/auron/variants/lulu/overridetree.cb @@ -10,7 +10,7 @@ chip soc/intel/broadwell }" device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # DTLE DATA / EDGE values register "sata_port0_gen3_dtle" = "0x5" register "sata_port1_gen3_dtle" = "0x5" diff --git a/src/mainboard/google/auron/variants/samus/overridetree.cb b/src/mainboard/google/auron/variants/samus/overridetree.cb index b0b8a603f6..b9a6431d0e 100644 --- a/src/mainboard/google/auron/variants/samus/overridetree.cb +++ b/src/mainboard/google/auron/variants/samus/overridetree.cb @@ -26,7 +26,7 @@ chip soc/intel/broadwell end device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint register "sata_port0_gen3_tx" = "0x72" # Set I2C0 to 1.8V diff --git a/src/mainboard/google/jecht/devicetree.cb b/src/mainboard/google/jecht/devicetree.cb index cdde70f503..2f8ccdc365 100644 --- a/src/mainboard/google/jecht/devicetree.cb +++ b/src/mainboard/google/jecht/devicetree.cb @@ -21,7 +21,7 @@ chip soc/intel/broadwell device pci 02.0 on end # vga controller device pci 03.0 on end # mini-hd audio - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # SuperIO range is 0x700-0x73f register "gen2_dec" = "0x003c0701" diff --git a/src/mainboard/google/jecht/dsdt.asl b/src/mainboard/google/jecht/dsdt.asl index 1aeb08cdce..7cc8c7b9f4 100644 --- a/src/mainboard/google/jecht/dsdt.asl +++ b/src/mainboard/google/jecht/dsdt.asl @@ -18,7 +18,7 @@ DefinitionBlock( #include // global NVS and variables - #include + #include #include // CPU @@ -28,7 +28,7 @@ DefinitionBlock( Device (PCI0) { #include - #include + #include } } diff --git a/src/mainboard/hp/elitebook_820_g2/devicetree.cb b/src/mainboard/hp/elitebook_820_g2/devicetree.cb index 626e6d56a7..63df5d16d9 100644 --- a/src/mainboard/hp/elitebook_820_g2/devicetree.cb +++ b/src/mainboard/hp/elitebook_820_g2/devicetree.cb @@ -24,7 +24,7 @@ chip soc/intel/broadwell end device pci 03.0 on end # Mini-HD audio - chip soc/intel/broadwell/pch # Wildcat Point PCH + chip southbridge/intel/wildcatpoint # Wildcat Point PCH device pci 13.0 off end # Smart Sound Audio DSP device pci 14.0 on end # xHCI Controller device pci 15.0 off end # Serial I/O DMA diff --git a/src/mainboard/hp/elitebook_820_g2/dsdt.asl b/src/mainboard/hp/elitebook_820_g2/dsdt.asl index 6d7555d02e..6b1b4267d5 100644 --- a/src/mainboard/hp/elitebook_820_g2/dsdt.asl +++ b/src/mainboard/hp/elitebook_820_g2/dsdt.asl @@ -17,7 +17,7 @@ DefinitionBlock( #include "acpi/platform.asl" #include - #include + #include #include #include #include @@ -25,7 +25,7 @@ DefinitionBlock( Device (\_SB.PCI0) { #include - #include + #include #include } } diff --git a/src/mainboard/intel/wtm2/devicetree.cb b/src/mainboard/intel/wtm2/devicetree.cb index 9e1e8a03cb..0b8bd36085 100644 --- a/src/mainboard/intel/wtm2/devicetree.cb +++ b/src/mainboard/intel/wtm2/devicetree.cb @@ -18,7 +18,7 @@ chip soc/intel/broadwell device pci 02.0 on end # vga controller device pci 03.0 on end # mini-hd audio - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint register "alt_gp_smi_en" = "0x0000" register "gpe0_en_1" = "0x00000400" register "gpe0_en_2" = "0x00000000" diff --git a/src/mainboard/intel/wtm2/dsdt.asl b/src/mainboard/intel/wtm2/dsdt.asl index 9e06eb7202..26ed596067 100644 --- a/src/mainboard/intel/wtm2/dsdt.asl +++ b/src/mainboard/intel/wtm2/dsdt.asl @@ -18,7 +18,7 @@ DefinitionBlock( #include "acpi/platform.asl" // global NVS and variables - #include + #include #include // CPU @@ -28,7 +28,7 @@ DefinitionBlock( Device (PCI0) { #include - #include + #include } } diff --git a/src/mainboard/purism/librem_bdw/devicetree.cb b/src/mainboard/purism/librem_bdw/devicetree.cb index f663afdd4c..934fd7eb8b 100644 --- a/src/mainboard/purism/librem_bdw/devicetree.cb +++ b/src/mainboard/purism/librem_bdw/devicetree.cb @@ -29,7 +29,7 @@ chip soc/intel/broadwell device pci 02.0 on end # vga controller device pci 03.0 on end # mini-hd audio - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # EC host command ranges are in 0x380-0x383 & 0x80-0x8f register "gen1_dec" = "0x00000381" diff --git a/src/mainboard/purism/librem_bdw/dsdt.asl b/src/mainboard/purism/librem_bdw/dsdt.asl index a631e5a5a5..2e8b5c57e2 100644 --- a/src/mainboard/purism/librem_bdw/dsdt.asl +++ b/src/mainboard/purism/librem_bdw/dsdt.asl @@ -12,14 +12,14 @@ DefinitionBlock( { #include #include - #include + #include #include Scope (\_SB) { Device (PCI0) { #include - #include + #include #include } } diff --git a/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb b/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb index 256077cbd9..9d47ae8055 100644 --- a/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb +++ b/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb @@ -1,7 +1,7 @@ chip soc/intel/broadwell device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # Port 0 is HDD # Port 3 is M.2 NGFF register "sata_port_map" = "0x9" diff --git a/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb b/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb index 76737cc5e2..01d317e6b5 100644 --- a/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb +++ b/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb @@ -3,7 +3,7 @@ chip soc/intel/broadwell register "dq_pins_interleaved" = "true" device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # Port 0 is HDD # Port 1 is M.2 NGFF register "sata_port_map" = "0x3" diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig index 74650ff212..e20ac3f1d7 100644 --- a/src/soc/intel/broadwell/Kconfig +++ b/src/soc/intel/broadwell/Kconfig @@ -10,7 +10,7 @@ config SOC_INTEL_BROADWELL select MRC_SETTINGS_PROTECT select REG_SCRIPT select TCO_SPACE_NOT_YET_SPLIT - select INTEL_LYNXPOINT_LP + select SOUTHBRIDGE_INTEL_WILDCATPOINT help Intel Broadwell and Haswell ULT support. @@ -117,6 +117,4 @@ config REFCODE_BLOB_FILE endif # HAVE_REFCODE_BLOB -source "src/soc/intel/broadwell/pch/Kconfig" - endif diff --git a/src/soc/intel/broadwell/pch/Makefile.mk b/src/soc/intel/broadwell/pch/Makefile.mk deleted file mode 100644 index be2f4a4292..0000000000 --- a/src/soc/intel/broadwell/pch/Makefile.mk +++ /dev/null @@ -1,45 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only -bootblock-y += bootblock.c - -ramstage-y += adsp.c -romstage-y += early_pch.c -ramstage-$(CONFIG_ELOG) += elog.c -ramstage-y += finalize.c -ramstage-y += ../../../../southbridge/intel/lynxpoint/lp_gpio.c -romstage-y += ../../../../southbridge/intel/lynxpoint/lp_gpio.c -verstage-y += ../../../../southbridge/intel/lynxpoint/lp_gpio.c -smm-y += ../../../../southbridge/intel/lynxpoint/lp_gpio.c -ramstage-y += hda.c -ramstage-y += ../../../../southbridge/intel/lynxpoint/hda_verb.c -ramstage-y += ../../../../southbridge/intel/lynxpoint/iobp.c -romstage-y += ../../../../southbridge/intel/lynxpoint/iobp.c -ramstage-y += fadt.c -ramstage-y += lpc.c -ramstage-y += me.c -ramstage-y += me_status.c -romstage-y += me_status.c -ramstage-y += pch.c -romstage-y += pch.c -ramstage-y += pcie.c -ramstage-y += pmutil.c -romstage-y += pmutil.c -smm-y += pmutil.c -verstage-y += pmutil.c -romstage-y += power_state.c -ramstage-y += ramstage.c -ramstage-y += sata.c -ramstage-y += serialio.c -ramstage-y += ../../../../southbridge/intel/lynxpoint/smbus.c -ramstage-y += smi.c -smm-y += smihandler.c -bootblock-y += usb_debug.c -romstage-y += usb_debug.c -ramstage-y += usb_debug.c -ramstage-y += usb_ehci.c -ramstage-y += usb_xhci.c -smm-y += usb_xhci.c - -bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/iobp.c -bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/uart_init.c -all-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/uart.c -smm-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/uart.c diff --git a/src/soc/intel/broadwell/pch/Kconfig b/src/southbridge/intel/wildcatpoint/Kconfig similarity index 93% rename from src/soc/intel/broadwell/pch/Kconfig rename to src/southbridge/intel/wildcatpoint/Kconfig index a671207b67..424b91d832 100644 --- a/src/soc/intel/broadwell/pch/Kconfig +++ b/src/southbridge/intel/wildcatpoint/Kconfig @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -config INTEL_LYNXPOINT_LP +config SOUTHBRIDGE_INTEL_WILDCATPOINT bool select ACPI_COMMON_MADT_IOAPIC select ACPI_COMMON_MADT_LAPIC @@ -14,6 +14,7 @@ config INTEL_LYNXPOINT_LP select HAVE_SMI_HANDLER select HAVE_USBDEBUG select INTEL_DESCRIPTOR_MODE_CAPABLE + select INTEL_LYNXPOINT_LP select RTC select SOUTHBRIDGE_INTEL_COMMON_EARLY_SMBUS select SOUTHBRIDGE_INTEL_COMMON_RESET @@ -23,6 +24,12 @@ config INTEL_LYNXPOINT_LP select SPI_FLASH select TCO_SPACE_NOT_YET_SPLIT +if SOUTHBRIDGE_INTEL_WILDCATPOINT + +# Placeholder +config INTEL_LYNXPOINT_LP + bool + config EHCI_BAR hex default 0xd8000000 @@ -72,3 +79,5 @@ config DISABLE_ME_PCI Disable and hide the ME PCI interface during finalize stage of boot. This will prevent the OS (and userspace apps) from interacting with the ME via the PCI interface after boot. + +endif diff --git a/src/southbridge/intel/wildcatpoint/Makefile.mk b/src/southbridge/intel/wildcatpoint/Makefile.mk new file mode 100644 index 0000000000..ee631d44cd --- /dev/null +++ b/src/southbridge/intel/wildcatpoint/Makefile.mk @@ -0,0 +1,50 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ifeq ($(CONFIG_SOUTHBRIDGE_INTEL_WILDCATPOINT),y) + +bootblock-y += bootblock.c + +ramstage-y += adsp.c +romstage-y += early_pch.c +ramstage-$(CONFIG_ELOG) += elog.c +ramstage-y += finalize.c +ramstage-y += ../lynxpoint/lp_gpio.c +romstage-y += ../lynxpoint/lp_gpio.c +verstage-y += ../lynxpoint/lp_gpio.c +smm-y += ../lynxpoint/lp_gpio.c +ramstage-y += hda.c +ramstage-y += ../lynxpoint/hda_verb.c +ramstage-y += ../lynxpoint/iobp.c +romstage-y += ../lynxpoint/iobp.c +ramstage-y += fadt.c +ramstage-y += lpc.c +ramstage-y += me.c +ramstage-y += me_status.c +romstage-y += me_status.c +ramstage-y += pch.c +romstage-y += pch.c +ramstage-y += pcie.c +ramstage-y += pmutil.c +romstage-y += pmutil.c +smm-y += pmutil.c +verstage-y += pmutil.c +romstage-y += power_state.c +ramstage-y += ramstage.c +ramstage-y += sata.c +ramstage-y += serialio.c +ramstage-y += ../lynxpoint/smbus.c +ramstage-y += smi.c +smm-y += smihandler.c +bootblock-y += usb_debug.c +romstage-y += usb_debug.c +ramstage-y += usb_debug.c +ramstage-y += usb_ehci.c +ramstage-y += usb_xhci.c +smm-y += usb_xhci.c + +bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/iobp.c +bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/uart_init.c +all-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/uart.c +smm-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/uart.c + +endif diff --git a/src/soc/intel/broadwell/pch/acpi/adsp.asl b/src/southbridge/intel/wildcatpoint/acpi/adsp.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/adsp.asl rename to src/southbridge/intel/wildcatpoint/acpi/adsp.asl diff --git a/src/soc/intel/broadwell/pch/acpi/globalnvs.asl b/src/southbridge/intel/wildcatpoint/acpi/globalnvs.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/globalnvs.asl rename to src/southbridge/intel/wildcatpoint/acpi/globalnvs.asl diff --git a/src/soc/intel/broadwell/pch/acpi/gpio.asl b/src/southbridge/intel/wildcatpoint/acpi/gpio.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/gpio.asl rename to src/southbridge/intel/wildcatpoint/acpi/gpio.asl diff --git a/src/soc/intel/broadwell/pch/acpi/lpc.asl b/src/southbridge/intel/wildcatpoint/acpi/lpc.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/lpc.asl rename to src/southbridge/intel/wildcatpoint/acpi/lpc.asl diff --git a/src/soc/intel/broadwell/pch/acpi/pch.asl b/src/southbridge/intel/wildcatpoint/acpi/pch.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/pch.asl rename to src/southbridge/intel/wildcatpoint/acpi/pch.asl diff --git a/src/soc/intel/broadwell/pch/acpi/pci_irqs.asl b/src/southbridge/intel/wildcatpoint/acpi/pci_irqs.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/pci_irqs.asl rename to src/southbridge/intel/wildcatpoint/acpi/pci_irqs.asl diff --git a/src/soc/intel/broadwell/pch/acpi/serialio.asl b/src/southbridge/intel/wildcatpoint/acpi/serialio.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/serialio.asl rename to src/southbridge/intel/wildcatpoint/acpi/serialio.asl diff --git a/src/soc/intel/broadwell/pch/acpi/xhci.asl b/src/southbridge/intel/wildcatpoint/acpi/xhci.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/xhci.asl rename to src/southbridge/intel/wildcatpoint/acpi/xhci.asl diff --git a/src/soc/intel/broadwell/pch/adsp.c b/src/southbridge/intel/wildcatpoint/adsp.c similarity index 96% rename from src/soc/intel/broadwell/pch/adsp.c rename to src/southbridge/intel/wildcatpoint/adsp.c index 05b1e60af2..c56f9cc584 100644 --- a/src/soc/intel/broadwell/pch/adsp.c +++ b/src/southbridge/intel/wildcatpoint/adsp.c @@ -11,13 +11,13 @@ #include #include #include -#include +#include #include #include static void adsp_init(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); struct resource *bar0, *bar1; u32 tmp32; diff --git a/src/soc/intel/broadwell/pch/bootblock.c b/src/southbridge/intel/wildcatpoint/bootblock.c similarity index 100% rename from src/soc/intel/broadwell/pch/bootblock.c rename to src/southbridge/intel/wildcatpoint/bootblock.c diff --git a/src/soc/intel/broadwell/pch/chip.h b/src/southbridge/intel/wildcatpoint/chip.h similarity index 97% rename from src/soc/intel/broadwell/pch/chip.h rename to src/southbridge/intel/wildcatpoint/chip.h index 84ad8fe820..dd31645849 100644 --- a/src/soc/intel/broadwell/pch/chip.h +++ b/src/southbridge/intel/wildcatpoint/chip.h @@ -5,7 +5,7 @@ #include -struct soc_intel_broadwell_pch_config { +struct southbridge_intel_wildcatpoint_config { /* GPE configuration */ uint32_t gpe0_en_1; uint32_t gpe0_en_2; diff --git a/src/soc/intel/broadwell/pch/early_pch.c b/src/southbridge/intel/wildcatpoint/early_pch.c similarity index 95% rename from src/soc/intel/broadwell/pch/early_pch.c rename to src/southbridge/intel/wildcatpoint/early_pch.c index cb45971772..adb65e6145 100644 --- a/src/soc/intel/broadwell/pch/early_pch.c +++ b/src/southbridge/intel/wildcatpoint/early_pch.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include static void pch_route_interrupts(void) { @@ -56,7 +56,7 @@ static void pch_enable_lpc(void) if (!dev || !dev->chip_info) return; - const struct soc_intel_broadwell_pch_config *config = dev->chip_info; + const struct southbridge_intel_wildcatpoint_config *config = dev->chip_info; pci_write_config32(PCH_DEV_LPC, LPC_GEN1_DEC, config->gen1_dec); pci_write_config32(PCH_DEV_LPC, LPC_GEN2_DEC, config->gen2_dec); diff --git a/src/soc/intel/broadwell/pch/elog.c b/src/southbridge/intel/wildcatpoint/elog.c similarity index 100% rename from src/soc/intel/broadwell/pch/elog.c rename to src/southbridge/intel/wildcatpoint/elog.c diff --git a/src/soc/intel/broadwell/pch/fadt.c b/src/southbridge/intel/wildcatpoint/fadt.c similarity index 100% rename from src/soc/intel/broadwell/pch/fadt.c rename to src/southbridge/intel/wildcatpoint/fadt.c diff --git a/src/soc/intel/broadwell/pch/finalize.c b/src/southbridge/intel/wildcatpoint/finalize.c similarity index 100% rename from src/soc/intel/broadwell/pch/finalize.c rename to src/southbridge/intel/wildcatpoint/finalize.c diff --git a/src/soc/intel/broadwell/pch/hda.c b/src/southbridge/intel/wildcatpoint/hda.c similarity index 100% rename from src/soc/intel/broadwell/pch/hda.c rename to src/southbridge/intel/wildcatpoint/hda.c diff --git a/src/soc/intel/broadwell/pch/lpc.c b/src/southbridge/intel/wildcatpoint/lpc.c similarity index 98% rename from src/soc/intel/broadwell/pch/lpc.c rename to src/southbridge/intel/wildcatpoint/lpc.c index 49a36b148a..9dd2350c93 100644 --- a/src/soc/intel/broadwell/pch/lpc.c +++ b/src/southbridge/intel/wildcatpoint/lpc.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -162,7 +162,7 @@ static void pch_power_options(struct device *dev) printk(BIOS_INFO, "Set power %s after power failure.\n", state); if (dev->chip_info) { - const struct soc_intel_broadwell_pch_config *config = dev->chip_info; + const struct southbridge_intel_wildcatpoint_config *config = dev->chip_info; /* GPE setup based on device tree configuration */ enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2, @@ -326,7 +326,7 @@ static void pch_enable_mphy(void) static void pch_init_deep_sx(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = dev->chip_info; + const struct southbridge_intel_wildcatpoint_config *config = dev->chip_info; if (!config) return; @@ -575,7 +575,7 @@ static void pch_lpc_add_io_resources(struct device *dev) /* LPC Generic IO Decode range. */ if (dev->chip_info) { - const struct soc_intel_broadwell_pch_config *config = dev->chip_info; + const struct southbridge_intel_wildcatpoint_config *config = dev->chip_info; pch_lpc_add_gen_io_resources(dev, config->gen1_dec, LPC_GEN1_DEC); pch_lpc_add_gen_io_resources(dev, config->gen2_dec, LPC_GEN2_DEC); pch_lpc_add_gen_io_resources(dev, config->gen3_dec, LPC_GEN3_DEC); diff --git a/src/soc/intel/broadwell/pch/me.c b/src/southbridge/intel/wildcatpoint/me.c similarity index 99% rename from src/soc/intel/broadwell/pch/me.c rename to src/southbridge/intel/wildcatpoint/me.c index 5756bdb00d..33bf915fae 100644 --- a/src/soc/intel/broadwell/pch/me.c +++ b/src/southbridge/intel/wildcatpoint/me.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include @@ -948,7 +948,7 @@ static int intel_me_read_mbp(me_bios_payload *mbp_data, struct device *dev) /* Check whether ME is present and do basic init */ static void intel_me_init(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); me_bios_path path = intel_me_path(dev); me_bios_payload mbp_data; int mbp_ret; diff --git a/src/soc/intel/broadwell/pch/me_status.c b/src/southbridge/intel/wildcatpoint/me_status.c similarity index 100% rename from src/soc/intel/broadwell/pch/me_status.c rename to src/southbridge/intel/wildcatpoint/me_status.c diff --git a/src/soc/intel/broadwell/pch/pch.c b/src/southbridge/intel/wildcatpoint/pch.c similarity index 98% rename from src/soc/intel/broadwell/pch/pch.c rename to src/southbridge/intel/wildcatpoint/pch.c index fa03d7359a..3714a7d8a7 100644 --- a/src/soc/intel/broadwell/pch/pch.c +++ b/src/southbridge/intel/wildcatpoint/pch.c @@ -196,7 +196,7 @@ static void broadwell_pch_enable_dev(struct device *dev) } } -struct chip_operations soc_intel_broadwell_pch_ops = { +struct chip_operations southbridge_intel_wildcatpoint_ops = { .name = "Intel Broadwell PCH", .enable_dev = &broadwell_pch_enable_dev, }; diff --git a/src/soc/intel/broadwell/pch/pcie.c b/src/southbridge/intel/wildcatpoint/pcie.c similarity index 98% rename from src/soc/intel/broadwell/pch/pcie.c rename to src/southbridge/intel/wildcatpoint/pcie.c index 4847da6788..9262d3c628 100644 --- a/src/soc/intel/broadwell/pch/pcie.c +++ b/src/southbridge/intel/wildcatpoint/pcie.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -121,7 +121,7 @@ static void root_port_init_config(struct device *dev) root_port_config_update_gbe_port(); pci_or_config8(dev, 0xe2, 3 << 4); - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); rpc.coalesce = config->pcie_port_coalesce; } @@ -435,7 +435,7 @@ static void pcie_add_0x0202000_iobp(u32 reg) static void pch_pcie_early(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); int do_aspm = 0; int rp = root_port_number(dev); diff --git a/src/soc/intel/broadwell/pch/pmutil.c b/src/southbridge/intel/wildcatpoint/pmutil.c similarity index 100% rename from src/soc/intel/broadwell/pch/pmutil.c rename to src/southbridge/intel/wildcatpoint/pmutil.c diff --git a/src/soc/intel/broadwell/pch/power_state.c b/src/southbridge/intel/wildcatpoint/power_state.c similarity index 100% rename from src/soc/intel/broadwell/pch/power_state.c rename to src/southbridge/intel/wildcatpoint/power_state.c diff --git a/src/soc/intel/broadwell/pch/ramstage.c b/src/southbridge/intel/wildcatpoint/ramstage.c similarity index 100% rename from src/soc/intel/broadwell/pch/ramstage.c rename to src/southbridge/intel/wildcatpoint/ramstage.c diff --git a/src/soc/intel/broadwell/pch/sata.c b/src/southbridge/intel/wildcatpoint/sata.c similarity index 97% rename from src/soc/intel/broadwell/pch/sata.c rename to src/southbridge/intel/wildcatpoint/sata.c index 92d34c302c..d2bb5d37a1 100644 --- a/src/soc/intel/broadwell/pch/sata.c +++ b/src/southbridge/intel/wildcatpoint/sata.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include static inline u32 sir_read(struct device *dev, int idx) @@ -26,7 +26,7 @@ static inline void sir_write(struct device *dev, int idx, u32 value) static void sata_init(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); u32 reg32; u8 *abar; u16 reg16; @@ -259,7 +259,7 @@ static void sata_init(struct device *dev) static void sata_enable(struct device *dev) { /* Get the chip configuration */ - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); u16 map = 0x0060; map |= (config->sata_port_map ^ 0xf) << 8; diff --git a/src/soc/intel/broadwell/pch/serialio.c b/src/southbridge/intel/wildcatpoint/serialio.c similarity index 98% rename from src/soc/intel/broadwell/pch/serialio.c rename to src/southbridge/intel/wildcatpoint/serialio.c index 336b501b32..bc86db3098 100644 --- a/src/soc/intel/broadwell/pch/serialio.c +++ b/src/southbridge/intel/wildcatpoint/serialio.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include @@ -156,7 +156,7 @@ static void serialio_init_once(int acpi_mode) static void serialio_init(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); struct resource *bar0, *bar1; int sio_index = -1; diff --git a/src/soc/intel/broadwell/pch/smi.c b/src/southbridge/intel/wildcatpoint/smi.c similarity index 100% rename from src/soc/intel/broadwell/pch/smi.c rename to src/southbridge/intel/wildcatpoint/smi.c diff --git a/src/soc/intel/broadwell/pch/smihandler.c b/src/southbridge/intel/wildcatpoint/smihandler.c similarity index 100% rename from src/soc/intel/broadwell/pch/smihandler.c rename to src/southbridge/intel/wildcatpoint/smihandler.c diff --git a/src/soc/intel/broadwell/pch/usb_debug.c b/src/southbridge/intel/wildcatpoint/usb_debug.c similarity index 100% rename from src/soc/intel/broadwell/pch/usb_debug.c rename to src/southbridge/intel/wildcatpoint/usb_debug.c diff --git a/src/soc/intel/broadwell/pch/usb_ehci.c b/src/southbridge/intel/wildcatpoint/usb_ehci.c similarity index 100% rename from src/soc/intel/broadwell/pch/usb_ehci.c rename to src/southbridge/intel/wildcatpoint/usb_ehci.c diff --git a/src/soc/intel/broadwell/pch/usb_xhci.c b/src/southbridge/intel/wildcatpoint/usb_xhci.c similarity index 100% rename from src/soc/intel/broadwell/pch/usb_xhci.c rename to src/southbridge/intel/wildcatpoint/usb_xhci.c From 0bc5746188e48f61f093737284d9552fa922428b Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 21:25:27 +0100 Subject: [PATCH 721/789] soc/intel/broadwell: Move to nb/intel/broadwell In preparation to unify the Haswell and Broadwell codebases, move the remaining Broadwell SoC code to the northbridge folder. This change only moves the files, and does the minimal amount of edits so that boards still build. Most of those edits boil down to "find and replace". Change-Id: I5bde032ee824a90328a78403ea03d39ad20f2b09 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91397 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/google/auron/devicetree.cb | 2 +- src/mainboard/google/auron/dsdt.asl | 2 +- .../google/auron/variants/auron_paine/overridetree.cb | 2 +- .../google/auron/variants/auron_yuna/overridetree.cb | 2 +- .../google/auron/variants/buddy/overridetree.cb | 2 +- .../google/auron/variants/gandof/overridetree.cb | 2 +- .../google/auron/variants/lulu/overridetree.cb | 2 +- .../google/auron/variants/samus/overridetree.cb | 2 +- src/mainboard/google/jecht/devicetree.cb | 2 +- src/mainboard/google/jecht/dsdt.asl | 2 +- src/mainboard/hp/elitebook_820_g2/devicetree.cb | 2 +- src/mainboard/hp/elitebook_820_g2/dsdt.asl | 2 +- src/mainboard/intel/wtm2/devicetree.cb | 2 +- src/mainboard/intel/wtm2/dsdt.asl | 2 +- src/mainboard/purism/librem_bdw/devicetree.cb | 2 +- src/mainboard/purism/librem_bdw/dsdt.asl | 2 +- .../librem_bdw/variants/librem13v1/overridetree.cb | 2 +- .../librem_bdw/variants/librem15v2/overridetree.cb | 2 +- src/{soc => northbridge}/intel/broadwell/Kconfig | 0 src/{soc => northbridge}/intel/broadwell/Makefile.mk | 5 ++--- src/{soc => northbridge}/intel/broadwell/acpi.c | 2 +- .../intel/broadwell/acpi/device_nvs.asl | 0 .../intel/broadwell/acpi/platform.asl | 2 +- src/{soc => northbridge}/intel/broadwell/bootblock.c | 0 src/{soc => northbridge}/intel/broadwell/chip.h | 2 +- src/{soc => northbridge}/intel/broadwell/early_init.c | 0 src/{soc => northbridge}/intel/broadwell/finalize.c | 0 src/{soc => northbridge}/intel/broadwell/gma.c | 10 +++++----- .../intel/broadwell/include/soc/acpi.h | 0 .../intel/broadwell/include/soc/adsp.h | 0 .../intel/broadwell/include/soc/cfr.h | 2 +- .../intel/broadwell/include/soc/chromeos.h | 0 .../intel/broadwell/include/soc/device_nvs.h | 0 .../intel/broadwell/include/soc/ehci.h | 0 .../intel/broadwell/include/soc/gpio.h | 0 .../intel/broadwell/include/soc/igd.h | 0 .../intel/broadwell/include/soc/iomap.h | 0 .../intel/broadwell/include/soc/lpc.h | 0 .../intel/broadwell/include/soc/me.h | 0 .../intel/broadwell/include/soc/nvs.h | 0 .../intel/broadwell/include/soc/pch.h | 0 .../intel/broadwell/include/soc/pci_devs.h | 0 .../intel/broadwell/include/soc/pei_data.h | 0 .../intel/broadwell/include/soc/pei_wrapper.h | 0 .../intel/broadwell/include/soc/pm.h | 0 .../intel/broadwell/include/soc/rcba.h | 0 .../intel/broadwell/include/soc/refcode.h | 0 .../intel/broadwell/include/soc/romstage.h | 0 .../intel/broadwell/include/soc/sata.h | 0 .../intel/broadwell/include/soc/serialio.h | 0 .../intel/broadwell/include/soc/spi.h | 0 .../intel/broadwell/include/soc/systemagent.h | 0 .../intel/broadwell/include/soc/xhci.h | 0 src/{soc => northbridge}/intel/broadwell/memmap.c | 0 src/{soc => northbridge}/intel/broadwell/minihd.c | 0 src/{soc => northbridge}/intel/broadwell/northbridge.c | 2 +- src/{soc => northbridge}/intel/broadwell/pei_data.c | 4 ++-- src/{soc => northbridge}/intel/broadwell/raminit.c | 0 src/{soc => northbridge}/intel/broadwell/refcode.c | 0 .../intel/broadwell/report_platform.c | 0 src/{soc => northbridge}/intel/broadwell/romstage.c | 0 src/{soc => northbridge}/intel/broadwell/spd.c | 0 src/southbridge/intel/wildcatpoint/ramstage.c | 2 +- 63 files changed, 33 insertions(+), 34 deletions(-) rename src/{soc => northbridge}/intel/broadwell/Kconfig (100%) rename src/{soc => northbridge}/intel/broadwell/Makefile.mk (94%) rename src/{soc => northbridge}/intel/broadwell/acpi.c (98%) rename src/{soc => northbridge}/intel/broadwell/acpi/device_nvs.asl (100%) rename src/{soc => northbridge}/intel/broadwell/acpi/platform.asl (90%) rename src/{soc => northbridge}/intel/broadwell/bootblock.c (100%) rename src/{soc => northbridge}/intel/broadwell/chip.h (94%) rename src/{soc => northbridge}/intel/broadwell/early_init.c (100%) rename src/{soc => northbridge}/intel/broadwell/finalize.c (100%) rename src/{soc => northbridge}/intel/broadwell/gma.c (98%) rename src/{soc => northbridge}/intel/broadwell/include/soc/acpi.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/adsp.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/cfr.h (95%) rename src/{soc => northbridge}/intel/broadwell/include/soc/chromeos.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/device_nvs.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/ehci.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/gpio.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/igd.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/iomap.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/lpc.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/me.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/nvs.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/pch.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/pci_devs.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/pei_data.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/pei_wrapper.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/pm.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/rcba.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/refcode.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/romstage.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/sata.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/serialio.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/spi.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/systemagent.h (100%) rename src/{soc => northbridge}/intel/broadwell/include/soc/xhci.h (100%) rename src/{soc => northbridge}/intel/broadwell/memmap.c (100%) rename src/{soc => northbridge}/intel/broadwell/minihd.c (100%) rename src/{soc => northbridge}/intel/broadwell/northbridge.c (99%) rename src/{soc => northbridge}/intel/broadwell/pei_data.c (89%) rename src/{soc => northbridge}/intel/broadwell/raminit.c (100%) rename src/{soc => northbridge}/intel/broadwell/refcode.c (100%) rename src/{soc => northbridge}/intel/broadwell/report_platform.c (100%) rename src/{soc => northbridge}/intel/broadwell/romstage.c (100%) rename src/{soc => northbridge}/intel/broadwell/spd.c (100%) diff --git a/src/mainboard/google/auron/devicetree.cb b/src/mainboard/google/auron/devicetree.cb index ff179c2ceb..3534ac9ea2 100644 --- a/src/mainboard/google/auron/devicetree.cb +++ b/src/mainboard/google/auron/devicetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell # IGD Displays register "gfx" = "GMA_STATIC_DISPLAYS(0)" diff --git a/src/mainboard/google/auron/dsdt.asl b/src/mainboard/google/auron/dsdt.asl index c6453e9a24..9505158f3c 100644 --- a/src/mainboard/google/auron/dsdt.asl +++ b/src/mainboard/google/auron/dsdt.asl @@ -11,7 +11,7 @@ DefinitionBlock( ) { #include - #include + #include // Thermal handler #include "acpi/thermal.asl" diff --git a/src/mainboard/google/auron/variants/auron_paine/overridetree.cb b/src/mainboard/google/auron/variants/auron_paine/overridetree.cb index b968ddb6bd..b18f1d77a3 100644 --- a/src/mainboard/google/auron/variants/auron_paine/overridetree.cb +++ b/src/mainboard/google/auron/variants/auron_paine/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "panel_cfg" = "{ .up_delay_ms = 40, diff --git a/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb b/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb index c9d9078c46..d658643130 100644 --- a/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb +++ b/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "panel_cfg" = "{ .up_delay_ms = 40, diff --git a/src/mainboard/google/auron/variants/buddy/overridetree.cb b/src/mainboard/google/auron/variants/buddy/overridetree.cb index e1bf686cc8..81fecac9c7 100644 --- a/src/mainboard/google/auron/variants/buddy/overridetree.cb +++ b/src/mainboard/google/auron/variants/buddy/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "panel_cfg" = "{ .up_delay_ms = 40, diff --git a/src/mainboard/google/auron/variants/gandof/overridetree.cb b/src/mainboard/google/auron/variants/gandof/overridetree.cb index ddb7a35dfa..c74f9f80b4 100644 --- a/src/mainboard/google/auron/variants/gandof/overridetree.cb +++ b/src/mainboard/google/auron/variants/gandof/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "panel_cfg" = "{ .up_delay_ms = 40, diff --git a/src/mainboard/google/auron/variants/lulu/overridetree.cb b/src/mainboard/google/auron/variants/lulu/overridetree.cb index b968ddb6bd..b18f1d77a3 100644 --- a/src/mainboard/google/auron/variants/lulu/overridetree.cb +++ b/src/mainboard/google/auron/variants/lulu/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "panel_cfg" = "{ .up_delay_ms = 40, diff --git a/src/mainboard/google/auron/variants/samus/overridetree.cb b/src/mainboard/google/auron/variants/samus/overridetree.cb index b9a6431d0e..013c3133ea 100644 --- a/src/mainboard/google/auron/variants/samus/overridetree.cb +++ b/src/mainboard/google/auron/variants/samus/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell # Enable DDI2 Hotplug with 6ms pulse register "gpu_dp_c_hotplug" = "0x06" diff --git a/src/mainboard/google/jecht/devicetree.cb b/src/mainboard/google/jecht/devicetree.cb index 2f8ccdc365..8de489c0ee 100644 --- a/src/mainboard/google/jecht/devicetree.cb +++ b/src/mainboard/google/jecht/devicetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell # Disable eDP Hotplug register "gpu_dp_d_hotplug" = "0x00" diff --git a/src/mainboard/google/jecht/dsdt.asl b/src/mainboard/google/jecht/dsdt.asl index 7cc8c7b9f4..8e76080411 100644 --- a/src/mainboard/google/jecht/dsdt.asl +++ b/src/mainboard/google/jecht/dsdt.asl @@ -19,7 +19,7 @@ DefinitionBlock( // global NVS and variables #include - #include + #include // CPU #include diff --git a/src/mainboard/hp/elitebook_820_g2/devicetree.cb b/src/mainboard/hp/elitebook_820_g2/devicetree.cb index 63df5d16d9..1641472522 100644 --- a/src/mainboard/hp/elitebook_820_g2/devicetree.cb +++ b/src/mainboard/hp/elitebook_820_g2/devicetree.cb @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-or-later -chip soc/intel/broadwell +chip northbridge/intel/broadwell chip cpu/intel/haswell device cpu_cluster 0 on ops haswell_cpu_bus_ops end end diff --git a/src/mainboard/hp/elitebook_820_g2/dsdt.asl b/src/mainboard/hp/elitebook_820_g2/dsdt.asl index 6b1b4267d5..bb744911a3 100644 --- a/src/mainboard/hp/elitebook_820_g2/dsdt.asl +++ b/src/mainboard/hp/elitebook_820_g2/dsdt.asl @@ -18,7 +18,7 @@ DefinitionBlock( #include #include - #include + #include #include #include diff --git a/src/mainboard/intel/wtm2/devicetree.cb b/src/mainboard/intel/wtm2/devicetree.cb index 0b8bd36085..453a45a70a 100644 --- a/src/mainboard/intel/wtm2/devicetree.cb +++ b/src/mainboard/intel/wtm2/devicetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell # Enable DisplayPort 1 Hotplug with 6ms pulse register "gpu_dp_d_hotplug" = "0x06" diff --git a/src/mainboard/intel/wtm2/dsdt.asl b/src/mainboard/intel/wtm2/dsdt.asl index 26ed596067..efa50eb92d 100644 --- a/src/mainboard/intel/wtm2/dsdt.asl +++ b/src/mainboard/intel/wtm2/dsdt.asl @@ -19,7 +19,7 @@ DefinitionBlock( // global NVS and variables #include - #include + #include // CPU #include diff --git a/src/mainboard/purism/librem_bdw/devicetree.cb b/src/mainboard/purism/librem_bdw/devicetree.cb index 934fd7eb8b..86d2cc2bbd 100644 --- a/src/mainboard/purism/librem_bdw/devicetree.cb +++ b/src/mainboard/purism/librem_bdw/devicetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell # IGD Displays register "gfx" = "GMA_STATIC_DISPLAYS(0)" diff --git a/src/mainboard/purism/librem_bdw/dsdt.asl b/src/mainboard/purism/librem_bdw/dsdt.asl index 2e8b5c57e2..7439e941de 100644 --- a/src/mainboard/purism/librem_bdw/dsdt.asl +++ b/src/mainboard/purism/librem_bdw/dsdt.asl @@ -11,7 +11,7 @@ DefinitionBlock( ) { #include - #include + #include #include #include diff --git a/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb b/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb index 9d47ae8055..1a8a469ea4 100644 --- a/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb +++ b/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell device domain 0 on chip southbridge/intel/wildcatpoint diff --git a/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb b/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb index 01d317e6b5..e2a66d8357 100644 --- a/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb +++ b/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "dq_pins_interleaved" = "true" diff --git a/src/soc/intel/broadwell/Kconfig b/src/northbridge/intel/broadwell/Kconfig similarity index 100% rename from src/soc/intel/broadwell/Kconfig rename to src/northbridge/intel/broadwell/Kconfig diff --git a/src/soc/intel/broadwell/Makefile.mk b/src/northbridge/intel/broadwell/Makefile.mk similarity index 94% rename from src/soc/intel/broadwell/Makefile.mk rename to src/northbridge/intel/broadwell/Makefile.mk index 3565cd180b..16576371ae 100644 --- a/src/soc/intel/broadwell/Makefile.mk +++ b/src/northbridge/intel/broadwell/Makefile.mk @@ -1,7 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -ifeq ($(CONFIG_SOC_INTEL_BROADWELL),y) -subdirs-y += pch +ifeq ($(CONFIG_SOC_INTEL_BROADWELL),y) bootblock-y += bootblock.c @@ -23,7 +22,7 @@ ramstage-y += pei_data.c romstage-y += pei_data.c ramstage-$(CONFIG_HAVE_REFCODE_BLOB) += refcode.c -CPPFLAGS_common += -Isrc/soc/intel/broadwell/include +CPPFLAGS_common += -Isrc/northbridge/intel/broadwell/include # If an MRC file is an ELF file determine the entry address and first loadable # section offset in the file. Subtract the offset from the entry address to diff --git a/src/soc/intel/broadwell/acpi.c b/src/northbridge/intel/broadwell/acpi.c similarity index 98% rename from src/soc/intel/broadwell/acpi.c rename to src/northbridge/intel/broadwell/acpi.c index 4c1cdf3392..7ca60c1f59 100644 --- a/src/soc/intel/broadwell/acpi.c +++ b/src/northbridge/intel/broadwell/acpi.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include static unsigned long acpi_fill_dmar(unsigned long current) { diff --git a/src/soc/intel/broadwell/acpi/device_nvs.asl b/src/northbridge/intel/broadwell/acpi/device_nvs.asl similarity index 100% rename from src/soc/intel/broadwell/acpi/device_nvs.asl rename to src/northbridge/intel/broadwell/acpi/device_nvs.asl diff --git a/src/soc/intel/broadwell/acpi/platform.asl b/src/northbridge/intel/broadwell/acpi/platform.asl similarity index 90% rename from src/soc/intel/broadwell/acpi/platform.asl rename to src/northbridge/intel/broadwell/acpi/platform.asl index fe254ff6f0..3a57f995d1 100644 --- a/src/soc/intel/broadwell/acpi/platform.asl +++ b/src/northbridge/intel/broadwell/acpi/platform.asl @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include +#include #include /* diff --git a/src/soc/intel/broadwell/bootblock.c b/src/northbridge/intel/broadwell/bootblock.c similarity index 100% rename from src/soc/intel/broadwell/bootblock.c rename to src/northbridge/intel/broadwell/bootblock.c diff --git a/src/soc/intel/broadwell/chip.h b/src/northbridge/intel/broadwell/chip.h similarity index 94% rename from src/soc/intel/broadwell/chip.h rename to src/northbridge/intel/broadwell/chip.h index 2b5cccd56e..6b02f59ed3 100644 --- a/src/soc/intel/broadwell/chip.h +++ b/src/northbridge/intel/broadwell/chip.h @@ -6,7 +6,7 @@ #include #include -struct soc_intel_broadwell_config { +struct northbridge_intel_broadwell_config { /* * Digital Port Hotplug Enable: * 0x04 = Enabled, 2ms short pulse diff --git a/src/soc/intel/broadwell/early_init.c b/src/northbridge/intel/broadwell/early_init.c similarity index 100% rename from src/soc/intel/broadwell/early_init.c rename to src/northbridge/intel/broadwell/early_init.c diff --git a/src/soc/intel/broadwell/finalize.c b/src/northbridge/intel/broadwell/finalize.c similarity index 100% rename from src/soc/intel/broadwell/finalize.c rename to src/northbridge/intel/broadwell/finalize.c diff --git a/src/soc/intel/broadwell/gma.c b/src/northbridge/intel/broadwell/gma.c similarity index 98% rename from src/soc/intel/broadwell/gma.c rename to src/northbridge/intel/broadwell/gma.c index 639a945d75..a166b7998b 100644 --- a/src/soc/intel/broadwell/gma.c +++ b/src/northbridge/intel/broadwell/gma.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -285,7 +285,7 @@ int gtt_poll(u32 reg, u32 mask, u32 value) static void gma_setup_panel(struct device *dev) { - struct soc_intel_broadwell_config *conf = config_of(dev); + struct northbridge_intel_broadwell_config *conf = config_of(dev); const struct i915_gpu_panel_config *panel_cfg = &conf->panel_cfg; u32 reg32; @@ -362,7 +362,7 @@ static void gma_setup_panel(struct device *dev) static int igd_get_cdclk_haswell(u32 *const cdsel, int *const inform_pc, struct device *const dev) { - const struct soc_intel_broadwell_config *const conf = config_of(dev); + const struct northbridge_intel_broadwell_config *const conf = config_of(dev); int cdclk = conf->cdclk; /* Check for ULX GT1 or GT2 */ @@ -397,7 +397,7 @@ static int igd_get_cdclk_broadwell(u32 *const cdsel, int *const inform_pc, struct device *const dev) { static const u32 cdsel_by_cdclk[] = { 0, 2, 0, 1, 3 }; - const struct soc_intel_broadwell_config *const conf = config_of(dev); + const struct northbridge_intel_broadwell_config *const conf = config_of(dev); int cdclk = conf->cdclk; /* Check for ULX */ @@ -576,7 +576,7 @@ static void igd_init(struct device *dev) static void gma_generate_ssdt(const struct device *dev) { - const struct soc_intel_broadwell_config *chip = dev->chip_info; + const struct northbridge_intel_broadwell_config *chip = dev->chip_info; drivers_intel_gma_displays_ssdt_generate(&chip->gfx); } diff --git a/src/soc/intel/broadwell/include/soc/acpi.h b/src/northbridge/intel/broadwell/include/soc/acpi.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/acpi.h rename to src/northbridge/intel/broadwell/include/soc/acpi.h diff --git a/src/soc/intel/broadwell/include/soc/adsp.h b/src/northbridge/intel/broadwell/include/soc/adsp.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/adsp.h rename to src/northbridge/intel/broadwell/include/soc/adsp.h diff --git a/src/soc/intel/broadwell/include/soc/cfr.h b/src/northbridge/intel/broadwell/include/soc/cfr.h similarity index 95% rename from src/soc/intel/broadwell/include/soc/cfr.h rename to src/northbridge/intel/broadwell/include/soc/cfr.h index 91dc9048c7..7f1e604e14 100644 --- a/src/soc/intel/broadwell/include/soc/cfr.h +++ b/src/northbridge/intel/broadwell/include/soc/cfr.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * CFR enums and structs for soc/intel/broadwell + * CFR enums and structs for northbridge/intel/broadwell */ #ifndef _BROADWELL_CFR_H_ diff --git a/src/soc/intel/broadwell/include/soc/chromeos.h b/src/northbridge/intel/broadwell/include/soc/chromeos.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/chromeos.h rename to src/northbridge/intel/broadwell/include/soc/chromeos.h diff --git a/src/soc/intel/broadwell/include/soc/device_nvs.h b/src/northbridge/intel/broadwell/include/soc/device_nvs.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/device_nvs.h rename to src/northbridge/intel/broadwell/include/soc/device_nvs.h diff --git a/src/soc/intel/broadwell/include/soc/ehci.h b/src/northbridge/intel/broadwell/include/soc/ehci.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/ehci.h rename to src/northbridge/intel/broadwell/include/soc/ehci.h diff --git a/src/soc/intel/broadwell/include/soc/gpio.h b/src/northbridge/intel/broadwell/include/soc/gpio.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/gpio.h rename to src/northbridge/intel/broadwell/include/soc/gpio.h diff --git a/src/soc/intel/broadwell/include/soc/igd.h b/src/northbridge/intel/broadwell/include/soc/igd.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/igd.h rename to src/northbridge/intel/broadwell/include/soc/igd.h diff --git a/src/soc/intel/broadwell/include/soc/iomap.h b/src/northbridge/intel/broadwell/include/soc/iomap.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/iomap.h rename to src/northbridge/intel/broadwell/include/soc/iomap.h diff --git a/src/soc/intel/broadwell/include/soc/lpc.h b/src/northbridge/intel/broadwell/include/soc/lpc.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/lpc.h rename to src/northbridge/intel/broadwell/include/soc/lpc.h diff --git a/src/soc/intel/broadwell/include/soc/me.h b/src/northbridge/intel/broadwell/include/soc/me.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/me.h rename to src/northbridge/intel/broadwell/include/soc/me.h diff --git a/src/soc/intel/broadwell/include/soc/nvs.h b/src/northbridge/intel/broadwell/include/soc/nvs.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/nvs.h rename to src/northbridge/intel/broadwell/include/soc/nvs.h diff --git a/src/soc/intel/broadwell/include/soc/pch.h b/src/northbridge/intel/broadwell/include/soc/pch.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/pch.h rename to src/northbridge/intel/broadwell/include/soc/pch.h diff --git a/src/soc/intel/broadwell/include/soc/pci_devs.h b/src/northbridge/intel/broadwell/include/soc/pci_devs.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/pci_devs.h rename to src/northbridge/intel/broadwell/include/soc/pci_devs.h diff --git a/src/soc/intel/broadwell/include/soc/pei_data.h b/src/northbridge/intel/broadwell/include/soc/pei_data.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/pei_data.h rename to src/northbridge/intel/broadwell/include/soc/pei_data.h diff --git a/src/soc/intel/broadwell/include/soc/pei_wrapper.h b/src/northbridge/intel/broadwell/include/soc/pei_wrapper.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/pei_wrapper.h rename to src/northbridge/intel/broadwell/include/soc/pei_wrapper.h diff --git a/src/soc/intel/broadwell/include/soc/pm.h b/src/northbridge/intel/broadwell/include/soc/pm.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/pm.h rename to src/northbridge/intel/broadwell/include/soc/pm.h diff --git a/src/soc/intel/broadwell/include/soc/rcba.h b/src/northbridge/intel/broadwell/include/soc/rcba.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/rcba.h rename to src/northbridge/intel/broadwell/include/soc/rcba.h diff --git a/src/soc/intel/broadwell/include/soc/refcode.h b/src/northbridge/intel/broadwell/include/soc/refcode.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/refcode.h rename to src/northbridge/intel/broadwell/include/soc/refcode.h diff --git a/src/soc/intel/broadwell/include/soc/romstage.h b/src/northbridge/intel/broadwell/include/soc/romstage.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/romstage.h rename to src/northbridge/intel/broadwell/include/soc/romstage.h diff --git a/src/soc/intel/broadwell/include/soc/sata.h b/src/northbridge/intel/broadwell/include/soc/sata.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/sata.h rename to src/northbridge/intel/broadwell/include/soc/sata.h diff --git a/src/soc/intel/broadwell/include/soc/serialio.h b/src/northbridge/intel/broadwell/include/soc/serialio.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/serialio.h rename to src/northbridge/intel/broadwell/include/soc/serialio.h diff --git a/src/soc/intel/broadwell/include/soc/spi.h b/src/northbridge/intel/broadwell/include/soc/spi.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/spi.h rename to src/northbridge/intel/broadwell/include/soc/spi.h diff --git a/src/soc/intel/broadwell/include/soc/systemagent.h b/src/northbridge/intel/broadwell/include/soc/systemagent.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/systemagent.h rename to src/northbridge/intel/broadwell/include/soc/systemagent.h diff --git a/src/soc/intel/broadwell/include/soc/xhci.h b/src/northbridge/intel/broadwell/include/soc/xhci.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/xhci.h rename to src/northbridge/intel/broadwell/include/soc/xhci.h diff --git a/src/soc/intel/broadwell/memmap.c b/src/northbridge/intel/broadwell/memmap.c similarity index 100% rename from src/soc/intel/broadwell/memmap.c rename to src/northbridge/intel/broadwell/memmap.c diff --git a/src/soc/intel/broadwell/minihd.c b/src/northbridge/intel/broadwell/minihd.c similarity index 100% rename from src/soc/intel/broadwell/minihd.c rename to src/northbridge/intel/broadwell/minihd.c diff --git a/src/soc/intel/broadwell/northbridge.c b/src/northbridge/intel/broadwell/northbridge.c similarity index 99% rename from src/soc/intel/broadwell/northbridge.c rename to src/northbridge/intel/broadwell/northbridge.c index c869b31035..771df81044 100644 --- a/src/soc/intel/broadwell/northbridge.c +++ b/src/northbridge/intel/broadwell/northbridge.c @@ -411,7 +411,7 @@ static void broadwell_init_pre_device(void *chip_info) broadwell_run_reference_code(); } -struct chip_operations soc_intel_broadwell_ops = { +struct chip_operations northbridge_intel_broadwell_ops = { .name = "Intel Broadwell", .init = &broadwell_init_pre_device, }; diff --git a/src/soc/intel/broadwell/pei_data.c b/src/northbridge/intel/broadwell/pei_data.c similarity index 89% rename from src/soc/intel/broadwell/pei_data.c rename to src/northbridge/intel/broadwell/pei_data.c index 4853294e90..28adb30e15 100644 --- a/src/soc/intel/broadwell/pei_data.c +++ b/src/northbridge/intel/broadwell/pei_data.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include static void ABI_X86 send_to_console(unsigned char b) @@ -15,7 +15,7 @@ static void ABI_X86 send_to_console(unsigned char b) void broadwell_fill_pei_data(struct pei_data *pei_data) { - const struct soc_intel_broadwell_config *cfg = config_of_soc(); + const struct northbridge_intel_broadwell_config *cfg = config_of_soc(); pei_data->pei_version = PEI_VERSION; pei_data->board_type = BOARD_TYPE_ULT; diff --git a/src/soc/intel/broadwell/raminit.c b/src/northbridge/intel/broadwell/raminit.c similarity index 100% rename from src/soc/intel/broadwell/raminit.c rename to src/northbridge/intel/broadwell/raminit.c diff --git a/src/soc/intel/broadwell/refcode.c b/src/northbridge/intel/broadwell/refcode.c similarity index 100% rename from src/soc/intel/broadwell/refcode.c rename to src/northbridge/intel/broadwell/refcode.c diff --git a/src/soc/intel/broadwell/report_platform.c b/src/northbridge/intel/broadwell/report_platform.c similarity index 100% rename from src/soc/intel/broadwell/report_platform.c rename to src/northbridge/intel/broadwell/report_platform.c diff --git a/src/soc/intel/broadwell/romstage.c b/src/northbridge/intel/broadwell/romstage.c similarity index 100% rename from src/soc/intel/broadwell/romstage.c rename to src/northbridge/intel/broadwell/romstage.c diff --git a/src/soc/intel/broadwell/spd.c b/src/northbridge/intel/broadwell/spd.c similarity index 100% rename from src/soc/intel/broadwell/spd.c rename to src/northbridge/intel/broadwell/spd.c diff --git a/src/southbridge/intel/wildcatpoint/ramstage.c b/src/southbridge/intel/wildcatpoint/ramstage.c index 027b3bb1c9..19105ff799 100644 --- a/src/southbridge/intel/wildcatpoint/ramstage.c +++ b/src/southbridge/intel/wildcatpoint/ramstage.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include /* Save bit index for PM1_STS and GPE_STS for ACPI _SWS */ static void pm_fill_gnvs(struct global_nvs *gnvs, const struct chipset_power_state *ps) From 4eb0fd7bea3fbee4fe46e84b4b3d26844e3a2ce0 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 21:43:00 +0100 Subject: [PATCH 722/789] nb/intel/broadwell: Move PCH headers to wildcatpoint Since this used to be a SoC (no distinction between CPU/NB/SB parts), all the headers were in a single place. Move headers about PCH things to where they belong. Change-Id: I296f57f5575d026ad87698e972eb9f448d54d09b Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91398 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/southbridge/intel/wildcatpoint/Makefile.mk | 2 ++ .../intel/wildcatpoint}/include/soc/adsp.h | 0 .../intel/wildcatpoint}/include/soc/cfr.h | 0 .../intel/wildcatpoint}/include/soc/chromeos.h | 0 .../intel/wildcatpoint}/include/soc/ehci.h | 0 .../intel/wildcatpoint}/include/soc/gpio.h | 0 .../intel/wildcatpoint}/include/soc/iomap.h | 0 .../intel/wildcatpoint}/include/soc/lpc.h | 0 .../intel/wildcatpoint}/include/soc/me.h | 0 .../intel/wildcatpoint}/include/soc/nvs.h | 0 .../intel/wildcatpoint}/include/soc/pch.h | 0 .../intel/wildcatpoint}/include/soc/pm.h | 0 .../intel/wildcatpoint}/include/soc/rcba.h | 0 .../intel/wildcatpoint}/include/soc/sata.h | 0 .../intel/wildcatpoint}/include/soc/serialio.h | 0 .../intel/wildcatpoint}/include/soc/spi.h | 0 .../intel/wildcatpoint}/include/soc/xhci.h | 0 17 files changed, 2 insertions(+) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/adsp.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/cfr.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/chromeos.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/ehci.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/gpio.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/iomap.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/lpc.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/me.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/nvs.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/pch.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/pm.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/rcba.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/sata.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/serialio.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/spi.h (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/xhci.h (100%) diff --git a/src/southbridge/intel/wildcatpoint/Makefile.mk b/src/southbridge/intel/wildcatpoint/Makefile.mk index ee631d44cd..ec54db4632 100644 --- a/src/southbridge/intel/wildcatpoint/Makefile.mk +++ b/src/southbridge/intel/wildcatpoint/Makefile.mk @@ -47,4 +47,6 @@ bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/uart_init.c all-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/uart.c smm-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/uart.c +CPPFLAGS_common += -Isrc/southbridge/intel/wildcatpoint/include + endif diff --git a/src/northbridge/intel/broadwell/include/soc/adsp.h b/src/southbridge/intel/wildcatpoint/include/soc/adsp.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/adsp.h rename to src/southbridge/intel/wildcatpoint/include/soc/adsp.h diff --git a/src/northbridge/intel/broadwell/include/soc/cfr.h b/src/southbridge/intel/wildcatpoint/include/soc/cfr.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/cfr.h rename to src/southbridge/intel/wildcatpoint/include/soc/cfr.h diff --git a/src/northbridge/intel/broadwell/include/soc/chromeos.h b/src/southbridge/intel/wildcatpoint/include/soc/chromeos.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/chromeos.h rename to src/southbridge/intel/wildcatpoint/include/soc/chromeos.h diff --git a/src/northbridge/intel/broadwell/include/soc/ehci.h b/src/southbridge/intel/wildcatpoint/include/soc/ehci.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/ehci.h rename to src/southbridge/intel/wildcatpoint/include/soc/ehci.h diff --git a/src/northbridge/intel/broadwell/include/soc/gpio.h b/src/southbridge/intel/wildcatpoint/include/soc/gpio.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/gpio.h rename to src/southbridge/intel/wildcatpoint/include/soc/gpio.h diff --git a/src/northbridge/intel/broadwell/include/soc/iomap.h b/src/southbridge/intel/wildcatpoint/include/soc/iomap.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/iomap.h rename to src/southbridge/intel/wildcatpoint/include/soc/iomap.h diff --git a/src/northbridge/intel/broadwell/include/soc/lpc.h b/src/southbridge/intel/wildcatpoint/include/soc/lpc.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/lpc.h rename to src/southbridge/intel/wildcatpoint/include/soc/lpc.h diff --git a/src/northbridge/intel/broadwell/include/soc/me.h b/src/southbridge/intel/wildcatpoint/include/soc/me.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/me.h rename to src/southbridge/intel/wildcatpoint/include/soc/me.h diff --git a/src/northbridge/intel/broadwell/include/soc/nvs.h b/src/southbridge/intel/wildcatpoint/include/soc/nvs.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/nvs.h rename to src/southbridge/intel/wildcatpoint/include/soc/nvs.h diff --git a/src/northbridge/intel/broadwell/include/soc/pch.h b/src/southbridge/intel/wildcatpoint/include/soc/pch.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/pch.h rename to src/southbridge/intel/wildcatpoint/include/soc/pch.h diff --git a/src/northbridge/intel/broadwell/include/soc/pm.h b/src/southbridge/intel/wildcatpoint/include/soc/pm.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/pm.h rename to src/southbridge/intel/wildcatpoint/include/soc/pm.h diff --git a/src/northbridge/intel/broadwell/include/soc/rcba.h b/src/southbridge/intel/wildcatpoint/include/soc/rcba.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/rcba.h rename to src/southbridge/intel/wildcatpoint/include/soc/rcba.h diff --git a/src/northbridge/intel/broadwell/include/soc/sata.h b/src/southbridge/intel/wildcatpoint/include/soc/sata.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/sata.h rename to src/southbridge/intel/wildcatpoint/include/soc/sata.h diff --git a/src/northbridge/intel/broadwell/include/soc/serialio.h b/src/southbridge/intel/wildcatpoint/include/soc/serialio.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/serialio.h rename to src/southbridge/intel/wildcatpoint/include/soc/serialio.h diff --git a/src/northbridge/intel/broadwell/include/soc/spi.h b/src/southbridge/intel/wildcatpoint/include/soc/spi.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/spi.h rename to src/southbridge/intel/wildcatpoint/include/soc/spi.h diff --git a/src/northbridge/intel/broadwell/include/soc/xhci.h b/src/southbridge/intel/wildcatpoint/include/soc/xhci.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/xhci.h rename to src/southbridge/intel/wildcatpoint/include/soc/xhci.h From 7240bbabe9f87d795ec3e64ad0993507d26b224b Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 21:56:07 +0100 Subject: [PATCH 723/789] nb/intel/broadwell/acpi.c: Drop unneeded includes Tested with BUILD_TIMELESS=1, Purism Librem 15 v2 remains identical. Change-Id: Iac166dd1a59e6e35101dd7076cc3f96d33d4eb64 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91399 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/northbridge/intel/broadwell/acpi.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/northbridge/intel/broadwell/acpi.c b/src/northbridge/intel/broadwell/acpi.c index 7ca60c1f59..691bcdec31 100644 --- a/src/northbridge/intel/broadwell/acpi.c +++ b/src/northbridge/intel/broadwell/acpi.c @@ -2,23 +2,15 @@ #include #include -#include #include -#include -#include -#include #include #include -#include -#include +#include #include #include -#include -#include #include -#include #include -#include +#include static unsigned long acpi_fill_dmar(unsigned long current) { From 3d4f2efcf759626c42fa761d34fd79998b8aabde Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 22:03:33 +0100 Subject: [PATCH 724/789] nb/intel/broadwell/bootblock.c: Use Haswell's file Tested with BUILD_TIMELESS=1, Purism Librem 15 v2 remains identical. Change-Id: Ie583224b4cfc4116e6cdb511793b8c39e8bf679e Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91400 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/northbridge/intel/broadwell/Makefile.mk | 2 +- src/northbridge/intel/broadwell/bootblock.c | 34 --------------------- 2 files changed, 1 insertion(+), 35 deletions(-) delete mode 100644 src/northbridge/intel/broadwell/bootblock.c diff --git a/src/northbridge/intel/broadwell/Makefile.mk b/src/northbridge/intel/broadwell/Makefile.mk index 16576371ae..e067285881 100644 --- a/src/northbridge/intel/broadwell/Makefile.mk +++ b/src/northbridge/intel/broadwell/Makefile.mk @@ -2,7 +2,7 @@ ifeq ($(CONFIG_SOC_INTEL_BROADWELL),y) -bootblock-y += bootblock.c +bootblock-y += ../haswell/bootblock.c romstage-y += early_init.c romstage-y += raminit.c diff --git a/src/northbridge/intel/broadwell/bootblock.c b/src/northbridge/intel/broadwell/bootblock.c deleted file mode 100644 index 8c851cac5d..0000000000 --- a/src/northbridge/intel/broadwell/bootblock.c +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -static uint32_t encode_pciexbar_length(void) -{ - switch (CONFIG_ECAM_MMCONF_BUS_NUMBER) { - case 256: return 0 << 1; - case 128: return 1 << 1; - case 64: return 2 << 1; - default: return dead_code_t(uint32_t); - } -} - -void bootblock_early_northbridge_init(void) -{ - /* - * The "io" variant of the config access is explicitly used to setup the - * PCIEXBAR because CONFIG(ECAM_MMCONF_SUPPORT) is set to true. That way, all - * subsequent non-explicit config accesses use MCFG. This code also assumes - * that bootblock_northbridge_init() is the first thing called in the non-asm - * boot block code. The final assumption is that no assembly code is using the - * CONFIG(ECAM_MMCONF_SUPPORT) option to do PCI config accesses. - * - * The PCIEXBAR is assumed to live in the memory mapped IO space under 4GiB. - */ - const uint32_t reg = CONFIG_ECAM_MMCONF_BASE_ADDRESS | encode_pciexbar_length() | 1; - pci_io_write_config32(HOST_BRIDGE, PCIEXBAR + 4, 0); - pci_io_write_config32(HOST_BRIDGE, PCIEXBAR, reg); -} From 35694d2ea491c2009dcc8e335c2588848258484e Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 22:08:25 +0100 Subject: [PATCH 725/789] nb/intel/broadwell: Move device NVS to southbridge Device NVS is only used in southbridge code. Also move the platform.asl file since it is mostly about southbridge stuff. Tested with BUILD_TIMELESS=1, Purism Librem 15 v2 remains identical. Change-Id: Ia0d301f6b77f7084a6d1dfe1238693c76c62ef7a Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91401 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/google/auron/dsdt.asl | 2 +- src/mainboard/google/jecht/dsdt.asl | 2 +- src/mainboard/hp/elitebook_820_g2/dsdt.asl | 2 +- src/mainboard/intel/wtm2/dsdt.asl | 2 +- src/mainboard/purism/librem_bdw/dsdt.asl | 2 +- .../intel/wildcatpoint}/acpi/device_nvs.asl | 0 .../intel/wildcatpoint}/acpi/platform.asl | 2 +- .../intel/wildcatpoint}/include/soc/device_nvs.h | 0 8 files changed, 6 insertions(+), 6 deletions(-) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/acpi/device_nvs.asl (100%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/acpi/platform.asl (90%) rename src/{northbridge/intel/broadwell => southbridge/intel/wildcatpoint}/include/soc/device_nvs.h (100%) diff --git a/src/mainboard/google/auron/dsdt.asl b/src/mainboard/google/auron/dsdt.asl index 9505158f3c..eebeeeacee 100644 --- a/src/mainboard/google/auron/dsdt.asl +++ b/src/mainboard/google/auron/dsdt.asl @@ -11,7 +11,7 @@ DefinitionBlock( ) { #include - #include + #include // Thermal handler #include "acpi/thermal.asl" diff --git a/src/mainboard/google/jecht/dsdt.asl b/src/mainboard/google/jecht/dsdt.asl index 8e76080411..62c8b58fe6 100644 --- a/src/mainboard/google/jecht/dsdt.asl +++ b/src/mainboard/google/jecht/dsdt.asl @@ -19,7 +19,7 @@ DefinitionBlock( // global NVS and variables #include - #include + #include // CPU #include diff --git a/src/mainboard/hp/elitebook_820_g2/dsdt.asl b/src/mainboard/hp/elitebook_820_g2/dsdt.asl index bb744911a3..95012ce708 100644 --- a/src/mainboard/hp/elitebook_820_g2/dsdt.asl +++ b/src/mainboard/hp/elitebook_820_g2/dsdt.asl @@ -18,7 +18,7 @@ DefinitionBlock( #include #include - #include + #include #include #include diff --git a/src/mainboard/intel/wtm2/dsdt.asl b/src/mainboard/intel/wtm2/dsdt.asl index efa50eb92d..764d442d5f 100644 --- a/src/mainboard/intel/wtm2/dsdt.asl +++ b/src/mainboard/intel/wtm2/dsdt.asl @@ -19,7 +19,7 @@ DefinitionBlock( // global NVS and variables #include - #include + #include // CPU #include diff --git a/src/mainboard/purism/librem_bdw/dsdt.asl b/src/mainboard/purism/librem_bdw/dsdt.asl index 7439e941de..18719a8f1e 100644 --- a/src/mainboard/purism/librem_bdw/dsdt.asl +++ b/src/mainboard/purism/librem_bdw/dsdt.asl @@ -11,7 +11,7 @@ DefinitionBlock( ) { #include - #include + #include #include #include diff --git a/src/northbridge/intel/broadwell/acpi/device_nvs.asl b/src/southbridge/intel/wildcatpoint/acpi/device_nvs.asl similarity index 100% rename from src/northbridge/intel/broadwell/acpi/device_nvs.asl rename to src/southbridge/intel/wildcatpoint/acpi/device_nvs.asl diff --git a/src/northbridge/intel/broadwell/acpi/platform.asl b/src/southbridge/intel/wildcatpoint/acpi/platform.asl similarity index 90% rename from src/northbridge/intel/broadwell/acpi/platform.asl rename to src/southbridge/intel/wildcatpoint/acpi/platform.asl index 3a57f995d1..af60f5cee7 100644 --- a/src/northbridge/intel/broadwell/acpi/platform.asl +++ b/src/southbridge/intel/wildcatpoint/acpi/platform.asl @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include +#include #include /* diff --git a/src/northbridge/intel/broadwell/include/soc/device_nvs.h b/src/southbridge/intel/wildcatpoint/include/soc/device_nvs.h similarity index 100% rename from src/northbridge/intel/broadwell/include/soc/device_nvs.h rename to src/southbridge/intel/wildcatpoint/include/soc/device_nvs.h From 958bc5cdffa6b0a4e4824bad02861f9907636eb1 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 22:13:16 +0100 Subject: [PATCH 726/789] nb/intel/broadwell: Move `size_of_dnvs()` to southbridge Device NVS is only used in southbridge code. This change is non-reproducible. Change-Id: I60ce9a80d6e3e0ce0c13037d4caae473d3d092a9 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91402 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/northbridge/intel/broadwell/acpi.c | 7 ------- src/southbridge/intel/wildcatpoint/Makefile.mk | 1 + src/southbridge/intel/wildcatpoint/acpi.c | 10 ++++++++++ 3 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 src/southbridge/intel/wildcatpoint/acpi.c diff --git a/src/northbridge/intel/broadwell/acpi.c b/src/northbridge/intel/broadwell/acpi.c index 691bcdec31..453c77a235 100644 --- a/src/northbridge/intel/broadwell/acpi.c +++ b/src/northbridge/intel/broadwell/acpi.c @@ -1,13 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include -#include #include #include #include #include #include -#include #include #include #include @@ -87,8 +85,3 @@ unsigned long northbridge_write_acpi_tables(const struct device *const dev, return current; } - -size_t size_of_dnvs(void) -{ - return sizeof(struct device_nvs); -} diff --git a/src/southbridge/intel/wildcatpoint/Makefile.mk b/src/southbridge/intel/wildcatpoint/Makefile.mk index ec54db4632..59f48805ce 100644 --- a/src/southbridge/intel/wildcatpoint/Makefile.mk +++ b/src/southbridge/intel/wildcatpoint/Makefile.mk @@ -4,6 +4,7 @@ ifeq ($(CONFIG_SOUTHBRIDGE_INTEL_WILDCATPOINT),y) bootblock-y += bootblock.c +ramstage-y += acpi.c ramstage-y += adsp.c romstage-y += early_pch.c ramstage-$(CONFIG_ELOG) += elog.c diff --git a/src/southbridge/intel/wildcatpoint/acpi.c b/src/southbridge/intel/wildcatpoint/acpi.c new file mode 100644 index 0000000000..091bb50319 --- /dev/null +++ b/src/southbridge/intel/wildcatpoint/acpi.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +size_t size_of_dnvs(void) +{ + return sizeof(struct device_nvs); +} From 3e89a234ef527b20469ad2b4161e02bab4379372 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 22:15:29 +0100 Subject: [PATCH 727/789] nb/intel/broadwell/acpi.c: Align with Haswell The idea is to use Haswell's acpi.c file in the next commit, and this little difference affects reproducibility. Change-Id: Ib2641586fbb9e8ed175eeca0bd665057f5049c0e Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91403 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/northbridge/intel/broadwell/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/northbridge/intel/broadwell/acpi.c b/src/northbridge/intel/broadwell/acpi.c index 453c77a235..5da7bd3476 100644 --- a/src/northbridge/intel/broadwell/acpi.c +++ b/src/northbridge/intel/broadwell/acpi.c @@ -12,7 +12,7 @@ static unsigned long acpi_fill_dmar(unsigned long current) { - struct device *const igfx_dev = pcidev_path_on_root(SA_DEVFN_IGD); + struct device *const igfx_dev = pcidev_on_root(2, 0); const u32 gfxvtbar = mchbar_read32(GFXVTBAR) & ~0xfff; const u32 vtvc0bar = mchbar_read32(VTVC0BAR) & ~0xfff; const bool gfxvten = mchbar_read32(GFXVTBAR) & 0x1; From bacb55e348675235adab3c750c227d51910388e2 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 23 Feb 2026 22:17:32 +0100 Subject: [PATCH 728/789] nb/intel/broadwell/acpi.c: Use Haswell's file Tested with BUILD_TIMELESS=1, Purism Librem 15 v2 remains identical. Change-Id: Ie44227273210c3074343e1d9ccadb63fc2a931d2 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91404 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/northbridge/intel/broadwell/Makefile.mk | 2 +- src/northbridge/intel/broadwell/acpi.c | 87 --------------------- 2 files changed, 1 insertion(+), 88 deletions(-) delete mode 100644 src/northbridge/intel/broadwell/acpi.c diff --git a/src/northbridge/intel/broadwell/Makefile.mk b/src/northbridge/intel/broadwell/Makefile.mk index e067285881..ce037157e2 100644 --- a/src/northbridge/intel/broadwell/Makefile.mk +++ b/src/northbridge/intel/broadwell/Makefile.mk @@ -10,7 +10,7 @@ romstage-y += report_platform.c romstage-y += romstage.c romstage-$(CONFIG_HAVE_SPD_IN_CBFS) += spd.c -ramstage-y += acpi.c +ramstage-y += ../haswell/acpi.c ramstage-y += finalize.c ramstage-y += gma.c ramstage-y += memmap.c diff --git a/src/northbridge/intel/broadwell/acpi.c b/src/northbridge/intel/broadwell/acpi.c deleted file mode 100644 index 5da7bd3476..0000000000 --- a/src/northbridge/intel/broadwell/acpi.c +++ /dev/null @@ -1,87 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned long acpi_fill_dmar(unsigned long current) -{ - struct device *const igfx_dev = pcidev_on_root(2, 0); - const u32 gfxvtbar = mchbar_read32(GFXVTBAR) & ~0xfff; - const u32 vtvc0bar = mchbar_read32(VTVC0BAR) & ~0xfff; - const bool gfxvten = mchbar_read32(GFXVTBAR) & 0x1; - const bool vtvc0en = mchbar_read32(VTVC0BAR) & 0x1; - - /* iGFX has to be enabled; GFXVTBAR set, enabled, in 32-bit space */ - const bool emit_igd = - igfx_dev && igfx_dev->enabled && - gfxvtbar && gfxvten && - !mchbar_read32(GFXVTBAR + 4); - - /* First, add DRHD entries */ - if (emit_igd) { - const unsigned long tmp = current; - - current += acpi_create_dmar_drhd_4k(current, 0, 0, gfxvtbar); - current += acpi_create_dmar_ds_pci(current, 0, 2, 0); - - acpi_dmar_drhd_fixup(tmp, current); - } - - /* VTVC0BAR has to be set, enabled, and in 32-bit space */ - if (vtvc0bar && vtvc0en && !mchbar_read32(VTVC0BAR + 4)) { - const unsigned long tmp = current; - current += acpi_create_dmar_drhd_4k(current, - DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); - current += acpi_create_dmar_ds_ioapic_from_hw(current, - IO_APIC_ADDR, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0); - size_t i; - for (i = 0; i < 8; ++i) - current += acpi_create_dmar_ds_msi_hpet(current, - 0, PCH_HPET_PCI_BUS, - PCH_HPET_PCI_SLOT, i); - acpi_dmar_drhd_fixup(tmp, current); - } - - /* Then, add RMRR entries after all DRHD entries */ - if (emit_igd) { - const unsigned long tmp = current; - - const struct device *sa_dev = pcidev_on_root(0, 0); - - /* Bit 0 is lock bit, not part of address */ - const u32 tolud = pci_read_config32(sa_dev, TOLUD) & ~1; - const u32 bgsm = pci_read_config32(sa_dev, BGSM) & ~1; - - current += acpi_create_dmar_rmrr(current, 0, bgsm, tolud - 1); - current += acpi_create_dmar_ds_pci(current, 0, 2, 0); - acpi_dmar_rmrr_fixup(tmp, current); - } - - return current; -} - -unsigned long northbridge_write_acpi_tables(const struct device *const dev, - unsigned long current, - struct acpi_rsdp *const rsdp) -{ - /* Create DMAR table only if we have VT-d capability. */ - const u32 capid0_a = pci_read_config32(dev, CAPID0_A); - if (capid0_a & VTD_DISABLE) - return current; - - acpi_dmar_t *const dmar = (acpi_dmar_t *)current; - printk(BIOS_DEBUG, "ACPI: * DMAR\n"); - acpi_create_dmar(dmar, DMAR_INTR_REMAP, acpi_fill_dmar); - current += dmar->header.length; - current = acpi_align_current(current); - acpi_add_table(rsdp, dmar); - - return current; -} From fec793e01dd9dd9ccebbb6e82e20d5a6e79b53a0 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Fri, 27 Feb 2026 21:00:58 +0100 Subject: [PATCH 729/789] sb/intel/wildcatpoint/acpi: Add CID for GPIO device Wildcat Point's GPIOs work the same as Lynx Point LP's GPIOs. Change-Id: I64963937a5b40bcab605acb826567d63af512427 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/91468 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/southbridge/intel/wildcatpoint/acpi/gpio.asl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/southbridge/intel/wildcatpoint/acpi/gpio.asl b/src/southbridge/intel/wildcatpoint/acpi/gpio.asl index bd9f581cf6..48167bfae5 100644 --- a/src/southbridge/intel/wildcatpoint/acpi/gpio.asl +++ b/src/southbridge/intel/wildcatpoint/acpi/gpio.asl @@ -13,6 +13,7 @@ Device (GPIO) // LynxPoint-LP Return ("INT33C7") } + Name (_CID, "INT33C7") Name (_UID, 1) Name (RBUF, ResourceTemplate () From e160f3c50695f7d46fdcad525a10dd08aa3a6114 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Fri, 13 Feb 2026 23:35:05 -0800 Subject: [PATCH 730/789] soc/intel/common/feature: Add common PMC lockdown driver This commit introduces common PMC (Power Management Controller) lockdown infrastructure to consolidate duplicate lockdown code across multiple Intel platform generations (Alder Lake, Meteor Lake, and Panther Lake). Key features implemented: - PMSYNC TPR configuration and locking - ABASE and sleep stretching policy locks - SMI locking (when coreboot handles chipset lockdown) - ST_FDIS_LOCK, SSML, and PM_CFG register configuration - IOSF Primary Trunk Clock Gating - PMC IPC notification for BIOS reset and PCI enumeration Platform-specific differences are handled through the PMC_FDIS_LOCK_REG define that each SoC provides in its soc/pmc.h header: - Alder Lake: PMC_FDIS_LOCK_REG = ST_PG_FDIS1 (0x1e20) - Meteor Lake: PMC_FDIS_LOCK_REG = GEN_PMCON_B (0x1024) - Panther Lake: PMC_FDIS_LOCK_REG = GEN_PMCON_B (0x1024) This consolidation eliminates ~150 lines of duplicated code, ensures consistent lockdown behavior across platforms, and simplifies maintenance. Change-Id: I215d834b66f7cb0f50f804eaaff3ea0e60d4340f Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91204 Reviewed-by: Jakub "Kuba" Czapiga Tested-by: build bot (Jenkins) --- src/soc/intel/common/feature/lockdown/Kconfig | 8 +++ .../intel/common/feature/lockdown/Makefile.mk | 3 + .../intel/common/feature/lockdown/lockdown.c | 55 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 src/soc/intel/common/feature/lockdown/Kconfig create mode 100644 src/soc/intel/common/feature/lockdown/Makefile.mk create mode 100644 src/soc/intel/common/feature/lockdown/lockdown.c diff --git a/src/soc/intel/common/feature/lockdown/Kconfig b/src/soc/intel/common/feature/lockdown/Kconfig new file mode 100644 index 0000000000..75a59b0d62 --- /dev/null +++ b/src/soc/intel/common/feature/lockdown/Kconfig @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_LOCKDOWN + bool + help + Include common PMC lockdown driver for Intel SoCs. This driver + consolidates the nearly identical PMC lockdown implementations + across multiple Intel platform generations. diff --git a/src/soc/intel/common/feature/lockdown/Makefile.mk b/src/soc/intel/common/feature/lockdown/Makefile.mk new file mode 100644 index 0000000000..6a39d8a309 --- /dev/null +++ b/src/soc/intel/common/feature/lockdown/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_SOC_INTEL_COMMON_FEATURE_LOCKDOWN) += lockdown.c diff --git a/src/soc/intel/common/feature/lockdown/lockdown.c b/src/soc/intel/common/feature/lockdown/lockdown.c new file mode 100644 index 0000000000..5da2bd93bd --- /dev/null +++ b/src/soc/intel/common/feature/lockdown/lockdown.c @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* PCR PSTH Control Register */ +#define PCR_PSTH_CTRLREG 0x1d00 +#define PSTH_CTRLREG_IOSFPTCGE BIT(2) + +static void pmc_lockdown_config(int chipset_lockdown) +{ + uint8_t *pmcbase = pmc_mmio_regs(); + + /* PMSYNC */ + setbits32(pmcbase + PMSYNC_TPR_CFG, PCH2CPU_TPR_CFG_LOCK); + /* Lock down ABASE and sleep stretching policy */ + setbits32(pmcbase + GEN_PMCON_B, SLP_STR_POL_LOCK | ACPI_BASE_LOCK); + + if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) + setbits32(pmcbase + GEN_PMCON_B, SMI_LOCK); + + if (!CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) { + setbits32(pmcbase + PMC_FDIS_LOCK_REG, ST_FDIS_LOCK); + setbits32(pmcbase + SSML, SSML_SSL_EN); + setbits32(pmcbase + PM_CFG, PM_CFG_DBG_MODE_LOCK | + PM_CFG_XRAM_READ_DISABLE); + } + + /* Send PMC IPC to inform about both BIOS Reset and PCI enumeration done */ + pmc_send_bios_reset_pci_enum_done(); +} + +static void soc_die_lockdown_cfg(void) +{ + if (CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) + return; + + /* Enable IOSF Primary Trunk Clock Gating */ + pcr_rmw32(PID_PSTH, PCR_PSTH_CTRLREG, ~0, PSTH_CTRLREG_IOSFPTCGE); +} + +void soc_lockdown_config(int chipset_lockdown) +{ + /* PMC lock down configuration */ + pmc_lockdown_config(chipset_lockdown); + /* SOC/PCH die lock down configuration */ + soc_die_lockdown_cfg(); +} From 19fe81f08f5eff7377b0f8595a1763874f0aeec3 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Fri, 13 Feb 2026 23:35:32 -0800 Subject: [PATCH 731/789] soc/intel/alderlake: Switch to common PMC lockdown driver Replace platform-specific lockdown.c with the common PMC lockdown driver introduced in the previous commit. Changes: - Remove src/soc/intel/alderlake/lockdown.c - Add PMC_FDIS_LOCK_REG define pointing to ST_PG_FDIS1 in soc/pmc.h - Enable SOC_INTEL_COMMON_FEATURE_PMC_LOCKDOWN in Kconfig - Update Makefile.mk to remove lockdown.c from build Alder Lake uses the ST_PG_FDIS1 register (0x1e20) for ST_FDIS_LOCK, which differs from newer platforms that use GEN_PMCON_B. This difference is handled through the PMC_FDIS_LOCK_REG define. Change-Id: Ic80aca618dcbe5a4fef54f4802e6f4ce6f4ebd44 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91205 Reviewed-by: Huang, Cliff Tested-by: build bot (Jenkins) --- src/soc/intel/alderlake/Kconfig | 1 + src/soc/intel/alderlake/Makefile.mk | 1 - src/soc/intel/alderlake/include/soc/pmc.h | 3 ++ src/soc/intel/alderlake/lockdown.c | 60 ----------------------- 4 files changed, 4 insertions(+), 61 deletions(-) delete mode 100644 src/soc/intel/alderlake/lockdown.c diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index a925cf09a0..9198377291 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -87,6 +87,7 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_LOCKDOWN select SOC_INTEL_COMMON_FEATURE_PMUTIL select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index 45c374849d..cbfa1ebda5 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -25,7 +25,6 @@ ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c ramstage-y += hsphy.c -ramstage-y += lockdown.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c diff --git a/src/soc/intel/alderlake/include/soc/pmc.h b/src/soc/intel/alderlake/include/soc/pmc.h index 81a99e00ec..aa7df21bee 100644 --- a/src/soc/intel/alderlake/include/soc/pmc.h +++ b/src/soc/intel/alderlake/include/soc/pmc.h @@ -168,6 +168,9 @@ extern struct device_operations pmc_ops; #define ST_PG_FDIS1 0x1e20 #define ST_FDIS_LOCK (1 << 31) +/* PMC lockdown configuration register for ST_FDIS_LOCK */ +#define PMC_FDIS_LOCK_REG ST_PG_FDIS1 + #define SCIS_IRQ9 0 #define SCIS_IRQ10 1 #define SCIS_IRQ11 2 diff --git a/src/soc/intel/alderlake/lockdown.c b/src/soc/intel/alderlake/lockdown.c deleted file mode 100644 index 59fa065b3d..0000000000 --- a/src/soc/intel/alderlake/lockdown.c +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 4 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* PCR PSTH Control Register */ -#define PCR_PSTH_CTRLREG 0x1d00 -#define PSTH_CTRLREG_IOSFPTCGE (1 << 2) - -static void pmc_lockdown_cfg(int chipset_lockdown) -{ - uint8_t *pmcbase = pmc_mmio_regs(); - - /* PMSYNC */ - setbits32(pmcbase + PMSYNC_TPR_CFG, PCH2CPU_TPR_CFG_LOCK); - /* Lock down ABASE and sleep stretching policy */ - setbits32(pmcbase + GEN_PMCON_B, SLP_STR_POL_LOCK | ACPI_BASE_LOCK); - - if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) - setbits32(pmcbase + GEN_PMCON_B, SMI_LOCK); - - if (!CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) { - setbits32(pmcbase + ST_PG_FDIS1, ST_FDIS_LOCK); - setbits32(pmcbase + SSML, SSML_SSL_EN); - setbits32(pmcbase + PM_CFG, PM_CFG_DBG_MODE_LOCK | - PM_CFG_XRAM_READ_DISABLE); - } - - /* Send PMC IPC to inform about both BIOS Reset and PCI enumeration done */ - pmc_send_bios_reset_pci_enum_done(); -} - -static void pch_lockdown_cfg(void) -{ - if (CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) - return; - - /* Enable IOSF Primary Trunk Clock Gating */ - pcr_rmw32(PID_PSTH, PCR_PSTH_CTRLREG, ~0, PSTH_CTRLREG_IOSFPTCGE); -} - -void soc_lockdown_config(int chipset_lockdown) -{ - /* PMC lock down configuration */ - pmc_lockdown_cfg(chipset_lockdown); - /* PCH lock down configuration */ - pch_lockdown_cfg(); -} From 4da2622964a3fab05674f2514cdb0a727e5f5ea8 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Fri, 13 Feb 2026 23:35:41 -0800 Subject: [PATCH 732/789] soc/intel/meteorlake: Switch to common PMC lockdown driver Replace platform-specific lockdown.c with the common PMC lockdown driver. Changes: - Remove src/soc/intel/meteorlake/lockdown.c - Add PMC_FDIS_LOCK_REG define pointing to GEN_PMCON_B in soc/pmc.h - Enable SOC_INTEL_COMMON_FEATURE_LOCKDOWN in Kconfig - Update Makefile.mk to remove lockdown.c from build Meteor Lake uses GEN_PMCON_B for ST_FDIS_LOCK (bit 21), the same approach as Panther Lake. Change-Id: Iecccc482f04d85cfec738dd57dc1473eaf82cfcc Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91206 Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/meteorlake/Kconfig | 1 + src/soc/intel/meteorlake/Makefile.mk | 1 - src/soc/intel/meteorlake/include/soc/pmc.h | 3 ++ src/soc/intel/meteorlake/lockdown.c | 54 ---------------------- 4 files changed, 4 insertions(+), 55 deletions(-) delete mode 100644 src/soc/intel/meteorlake/lockdown.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 25d9d68e44..7dc41fc752 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -89,6 +89,7 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_LOCKDOWN select SOC_INTEL_COMMON_FEATURE_PMUTIL select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index b2c2429476..03463ff393 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -29,7 +29,6 @@ ramstage-y += elog.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c -ramstage-y += lockdown.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c diff --git a/src/soc/intel/meteorlake/include/soc/pmc.h b/src/soc/intel/meteorlake/include/soc/pmc.h index 6c40b4a5ee..19365ea122 100644 --- a/src/soc/intel/meteorlake/include/soc/pmc.h +++ b/src/soc/intel/meteorlake/include/soc/pmc.h @@ -62,6 +62,9 @@ extern struct device_operations ioe_pmc_ops; #define SMI_LOCK (1 << 4) #define RTC_BATTERY_DEAD (1 << 2) +/* PMC lockdown configuration register for ST_FDIS_LOCK */ +#define PMC_FDIS_LOCK_REG GEN_PMCON_B + #define ETR 0x1048 #define CF9_LOCK (1 << 31) #define CF9_GLB_RST (1 << 20) diff --git a/src/soc/intel/meteorlake/lockdown.c b/src/soc/intel/meteorlake/lockdown.c deleted file mode 100644 index 324c37ba38..0000000000 --- a/src/soc/intel/meteorlake/lockdown.c +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* PCR PSTH Control Register */ -#define PCR_PSTH_CTRLREG 0x1d00 -#define PSTH_CTRLREG_IOSFPTCGE (1 << 2) - -static void pmc_lockdown_cfg(int chipset_lockdown) -{ - uint8_t *pmcbase = pmc_mmio_regs(); - - /* PMSYNC */ - setbits32(pmcbase + PMSYNC_TPR_CFG, PCH2CPU_TPR_CFG_LOCK); - /* Lock down ABASE and sleep stretching policy */ - setbits32(pmcbase + GEN_PMCON_B, SLP_STR_POL_LOCK | ACPI_BASE_LOCK); - - if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) - setbits32(pmcbase + GEN_PMCON_B, SMI_LOCK); - - if (!CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) { - setbits32(pmcbase + GEN_PMCON_B, ST_FDIS_LOCK); - setbits32(pmcbase + SSML, SSML_SSL_EN); - setbits32(pmcbase + PM_CFG, PM_CFG_DBG_MODE_LOCK | - PM_CFG_XRAM_READ_DISABLE); - } - - /* Send PMC IPC to inform about both BIOS Reset and PCI enumeration done */ - pmc_send_bios_reset_pci_enum_done(); -} - -static void soc_die_lockdown_cfg(void) -{ - if (CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) - return; - - /* Enable IOSF Primary Trunk Clock Gating */ - pcr_rmw32(PID_PSTH, PCR_PSTH_CTRLREG, ~0, PSTH_CTRLREG_IOSFPTCGE); -} - -void soc_lockdown_config(int chipset_lockdown) -{ - /* PMC lock down configuration */ - pmc_lockdown_cfg(chipset_lockdown); - /* SOC Die lock down configuration */ - soc_die_lockdown_cfg(); -} From 7d8acb88c5b8fd5309ea736861dd1e6c98239d9c Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Fri, 13 Feb 2026 23:35:49 -0800 Subject: [PATCH 733/789] soc/intel/pantherlake: Switch to common PMC lockdown driver Replace platform-specific lockdown.c with the common PMC lockdown driver. Changes: - Remove src/soc/intel/pantherlake/lockdown.c - Add PMC_FDIS_LOCK_REG define pointing to GEN_PMCON_B in soc/pmc.h - Enable SOC_INTEL_COMMON_FEATURE_PMC_LOCKDOWN in Kconfig - Update Makefile.mk to remove lockdown.c from build Panther Lake uses GEN_PMCON_B for ST_FDIS_LOCK (bit 21), the same approach as Meteor Lake. Change-Id: I9becbedbb1bcbc19f60d3ebb024dd5e43c7cee29 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91207 Reviewed-by: Huang, Cliff Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/Kconfig | 1 + src/soc/intel/pantherlake/Makefile.mk | 1 - src/soc/intel/pantherlake/include/soc/pmc.h | 3 ++ src/soc/intel/pantherlake/lockdown.c | 54 --------------------- 4 files changed, 4 insertions(+), 55 deletions(-) delete mode 100644 src/soc/intel/pantherlake/lockdown.c diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index decd4c84c6..6b68c95dde 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -99,6 +99,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_LOCKDOWN select SOC_INTEL_COMMON_FEATURE_PMUTIL select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index 7349987e28..868ae605cd 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -27,7 +27,6 @@ ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c ramstage-y += elog.c ramstage-y += finalize.c ramstage-y += fsp_params.c -ramstage-y += lockdown.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c diff --git a/src/soc/intel/pantherlake/include/soc/pmc.h b/src/soc/intel/pantherlake/include/soc/pmc.h index 415bf074fb..bf0f6b5978 100644 --- a/src/soc/intel/pantherlake/include/soc/pmc.h +++ b/src/soc/intel/pantherlake/include/soc/pmc.h @@ -62,6 +62,9 @@ extern struct device_operations pmc_ops; #define SMI_LOCK BIT(4) #define RTC_BATTERY_DEAD BIT(2) +/* PMC lockdown configuration register for ST_FDIS_LOCK */ +#define PMC_FDIS_LOCK_REG GEN_PMCON_B + /* Extended Test Mode Register */ #define ETR 0x1048 #define CF9_LOCK BIT(31) diff --git a/src/soc/intel/pantherlake/lockdown.c b/src/soc/intel/pantherlake/lockdown.c deleted file mode 100644 index 2994952d00..0000000000 --- a/src/soc/intel/pantherlake/lockdown.c +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* PCR PSTH Control Register */ -#define PCR_PSTH_CTRLREG 0x1d00 -#define PSTH_CTRLREG_IOSFPTCGE BIT(2) - -static void pmc_lockdown_cfg(int chipset_lockdown) -{ - uint8_t *pmcbase = pmc_mmio_regs(); - - /* PMSYNC */ - setbits32(pmcbase + PMSYNC_TPR_CFG, PCH2CPU_TPR_CFG_LOCK); - /* Lock down ABASE and sleep stretching policy */ - setbits32(pmcbase + GEN_PMCON_B, SLP_STR_POL_LOCK | ACPI_BASE_LOCK); - - if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) - setbits32(pmcbase + GEN_PMCON_B, SMI_LOCK); - - if (!CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) { - setbits32(pmcbase + GEN_PMCON_B, ST_FDIS_LOCK); - setbits32(pmcbase + SSML, SSML_SSL_EN); - setbits32(pmcbase + PM_CFG, PM_CFG_DBG_MODE_LOCK | - PM_CFG_XRAM_READ_DISABLE); - } - - /* Send PMC IPC to inform about both BIOS Reset and PCI enumeration done */ - pmc_send_bios_reset_pci_enum_done(); -} - -static void soc_die_lockdown_cfg(void) -{ - if (CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) - return; - - /* Enable IOSF Primary Trunk Clock Gating */ - pcr_rmw32(PID_PSTH, PCR_PSTH_CTRLREG, ~0, PSTH_CTRLREG_IOSFPTCGE); -} - -void soc_lockdown_config(int chipset_lockdown) -{ - /* PMC lock down configuration */ - pmc_lockdown_cfg(chipset_lockdown); - /* SOC Die lock down configuration */ - soc_die_lockdown_cfg(); -} From e4ea8401143466365c0b84c9228b468c3a0f848a Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Fri, 13 Feb 2026 23:59:57 -0800 Subject: [PATCH 734/789] soc/intel/common: Add common global reset implementation This introduces a common implementation of do_global_reset() that uses CSE (Converged Security Engine) with PMC (Power Management Controller) fallback. This implementation is identical across 7 Intel client platforms. The function attempts to request a global reset from the CSE first, which is the preferred method. If CSE is unavailable or the request fails, it falls back to enabling PMC-based global reset and triggering a full reset. This consolidates the global reset handling and eliminates duplicate code across multiple platforms. The common implementation is enabled via the SOC_INTEL_COMMON_RESET_GLOBAL_RESET_CSE_PMC Kconfig option. Platforms that will use this common implementation: - Alder Lake - Meteor Lake - Panther Lake - Tiger Lake - Cannon Lake - Jasper Lake - Elkhart Lake Change-Id: Ida59bc2df483db5397ee043f66fdee56508bd0df Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91208 Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- .../intel/common/feature/globalreset/Kconfig | 9 +++++++++ .../common/feature/globalreset/Makefile.mk | 3 +++ .../feature/globalreset/global_reset_cse_pmc.c | 17 +++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 src/soc/intel/common/feature/globalreset/Kconfig create mode 100644 src/soc/intel/common/feature/globalreset/Makefile.mk create mode 100644 src/soc/intel/common/feature/globalreset/global_reset_cse_pmc.c diff --git a/src/soc/intel/common/feature/globalreset/Kconfig b/src/soc/intel/common/feature/globalreset/Kconfig new file mode 100644 index 0000000000..77c695d51a --- /dev/null +++ b/src/soc/intel/common/feature/globalreset/Kconfig @@ -0,0 +1,9 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC + bool + help + Include common implementation of do_global_reset() that uses CSE + (Converged Security Engine) with PMC (Power Management Controller) + fallback. This implementation is identical across multiple Intel + client platforms. diff --git a/src/soc/intel/common/feature/globalreset/Makefile.mk b/src/soc/intel/common/feature/globalreset/Makefile.mk new file mode 100644 index 0000000000..cff5f7a5e5 --- /dev/null +++ b/src/soc/intel/common/feature/globalreset/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC) += global_reset_cse_pmc.c diff --git a/src/soc/intel/common/feature/globalreset/global_reset_cse_pmc.c b/src/soc/intel/common/feature/globalreset/global_reset_cse_pmc.c new file mode 100644 index 0000000000..3c13f6dfe5 --- /dev/null +++ b/src/soc/intel/common/feature/globalreset/global_reset_cse_pmc.c @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void do_global_reset(void) +{ + /* Ask CSE to do the global reset */ + if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) + return; + + /* global reset if CSE fail to reset */ + pmc_global_reset_enable(1); + do_full_reset(); +} From b2a533c918d99e7bc417dc747d1158b13389139a Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Sat, 14 Feb 2026 00:00:08 -0800 Subject: [PATCH 735/789] soc/intel/alderlake: Switch to common global reset implementation Replace platform-specific reset.c with the common global reset implementation using CSE with PMC fallback. Changes: - Remove src/soc/intel/alderlake/reset.c - Enable SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC in Kconfig - Update Makefile.mk to remove reset.c from build The global reset implementation was identical to 6 other platforms, making it an ideal candidate for consolidation. Change-Id: Iebaf5bafd5a97dde37ffc435b2ad8b6a8dcfecd0 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91209 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/alderlake/Kconfig | 1 + src/soc/intel/alderlake/Makefile.mk | 2 -- src/soc/intel/alderlake/reset.c | 17 ----------------- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 src/soc/intel/alderlake/reset.c diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 9198377291..91058e8ed3 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -86,6 +86,7 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_LOCKDOWN select SOC_INTEL_COMMON_FEATURE_PMUTIL diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index cbfa1ebda5..5ca354832d 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -15,7 +15,6 @@ bootblock-$(CONFIG_ALDERLAKE_CONFIGURE_DESCRIPTOR) += bootblock/update_descripto romstage-$(CONFIG_SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY) += cse_telemetry.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c ramstage-y += acpi.c ramstage-y += chip.c @@ -28,7 +27,6 @@ ramstage-y += hsphy.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-$(CONFIG_SOC_INTEL_ALDERLAKE_TCSS_USB4_SUPPORT) += retimer.c ramstage-y += systemagent.c ramstage-y += tcss.c diff --git a/src/soc/intel/alderlake/reset.c b/src/soc/intel/alderlake/reset.c deleted file mode 100644 index 3c13f6dfe5..0000000000 --- a/src/soc/intel/alderlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} From 5c85dcda7f9d223c18032319b7ca01798361bd8d Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Sat, 14 Feb 2026 00:00:08 -0800 Subject: [PATCH 736/789] soc/intel/meteorlake: Switch to common global reset implementation Replace platform-specific reset.c with the common global reset implementation using CSE with PMC fallback. Changes: - Remove src/soc/intel/meteorlake/reset.c - Enable SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC in Kconfig - Update Makefile.mk to remove reset.c from build The global reset implementation was identical to 6 other platforms, making it an ideal candidate for consolidation. Change-Id: I0ad75bbeb1fad7352b2b898487a5b54eff496d0b Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91210 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/meteorlake/Kconfig | 1 + src/soc/intel/meteorlake/Makefile.mk | 2 -- src/soc/intel/meteorlake/reset.c | 17 ----------------- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 src/soc/intel/meteorlake/reset.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 7dc41fc752..4d4fe30fd5 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -88,6 +88,7 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_LOCKDOWN select SOC_INTEL_COMMON_FEATURE_PMUTIL diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index 03463ff393..1ee64e2973 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -17,7 +17,6 @@ bootblock-y += soc_info.c romstage-$(CONFIG_SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY) += cse_telemetry.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c romstage-y += soc_info.c ramstage-y += acpi.c @@ -32,7 +31,6 @@ ramstage-y += graphics.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-y += retimer.c ramstage-y += systemagent.c ramstage-y += tcss.c diff --git a/src/soc/intel/meteorlake/reset.c b/src/soc/intel/meteorlake/reset.c deleted file mode 100644 index 3c13f6dfe5..0000000000 --- a/src/soc/intel/meteorlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} From 0d4b9347261b2f2d9712251e7126c4fcc044591f Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Sat, 14 Feb 2026 00:00:08 -0800 Subject: [PATCH 737/789] soc/intel/pantherlake: Switch to common global reset implementation Replace platform-specific reset.c with the common global reset implementation using CSE with PMC fallback. Changes: - Remove src/soc/intel/pantherlake/reset.c - Enable SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC in Kconfig - Update Makefile.mk to remove reset.c from build The global reset implementation was identical to 6 other platforms, making it an ideal candidate for consolidation. Change-Id: I9bd0dae5bbfc0ec2e9101e848de2037760314456 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91211 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/pantherlake/Kconfig | 1 + src/soc/intel/pantherlake/Makefile.mk | 2 -- src/soc/intel/pantherlake/reset.c | 17 ----------------- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 src/soc/intel/pantherlake/reset.c diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index 6b68c95dde..279cc68b7d 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -98,6 +98,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_LOCKDOWN select SOC_INTEL_COMMON_FEATURE_PMUTIL diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index 868ae605cd..04afc634d8 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -16,7 +16,6 @@ bootblock-y += bootblock/report_platform.c romstage-$(CONFIG_SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY) += cse_telemetry.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c romstage-y += tdp.c ramstage-y += acpi.c @@ -30,7 +29,6 @@ ramstage-y += fsp_params.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-y += retimer.c ramstage-y += systemagent.c ramstage-y += tcss.c diff --git a/src/soc/intel/pantherlake/reset.c b/src/soc/intel/pantherlake/reset.c deleted file mode 100644 index 3c13f6dfe5..0000000000 --- a/src/soc/intel/pantherlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} From 2ff987f906f0df3e431f3185a26cd5399dd8b6de Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Sat, 14 Feb 2026 00:00:08 -0800 Subject: [PATCH 738/789] soc/intel/tigerlake: Switch to common global reset implementation Replace platform-specific reset.c with the common global reset implementation using CSE with PMC fallback. Changes: - Remove src/soc/intel/tigerlake/reset.c - Enable SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC in Kconfig - Update Makefile.mk to remove reset.c from build The global reset implementation was identical to 6 other platforms, making it an ideal candidate for consolidation. Change-Id: I1bf9d4eeab0fecbb33d122a32ecdeef85af059fa Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91212 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/tigerlake/Kconfig | 1 + src/soc/intel/tigerlake/Makefile.mk | 2 -- src/soc/intel/tigerlake/reset.c | 17 ----------------- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 src/soc/intel/tigerlake/reset.c diff --git a/src/soc/intel/tigerlake/Kconfig b/src/soc/intel/tigerlake/Kconfig index 192444ec11..81f01e3363 100644 --- a/src/soc/intel/tigerlake/Kconfig +++ b/src/soc/intel/tigerlake/Kconfig @@ -74,6 +74,7 @@ config SOC_INTEL_TIGERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE diff --git a/src/soc/intel/tigerlake/Makefile.mk b/src/soc/intel/tigerlake/Makefile.mk index 5caff77277..09b02a96d4 100644 --- a/src/soc/intel/tigerlake/Makefile.mk +++ b/src/soc/intel/tigerlake/Makefile.mk @@ -15,7 +15,6 @@ bootblock-y += p2sb.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c ramstage-y += acpi.c ramstage-y += chip.c @@ -29,7 +28,6 @@ ramstage-y += lpm.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-y += retimer.c ramstage-y += systemagent.c ramstage-y += tcss.c diff --git a/src/soc/intel/tigerlake/reset.c b/src/soc/intel/tigerlake/reset.c deleted file mode 100644 index 3c13f6dfe5..0000000000 --- a/src/soc/intel/tigerlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} From 0277c75bddfa8cd6b26eb23422fd349fba6c09e5 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Sat, 14 Feb 2026 00:00:08 -0800 Subject: [PATCH 739/789] soc/intel/cannonlake: Switch to common global reset implementation Replace platform-specific reset.c with the common global reset implementation using CSE with PMC fallback. Changes: - Remove src/soc/intel/cannonlake/reset.c - Enable SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC in Kconfig - Update Makefile.mk to remove reset.c from build The global reset implementation was identical to 6 other platforms, making it an ideal candidate for consolidation. Change-Id: If5a70a0e05c50ab893ba8861e200b078982dfad9 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91213 Reviewed-by: Guvendik, Bora Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/Kconfig | 1 + src/soc/intel/cannonlake/Makefile.mk | 2 -- src/soc/intel/cannonlake/reset.c | 17 ----------------- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 src/soc/intel/cannonlake/reset.c diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index 0389d58f9c..cd1eb24760 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -60,6 +60,7 @@ config SOC_INTEL_CANNONLAKE_BASE select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES diff --git a/src/soc/intel/cannonlake/Makefile.mk b/src/soc/intel/cannonlake/Makefile.mk index a281068425..f869176ca7 100644 --- a/src/soc/intel/cannonlake/Makefile.mk +++ b/src/soc/intel/cannonlake/Makefile.mk @@ -18,7 +18,6 @@ romstage-y += cnl_memcfg_init.c romstage-y += lpc.c romstage-y += pcie_rp.c romstage-y += pmutil.c -romstage-y += reset.c romstage-y += spi.c ramstage-y += acpi.c @@ -35,7 +34,6 @@ ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c ramstage-y += pmutil.c -ramstage-y += reset.c ramstage-y += spi.c ramstage-y += systemagent.c ramstage-y += vr_config.c diff --git a/src/soc/intel/cannonlake/reset.c b/src/soc/intel/cannonlake/reset.c deleted file mode 100644 index 3c13f6dfe5..0000000000 --- a/src/soc/intel/cannonlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} From 73e89322ce87159e5b89e6e5899dc9a99ac262a0 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Sat, 14 Feb 2026 00:00:09 -0800 Subject: [PATCH 740/789] soc/intel/jasperlake: Switch to common global reset implementation Replace platform-specific reset.c with the common global reset implementation using CSE with PMC fallback. Changes: - Remove src/soc/intel/jasperlake/reset.c - Enable SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC in Kconfig - Update Makefile.mk to remove reset.c from build The global reset implementation was identical to 6 other platforms, making it an ideal candidate for consolidation. Change-Id: Ia039b25b21b4af5912dd5e8af9ef06a66c00a7bd Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91214 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/jasperlake/Kconfig | 1 + src/soc/intel/jasperlake/Makefile.mk | 2 -- src/soc/intel/jasperlake/reset.c | 17 ----------------- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 src/soc/intel/jasperlake/reset.c diff --git a/src/soc/intel/jasperlake/Kconfig b/src/soc/intel/jasperlake/Kconfig index 7bcd734887..6f90f28a95 100644 --- a/src/soc/intel/jasperlake/Kconfig +++ b/src/soc/intel/jasperlake/Kconfig @@ -57,6 +57,7 @@ config SOC_INTEL_JASPERLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN diff --git a/src/soc/intel/jasperlake/Makefile.mk b/src/soc/intel/jasperlake/Makefile.mk index 05288ee8a1..bff546748e 100644 --- a/src/soc/intel/jasperlake/Makefile.mk +++ b/src/soc/intel/jasperlake/Makefile.mk @@ -17,7 +17,6 @@ bootblock-y += p2sb.c romstage-y += gpio.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c ramstage-y += acpi.c ramstage-y += chip.c @@ -31,7 +30,6 @@ ramstage-y += lockdown.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-y += systemagent.c ramstage-y += sd.c ramstage-y += xhci.c diff --git a/src/soc/intel/jasperlake/reset.c b/src/soc/intel/jasperlake/reset.c deleted file mode 100644 index 3c13f6dfe5..0000000000 --- a/src/soc/intel/jasperlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} From c9ba628d512e1cb8693e1fc7b2b2b1e661d7a309 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Sat, 14 Feb 2026 00:00:09 -0800 Subject: [PATCH 741/789] soc/intel/elkhartlake: Switch to common global reset implementation Replace platform-specific reset.c with the common global reset implementation using CSE with PMC fallback. Changes: - Remove src/soc/intel/elkhartlake/reset.c - Enable SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC in Kconfig - Update Makefile.mk to remove reset.c from build The global reset implementation was identical to 6 other platforms, making it an ideal candidate for consolidation. Change-Id: I635347f15e35ec8e69c24edcec8c45c55a496ffd Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91215 Tested-by: build bot (Jenkins) Reviewed-by: Guvendik, Bora --- src/soc/intel/elkhartlake/Kconfig | 1 + src/soc/intel/elkhartlake/Makefile.mk | 2 -- src/soc/intel/elkhartlake/reset.c | 17 ----------------- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 src/soc/intel/elkhartlake/reset.c diff --git a/src/soc/intel/elkhartlake/Kconfig b/src/soc/intel/elkhartlake/Kconfig index e8629039a2..a3abfe650d 100644 --- a/src/soc/intel/elkhartlake/Kconfig +++ b/src/soc/intel/elkhartlake/Kconfig @@ -57,6 +57,7 @@ config SOC_INTEL_ELKHARTLAKE select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES diff --git a/src/soc/intel/elkhartlake/Makefile.mk b/src/soc/intel/elkhartlake/Makefile.mk index e46946f0bb..5fc5336723 100644 --- a/src/soc/intel/elkhartlake/Makefile.mk +++ b/src/soc/intel/elkhartlake/Makefile.mk @@ -18,7 +18,6 @@ bootblock-y += p2sb.c romstage-y += gpio.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c ramstage-y += acpi.c ramstage-y += chip.c @@ -30,7 +29,6 @@ ramstage-y += lockdown.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-y += systemagent.c ramstage-y += sd.c ramstage-$(CONFIG_EHL_TSN_DRIVER) += tsn_gbe.c diff --git a/src/soc/intel/elkhartlake/reset.c b/src/soc/intel/elkhartlake/reset.c deleted file mode 100644 index 3c13f6dfe5..0000000000 --- a/src/soc/intel/elkhartlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} From ae932349bfeac758b09b90114fd75c16e44b4ebf Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Sat, 14 Feb 2026 21:25:04 -0800 Subject: [PATCH 742/789] soc/intel/common/block: Add common finalize implementation This introduces a common finalize implementation for Intel SoCs that consolidates the nearly identical finalize.c files across Meteor Lake and Panther Lake platforms. The implementation includes: - pch_finalize(): TCO lockdown and PMC status clearing - tbt_finalize(): Disable Thunderbolt PCIe root ports bus master - sa_finalize(): Lock system agent PAM regions when coreboot handles chipset lockdown - heci_finalize(): Set HECI to D0i3 and optionally disable HECI1 - soc_finalize(): Main finalization sequence coordinating all the above This consolidation eliminates duplicate code and ensures consistent finalization behavior across platforms. Alder Lake is intentionally excluded as it has additional platform-specific camera clock (ISCLK) configuration that would complicate the common implementation. The common driver is enabled via the SOC_INTEL_COMMON_FEATURE_FINALIZE Kconfig option. Platforms that will use this common implementation: - Meteor Lake - Panther Lake Change-Id: I4dd9ccf7e14fecdded92da6bf366e6ff56d866a4 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91227 Reviewed-by: Huang, Cliff Tested-by: build bot (Jenkins) --- src/soc/intel/common/feature/finalize/Kconfig | 8 ++ .../intel/common/feature/finalize/Makefile.mk | 3 + .../intel/common/feature/finalize/finalize.c | 79 +++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 src/soc/intel/common/feature/finalize/Kconfig create mode 100644 src/soc/intel/common/feature/finalize/Makefile.mk create mode 100644 src/soc/intel/common/feature/finalize/finalize.c diff --git a/src/soc/intel/common/feature/finalize/Kconfig b/src/soc/intel/common/feature/finalize/Kconfig new file mode 100644 index 0000000000..87a48b22a4 --- /dev/null +++ b/src/soc/intel/common/feature/finalize/Kconfig @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_FINALIZE + bool + help + Include common finalize implementation for Intel SoCs. This driver + consolidates the nearly identical finalize implementations across + Meteor Lake and Panther Lake platforms. diff --git a/src/soc/intel/common/feature/finalize/Makefile.mk b/src/soc/intel/common/feature/finalize/Makefile.mk new file mode 100644 index 0000000000..7f56bee857 --- /dev/null +++ b/src/soc/intel/common/feature/finalize/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_SOC_INTEL_COMMON_FEATURE_FINALIZE) += finalize.c diff --git a/src/soc/intel/common/feature/finalize/finalize.c b/src/soc/intel/common/feature/finalize/finalize.c new file mode 100644 index 0000000000..7830fb8e63 --- /dev/null +++ b/src/soc/intel/common/feature/finalize/finalize.c @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Common finalize implementation for Intel SoCs. + * This consolidates the nearly identical finalize.c implementations + * across Meteor Lake and Panther Lake platforms. + */ + +static void pch_finalize(void) +{ + /* TCO Lock down */ + tco_lockdown(); + + /* TODO: Add Thermal Configuration */ + + pmc_clear_pmcon_sts(); +} + +static void tbt_finalize(void) +{ + int i; + const struct device *dev; + + /* Disable Thunderbolt PCIe root ports bus master */ + for (i = 0; i < NUM_TBT_FUNCTIONS; i++) { + dev = pcidev_path_on_root(PCI_DEVFN_TBT(i)); + if (dev) + pci_dev_disable_bus_master(dev); + } +} + +static void sa_finalize(void) +{ + if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT) + sa_lock_pam(); +} + +static void heci_finalize(void) +{ + heci_set_to_d0i3(); + if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) + heci1_disable(); +} + +static void soc_finalize(void *unused) +{ + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); + apm_control(APM_CNT_FINALIZE); + tbt_finalize(); + sa_finalize(); + if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && + CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) + heci_finalize(); + + /* Indicate finalize step with post code */ + post_code(POSTCODE_OS_BOOT); +} + +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL); +/* + * The purpose of this change is to accommodate more time to push out sending + * CSE EOP messages at post. + */ +BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, soc_finalize, NULL); From 5c56b9ff72e50fb8e9717a2d1c1ad1e97675d90e Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Sat, 14 Feb 2026 21:25:17 -0800 Subject: [PATCH 743/789] soc/intel/meteorlake: Switch to common finalize implementation Replace platform-specific finalize.c with the common finalize implementation. Changes: - Remove src/soc/intel/meteorlake/finalize.c - Enable SOC_INTEL_COMMON_FEATURE_FINALIZE in Kconfig - Update Makefile.mk to remove finalize.c from build The finalize implementation was identical to Panther Lake, making it an ideal candidate for consolidation. Change-Id: Id0c3bde3b721b7a3e497711cfc6dd21efbfda4c5 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91228 Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/meteorlake/Kconfig | 1 + src/soc/intel/meteorlake/Makefile.mk | 1 - src/soc/intel/meteorlake/finalize.c | 83 ---------------------------- 3 files changed, 1 insertion(+), 84 deletions(-) delete mode 100644 src/soc/intel/meteorlake/finalize.c diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 4d4fe30fd5..9bdeea0b8d 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -88,6 +88,7 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_FINALIZE select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_LOCKDOWN diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index 1ee64e2973..9d6e840369 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -25,7 +25,6 @@ ramstage-y += cpu.c ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c ramstage-y += ioe_pmc.c ramstage-y += elog.c -ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c ramstage-y += p2sb.c diff --git a/src/soc/intel/meteorlake/finalize.c b/src/soc/intel/meteorlake/finalize.c deleted file mode 100644 index 1fd1d98fb5..0000000000 --- a/src/soc/intel/meteorlake/finalize.c +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void pch_finalize(void) -{ - /* TCO Lock down */ - tco_lockdown(); - - /* TODO: Add Thermal Configuration */ - - pmc_clear_pmcon_sts(); -} - -static void tbt_finalize(void) -{ - int i; - const struct device *dev; - - /* Disable Thunderbolt PCIe root ports bus master */ - for (i = 0; i < NUM_TBT_FUNCTIONS; i++) { - dev = pcidev_path_on_root(PCI_DEVFN_TBT(i)); - if (dev) - pci_dev_disable_bus_master(dev); - } -} - -static void sa_finalize(void) -{ - if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT) - sa_lock_pam(); -} - -static void heci_finalize(void) -{ - heci_set_to_d0i3(); - if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) - heci1_disable(); -} - -static void soc_finalize(void *unused) -{ - printk(BIOS_DEBUG, "Finalizing chipset.\n"); - - pch_finalize(); - apm_control(APM_CNT_FINALIZE); - tbt_finalize(); - sa_finalize(); - if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && - CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) - heci_finalize(); - - /* Indicate finalize step with post code */ - post_code(POSTCODE_OS_BOOT); -} - -BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL); -/* - * The purpose of this change is to accommodate more time to push out sending - * CSE EOP messages at post. - */ -BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, soc_finalize, NULL); From b52236fe9e210327fc26cf7c750948ff49066891 Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Sat, 14 Feb 2026 21:25:27 -0800 Subject: [PATCH 744/789] soc/intel/pantherlake: Switch to common finalize implementation Replace platform-specific finalize.c with the common finalize implementation. Changes: - Remove src/soc/intel/pantherlake/finalize.c - Enable SOC_INTEL_COMMON_FEATURE_FINALIZE in Kconfig - Update Makefile.mk to remove finalize.c from build The finalize implementation was identical to Meteor Lake, making it an ideal candidate for consolidation. Change-Id: I749eea246fdc7ab89848ed4160c61666e8944095 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91229 Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/pantherlake/Kconfig | 1 + src/soc/intel/pantherlake/Makefile.mk | 1 - src/soc/intel/pantherlake/finalize.c | 82 --------------------------- 3 files changed, 1 insertion(+), 83 deletions(-) delete mode 100644 src/soc/intel/pantherlake/finalize.c diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index 279cc68b7d..e85d80cddd 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -98,6 +98,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_FEATURE select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_FINALIZE select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN select SOC_INTEL_COMMON_FEATURE_LOCKDOWN diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index 04afc634d8..b7ea31b1f6 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -24,7 +24,6 @@ ramstage-y += chip.c ramstage-y += cpu.c ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c ramstage-y += elog.c -ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c diff --git a/src/soc/intel/pantherlake/finalize.c b/src/soc/intel/pantherlake/finalize.c deleted file mode 100644 index 05ec3eaaca..0000000000 --- a/src/soc/intel/pantherlake/finalize.c +++ /dev/null @@ -1,82 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void pch_finalize(void) -{ - /* TCO Lock down */ - tco_lockdown(); - - pmc_clear_pmcon_sts(); -} - -static void tbt_finalize(void) -{ - int i; - const struct device *dev; - - /* Disable Thunderbolt PCIe root ports bus master */ - for (i = 0; i < NUM_TBT_FUNCTIONS; i++) { - dev = pcidev_path_on_root(PCI_DEVFN_TBT(i)); - if (dev) - pci_dev_disable_bus_master(dev); - } -} - -static void sa_finalize(void) -{ - if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT) - sa_lock_pam(); -} - -static void heci_finalize(void) -{ - heci_set_to_d0i3(); - if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) - heci1_disable(); -} - -static void soc_finalize(void *unused) -{ - printk(BIOS_DEBUG, "Finalizing chipset.\n"); - - pch_finalize(); - apm_control(APM_CNT_FINALIZE); - tbt_finalize(); - sa_finalize(); - if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && - CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) - heci_finalize(); - - /* Indicate finalize step with post code */ - post_code(POSTCODE_OS_BOOT); -} - -BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL); -/* - * The purpose of this change is to accommodate more time to push out sending - * CSE EOP messages at post. - */ -BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, soc_finalize, NULL); From 1b5df51c51101826b4a0fd731884fcd4b69f931e Mon Sep 17 00:00:00 2001 From: Jeremy Compostella Date: Mon, 2 Mar 2026 13:22:43 -0800 Subject: [PATCH 745/789] soc/intel: Fix Kconfig select order Sort the SOC_INTEL_COMMON_FEATURE_* select statements alphabetically. Change-Id: I314bbced381ecea969054a0d2b841ef68f1efc58 Signed-off-by: Jeremy Compostella Reviewed-on: https://review.coreboot.org/c/coreboot/+/91513 Reviewed-by: Pranava Y N Tested-by: build bot (Jenkins) Reviewed-by: Huang, Cliff --- src/soc/intel/alderlake/Kconfig | 2 +- src/soc/intel/jasperlake/Kconfig | 2 +- src/soc/intel/meteorlake/Kconfig | 2 +- src/soc/intel/pantherlake/Kconfig | 2 +- src/soc/intel/tigerlake/Kconfig | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 91058e8ed3..334ea26e5b 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -88,13 +88,13 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_LOCKDOWN select SOC_INTEL_COMMON_FEATURE_PMUTIL select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF - select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/jasperlake/Kconfig b/src/soc/intel/jasperlake/Kconfig index 6f90f28a95..a9b19b9a12 100644 --- a/src/soc/intel/jasperlake/Kconfig +++ b/src/soc/intel/jasperlake/Kconfig @@ -59,8 +59,8 @@ config SOC_INTEL_JASPERLAKE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN - select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 9bdeea0b8d..e5abfc0762 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -91,13 +91,13 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_FEATURE_FINALIZE select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_LOCKDOWN select SOC_INTEL_COMMON_FEATURE_PMUTIL select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF - select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_BASECODE select SOC_INTEL_COMMON_BASECODE_RAMTOP diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index e85d80cddd..00616f14a5 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -101,13 +101,13 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_FEATURE_FINALIZE select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_LOCKDOWN select SOC_INTEL_COMMON_FEATURE_PMUTIL select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF - select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/tigerlake/Kconfig b/src/soc/intel/tigerlake/Kconfig index 81f01e3363..406d3ffb93 100644 --- a/src/soc/intel/tigerlake/Kconfig +++ b/src/soc/intel/tigerlake/Kconfig @@ -76,11 +76,11 @@ config SOC_INTEL_TIGERLAKE select SOC_INTEL_COMMON_FEATURE_ESPI select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_SMIHANDLER select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF - select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT From 2f88fec014074b19fdd55c17dcc43f9770340a6b Mon Sep 17 00:00:00 2001 From: KangMin Wang Date: Tue, 3 Mar 2026 14:54:35 +0800 Subject: [PATCH 746/789] mb/google/bluey/mica: Add TPM I2C and EC SPI configuration Communication with GSC and EC is abnormal because Mica is missing the following configurations: DRIVER_TPM_I2C_BUS, EC_GOOGLE_CHROMEEC_SPI_BUS,and MAINBOARD_GPIO_PIN_FOR_GSC_AP_INTERRUPT. BUG=b:489062509,b:489264026 TEST=build mica board, flash to Quenbi to verify the GSC and EC communication functionality. Check if there are any further abnormalities in the bootup log: For GSC: Probing TPM I2C: Cr50 TPM IRQ timeout! For EC: crosec_spi_io: Timeout waiting for framing byte. Change-Id: I2ff158968f946eb780d593c8b1d1e8b07f95ce8a Signed-off-by: KangMin Wang Reviewed-on: https://review.coreboot.org/c/coreboot/+/91517 Reviewed-by: Paul Menzel Reviewed-by: Derek Huang Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mainboard/google/bluey/Kconfig b/src/mainboard/google/bluey/Kconfig index 45017a4e01..c76878cf1b 100644 --- a/src/mainboard/google/bluey/Kconfig +++ b/src/mainboard/google/bluey/Kconfig @@ -175,6 +175,7 @@ config DRIVER_TPM_I2C_BUS hex default 0xa if BOARD_GOOGLE_MODEL_QUENBI default 0xa if BOARD_GOOGLE_MODEL_QUARTZ + default 0xa if BOARD_GOOGLE_MODEL_MICA default 0x10 config DRIVER_TPM_I2C_ADDR @@ -185,6 +186,7 @@ config EC_GOOGLE_CHROMEEC_SPI_BUS hex default 0xd if BOARD_GOOGLE_MODEL_QUENBI default 0xd if BOARD_GOOGLE_MODEL_QUARTZ + default 0xd if BOARD_GOOGLE_MODEL_MICA default 0xb config MAINBOARD_GPIO_PIN_FOR_TOUCHPAD_POWER @@ -200,6 +202,7 @@ config MAINBOARD_GPIO_PIN_FOR_GSC_AP_INTERRUPT int default 91 if BOARD_GOOGLE_MODEL_QUENBI default 91 if BOARD_GOOGLE_MODEL_QUARTZ + default 91 if BOARD_GOOGLE_MODEL_MICA default 34 help This option specifies the GPIO pin number on the mainboard that is From 510e43d8bd233b7221e8431f95ed70dc2aea9b9f Mon Sep 17 00:00:00 2001 From: Jarried Lin Date: Wed, 4 Mar 2026 12:52:10 +0800 Subject: [PATCH 747/789] soc/mediatek/mt8196: Move WATCHDOG_TOMBSTONE from SRAM to SRAM_L2C The purpose of the WATCHDOG_TOMBSTONE section is to temporarily record the watchdog timeout event, before triggering the reboot. Then, in the next boot, if WATCHDOG_TOMBSTONE contains the watchdog event magic, then a watchdog event will be added to the event log. The flow relies on the fact that the WATCHDOG_TOMBSTONE section can be preserved across AP resets. However, for MT8196, the whole SRAM region will be powered down during AP reset via GPIO AP_SYSRST_ODL (SYSRSTB). On MT8196, L3C (used as SRAM_L2C) is powered on by default. Also, per MT8196 PMIC configuration, a SYSRSTB reset will retain the L3C power. Therefore, region data in SRAM_L2C can be preserved across AP resets. Fix the WATCHDOG_TOMBSTONE preservation by moving it to SRAM_L2C. Reduce PRERAM_CBMEM_CONSOLE by 1K for WATCHDOG_TOMBSTONE. BUG=b:481854714 TEST=watchdog event added to eventlog on WDT timeout: 17 | 2026-03-04 08:57:17+0000 | Hardware watchdog reset TEST=cbmem logs preserved on WDT timeout Change-Id: I630d1749e1a743069f2d814efe0a4994889a2a3f Signed-off-by: Jarried Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/91540 Reviewed-by: Yidi Lin Reviewed-by: Hung-Te Lin Reviewed-by: Paul Menzel Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- src/soc/mediatek/mt8196/include/soc/memlayout.ld | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/soc/mediatek/mt8196/include/soc/memlayout.ld b/src/soc/mediatek/mt8196/include/soc/memlayout.ld index 2bd3a26b71..48f4dc77ce 100644 --- a/src/soc/mediatek/mt8196/include/soc/memlayout.ld +++ b/src/soc/mediatek/mt8196/include/soc/memlayout.ld @@ -13,13 +13,15 @@ SECTIONS { - /* MT8196 has 256KB SRAM. */ + /* MT8196 has 256KB SRAM. Per HW design, on SoC reset via GPIO + * AP_SYSRST_ODL (SYSRSTB), SRAM will be powered down. That means + * SRAM data will be lost across SoC resets. + */ SRAM_START(0x00100000) /* Regions that need to stay in SRAM. */ TTB(0x00100000, 28K) DMA_COHERENT(0x00107000, 4K) STACK(0x00108000, 15K) - WATCHDOG_TOMBSTONE(0x0010bc00, 4) EARLY_INIT(0x0010bc10, 128) /* EMPTY(0x0010bc90, 29K - 144) */ /* @@ -56,7 +58,8 @@ SECTIONS #endif OVERLAP_DECOMPRESSOR_VERSTAGE_ROMSTAGE(0x02096000, 272K) PRERAM_CBFS_CACHE(0x020DA000, 48K) - PRERAM_CBMEM_CONSOLE(0x020E6000, 340K) + PRERAM_CBMEM_CONSOLE(0x020E6000, 339K) + WATCHDOG_TOMBSTONE(0x0213AC00, 4) FSP_ROMSTAGE_INIT_CODE(0x02140000, 64K) SRAM_L2C_END(0x02200000) From a300b135c37bfee521282ccecb3bee4a8311f3c0 Mon Sep 17 00:00:00 2001 From: Jarried Lin Date: Wed, 4 Mar 2026 13:06:14 +0800 Subject: [PATCH 748/789] soc/mediatek/mt8196: Call mtk_mmu_disable_l2c_sram via boot state The commit 7072f42c08f7 ("soc/mediatek/mt8196: Move WATCHDOG_TOMBSTONE from SRAM to SRAM_L2C") move WATCHDOG_TOMBSTONE from SRAM to SRAM_L2C causes elog_handle_watchdog_tombstone (BS_POST_DEVICE, BS_ON_ENTRY) to be invoked after mtk_mmu_disable_l2c_sram. As a result, the watchdog event magic value in WATCHDOG_TOMBSTONE is cleared before it can be processed, which is incorrect behavior. So we refactor the mtk_mmu_disable_l2c_sram to be called as a boot state entry (BS_POST_DEVICE, BS_ON_EXIT) instead of directly from soc_init. This ensures that mtk_mmu_disable_l2c_sram will be executed after elog_handle_watchdog_tombstone. BUG=b:481854714 TEST=watchdog event added to eventlog on WDT timeout (triggered via echo > /dev/watchdog) TEST=cbmem logs preserved on WDT timeout Change-Id: I69ef567ab73f2f7006bb249cb577f377d4720909 Signed-off-by: Jarried Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/91539 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Yidi Lin Reviewed-by: Yu-Ping Wu --- src/soc/mediatek/mt8196/soc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/soc/mediatek/mt8196/soc.c b/src/soc/mediatek/mt8196/soc.c index c739998383..1e228c8a54 100644 --- a/src/soc/mediatek/mt8196/soc.c +++ b/src/soc/mediatek/mt8196/soc.c @@ -70,10 +70,15 @@ static void fsp_init(void *arg) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, fsp_init, NULL); -static void soc_init(struct device *dev) +static void mmu_disable_l2c_sram(void *unused) { mtk_mmu_disable_l2c_sram(); +} + +BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, mmu_disable_l2c_sram, NULL); +static void soc_init(struct device *dev) +{ if (dpm_init()) printk(BIOS_ERR, "dpm init failed, DVFS may not work\n"); if (spm_init()) From 8a4937bf8fffd08ecf9643d8b3217df6aa1cc855 Mon Sep 17 00:00:00 2001 From: Yang Wu Date: Fri, 13 Feb 2026 16:05:54 +0800 Subject: [PATCH 749/789] soc/mediatek: Add mtk_mipi_panel_poweroff() Introduce mtk_mipi_panel_poweroff() in common display layer and mtk_dsi_panel_poweroff() in DSI driver. The DSI mode flags are saved during init and reused for the power-off command path. BUG=b:474187570 TEST=emerge-jedi coreboot chromeos-bootimage BRANCH=skywalker Change-Id: Ic684822bc5f20d3e2f5ce3d44035c902a2b44184 Signed-off-by: Yang Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/91432 Reviewed-by: Yidi Lin Tested-by: build bot (Jenkins) Reviewed-by: Zhengqiao Xia Reviewed-by: Yu-Ping Wu --- src/soc/mediatek/common/display.c | 11 +++++ src/soc/mediatek/common/dsi_common.c | 47 +++++++++++++++++++ src/soc/mediatek/common/include/soc/display.h | 1 + .../mediatek/common/include/soc/display_dsi.h | 1 + 4 files changed, 60 insertions(+) diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c index 3b9d8be96c..d1fce217a6 100644 --- a/src/soc/mediatek/common/display.c +++ b/src/soc/mediatek/common/display.c @@ -16,6 +16,7 @@ #include #include +static u32 dsi_mode_flags; static struct panel_serializable_data *mipi_data; static struct panel_serializable_data *get_mipi_cmd_from_cbfs(struct panel_description *desc) @@ -172,6 +173,8 @@ int mtk_display_init(void) lanes = 4; } + dsi_mode_flags = mipi_dsi_flags; + if (mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, lanes, &edid, mipi_data ? mipi_data->init : NULL) < 0) { printk(BIOS_ERR, "%s: Failed in DSI init\n", __func__); @@ -219,6 +222,14 @@ int mtk_display_init(void) return 0; } +int mtk_mipi_panel_poweroff(void) +{ + if (!mipi_data) + return 0; + + return mtk_dsi_panel_poweroff(dsi_mode_flags, mipi_data->poweroff); +} + u32 mtk_get_vrefresh(const struct edid *edid) { u32 width = edid->mode.ha; diff --git a/src/soc/mediatek/common/dsi_common.c b/src/soc/mediatek/common/dsi_common.c index 6f8d640845..04dc0a85c3 100644 --- a/src/soc/mediatek/common/dsi_common.c +++ b/src/soc/mediatek/common/dsi_common.c @@ -444,6 +444,11 @@ static void mtk_dsi_reset_phy(struct dsi_regs *const dsi_reg) clrbits32(&dsi_reg->dsi_con_ctrl, DPHY_RESET); } +static void mtk_dsi_stop(struct dsi_regs *dsi) +{ + write32(&dsi->dsi_start, 0); +} + int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, const u8 *init_commands) { @@ -502,3 +507,45 @@ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, return 0; } + +int mtk_dsi_panel_poweroff(u32 mode_flags, const u8 *poweroff_cmds) +{ + int ret; + unsigned int num_dsi = (mode_flags & MIPI_DSI_DUAL_CHANNEL) ? 2 : 1; + + /* Stop DSI-0 engine */ + mtk_dsi_stop(dsi_mipi_regs[0].dsi_reg); + + /* Wait for DSI engines to become idle */ + for (unsigned int i = 0; i < num_dsi; i++) { + struct dsi_regs *dsi = dsi_mipi_regs[i].dsi_reg; + + if (!wait_ms(20, !(read32(&dsi->dsi_intsta) & DSI_BUSY))) { + u32 intsta = read32(&dsi->dsi_intsta); + + printk(BIOS_ERR, "%s: Timeout (20ms) waiting for DSI-%d idle " + "and the panel may not power-off properly. " + "DSI_INTSTA=0x%08x.\n", + __func__, i, intsta); + return -1; + } + + write32(&dsi->dsi_intsta, 0); + write32(&dsi->dsi_mode_ctrl, CMD_MODE); + } + + /* Send panel poweroff commands */ + ret = mipi_panel_parse_commands(poweroff_cmds, mtk_dsi_cmdq, + &mode_flags); + + /* Final shutdown: stop + disable PHY */ + mtk_dsi_stop(dsi_mipi_regs[0].dsi_reg); + + for (unsigned int i = 0; i < num_dsi; i++) { + struct dsi_regs *dsi = dsi_mipi_regs[i].dsi_reg; + + write32(&dsi->dsi_phy_lccon, 0x0); + } + + return ret; +} diff --git a/src/soc/mediatek/common/include/soc/display.h b/src/soc/mediatek/common/include/soc/display.h index 3e3b4a2164..87a6a04d9d 100644 --- a/src/soc/mediatek/common/include/soc/display.h +++ b/src/soc/mediatek/common/include/soc/display.h @@ -32,6 +32,7 @@ struct panel_description { struct panel_description *get_active_panel(void); void mtk_display_disable_secure_mode(void); int mtk_display_init(void); +int mtk_mipi_panel_poweroff(void); void mtk_ddp_init(void); u32 mtk_get_vrefresh(const struct edid *edid); diff --git a/src/soc/mediatek/common/include/soc/display_dsi.h b/src/soc/mediatek/common/include/soc/display_dsi.h index 62bdb3cca3..6a51dca55a 100644 --- a/src/soc/mediatek/common/include/soc/display_dsi.h +++ b/src/soc/mediatek/common/include/soc/display_dsi.h @@ -51,5 +51,6 @@ enum { /* Public API for common display code (display.c). */ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, const u8 *init_commands); +int mtk_dsi_panel_poweroff(u32 mode_flags, const u8 *poweroff_cmds); #endif /* SOC_MEDIATEK_DISPLAY_DSI_H */ From b5a703e5a0fe8fc953b3e351983105d140dd33ba Mon Sep 17 00:00:00 2001 From: Yang Wu Date: Mon, 2 Mar 2026 20:26:54 +0800 Subject: [PATCH 750/789] mb/google/skywalker: Add mainboard_prepare_cr50_reset() The LCD MIPI panel requires proper power-off commands before reset. Skipping them may cause overpotential conditions, leading to image stickiness or flicker. On MTK platforms, CR50 reset is the only reboot path in coreboot. Add mainboard_prepare_cr50_reset() implementation on skywalker to power off the MIPI panel before issuing CR50 reset. BUG=b:474187570 TEST=emerge-jedi coreboot chromeos-bootimage BRANCH=skywalker Change-Id: I46a654e03ca2e7374cdaf05729f12b182669a64f Signed-off-by: Yang Wu Reviewed-on: https://review.coreboot.org/c/coreboot/+/91507 Reviewed-by: Yu-Ping Wu Reviewed-by: Paul Menzel Reviewed-by: Yidi Lin Reviewed-by: Zhengqiao Xia Tested-by: build bot (Jenkins) --- src/mainboard/google/skywalker/mainboard.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mainboard/google/skywalker/mainboard.c b/src/mainboard/google/skywalker/mainboard.c index a36e3fa7a2..f7191e9140 100644 --- a/src/mainboard/google/skywalker/mainboard.c +++ b/src/mainboard/google/skywalker/mainboard.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "gpio.h" #include "panel.h" @@ -107,6 +108,13 @@ static void power_on_fpmcu(void) gpio_output(GPIO_FP_RST_1V8_S3_L, 1); } +void mainboard_prepare_cr50_reset(void) +{ + printk(BIOS_INFO, "%s: Powering MIPI panel off\n", __func__); + if (mtk_mipi_panel_poweroff() < 0) + printk(BIOS_ERR, "%s: Failed to power off MIPI panel\n", __func__); +} + enum mtk_storage_type mainboard_get_storage_type(void) { uint32_t index = storage_id(); From 23db1b368635fe0371c93ff26a729f63ca0bfdbd Mon Sep 17 00:00:00 2001 From: KangMin Wang Date: Wed, 4 Mar 2026 11:07:27 +0800 Subject: [PATCH 751/789] mb/google/bluey/mica: Add mainboard part number Add MAINBOARD_PART_NUMBER config for mica variant. BUG=none TEST=emerge-bluey coreboot Change-Id: I96ace7c6ed9b9f4892ed110134b2580516ec36bd Signed-off-by: KangMin Wang Reviewed-on: https://review.coreboot.org/c/coreboot/+/91538 Reviewed-by: Kapil Porwal Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik Reviewed-by: Paul Menzel Reviewed-by: Derek Huang --- src/mainboard/google/bluey/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/google/bluey/Kconfig b/src/mainboard/google/bluey/Kconfig index c76878cf1b..d5ecf88a26 100644 --- a/src/mainboard/google/bluey/Kconfig +++ b/src/mainboard/google/bluey/Kconfig @@ -169,6 +169,7 @@ config MAINBOARD_PART_NUMBER default "Quenbi" if BOARD_GOOGLE_QUENBI default "QuenbiH" if BOARD_GOOGLE_QUENBIH default "Quartz" if BOARD_GOOGLE_MODEL_QUARTZ + default "Mica" if BOARD_GOOGLE_MODEL_MICA config DRIVER_TPM_I2C_BUS depends on I2C_TPM From dfc2c45ff4e22a150593d5274186d4271a6b606c Mon Sep 17 00:00:00 2001 From: Ivi Ballou Date: Wed, 25 Feb 2026 17:59:57 +0200 Subject: [PATCH 752/789] util/inteltool: Add support for Wellsburg Added Wellsburg (C610 / X99) support for the following tables: - GPIOS - RCBA - PMBASE - LPC - SPI Change-Id: I1ee52b50b0093f38b00bfbaa003eecc96bd1874e Signed-off-by: Ivi Ballou Reviewed-on: https://review.coreboot.org/c/coreboot/+/91417 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- util/inteltool/gpio.c | 5 +++- util/inteltool/inteltool.c | 3 ++ util/inteltool/inteltool.h | 3 ++ util/inteltool/lpc.c | 59 ++++++++++++++++++++++++++++++++++++++ util/inteltool/powermgt.c | 6 +++- util/inteltool/rootcmplx.c | 3 ++ util/inteltool/spi.c | 6 ++++ 7 files changed, 83 insertions(+), 2 deletions(-) diff --git a/util/inteltool/gpio.c b/util/inteltool/gpio.c index c0005bf802..891b3abffd 100644 --- a/util/inteltool/gpio.c +++ b/util/inteltool/gpio.c @@ -228,7 +228,7 @@ static const io_register_t pch_gpio_registers[] = { { 0x40, 4, "GPIO_USE_SEL3" }, { 0x44, 4, "GP_IO_SEL3" }, { 0x48, 4, "GP_LVL3" }, - { 0x4c, 4, "RESERVED" }, + { 0x4c, 4, "GPI_INV2" }, // GPIO Signal Invert 2 { 0x50, 4, "RESERVED" }, { 0x54, 4, "RESERVED" }, { 0x58, 4, "RESERVED" }, @@ -861,6 +861,9 @@ int print_gpios(struct pci_dev *sb, int show_all, int show_diffs) case PCI_DEVICE_ID_INTEL_HM97: case PCI_DEVICE_ID_INTEL_Z97: case PCI_DEVICE_ID_INTEL_H97: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: gpiobase = pci_read_word(sb, 0x48) & 0xfffc; gpio_registers = pch_gpio_registers; size = ARRAY_SIZE(pch_gpio_registers); diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c index 66d42a903d..05d5c092fd 100644 --- a/util/inteltool/inteltool.c +++ b/util/inteltool/inteltool.c @@ -447,6 +447,9 @@ static const struct { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Z97, "Z97"}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_H97, "H97"}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL_LPC, "Apollo Lake" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER, "Wellsburg Super SKU" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_C612, "Wellsburg C612" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_X99, "Wellsburg X99" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_LPC, "Denverton" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK_LPC, "Gemini Lake" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_H510, "H510" }, diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h index 3a173da19c..e38fb190bb 100644 --- a/util/inteltool/inteltool.h +++ b/util/inteltool/inteltool.h @@ -309,6 +309,9 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_HM97 0x8cc3 #define PCI_DEVICE_ID_INTEL_Z97 0x8cc4 #define PCI_DEVICE_ID_INTEL_H97 0x8cc6 +#define PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER 0x8d40 +#define PCI_DEVICE_ID_INTEL_WELLSBURG_C612 0x8d44 +#define PCI_DEVICE_ID_INTEL_WELLSBURG_X99 0x8d47 #define PCI_DEVICE_ID_INTEL_82X58 0x3405 #define PCI_DEVICE_ID_INTEL_SCH_POULSBO 0x8100 diff --git a/util/inteltool/lpc.c b/util/inteltool/lpc.c index 0d21bedc80..af452a24d1 100644 --- a/util/inteltool/lpc.c +++ b/util/inteltool/lpc.c @@ -9,6 +9,47 @@ #define SUNRISE_LPC_BC 0xdc +static const io_register_t c610_lpc_cfg_registers[] = { + {0x00, 2, "VID"}, // Vendor Identification + {0x02, 2, "DID"}, // Device Identification + {0x04, 2, "PCICMD"}, // PCI Command + {0x06, 2, "PCISTS"}, // PCI Status + {0x08, 1, "RID"}, // Revision Identification + {0x09, 1, "PI"}, // Programming Interface + {0x0A, 1, "SCC"}, // Sub Class Code + {0x0B, 1, "BCC"}, // Base Class Code + {0x0D, 1, "PLT"}, // Primary Latency Timer + {0x0E, 1, "HEADTYP"}, // Header Type + {0x2C, 4, "SS"}, // Sub System Identifiers + {0x40, 4, "PMBASE"}, // ACPI Base Address + {0x44, 1, "ACPI_CNTL"}, // ACPI Control + {0x48, 4, "GPIOBASE"}, // ACPI Base Address + {0x4C, 1, "GC"}, // GPIO Control + {0x60, 4, "PIRQ[n]_ROUT"}, // PIRQ[A-D] Routing Control + {0x64, 1, "SIRQ_CNTL"}, // Serial IRQ Control + {0x68, 4, "PIRQ[n]_ROUT"}, // PIRQ[E-H] Routing Control + {0x6C, 2, "LPC_IBDF"}, // IOxAPIC Bus:Device:Function + {0x70, 8, "LPC_HnBDF"}, // HPET Configuration + {0x80, 1, "LPC_I/O_DEC"}, // I/O Decode + {0x82, 2, "LPC_EN"}, // LPC I/F Enables + {0x84, 4, "GEN1_DEC"}, // LPC I/F Generic Decode Range 1 + {0x88, 4, "GEN2_DEC"}, // LPC I/F Generic Decode Range 2 + {0x8C, 4, "GEN3_DEC"}, // LPC I/F Generic Decode Range 3 + {0x90, 4, "GEN4_DEC"}, // LPC I/F Generic Decode Range 4 00000000h R/W + {0x94, 4, "ULKMC"}, // USB Legacy Keyboard / Mouse Control 00000000h RO, R/WC, R/W, RW1L + {0x98, 4, "LGMR LPC"}, // I/F Generic Memory Range 00000000h R/W + {0xD0, 4, "BIOS_SEL1"}, // BIOS Select + {0xD4, 2, "BIOS_SEL2"}, // BIOS Select + {0xD8, 2, "BIOS_DEC_EN1"}, // BIOS Decode Enable + {0xDC, 1, "BIOS_CNTL"}, // BIOS Control + {0xE0, 2, "FDCAP"}, // Feature Detection Capability ID + {0xE2, 1, "FDLEN"}, // Feature Detection Capability Length + {0xE3, 1, "FDVER"}, // Feature Detection Version + {0xE4, 4, "FVECIDX"}, // Feature Vector Index + {0xE8, 4, "FVECD"}, // Feature Vector Data + {0xF0, 4, "RCBA"}, // Root Complex Base Address +}; + static const io_register_t sunrise_lpc_cfg_registers[] = { {0x00, 4, "ID"}, {0x04, 2, "CMD"}, @@ -109,6 +150,17 @@ int print_lpc(struct pci_dev *sb, struct pci_access *pacc) printf("\n========== LPC/eSPI =========\n\n"); switch (sb->device_id) { + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: + dev = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 0); + if (!dev) { + printf("LPC interface not found.\n"); + return 1; + } + cfg_registers = c610_lpc_cfg_registers; + cfg_registers_size = ARRAY_SIZE(c610_lpc_cfg_registers); + break; case PCI_DEVICE_ID_INTEL_H110: case PCI_DEVICE_ID_INTEL_H170: case PCI_DEVICE_ID_INTEL_Z170: @@ -212,6 +264,13 @@ int print_lpc(struct pci_dev *sb, struct pci_access *pacc) pci_read_long(dev, cfg_registers[i].addr), cfg_registers[i].name); break; + case 3: + printf("0x%04x: 0x%04x%02x (%s)\n", + cfg_registers[i].addr, + pci_read_word(dev, cfg_registers[i].addr), + pci_read_byte(dev, cfg_registers[i].addr + 2), + cfg_registers[i].name); + break; case 2: printf("0x%04x: 0x%04x (%s)\n", cfg_registers[i].addr, diff --git a/util/inteltool/powermgt.c b/util/inteltool/powermgt.c index 716b85ce03..31b3325223 100644 --- a/util/inteltool/powermgt.c +++ b/util/inteltool/powermgt.c @@ -97,7 +97,8 @@ static const io_register_t pch_pm_registers[] = { { 0x52, 2, "RESERVED" }, { 0x54, 4, "RESERVED" }, { 0x58, 4, "RESERVED" }, - { 0x5c, 4, "RESERVED" }, + { 0x5c, 2, "ALT_GPI_SMI_EN2" }, // Alternate GPI SMI Enable 2 Register + { 0x5e, 2, "ALT_GPI_SMI_STS2" }, // Alternate GPI SMI Status 2 Register /* The TCO registers start here. */ { 0x60, 2, "TCO_RLD" }, { 0x62, 1, "TCO_DAT_IN" }, @@ -771,6 +772,9 @@ int print_pmbase(struct pci_dev *sb, struct pci_access *pacc) case PCI_DEVICE_ID_INTEL_HM97: case PCI_DEVICE_ID_INTEL_Z97: case PCI_DEVICE_ID_INTEL_H97: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: pmbase = pci_read_word(sb, 0x40) & 0xff80; pm_registers = pch_pm_registers; pm_registers_size = ARRAY_SIZE(pch_pm_registers); diff --git a/util/inteltool/rootcmplx.c b/util/inteltool/rootcmplx.c index 46f7858feb..965c492e8d 100644 --- a/util/inteltool/rootcmplx.c +++ b/util/inteltool/rootcmplx.c @@ -106,6 +106,9 @@ int print_rcba(struct pci_dev *sb) case PCI_DEVICE_ID_INTEL_HM97: case PCI_DEVICE_ID_INTEL_Z97: case PCI_DEVICE_ID_INTEL_H97: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: diff --git a/util/inteltool/spi.c b/util/inteltool/spi.c index 6e869a2da9..6d6b500eeb 100644 --- a/util/inteltool/spi.c +++ b/util/inteltool/spi.c @@ -321,6 +321,9 @@ static int print_bioscntl(struct pci_dev *sb) case PCI_DEVICE_ID_INTEL_HM97: case PCI_DEVICE_ID_INTEL_Z97: case PCI_DEVICE_ID_INTEL_H97: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: case PCI_DEVICE_ID_INTEL_H110: case PCI_DEVICE_ID_INTEL_H170: case PCI_DEVICE_ID_INTEL_Z170: @@ -509,6 +512,9 @@ static int print_spibar(struct pci_dev *sb, struct pci_access *pacc) { case PCI_DEVICE_ID_INTEL_HM97: case PCI_DEVICE_ID_INTEL_Z97: case PCI_DEVICE_ID_INTEL_H97: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: From c772a88b1d5a81fdaf1820e6d928a2e7078d877b Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Wed, 4 Mar 2026 09:27:30 +0000 Subject: [PATCH 753/789] configs: Remove starbook/adl option table config This board no longer uses option table, so the config is invalid. Change-Id: I62268472e9a2020e81c352933aa9bac8bb2fcddd Signed-off-by: Sean Rhodes Reviewed-on: https://review.coreboot.org/c/coreboot/+/91541 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- configs/config.starlabs_starbook_adl_option_table | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 configs/config.starlabs_starbook_adl_option_table diff --git a/configs/config.starlabs_starbook_adl_option_table b/configs/config.starlabs_starbook_adl_option_table deleted file mode 100644 index 56211266a1..0000000000 --- a/configs/config.starlabs_starbook_adl_option_table +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG_VENDOR_STARLABS=y -CONFIG_BOARD_STARLABS_STARBOOK_ADL=y -CONFIG_MAINBOARD_SERIAL_NUMBER="B6I0000" -CONFIG_USE_OPTION_TABLE=y -CONFIG_LOCALVERSION="8.42" -CONFIG_MAINBOARD_USE_LIBGFXINIT=n -CONFIG_SMMSTORE=y -CONFIG_SMMSTORE_V2=y From f12d2997fcde22afdf681a09262f3f819f241055 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 22 Feb 2026 16:40:28 +0100 Subject: [PATCH 754/789] lib/cbfs: Don't include unused LZ4 code to shrink postcar stage When ramstage is not LZ4 compressed then don't include the LZ4 decompressor into postcar stage. TEST=Reduces postcar size on Lenovo x220 by 1224 bytes. Change-Id: I51e25d94213b42474c8cedd9e7bae9e81568566d Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/91385 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel --- src/lib/cbfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 0c602474b3..25a29a2885 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -137,6 +137,9 @@ static inline bool cbfs_lz4_enabled(void) if (ENV_SMM) return false; + if (ENV_RAMSTAGE_LOADER && !CONFIG(COMPRESS_RAMSTAGE_LZ4)) + return false; + return true; } From aaddb83491a26f3f6e193d0a287e272485f0b3f7 Mon Sep 17 00:00:00 2001 From: Sowmya Aralguppe Date: Sat, 28 Feb 2026 00:11:52 +0530 Subject: [PATCH 755/789] soc/intel/pantherlake: Configure TDC IRMS mode for WCL IA domain Set IA voltage regulator to use IRMS mode with 28 second time window for more accurate thermal design current measurement. Ref=:830097_WCL_PDG_SchChk_Rev1p5 BUG=b:None TEST=Build ocelot and verify that the system boots with the following VR parameter [SPEW ] TdcMode[0]:0x1 [SPEW ] TdcMode[1]:0x0 [SPEW ] TdcMode[2]:0x0 [SPEW ] TdcMode[3]:0x0 [SPEW ] TdcTimeWindow[0]:0x6D60 [SPEW ] TdcTimeWindow[1]:0x0 [SPEW ] TdcTimeWindow[2]:0x0 [SPEW ] TdcTimeWindow[3]:0x0 Change-Id: I4b7b9484d47cf9d98548cfc8b53e47be4e21c4d1 Signed-off-by: Sowmya Aralguppe Reviewed-on: https://review.coreboot.org/c/coreboot/+/91455 Reviewed-by: Pranava Y N Tested-by: build bot (Jenkins) --- src/soc/intel/pantherlake/chipset_wcl.cb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/soc/intel/pantherlake/chipset_wcl.cb b/src/soc/intel/pantherlake/chipset_wcl.cb index 4d8d296aa5..ed32d4826d 100644 --- a/src/soc/intel/pantherlake/chipset_wcl.cb +++ b/src/soc/intel/pantherlake/chipset_wcl.cb @@ -12,6 +12,9 @@ chip soc/intel/pantherlake [VR_DOMAIN_GT] = 36 * 4, }" + register "tdc_mode[VR_DOMAIN_IA]" = "TDC_IRMS" + register "tdc_time_window_ms[VR_DOMAIN_IA]" = "28000" + # Reduce the size of BasicMemoryTests to speed up the boot time. register "lower_basic_mem_test_size" = "true" From c97e7409816fcffe8b8c279e2b631dd5351fc12e Mon Sep 17 00:00:00 2001 From: Sowmya Aralguppe Date: Fri, 27 Feb 2026 11:56:30 +0530 Subject: [PATCH 756/789] mb/google/ocelot: Fix fast_vmode_i_trip indexing in devicetree This aligns with the corrected indexing scheme used in the SoC VR configuration code. Ref=:830097_WCL_PDG_SchChk_Rev1p5 BUG=b:None TEST=Build ocelot and verify that the system boots Change-Id: I948c9233f4a5518992891b90fb9bb6a3793baa5f Signed-off-by: Sowmya Aralguppe Reviewed-on: https://review.coreboot.org/c/coreboot/+/91449 Tested-by: build bot (Jenkins) Reviewed-by: Pranava Y N --- .../google/ocelot/variants/baseboard/ocelot/devicetree.cb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb b/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb index b53380c2ee..299c770d5e 100644 --- a/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb +++ b/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb @@ -73,7 +73,7 @@ chip soc/intel/pantherlake # TODO: Update with actual i_trip values. register "enable_fast_vmode[VR_DOMAIN_GT]" = "true" register "cep_enable[VR_DOMAIN_GT]" = "true" - register "fast_vmode_i_trip[WCL_CORE]" = "{ + register "fast_vmode_i_trip[WCL_SKU_1]" = "{ [VR_DOMAIN_GT] = 25 * 4, }" From 8aa0ea4062ad9b098cb9751bbb71391e945b3d5c Mon Sep 17 00:00:00 2001 From: Sowmya Aralguppe Date: Mon, 2 Mar 2026 13:33:48 +0530 Subject: [PATCH 757/789] soc/intel/pantherlake: Keep default values for TdcTimeWindow This patch prevents coreboot from overwriting FSP defaults with zeros for unconfigured VR domains. Ref=:830097_WCL_PDG_SchChk_Rev1p5 BUG=b:None TEST=Build ocelot and verify that the system boots with correct VR parameter [SPEW ] TdcTimeWindow[0]:0x6D60 [SPEW ] TdcTimeWindow[1]:0x0 [SPEW ] TdcTimeWindow[2]:0x0 [SPEW ] TdcTimeWindow[3]:0x0 [SPEW ] Override TdcTimeWindow[0] = 28000 [SPEW ] Override TdcTimeWindow[1] = 1000 [SPEW ] Override TdcTimeWindow[2] = 0 [SPEW ] Override TdcTimeWindow[3] = 1000 FSP defaults: [SPEW ] Override TdcTimeWindow[0] = 28000 [SPEW ] Override TdcTimeWindow[1] = 1000 [SPEW ] Override TdcTimeWindow[2] = 0 [SPEW ] Override TdcTimeWindow[3] = 1000 Added print in the coreboot code [DEBUG] VR[0]: Setting TdcTimeWindow to 28000 [DEBUG] VR[1]: Setting TdcTimeWindow to 0 [DEBUG] VR[2]: Setting TdcTimeWindow to 0 [DEBUG] VR[3]: Setting TdcTimeWindow to 0 Change-Id: Ib2531b908ddf80c40c52f620229852487d3425e9 Signed-off-by: Sowmya Aralguppe Reviewed-on: https://review.coreboot.org/c/coreboot/+/91503 Reviewed-by: Pranava Y N Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik --- src/soc/intel/pantherlake/romstage/fsp_params.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/pantherlake/romstage/fsp_params.c b/src/soc/intel/pantherlake/romstage/fsp_params.c index d143d95688..5e652da187 100644 --- a/src/soc/intel/pantherlake/romstage/fsp_params.c +++ b/src/soc/intel/pantherlake/romstage/fsp_params.c @@ -366,8 +366,10 @@ static void fill_fspm_vr_config_params(FSP_M_CONFIG *m_cfg, } for (size_t i = 0; i < ARRAY_SIZE(config->tdc_mode); i++) { - m_cfg->TdcMode[i] = config->tdc_mode[i]; - m_cfg->TdcTimeWindow[i] = config->tdc_time_window_ms[i]; + if (config->tdc_mode[i]) + m_cfg->TdcMode[i] = config->tdc_mode[i]; + if (config->tdc_time_window_ms[i]) + m_cfg->TdcTimeWindow[i] = config->tdc_time_window_ms[i]; } for (size_t i = 0; i < ARRAY_SIZE(config->ps1_threshold); i++) { From 61657cff8f4bc494f0e8647c9aede53f7d351000 Mon Sep 17 00:00:00 2001 From: Bora Guvendik Date: Wed, 21 Jan 2026 11:36:12 -0800 Subject: [PATCH 758/789] spd/lp5: Add SPD for SK hynix H58G56DK9BX068 Add H58G56DK9BX068 in the memory_parts.json and re-generate the SPD. BUG=none TEST= Booted successfully on nvlrvp board using H58G56DK9BX068. util/spd_tools/bin/spd_gen spd/lp5/memory_parts.json lp5 Change-Id: I7f8e13c2dac50b108f3ded1528a48b641eafbeec Signed-off-by: Bora Guvendik Reviewed-on: https://review.coreboot.org/c/coreboot/+/90856 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- spd/lp5/memory_parts.json | 11 +++++++++++ spd/lp5/set-0/parts_spd_manifest.generated.txt | 1 + spd/lp5/set-0/spd-14.hex | 6 +++--- spd/lp5/set-1/parts_spd_manifest.generated.txt | 1 + spd/lp5/set-1/spd-14.hex | 4 ++-- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/spd/lp5/memory_parts.json b/spd/lp5/memory_parts.json index 4c21c7bb28..a38e0ac23f 100644 --- a/spd/lp5/memory_parts.json +++ b/spd/lp5/memory_parts.json @@ -456,6 +456,17 @@ "speedMbps": 8533, "lp5x": true } + }, + { + "name": "H58G56DK9BX068", + "attribs": { + "densityPerDieGb": 16, + "diesPerPackage": 2, + "bitWidthPerChannel": 16, + "ranksPerChannel": 1, + "speedMbps": 9600, + "lp5x": true + } } ] } diff --git a/spd/lp5/set-0/parts_spd_manifest.generated.txt b/spd/lp5/set-0/parts_spd_manifest.generated.txt index 11221ec42c..ac104fc010 100644 --- a/spd/lp5/set-0/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-0/parts_spd_manifest.generated.txt @@ -44,3 +44,4 @@ MT62F2G32D4DS-031RF WT:C,spd-6.hex RS1G32LO5D2FDB-23BT,spd-11.hex BWMYAX32P8A-32G,spd-7.hex MT62F2G32D4DS-020 WT:D,spd-10.hex +H58G56DK9BX068,spd-14.hex diff --git a/spd/lp5/set-0/spd-14.hex b/spd/lp5/set-0/spd-14.hex index fb1b5a43c4..f9bb5a2eaf 100644 --- a/spd/lp5/set-0/spd-14.hex +++ b/spd/lp5/set-0/spd-14.hex @@ -1,11 +1,11 @@ -23 10 15 0E 16 22 91 08 00 00 00 00 0A 01 00 00 -00 00 08 00 00 00 00 00 AD 00 90 A8 90 C0 08 60 +23 10 15 0E 16 22 95 08 00 00 00 00 02 01 00 00 +00 00 07 00 00 00 00 00 AE 00 90 A8 90 C0 08 60 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 B6 00 C1 00 00 +00 00 00 00 00 00 00 00 00 00 00 A4 00 D6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/spd/lp5/set-1/parts_spd_manifest.generated.txt b/spd/lp5/set-1/parts_spd_manifest.generated.txt index 11221ec42c..ac104fc010 100644 --- a/spd/lp5/set-1/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-1/parts_spd_manifest.generated.txt @@ -44,3 +44,4 @@ MT62F2G32D4DS-031RF WT:C,spd-6.hex RS1G32LO5D2FDB-23BT,spd-11.hex BWMYAX32P8A-32G,spd-7.hex MT62F2G32D4DS-020 WT:D,spd-10.hex +H58G56DK9BX068,spd-14.hex diff --git a/spd/lp5/set-1/spd-14.hex b/spd/lp5/set-1/spd-14.hex index 37203cc057..8ecc7a190c 100644 --- a/spd/lp5/set-1/spd-14.hex +++ b/spd/lp5/set-1/spd-14.hex @@ -1,11 +1,11 @@ -23 11 13 0E 86 21 91 18 00 40 00 00 0A 02 00 00 +23 11 13 0E 86 21 95 18 00 40 00 00 02 02 00 00 00 00 02 00 00 00 00 00 2C 00 90 A8 90 C0 08 60 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 8A 00 F0 00 00 +00 00 00 00 00 00 00 00 00 00 00 A4 00 D6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 From 762b564f3b78f12cae1e9534085cefffecf6d133 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Thu, 5 Mar 2026 14:15:26 +0530 Subject: [PATCH 759/789] mb/google/bluey: Add timeout for charging rail stabilization In the charger applet, it is possible for the PMIC to take some time to negotiate and enable the charging current. Previously, the code proceeded immediately, which could lead to false-positive power-off triggers if current hadn't started flowing yet. This change: 1. Implements a 3000ms stopwatch-based timeout. 2. Polls get_battery_icurr_ma() until a non-zero current is detected. 3. Aborts the applet if current fails to stabilize within the window. 4. Adds logging to track the actual duration of the power-up sequence. BUG=none BRANCH=none TEST=Verified that the system enters off-mode charging more reliably without powering off. ``` [INFO ] Inside launch_charger_applet. Initiating charging ... ... [INFO ] Issuing power-off due to change in charging state. ... ... ``` Change-Id: Ie3501dff06aadf81d527658c4042de7c92de24b5 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/91547 Tested-by: build bot (Jenkins) Reviewed-by: Kapil Porwal --- src/mainboard/google/bluey/charging.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/mainboard/google/bluey/charging.c b/src/mainboard/google/bluey/charging.c index 690f30964f..f81d5b9650 100644 --- a/src/mainboard/google/bluey/charging.c +++ b/src/mainboard/google/bluey/charging.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #define SMB1_SLAVE_ID 0x07 @@ -41,6 +42,7 @@ #define PERPH_EN 0x80 #define DELAY_CHARGING_APPLET_MS 2000 /* 2sec */ +#define CHARGING_RAIL_STABILIZATION_DELAY_MS 3000 /* 3sec */ enum charging_status { CHRG_DISABLE, @@ -86,11 +88,25 @@ void launch_charger_applet(void) if (!CONFIG(EC_GOOGLE_CHROMEEC)) return; + static const long charging_enable_timeout_ms = CHARGING_RAIL_STABILIZATION_DELAY_MS; + struct stopwatch sw; + printk(BIOS_INFO, "Inside %s. Initiating charging\n", __func__); /* clear any pending power button press and lid open event */ clear_ec_manual_poweron_event(); + stopwatch_init_msecs_expire(&sw, charging_enable_timeout_ms); + while (!get_battery_icurr_ma()) { + if (stopwatch_expired(&sw)) { + printk(BIOS_WARNING, "Charging not enabled %ld ms. Abort.\n", + charging_enable_timeout_ms); + return; + } + mdelay(200); + } + printk(BIOS_INFO, "Charging ready after %lld ms\n", stopwatch_duration_msecs(&sw)); + do { /* Add static delay before reading the charging applet pre-requisites */ mdelay(DELAY_CHARGING_APPLET_MS); From b7ddbf53967e80f1df3bcebd003ef2bb5c9fe44d Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Fri, 31 May 2024 12:16:10 -0600 Subject: [PATCH 760/789] security/tpm/tspi: Do TPM Restart if TPM Resume fails The Infineon SLB 9672 on newer Clevo machines regularly fails TPM Resume on S3 with the error `TPM_RC_VALUE`. Per TPM2 spec, handle the failure by performing a TPM Restart. > The startup behavior defined by this specification is different than > TPM 1.2 with respect to Startup(STATE). A TPM 1.2 device will enter > Failure Mode if no state is available when the TPM receives > Startup(STATE). This is not the case in this specification. It is up > to the CRTM to take corrective action if it the TPM returns > TPM_RC_VALUE in response to Startup(STATE). Fixes the following error from being repeatedly logged in Linux: > kernel: tpm tpm0: A TPM error (256) occurred attempting get random Ref: Trusted Platform Module Library, Part 1: Architecture, rev 1.59 Change-Id: I3388007d4448c93bd0dda591c8ca7d1a8dc5306b Signed-off-by: Tim Crawford --- src/security/tpm/tspi/tspi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c index 56b8fa8ede..b69273e5f2 100644 --- a/src/security/tpm/tspi/tspi.c +++ b/src/security/tpm/tspi/tspi.c @@ -73,6 +73,14 @@ static tpm_result_t tpm_setup_s3_helper(void) default: printk(BIOS_ERR, "TPM: Resume failed (%#x).\n", rc); + if (CONFIG(TPM2)) { + /* + * TODO: Record EV_SEPARATOR event to indicate to host + * that an error has occurred. + */ + printk(BIOS_WARNING, "TPM: Performing restart\n"); + rc = tlcl_startup(); + } break; } From 54e0735788c42792ebf167076dfda55d611b601f Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 19 Mar 2024 11:23:03 -0600 Subject: [PATCH 761/789] soc/intel/adl,mtl: Use channel 0 only for memory down in mixed topo Change-Id: Ic30bec272e82535f6f606033c3ba512662cb2c8b Signed-off-by: Jeremy Soller --- src/soc/intel/alderlake/meminit.c | 4 ++-- src/soc/intel/meteorlake/meminit.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/soc/intel/alderlake/meminit.c b/src/soc/intel/alderlake/meminit.c index efeac5cecd..014b5db434 100644 --- a/src/soc/intel/alderlake/meminit.c +++ b/src/soc/intel/alderlake/meminit.c @@ -70,8 +70,8 @@ static const struct soc_mem_cfg soc_mem_cfg[] = { * configuration. */ .half_channel = BIT(0), - /* In mixed topologies, either channel 0 or 1 can be memory-down. */ - .mixed_topo = BIT(0) | BIT(1), + /* In mixed topologies, channel 0 is memory-down. */ + .mixed_topo = BIT(0), }, }, [MEM_TYPE_LP4X] = { diff --git a/src/soc/intel/meteorlake/meminit.c b/src/soc/intel/meteorlake/meminit.c index f4cde7e168..eb405bf8a8 100644 --- a/src/soc/intel/meteorlake/meminit.c +++ b/src/soc/intel/meteorlake/meminit.c @@ -46,8 +46,8 @@ static const struct soc_mem_cfg soc_mem_cfg[] = { * configuration. */ .half_channel = BIT(0), - /* In mixed topologies, either channel 0 or 1 can be memory-down. */ - .mixed_topo = BIT(0) | BIT(1), + /* In mixed topologies, channel 0 is memory-down. */ + .mixed_topo = BIT(0), }, }, [MEM_TYPE_LP5X] = { From 698cd18ad8eb736ff7e926d939120c49c5e6db35 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 21 Mar 2024 11:46:04 -0600 Subject: [PATCH 762/789] soc/intel/meteorlake: increase cbfs and preram cbmem console sizes These values were taken from alderlake. Change-Id: Ib790c7d52748156b25bad423ed082c1b51a33550 Signed-off-by: Jeremy Soller --- src/soc/intel/meteorlake/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index e5abfc0762..aa8d5eeb60 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -348,11 +348,11 @@ config VBOOT_HASH_BLOCK_SIZE config CBFS_SIZE hex - default 0x200000 + default 0x400000 config PRERAM_CBMEM_CONSOLE_SIZE hex - default 0x2000 + default 0x4000 config CONSOLE_CBMEM_BUFFER_SIZE hex From fe4f34556f21d31ec8e08c721e566405726dfe37 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Wed, 5 Jun 2024 08:14:33 -0600 Subject: [PATCH 763/789] soc/intel/mtl: Set HDA subsystem ID during FSP-M Intel introduced a new UPD specifically for setting the HDA subsystem ID in FSP-M. Using SiSsidTablePtr in FSP-S no longer works as it will be locked with a default value of 0 by that point. Tested on Clevo V560TU with MTL FSP 4122.12 (0D.00.A8.20). TEST=PCI config space for HDA device has subsystem ID set. Change-Id: I5e668747d99b955b0a3946524c5918d328b8e1d3 Signed-off-by: Tim Crawford --- src/soc/intel/meteorlake/romstage/fsp_params.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/soc/intel/meteorlake/romstage/fsp_params.c b/src/soc/intel/meteorlake/romstage/fsp_params.c index d6c0b04782..3ab0618174 100644 --- a/src/soc/intel/meteorlake/romstage/fsp_params.c +++ b/src/soc/intel/meteorlake/romstage/fsp_params.c @@ -294,6 +294,8 @@ static void fill_fspm_misc_params(FSP_M_CONFIG *m_cfg, static void fill_fspm_audio_params(FSP_M_CONFIG *m_cfg, const struct soc_intel_meteorlake_config *config) { + const struct device *dev; + /* Audio: HDAUDIO_LINK_MODE I2S/SNDW */ m_cfg->PchHdaEnable = is_devfn_enabled(PCI_DEVFN_HDA); m_cfg->PchHdaDspEnable = config->pch_hda_dsp_enable; @@ -308,6 +310,13 @@ static void fill_fspm_audio_params(FSP_M_CONFIG *m_cfg, memset(m_cfg->PchHdaAudioLinkDmicEnable, 0, sizeof(m_cfg->PchHdaAudioLinkDmicEnable)); memset(m_cfg->PchHdaAudioLinkSspEnable, 0, sizeof(m_cfg->PchHdaAudioLinkSspEnable)); memset(m_cfg->PchHdaAudioLinkSndwEnable, 0, sizeof(m_cfg->PchHdaAudioLinkSndwEnable)); + + dev = pcidev_path_on_root(PCI_DEVFN_HDA); + if (dev) { + uint16_t svid = CONFIG_SUBSYSTEM_VENDOR_ID ? : (dev->subsystem_vendor ? : 0x8086); + uint16_t ssid = CONFIG_SUBSYSTEM_DEVICE_ID ? : (dev->subsystem_device ? : 0x7e28); + m_cfg->PchHdaSubSystemIds = (ssid << 16) | svid; + } } static void fill_fspm_cnvi_params(FSP_M_CONFIG *m_cfg, From 0b3b3ce10c2039fb4e1c01bdd530d6cdfb6ed8af Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 29 Dec 2020 11:22:00 -0700 Subject: [PATCH 764/789] intel/block/pcie/rtd3: Also implement _PR3 Change-Id: Id7f4373989dffe8c3bc68a034f59a94d2160dd15 Signed-off-by: Jeremy Soller --- src/soc/intel/common/block/pcie/rtd3/rtd3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/intel/common/block/pcie/rtd3/rtd3.c b/src/soc/intel/common/block/pcie/rtd3/rtd3.c index 3a7c8b4afc..06775f125b 100644 --- a/src/soc/intel/common/block/pcie/rtd3/rtd3.c +++ b/src/soc/intel/common/block/pcie/rtd3/rtd3.c @@ -384,7 +384,7 @@ static void pcie_rtd3_acpi_fill_ssdt(const struct device *dev) static bool mutex_created = false; const struct soc_intel_common_block_pcie_rtd3_config *config = config_of(dev); - static const char *const power_res_states[] = {"_PR0"}; + static const char *const power_res_states[] = {"_PR0", "_PR3"}; const struct device *parent = dev->upstream->dev; const char *scope = acpi_device_path(parent); const struct opregion opregion = OPREGION("PXCS", PCI_CONFIG, 0, 0xff); From aa98aede36480373e4c6bf53a5200c68002d760e Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Fri, 15 Jul 2022 09:22:21 -0600 Subject: [PATCH 765/789] mb/system76/bonw14: Enable TAS5825M smart amp The Bonobo has 2 AMPs: one for the speakers and one for the subwoofer. Smart AMP data was collected using a logic analyzer connected to the IC during system start on proprietary firmware. This data is then used to generate a C file [1]. [1]: https://github.com/system76/smart-amp Change-Id: I5389a9890563ebd3adb20096b6225f474bc006f9 Signed-off-by: Tim Crawford --- src/mainboard/system76/bonw14/Kconfig | 1 + src/mainboard/system76/bonw14/Makefile.mk | 1 + src/mainboard/system76/bonw14/devicetree.cb | 11 +- .../system76/bonw14/tas5825m-normal.c | 1240 +++++++++++++++++ src/mainboard/system76/bonw14/tas5825m-sub.c | 1240 +++++++++++++++++ src/mainboard/system76/bonw14/tas5825m.c | 15 + 6 files changed, 2507 insertions(+), 1 deletion(-) create mode 100644 src/mainboard/system76/bonw14/tas5825m-normal.c create mode 100644 src/mainboard/system76/bonw14/tas5825m-sub.c create mode 100644 src/mainboard/system76/bonw14/tas5825m.c diff --git a/src/mainboard/system76/bonw14/Kconfig b/src/mainboard/system76/bonw14/Kconfig index 7c7e42e10b..2cc814a3a7 100644 --- a/src/mainboard/system76/bonw14/Kconfig +++ b/src/mainboard/system76/bonw14/Kconfig @@ -9,6 +9,7 @@ config BOARD_SPECIFIC_OPTIONS select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID select DRIVERS_I2C_HID + select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC select EC_SYSTEM76_EC_DGPU select HAVE_ACPI_RESUME diff --git a/src/mainboard/system76/bonw14/Makefile.mk b/src/mainboard/system76/bonw14/Makefile.mk index 2efcac5f42..89b8816938 100644 --- a/src/mainboard/system76/bonw14/Makefile.mk +++ b/src/mainboard/system76/bonw14/Makefile.mk @@ -10,3 +10,4 @@ romstage-y += romstage.c ramstage-y += ramstage.c ramstage-y += gpio.c ramstage-y += hda_verb.c +ramstage-y += tas5825m.c diff --git a/src/mainboard/system76/bonw14/devicetree.cb b/src/mainboard/system76/bonw14/devicetree.cb index 4064c00b55..9f2d35a993 100644 --- a/src/mainboard/system76/bonw14/devicetree.cb +++ b/src/mainboard/system76/bonw14/devicetree.cb @@ -175,6 +175,15 @@ chip soc/intel/cannonlake device ref hda on register "PchHdaAudioLinkHda" = "1" end - device ref smbus on end + device ref smbus on + chip drivers/i2c/tas5825m + register "id" = "0" + device i2c 4e on end # (8bit address: 0x9c) + end + chip drivers/i2c/tas5825m + register "id" = "1" + device i2c 4f on end # (8bit address: 0x9e) + end + end end end diff --git a/src/mainboard/system76/bonw14/tas5825m-normal.c b/src/mainboard/system76/bonw14/tas5825m-normal.c new file mode 100644 index 0000000000..81695effd8 --- /dev/null +++ b/src/mainboard/system76/bonw14/tas5825m-normal.c @@ -0,0 +1,1240 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +static int tas5825m_setup_normal(struct device *dev) +{ + int res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x01, 0x11); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x46, 0x11); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x02, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x53, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x54, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x29, 0x7C); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x29, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x12); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x48, 0x0C); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x64); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xFE, 0x00, 0x40, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x50, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x93, 0x00, 0xFC, 0x00, 0x00, + 0x8F, 0x00, 0xFF, 0xEF, 0x84, 0x49, 0x03, 0x27, + 0x84, 0x02, 0x04, 0x06, 0x02, 0x60, 0x00, 0x01, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x70, 0x00, 0x06, 0x02, 0x78, 0x00, 0x05, + 0x02, 0x68, 0x00, 0x02, 0x02, 0x28, 0x03, 0x4D, + 0x84, 0x2A, 0x04, 0x00, 0xE2, 0x57, 0x91, 0x9F, + 0x84, 0x82, 0x20, 0xE0, 0x84, 0x82, 0x04, 0x01, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x68, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x27, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x41, 0x03, 0x37, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x00, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x11, 0xAA, 0xF0, 0x1C, 0x11, 0xAB, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1C, 0x11, 0xAC, 0xF0, 0x1F, 0x11, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x43, 0x03, 0x37, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x51, 0x03, 0x3E, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x47, 0x84, 0xC2, 0x40, 0xE0, + 0x8C, 0xFF, 0x03, 0x23, 0xE0, 0x10, 0x11, 0xB3, + 0xF0, 0x1C, 0x51, 0xB4, 0xF0, 0x1C, 0x51, 0xB5, + 0xF0, 0x1C, 0x51, 0xB6, 0xF0, 0x1F, 0x51, 0xB7, + 0x86, 0xA1, 0x01, 0xC6, 0x80, 0x27, 0x80, 0xEA, + 0x84, 0x53, 0x03, 0x3E, 0x84, 0x82, 0x04, 0x05, + 0x84, 0x51, 0x03, 0x75, 0xE2, 0x6B, 0xC0, 0x00, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x80, 0x31, 0xB8, + 0x84, 0x82, 0x40, 0xE0, 0xF0, 0x1C, 0x51, 0xB9, + 0xF0, 0x1C, 0x51, 0xBA, 0xF0, 0x1C, 0x51, 0xBB, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1F, 0x51, 0xBC, 0x86, 0xA1, 0x01, 0xC5, + 0x80, 0x27, 0x80, 0xEA, 0x60, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x81, 0x84, 0xA1, 0x03, 0x4F, + 0xE0, 0x80, 0xA0, 0x00, 0x01, 0x07, 0x11, 0x20, + 0x08, 0x44, 0x26, 0x30, 0x08, 0x00, 0x98, 0x4A, + 0x84, 0x53, 0x03, 0x75, 0x08, 0x00, 0x30, 0x48, + 0x02, 0xCA, 0x00, 0x01, 0x08, 0x60, 0x26, 0x32, + 0x84, 0x51, 0x03, 0x45, 0xE4, 0x10, 0x40, 0x00, + 0x80, 0x40, 0xC0, 0x82, 0x84, 0xC2, 0x40, 0xE0, + 0x84, 0xC3, 0x03, 0x5E, 0x08, 0x00, 0x50, 0x48, + 0xE0, 0x10, 0x11, 0xBD, 0x02, 0xC2, 0x00, 0x02, + 0x08, 0x60, 0x06, 0x12, 0x84, 0xD3, 0x03, 0x4F, + 0xF0, 0x1C, 0x51, 0xBE, 0xF0, 0x1C, 0x51, 0xBF, + 0xF0, 0x1C, 0x51, 0xC0, 0xF0, 0x1F, 0x51, 0xC1, + 0x84, 0xA1, 0x03, 0x65, 0x80, 0x27, 0x80, 0xEA, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x83, + 0x08, 0x00, 0x98, 0x6B, 0x08, 0x00, 0x30, 0x68, + 0x84, 0x53, 0x03, 0x45, 0x08, 0x60, 0x26, 0x33, + 0x84, 0x51, 0x03, 0x25, 0xE4, 0x10, 0x60, 0x00, + 0x80, 0x40, 0xC0, 0x81, 0x02, 0x70, 0x00, 0x7F, + 0x08, 0x00, 0x50, 0x28, 0x08, 0x60, 0x06, 0x11, + 0x84, 0xCB, 0x03, 0x65, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x01, + 0x84, 0xA2, 0x04, 0x03, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x25, 0x80, 0x00, 0xC4, 0x04, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x60, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x02, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x60, 0x00, 0x01, 0x02, 0x70, 0x00, 0x04, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0x41, 0x03, 0x67, + 0x84, 0x51, 0x03, 0x6D, 0x84, 0xC0, 0x04, 0x02, + 0x04, 0x80, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x02, 0x78, 0x00, 0x03, 0x02, 0x68, 0x00, 0x02, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + 0x84, 0x49, 0x03, 0x2F, 0xE0, 0x80, 0x71, 0xA9, + 0x02, 0x28, 0x03, 0x55, 0x84, 0x82, 0x00, 0xE0, + 0x84, 0x2A, 0x04, 0x00, 0xF0, 0x1C, 0x11, 0xAA, + 0xF0, 0x1C, 0x11, 0xAB, 0xF0, 0x1C, 0x11, 0xAC, + 0xF0, 0x1F, 0x11, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xE8, 0x84, 0x82, 0x04, 0x07, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x80, 0x60, 0x00, 0x84, 0x82, 0x40, 0xE0, + 0x84, 0x43, 0x03, 0x67, 0xF0, 0x1C, 0x51, 0xAF, + 0xF0, 0x1C, 0x51, 0xB0, 0xF0, 0x1C, 0x51, 0xB1, + 0xF0, 0x1F, 0x51, 0xB2, 0x02, 0x78, 0x00, 0x05, + 0x80, 0x27, 0x80, 0xEA, 0x84, 0x82, 0x04, 0x08, + 0x02, 0x70, 0x00, 0x06, 0x84, 0x53, 0x03, 0x6D, + 0x84, 0x80, 0x04, 0x07, 0xE0, 0x00, 0x00, 0x82, + 0xF0, 0x81, 0x00, 0x80, 0x80, 0x07, 0x12, 0xBC, + 0x86, 0xA1, 0x01, 0x9F, 0xE2, 0x57, 0xA0, 0x00, + 0x84, 0x82, 0x04, 0x09, 0x84, 0x82, 0x20, 0xE0, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x08); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x6A, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x2F, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x59, 0x03, 0x3D, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x60, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x71, 0xAA, 0xF0, 0x1C, 0x71, 0xAB, + 0xF0, 0x1C, 0x71, 0xAC, 0xF0, 0x1F, 0x71, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xEB, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x5B, 0x03, 0x3D, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x59, 0x03, 0x3F, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x57, 0x84, 0xC2, 0x60, 0xE0, + 0xE0, 0x10, 0x11, 0xB3, 0xF0, 0x1C, 0x71, 0xB4, + 0xF0, 0x1C, 0x71, 0xB5, 0xF0, 0x1C, 0x71, 0xB6, + 0xF0, 0x1F, 0x71, 0xB7, 0x86, 0xA1, 0x01, 0xC6, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x09); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x80, 0x27, 0x80, 0xEB, 0x84, 0x5B, 0x03, 0x3F, + 0x84, 0x82, 0x04, 0x0D, 0x84, 0x41, 0x03, 0x76, + 0xE2, 0x6B, 0xE0, 0x00, 0x80, 0x07, 0x00, 0x80, + 0xE0, 0x81, 0x31, 0xB8, 0x84, 0x82, 0x00, 0xE0, + 0xF0, 0x1C, 0x11, 0xB9, 0xF0, 0x1C, 0x11, 0xBA, + 0xF0, 0x1C, 0x11, 0xBB, 0xF0, 0x1F, 0x11, 0xBC, + 0x86, 0xA1, 0x01, 0xC5, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x81, + 0x84, 0xA1, 0x03, 0x5D, 0xE0, 0x81, 0xA0, 0x00, + 0x01, 0x07, 0x11, 0x20, 0x08, 0x44, 0x26, 0x30, + 0x08, 0x00, 0x98, 0x4A, 0x84, 0x43, 0x03, 0x76, + 0x08, 0x00, 0x30, 0x48, 0x02, 0xCA, 0x00, 0x01, + 0x08, 0x60, 0x26, 0x32, 0x84, 0x41, 0x03, 0x46, + 0xE4, 0x10, 0x40, 0x00, 0x80, 0x40, 0xC0, 0x82, + 0x84, 0xC2, 0x00, 0xE0, 0x84, 0xC3, 0x03, 0x5F, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x50, 0x48, 0xE0, 0x10, 0x11, 0xBD, + 0x02, 0xC2, 0x00, 0x02, 0x08, 0x60, 0x06, 0x12, + 0x84, 0xD3, 0x03, 0x5D, 0xF0, 0x1C, 0x11, 0xBE, + 0xF0, 0x1C, 0x11, 0xBF, 0xF0, 0x1C, 0x11, 0xC0, + 0xF0, 0x1F, 0x11, 0xC1, 0x84, 0xA1, 0x03, 0x66, + 0x80, 0x27, 0x80, 0xE8, 0xE0, 0x00, 0x00, 0x00, + 0x80, 0x07, 0x00, 0x83, 0x08, 0x00, 0x98, 0x6B, + 0x08, 0x00, 0x30, 0x68, 0x84, 0x43, 0x03, 0x46, + 0x08, 0x60, 0x26, 0x33, 0x84, 0x51, 0x03, 0x26, + 0xE4, 0x10, 0x60, 0x00, 0x80, 0x40, 0xC0, 0x81, + 0x02, 0x70, 0x00, 0x7F, 0x08, 0x00, 0x50, 0x28, + 0x08, 0x60, 0x06, 0x11, 0x8C, 0xFF, 0x03, 0x24, + 0x84, 0xCB, 0x03, 0x66, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x09, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0xA2, 0x04, 0x0B, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x26, 0x80, 0x00, 0xC4, 0x0C, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x80, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x0A, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x70, 0x00, 0x04, 0x02, 0x68, 0x00, 0x01, + 0x02, 0x60, 0x00, 0x03, 0x02, 0x78, 0x00, 0x02, + 0x84, 0x49, 0x03, 0x6E, 0x84, 0x41, 0x03, 0x6F, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0xC0, 0x04, 0x0A, + 0x04, 0x81, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0x00, 0x04, 0x06, 0xE0, 0x81, 0x71, 0xA9, + 0x84, 0x82, 0x20, 0xE8, 0xF0, 0x1D, 0x31, 0xAA, + 0xF0, 0x1D, 0x31, 0xAB, 0xF0, 0x1D, 0x31, 0xAC, + 0xF0, 0x1C, 0x31, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xF9, 0x84, 0x82, 0x04, 0x0E, + 0xE0, 0x81, 0x60, 0x00, 0x84, 0x82, 0x00, 0xE8, + 0x84, 0x4B, 0x03, 0x6E, 0xF0, 0x1D, 0x11, 0xAF, + 0xF0, 0x1D, 0x11, 0xB0, 0xF0, 0x1D, 0x11, 0xB1, + 0xF0, 0x1C, 0x11, 0xB2, 0x02, 0xA3, 0x00, 0x1A, + 0x80, 0x27, 0x80, 0xF8, 0x84, 0x82, 0x04, 0x0F, + 0xE0, 0x81, 0xC0, 0x00, 0xF0, 0x81, 0xE0, 0x80, + 0x84, 0x43, 0x03, 0x6F, 0x80, 0x07, 0x12, 0xBD, + 0x02, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x11, 0x8F, 0x00, 0xFF, 0xFF, + 0x84, 0x58, 0x04, 0x01, 0x84, 0xC2, 0x04, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0xC2, 0x60, 0x00, 0x84, 0xA0, 0x61, 0x00, + 0xE0, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x40, 0x40, 0xA0, 0x00, 0x80, 0x00, 0xC0, 0x82, + 0x08, 0xFC, 0x48, 0x3A, 0x08, 0xFC, 0x18, 0x50, + 0x00, 0xFC, 0x00, 0x00, 0xE0, 0x10, 0x00, 0x00, + 0x86, 0xA0, 0x41, 0x00, 0x40, 0x47, 0x20, 0x00, + 0x80, 0x00, 0xC0, 0x83, 0x04, 0xE0, 0x3D, 0x1E, + 0x04, 0x80, 0x11, 0xE0, 0x08, 0x44, 0x26, 0x33, + 0x02, 0xCB, 0x00, 0x10, 0xE0, 0x10, 0x40, 0x83, + 0x08, 0x00, 0x28, 0x21, 0x84, 0xCA, 0x61, 0x00, + 0x80, 0x07, 0x00, 0x81, 0x0C, 0xE0, 0x2C, 0x09, + 0x84, 0xCA, 0x21, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x01 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x18); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x03, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x40, 0x00, 0x00, 0x03, 0x48, + 0x00, 0x00, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x54, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x03, 0x60, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x74, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x0C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x03, 0x78, + 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x24, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x04, 0x88, 0x00, 0x00, 0x04, 0x90, + }; + res = tas5825m_write_block_at(dev, 0x44, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xA7, 0x26, 0x4A, 0x7F, 0xFF, 0xFF, 0xFF, + 0x00, 0x20, 0xC4, 0x9C, 0x00, 0x20, 0xC4, 0x9C, + 0x00, 0x00, 0x68, 0xDB, 0x00, 0x00, 0xD1, 0xB7, + 0x00, 0x00, 0x68, 0xDB, 0x0F, 0xA4, 0xA8, 0xC1, + 0xF8, 0x59, 0x7F, 0x63 + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xB7, 0xE9, + 0x00, 0x5F, 0x6F, 0xD2, 0x00, 0x2F, 0xB7, 0xE9, + 0x0B, 0x1E, 0x4F, 0x76, 0xFC, 0x23, 0x05, 0x54, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x7D, 0xBF, 0x48, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x1E, 0x4F, 0x76, + 0xFC, 0x23, 0x05, 0x54, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x10); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x89, 0xA0, 0x27, 0x7F, 0xEC, 0x56, 0xD5, + 0x7F, 0xFC, 0xB9, 0x23, 0x00, 0x89, 0xA0, 0x27, + 0x7F, 0xEC, 0x56, 0xD5, 0x7F, 0xFC, 0xB9, 0x23, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x40, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x11, 0xFF + }; + res = tas5825m_write_block_at(dev, 0x7D, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x51, 0x05); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x19, 0xDF); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x71, 0x94, 0x9A + }; + res = tas5825m_write_block_at(dev, 0x2C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00, 0x0C, 0xCC, 0xCD, + 0x00, 0x0C, 0xCC, 0xCD, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0x62, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x28, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x03, 0x69, 0xC5, 0x00, 0xA9, 0x15, 0xB8, + 0x00, 0x22, 0x1D, 0x95, 0x00, 0x03, 0x69, 0xC5, + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x7F, 0xF9, 0x2C, 0x60, 0x01, 0x33, 0x51, 0x50, + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0xAA); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xD1, 0x27, 0x3E, 0xF0, 0x5D, 0xB1, 0x85, + 0x07, 0xD1, 0x27, 0x3E, 0x0F, 0xA1, 0x3C, 0x1E, + 0xF8, 0x5C, 0x9F, 0x28, 0x07, 0xD1, 0x27, 0x3E, + 0xF0, 0x5D, 0xB1, 0x85, 0x07, 0xD1, 0x27, 0x3E, + 0x0F, 0xA1, 0x3C, 0x1E, 0xF8, 0x5C, 0x9F, 0x28, + 0x08, 0x00, 0x00, 0x00, 0xF0, 0x71, 0x4C, 0x87, + 0x07, 0x91, 0xC6, 0x22, 0x0F, 0x8E, 0xB3, 0x79, + 0xF8, 0x6E, 0x39, 0xDE, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x21, 0xA6, 0xC8, 0xF0, 0xA9, 0xF7, 0x0B, + 0x07, 0x3B, 0x34, 0x61, 0x0F, 0x56, 0x08, 0xF5, + 0xF8, 0xA3, 0x24, 0xD7, 0x08, 0x58, 0xFE, 0x57, + 0xF8, 0xB7, 0x23, 0xC8, 0x01, 0xF4, 0x51, 0x2E, + 0x07, 0x48, 0xDC, 0x38, 0xFD, 0xB2, 0xB0, 0x7B, + 0x0A, 0x8B, 0x89, 0x0F, 0xFA, 0xBE, 0x92, 0xE5, + 0xFE, 0xEA, 0x2A, 0xF4, 0x05, 0x41, 0x6D, 0x1B, + 0xFE, 0x8A, 0x4B, 0xFE, 0x09, 0x6F, 0x71, 0xB3, + 0xF4, 0xC9, 0x2E, 0xBA, 0x02, 0xE0, 0x4E, 0xFB, + 0x0B, 0x36, 0xD1, 0x46, 0xFB, 0xB0, 0x3F, 0x52, + 0x07, 0x86, 0xC1, 0xF0, 0xF3, 0x50, 0x29, 0xD7, + 0x05, 0x3A, 0xF8, 0x0F, 0x0C, 0xAF, 0xD6, 0x29, + 0xFB, 0x3E, 0x46, 0x00, 0x08, 0x17, 0x5D, 0x4C, + 0xF0, 0xBC, 0xDB, 0x13, 0x07, 0x34, 0x29, 0xCB, + 0x0F, 0x43, 0x24, 0xED, 0xF8, 0xB4, 0x78, 0xEA, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xFC, 0xDB, 0x0F, 0xF0, 0x3A, 0xC4, 0xBE, + 0x07, 0xC9, 0x51, 0x50, 0x0F, 0xC5, 0x3B, 0x42, + 0xF8, 0x39, 0xD3, 0xA1, 0x07, 0xFC, 0x38, 0xBF, + 0xF0, 0x47, 0x14, 0xF2, 0x07, 0xBE, 0x4A, 0x80, + 0x0F, 0xB8, 0xEB, 0x0E, 0xF8, 0x45, 0x7C, 0xC1, + 0x07, 0xEB, 0xF6, 0xEF, 0xF1, 0x08, 0x7E, 0x56, + 0x07, 0x17, 0x63, 0xC3, 0x0E, 0xF7, 0x81, 0xAA, + 0xF8, 0xFC, 0xA5, 0x4E, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xD1, 0x27, 0x3E, + 0xF0, 0x5D, 0xB1, 0x85, 0x07, 0xD1, 0x27, 0x3E, + 0x0F, 0xA1, 0x3C, 0x1E, 0xF8, 0x5C, 0x9F, 0x28, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xD1, 0x27, 0x3E, 0xF0, 0x5D, 0xB1, 0x85, + 0x07, 0xD1, 0x27, 0x3E, 0x0F, 0xA1, 0x3C, 0x1E, + 0xF8, 0x5C, 0x9F, 0x28, 0x08, 0x00, 0x00, 0x00, + 0xF0, 0x71, 0x4C, 0x87, 0x07, 0x91, 0xC6, 0x22, + 0x0F, 0x8E, 0xB3, 0x79, 0xF8, 0x6E, 0x39, 0xDE, + 0x08, 0x21, 0xA6, 0xC8, 0xF0, 0xA9, 0xF7, 0x0B, + 0x07, 0x3B, 0x34, 0x61, 0x0F, 0x56, 0x08, 0xF5, + 0xF8, 0xA3, 0x24, 0xD7, 0x08, 0x58, 0xFE, 0x57, + 0xF8, 0xB7, 0x23, 0xC8, 0x01, 0xF4, 0x51, 0x2E, + 0x07, 0x48, 0xDC, 0x38, 0xFD, 0xB2, 0xB0, 0x7B, + 0x0A, 0x8B, 0x89, 0x0F, 0xFA, 0xBE, 0x92, 0xE5, + 0xFE, 0xEA, 0x2A, 0xF4, 0x05, 0x41, 0x6D, 0x1B, + 0xFE, 0x8A, 0x4B, 0xFE, 0x09, 0x6F, 0x71, 0xB3, + 0xF4, 0xC9, 0x2E, 0xBA, 0x02, 0xE0, 0x4E, 0xFB, + 0x0B, 0x36, 0xD1, 0x46, 0xFB, 0xB0, 0x3F, 0x52, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0x86, 0xC1, 0xF0, 0xF3, 0x50, 0x29, 0xD7, + 0x05, 0x3A, 0xF8, 0x0F, 0x0C, 0xAF, 0xD6, 0x29, + 0xFB, 0x3E, 0x46, 0x00, 0x08, 0x17, 0x5D, 0x4C, + 0xF0, 0xBC, 0xDB, 0x13, 0x07, 0x34, 0x29, 0xCB, + 0x0F, 0x43, 0x24, 0xED, 0xF8, 0xB4, 0x78, 0xEA, + 0x07, 0xFB, 0x25, 0x84, 0xF0, 0x49, 0xA3, 0xCE, + 0x07, 0xC7, 0xA6, 0xCB, 0x0F, 0xB6, 0x5C, 0x32, + 0xF8, 0x3D, 0x33, 0xB1, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x86, 0x43, 0x99, 0xFF, 0x02, 0xE6, 0x50, + 0x00, 0x77, 0xAC, 0xFD, 0x0F, 0xD7, 0xE6, 0xBF, + 0xF8, 0x27, 0x42, 0x5B + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF4, 0x49, 0x81, + 0xFF, 0xE8, 0x93, 0x02, 0xFF, 0xF4, 0x49, 0x81, + 0x0D, 0x94, 0x7A, 0x64, 0xFA, 0x3C, 0xAB, 0xA1, + 0x06, 0xD5, 0xF3, 0xB1, 0xF2, 0x54, 0x18, 0x9F, + 0x06, 0xD5, 0xF3, 0xB1, 0x0D, 0x94, 0x7A, 0x64, + 0xFA, 0x3C, 0xAB, 0xA1, 0x00, 0x00, 0x38, 0xE4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xD5, 0x55, 0x55, 0xF8, 0x2A, 0x71, 0xC7, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x30, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x60, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x62, 0x09); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4C, 0x30); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x03); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x78, 0x80); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x60, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x64, 0x02); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4E, 0xBB); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4F, 0xB0); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x03); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x78, 0x80); + if (res < 0) + return res; + + return 0; +} diff --git a/src/mainboard/system76/bonw14/tas5825m-sub.c b/src/mainboard/system76/bonw14/tas5825m-sub.c new file mode 100644 index 0000000000..28987d9be2 --- /dev/null +++ b/src/mainboard/system76/bonw14/tas5825m-sub.c @@ -0,0 +1,1240 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +static int tas5825m_setup_sub(struct device *dev) +{ + int res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x01, 0x11); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x46, 0x11); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x02, 0x04); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x53, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x54, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x29, 0x7C); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x29, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x12); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x48, 0x0C); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x64); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xFE, 0x00, 0x40, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x50, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x93, 0x00, 0xFC, 0x00, 0x00, + 0x8F, 0x00, 0xFF, 0xEF, 0x84, 0x49, 0x03, 0x27, + 0x84, 0x02, 0x04, 0x06, 0x02, 0x60, 0x00, 0x01, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x70, 0x00, 0x06, 0x02, 0x78, 0x00, 0x05, + 0x02, 0x68, 0x00, 0x02, 0x02, 0x28, 0x03, 0x4D, + 0x84, 0x2A, 0x04, 0x00, 0xE2, 0x57, 0x91, 0x9F, + 0x84, 0x82, 0x20, 0xE0, 0x84, 0x82, 0x04, 0x01, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x68, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x27, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x41, 0x03, 0x37, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x00, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x11, 0xAA, 0xF0, 0x1C, 0x11, 0xAB, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1C, 0x11, 0xAC, 0xF0, 0x1F, 0x11, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x43, 0x03, 0x37, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x51, 0x03, 0x3E, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x47, 0x84, 0xC2, 0x40, 0xE0, + 0x8C, 0xFF, 0x03, 0x23, 0xE0, 0x10, 0x11, 0xB3, + 0xF0, 0x1C, 0x51, 0xB4, 0xF0, 0x1C, 0x51, 0xB5, + 0xF0, 0x1C, 0x51, 0xB6, 0xF0, 0x1F, 0x51, 0xB7, + 0x86, 0xA1, 0x01, 0xC6, 0x80, 0x27, 0x80, 0xEA, + 0x84, 0x53, 0x03, 0x3E, 0x84, 0x82, 0x04, 0x05, + 0x84, 0x51, 0x03, 0x75, 0xE2, 0x6B, 0xC0, 0x00, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x80, 0x31, 0xB8, + 0x84, 0x82, 0x40, 0xE0, 0xF0, 0x1C, 0x51, 0xB9, + 0xF0, 0x1C, 0x51, 0xBA, 0xF0, 0x1C, 0x51, 0xBB, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1F, 0x51, 0xBC, 0x86, 0xA1, 0x01, 0xC5, + 0x80, 0x27, 0x80, 0xEA, 0x60, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x81, 0x84, 0xA1, 0x03, 0x4F, + 0xE0, 0x80, 0xA0, 0x00, 0x01, 0x07, 0x11, 0x20, + 0x08, 0x44, 0x26, 0x30, 0x08, 0x00, 0x98, 0x4A, + 0x84, 0x53, 0x03, 0x75, 0x08, 0x00, 0x30, 0x48, + 0x02, 0xCA, 0x00, 0x01, 0x08, 0x60, 0x26, 0x32, + 0x84, 0x51, 0x03, 0x45, 0xE4, 0x10, 0x40, 0x00, + 0x80, 0x40, 0xC0, 0x82, 0x84, 0xC2, 0x40, 0xE0, + 0x84, 0xC3, 0x03, 0x5E, 0x08, 0x00, 0x50, 0x48, + 0xE0, 0x10, 0x11, 0xBD, 0x02, 0xC2, 0x00, 0x02, + 0x08, 0x60, 0x06, 0x12, 0x84, 0xD3, 0x03, 0x4F, + 0xF0, 0x1C, 0x51, 0xBE, 0xF0, 0x1C, 0x51, 0xBF, + 0xF0, 0x1C, 0x51, 0xC0, 0xF0, 0x1F, 0x51, 0xC1, + 0x84, 0xA1, 0x03, 0x65, 0x80, 0x27, 0x80, 0xEA, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x83, + 0x08, 0x00, 0x98, 0x6B, 0x08, 0x00, 0x30, 0x68, + 0x84, 0x53, 0x03, 0x45, 0x08, 0x60, 0x26, 0x33, + 0x84, 0x51, 0x03, 0x25, 0xE4, 0x10, 0x60, 0x00, + 0x80, 0x40, 0xC0, 0x81, 0x02, 0x70, 0x00, 0x7F, + 0x08, 0x00, 0x50, 0x28, 0x08, 0x60, 0x06, 0x11, + 0x84, 0xCB, 0x03, 0x65, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x01, + 0x84, 0xA2, 0x04, 0x03, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x25, 0x80, 0x00, 0xC4, 0x04, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x60, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x02, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x60, 0x00, 0x01, 0x02, 0x70, 0x00, 0x04, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0x41, 0x03, 0x67, + 0x84, 0x51, 0x03, 0x6D, 0x84, 0xC0, 0x04, 0x02, + 0x04, 0x80, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x02, 0x78, 0x00, 0x03, 0x02, 0x68, 0x00, 0x02, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + 0x84, 0x49, 0x03, 0x2F, 0xE0, 0x80, 0x71, 0xA9, + 0x02, 0x28, 0x03, 0x55, 0x84, 0x82, 0x00, 0xE0, + 0x84, 0x2A, 0x04, 0x00, 0xF0, 0x1C, 0x11, 0xAA, + 0xF0, 0x1C, 0x11, 0xAB, 0xF0, 0x1C, 0x11, 0xAC, + 0xF0, 0x1F, 0x11, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xE8, 0x84, 0x82, 0x04, 0x07, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x80, 0x60, 0x00, 0x84, 0x82, 0x40, 0xE0, + 0x84, 0x43, 0x03, 0x67, 0xF0, 0x1C, 0x51, 0xAF, + 0xF0, 0x1C, 0x51, 0xB0, 0xF0, 0x1C, 0x51, 0xB1, + 0xF0, 0x1F, 0x51, 0xB2, 0x02, 0x78, 0x00, 0x05, + 0x80, 0x27, 0x80, 0xEA, 0x84, 0x82, 0x04, 0x08, + 0x02, 0x70, 0x00, 0x06, 0x84, 0x53, 0x03, 0x6D, + 0x84, 0x80, 0x04, 0x07, 0xE0, 0x00, 0x00, 0x82, + 0xF0, 0x81, 0x00, 0x80, 0x80, 0x07, 0x12, 0xBC, + 0x86, 0xA1, 0x01, 0x9F, 0xE2, 0x57, 0xA0, 0x00, + 0x84, 0x82, 0x04, 0x09, 0x84, 0x82, 0x20, 0xE0, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x08); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x6A, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x2F, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x59, 0x03, 0x3D, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x60, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x71, 0xAA, 0xF0, 0x1C, 0x71, 0xAB, + 0xF0, 0x1C, 0x71, 0xAC, 0xF0, 0x1F, 0x71, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xEB, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x5B, 0x03, 0x3D, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x59, 0x03, 0x3F, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x57, 0x84, 0xC2, 0x60, 0xE0, + 0xE0, 0x10, 0x11, 0xB3, 0xF0, 0x1C, 0x71, 0xB4, + 0xF0, 0x1C, 0x71, 0xB5, 0xF0, 0x1C, 0x71, 0xB6, + 0xF0, 0x1F, 0x71, 0xB7, 0x86, 0xA1, 0x01, 0xC6, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x09); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x80, 0x27, 0x80, 0xEB, 0x84, 0x5B, 0x03, 0x3F, + 0x84, 0x82, 0x04, 0x0D, 0x84, 0x41, 0x03, 0x76, + 0xE2, 0x6B, 0xE0, 0x00, 0x80, 0x07, 0x00, 0x80, + 0xE0, 0x81, 0x31, 0xB8, 0x84, 0x82, 0x00, 0xE0, + 0xF0, 0x1C, 0x11, 0xB9, 0xF0, 0x1C, 0x11, 0xBA, + 0xF0, 0x1C, 0x11, 0xBB, 0xF0, 0x1F, 0x11, 0xBC, + 0x86, 0xA1, 0x01, 0xC5, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x81, + 0x84, 0xA1, 0x03, 0x5D, 0xE0, 0x81, 0xA0, 0x00, + 0x01, 0x07, 0x11, 0x20, 0x08, 0x44, 0x26, 0x30, + 0x08, 0x00, 0x98, 0x4A, 0x84, 0x43, 0x03, 0x76, + 0x08, 0x00, 0x30, 0x48, 0x02, 0xCA, 0x00, 0x01, + 0x08, 0x60, 0x26, 0x32, 0x84, 0x41, 0x03, 0x46, + 0xE4, 0x10, 0x40, 0x00, 0x80, 0x40, 0xC0, 0x82, + 0x84, 0xC2, 0x00, 0xE0, 0x84, 0xC3, 0x03, 0x5F, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x50, 0x48, 0xE0, 0x10, 0x11, 0xBD, + 0x02, 0xC2, 0x00, 0x02, 0x08, 0x60, 0x06, 0x12, + 0x84, 0xD3, 0x03, 0x5D, 0xF0, 0x1C, 0x11, 0xBE, + 0xF0, 0x1C, 0x11, 0xBF, 0xF0, 0x1C, 0x11, 0xC0, + 0xF0, 0x1F, 0x11, 0xC1, 0x84, 0xA1, 0x03, 0x66, + 0x80, 0x27, 0x80, 0xE8, 0xE0, 0x00, 0x00, 0x00, + 0x80, 0x07, 0x00, 0x83, 0x08, 0x00, 0x98, 0x6B, + 0x08, 0x00, 0x30, 0x68, 0x84, 0x43, 0x03, 0x46, + 0x08, 0x60, 0x26, 0x33, 0x84, 0x51, 0x03, 0x26, + 0xE4, 0x10, 0x60, 0x00, 0x80, 0x40, 0xC0, 0x81, + 0x02, 0x70, 0x00, 0x7F, 0x08, 0x00, 0x50, 0x28, + 0x08, 0x60, 0x06, 0x11, 0x8C, 0xFF, 0x03, 0x24, + 0x84, 0xCB, 0x03, 0x66, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x09, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0xA2, 0x04, 0x0B, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x26, 0x80, 0x00, 0xC4, 0x0C, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x80, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x0A, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x70, 0x00, 0x04, 0x02, 0x68, 0x00, 0x01, + 0x02, 0x60, 0x00, 0x03, 0x02, 0x78, 0x00, 0x02, + 0x84, 0x49, 0x03, 0x6E, 0x84, 0x41, 0x03, 0x6F, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0xC0, 0x04, 0x0A, + 0x04, 0x81, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0x00, 0x04, 0x06, 0xE0, 0x81, 0x71, 0xA9, + 0x84, 0x82, 0x20, 0xE8, 0xF0, 0x1D, 0x31, 0xAA, + 0xF0, 0x1D, 0x31, 0xAB, 0xF0, 0x1D, 0x31, 0xAC, + 0xF0, 0x1C, 0x31, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xF9, 0x84, 0x82, 0x04, 0x0E, + 0xE0, 0x81, 0x60, 0x00, 0x84, 0x82, 0x00, 0xE8, + 0x84, 0x4B, 0x03, 0x6E, 0xF0, 0x1D, 0x11, 0xAF, + 0xF0, 0x1D, 0x11, 0xB0, 0xF0, 0x1D, 0x11, 0xB1, + 0xF0, 0x1C, 0x11, 0xB2, 0x02, 0xA3, 0x00, 0x1A, + 0x80, 0x27, 0x80, 0xF8, 0x84, 0x82, 0x04, 0x0F, + 0xE0, 0x81, 0xC0, 0x00, 0xF0, 0x81, 0xE0, 0x80, + 0x84, 0x43, 0x03, 0x6F, 0x80, 0x07, 0x12, 0xBD, + 0x02, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x11, 0x8F, 0x00, 0xFF, 0xFF, + 0x84, 0x58, 0x04, 0x01, 0x84, 0xC2, 0x04, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0xC2, 0x60, 0x00, 0x84, 0xA0, 0x61, 0x00, + 0xE0, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x40, 0x40, 0xA0, 0x00, 0x80, 0x00, 0xC0, 0x82, + 0x08, 0xFC, 0x48, 0x3A, 0x08, 0xFC, 0x18, 0x50, + 0x00, 0xFC, 0x00, 0x00, 0xE0, 0x10, 0x00, 0x00, + 0x86, 0xA0, 0x41, 0x00, 0x40, 0x47, 0x20, 0x00, + 0x80, 0x00, 0xC0, 0x83, 0x04, 0xE0, 0x3D, 0x1E, + 0x04, 0x80, 0x11, 0xE0, 0x08, 0x44, 0x26, 0x33, + 0x02, 0xCB, 0x00, 0x10, 0xE0, 0x10, 0x40, 0x83, + 0x08, 0x00, 0x28, 0x21, 0x84, 0xCA, 0x61, 0x00, + 0x80, 0x07, 0x00, 0x81, 0x0C, 0xE0, 0x2C, 0x09, + 0x84, 0xCA, 0x21, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x01 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x18); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x03, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x40, 0x00, 0x00, 0x03, 0x48, + 0x00, 0x00, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x54, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x03, 0x60, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x74, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x0C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x03, 0x78, + 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x24, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x04, 0x88, 0x00, 0x00, 0x04, 0x90, + }; + res = tas5825m_write_block_at(dev, 0x44, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xA7, 0x26, 0x4A, 0x7F, 0xFF, 0xFF, 0xFF, + 0x00, 0x20, 0xC4, 0x9C, 0x00, 0x20, 0xC4, 0x9C, + 0x00, 0x00, 0x68, 0xDB, 0x00, 0x00, 0xD1, 0xB7, + 0x00, 0x00, 0x68, 0xDB, 0x0F, 0xA4, 0xA8, 0xC1, + 0xF8, 0x59, 0x7F, 0x63 + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xB7, 0xE9, + 0x00, 0x5F, 0x6F, 0xD2, 0x00, 0x2F, 0xB7, 0xE9, + 0x0B, 0x1E, 0x4F, 0x76, 0xFC, 0x23, 0x05, 0x54, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x7D, 0xBF, 0x48, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x1E, 0x4F, 0x76, + 0xFC, 0x23, 0x05, 0x54, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x10); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x89, 0xA0, 0x27, 0x7F, 0xEC, 0x56, 0xD5, + 0x7F, 0xFC, 0xB9, 0x23, 0x00, 0x89, 0xA0, 0x27, + 0x7F, 0xEC, 0x56, 0xD5, 0x7F, 0xFC, 0xB9, 0x23, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x40, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x11, 0xFF + }; + res = tas5825m_write_block_at(dev, 0x7D, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x51, 0x05); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x19, 0xDF); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x71, 0x94, 0x9A + }; + res = tas5825m_write_block_at(dev, 0x2C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x5A, 0x84, + 0x00, 0x1E, 0x5A, 0x84, 0x00, 0x40, 0x26, 0xE7, + 0x00, 0x40, 0x26, 0xE7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0x62, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x28, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x03, 0x69, 0xC5, 0x00, 0xEB, 0x8F, 0xA8, + 0x00, 0x22, 0x1D, 0x95, 0x00, 0x03, 0x69, 0xC5, + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x7F, 0xF9, 0x2C, 0x60, 0x01, 0xEB, 0x55, 0xAC, + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0xAA); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x01, 0x0A, 0x7A, 0x00, 0x02, 0x14, 0xF5, + 0x00, 0x01, 0x0A, 0x7A, 0x0F, 0x7B, 0xDB, 0x58, + 0xF8, 0x7F, 0xFA, 0xBE, 0x00, 0x01, 0x0A, 0x7A, + 0x00, 0x02, 0x14, 0xF5, 0x00, 0x01, 0x0A, 0x7A, + 0x0F, 0x7B, 0xDB, 0x58, 0xF8, 0x7F, 0xFA, 0xBE, + 0x07, 0xFD, 0xF9, 0x62, 0xF0, 0x25, 0x7A, 0x1B, + 0x07, 0xDC, 0xC4, 0xC6, 0x0F, 0xDA, 0x85, 0xE5, + 0xF8, 0x25, 0x41, 0xD8, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xF7, 0xFF, 0xB5, 0xF0, 0x4F, 0x8C, 0x33, + 0x07, 0xBA, 0x32, 0x37, 0x0F, 0xB0, 0x73, 0xCD, + 0xF8, 0x4D, 0xCE, 0x15, 0x07, 0xFA, 0x6B, 0x45, + 0xF0, 0x68, 0xC7, 0x1B, 0x07, 0x9E, 0xF0, 0xFB, + 0x0F, 0x97, 0x38, 0xE5, 0xF8, 0x66, 0xA3, 0xC0, + 0x07, 0xFE, 0x8C, 0x9C, 0xF0, 0x34, 0xCF, 0xDE, + 0x07, 0xCD, 0x94, 0xFF, 0x0F, 0xCB, 0x30, 0x22, + 0xF8, 0x33, 0xDE, 0x65, 0x07, 0xFE, 0x73, 0xDB, + 0xF0, 0x38, 0x93, 0x60, 0x07, 0xCA, 0x38, 0xAE, + 0x0F, 0xC7, 0x6C, 0xA0, 0xF8, 0x37, 0x53, 0x77, + 0x07, 0xF8, 0xC1, 0xBE, 0xF0, 0x88, 0xCB, 0x7D, + 0x07, 0x82, 0x08, 0xA9, 0x0F, 0x77, 0x34, 0x83, + 0xF8, 0x85, 0x35, 0x99, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xEE, 0xC6, 0xB4, + 0xF0, 0x22, 0x72, 0x97, 0x07, 0xEE, 0xC6, 0xB4, + 0x0F, 0xDD, 0x77, 0x9C, 0xF8, 0x22, 0x5C, 0xCB, + 0x07, 0xF4, 0x93, 0x76, 0xF0, 0x34, 0x67, 0xAD, + 0x07, 0xD7, 0xAE, 0x5A, 0x0F, 0xCB, 0x98, 0x53, + 0xF8, 0x33, 0xBE, 0x30, 0x08, 0x13, 0x15, 0xCB, + 0xF0, 0x0E, 0xB9, 0x1C, 0x07, 0xDE, 0xDC, 0x2A, + 0x0F, 0xF1, 0x86, 0x85, 0xF8, 0x0E, 0x4D, 0xAB, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xEE, 0xC6, 0xB4, 0xF0, 0x22, 0x72, 0x97, + 0x07, 0xEE, 0xC6, 0xB4, 0x0F, 0xDD, 0x77, 0x9C, + 0xF8, 0x22, 0x5C, 0xCB, 0x07, 0xF4, 0x93, 0x76, + 0xF0, 0x34, 0x67, 0xAD, 0x07, 0xD7, 0xAE, 0x5A, + 0x0F, 0xCB, 0x98, 0x53, 0xF8, 0x33, 0xBE, 0x30, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x13, 0x15, 0xCB, 0xF0, 0x0E, 0xB9, 0x1C, + 0x07, 0xDE, 0xDC, 0x2A, 0x0F, 0xF1, 0x86, 0x85, + 0xF8, 0x0E, 0x4D, 0xAB, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x85, 0xC0, 0x8D, 0xFF, 0x02, 0x2B, 0x75, + 0x00, 0x78, 0xBE, 0x6E, 0x0F, 0xE2, 0x46, 0xF6, + 0xF8, 0x1D, 0x0E, 0x9A + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xAA, 0xC3, + 0xFF, 0xFD, 0x55, 0x85, 0xFF, 0xFE, 0xAA, 0xC3, + 0x0F, 0x2F, 0x01, 0x62, 0xF8, 0xCB, 0xA9, 0xA8, + 0x07, 0x98, 0xD5, 0xEF, 0xF0, 0xCE, 0x54, 0x23, + 0x07, 0x98, 0xD5, 0xEF, 0x0F, 0x2F, 0x01, 0x62, + 0xF8, 0xCB, 0xA9, 0xA8, 0x00, 0x00, 0x38, 0xE4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xD5, 0x55, 0x55, 0xF8, 0x2A, 0x71, 0xC7, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x30, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x60, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x62, 0x09); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4C, 0x30); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x03); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x78, 0x80); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x60, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x64, 0x02); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4E, 0xBB); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4F, 0xB0); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x03); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x78, 0x80); + if (res < 0) + return res; + + return 0; +} diff --git a/src/mainboard/system76/bonw14/tas5825m.c b/src/mainboard/system76/bonw14/tas5825m.c new file mode 100644 index 0000000000..95680fae92 --- /dev/null +++ b/src/mainboard/system76/bonw14/tas5825m.c @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#include "tas5825m-normal.c" +#include "tas5825m-sub.c" + +int tas5825m_setup(struct device *dev, int id) +{ + if (id == 0) + return tas5825m_setup_normal(dev); + if (id == 1) + return tas5825m_setup_sub(dev); + return -1; +} From 21471fc40ae5c6d2dfef03837b20a0c1c0dd1ed8 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Tue, 1 Apr 2025 09:23:16 -0600 Subject: [PATCH 766/789] mb/system76/mtl: Enable EnableTcssCovTypeA configs This config is not available in coreboot FSP headers, but is required for USB3 to work correctly. Change-Id: I253c7b6b9fe67e251f6ba88d8176c7058292de0a Signed-off-by: Tim Crawford --- src/mainboard/system76/mtl/variants/darp10/ramstage.c | 3 +-- src/mainboard/system76/mtl/variants/lemp13/ramstage.c | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/mainboard/system76/mtl/variants/darp10/ramstage.c b/src/mainboard/system76/mtl/variants/darp10/ramstage.c index 0e3baf2ad6..63dfb35151 100644 --- a/src/mainboard/system76/mtl/variants/darp10/ramstage.c +++ b/src/mainboard/system76/mtl/variants/darp10/ramstage.c @@ -9,8 +9,7 @@ void mainboard_silicon_init_params(FSP_S_CONFIG *params) // BIT 4:5 is reserved // BIT 6 is orientational // BIT 7 is enable - // TODO: Add to coreboot FSP headers as no Client FSP release will be made. - //params->EnableTcssCovTypeA[1] = 0x82; + params->EnableTcssCovTypeA[1] = 0x82; // XXX: Enabling C10 reporting causes system to constantly enter and // exit opportunistic suspend when idle. diff --git a/src/mainboard/system76/mtl/variants/lemp13/ramstage.c b/src/mainboard/system76/mtl/variants/lemp13/ramstage.c index f99c93b0f2..26a52e4c88 100644 --- a/src/mainboard/system76/mtl/variants/lemp13/ramstage.c +++ b/src/mainboard/system76/mtl/variants/lemp13/ramstage.c @@ -11,9 +11,8 @@ void mainboard_silicon_init_params(FSP_S_CONFIG *params) // BIT 4:5 is reserved // BIT 6 is orientational // BIT 7 is enable - // TODO: Add to coreboot FSP headers as no Client FSP release will be made. - //params->EnableTcssCovTypeA[1] = 0x81; - //params->EnableTcssCovTypeA[3] = 0x85; + params->EnableTcssCovTypeA[1] = 0x81; + params->EnableTcssCovTypeA[3] = 0x85; // Disable reporting CPU C10 state over eSPI (causes LED flicker). params->PchEspiHostC10ReportEnable = 0; From be9c660930a82fffba63bd5a9680b0c7b627a10b Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Thu, 18 Jul 2024 10:40:28 -0600 Subject: [PATCH 767/789] mb/system76/rpl: Add bonw15-b variant The Bonobo has been updated with a Thunderbolt 5 controller (Barlow Ridge). Identified chip changes from the schematics: - JHL8540_MP -> JHL9580_QS - TPS65994BF -> TPS65994BH - IT5570E-128 -> IT5570E-256 Change-Id: I784e489cdd034febeaaac0182ab5b4fe672381ec Signed-off-by: Tim Crawford --- src/mainboard/system76/rpl/Kconfig | 11 +- src/mainboard/system76/rpl/Kconfig.name | 3 + .../system76/rpl/variants/bonw15-b/board.fmd | 12 + .../rpl/variants/bonw15-b/board_info.txt | 2 + .../system76/rpl/variants/bonw15-b/data.vbt | Bin 0 -> 8704 bytes .../system76/rpl/variants/bonw15-b/gpio.c | 294 ++++++++++++++++++ .../rpl/variants/bonw15-b/gpio_early.c | 16 + .../system76/rpl/variants/bonw15-b/hda_verb.c | 263 ++++++++++++++++ .../rpl/variants/bonw15-b/overridetree.cb | 111 +++++++ .../system76/rpl/variants/bonw15-b/romstage.c | 32 ++ 10 files changed, 743 insertions(+), 1 deletion(-) create mode 100644 src/mainboard/system76/rpl/variants/bonw15-b/board.fmd create mode 100644 src/mainboard/system76/rpl/variants/bonw15-b/board_info.txt create mode 100644 src/mainboard/system76/rpl/variants/bonw15-b/data.vbt create mode 100644 src/mainboard/system76/rpl/variants/bonw15-b/gpio.c create mode 100644 src/mainboard/system76/rpl/variants/bonw15-b/gpio_early.c create mode 100644 src/mainboard/system76/rpl/variants/bonw15-b/hda_verb.c create mode 100644 src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb create mode 100644 src/mainboard/system76/rpl/variants/bonw15-b/romstage.c diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index c46ed2dada..2c22affff1 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -46,6 +46,12 @@ config BOARD_SYSTEM76_BONW15 select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S +config BOARD_SYSTEM76_BONW15_B + select BOARD_SYSTEM76_RPL_COMMON + select EC_SYSTEM76_EC_DGPU + select PCIEXP_HOTPLUG + select SOC_INTEL_ALDERLAKE_PCH_S + config BOARD_SYSTEM76_DARP9 select BOARD_SYSTEM76_RPL_COMMON select PCIEXP_HOTPLUG @@ -97,6 +103,7 @@ config VARIANT_DIR default "addw3" if BOARD_SYSTEM76_ADDW3 default "addw4" if BOARD_SYSTEM76_ADDW4 default "bonw15" if BOARD_SYSTEM76_BONW15 + default "bonw15-b" if BOARD_SYSTEM76_BONW15_B default "darp9" if BOARD_SYSTEM76_DARP9 default "galp7" if BOARD_SYSTEM76_GALP7 default "gaze18" if BOARD_SYSTEM76_GAZE18 @@ -112,6 +119,7 @@ config MAINBOARD_PART_NUMBER default "addw3" if BOARD_SYSTEM76_ADDW3 default "addw4" if BOARD_SYSTEM76_ADDW4 default "bonw15" if BOARD_SYSTEM76_BONW15 + default "bonw15-b" if BOARD_SYSTEM76_BONW15_B default "darp9" if BOARD_SYSTEM76_DARP9 default "galp7" if BOARD_SYSTEM76_GALP7 default "gaze18" if BOARD_SYSTEM76_GAZE18 @@ -122,7 +130,7 @@ config MAINBOARD_PART_NUMBER config MAINBOARD_SMBIOS_PRODUCT_NAME default "Adder WS" if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_ADDW4 - default "Bonobo WS" if BOARD_SYSTEM76_BONW15 + default "Bonobo WS" if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B default "Darter Pro" if BOARD_SYSTEM76_DARP9 default "Galago Pro" if BOARD_SYSTEM76_GALP7 default "Gazelle" if BOARD_SYSTEM76_GAZE18 @@ -134,6 +142,7 @@ config MAINBOARD_VERSION default "addw3" if BOARD_SYSTEM76_ADDW3 default "addw4" if BOARD_SYSTEM76_ADDW4 default "bonw15" if BOARD_SYSTEM76_BONW15 + default "bonw15-b" if BOARD_SYSTEM76_BONW15_B default "darp9" if BOARD_SYSTEM76_DARP9 default "galp7" if BOARD_SYSTEM76_GALP7 default "gaze18" if BOARD_SYSTEM76_GAZE18 diff --git a/src/mainboard/system76/rpl/Kconfig.name b/src/mainboard/system76/rpl/Kconfig.name index 41842651f1..86ac52f945 100644 --- a/src/mainboard/system76/rpl/Kconfig.name +++ b/src/mainboard/system76/rpl/Kconfig.name @@ -9,6 +9,9 @@ config BOARD_SYSTEM76_ADDW4 config BOARD_SYSTEM76_BONW15 bool "bonw15" +config BOARD_SYSTEM76_BONW15_B + bool "bonw15-b" + config BOARD_SYSTEM76_DARP9 bool "darp9" diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/board.fmd b/src/mainboard/system76/rpl/variants/bonw15-b/board.fmd new file mode 100644 index 0000000000..b2615d1e17 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/board.fmd @@ -0,0 +1,12 @@ +FLASH 32M { + SI_DESC 4K + SI_ME 3944K + SI_BIOS@16M 16M { + RW_MRC_CACHE 64K + SMMSTORE(PRESERVE) 256K + WP_RO { + FMAP 4K + COREBOOT(CBFS) + } + } +} diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/board_info.txt b/src/mainboard/system76/rpl/variants/bonw15-b/board_info.txt new file mode 100644 index 0000000000..9dae13e21c --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/board_info.txt @@ -0,0 +1,2 @@ +Board name: bonw15-b +Release year: 2024 diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/data.vbt b/src/mainboard/system76/rpl/variants/bonw15-b/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..fedf53f295c415346e62bf301bacf849e43c00ba GIT binary patch literal 8704 zcmeHMO-vg{6n^8M#c@q>1Wg>8(1Aq6&;W}elpxfs`AeMeV;h1TDH4R(X=zDt38`pQ ziLHbxPSu_&5>=`dwNi_E;MB8^sJ);bs;cUNV-)qsDN5>oGrQQBgy2L?8&bd3+nJsB z=9~B4{Os)PvC*y(J`y_98|@FC@8y!>q|)!z0o)&_uF%l%SWj>yIM&ra)P0^mpab-M z^#Rch~U% z+G&uu(q!H}J(FzY!Ko=86*@O~G;t#_^Kl~HSn3u)X>vIj5pz?SPRIy))J0x$A>#mR zU=H?zZQw%57H2lpKkg#Mx3v!1wBtDqV4f}Kq-XPH=AfCR(Js%5xU`78UjBd!dtkRI zOC!gvyeQGc&FiHD)ux(o29(~W#zi620+yOE43yrcCNZEkXsNv>wH{NG(Sh0rPgi5Y zXsCT|sg-S_B`p^$D})}@?pkW5)|N(1wTHJLuslZ%K}2sb%~H=L-`H1k4_2<#>85wV zXTeeMCGb^n5_}810R95J1ilOY0sJF44gLwdFAgA^92PI?z6^5zOxYoy$!vPDS96|n zI)`y=cXcitmcCpd%6wh1Op5tP)Vb;66VjJL_T~xuT8W$1N;cSH`OB5tU=Ll3<%{J{ z2;B}v*>Pkp6+37ZQhd*T&zif1Xcu+(G54 zwKr(7hFo9RN$&7G*ikFH&x<;Z#&s$m_j>n>cC9$bSCgl|FFY2$d_6HWc==l56?iZm ze9`x}o0)QMm6X`>3%MH%$eC?q+eTv3`n()QU9l!TFN@LV+D0gPDxDalKl`8&!p8do zg(*%a*q4Oe4g8!J7u=EQfo+8H>;`>n3ymtH#VqZOtZDzIJO6sxBA0N}h}JeNI|fz( zxgc&0Eb^JmX&H5~^a?B2vRP=QFP``)Y(a{z+`P-8>6F>*8})W9P@Wl z0P6B%5^1sJTw_XszK#(cDh)9YFsl8Ms_V1d`a#UDxM5>qJ&9ToNPEelG6g>25rnHRE3 zhc{1V{2^rPEJjO^)#l08=4_-Xs!apRiX)IGdpN*o)Va+1$bcQ7x=joA8ep2=*g__J(3Dm3Q3SHM z&<30S?G%?Z2j3g0-O-R|=bg{+quDi%ALBR=P|9Ho Sa6oDB)B5jKkO@C`r@sNl8fgju literal 0 HcmV?d00001 diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/gpio.c b/src/mainboard/system76/rpl/variants/bonw15-b/gpio.c new file mode 100644 index 0000000000..3fa5f195d5 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/gpio.c @@ -0,0 +1,294 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config gpio_table[] = { + /* ------- GPIO Group GPD ------- */ + PAD_NC(GPD0, NONE), + PAD_CFG_NF(GPD1, NATIVE, PWROK, NF1), // AC_PRESENT + _PAD_CFG_STRUCT(GPD2, 0x42880100, 0x0000), // PCH_LAN_WAKE# + PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1), // PWR_BTN# + PAD_CFG_NF(GPD4, NONE, PWROK, NF1), // SUSB#_PCH + PAD_CFG_NF(GPD5, NONE, PWROK, NF1), // SUSC#_PCH + PAD_NC(GPD6, NONE), + PAD_CFG_GPI(GPD7, NONE, PWROK), // GPD_7 + PAD_CFG_NF(GPD8, NONE, PWROK, NF1), // CNVI_SUSCLK + PAD_CFG_GPO(GPD9, 0, PWROK), // SLP_WLAN_N + PAD_NC(GPD10, NONE), + PAD_CFG_GPO(GPD11, 0, DEEP), // LANPHYPC + PAD_NC(GPD12, NONE), + + /* ------- GPIO Group GPP_A ------- */ + PAD_CFG_NF(GPP_A0, UP_20K, DEEP, NF1), // ESPI_IO0_EC + PAD_CFG_NF(GPP_A1, UP_20K, DEEP, NF1), // ESPI_IO1_EC + PAD_CFG_NF(GPP_A2, UP_20K, DEEP, NF1), // ESPI_IO2_EC + PAD_CFG_NF(GPP_A3, UP_20K, DEEP, NF1), // ESPI_IO3_EC + PAD_CFG_NF(GPP_A4, UP_20K, DEEP, NF1), // ESPI_CS_EC# + PAD_CFG_NF(GPP_A5, DN_20K, DEEP, NF1), // ESPI_CLK_EC + PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), // ESPI_RESET_N + PAD_NC(GPP_A7, NONE), + PAD_NC(GPP_A8, NONE), + PAD_NC(GPP_A9, NONE), + PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1), // ESPI_ALERT0# + PAD_NC(GPP_A11, NONE), + PAD_NC(GPP_A12, NONE), + PAD_NC(GPP_A13, NONE), + PAD_NC(GPP_A14, NONE), + + /* ------- GPIO Group GPP_B ------- */ + _PAD_CFG_STRUCT(GPP_B0, 0x82900100, 0x0000), // TPM_PIRQ# + PAD_NC(GPP_B1, NONE), + PAD_CFG_GPI(GPP_B2, NONE, DEEP), // CNVI_WAKE# + PAD_CFG_GPO(GPP_B3, 1, DEEP), // PCH_BT_EN + PAD_NC(GPP_B4, NONE), + PAD_NC(GPP_B5, NONE), + PAD_NC(GPP_B6, NONE), + PAD_NC(GPP_B7, NONE), + PAD_NC(GPP_B8, NONE), + PAD_NC(GPP_B9, NONE), + PAD_NC(GPP_B10, NONE), + PAD_NC(GPP_B11, NONE), + PAD_NC(GPP_B12, NONE), + PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), // PLT_RST# + PAD_CFG_NF(GPP_B14, NONE, DEEP, NF1), // HDA_SPKR + PAD_NC(GPP_B15, NONE), // PS8461_SW + PAD_NC(GPP_B16, NONE), + PAD_NC(GPP_B17, NONE), // 2.5G_LAN_EN + PAD_CFG_NF(GPP_B18, NONE, RSMRST, NF1), // PMCALERT# (tied high) + PAD_CFG_GPO(GPP_B19, 1, DEEP), // PCH_WLAN_EN + PAD_NC(GPP_B20, NONE), + PAD_NC(GPP_B21, NONE), + PAD_CFG_GPO(GPP_B22, 1, DEEP), // LAN_RST# + PAD_CFG_GPI(GPP_B23, NONE, RSMRST), // GPP_B23 (XTAL FREQ SEL1) + + /* ------- GPIO Group GPP_C ------- */ + PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), // SMB_CLK + PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), // SMB_DATA + PAD_CFG_GPI(GPP_C2, NONE, PLTRST), // TLS confidentiality strap + PAD_CFG_GPO(GPP_C3, 0, DEEP), // GPPC_I2C2_SDA (Pantone) + PAD_CFG_GPO(GPP_C4, 0, DEEP), // GPPC_I2C2_SCL (Pantone) + PAD_NC(GPP_C5, NONE), // eSPI disable strap + PAD_NC(GPP_C6, NONE), + PAD_NC(GPP_C7, NONE), + PAD_CFG_GPI(GPP_C8, NONE, DEEP), // TPM_DET + PAD_NC(GPP_C9, NONE), + PAD_NC(GPP_C10, NONE), + PAD_NC(GPP_C11, NONE), + PAD_NC(GPP_C12, NONE), + PAD_NC(GPP_C13, NONE), + PAD_NC(GPP_C14, NONE), + PAD_NC(GPP_C15, NONE), + PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), // I2C_SDA_TP + PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), // I2C_SCL_TP + PAD_CFG_NF(GPP_C18, NONE, DEEP, NF1), // PCH_I2C_SDA (TPS65994) + PAD_CFG_NF(GPP_C19, NONE, DEEP, NF1), // PCH_I2C_SCL (TPS65994) + // GPP_C20 (UART2_RXD) configured in bootblock + // GPP_C21 (UART2_TXD) configured in bootblock + PAD_CFG_GPO(GPP_C22, 0, DEEP), // ROM_I2C_EN (TPS65994) + PAD_NC(GPP_C23, NONE), + + /* ------- GPIO Group GPP_D ------- */ + PAD_NC(GPP_D0, NONE), + PAD_NC(GPP_D1, NONE), + PAD_NC(GPP_D2, NONE), + PAD_NC(GPP_D3, NONE), // GFX_DETECT_STRAP + PAD_NC(GPP_D4, NONE), + PAD_CFG_GPO(GPP_D5, 1, DEEP), // M.2_BT_PCMFRM_CRF_RST_N + // GPP_D6 (M.2_BT_PCMOUT_CLKREQ0) configured by FSP + PAD_NC(GPP_D7, NONE), + PAD_NC(GPP_D8, NONE), + PAD_NC(GPP_D9, NONE), + PAD_NC(GPP_D10, NONE), + PAD_NC(GPP_D11, NONE), + PAD_NC(GPP_D12, NONE), + PAD_NC(GPP_D13, NONE), + PAD_NC(GPP_D14, NONE), + PAD_NC(GPP_D15, NONE), + PAD_NC(GPP_D16, NONE), + PAD_NC(GPP_D17, NONE), + PAD_NC(GPP_D18, NONE), + PAD_NC(GPP_D19, NONE), + PAD_NC(GPP_D20, NONE), + PAD_NC(GPP_D21, NONE), + PAD_NC(GPP_D22, NONE), + PAD_NC(GPP_D23, NONE), + + /* ------- GPIO Group GPP_E ------- */ + PAD_CFG_GPO(GPP_E0, 1, DEEP), // GPP_E0_TBT_RST# + PAD_NC(GPP_E1, NONE), + PAD_NC(GPP_E2, NONE), + PAD_NC(GPP_E3, NONE), + PAD_NC(GPP_E4, NONE), + PAD_NC(GPP_E5, NONE), + PAD_NC(GPP_E6, NONE), + PAD_CFG_GPI_INT(GPP_E7, NONE, PLTRST, LEVEL), // TP_ATTN# + PAD_CFG_NF(GPP_E8, NONE, DEEP, NF1), // SATA_LED# + PAD_CFG_NF(GPP_E9, NONE, DEEP, NF1), // GPP_E_9_USB_OC0_N + PAD_CFG_NF(GPP_E10, NONE, DEEP, NF1), // GPP_E_10_USB_OC1_N + PAD_CFG_NF(GPP_E11, NONE, DEEP, NF1), // GPP_E_11_USB_OC2_N + PAD_CFG_NF(GPP_E12, NONE, DEEP, NF1), // GPP_E_12_USB_OC3_N + PAD_NC(GPP_E13, NONE), + PAD_NC(GPP_E14, NONE), + PAD_NC(GPP_E15, NONE), + PAD_NC(GPP_E16, NONE), + PAD_NC(GPP_E17, NONE), + PAD_CFG_GPO(GPP_E18, 1, DEEP), // SB_BLON + _PAD_CFG_STRUCT(GPP_E19, 0x42880100, 0x0000), // GPP_E19_TBT_WAKE# + PAD_NC(GPP_E20, NONE), + PAD_NC(GPP_E21, NONE), + + /* ------- GPIO Group GPP_F ------- */ + PAD_NC(GPP_F0, NONE), + PAD_NC(GPP_F1, NONE), + PAD_NC(GPP_F2, NONE), + PAD_NC(GPP_F3, NONE), + PAD_NC(GPP_F4, NONE), + PAD_NC(GPP_F5, NONE), + PAD_NC(GPP_F6, NONE), + PAD_NC(GPP_F7, NONE), + PAD_CFG_GPI(GPP_F8, NONE, DEEP), // GC6_FB_EN_PCH + PAD_NC(GPP_F9, NONE), + PAD_NC(GPP_F10, NONE), + PAD_NC(GPP_F11, NONE), + PAD_NC(GPP_F12, NONE), + PAD_NC(GPP_F13, NONE), + PAD_CFG_GPI(GPP_F14, NONE, DEEP), // TBT5 strap + PAD_CFG_GPI(GPP_F15, NONE, DEEP), // H_SKTOCC_N + PAD_NC(GPP_F16, NONE), + PAD_NC(GPP_F17, NONE), + PAD_CFG_GPO(GPP_F18, 0, DEEP), // CCD_FW_WP# + PAD_CFG_NF(GPP_F19, NONE, DEEP, NF1), // NB_ENAVDD + PAD_CFG_NF(GPP_F20, NONE, DEEP, NF1), // BLON + PAD_CFG_NF(GPP_F21, NONE, DEEP, NF1), // EDP_BRIGHTNESS + // GPP_F22 (DGPU_PWR_EN) configured in bootblock + PAD_NC(GPP_F23, NONE), + + /* ------- GPIO Group GPP_G ------- */ + PAD_NC(GPP_G0, NONE), + PAD_CFG_GPI(GPP_G1, NONE, DEEP), // GPU SKU strap (L: X9, H: X11) + PAD_NC(GPP_G2, NONE), + PAD_CFG_GPI(GPP_G3, NONE, DEEP), // DDS strap (L: Non-DDS, H: DDS) + PAD_CFG_GPI(GPP_G4, NONE, DEEP), // Smart AMP strap (L: TI, H: Realtek) + PAD_CFG_NF(GPP_G5, NONE, DEEP, NF1), // SLP_DRAM_N + PAD_CFG_GPI(GPP_G6, NONE, DEEP), // Pantone (L: W/O, H: W) + PAD_NC(GPP_G7, NONE), + + /* ------- GPIO Group GPP_H ------- */ + PAD_CFG_GPI(GPP_H0, NONE, DEEP), // VAL_SV_ADVANCE_STRAP + PAD_NC(GPP_H1, NONE), + PAD_NC(GPP_H2, NONE), // WLAN_WAKE_N + // GPP_H3 (WLAN_CLKREQ9#) configured by FSP + // GPP_H4 (SSD1_CLKREQ10#) configured by FSP + // GPP_H5 (SSD2_CLKREQ11#) configured by FSP + // GPP_H6 (SSD3_CLKREQ12#) configured by FSP + // GPP_H7 (TBT_CLKREQ13#) configured by FSP + // GPP_H8 (GPU_PCIE_CLKREQ14#) configured by FSP + // GPP_H9 (GLAN_CLKREQ15#) configured by FSP + PAD_NC(GPP_H10, NONE), + PAD_NC(GPP_H11, NONE), + PAD_CFG_GPI(GPP_H12, NONE, RSMRST), // eSPI flash sharing mode strap (L: MAF, H: SAF) + PAD_NC(GPP_H13, NONE), + PAD_NC(GPP_H14, NONE), + PAD_CFG_GPI(GPP_H15, NONE, RSMRST), // JTAG ODT disable strap (L: Disable, H: Enable) + PAD_NC(GPP_H16, NONE), + PAD_CFG_GPO(GPP_H17, 1, DEEP), // M.2_PLT_RST_CNTRL3# + PAD_CFG_GPI(GPP_H18, NONE, RSMRST), // VCCPSPI strap (L: 3.3V, H: 1.8V) + PAD_NC(GPP_H19, NONE), + PAD_NC(GPP_H20, NONE), + PAD_NC(GPP_H21, NONE), // TBT_MRESET_PCH + PAD_NC(GPP_H22, NONE), + PAD_NC(GPP_H23, NONE), + + /* ------- GPIO Group GPP_I ------- */ + PAD_NC(GPP_I0, NONE), + _PAD_CFG_STRUCT(GPP_I1, 0x86880100, 0x0000), // G_DP_DHPD_E + _PAD_CFG_STRUCT(GPP_I2, 0x86880100, 0x0000), // DP_D_HPD + _PAD_CFG_STRUCT(GPP_I3, 0x86880100, 0x0000), // HDMI_HPD + _PAD_CFG_STRUCT(GPP_I4, 0x86880100, 0x0000), // DP_A_HPD + PAD_NC(GPP_I5, NONE), + PAD_NC(GPP_I6, NONE), + PAD_NC(GPP_I7, NONE), + PAD_NC(GPP_I8, NONE), + PAD_NC(GPP_I9, NONE), + PAD_NC(GPP_I10, NONE), + PAD_CFG_NF(GPP_I11, NONE, DEEP, NF1), // GPP_I_11_USB_OC4_N + PAD_CFG_NF(GPP_I12, NONE, DEEP, NF1), // GPP_I_12_USB_OC5_N + PAD_CFG_NF(GPP_I13, NONE, DEEP, NF1), // GPP_I_13_USB_OC6_N + PAD_CFG_NF(GPP_I14, NONE, DEEP, NF1), // GPP_I_14_USB_OC7_N + PAD_NC(GPP_I15, NONE), + PAD_NC(GPP_I16, NONE), + PAD_NC(GPP_I17, NONE), + PAD_CFG_GPI(GPP_I18, NONE, PWROK), // No reboot strap (L: Disable, H: Enable) + PAD_NC(GPP_I19, NONE), + PAD_NC(GPP_I20, NONE), + PAD_NC(GPP_I21, NONE), + PAD_CFG_GPI(GPP_I22, NONE, PWROK), // Boot BIOS strap (L: MAF or SAF, H: eSPI) + + /* ------- GPIO Group GPP_J ------- */ + PAD_CFG_NF(GPP_J0, NONE, DEEP, NF1), // CNVI_GNSS_PA_BLANKING + PAD_CFG_NF(GPP_J1, NONE, DEEP, NF1), // CPU_C10_GATE# + PAD_CFG_NF(GPP_J2, NONE, DEEP, NF1), // CNVI_BRI_DT_R + PAD_CFG_NF(GPP_J3, UP_20K, DEEP, NF1), // CNVI_BRI_RSP + PAD_CFG_NF(GPP_J4, NONE, DEEP, NF1), // CNVI_RGI_DT_R + PAD_CFG_NF(GPP_J5, UP_20K, DEEP, NF1), // CNVI_RGI_RSP + PAD_CFG_NF(GPP_J6, NONE, DEEP, NF1), // CNVI_MFUART2_RXD + PAD_CFG_NF(GPP_J7, NONE, DEEP, NF1), // CNVI_MFUART2_TXD + PAD_CFG_GPI(GPP_J8, NONE, DEEP), // VAL_TEST_SETUP_MENU + PAD_NC(GPP_J9, NONE), + PAD_NC(GPP_J10, NONE), + PAD_NC(GPP_J11, NONE), + + /* ------- GPIO Group GPP_K ------- */ + PAD_NC(GPP_K0, NONE), + PAD_NC(GPP_K1, NONE), + PAD_NC(GPP_K2, NONE), + PAD_NC(GPP_K3, NONE), + PAD_NC(GPP_K4, NONE), + PAD_NC(GPP_K5, NONE), + // GPP_K6 missing + // GPP_K7 missing + PAD_CFG_NF(GPP_K8, NONE, DEEP, NF1), // GPP_K_8_CORE_VID_0 + PAD_CFG_NF(GPP_K9, NONE, DEEP, NF1), // GPP_K_9_CORE_VID_1 + PAD_CFG_NF(GPP_K10, NONE, DEEP, NF2), + PAD_NC(GPP_K11, NONE), + + /* ------- GPIO Group GPP_R ------- */ + PAD_CFG_NF(GPP_R0, NONE, DEEP, NF1), // HDA_BITCLK + PAD_CFG_NF(GPP_R1, NATIVE, DEEP, NF1), // HDA_SYNC + PAD_CFG_NF(GPP_R2, NATIVE, DEEP, NF1), // HDA_SDOUT + PAD_CFG_NF(GPP_R3, NATIVE, DEEP, NF1), // HDA_SDIN0 + PAD_CFG_NF(GPP_R4, NONE, DEEP, NF1), // HDA_RST# + PAD_NC(GPP_R5, NONE), + PAD_NC(GPP_R6, NONE), + PAD_CFG_GPO(GPP_R7, 1, DEEP), // GPP_R7_TBT_RTD3 + PAD_CFG_GPI(GPP_R8, NONE, DEEP), // DGPU_PWRGD + PAD_CFG_NF(GPP_R9, NONE, DEEP, NF1), // EDP_HPD + PAD_NC(GPP_R10, NONE), + PAD_NC(GPP_R11, NONE), + PAD_NC(GPP_R12, NONE), + PAD_NC(GPP_R13, NONE), + PAD_NC(GPP_R14, NONE), + PAD_NC(GPP_R15, NONE), + // GPP_R16 (DGPU_RST#_PCH) configured in bootblock + PAD_NC(GPP_R17, NONE), + PAD_NC(GPP_R18, NONE), + PAD_NC(GPP_R19, NONE), + PAD_NC(GPP_R20, NONE), + PAD_NC(GPP_R21, NONE), + + /* ------- GPIO Group GPP_S ------- */ + PAD_NC(GPP_S0, NONE), + PAD_NC(GPP_S1, NONE), + PAD_NC(GPP_S2, NONE), + PAD_NC(GPP_S3, NONE), + PAD_NC(GPP_S4, NONE), // GPPS_DMIC_CLK + PAD_NC(GPP_S5, NONE), // GPPS_DMIC_DATA + PAD_NC(GPP_S6, NONE), + PAD_NC(GPP_S7, NONE), +}; + +void mainboard_configure_gpios(void) +{ + gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); +} diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/gpio_early.c b/src/mainboard/system76/rpl/variants/bonw15-b/gpio_early.c new file mode 100644 index 0000000000..cea38b54ce --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/gpio_early.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config early_gpio_table[] = { + PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), // UART2_RXD + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), // UART2_TXD + PAD_CFG_GPO(GPP_F22, 0, DEEP), // DGPU_PWR_EN + PAD_CFG_GPO(GPP_R16, 0, DEEP), // DGPU_RST#_PCH +}; + +void mainboard_configure_early_gpios(void) +{ + gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table)); +} diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/hda_verb.c b/src/mainboard/system76/rpl/variants/bonw15-b/hda_verb.c new file mode 100644 index 0000000000..c1f031cc95 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/hda_verb.c @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +const u32 cim_verb_data[] = { + /* Realtek, ALC1220 */ + 0x10ec1220, /* Vendor ID */ + 0x15583702, /* Subsystem ID */ + 243, /* Number of entries */ + + 0x02050008, 0x020480cb, 0x02050008, 0x0204c0cb, + AZALIA_SUBVENDOR(0, 0x15583702), + AZALIA_RESET(1), + AZALIA_PIN_CFG(0, 0x12, 0x90a60130), + AZALIA_PIN_CFG(0, 0x14, 0x0421101f), + AZALIA_PIN_CFG(0, 0x15, 0x40000000), + AZALIA_PIN_CFG(0, 0x16, 0x411111f0), + AZALIA_PIN_CFG(0, 0x17, 0x411111f0), + AZALIA_PIN_CFG(0, 0x18, 0x04a11040), + AZALIA_PIN_CFG(0, 0x19, 0x411111f0), + AZALIA_PIN_CFG(0, 0x1a, 0x411111f0), + AZALIA_PIN_CFG(0, 0x1b, 0x90170110), + AZALIA_PIN_CFG(0, 0x1d, 0x40b7952d), + AZALIA_PIN_CFG(0, 0x1e, 0x04451150), + + // ALC1318 smart amp + 0x05b50000, 0x05b43530, 0x05750002, 0x05741400, + 0x02050058, 0x02048ed1, 0x02050063, 0x0204e430, + 0x02050016, 0x02048020, 0x02050016, 0x02048020, + 0x02050043, 0x02043005, 0x02050058, 0x02048ed1, + 0x02050063, 0x0204e430, 0x05b50000, 0x05b43530, + 0x05750002, 0x05741400, 0x05b5000a, 0x05b45520, + 0x02050042, 0x020486cb, 0x0143b000, 0x01470700, + 0x02050036, 0x02042a6a, 0x02050008, 0x0204800b, + 0x02050007, 0x020403c3, 0x01470c02, 0x01470c02, + 0x00c37100, 0x01b3b000, 0x01b70700, 0x00b37417, + 0x0205001b, 0x02044002, 0x0205001b, 0x02044002, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c000, 0x0205002b, 0x02040001, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f20d, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f212, 0x0205002b, 0x0204003e, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c001, + 0x0205002b, 0x02040002, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c003, 0x0205002b, 0x02040022, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c004, + 0x0205002b, 0x02040044, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c005, 0x0205002b, 0x02040044, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c007, + 0x0205002b, 0x02040064, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c00e, 0x0205002b, 0x020400e7, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f223, + 0x0205002b, 0x0204007f, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f224, 0x0205002b, 0x020400db, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f225, + 0x0205002b, 0x020400ee, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f226, 0x0205002b, 0x0204003f, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f227, + 0x0205002b, 0x0204000f, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f21a, 0x0205002b, 0x02040078, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f242, + 0x0205002b, 0x0204003c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c120, 0x0205002b, 0x02040040, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c125, + 0x0205002b, 0x02040003, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c321, 0x0205002b, 0x0204000b, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c200, + 0x0205002b, 0x020400d8, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c201, 0x0205002b, 0x02040027, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c202, + 0x0205002b, 0x0204000f, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c400, 0x0205002b, 0x0204000e, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c401, + 0x0205002b, 0x02040043, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c402, 0x0205002b, 0x020400e0, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c403, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c404, 0x0205002b, 0x0204004c, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c406, + 0x0205002b, 0x02040040, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c407, 0x0205002b, 0x02040002, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c408, + 0x0205002b, 0x0204003f, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c300, 0x0205002b, 0x02040001, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c125, + 0x0205002b, 0x02040003, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204df00, 0x0205002b, 0x02040010, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204df5f, + 0x0205002b, 0x02040001, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204df60, 0x0205002b, 0x020400a7, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204ea00, + 0x0205002b, 0x02040047, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c203, 0x0205002b, 0x02040004, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c206, + 0x0205002b, 0x02040078, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f102, 0x0205002b, 0x02040000, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f103, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f104, 0x0205002b, 0x020400f4, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f105, + 0x0205002b, 0x02040003, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f109, 0x0205002b, 0x020400e0, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10a, + 0x0205002b, 0x0204000b, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10b, 0x0205002b, 0x0204004c, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10b, + 0x0205002b, 0x0204005c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f102, 0x0205002b, 0x02040000, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f103, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f104, 0x0205002b, 0x020400f4, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f105, + 0x0205002b, 0x02040004, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f109, 0x0205002b, 0x02040065, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10a, + 0x0205002b, 0x0204000b, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10b, 0x0205002b, 0x0204004c, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10b, + 0x0205002b, 0x0204005c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204e706, 0x0205002b, 0x0204000f, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204e707, + 0x0205002b, 0x02040030, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204e806, 0x0205002b, 0x0204000f, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204e807, + 0x0205002b, 0x02040030, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204ce04, 0x0205002b, 0x02040002, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204ce05, + 0x0205002b, 0x02040087, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204ce06, 0x0205002b, 0x020400a2, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204ce07, + 0x0205002b, 0x0204006c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204cf04, 0x0205002b, 0x02040002, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204cf05, + 0x0205002b, 0x02040087, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204cf06, 0x0205002b, 0x020400a2, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204cf07, + 0x0205002b, 0x0204006c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204ce60, 0x0205002b, 0x020400e3, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c130, + 0x0205002b, 0x02040051, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204e000, 0x0205002b, 0x020400a8, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f102, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f103, 0x0205002b, 0x02040000, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f104, + 0x0205002b, 0x020400f5, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f105, 0x0205002b, 0x02040023, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f109, + 0x0205002b, 0x02040004, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10a, 0x0205002b, 0x0204000b, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10b, + 0x0205002b, 0x0204004c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10b, 0x0205002b, 0x0204005c, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02044100, 0x02050029, 0x02041888, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c121, 0x0205002b, 0x0204000b, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f102, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f103, 0x0205002b, 0x02040000, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f104, + 0x0205002b, 0x020400f5, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f105, 0x0205002b, 0x02040023, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f109, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10a, 0x0205002b, 0x0204000b, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10b, + 0x0205002b, 0x0204004c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10b, 0x0205002b, 0x0204005c, + 0x0205002c, 0x0204b423, + + // XXX: Duplicate last 2 u32s to keep in 4-dword blocks + 0x0205002c, 0x0204b423, +}; + +const u32 pc_beep_verbs[] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb b/src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb new file mode 100644 index 0000000000..0c455f60f7 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb @@ -0,0 +1,111 @@ +chip soc/intel/alderlake + # Support 5600 MT/s memory + register "max_dram_speed_mts" = "5600" + + device domain 0 on + subsystemid 0x1558 0x3702 inherit + + device ref xhci on + register "usb2_ports" = "{ + [0] = USB2_PORT_MID(OC_SKIP), /* Type-A 3.2 Gen 2 (Left, Front) */ + [1] = USB2_PORT_MID(OC_SKIP), /* Type-A 3.2 Gen 2 (Left, Rear) */ + [5] = USB2_PORT_MID(OC_SKIP), /* Camera */ + [6] = USB2_PORT_MID(OC_SKIP), /* Per-key RGB */ + /* Port reset messaging cannot be used, + * so do not use USB2_PORT_TYPE_C for these */ + [8] = USB2_PORT_MID(OC_SKIP), /* Type-C Thunderbolt (Right, Front) */ + [9] = USB2_PORT_MID(OC_SKIP), /* Type-C Thunderbolt with PD (Right, Rear) */ + [13] = USB2_PORT_MID(OC_SKIP), /* Bluetooth */ + }" + register "usb3_ports" = "{ + [0] = USB3_PORT_DEFAULT(OC_SKIP), /* Type-A 3.2 Gen 2 (Left, Front) */ + [2] = USB3_PORT_DEFAULT(OC_SKIP), /* Type-A 3.2 Gen 2 (Left, Rear) */ + }" + end + + device ref i2c0 on + # Touchpad I2C bus + register "serial_io_i2c_mode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + chip drivers/i2c/hid + register "generic.hid" = ""ELAN0412"" + register "generic.desc" = ""ELAN Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_E7)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 15 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""FTCS1000"" + register "generic.desc" = ""FocalTech Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_E7)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 38 on end + end + end + + device ref pcie5_0 on + # CPU PCIe RP#3 x4, CLKOUT 2, CLKREQ 11 (SSD2) + register "cpu_pcie_rp[CPU_RP(2)]" = "{ + .clk_src = 2, + .clk_req = 11, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + + device ref pcie5_1 on + # CPU PCIe RP#2 x8, Clock 14 (DGPU) + register "cpu_pcie_rp[CPU_RP(3)]" = "{ + .clk_src = 14, + .clk_req = 14, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + + device ref pcie4_0 on + # CPU PCIe RP#1 x4, Clock 12 (SSD3) + register "cpu_pcie_rp[CPU_RP(1)]" = "{ + .clk_src = 12, + .clk_req = 12, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + + device ref pcie_rp7 on + # PCH RP#7 x1, Clock 13 (GLAN) + register "pch_pcie_rp[PCH_RP(7)]" = "{ + .clk_src = 15, + .clk_req = 15, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + device pci 00.0 on end + end + + device ref pcie_rp8 on + # PCH RP#8 x1, Clock 9 (WLAN) + register "pch_pcie_rp[PCH_RP(8)]" = "{ + .clk_src = 9, + .clk_req = 9, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + + device ref pcie_rp9 on + # PCH RP#9 x4, Clock 15 (TBT) + register "pch_pcie_rp[PCH_RP(9)]" = "{ + .clk_src = 13, + .clk_req = 13, + .flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR, + }" + end + + device ref pcie_rp21 on + # PCH RP#21 x4, Clock 10 (SSD1) + register "pch_pcie_rp[PCH_RP(21)]" = "{ + .clk_src = 10, + .clk_req = 10, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + end +end diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/romstage.c b/src/mainboard/system76/rpl/variants/bonw15-b/romstage.c new file mode 100644 index 0000000000..30a904544c --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/romstage.c @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + const struct mb_cfg board_cfg = { + .type = MEM_TYPE_DDR5, + .ect = true, + .LpDdrDqDqsReTraining = 1, + .ddr_config = { + .dq_pins_interleaved = true, + }, + }; + const struct mem_spd spd_info = { + .topo = MEM_TOPO_DIMM_MODULE, + .smbus = { + [0] = { .addr_dimm[0] = 0x50, }, + [1] = { .addr_dimm[0] = 0x52, }, + }, + }; + const bool half_populated = false; + + // Set primary display to internal graphics + mupd->FspmConfig.PrimaryDisplay = 0; + + mupd->FspmConfig.DmiMaxLinkSpeed = 4; + mupd->FspmConfig.GpioOverride = 0; + + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); +} From 833feebdda3cd46e5cb50ba9bdda39c4d98742ed Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 17 Apr 2025 09:50:02 -0600 Subject: [PATCH 768/789] mb/system76/meer9: Add Meerkat 9 The Meerkat 9 is an Intel Meteor Lake-H based small form factor desktop computer based on the Asus NUC-155H R2. Change-Id: I37a0b808cf383379b8e284831644c824c0d4817e Signed-off-by: Jeremy Soller Signed-off-by: Tim Crawford --- src/mainboard/system76/meer9/Kconfig | 83 +++++++ src/mainboard/system76/meer9/Kconfig.name | 4 + src/mainboard/system76/meer9/Makefile.mk | 13 ++ .../system76/meer9/acpi/mainboard.asl | 7 + src/mainboard/system76/meer9/acpi/s76.asl | 113 +++++++++ src/mainboard/system76/meer9/acpi/sio.asl | 49 ++++ src/mainboard/system76/meer9/acpi/sleep.asl | 11 + src/mainboard/system76/meer9/board_info.txt | 6 + src/mainboard/system76/meer9/bootblock.c | 186 +++++++++++++++ src/mainboard/system76/meer9/cmos.default | 6 + src/mainboard/system76/meer9/cmos.layout | 51 +++++ src/mainboard/system76/meer9/devicetree.cb | 56 +++++ src/mainboard/system76/meer9/dsdt.asl | 36 +++ .../system76/meer9/include/mainboard/gpio.h | 9 + src/mainboard/system76/meer9/ramstage.c | 19 ++ .../system76/meer9/variants/meer9/board.fmd | 12 + .../meer9/variants/meer9/board_info.txt | 2 + .../system76/meer9/variants/meer9/data.vbt | Bin 0 -> 7680 bytes .../system76/meer9/variants/meer9/gpio.c | 216 ++++++++++++++++++ .../meer9/variants/meer9/gpio_early.c | 14 ++ .../system76/meer9/variants/meer9/hda_verb.c | 34 +++ .../meer9/variants/meer9/overridetree.cb | 102 +++++++++ .../system76/meer9/variants/meer9/ramstage.c | 18 ++ .../system76/meer9/variants/meer9/romstage.c | 25 ++ 24 files changed, 1072 insertions(+) create mode 100644 src/mainboard/system76/meer9/Kconfig create mode 100644 src/mainboard/system76/meer9/Kconfig.name create mode 100644 src/mainboard/system76/meer9/Makefile.mk create mode 100644 src/mainboard/system76/meer9/acpi/mainboard.asl create mode 100644 src/mainboard/system76/meer9/acpi/s76.asl create mode 100644 src/mainboard/system76/meer9/acpi/sio.asl create mode 100644 src/mainboard/system76/meer9/acpi/sleep.asl create mode 100644 src/mainboard/system76/meer9/board_info.txt create mode 100644 src/mainboard/system76/meer9/bootblock.c create mode 100644 src/mainboard/system76/meer9/cmos.default create mode 100644 src/mainboard/system76/meer9/cmos.layout create mode 100644 src/mainboard/system76/meer9/devicetree.cb create mode 100644 src/mainboard/system76/meer9/dsdt.asl create mode 100644 src/mainboard/system76/meer9/include/mainboard/gpio.h create mode 100644 src/mainboard/system76/meer9/ramstage.c create mode 100644 src/mainboard/system76/meer9/variants/meer9/board.fmd create mode 100644 src/mainboard/system76/meer9/variants/meer9/board_info.txt create mode 100644 src/mainboard/system76/meer9/variants/meer9/data.vbt create mode 100644 src/mainboard/system76/meer9/variants/meer9/gpio.c create mode 100644 src/mainboard/system76/meer9/variants/meer9/gpio_early.c create mode 100644 src/mainboard/system76/meer9/variants/meer9/hda_verb.c create mode 100644 src/mainboard/system76/meer9/variants/meer9/overridetree.cb create mode 100644 src/mainboard/system76/meer9/variants/meer9/ramstage.c create mode 100644 src/mainboard/system76/meer9/variants/meer9/romstage.c diff --git a/src/mainboard/system76/meer9/Kconfig b/src/mainboard/system76/meer9/Kconfig new file mode 100644 index 0000000000..3c7cb97593 --- /dev/null +++ b/src/mainboard/system76/meer9/Kconfig @@ -0,0 +1,83 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_SYSTEM76_MEER9_COMMON + def_bool n + select BOARD_ROMSIZE_KB_32768 + select CRB_TPM + select DRIVERS_GENERIC_CBFS_SERIAL + select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_UART_8250IO + select HAVE_ACPI_RESUME + select HAVE_ACPI_TABLES + select HAVE_CMOS_DEFAULT + select HAVE_INTEL_PTT + select HAVE_OPTION_TABLE + select INTEL_GMA_HAVE_VBT + select MAINBOARD_HAS_TPM2 + select NO_UART_ON_SUPERIO + select PCIEXP_SUPPORT_RESIZABLE_BARS + select SOC_INTEL_COMMON_BLOCK_HDA_VERB + select SOC_INTEL_CRASHLOG + select SOC_INTEL_METEORLAKE + select SPD_READ_BY_WORD + +config BOARD_SYSTEM76_MEER9 + select BOARD_SYSTEM76_MEER9_COMMON + select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES + select SOC_INTEL_METEORLAKE_U_H + +if BOARD_SYSTEM76_MEER9_COMMON + +config MAINBOARD_DIR + default "system76/meer9" + +config VARIANT_DIR + default "meer9" if BOARD_SYSTEM76_MEER9 + +config OVERRIDE_DEVICETREE + default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" + +config MAINBOARD_PART_NUMBER + default "meer9" if BOARD_SYSTEM76_MEER9 + +config MAINBOARD_SMBIOS_PRODUCT_NAME + default "Meerkat" if BOARD_SYSTEM76_MEER9 + +config MAINBOARD_VERSION + default "meer9" if BOARD_SYSTEM76_MEER9 + +config CMOS_DEFAULT_FILE + default "src/mainboard/\$(MAINBOARDDIR)/cmos.default" + +config CONSOLE_POST + default y + +config D3COLD_SUPPORT + default n + +config DIMM_SPD_SIZE + default 1024 + +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" + +config ONBOARD_VGA_IS_PRIMARY + default y + +config PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS + default 36 + +config POST_DEVICE + default n + +config TPM_MEASURED_BOOT + default y + +config UART_FOR_CONSOLE + default 0 + +# PM Timer Disabled, saves power +config USE_PM_ACPI_TIMER + default n + +endif diff --git a/src/mainboard/system76/meer9/Kconfig.name b/src/mainboard/system76/meer9/Kconfig.name new file mode 100644 index 0000000000..516503db02 --- /dev/null +++ b/src/mainboard/system76/meer9/Kconfig.name @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_SYSTEM76_MEER9 + bool "meer9" diff --git a/src/mainboard/system76/meer9/Makefile.mk b/src/mainboard/system76/meer9/Makefile.mk new file mode 100644 index 0000000000..d687753afa --- /dev/null +++ b/src/mainboard/system76/meer9/Makefile.mk @@ -0,0 +1,13 @@ +## SPDX-License-Identifier: GPL-2.0-only + +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include + +bootblock-y += bootblock.c +bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c + +romstage-y += variants/$(VARIANT_DIR)/romstage.c + +ramstage-y += ramstage.c +ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c +ramstage-y += variants/$(VARIANT_DIR)/gpio.c +ramstage-y += variants/$(VARIANT_DIR)/ramstage.c diff --git a/src/mainboard/system76/meer9/acpi/mainboard.asl b/src/mainboard/system76/meer9/acpi/mainboard.asl new file mode 100644 index 0000000000..99e94438ac --- /dev/null +++ b/src/mainboard/system76/meer9/acpi/mainboard.asl @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Scope (\_SB) { + #include "sio.asl" + #include "sleep.asl" + #include "s76.asl" +} diff --git a/src/mainboard/system76/meer9/acpi/s76.asl b/src/mainboard/system76/meer9/acpi/s76.asl new file mode 100644 index 0000000000..12f4ed9f1f --- /dev/null +++ b/src/mainboard/system76/meer9/acpi/s76.asl @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +// Notifications: +// 0x80 - hardware backlight toggle +// 0x81 - backlight toggle +// 0x82 - backlight down +// 0x83 - backlight up +// 0x84 - backlight color change +// 0x85 - OLED screen toggle +Device (S76D) { + Name (_HID, "17761776") + Name (_UID, 0) + // Hide the device so that Windows does not warn about a missing driver. + Name (_STA, 0xB) + + OperationRegion (HMIO, SystemIO, 0x295, 0x02) + Field (HMIO, ByteAcc, NoLock, Preserve) { + // Hardware manager index + HMID, 8, + // Hardware manager data + HMDT, 8, + } + + Method (INIT, 0, Serialized) { + Printf ("S76D: INIT") + Return (0) + } + + Method (FINI, 0, Serialized) { + Printf ("S76D: FINI") + Return (0) + } + + // Get Airplane LED + Method (GAPL, 0, Serialized) { + Return (0) + } + + // Set Airplane LED + Method (SAPL, 1, Serialized) {} + + // Get Keyboard Backlight Kind + // 0 - No backlight + // 1 - White backlight + // 2 - RGB backlight + Method (GKBK, 0, Serialized) { + Return (0) + } + + // Get Keyboard Brightness + Method (GKBB, 0, Serialized) { + Return (0) + } + + // Set Keyboard Brightness + Method (SKBB, 1, Serialized) {} + + // Get Keyboard Color + Method (GKBC, 0, Serialized) { + Return (0) + } + + // Set Keyboard Color + Method (SKBC, 1, Serialized) {} + + // Fan names + Method (NFAN, 0, Serialized) { + Return (Package() { + "CPU fan" + }) + } + + // Get fan duty cycle and RPM as a single value + Method (GFAN, 1, Serialized) { + // Set bank 0 + HMID = 0x4E + HMDT = 0x80 + + // Read fan duty cycle + HMID = 0x4B + Local0 = HMDT + + // Read fan RPM (low) + HMID = 0x33 + Local1 = HMDT + + // Read fan RPM (high) + HMID = 0x32 + Local2 = HMDT + + Return ((Local2 << 16) | (Local1 << 8) | Local0) + } + + // Temperature names + Method (NTMP, 0, Serialized) { + Return (Package() { + "CPU temp" + }) + } + + // Get temperature + Method (GTMP, 1, Serialized) { + // Set bank 0 + HMID = 0x4E + HMDT = 0x80 + + // Read temperature + HMID = 0x19 + Local0 = HMDT + + Return (Local0) + } +} diff --git a/src/mainboard/system76/meer9/acpi/sio.asl b/src/mainboard/system76/meer9/acpi/sio.asl new file mode 100644 index 0000000000..4f91a83712 --- /dev/null +++ b/src/mainboard/system76/meer9/acpi/sio.asl @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (SIO) { + Name (_ADR, 0x2E) + OperationRegion (SIOA, SystemIO, 0x2E, 0x02) + Field (SIOA, ByteAcc, NoLock, Preserve) + { + SI2E, 8, + SI2F, 8, + } + IndexField (SI2E, SI2F, ByteAcc, NoLock, Preserve) + { + Offset (0x07), + SLDN, 8, /* Logical Device Number */ + Offset(0xE5), + SRE5, 8, /* Register 0xE5 */ + } + + Method (ENTR, 0, Serialized) { + // Enter config mode + SI2E = 0x87 + SI2E = 0x87 + } + + Method (EXIT, 0, Serialized) { + // Exit config mode + SI2E = 0xAA + } + + Method (PTS, 0, Serialized) { + ENTR() + + // Turn on fading LED + SLDN = 0x15 + SRE5 = 0x43 + + EXIT() + } + + Method (WAK, 0, Serialized) { + ENTR() + + // Turn off fading LED + SLDN = 0x15 + SRE5 = 0x42 + + EXIT() + } +} diff --git a/src/mainboard/system76/meer9/acpi/sleep.asl b/src/mainboard/system76/meer9/acpi/sleep.asl new file mode 100644 index 0000000000..0212e7aeeb --- /dev/null +++ b/src/mainboard/system76/meer9/acpi/sleep.asl @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Method called from _PTS prior to enter sleep state */ +Method (MPTS, 1) { + \_SB.SIO.PTS() +} + +/* Method called from _WAK prior to wakeup */ +Method (MWAK, 1) { + \_SB.SIO.WAK() +} diff --git a/src/mainboard/system76/meer9/board_info.txt b/src/mainboard/system76/meer9/board_info.txt new file mode 100644 index 0000000000..7d87752e22 --- /dev/null +++ b/src/mainboard/system76/meer9/board_info.txt @@ -0,0 +1,6 @@ +Vendor name: System76 +Category: desktop +ROM package: WSON-8 +ROM protocol: SPI +ROM socketed: y +Flashrom support: y diff --git a/src/mainboard/system76/meer9/bootblock.c b/src/mainboard/system76/meer9/bootblock.c new file mode 100644 index 0000000000..86b980bdde --- /dev/null +++ b/src/mainboard/system76/meer9/bootblock.c @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +// nuvoton_pnp_enter_conf_state +static void pnp_enter_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(0x87, port); + outb(0x87, port); +} + +// nuvoton_pnp_exit_conf_state +static void pnp_exit_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(0xaa, port); +} + +static void superio_init(void) +{ + //TODO: use superio driver? + pnp_devfn_t dev = PNP_DEV(0x2E, 0x00); + + printk(BIOS_DEBUG, "entering PNP config mode\n"); + pnp_enter_conf_state(dev); + + printk(BIOS_DEBUG, "configure global PNP\n"); + //TODO: document these + pnp_write_config(dev, 0x1A, 0x88); // Default is 0x03 + pnp_write_config(dev, 0x1B, 0x00); // Default is 0x03 + pnp_write_config(dev, 0x1D, 0x08); // Default is 0x00 + pnp_write_config(dev, 0x2C, 0x03); // Default is 0x0F + pnp_write_config(dev, 0x2F, 0xE4); // Default is 0x74 + + printk(BIOS_DEBUG, "configure GPIO (logical device 7)\n"); + dev = PNP_DEV(0x2E, 0x07); + pnp_set_logical_device(dev); + // Enable GPIO 0, 5, and 6 + pnp_write_config(dev, 0x30, 0x61); // Default is 0x00 + // Set GPIO 00-06 as output, 07 as input + pnp_write_config(dev, 0xE0, 0x80); // Default is 0xFF + // Set GPIO 00-02 and 04-05 high + pnp_write_config(dev, 0xE1, 0x37); // Default is 0x00 + // Set GPIO 53-54 as output, 50-52 and 55-57 as input + pnp_write_config(dev, 0xF8, 0xE7); // Default is 0xFF + // Set GPIO 53-53 high + pnp_write_config(dev, 0xF9, 0x18); // Default is 0x00 + + printk(BIOS_DEBUG, "configure GPIO (logical device 8)\n"); + dev = PNP_DEV(0x2E, 0x08); + pnp_set_logical_device(dev); + // Disable WDT1 + pnp_write_config(dev, 0x30, 0x00); // Default is 0x01 + // GPIO0 multi-function select, set GPIO0 as SUSLED + pnp_write_config(dev, 0xE0, 0x01); // Default is 0x00 + pnp_write_config(dev, 0xE9, 0x00); // Default is 0xFF TODO? + pnp_write_config(dev, 0xEA, 0x00); // Default is 0xFF TODO? + + printk(BIOS_DEBUG, "configure GPIO (logical device 9)\n"); + dev = PNP_DEV(0x2E, 0x09); + pnp_set_logical_device(dev); + // Enable GPIO 8 and 9 + pnp_write_config(dev, 0x30, 0x03); // Default is 0x00 + // GPIO 80-86 set as input, 87 as output + pnp_write_config(dev, 0xF0, 0x7F); // Default is 0xFF + // GPIO 87 set high + pnp_write_config(dev, 0xF1, 0x80); // Default is 0xFF + + printk(BIOS_DEBUG, "configure ACPI (logical device A)\n"); + dev = PNP_DEV(0x2E, 0x0A); + pnp_set_logical_device(dev); + // User-defined resume state after power loss + pnp_write_config(dev, 0xE4, 0x60); // Default is 0x00 + + printk(BIOS_DEBUG, "configure hardware monitor (logical device B)\n"); + dev = PNP_DEV(0x2E, 0x0B); + pnp_set_logical_device(dev); + // Enable hardware monitor + pnp_write_config(dev, 0x30, 0x01); // Default is 0x00 + // Set address base to 0x290 + pnp_write_config(dev, 0x60, 0x02); + pnp_write_config(dev, 0x61, 0x90); + + printk(BIOS_DEBUG, "configure GPIO (logical device F)\n"); + dev = PNP_DEV(0x2E, 0x0F); + pnp_set_logical_device(dev); + // Set GPIO 00, 01, and 07 as open drain, and 2-6 as push-pull + pnp_write_config(dev, 0xE0, 0x83); // Default is 0xFF + // Set GPIO 52-57 as open drain, and 50-51 as push-pull + pnp_write_config(dev, 0xE5, 0xFC); // Default is 0xFF + // Set GPIO 60-62 and 65-67 as open drain, and 63-64 as push-pull + pnp_write_config(dev, 0xE6, 0xE7); // Default is 0xFF + // Set GPIO 80-86 as open drain, and 87 as push-pull + pnp_write_config(dev, 0xE8, 0x7F); // Default is 0xFF + + printk(BIOS_DEBUG, "configure fading LED (logical device 15)\n"); + dev = PNP_DEV(0x2E, 0x15); + pnp_set_logical_device(dev); + // Configure fading LED (divide by 4, frequency 1 Khz, off) + pnp_write_config(dev, 0xE5, 0x42); + + printk(BIOS_DEBUG, "configure deep sleep (logical device 16)\n"); + dev = PNP_DEV(0x2E, 0x16); + pnp_set_logical_device(dev); + // Set deep sleep delay time to 0s + pnp_write_config(dev, 0xE2, 0x00); + + printk(BIOS_DEBUG, "exiting PNP config mode\n"); + pnp_exit_conf_state(dev); +} + +static void hm_write(uint8_t reg, uint8_t value) +{ + outb(reg, 0x295); + outb(value, 0x296); +} + +static void hm_init(void) +{ + // Bank 2 + hm_write(0x4E, 0x82); + + // Enable PECI 3.0 with routine function + hm_write(0x00, 0x85); + + // Enable PECI agent 30 + hm_write(0x02, 0x10); + + // PECI Tbase0 = 110C + hm_write(0x04, 110); + + // Bank 3 + hm_write(0x4E, 0x83); + + // Enable PECI agent 0 mode + hm_write(0x90, 0x01); + + // Bank 1 + hm_write(0x4E, 0x81); + + // CPUFAN T1 = 50C + hm_write(0x70, 50); + // CPUFAN FD1 = 25% = 0x3F + hm_write(0x74, 0x3F); + + // CPUFAN T2 = 75C + hm_write(0x71, 75); + // CPUFAN FD2 = 50% = 0x7F + hm_write(0x75, 0x7F); + + // CPUFAN T3 = 90C + hm_write(0x72, 90); + // CPUFAN FD3 = 75% = 0xBF + hm_write(0x76, 0xBF); + + // CPUFAN T4 = 99C + hm_write(0x73, 99); + // CPUFAN FD4 = 100% = 0xFF + hm_write(0x77, 0xFF); + + // CPUFAN critical temperature = 105C + hm_write(0x2A, 105); + // By default critical duty is 0xFF + + // CPUFAN step up time = 1s + hm_write(0x24, 10); + + // CPUFAN step down time = 0.5s + hm_write(0x25, 5); + + // Use PECI agent 0 as CPUFAN monitoring source + hm_write(0x20, 0x0C); + + // CPUFAN Smart Fan IV mode + hm_write(0x23, 0x40); +} + +void bootblock_mainboard_early_init(void) +{ + mainboard_configure_early_gpios(); + superio_init(); + hm_init(); +} diff --git a/src/mainboard/system76/meer9/cmos.default b/src/mainboard/system76/meer9/cmos.default new file mode 100644 index 0000000000..d2ca53be53 --- /dev/null +++ b/src/mainboard/system76/meer9/cmos.default @@ -0,0 +1,6 @@ +## SPDX-License-Identifier: GPL-2.0-only + +boot_option=Fallback +debug_level=Debug +me_state=Enable +power_on_after_fail=Disable diff --git a/src/mainboard/system76/meer9/cmos.layout b/src/mainboard/system76/meer9/cmos.layout new file mode 100644 index 0000000000..6414d665b6 --- /dev/null +++ b/src/mainboard/system76/meer9/cmos.layout @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: GPL-2.0-only + +entries + +0 384 r 0 reserved_memory + +# RTC_BOOT_BYTE (coreboot hardcoded) +384 1 e 4 boot_option +388 4 h 0 reboot_counter + +# RTC_CLK_ALTCENTURY +400 8 r 0 century + +409 2 e 7 power_on_after_fail +412 4 e 6 debug_level +416 1 e 2 me_state +417 3 h 0 me_state_counter + +# CMOS_VSTART_ramtop +800 80 r 0 ramtop + +984 16 h 0 check_sum + +enumerations + +1 0 Disable +1 1 Enable + +2 0 Enable +2 1 Disable + +4 0 Fallback +4 1 Normal + +6 0 Emergency +6 1 Alert +6 2 Critical +6 3 Error +6 4 Warning +6 5 Notice +6 6 Info +6 7 Debug +6 8 Spew + +7 0 Disable +7 1 Enable +7 2 Keep + +checksums + +checksum 408 799 984 diff --git a/src/mainboard/system76/meer9/devicetree.cb b/src/mainboard/system76/meer9/devicetree.cb new file mode 100644 index 0000000000..b664ef9763 --- /dev/null +++ b/src/mainboard/system76/meer9/devicetree.cb @@ -0,0 +1,56 @@ +chip soc/intel/meteorlake + # Enable Enhanced Intel SpeedStep + register "eist_enable" = "1" + + # Thermal + register "tcc_offset" = "11" # 110C - 11C = 99C + + device cpu_cluster 0 on end + + register "power_limits_config[MTL_P_682_482_CORE]" = "{ + .tdp_pl1_override = 40, + .tdp_pl2_override = 64, + .tdp_pl4 = 120, + }" + + device domain 0 on + device ref system_agent on end + device ref igpu on + # DDIA is HDMI1, DDIB is HDMI2 + register "ddi_ports_config" = "{ + [DDI_PORT_A] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_B] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + }" + end + device ref vpu on end + device ref ioe_shared_sram on end + device ref pmc_shared_sram on end + device ref cnvi_wifi on + register "cnvi_bt_core" = "true" + register "cnvi_bt_audio_offload" = "true" + chip drivers/wifi/generic + register "wake" = "GPE0_PME_B0" + device generic 0 on end + end + end + + device ref heci1 on end + device ref soc_espi on + register "gen1_dec" = "0x007c0281" # Port 0x280 to 0x2FF (hardware monitor) + register "gen2_dec" = "0x000c0081" # Port 0x80 to 0x8F (debug) + end + device ref p2sb on end + device ref hda on + register "pch_hda_sdi_enable[0]" = "1" + register "pch_hda_audio_link_hda_enable" = "1" + register "pch_hda_idisp_codec_enable" = "1" + register "pch_hda_idisp_link_frequency" = "HDA_LINKFREQ_96MHZ" + register "pch_hda_idisp_link_tmode" = "HDA_TMODE_8T" + end + device ref smbus on end + device ref fast_spi on end + end + chip drivers/crb + device mmio 0xfed40000 on end + end +end diff --git a/src/mainboard/system76/meer9/dsdt.asl b/src/mainboard/system76/meer9/dsdt.asl new file mode 100644 index 0000000000..cf8d58d434 --- /dev/null +++ b/src/mainboard/system76/meer9/dsdt.asl @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +//TODO: HACK FOR MISSING MISCCFG_GPIO_PM_CONFIG_BITS +#include + +#include +DefinitionBlock( + "dsdt.aml", + "DSDT", + ACPI_DSDT_REV_2, + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20110725 +) +{ + #include + #include + #include + #include + + Device (\_SB.PCI0) + { + #include + #include + #include + } + + #include + + Scope (\_SB.PCI0.LPCB) + { + #include + } + + #include "acpi/mainboard.asl" +} diff --git a/src/mainboard/system76/meer9/include/mainboard/gpio.h b/src/mainboard/system76/meer9/include/mainboard/gpio.h new file mode 100644 index 0000000000..c6393beebb --- /dev/null +++ b/src/mainboard/system76/meer9/include/mainboard/gpio.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef MAINBOARD_GPIO_H +#define MAINBOARD_GPIO_H + +void mainboard_configure_early_gpios(void); +void mainboard_configure_gpios(void); + +#endif diff --git a/src/mainboard/system76/meer9/ramstage.c b/src/mainboard/system76/meer9/ramstage.c new file mode 100644 index 0000000000..c6fca5fcd4 --- /dev/null +++ b/src/mainboard/system76/meer9/ramstage.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +static void mainboard_init(void *chip_info) +{ + mainboard_configure_gpios(); + + // The DACC feature resets CMOS and causes a system reset if the + // firmware does not send this message within 10 seconds of power on. + printk(BIOS_DEBUG, "Handling DACC\n"); + do_smbus_write_byte(CONFIG_FIXED_SMBUS_IO_BASE, 0xBA >> 1, 0x0F, 0xAA); +} + +struct chip_operations mainboard_ops = { + .init = mainboard_init, +}; diff --git a/src/mainboard/system76/meer9/variants/meer9/board.fmd b/src/mainboard/system76/meer9/variants/meer9/board.fmd new file mode 100644 index 0000000000..4713b67297 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/board.fmd @@ -0,0 +1,12 @@ +FLASH 32M { + SI_DESC 16K + SI_ME 10160K + SI_BIOS@16M 16M { + RW_MRC_CACHE 64K + SMMSTORE(PRESERVE) 256K + WP_RO { + FMAP 4K + COREBOOT(CBFS) + } + } +} diff --git a/src/mainboard/system76/meer9/variants/meer9/board_info.txt b/src/mainboard/system76/meer9/variants/meer9/board_info.txt new file mode 100644 index 0000000000..dcb8a8bd1f --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/board_info.txt @@ -0,0 +1,2 @@ +Board name: meer9 +Release year: 2024 diff --git a/src/mainboard/system76/meer9/variants/meer9/data.vbt b/src/mainboard/system76/meer9/variants/meer9/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..93276b46fac7ede5838a977d7b096ba509227f02 GIT binary patch literal 7680 zcmeHML2MI86#cX7-5A$t3`xO+kWLd6oRlPM2htE(Vr?e@LxSxjL`JO?6YN4%L);Lm zP*q}EQYlhZX-{oHNVt_MRp}*{o_eScs7l4fqEg#KE9F*%da240>i(Hs+c*$nN@)r5 zxBkrE`G4O0|7Uh~cD-xNKT3!CNBcv=gT5pElu;ZMIN0zZmJgCY7#bPx^Nsq({ez*v z5qb}{!q$erZUe*#*=~0$iaU6ACXsXvx6+}hiOFQ5voCS(t(mD54F`hMck*N+nV3E? zlZexiv4cL!@TzV8^OMOqJ$nAkL}I#^B8Y<4)V;T(YcHjq*E*H1PLJZ=hnik@ckjOa z)waI=Kxil&9Q2I_Lq}<7nDzxnd?O?ML;k_zG&~$S6!Zs2`}?YGB_RZ+QWvHtPo18j zu0SjG;5h9Zm%B^@Q`4yq>Psf+Fta&FhZE-#)9)nW9o04llmV-S01zA0WB>(5_x#`h z3#iBx*?|&8c3{cc0cAiL@M>)mJ|Y6z?zXNn!7)W_%5c!Uj)ImK&AQ5{Gkny%j(Kx4 z1`Y?D+EEyrpf-aMP$rn9nr4?wGgJwv%B(V@@ZD*KcFi=aHo9Mjn2E+bWnmg--FwH__}*)2!~{W_&Wxtfrw5DKjjh8NL~v*Dde9iza4* z2oOd9FA?>DjyJ^R2ijhjY>+^nLcV}}3Hf8>Pmw=E{tEePpR4OwN$eka=9NjX*ylm>9EF{jNXmi7jf@rvYm=iVSR*j4Fz|!fx0yF zA%zHhA4deXH?5Bl-wvt|S`_Dex8Z}c`=ZDX0Ei%gg&}zHNw#(rN*gRhKv9)ct$~0( zU`Hm~XQleG5N2tl-l00~Lm;~J7zkf>&aOo2Th!=6(FdZ-96^tCfilH90a9JU5?Gg z6=#I60q%o{i-{rp!!?Ofh``T&xF%^CQQWSFbeL{a>`H)*Yxtn!{fItjRXuz?utmQ1 zsup@R=i5E)YP7vL7b5V3r5&swuYX^(su0tlHs)|_X5*T9;Achq;6QjheBx{(dGy4Y z#B*?A1o(8zT<%pjkq<9}99?{RB|E3yPl6z9K`szGwmu27J?Tlxd3W50oZ4A-yJs;wKUU%_r-Ed-WH*Q5b z?hJgB%qP{XbGZY2CfIh&yv&*}-fVNNx%l#dI-FQG!E2G%3s%o$%Ro1Q=E<`je0dyq zdBKC`{1p@H%E-msRkHo>udqAB_|4ZozEqr)5LKFq(MLk4|PuL4jJhzm4`qAfAr__^-ZJv6YW z#0m5G1*8REv}7KIhULl^_J%|-5nw@CM}Wy(9xGh)ERH38jkmKmVhp&@h>Nen2iNLGpN&# z3!qgQx+P09Ms9q%W;#onKw8R@FkFT?u?aDaGa1vd_*8iroDe}>oLM8oBlD6${jO@3 zmoy#$(Hn6a_A2J3u8;ZR#Ms-R$I@Qn=au(yPOSKs3;sZ^MPK;$BR<}v=I?pXVcIIR H5i{^NsDO70 literal 0 HcmV?d00001 diff --git a/src/mainboard/system76/meer9/variants/meer9/gpio.c b/src/mainboard/system76/meer9/variants/meer9/gpio.c new file mode 100644 index 0000000000..c7fc1810b7 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/gpio.c @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config gpio_table[] = { + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A00, UP_20K, DEEP, NF1), // ESPI_IO0 + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A01, UP_20K, DEEP, NF1), // ESPI_IO1 + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A02, UP_20K, DEEP, NF1), // ESPI_IO2 + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A03, UP_20K, DEEP, NF1), // ESPI_IO3 + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A04, UP_20K, DEEP, NF1), // ESPI_CS0# + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A05, UP_20K, DEEP, NF1), // ESPI_CLK + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A06, NONE, DEEP, NF1), // ESPI_RESET# + PAD_NC(GPP_A07, NONE), + PAD_NC(GPP_A08, NONE), + PAD_NC(GPP_A09, NONE), + PAD_NC(GPP_A10, NONE), + PAD_CFG_GPI(GPP_A11, NONE, PLTRST), + PAD_CFG_GPI(GPP_A12, NONE, PLTRST), + PAD_CFG_GPI(GPP_A13, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_A14, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_A15, NONE, PLTRST), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A16, UP_20K, DEEP, NF1), // ESPI_ALERT0# + PAD_CFG_GPI(GPP_A17, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_A18, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_A19, UP_20K, DEEP), + PAD_CFG_GPI(GPP_A20, NATIVE, DEEP), + PAD_CFG_NF(GPP_A21, NATIVE, DEEP, NF1), // PMCALERT# + + PAD_CFG_GPI(GPP_B00, NONE, PLTRST), + PAD_CFG_GPI(GPP_B01, NONE, PLTRST), + PAD_CFG_GPI(GPP_B02, NONE, PLTRST), + PAD_CFG_GPI(GPP_B03, NONE, PLTRST), + PAD_CFG_GPI(GPP_B04, NONE, PLTRST), + PAD_CFG_GPI(GPP_B05, NONE, PLTRST), + PAD_CFG_GPI(GPP_B06, NONE, PLTRST), + PAD_CFG_GPI(GPP_B07, NONE, PLTRST), + PAD_CFG_GPO(GPP_B08, 1, PLTRST), + PAD_CFG_GPI(GPP_B09, NONE, PLTRST), + PAD_CFG_GPI(GPP_B10, NONE, PLTRST), + PAD_CFG_GPI(GPP_B11, NONE, PLTRST), + PAD_CFG_GPI(GPP_B12, NONE, PLTRST), + PAD_CFG_NF(GPP_B13, NONE, PLTRST, NF1), // PLTRST# + PAD_CFG_GPI(GPP_B14, NONE, PLTRST), + PAD_CFG_GPI(GPP_B15, NONE, PLTRST), + PAD_CFG_NF(GPP_B16, NONE, PLTRST, NF2), // HDMI_HPD2 + PAD_CFG_GPI(GPP_B17, NONE, PLTRST), + PAD_CFG_GPO(GPP_B18, 1, PLTRST), + PAD_CFG_GPO(GPP_B19, 1, PLTRST), + PAD_CFG_GPI(GPP_B20, NONE, PLTRST), + PAD_CFG_GPI(GPP_B21, NONE, PLTRST), + PAD_CFG_GPI(GPP_B22, NONE, PLTRST), + PAD_CFG_GPI(GPP_B23, NONE, PLTRST), + + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C00, NONE, DEEP, NF1), // SMBCLK + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C01, NONE, DEEP, NF1), // SMBDATA + PAD_CFG_NF(GPP_C02, NONE, DEEP, NF1), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C03, NONE, DEEP, NF1), // SML0CLK + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C04, NONE, DEEP, NF1), // SML0DATA + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C05, UP_20K, DEEP, NF1), // SM0ALERT# + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C06, NONE, DEEP, NF1), // SML1CLK + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C07, NONE, DEEP, NF1), // SML1DATA + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C08, NONE, DEEP, NF1), // SML1ALERT# + PAD_CFG_NF(GPP_C09, NONE, PLTRST, NF1), + PAD_CFG_NF(GPP_C10, NONE, DEEP, NF1), // SRCCLKREQ1# + PAD_CFG_NF(GPP_C11, NONE, DEEP, NF1), // SRCCLKREQ2# + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), // SRCCLKREQ3# + PAD_CFG_GPI(GPP_C13, NONE, PLTRST), + PAD_NC(GPP_C14, NONE), + PAD_CFG_NF(GPP_C15, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), // TBT_LSX0_TXD + PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), // TBT_LSX0_RXD + PAD_NC(GPP_C18, NONE), + PAD_NC(GPP_C19, NONE), + PAD_CFG_GPI(GPP_C20, NONE, PLTRST), + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_C22, NONE, DEEP, NF1), + PAD_CFG_GPI(GPP_C23, NONE, PLTRST), + + PAD_CFG_GPO(GPP_D00, 0, PWROK), + PAD_CFG_GPI(GPP_D01, NONE, PLTRST), + PAD_CFG_GPI(GPP_D02, NONE, PLTRST), + PAD_CFG_GPI(GPP_D03, NONE, PLTRST), + PAD_CFG_GPO(GPP_D04, 1, PWROK), + PAD_CFG_GPO(GPP_D05, 1, PLTRST), + PAD_CFG_GPO(GPP_D06, 1, PLTRST), + PAD_CFG_GPO(GPP_D07, 1, PLTRST), + PAD_CFG_GPO(GPP_D08, 1, PLTRST), + PAD_CFG_GPO(GPP_D09, 0, PWROK), // ME_OVERRIDE + PAD_CFG_NF(GPP_D10, NONE, PLTRST, NF1), // HDA_BCLK + PAD_CFG_NF(GPP_D11, NATIVE, PLTRST, NF1), // HDA_SYNC + PAD_CFG_NF(GPP_D12, NATIVE, PLTRST, NF1), // HDA_SDO + PAD_CFG_NF(GPP_D13, NATIVE, PLTRST, NF1), // HDA_SDI0 + PAD_CFG_GPI(GPP_D14, NONE, PLTRST), + PAD_CFG_GPI(GPP_D15, NONE, PLTRST), + PAD_CFG_GPI(GPP_D16, NONE, PLTRST), + PAD_CFG_NF(GPP_D17, NONE, PLTRST, NF1), // HDA_RST# + PAD_CFG_NF(GPP_D18, NONE, DEEP, NF1), // SRCCLKREQ6# + PAD_NC(GPP_D19, NONE), + PAD_CFG_NF(GPP_D20, NONE, DEEP, NF1), // SRCCLKREQ8# + PAD_CFG_NF(GPP_D21, NONE, DEEP, NF1), + PAD_CFG_GPI(GPP_D22, NATIVE, PLTRST), + PAD_CFG_GPI(GPP_D23, NATIVE, PLTRST), + + PAD_CFG_GPI(GPP_E00, NONE, PLTRST), + PAD_CFG_GPI(GPP_E01, NONE, PLTRST), + PAD_CFG_GPI(GPP_E02, NONE, PLTRST), + PAD_CFG_GPI(GPP_E03, NONE, PLTRST), + PAD_CFG_GPO(GPP_E04, 0, PLTRST), + PAD_CFG_GPO(GPP_E05, 1, PLTRST), + PAD_CFG_GPI(GPP_E06, NONE, PLTRST), + PAD_CFG_GPI(GPP_E07, NONE, PLTRST), + PAD_CFG_NF(GPP_E08, NONE, PLTRST, NF1), // DDPA_CTRLDATA + PAD_CFG_GPI(GPP_E09, NONE, PLTRST), + PAD_CFG_GPI(GPP_E10, NONE, PLTRST), + PAD_CFG_GPI(GPP_E11, NONE, PLTRST), + PAD_CFG_GPI(GPP_E12, NONE, PLTRST), + PAD_CFG_GPI(GPP_E13, NONE, PLTRST), + PAD_CFG_NF(GPP_E14, NONE, PLTRST, NF1), // HDMI_HPD + PAD_CFG_GPI(GPP_E15, NONE, PLTRST), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_E16, NONE, PLTRST, NF2), // VRALERT# + PAD_CFG_GPI(GPP_E17, NONE, PLTRST), + PAD_NC(GPP_E18, NONE), + PAD_NC(GPP_E19, NONE), + PAD_NC(GPP_E20, NONE), + PAD_NC(GPP_E21, NONE), + PAD_CFG_NF(GPP_E22, DN_20K, PLTRST, NF1), // DDPA_CTRLCLK + + PAD_CFG_NF(GPP_F00, NONE, PLTRST, NF1), // CNV_BRI_DT + PAD_CFG_NF(GPP_F01, UP_20K, PLTRST, NF1), // CNV_BRI_RSP + PAD_CFG_NF(GPP_F02, NONE, PLTRST, NF1), // CNV_BRI_RSP + PAD_CFG_NF(GPP_F03, UP_20K, PLTRST, NF1), // CNV_RGI_DT + PAD_CFG_NF(GPP_F04, NONE, PLTRST, NF1), // CNV_RGI_RSP + PAD_CFG_NF(GPP_F05, NONE, PLTRST, NF3), // CNV_RF_RESET# + PAD_CFG_NF(GPP_F06, NONE, PLTRST, NF1), // MODEM_CLKREQ + PAD_CFG_TERM_GPO(GPP_F07, 1, DN_20K, PWROK), // CNV_PA_BLANKING + PAD_CFG_GPI(GPP_F08, DN_20K, PLTRST), + PAD_CFG_GPI(GPP_F09, NONE, PLTRST), + PAD_CFG_GPI(GPP_F10, NONE, PLTRST), + PAD_CFG_GPI(GPP_F11, NONE, PLTRST), + PAD_CFG_GPI(GPP_F12, NONE, PLTRST), + PAD_CFG_GPI(GPP_F13, NONE, PLTRST), + PAD_CFG_GPI(GPP_F14, NONE, PLTRST), + PAD_CFG_GPI(GPP_F15, NONE, PLTRST), + PAD_CFG_GPI(GPP_F16, NONE, PLTRST), + PAD_CFG_GPI(GPP_F17, NONE, PLTRST), + PAD_CFG_GPI(GPP_F18, NONE, PLTRST), + PAD_CFG_GPI(GPP_F19, NONE, PLTRST), + PAD_CFG_GPI(GPP_F20, NONE, PLTRST), + PAD_CFG_GPI(GPP_F21, NONE, PLTRST), + PAD_CFG_GPI(GPP_F22, NONE, PLTRST), + PAD_CFG_GPI(GPP_F23, NONE, PLTRST), + + PAD_CFG_GPI(GPP_H00, NONE, PLTRST), + PAD_CFG_GPI(GPP_H01, NONE, PLTRST), + PAD_CFG_GPI(GPP_H02, NONE, PLTRST), + PAD_NC(GPP_H03, NONE), + PAD_CFG_NF(GPP_H04, NONE, PLTRST, NF2), // CNV_MFUART2_RXD + PAD_CFG_NF(GPP_H05, NONE, PLTRST, NF2), // CNV_MFUART2_TXD + PAD_CFG_GPI(GPP_H06, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_H07, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_H08, NONE, PLTRST), + PAD_CFG_GPI(GPP_H09, NONE, PLTRST), + PAD_CFG_GPI(GPP_H10, NONE, PLTRST), + PAD_CFG_GPI(GPP_H11, NONE, PLTRST), + PAD_NC(GPP_H12, NONE), + PAD_CFG_GPI(GPP_H13, NONE, PLTRST), + PAD_CFG_GPI(GPP_H14, NONE, PLTRST), + PAD_CFG_GPO(GPP_H15, 1, PLTRST), + PAD_CFG_NF(GPP_H16, NONE, PLTRST, NF1), // DDPB_CTRLCLK + PAD_CFG_NF(GPP_H17, NONE, PLTRST, NF1), // DDPB_CTRLDATA + PAD_NC(GPP_H18, NONE), + PAD_CFG_NF(GPP_H19, NONE, PLTRST, NF1), // CCG6DF_I2C_SDA (PD) + PAD_CFG_NF(GPP_H20, NONE, PLTRST, NF1), // CCG6DF_I2C_SCL (PD) + PAD_CFG_GPO(GPP_H21, 1, PLTRST), + PAD_CFG_GPI(GPP_H22, NONE, PLTRST), + + PAD_CFG_GPI(GPP_S00, NONE, PLTRST), + PAD_CFG_GPI(GPP_S01, NONE, PLTRST), + PAD_CFG_GPI(GPP_S02, NONE, PLTRST), + PAD_CFG_GPI(GPP_S03, NONE, PLTRST), + PAD_CFG_GPI(GPP_S04, NONE, PLTRST), + PAD_CFG_GPI(GPP_S05, NONE, PLTRST), + PAD_CFG_GPI(GPP_S06, NONE, PLTRST), + PAD_CFG_GPI(GPP_S07, NONE, PLTRST), + + PAD_CFG_NF(GPP_V00, NONE, DEEP, NF1), // BATLOW# + PAD_CFG_NF(GPP_V01, NONE, DEEP, NF1), // ACPRESENT + PAD_CFG_NF(GPP_V02, NONE, DEEP, NF1), // SOC_WAKE# + PAD_CFG_NF(GPP_V03, NONE, DEEP, NF1), // PWRBTN# + PAD_CFG_NF(GPP_V04, NONE, DEEP, NF1), // SLP_S3# + PAD_CFG_NF(GPP_V05, UP_20K, PLTRST, NF1), // SLP_S4# + PAD_CFG_NF(GPP_V06, NATIVE, PLTRST, NF1), + PAD_CFG_NF(GPP_V07, NATIVE, PLTRST, NF1), + PAD_CFG_NF(GPP_V08, UP_20K, PLTRST, NF1), // SUSCLK + PAD_CFG_NF(GPP_V09, NONE, PLTRST, NF1), + PAD_CFG_NF(GPP_V10, NONE, PLTRST, NF1), + PAD_CFG_GPI(GPP_V11, NONE, PLTRST), + PAD_NC(GPP_V12, NONE), + PAD_CFG_NF(GPP_V13, NONE, PLTRST, NF1), + PAD_CFG_GPI(GPP_V14, NONE, PLTRST), // WAKE# + PAD_CFG_GPI(GPP_V15, NONE, PLTRST), + PAD_CFG_GPI(GPP_V16, NONE, PLTRST), + PAD_CFG_GPI(GPP_V17, NONE, PLTRST), + PAD_NC(GPP_V18, NONE), + PAD_CFG_NF(GPP_V19, NONE, PLTRST, NF1), + PAD_NC(GPP_V20, NONE), + PAD_NC(GPP_V21, NONE), + PAD_NC(GPP_V22, NONE), + PAD_NC(GPP_V23, NONE), +}; + +void mainboard_configure_gpios(void) +{ + gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); +} diff --git a/src/mainboard/system76/meer9/variants/meer9/gpio_early.c b/src/mainboard/system76/meer9/variants/meer9/gpio_early.c new file mode 100644 index 0000000000..b3cd0c9924 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/gpio_early.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config early_gpio_table[] = { + PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), // SMB_CLK + PAD_CFG_NF(GPP_C01, NONE, DEEP, NF1), // SMB_DATA +}; + +void mainboard_configure_early_gpios(void) +{ + gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table)); +} diff --git a/src/mainboard/system76/meer9/variants/meer9/hda_verb.c b/src/mainboard/system76/meer9/variants/meer9/hda_verb.c new file mode 100644 index 0000000000..c824b14261 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/hda_verb.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +const u32 cim_verb_data[] = { + /* Realtek, ALC256 */ + 0x10ec0256, /* Vendor ID */ + 0x18490256, /* Subsystem ID */ + 13, /* Number of entries */ + AZALIA_SUBVENDOR(0, 0x18490256), + AZALIA_RESET(1), + AZALIA_PIN_CFG(0, 0x12, 0x40000000), // DMIC + AZALIA_PIN_CFG(0, 0x13, AZALIA_PIN_CFG_NC(0)), // DMIC + AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_CFG_NC(0)), // Front (Port-D) + AZALIA_PIN_CFG(0, 0x18, AZALIA_PIN_CFG_NC(0)), // NPC + AZALIA_PIN_CFG(0, 0x19, 0x02a11020), // MIC2 (Port-F) + AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), // LINE1 (Port-C) + AZALIA_PIN_CFG(0, 0x1b, AZALIA_PIN_CFG_NC(0)), // LINE2 (Port-E) + AZALIA_PIN_CFG(0, 0x1d, 0x40400001), // BEEP-IN + AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), // S/PDIF-OUT + AZALIA_PIN_CFG(0, 0x21, 0x02211010), // HP1-OUT (Port-I) + + // Enable HP-JD + 0x0205001B, 0x02040A4B, 0x0205001B, 0x02040A4B, +}; + +const u32 pc_beep_verbs[] = { + // Dos beep path - 1 + 0x02170C00, 0x02050036, 0x02041151, 0x021707C0, + // Dos beep path - 2 + 0x0213B000, 0x02170C02, 0x02170C02, 0x02170C02, +}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/system76/meer9/variants/meer9/overridetree.cb b/src/mainboard/system76/meer9/variants/meer9/overridetree.cb new file mode 100644 index 0000000000..8807034adf --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/overridetree.cb @@ -0,0 +1,102 @@ +chip soc/intel/meteorlake + device domain 0 on + #TODO: all the devices have different subsystem product IDs + #subsystemid 0x1849 TODO inherit + + device ref tbt_pcie_rp0 on end + device ref tcss_xhci on + register "tcss_ports[0]" = "TCSS_PORT_DEFAULT(OC_SKIP)" # TBT + register "tcss_ports[1]" = "TCSS_PORT_DEFAULT(OC_SKIP)" # Type-C + register "tcss_ports[2]" = "TCSS_PORT_DEFAULT(OC_SKIP)" # USB3 Front + chip drivers/usb/acpi + device ref tcss_root_hub on + chip drivers/usb/acpi + register "desc" = ""TBT Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + device ref tcss_usb3_port0 on end + end + chip drivers/usb/acpi + register "desc" = ""USB Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + device ref tcss_usb3_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""USB Type-A"" + register "type" = "UPC_TYPE_USB3_A" + device ref tcss_usb3_port2 on end + end + end + end + end + device ref tcss_dma0 on end + device ref xhci on + register "usb2_ports" = "{ + [0] = USB2_PORT_MID(OC_SKIP), /* USB3 Rear */ + [1] = USB2_PORT_MID(OC_SKIP), /* USB3 Rear */ + [2] = USB2_PORT_MID(OC_SKIP), /* USB2 Header */ + [3] = USB2_PORT_MID(OC_SKIP), /* USB2 Header */ + [4] = USB2_PORT_TYPE_C(OC_SKIP), /* TBT */ + [5] = USB2_PORT_TYPE_C(OC_SKIP), /* Type-C */ + [6] = USB2_PORT_MID(OC_SKIP), /* USB3 Front */ + [7] = USB2_PORT_MID(OC_SKIP), /* USB3 Front */ + [8] = USB2_PORT_MID(OC_SKIP), /* M.2 Key M */ + [9] = USB2_PORT_MID(OC_SKIP), /* M.2 Key E */ + }" + register "usb3_ports" = "{ + [0] = USB3_PORT_DEFAULT(OC_SKIP), /* USB3 Rear */ + [1] = USB3_PORT_DEFAULT(OC_SKIP), /* USB3 Rear */ + }" + end + device ref pcie_rp5 on + # GLAN1 + register "pcie_rp[PCH_RP(5)]" = "{ + .clk_src = 2, + .clk_req = 2, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + device pci 00.0 on end + end + device ref pcie_rp6 on + # GLAN2 + register "pcie_rp[PCH_RP(6)]" = "{ + .clk_src = 3, + .clk_req = 3, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref pcie_rp7 on + # M.2 Key-E1 + register "pcie_rp[PCH_RP(7)]" = "{ + .clk_src = 1, + .clk_req = 1, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref pcie_rp10 on + # M.2 Key-M1 + # XXX: Schematics show RP[13:16] used + register "pcie_rp[PCH_RP(10)]" = "{ + .clk_src = 8, + .clk_req = 8, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref pcie_rp11 on + # M.2 Key-M2 + # XXX: Schematics show RP[17:20] used + register "pcie_rp[PCH_RP(11)]" = "{ + .clk_src = 6, + .clk_req = 6, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref sata on + register "sata_salp_support" = "1" + register "sata_ports_enable[0]" = "1" # SATA 0 + register "sata_ports_dev_slp[0]" = "1" + end + device ref hda on + subsystemid 0x1849 0x0256 + end + end +end diff --git a/src/mainboard/system76/meer9/variants/meer9/ramstage.c b/src/mainboard/system76/meer9/variants/meer9/ramstage.c new file mode 100644 index 0000000000..c0c90dd45d --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/ramstage.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void mainboard_silicon_init_params(FSP_S_CONFIG *params) +{ + // Enable TCP1 and TCP2 USB-A conversion + // BIT 0:3 is mapping to PCH XHCI USB2 port + // BIT 4:5 is reserved + // BIT 6 is orientational + // BIT 7 is enable + params->EnableTcssCovTypeA[1] = 0x86; + params->EnableTcssCovTypeA[2] = 0x87; + + // XXX: Enabling C10 reporting causes system to constantly enter and + // exit opportunistic suspend when idle. + params->PchEspiHostC10ReportEnable = 0; +} diff --git a/src/mainboard/system76/meer9/variants/meer9/romstage.c b/src/mainboard/system76/meer9/variants/meer9/romstage.c new file mode 100644 index 0000000000..b047f523ac --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/romstage.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + const struct mb_cfg board_cfg = { + .type = MEM_TYPE_DDR5, + .ect = true, + }; + const struct mem_spd spd_info = { + .topo = MEM_TOPO_DIMM_MODULE, + .smbus = { + [0] = { .addr_dimm[0] = 0x50, }, + [1] = { .addr_dimm[0] = 0x52, }, + }, + }; + const bool half_populated = false; + + mupd->FspmConfig.DmiMaxLinkSpeed = 4; + mupd->FspmConfig.GpioOverride = 0; + + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); +} From 947bdab68f5a1e9b90155531e47ccddcfbac739b Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Mon, 20 Nov 2023 07:24:17 -0700 Subject: [PATCH 769/789] ec/system76: Support lockdown based on EC security state Change-Id: I202c0607c2cdac1df59f42fb41735704dd5bd95c Signed-off-by: Jeremy Soller Signed-off-by: Tim Crawford --- src/ec/system76/ec/Kconfig | 5 +++ src/ec/system76/ec/Makefile.mk | 1 + src/ec/system76/ec/lockdown.c | 59 ++++++++++++++++++++++++++++++++ src/ec/system76/ec/system76_ec.c | 9 +++++ src/ec/system76/ec/system76_ec.h | 11 ++++++ 5 files changed, 85 insertions(+) create mode 100644 src/ec/system76/ec/lockdown.c diff --git a/src/ec/system76/ec/Kconfig b/src/ec/system76/ec/Kconfig index f0702a76d1..14899dbce7 100644 --- a/src/ec/system76/ec/Kconfig +++ b/src/ec/system76/ec/Kconfig @@ -21,6 +21,11 @@ config EC_SYSTEM76_EC_DGPU select EC_SYSTEM76_EC_FAN2 depends on EC_SYSTEM76_EC +config EC_SYSTEM76_EC_LOCKDOWN + bool + default n + depends on EC_SYSTEM76_EC + config EC_SYSTEM76_EC_OLED bool default n diff --git a/src/ec/system76/ec/Makefile.mk b/src/ec/system76/ec/Makefile.mk index 9808e297d6..02fcda537c 100644 --- a/src/ec/system76/ec/Makefile.mk +++ b/src/ec/system76/ec/Makefile.mk @@ -4,6 +4,7 @@ ifeq ($(CONFIG_EC_SYSTEM76_EC),y) all-y += system76_ec.c ramstage-y += smbios.c +ramstage-$(CONFIG_EC_SYSTEM76_EC_LOCKDOWN) += lockdown.c smm-$(CONFIG_DEBUG_SMI) += system76_ec.c diff --git a/src/ec/system76/ec/lockdown.c b/src/ec/system76/ec/lockdown.c new file mode 100644 index 0000000000..d6f52f4102 --- /dev/null +++ b/src/ec/system76/ec/lockdown.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "system76_ec.h" +#include +#include +#include +#include + +static int protect_region_by_name(const char *name) +{ + int res; + struct region region; + + res = fmap_locate_area(name, ®ion); + if (res < 0) { + printk(BIOS_ERR, "fmap_locate_area '%s' failed: %d\n", name, res); + return res; + } + + res = spi_flash_ctrlr_protect_region( + boot_device_spi_flash(), + ®ion, + WRITE_PROTECT + ); + if (res < 0) { + printk(BIOS_ERR, "spi_flash_ctrlr_protect_region '%s' failed: %d\n", name, res); + return res; + } + + printk(BIOS_INFO, "protected '%s'\n", name); + return 0; +} + +static void lock(void *unused) +{ + uint8_t state = SYSTEM76_EC_SECURITY_STATE_UNLOCK; + if (!system76_ec_security_get(&state)) { + printk(BIOS_INFO, "failed to get security state, assuming unlocked\n"); + state = SYSTEM76_EC_SECURITY_STATE_UNLOCK; + } + + printk(BIOS_INFO, "security state: %d\n", state); + if (state != SYSTEM76_EC_SECURITY_STATE_UNLOCK) { + // Protect WP_RO region, which should contain FMAP and COREBOOT + protect_region_by_name("WP_RO"); + // Protect RW_MRC_CACHE region, this must be done after it is written + protect_region_by_name("RW_MRC_CACHE"); + //TODO: protect entire flash except when in SMM? + } +} + +/* + * Keep in sync with mrc_cache.c + */ +#if CONFIG(MRC_WRITE_NV_LATE) +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME_CHECK, BS_ON_EXIT, lock, NULL); +#else +BOOT_STATE_INIT_ENTRY(BS_DEV_RESOURCES, BS_ON_ENTRY, lock, NULL); +#endif diff --git a/src/ec/system76/ec/system76_ec.c b/src/ec/system76/ec/system76_ec.c index 828376d0e5..ee41b1e8d7 100644 --- a/src/ec/system76/ec/system76_ec.c +++ b/src/ec/system76/ec/system76_ec.c @@ -26,6 +26,9 @@ #define CMD_PRINT_REG_LEN 3 #define CMD_PRINT_REG_DATA 4 +// Get security state command +#define CMD_SECURITY_GET 20 + static inline uint8_t system76_ec_read(uint8_t addr) { return inb(SYSTEM76_EC_BASE + (uint16_t)addr); @@ -110,3 +113,9 @@ bool system76_ec_cmd(uint8_t cmd, const uint8_t *request_data, return ret; } + +bool system76_ec_security_get(uint8_t *state) +{ + *state = SYSTEM76_EC_SECURITY_STATE_LOCK; + return system76_ec_cmd(CMD_SECURITY_GET, NULL, 0, state, sizeof(*state)); +} diff --git a/src/ec/system76/ec/system76_ec.h b/src/ec/system76/ec/system76_ec.h index 9675bd0caf..6c91bb6aec 100644 --- a/src/ec/system76/ec/system76_ec.h +++ b/src/ec/system76/ec/system76_ec.h @@ -6,6 +6,15 @@ #include #include +// Default value, flashing is prevented, cannot be set with CMD_SECURITY_SET +#define SYSTEM76_EC_SECURITY_STATE_LOCK 0 +// Flashing is allowed, cannot be set with CMD_SECURITY_SET +#define SYSTEM76_EC_SECURITY_STATE_UNLOCK 1 +// Flashing will be prevented on the next reboot +#define SYSTEM76_EC_SECURITY_STATE_PREPARE_LOCK 2 +// Flashing will be allowed on the next reboot +#define SYSTEM76_EC_SECURITY_STATE_PREPARE_UNLOCK 3 + /* * Send a command to the EC. request_data/request_size are the request payload, * request_data can be NULL if request_size is 0. reply_data/reply_size are @@ -14,4 +23,6 @@ bool system76_ec_cmd(uint8_t cmd, const uint8_t *request_data, uint8_t request_size, uint8_t *reply_data, uint8_t reply_size); +bool system76_ec_security_get(uint8_t *state); + #endif From c08b7d66e8499e8a786d7eb4187c76de3db47860 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Mon, 20 Nov 2023 07:27:49 -0700 Subject: [PATCH 770/789] mb/system76: Enable EC lockdown on TGL+ Change-Id: I4b07846c404eb93ab4baf0a78a4bbffcc5d8afca Signed-off-by: Tim Crawford --- src/mainboard/system76/adl/Kconfig | 1 + src/mainboard/system76/mtl/Kconfig | 1 + src/mainboard/system76/rpl/Kconfig | 1 + src/mainboard/system76/tgl-h/Kconfig | 1 + src/mainboard/system76/tgl-u/Kconfig | 1 + 5 files changed, 5 insertions(+) diff --git a/src/mainboard/system76/adl/Kconfig b/src/mainboard/system76/adl/Kconfig index 18c5e9b2d1..9d35a35fdd 100644 --- a/src/mainboard/system76/adl/Kconfig +++ b/src/mainboard/system76/adl/Kconfig @@ -11,6 +11,7 @@ config BOARD_SYSTEM76_ADL_COMMON select DRIVERS_INTEL_PMC select DRIVERS_INTEL_USB4_RETIMER select EC_SYSTEM76_EC + select EC_SYSTEM76_EC_LOCKDOWN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT diff --git a/src/mainboard/system76/mtl/Kconfig b/src/mainboard/system76/mtl/Kconfig index 761c599fda..9b1f369cd6 100644 --- a/src/mainboard/system76/mtl/Kconfig +++ b/src/mainboard/system76/mtl/Kconfig @@ -9,6 +9,7 @@ config BOARD_SYSTEM76_MTL_COMMON select DRIVERS_GENERIC_CBFS_UUID select DRIVERS_I2C_HID select EC_SYSTEM76_EC + select EC_SYSTEM76_EC_LOCKDOWN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index 2c22affff1..f0799072b1 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -9,6 +9,7 @@ config BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GENERIC_CBFS_UUID select DRIVERS_I2C_HID select EC_SYSTEM76_EC + select EC_SYSTEM76_EC_LOCKDOWN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT diff --git a/src/mainboard/system76/tgl-h/Kconfig b/src/mainboard/system76/tgl-h/Kconfig index 7a0d3f5695..b3cde756d8 100644 --- a/src/mainboard/system76/tgl-h/Kconfig +++ b/src/mainboard/system76/tgl-h/Kconfig @@ -13,6 +13,7 @@ config BOARD_SPECIFIC_OPTIONS select DRIVERS_I2C_TAS5825M if BOARD_SYSTEM76_ORYP8 select EC_SYSTEM76_EC select EC_SYSTEM76_EC_DGPU + select EC_SYSTEM76_EC_LOCKDOWN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT diff --git a/src/mainboard/system76/tgl-u/Kconfig b/src/mainboard/system76/tgl-u/Kconfig index 56f516ff0a..88ce646df7 100644 --- a/src/mainboard/system76/tgl-u/Kconfig +++ b/src/mainboard/system76/tgl-u/Kconfig @@ -14,6 +14,7 @@ config BOARD_SPECIFIC_OPTIONS select DRIVERS_INTEL_USB4_RETIMER select EC_SYSTEM76_EC select EC_SYSTEM76_EC_DGPU if BOARD_SYSTEM76_GALP5 + select EC_SYSTEM76_EC_LOCKDOWN select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT select HAVE_OPTION_TABLE From 2cf2ad98296729473a20984555a84c1d84775b7e Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 27 Jun 2023 09:52:22 -0600 Subject: [PATCH 771/789] drivers/gfx/nvidia: Add driver for NVIDIA GPU Add a driver for laptops with NVIDIA Optimus (hybrid) graphics. The driver provides ACPI support for dynamically powering on and off the GPU, NVIDIA Dynamic Boost support, and a function for enabling the GPU power in romstage. References: - DG-09845-001: NVIDIA GN20/QN20 Hardware Design Guide - DG-09954-001: NVIDIA GN20/QN20 Software Design Guide Change-Id: I2dec7aa2c8db7994f78a7cc1220502676e248465 Signed-off-by: Jeremy Soller Signed-off-by: Tim Crawford --- src/drivers/gfx/nvidia/Kconfig | 38 +++++ src/drivers/gfx/nvidia/Makefile.mk | 5 + src/drivers/gfx/nvidia/acpi/coffeelake.asl | 96 +++++++++++ src/drivers/gfx/nvidia/acpi/common/dsm.asl | 30 ++++ src/drivers/gfx/nvidia/acpi/common/gps.asl | 66 ++++++++ src/drivers/gfx/nvidia/acpi/common/gpu.asl | 18 +++ src/drivers/gfx/nvidia/acpi/common/nvjt.asl | 152 ++++++++++++++++++ src/drivers/gfx/nvidia/acpi/common/nvpcf.asl | 113 +++++++++++++ src/drivers/gfx/nvidia/acpi/common/power.asl | 120 ++++++++++++++ .../gfx/nvidia/acpi/common/utility.asl | 63 ++++++++ src/drivers/gfx/nvidia/acpi/tigerlake.asl | 140 ++++++++++++++++ src/drivers/gfx/nvidia/chip.h | 10 ++ src/drivers/gfx/nvidia/gpu.h | 19 +++ src/drivers/gfx/nvidia/nvidia.c | 71 ++++++++ src/drivers/gfx/nvidia/romstage.c | 33 ++++ 15 files changed, 974 insertions(+) create mode 100644 src/drivers/gfx/nvidia/Kconfig create mode 100644 src/drivers/gfx/nvidia/Makefile.mk create mode 100644 src/drivers/gfx/nvidia/acpi/coffeelake.asl create mode 100644 src/drivers/gfx/nvidia/acpi/common/dsm.asl create mode 100644 src/drivers/gfx/nvidia/acpi/common/gps.asl create mode 100644 src/drivers/gfx/nvidia/acpi/common/gpu.asl create mode 100644 src/drivers/gfx/nvidia/acpi/common/nvjt.asl create mode 100644 src/drivers/gfx/nvidia/acpi/common/nvpcf.asl create mode 100644 src/drivers/gfx/nvidia/acpi/common/power.asl create mode 100644 src/drivers/gfx/nvidia/acpi/common/utility.asl create mode 100644 src/drivers/gfx/nvidia/acpi/tigerlake.asl create mode 100644 src/drivers/gfx/nvidia/chip.h create mode 100644 src/drivers/gfx/nvidia/gpu.h create mode 100644 src/drivers/gfx/nvidia/nvidia.c create mode 100644 src/drivers/gfx/nvidia/romstage.c diff --git a/src/drivers/gfx/nvidia/Kconfig b/src/drivers/gfx/nvidia/Kconfig new file mode 100644 index 0000000000..4c9c7ff08c --- /dev/null +++ b/src/drivers/gfx/nvidia/Kconfig @@ -0,0 +1,38 @@ +config DRIVERS_GFX_NVIDIA + bool + default n + help + Support for NVIDIA Optimus graphics + +config DRIVERS_GFX_NVIDIA_BRIDGE + hex "PCI bridge for the GPU device" + default 0x01 + depends on DRIVERS_GFX_NVIDIA + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + depends on DRIVERS_GFX_NVIDIA + bool + default n + help + Support for NVIDIA Dynamic Boost + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP + int "Total processor power offset from default TGP in watts" + default 45 + depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + help + This identifies the available power for the CPU or GPU boost + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MIN + int "Minimum TGP offset from default TGP in watts" + default 0 + depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + help + This is used to transfer power from the GPU to the CPU + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX + int "Maximum TGP offset from default TGP in watts" + default 0 + depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + help + This is used to transfer power from the CPU to the GPU diff --git a/src/drivers/gfx/nvidia/Makefile.mk b/src/drivers/gfx/nvidia/Makefile.mk new file mode 100644 index 0000000000..32ddf7e64e --- /dev/null +++ b/src/drivers/gfx/nvidia/Makefile.mk @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +romstage-$(CONFIG_DRIVERS_GFX_NVIDIA) += romstage.c + +ramstage-$(CONFIG_DRIVERS_GFX_NVIDIA) += nvidia.c diff --git a/src/drivers/gfx/nvidia/acpi/coffeelake.asl b/src/drivers/gfx/nvidia/acpi/coffeelake.asl new file mode 100644 index 0000000000..c515ec1cb2 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/coffeelake.asl @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* NVIDIA GC6 on CFL and CML CPU PCIe ports */ + +// Memory mapped PCI express config space +OperationRegion (PCIC, SystemMemory, CONFIG_ECAM_MMCONF_BASE_ADDRESS + (CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 15), 0x1000) + +Field (PCIC, ByteAcc, NoLock, Preserve) { + PVID, 16, + PDID, 16, + + Offset (0x248), + , 7, + L23E, 1, /* L23_Rdy Entry Request */ + L23R, 1, /* L23_Rdy to Detect Transition */ + + Offset (0xC20), + , 4, + P0AP, 2, /* Additional power savings */ + + Offset (0xC38), + , 3, + P0RM, 1, /* Robust squelch mechanism */ +} + +// Enter L23 +Method (DL23, 0, Serialized) { + Printf(" GPU PORT DL23 START") + + L23E = 1 + Sleep (16) + Local0 = 0 + While (L23E) { + If ((Local0 > 4)) { + Break + } + + Sleep (16) + Local0++ + } + + P0RM = 1 + P0AP = 3 + + Printf(" GPU PORT DL23 FINISH") +} + +// Exit L23 +Method (L23D, 0, Serialized) { + Printf(" GPU PORT L23D START") + + L23R = 1 + Sleep (16) + Local0 = 0 + While (L23R) { + If ((Local0 > 4)) { + Break + } + + Sleep (16) + Local0++ + } + + P0RM = 0 + P0AP = 0 + + Printf(" GPU PORT L23D FINISH") +} + +// Main power resource +PowerResource (PWRR, 0, 0) { + Name (_STA, 1) + + Method (_ON, 0, Serialized) { + Printf("GPU PORT PWRR._ON") + + ^^DEV0._ON() + + _STA = 1 + } + + Method (_OFF, 0, Serialized) { + Printf("GPU PORT PWRR._OFF") + + ^^DEV0._OFF() + + _STA = 0 + } +} + +// Power resources for entering D0 +Name (_PR0, Package () { PWRR }) + +// Power resources for entering D3 +Name (_PR3, Package () { PWRR }) + +#include "common/gpu.asl" diff --git a/src/drivers/gfx/nvidia/acpi/common/dsm.asl b/src/drivers/gfx/nvidia/acpi/common/dsm.asl new file mode 100644 index 0000000000..ad440b58b7 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/dsm.asl @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define NV_ERROR_SUCCESS 0x0 +#define NV_ERROR_UNSPECIFIED 0x80000001 +#define NV_ERROR_UNSUPPORTED 0x80000002 + +#include "gps.asl" +#include "nvjt.asl" + +Method (_DSM, 4, Serialized) { + Printf("GPU _DSM") + If (Arg0 == ToUUID (JT_DSM_GUID)) { + If (ToInteger(Arg1) >= JT_REVISION_ID_MIN) { + Return (NVJT(Arg2, Arg3)) + } Else { + Printf(" Unsupported JT revision: %o", SFST(Arg1)) + Return (NV_ERROR_UNSUPPORTED) + } + } ElseIf (Arg0 == ToUUID (GPS_DSM_GUID)) { + If (ToInteger(Arg1) == GPS_REVISION_ID) { + Return (GPS(Arg2, Arg3)) + } Else { + Printf(" Unsupported GPS revision: %o", SFST(Arg1)) + Return (NV_ERROR_UNSUPPORTED) + } + } Else { + Printf(" Unsupported GUID: %o", IDST(Arg0)) + Return (NV_ERROR_UNSPECIFIED) + } +} diff --git a/src/drivers/gfx/nvidia/acpi/common/gps.asl b/src/drivers/gfx/nvidia/acpi/common/gps.asl new file mode 100644 index 0000000000..7d69b19406 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/gps.asl @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define GPS_DSM_GUID "A3132D01-8CDA-49BA-A52E-BC9D46DF6B81" +#define GPS_REVISION_ID 0x00000200 +#define GPS_FUNC_SUPPORT 0x00000000 +#define GPS_FUNC_PSHARESTATUS 0x00000020 +#define GPS_FUNC_PSHAREPARAMS 0x0000002A + +Method(GPS, 2, Serialized) { + Printf(" GPU GPS") + Switch(ToInteger(Arg0)) { + Case(GPS_FUNC_SUPPORT) { + Printf(" Supported Functions") + Return(ITOB( + (1 << GPS_FUNC_SUPPORT) | + (1 << GPS_FUNC_PSHARESTATUS) | + (1 << GPS_FUNC_PSHAREPARAMS) + )) + } + Case(GPS_FUNC_PSHARESTATUS) { + Printf(" Power Share Status") + Return(ITOB(0)) + } + Case(GPS_FUNC_PSHAREPARAMS) { + Printf(" Power Share Parameters") + + CreateField(Arg1, 0, 4, QTYP) // Query type + + Name(GPSP, Buffer(36) { 0x00 }) + CreateDWordField(GPSP, 0, RSTS) // Response status + CreateDWordField(GPSP, 4, VERS) // Version + + // Set query type of response + RSTS = QTYP + // Set version of response + VERS = 0x00010000 + + Switch(ToInteger(QTYP)) { + Case(0) { + Printf(" Request Current Information") + // No required information + Return(GPSP) + } + Case(1) { + Printf(" Request Supported Fields") + // Support GPU temperature field + RSTS |= (1 << 8) + Return(GPSP) + } + Case(2) { + Printf(" Request Current Limits") + // No required limits + Return(GPSP) + } + Default { + Printf(" Unknown Query: %o", SFST(QTYP)) + Return(NV_ERROR_UNSUPPORTED) + } + } + } + Default { + Printf(" Unsupported function: %o", SFST(Arg0)) + Return(NV_ERROR_UNSUPPORTED) + } + } +} diff --git a/src/drivers/gfx/nvidia/acpi/common/gpu.asl b/src/drivers/gfx/nvidia/acpi/common/gpu.asl new file mode 100644 index 0000000000..49e5c47285 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/gpu.asl @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (DEV0) { + Name(_ADR, 0x00000000) + + #include "utility.asl" + #include "dsm.asl" + #include "power.asl" +} + +#if CONFIG(DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST) +Scope (\_SB) { + Device(NPCF) { + #include "utility.asl" + #include "nvpcf.asl" + } +} +#endif diff --git a/src/drivers/gfx/nvidia/acpi/common/nvjt.asl b/src/drivers/gfx/nvidia/acpi/common/nvjt.asl new file mode 100644 index 0000000000..31eaed275e --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/nvjt.asl @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define JT_DSM_GUID "CBECA351-067B-4924-9CBD-B46B00B86F34" +#define JT_REVISION_ID_MIN 0x00000100 +#define JT_REVISION_ID_MAX 0x00000200 +#define JT_FUNC_SUPPORT 0x00000000 +#define JT_FUNC_CAPS 0x00000001 +#define JT_FUNC_POWERCONTROL 0x00000003 + +//TODO: SMI traps and EGIN/XCLM +#define JT_GPC_GSS 0 // Get current GPU GCx sleep status +#define JT_GPC_EGNS 1 // Enter GC6 without self-refresh +#define JT_GPC_EGIS 2 // Enter GC6 with self-refresh +#define JT_GPC_XGXS 3 // Exit GC6 and stop self-refresh +#define JT_GPC_XGIS 4 // Exit GC6 for self-refresh update + +#define JT_DFGC_NONE 0 // Handle request immediately +#define JT_DFGC_DEFER 1 // Defer GPC and GPCX +//TODO #define JT_DFGC_CLEAR 2 // Clear pending requests + +// Deferred GC6 enter/exit until D3-cold (saved DFGC) +Name(DFEN, 0) + +// Deferred GC6 enter control (saved GPC) +Name(DFCI, 0) + +// Deferred GC6 exit control (saved GPCX) +Name(DFCO, 0) + +Method (NVJT, 2, Serialized) { + Printf(" GPU NVJT") + Switch (ToInteger(Arg0)) { + Case (JT_FUNC_SUPPORT) { + Printf(" Supported Functions") + Return(ITOB( + (1 << JT_FUNC_SUPPORT) | + (1 << JT_FUNC_CAPS) | + (1 << JT_FUNC_POWERCONTROL) + )) + } + Case (JT_FUNC_CAPS) { + Printf(" Capabilities") + Return(ITOB( + (1 << 0) | // G-SYNC NSVR power-saving features are enabled + (1 << 1) | // NVSR disabled + (2 << 3) | // Panel power and backlight are on the suspend rail + (0 << 5) | // self-refresh controller remains powered while panel is powered + (0 << 6) | // FB is not on the suspend rail but is powered on in GC6 + (0 << 8) | // Combined power rail for all GPUs + (0 << 10) | // External SPI ROM + (1 << 11) | // No SMI handler for kernel panic exit while in GC6 + (0 << 12) | // Supports notify on GC6 state done + (1 << 13) | // Support deferred GC6 + (1 << 14) | // Support fine-grained root port control + (2 << 15) | // GC6 version is GC6-R + (0 << 17) | // GC6 exit ISR is not supported + (0 << 18) | // GC6 self wakeup not supported + (JT_REVISION_ID_MAX << 20) // Highest revision supported + )) + } + Case (JT_FUNC_POWERCONTROL) { + Printf(" Power Control: %o", SFST(Arg1)) + + CreateField (Arg1, 0, 3, GPC) // GPU power control + CreateField (Arg1, 4, 1, PPC) // Panel power control + CreateField (Arg1, 14, 2, DFGC) // Defer GC6 enter/exit until D3 cold + CreateField (Arg1, 16, 3, GPCX) // Deferred GC6 exit control + + // Save deferred GC6 request + If ((ToInteger(GPC) != 0) || (ToInteger(DFGC) != 0)) { + DFEN = DFGC + DFCI = GPC + DFCO = GPCX + } + + // Buffer to cache current state + Name (JTBF, Buffer (4) { 0, 0, 0, 0 }) + CreateField (JTBF, 0, 3, CGCS) // Current GC state + CreateField (JTBF, 3, 1, CGPS) // Current GPU power status + CreateField (JTBF, 7, 1, CPSS) // Current panel and SRC state (0 when on) + + // If doing deferred GC6 request, return now + If (ToInteger(DFGC) != 0) { + CGCS = 1 + CGPS = 1 + Return (JTBF) + } + + // Apply requested state + Switch (ToInteger(GPC)) { + Case (JT_GPC_GSS) { + Printf(" Get current GPU GCx sleep status") + //TODO: include transitions! + If (GTXS(DGPU_RST_N)) { + // GPU powered on + CGCS = 1 + CGPS = 1 + } ElseIf (GTXS(DGPU_PWR_EN)) { + // GPU powered off, GC6 + CGCS = 3 + CGPS = 0 + } Else { + // GPU powered off, D3 cold + CGCS = 2 + CGPS = 0 + } + } + Case (JT_GPC_EGNS) { + Printf(" Enter GC6 without self-refresh") + GC6I() + CPSS = 1 + } + Case (JT_GPC_EGIS) { + Printf(" Enter GC6 with self-refresh") + GC6I() + If (ToInteger(PPC) == 0) { + CPSS = 0 + } + } + Case (JT_GPC_XGXS) { + Printf(" Exit GC6 and stop self-refresh") + GC6O() + + CGCS = 1 + CGPS = 1 + If (ToInteger(PPC) != 0) { + CPSS = 0 + } + } + Case (JT_GPC_XGIS) { + Printf(" Exit GC6 for self-refresh update") + GC6O() + + CGCS = 1 + CGPS = 1 + If (ToInteger(PPC) != 0) { + CPSS = 0 + } + } + Default { + Printf(" Unsupported GPU power control: %o", SFST(GPC)) + } + } + + Return (JTBF) + } + Default { + Printf(" Unsupported function: %o", SFST(Arg0)) + Return (NV_ERROR_UNSUPPORTED) + } + } +} diff --git a/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl b/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl new file mode 100644 index 0000000000..16b9fbd56d --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define NVPCF_DSM_GUID "36b49710-2483-11e7-9598-0800200c9a66" +#define NVPCF_REVISION_ID 0x00000200 +#define NVPCF_ERROR_SUCCESS 0x0 +#define NVPCF_ERROR_GENERIC 0x80000001 +#define NVPCF_ERROR_UNSUPPORTED 0x80000002 +#define NVPCF_FUNC_GET_SUPPORTED 0x00000000 +#define NVPCF_FUNC_GET_STATIC_CONFIG_TABLES 0x00000001 +#define NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS 0x00000002 + +Name(_HID, "NVDA0820") + +Name(_UID, "NPCF") + +Method(_DSM, 4, Serialized) { + Printf("NVPCF _DSM") + If (Arg0 == ToUUID(NVPCF_DSM_GUID)) { + If (ToInteger(Arg1) == NVPCF_REVISION_ID) { + Return(NPCF(Arg2, Arg3)) + } Else { + Printf(" Unsupported NVPCF revision: %o", SFST(Arg1)) + Return(NVPCF_ERROR_GENERIC) + } + } Else { + Printf(" Unsupported GUID: %o", IDST(Arg0)) + Return(NVPCF_ERROR_GENERIC) + } +} + +Method(NPCF, 2, Serialized) { + Printf(" NVPCF NPCF") + Switch(ToInteger(Arg0)) { + Case(NVPCF_FUNC_GET_SUPPORTED) { + Printf(" Supported Functions") + Return(ITOB( + (1 << NVPCF_FUNC_GET_SUPPORTED) | + (1 << NVPCF_FUNC_GET_STATIC_CONFIG_TABLES) | + (1 << NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS) + )) + } + Case(NVPCF_FUNC_GET_STATIC_CONFIG_TABLES) { + Printf(" Get Static Config") + Return(Buffer(14) { + // Device table header + 0x20, 0x03, 0x01, + // Intel + NVIDIA + 0x00, + // Controller table header + 0x23, 0x04, 0x05, 0x01, + // Dynamic boost controller + 0x01, + // Supports DC + 0x01, + // Reserved + 0x00, 0x00, 0x00, + // Checksum + 0xAD + }) + } + Case(NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS) { + Printf(" Update Dynamic Boost") + + CreateField(Arg1, 0x28, 2, ICMD) // Input command + + Name(PCFP, Buffer(49) { + // Table version + 0x23, + // Table header size + 0x05, + // Size of common status in bytes + 0x10, + // Size of controller entry in bytes + 0x1C, + // Other fields filled in later + }) + CreateByteField(PCFP, 0x04, CCNT) // Controller count + CreateWordField(PCFP, 0x19, ATPP) // AC TPP offset + CreateWordField(PCFP, 0x1D, AMXP) // AC maximum TGP offset + CreateWordField(PCFP, 0x21, AMNP) // AC minimum TGP offset + + Switch(ToInteger(ICMD)) { + Case(0) { + Printf(" Get Controller Params") + // Number of controllers + CCNT = 1 + // AC total processor power offset from default TGP in 1/8 watt units + ATPP = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP << 3) + // AC maximum TGP offset from default TGP in 1/8 watt units + AMXP = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX << 3) + // AC minimum TGP offset from default TGP in 1/8 watt units + AMNP = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MIN << 3) + Printf("PCFP: %o", SFST(PCFP)) + Return(PCFP) + } + Case(1) { + Printf(" Set Controller Status") + //TODO + Printf("PCFP: %o", SFST(PCFP)) + Return(PCFP) + } + Default { + Printf(" Unknown Input Command: %o", SFST(ICMD)) + Return(NV_ERROR_UNSUPPORTED) + } + } + } + Default { + Printf(" Unsupported function: %o", SFST(Arg0)) + Return(NVPCF_ERROR_UNSUPPORTED) + } + } +} diff --git a/src/drivers/gfx/nvidia/acpi/common/power.asl b/src/drivers/gfx/nvidia/acpi/common/power.asl new file mode 100644 index 0000000000..b285ba6af0 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/power.asl @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +//TODO: evaluate sleeps + +OperationRegion (PCIC, PCI_Config, 0x00, 0xFF) +Field (PCIC, DwordAcc, NoLock, Preserve) { + Offset (0x40), + SSID, 32, // Subsystem vendor and product ID +} + +// Enter GC6 +Method(GC6I, 0, Serialized) { + Printf(" GPU GC6I START") + + // Enter L23 + ^^DL23() + Sleep(5) + + // Put GPU into reset + Printf(" Put GPU into reset") + CTXS(DGPU_RST_N) + Sleep(5) + + Printf(" GPU GC6I FINISH") +} + +// Exit GC6 +Method(GC6O, 0, Serialized) { + Printf(" GPU GC6O START") + + // Bring GPU out of reset + Printf(" Bring GPU out of reset") + STXS(DGPU_RST_N) + Sleep(5) + + // Exit L23 + ^^L23D() + Sleep(5) + + Printf(" GPU GC6O FINISH") +} + +Method (_ON, 0, Serialized) { + Printf(" GPU _ON START") + + If (DFEN == JT_DFGC_DEFER) { + Switch (ToInteger(DFCO)) { + Case (JT_GPC_XGXS) { + Printf(" Exit GC6 and stop self-refresh") + GC6O() + } + Default { + Printf(" Unsupported DFCO: %o", SFST(DFCO)) + } + } + DFEN = JT_DFGC_NONE + } Else { + Printf(" Standard RTD3 power on") + STXS(DGPU_PWR_EN) + Sleep(5) + GC6O() + } + + Printf(" GPU _ON FINISH") +} + +Method (_OFF, 0, Serialized) { + Printf(" GPU _OFF START") + + If (DFEN == JT_DFGC_DEFER) { + Switch (ToInteger(DFCI)) { + Case (JT_GPC_EGNS) { + Printf(" Enter GC6 without self-refresh") + GC6I() + } + Case (JT_GPC_EGIS) { + Printf(" Enter GC6 with self-refresh") + GC6I() + } + Default { + Printf(" Unsupported DFCI: %o", SFST(DFCI)) + } + } + DFEN = JT_DFGC_NONE + } Else { + Printf(" Standard RTD3 power off") + GC6I() + CTXS(DGPU_PWR_EN) + Sleep(5) + } + + Printf(" GPU _OFF FINISH") +} + +// Main power resource +PowerResource (PWRR, 0, 0) { + Name (_STA, 1) + + Method (_ON, 0, Serialized) { + Printf("GPU PWRR._ON") + + // Restore SSID + ^^SSID = DGPU_SSID + Printf(" Restore SSID: %o", SFST(^^SSID)) + + _STA = 1 + } + + Method (_OFF, 0, Serialized) { + Printf("GPU PWRR._OFF") + + _STA = 0 + } +} + +// Power resources for entering D0 +Name (_PR0, Package () { PWRR }) + +// Power resources for entering D3 +Name (_PR3, Package () { PWRR }) diff --git a/src/drivers/gfx/nvidia/acpi/common/utility.asl b/src/drivers/gfx/nvidia/acpi/common/utility.asl new file mode 100644 index 0000000000..edf42bd024 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/utility.asl @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +// Convert a byte to a hex string, trimming extra parts +Method (BHEX, 1) { + Local0 = ToHexString(Arg0) + Return (Mid(Local0, SizeOf(Local0) - 2, 2)) +} + +// UUID to string +Method (IDST, 1) { + Local0 = "" + Fprintf( + Local0, + "%o%o%o%o-%o%o-%o%o-%o%o-%o%o%o%o%o%o", + BHEX(DerefOf(Arg0[3])), + BHEX(DerefOf(Arg0[2])), + BHEX(DerefOf(Arg0[1])), + BHEX(DerefOf(Arg0[0])), + BHEX(DerefOf(Arg0[5])), + BHEX(DerefOf(Arg0[4])), + BHEX(DerefOf(Arg0[7])), + BHEX(DerefOf(Arg0[6])), + BHEX(DerefOf(Arg0[8])), + BHEX(DerefOf(Arg0[9])), + BHEX(DerefOf(Arg0[10])), + BHEX(DerefOf(Arg0[11])), + BHEX(DerefOf(Arg0[12])), + BHEX(DerefOf(Arg0[13])), + BHEX(DerefOf(Arg0[14])), + BHEX(DerefOf(Arg0[15])) + ) + Return (Local0) +} + +// Safe hex conversion, checks type first +Method (SFST, 1) { + Local0 = ObjectType(Arg0) + If (Local0 == 1 || Local0 == 2 || Local0 == 3) { + Return (ToHexString(Arg0)) + } Else { + Return (Concatenate("Type: ", Arg0)) + } +} + +// Convert from 4-byte buffer to 32-bit integer +Method (BTOI, 1) { + Return( + DerefOf(Arg0[0]) | + (DerefOf(Arg0[1]) << 8) | + (DerefOf(Arg0[2]) << 16) | + (DerefOf(Arg0[3]) << 24) + ) +} + +// Convert from 32-bit integer to 4-byte buffer +Method (ITOB, 1) { + Local0 = Buffer(4) { 0, 0, 0, 0 } + Local0[0] = Arg0 & 0xFF + Local0[1] = (Arg0 >> 8) & 0xFF + Local0[2] = (Arg0 >> 16) & 0xFF + Local0[3] = (Arg0 >> 24) & 0xFF + Return (Local0) +} diff --git a/src/drivers/gfx/nvidia/acpi/tigerlake.asl b/src/drivers/gfx/nvidia/acpi/tigerlake.asl new file mode 100644 index 0000000000..a13e46a04f --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/tigerlake.asl @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* NVIDIA GC6 on (TGL and ADL) (CPU and PCH) PCIe ports */ + +// Port mapped PCI express config space +OperationRegion (PCIC, PCI_Config, 0x00, 0xFF) + +Field (PCIC, AnyAcc, NoLock, Preserve) { + Offset(0x52), /* LSTS - Link Status Register */ + , 13, + LASX, 1, /* 0, Link Active Status */ + + Offset(0x60), /* RSTS - Root Status Register */ + , 16, + PSPX, 1, /* 16, PME Status */ + + Offset(0xD8), /* 0xD8, MPC - Miscellaneous Port Configuration Register */ + , 30, + HPEX, 1, /* 30, Hot Plug SCI Enable */ + PMEX, 1, /* 31, Power Management SCI Enable */ + + Offset (0xE0), /* 0xE0, SPR - Scratch Pad Register */ + SCB0, 1, /* Scratch bit 0 */ + + Offset(0xE2), /* 0xE2, RPPGEN - Root Port Power Gating Enable */ + , 2, + L23E, 1, /* 2, L23_Rdy Entry Request (L23ER) */ + L23R, 1, /* 3, L23_Rdy to Detect Transition (L23R2DT) */ +} + +Field (PCIC, AnyAcc, NoLock, WriteAsZeros) { + Offset(0xDC), /* 0xDC, SMSCS - SMI/SCI Status Register */ + , 30, + HPSX, 1, /* 30, Hot Plug SCI Status */ + PMSX, 1 /* 31, Power Management SCI Status */ +} + +// Enter L23 +Method (DL23, 0, Serialized) { + Printf(" GPU PORT DL23 START") + + L23E = 1 + Sleep (16) + Local0 = 0 + While (L23E) { + If ((Local0 > 4)) { + Break + } + + Sleep (16) + Local0++ + } + SCB0 = 1 + + Printf(" GPU PORT DL23 FINISH") +} + +// Exit L23 +Method (L23D, 0, Serialized) { + Printf(" GPU PORT L23D START") + + If ((SCB0 == 1)) { + L23R = 1 + Local0 = 0 + While (L23R) { + If ((Local0 > 4)) { + Break + } + Sleep (16) + Local0++ + } + + SCB0 = 0 + Local0 = 0 + While ((LASX == 0)) { + If ((Local0 > 8)) { + Break + } + Sleep (16) + Local0++ + } + } + + Printf(" GPU PORT L23D FINISH") +} + +Method (HPME, 0, Serialized) { + Printf(" GPU PORT HPME START") + + If (PMSX == 1) { + Printf(" Notify GPU driver of PME SCI") + Notify(DEV0, 0x2) + Printf(" Clear PME SCI") + PMSX = 1 + Printf(" Consume PME notification") + PSPX = 1 + } + + Printf(" GPU PORT HPME FINISH") +} + +// Main power resource +PowerResource (PWRR, 0, 0) { + Name (_STA, 1) + + Method (_ON, 0, Serialized) { + Printf("GPU PORT PWRR._ON") + + HPME(); + If (PMEX == 1) { + Printf(" Disable power management SCI") + PMEX = 0 + } + + ^^DEV0._ON() + + _STA = 1 + } + + Method (_OFF, 0, Serialized) { + Printf("GPU PORT PWRR._OFF") + + ^^DEV0._OFF() + + If (PMEX == 0) { + Printf(" Enable power management SCI") + PMEX = 1 + HPME() + } + + _STA = 0 + } +} + +// Power resources for entering D0 +Name (_PR0, Package () { PWRR }) + +// Power resources for entering D3 +Name (_PR3, Package () { PWRR }) + +#include "common/gpu.asl" diff --git a/src/drivers/gfx/nvidia/chip.h b/src/drivers/gfx/nvidia/chip.h new file mode 100644 index 0000000000..b6d9c908eb --- /dev/null +++ b/src/drivers/gfx/nvidia/chip.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _DRIVERS_GFX_NVIDIA_CHIP_H_ +#define _DRIVERS_GFX_NVIDIA_CHIP_H_ + +struct drivers_gfx_nvidia_config { + /* TODO: Set GPIOs in devicetree? */ +}; + +#endif /* _DRIVERS_GFX_NVIDIA_CHIP_H_ */ diff --git a/src/drivers/gfx/nvidia/gpu.h b/src/drivers/gfx/nvidia/gpu.h new file mode 100644 index 0000000000..68b6cd2d59 --- /dev/null +++ b/src/drivers/gfx/nvidia/gpu.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _DRIVERS_GFX_NVIDIA_GPU_H_ +#define _DRIVERS_GFX_NVIDIA_GPU_H_ + +#include + +struct nvidia_gpu_config { + /* GPIO for GPU_PWR_EN */ + unsigned int power_gpio; + /* GPIO for GPU_RST# */ + unsigned int reset_gpio; + /* Enable or disable GPU power */ + bool enable; +}; + +void nvidia_set_power(const struct nvidia_gpu_config *config); + +#endif /* _DRIVERS_NVIDIA_GPU_H_ */ diff --git a/src/drivers/gfx/nvidia/nvidia.c b/src/drivers/gfx/nvidia/nvidia.c new file mode 100644 index 0000000000..09083e83b5 --- /dev/null +++ b/src/drivers/gfx/nvidia/nvidia.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "chip.h" +#include +#include +#include +#include + +#define NVIDIA_SUBSYSTEM_ID_OFFSET 0x40 + +static void nvidia_read_resources(struct device *dev) +{ + printk(BIOS_DEBUG, "%s: %s\n", __func__, dev_path(dev)); + + pci_dev_read_resources(dev); + + // Find all BARs on GPU, mark them above 4g if prefetchable + for (int bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4) { + struct resource *res = probe_resource(dev, bar); + + if (res) { + if (res->flags & IORESOURCE_PREFETCH) { + printk(BIOS_INFO, " BAR at 0x%02x marked above 4g\n", bar); + res->flags |= IORESOURCE_ABOVE_4G; + } else { + printk(BIOS_DEBUG, " BAR at 0x%02x not prefetch\n", bar); + } + } else { + printk(BIOS_DEBUG, " BAR at 0x%02x not found\n", bar); + } + } +} + +static void nvidia_set_subsystem(struct device *dev, unsigned int vendor, unsigned int device) +{ + pci_write_config32(dev, NVIDIA_SUBSYSTEM_ID_OFFSET, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations nvidia_device_ops_pci = { + .set_subsystem = nvidia_set_subsystem, +}; + +static struct device_operations nvidia_device_ops = { + .read_resources = nvidia_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, +#if CONFIG(HAVE_ACPI_TABLES) + .write_acpi_tables = pci_rom_write_acpi_tables, + .acpi_fill_ssdt = pci_rom_ssdt, +#endif + .init = pci_dev_init, + .ops_pci = &nvidia_device_ops_pci, + +}; + +static void nvidia_enable(struct device *dev) +{ + if (!is_dev_enabled(dev) || dev->path.type != DEVICE_PATH_PCI) + return; + + if (pci_read_config16(dev, PCI_VENDOR_ID) != PCI_VID_NVIDIA) + return; + + dev->ops = &nvidia_device_ops; +} + +struct chip_operations drivers_gfx_nvidia_ops = { + .name = "NVIDIA Optimus Graphics Device", + .enable_dev = nvidia_enable +}; diff --git a/src/drivers/gfx/nvidia/romstage.c b/src/drivers/gfx/nvidia/romstage.c new file mode 100644 index 0000000000..78fe5ddf50 --- /dev/null +++ b/src/drivers/gfx/nvidia/romstage.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include "chip.h" +#include "gpu.h" + +void nvidia_set_power(const struct nvidia_gpu_config *config) +{ + if (!config->power_gpio || !config->reset_gpio) { + printk(BIOS_ERR, "%s: GPU_PWR_EN and GPU_RST# must be set\n", __func__); + return; + } + + printk(BIOS_DEBUG, "%s: GPU_PWR_EN = %d\n", __func__, config->power_gpio); + printk(BIOS_DEBUG, "%s: GPU_RST# = %d\n", __func__, config->reset_gpio); + + gpio_set(config->reset_gpio, 0); + mdelay(10); + + if (config->enable) { + gpio_set(config->power_gpio, 1); + mdelay(25); + gpio_set(config->reset_gpio, 1); + } else { + gpio_set(config->power_gpio, 0); + } + + mdelay(10); +} From e441d470dfacfc74a8e507876d8050c85c2276b2 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Tue, 1 Apr 2025 11:36:00 -0600 Subject: [PATCH 772/789] mb/system76: Enable dGPUs Change-Id: I4ca91ff631dd4badbfba72e69651f03753323a54 Signed-off-by: Tim Crawford --- src/mainboard/system76/addw1/Kconfig | 1 + src/mainboard/system76/addw1/Makefile.mk | 2 +- .../system76/addw1/acpi/mainboard.asl | 8 ++++++ src/mainboard/system76/addw1/devicetree.cb | 6 +++++ src/mainboard/system76/addw1/romstage.c | 14 ++++++++++ .../variants/addw1}/include/variant/gpio.h | 9 +++++++ .../variants/addw2/include/variant/gpio.h | 18 +++++++++++++ src/mainboard/system76/adl/Kconfig | 12 +++++++++ src/mainboard/system76/adl/Makefile.mk | 4 +++ src/mainboard/system76/adl/acpi/mainboard.asl | 10 +++++++ .../gaze17-3050/include/variant/gpio.h | 13 +++++++++ .../adl/variants/gaze17-3050/overridetree.cb | 4 +++ .../adl/variants/gaze17-3050/romstage.c | 10 +++++++ .../gaze17-3060-b/include/variant/gpio.h | 13 +++++++++ .../variants/gaze17-3060-b/overridetree.cb | 4 +++ .../adl/variants/gaze17-3060-b/romstage.c | 10 +++++++ .../variants/oryp10/include/variant/gpio.h | 13 +++++++++ .../adl/variants/oryp10/overridetree.cb | 4 +++ .../system76/adl/variants/oryp10/romstage.c | 10 +++++++ .../adl/variants/oryp9/include/variant/gpio.h | 13 +++++++++ .../adl/variants/oryp9/overridetree.cb | 4 +++ .../system76/adl/variants/oryp9/romstage.c | 10 +++++++ src/mainboard/system76/bonw14/Kconfig | 1 + src/mainboard/system76/bonw14/devicetree.cb | 11 ++++---- src/mainboard/system76/gaze15/Kconfig | 1 + src/mainboard/system76/gaze15/Makefile.mk | 2 +- .../system76/gaze15/acpi/mainboard.asl | 6 +++++ src/mainboard/system76/gaze15/devicetree.cb | 6 +++++ src/mainboard/system76/gaze15/romstage.c | 14 ++++++++++ .../variants/gaze14/include/variant/gpio.h | 18 +++++++++++++ .../variants/gaze15/include/variant/gpio.h | 18 +++++++++++++ src/mainboard/system76/oryp5/Kconfig | 1 + .../system76/oryp5/acpi/mainboard.asl | 6 +++++ src/mainboard/system76/oryp5/devicetree.cb | 6 +++++ .../system76/oryp5/include/mainboard/gpio.h | 9 +++++++ src/mainboard/system76/oryp5/romstage.c | 14 ++++++++++ src/mainboard/system76/oryp6/Kconfig | 1 + src/mainboard/system76/oryp6/Makefile.mk | 1 + .../system76/oryp6/acpi/mainboard.asl | 6 +++++ src/mainboard/system76/oryp6/devicetree.cb | 6 +++++ src/mainboard/system76/oryp6/romstage.c | 14 ++++++++++ .../variants/oryp6/include/variant/gpio.h | 18 +++++++++++++ .../variants/oryp7/include/variant/gpio.h | 18 +++++++++++++ src/mainboard/system76/rpl/Kconfig | 27 +++++++++++++++++++ src/mainboard/system76/rpl/Makefile.mk | 4 +++ src/mainboard/system76/rpl/acpi/mainboard.asl | 16 +++++++++++ .../rpl/variants/addw3/include/variant/gpio.h | 13 +++++++++ .../system76/rpl/variants/addw3/romstage.c | 11 ++++++++ .../rpl/variants/addw4/include/variant/gpio.h | 12 +++++++++ .../system76/rpl/variants/addw4/romstage.c | 11 ++++++++ .../variants/bonw15-b/include/variant/gpio.h | 13 +++++++++ .../system76/rpl/variants/bonw15-b/romstage.c | 11 ++++++++ .../variants/bonw15/include/variant/gpio.h | 13 +++++++++ .../system76/rpl/variants/bonw15/romstage.c | 11 ++++++++ .../variants/gaze18/include/variant/gpio.h | 13 +++++++++ .../system76/rpl/variants/gaze18/romstage.c | 11 ++++++++ .../variants/oryp11/include/variant/gpio.h | 13 +++++++++ .../system76/rpl/variants/oryp11/romstage.c | 11 ++++++++ .../variants/oryp12/include/variant/gpio.h | 12 +++++++++ .../system76/rpl/variants/oryp12/romstage.c | 11 ++++++++ .../variants/serw13/include/variant/gpio.h | 13 +++++++++ .../system76/rpl/variants/serw13/romstage.c | 10 +++++++ src/mainboard/system76/tgl-h/Kconfig | 1 + src/mainboard/system76/tgl-h/Makefile.mk | 1 + .../system76/tgl-h/acpi/mainboard.asl | 5 ++++ src/mainboard/system76/tgl-h/romstage.c | 18 +++++++++++-- .../gaze16-3050}/include/variant/gpio.h | 9 +++++++ .../variants/gaze16-3050/overridetree.cb | 14 ++++------ .../gaze16-3060}/include/variant/gpio.h | 9 +++++++ .../variants/gaze16-3060/overridetree.cb | 14 ++++------ .../variants/oryp8}/include/variant/gpio.h | 9 +++++++ .../tgl-h/variants/oryp8/overridetree.cb | 14 ++++------ src/mainboard/system76/tgl-u/Kconfig | 12 +++++++++ .../system76/tgl-u/acpi/mainboard.asl | 9 +++++++ .../tgl-u/variants/galp5/overridetree.cb | 14 ++++------ .../system76/tgl-u/variants/galp5/romstage.c | 15 ++++++++++- 76 files changed, 703 insertions(+), 46 deletions(-) rename src/mainboard/system76/{tgl-h => addw1/variants/addw1}/include/variant/gpio.h (53%) create mode 100644 src/mainboard/system76/addw1/variants/addw2/include/variant/gpio.h create mode 100644 src/mainboard/system76/adl/variants/gaze17-3050/include/variant/gpio.h create mode 100644 src/mainboard/system76/adl/variants/gaze17-3060-b/include/variant/gpio.h create mode 100644 src/mainboard/system76/adl/variants/oryp10/include/variant/gpio.h create mode 100644 src/mainboard/system76/adl/variants/oryp9/include/variant/gpio.h create mode 100644 src/mainboard/system76/gaze15/variants/gaze14/include/variant/gpio.h create mode 100644 src/mainboard/system76/gaze15/variants/gaze15/include/variant/gpio.h create mode 100644 src/mainboard/system76/oryp6/variants/oryp6/include/variant/gpio.h create mode 100644 src/mainboard/system76/oryp6/variants/oryp7/include/variant/gpio.h create mode 100644 src/mainboard/system76/rpl/variants/addw3/include/variant/gpio.h create mode 100644 src/mainboard/system76/rpl/variants/addw4/include/variant/gpio.h create mode 100644 src/mainboard/system76/rpl/variants/bonw15-b/include/variant/gpio.h create mode 100644 src/mainboard/system76/rpl/variants/bonw15/include/variant/gpio.h create mode 100644 src/mainboard/system76/rpl/variants/gaze18/include/variant/gpio.h create mode 100644 src/mainboard/system76/rpl/variants/oryp11/include/variant/gpio.h create mode 100644 src/mainboard/system76/rpl/variants/oryp12/include/variant/gpio.h create mode 100644 src/mainboard/system76/rpl/variants/serw13/include/variant/gpio.h rename src/mainboard/system76/{addw1 => tgl-h/variants/gaze16-3050}/include/variant/gpio.h (53%) rename src/mainboard/system76/{gaze15 => tgl-h/variants/gaze16-3060}/include/variant/gpio.h (53%) rename src/mainboard/system76/{oryp6 => tgl-h/variants/oryp8}/include/variant/gpio.h (53%) diff --git a/src/mainboard/system76/addw1/Kconfig b/src/mainboard/system76/addw1/Kconfig index a444da0441..4905ec8e55 100644 --- a/src/mainboard/system76/addw1/Kconfig +++ b/src/mainboard/system76/addw1/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_16384 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC diff --git a/src/mainboard/system76/addw1/Makefile.mk b/src/mainboard/system76/addw1/Makefile.mk index 09424595d7..1447b6a87f 100644 --- a/src/mainboard/system76/addw1/Makefile.mk +++ b/src/mainboard/system76/addw1/Makefile.mk @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/addw1/acpi/mainboard.asl b/src/mainboard/system76/addw1/acpi/mainboard.asl index 4e67439c56..2f01acc0bc 100644 --- a/src/mainboard/system76/addw1/acpi/mainboard.asl +++ b/src/mainboard/system76/addw1/acpi/mainboard.asl @@ -1,11 +1,19 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include + #define EC_GPE_SCI 0x03 /* GPP_K3 */ #define EC_GPE_SWI 0x06 /* GPP_K6 */ #include Scope (\_SB) { #include "sleep.asl" + Scope (PCI0) { + Device (PEGP) { + Name (_ADR, CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 16) + #include + } + } } Scope (\_GPE) { diff --git a/src/mainboard/system76/addw1/devicetree.cb b/src/mainboard/system76/addw1/devicetree.cb index cd93ddcc14..f9a85fb2fe 100644 --- a/src/mainboard/system76/addw1/devicetree.cb +++ b/src/mainboard/system76/addw1/devicetree.cb @@ -55,6 +55,12 @@ chip soc/intel/cannonlake # PCI Express Graphics #0 x16, Clock 8 (NVIDIA GPU) register "PcieClkSrcUsage[8]" = "0x40" register "PcieClkSrcClkReq[8]" = "8" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller + end end device ref igpu on end device ref dptf on end diff --git a/src/mainboard/system76/addw1/romstage.c b/src/mainboard/system76/addw1/romstage.c index 02634ba2ad..fdb208b88d 100644 --- a/src/mainboard/system76/addw1/romstage.c +++ b/src/mainboard/system76/addw1/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include static const struct cnl_mb_cfg memcfg = { .spd[0] = { @@ -20,5 +22,17 @@ static const struct cnl_mb_cfg memcfg = { void mainboard_memory_init_params(FSPM_UPD *memupd) { + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + memupd->FspmConfig.PrimaryDisplay = 0; + cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg); } diff --git a/src/mainboard/system76/tgl-h/include/variant/gpio.h b/src/mainboard/system76/addw1/variants/addw1/include/variant/gpio.h similarity index 53% rename from src/mainboard/system76/tgl-h/include/variant/gpio.h rename to src/mainboard/system76/addw1/variants/addw1/include/variant/gpio.h index 95d576294f..c78f11b4cd 100644 --- a/src/mainboard/system76/tgl-h/include/variant/gpio.h +++ b/src/mainboard/system76/addw1/variants/addw1/include/variant/gpio.h @@ -3,7 +3,16 @@ #ifndef VARIANT_GPIO_H #define VARIANT_GPIO_H +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_C12 +#define DGPU_SSID 0x65d11558 + +#ifndef __ACPI__ void variant_configure_early_gpios(void); void variant_configure_gpios(void); +#endif #endif diff --git a/src/mainboard/system76/addw1/variants/addw2/include/variant/gpio.h b/src/mainboard/system76/addw1/variants/addw2/include/variant/gpio.h new file mode 100644 index 0000000000..321cd43527 --- /dev/null +++ b/src/mainboard/system76/addw1/variants/addw2/include/variant/gpio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_C12 +#define DGPU_SSID 0x65e11558 + +#ifndef __ACPI__ +void variant_configure_early_gpios(void); +void variant_configure_gpios(void); +#endif + +#endif diff --git a/src/mainboard/system76/adl/Kconfig b/src/mainboard/system76/adl/Kconfig index 9d35a35fdd..72f2d46a02 100644 --- a/src/mainboard/system76/adl/Kconfig +++ b/src/mainboard/system76/adl/Kconfig @@ -36,10 +36,12 @@ config BOARD_SYSTEM76_GALP6 config BOARD_SYSTEM76_GAZE17_3050 select BOARD_SYSTEM76_ADL_COMMON + select DRIVERS_GFX_NVIDIA select EC_SYSTEM76_EC_DGPU config BOARD_SYSTEM76_GAZE17_3060_B select BOARD_SYSTEM76_ADL_COMMON + select DRIVERS_GFX_NVIDIA select EC_SYSTEM76_EC_DGPU select MAINBOARD_USES_IFD_GBE_REGION @@ -49,11 +51,15 @@ config BOARD_SYSTEM76_LEMP11 config BOARD_SYSTEM76_ORYP9 select BOARD_SYSTEM76_ADL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC_DGPU config BOARD_SYSTEM76_ORYP10 select BOARD_SYSTEM76_ADL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU if BOARD_SYSTEM76_ADL_COMMON @@ -104,6 +110,12 @@ config CONSOLE_POST config D3COLD_SUPPORT default n +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP + default 45 if BOARD_SYSTEM76_ORYP9 || BOARD_SYSTEM76_ORYP10 + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX + default 25 if BOARD_SYSTEM76_ORYP9 || BOARD_SYSTEM76_ORYP10 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/board.fmd" diff --git a/src/mainboard/system76/adl/Makefile.mk b/src/mainboard/system76/adl/Makefile.mk index c5334f1f0c..727ce27218 100644 --- a/src/mainboard/system76/adl/Makefile.mk +++ b/src/mainboard/system76/adl/Makefile.mk @@ -2,6 +2,10 @@ CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +ifeq ($(CONFIG_DRIVERS_GFX_NVIDIA),y) +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include +endif + bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/adl/acpi/mainboard.asl b/src/mainboard/system76/adl/acpi/mainboard.asl index c982a9ee4c..f7453fc339 100644 --- a/src/mainboard/system76/adl/acpi/mainboard.asl +++ b/src/mainboard/system76/adl/acpi/mainboard.asl @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#if CONFIG(DRIVERS_GFX_NVIDIA) +#include +#endif + #define EC_GPE_SCI 0x6E #define EC_GPE_SWI 0x6B #include @@ -8,5 +12,11 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + +#if CONFIG(DRIVERS_GFX_NVIDIA) + Scope (PEG2) { + #include + } +#endif } } diff --git a/src/mainboard/system76/adl/variants/gaze17-3050/include/variant/gpio.h b/src/mainboard/system76/adl/variants/gaze17-3050/include/variant/gpio.h new file mode 100644 index 0000000000..5c2c0635fa --- /dev/null +++ b/src/mainboard/system76/adl/variants/gaze17-3050/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_F13 +#define DGPU_SSID 0x866d1558 + +#endif diff --git a/src/mainboard/system76/adl/variants/gaze17-3050/overridetree.cb b/src/mainboard/system76/adl/variants/gaze17-3050/overridetree.cb index 511e0535b7..876576f7c9 100644 --- a/src/mainboard/system76/adl/variants/gaze17-3050/overridetree.cb +++ b/src/mainboard/system76/adl/variants/gaze17-3050/overridetree.cb @@ -40,6 +40,10 @@ chip soc/intel/alderlake .clk_req = 3, .flags = PCIE_RP_LTR, }" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + end end device ref pcie4_0 on # PCIe PEG0 x4, Clock 0 (SSD2) diff --git a/src/mainboard/system76/adl/variants/gaze17-3050/romstage.c b/src/mainboard/system76/adl/variants/gaze17-3050/romstage.c index 5e6cf7dd52..cea4ff5155 100644 --- a/src/mainboard/system76/adl/variants/gaze17-3050/romstage.c +++ b/src/mainboard/system76/adl/variants/gaze17-3050/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -17,6 +19,14 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/adl/variants/gaze17-3060-b/include/variant/gpio.h b/src/mainboard/system76/adl/variants/gaze17-3060-b/include/variant/gpio.h new file mode 100644 index 0000000000..6bf3550d25 --- /dev/null +++ b/src/mainboard/system76/adl/variants/gaze17-3060-b/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_F13 +#define DGPU_SSID 0x867c1558 + +#endif diff --git a/src/mainboard/system76/adl/variants/gaze17-3060-b/overridetree.cb b/src/mainboard/system76/adl/variants/gaze17-3060-b/overridetree.cb index de67935293..a81796db0f 100644 --- a/src/mainboard/system76/adl/variants/gaze17-3060-b/overridetree.cb +++ b/src/mainboard/system76/adl/variants/gaze17-3060-b/overridetree.cb @@ -40,6 +40,10 @@ chip soc/intel/alderlake .clk_req = 3, .flags = PCIE_RP_LTR, }" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + end end device ref igpu on # DDIA is eDP diff --git a/src/mainboard/system76/adl/variants/gaze17-3060-b/romstage.c b/src/mainboard/system76/adl/variants/gaze17-3060-b/romstage.c index 5e6cf7dd52..cea4ff5155 100644 --- a/src/mainboard/system76/adl/variants/gaze17-3060-b/romstage.c +++ b/src/mainboard/system76/adl/variants/gaze17-3060-b/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -17,6 +19,14 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/adl/variants/oryp10/include/variant/gpio.h b/src/mainboard/system76/adl/variants/oryp10/include/variant/gpio.h new file mode 100644 index 0000000000..489487ba7b --- /dev/null +++ b/src/mainboard/system76/adl/variants/oryp10/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_A7 +#define DGPU_SSID 0x65f51558 + +#endif diff --git a/src/mainboard/system76/adl/variants/oryp10/overridetree.cb b/src/mainboard/system76/adl/variants/oryp10/overridetree.cb index b213892232..94b1059960 100644 --- a/src/mainboard/system76/adl/variants/oryp10/overridetree.cb +++ b/src/mainboard/system76/adl/variants/oryp10/overridetree.cb @@ -25,6 +25,10 @@ chip soc/intel/alderlake .clk_req = 3, .flags = PCIE_RP_LTR, }" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + end end device ref igpu on register "ddi_portA_config" = "1" diff --git a/src/mainboard/system76/adl/variants/oryp10/romstage.c b/src/mainboard/system76/adl/variants/oryp10/romstage.c index 86ecf32826..dfd826a759 100644 --- a/src/mainboard/system76/adl/variants/oryp10/romstage.c +++ b/src/mainboard/system76/adl/variants/oryp10/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -20,6 +22,14 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/adl/variants/oryp9/include/variant/gpio.h b/src/mainboard/system76/adl/variants/oryp9/include/variant/gpio.h new file mode 100644 index 0000000000..489487ba7b --- /dev/null +++ b/src/mainboard/system76/adl/variants/oryp9/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_A7 +#define DGPU_SSID 0x65f51558 + +#endif diff --git a/src/mainboard/system76/adl/variants/oryp9/overridetree.cb b/src/mainboard/system76/adl/variants/oryp9/overridetree.cb index e41c0a278a..3cbf1b984f 100644 --- a/src/mainboard/system76/adl/variants/oryp9/overridetree.cb +++ b/src/mainboard/system76/adl/variants/oryp9/overridetree.cb @@ -25,6 +25,10 @@ chip soc/intel/alderlake .clk_req = 3, .flags = PCIE_RP_LTR, }" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + end end device ref igpu on register "ddi_portA_config" = "1" diff --git a/src/mainboard/system76/adl/variants/oryp9/romstage.c b/src/mainboard/system76/adl/variants/oryp9/romstage.c index 5e6cf7dd52..cea4ff5155 100644 --- a/src/mainboard/system76/adl/variants/oryp9/romstage.c +++ b/src/mainboard/system76/adl/variants/oryp9/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -17,6 +19,14 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/bonw14/Kconfig b/src/mainboard/system76/bonw14/Kconfig index 2cc814a3a7..77842e493e 100644 --- a/src/mainboard/system76/bonw14/Kconfig +++ b/src/mainboard/system76/bonw14/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_16384 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC diff --git a/src/mainboard/system76/bonw14/devicetree.cb b/src/mainboard/system76/bonw14/devicetree.cb index 9f2d35a993..d4d9c6d318 100644 --- a/src/mainboard/system76/bonw14/devicetree.cb +++ b/src/mainboard/system76/bonw14/devicetree.cb @@ -58,11 +58,12 @@ chip soc/intel/cannonlake # PCI Express Graphics #0 x16, Clock 7 (NVIDIA GPU) register "PcieClkSrcUsage[7]" = "0x40" register "PcieClkSrcClkReq[7]" = "7" - - device pci 00.0 on end # VGA controller - device pci 00.1 on end # Audio device - device pci 00.2 on end # USB xHCI Host controller - device pci 00.3 on end # USB Type-C UCSI controller + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller + end end device ref dptf on end device ref thermal on end diff --git a/src/mainboard/system76/gaze15/Kconfig b/src/mainboard/system76/gaze15/Kconfig index ea0ef2ded7..6a3cd7adc9 100644 --- a/src/mainboard/system76/gaze15/Kconfig +++ b/src/mainboard/system76/gaze15/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_16384 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select EC_SYSTEM76_EC select EC_SYSTEM76_EC_DGPU diff --git a/src/mainboard/system76/gaze15/Makefile.mk b/src/mainboard/system76/gaze15/Makefile.mk index 72f13667d3..ab7df6c275 100644 --- a/src/mainboard/system76/gaze15/Makefile.mk +++ b/src/mainboard/system76/gaze15/Makefile.mk @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/gaze15/acpi/mainboard.asl b/src/mainboard/system76/gaze15/acpi/mainboard.asl index b235437c25..610cdd12ba 100644 --- a/src/mainboard/system76/gaze15/acpi/mainboard.asl +++ b/src/mainboard/system76/gaze15/acpi/mainboard.asl @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include + #define EC_GPE_SCI 0x03 /* GPP_K3 */ #define EC_GPE_SWI 0x06 /* GPP_K6 */ #include @@ -8,6 +10,10 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + Device (PEGP) { + Name (_ADR, CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 16) + #include + } } } diff --git a/src/mainboard/system76/gaze15/devicetree.cb b/src/mainboard/system76/gaze15/devicetree.cb index be36abf73f..e2ea5fda73 100644 --- a/src/mainboard/system76/gaze15/devicetree.cb +++ b/src/mainboard/system76/gaze15/devicetree.cb @@ -54,6 +54,12 @@ chip soc/intel/cannonlake # PCI Express Graphics #0 x16, Clock 8 (NVIDIA GPU) register "PcieClkSrcUsage[8]" = "0x40" register "PcieClkSrcClkReq[8]" = "8" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller + end end device ref igpu on register "gfx" = "GMA_DEFAULT_PANEL(0)" diff --git a/src/mainboard/system76/gaze15/romstage.c b/src/mainboard/system76/gaze15/romstage.c index 02634ba2ad..fdb208b88d 100644 --- a/src/mainboard/system76/gaze15/romstage.c +++ b/src/mainboard/system76/gaze15/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include static const struct cnl_mb_cfg memcfg = { .spd[0] = { @@ -20,5 +22,17 @@ static const struct cnl_mb_cfg memcfg = { void mainboard_memory_init_params(FSPM_UPD *memupd) { + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + memupd->FspmConfig.PrimaryDisplay = 0; + cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg); } diff --git a/src/mainboard/system76/gaze15/variants/gaze14/include/variant/gpio.h b/src/mainboard/system76/gaze15/variants/gaze14/include/variant/gpio.h new file mode 100644 index 0000000000..d1647fc437 --- /dev/null +++ b/src/mainboard/system76/gaze15/variants/gaze14/include/variant/gpio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_K21 +#define DGPU_SSID 0x85501558 + +#ifndef __ACPI__ +void variant_configure_early_gpios(void); +void variant_configure_gpios(void); +#endif + +#endif diff --git a/src/mainboard/system76/gaze15/variants/gaze15/include/variant/gpio.h b/src/mainboard/system76/gaze15/variants/gaze15/include/variant/gpio.h new file mode 100644 index 0000000000..0bfd82ed79 --- /dev/null +++ b/src/mainboard/system76/gaze15/variants/gaze15/include/variant/gpio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_K21 +#define DGPU_SSID 0x85201558 + +#ifndef __ACPI__ +void variant_configure_early_gpios(void); +void variant_configure_gpios(void); +#endif + +#endif diff --git a/src/mainboard/system76/oryp5/Kconfig b/src/mainboard/system76/oryp5/Kconfig index a74bea2339..28f2fc7bbd 100644 --- a/src/mainboard/system76/oryp5/Kconfig +++ b/src/mainboard/system76/oryp5/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_16384 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC diff --git a/src/mainboard/system76/oryp5/acpi/mainboard.asl b/src/mainboard/system76/oryp5/acpi/mainboard.asl index 17d2221ab4..f816e3f2da 100644 --- a/src/mainboard/system76/oryp5/acpi/mainboard.asl +++ b/src/mainboard/system76/oryp5/acpi/mainboard.asl @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include + #define EC_GPE_SCI 0x17 /* GPP_B23 */ #define EC_GPE_SWI 0x26 /* GPP_G6 */ #include @@ -9,6 +11,10 @@ Scope (\_SB) #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + Device (PEGP) { + Name (_ADR, CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 16) + #include + } } } diff --git a/src/mainboard/system76/oryp5/devicetree.cb b/src/mainboard/system76/oryp5/devicetree.cb index b72d9ba854..0095355492 100644 --- a/src/mainboard/system76/oryp5/devicetree.cb +++ b/src/mainboard/system76/oryp5/devicetree.cb @@ -62,6 +62,12 @@ chip soc/intel/cannonlake # PCI Express Graphics #0 x16, Clock 8 (NVIDIA GPU) register "PcieClkSrcUsage[8]" = "0x40" register "PcieClkSrcClkReq[8]" = "8" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller + end end device ref igpu on register "gfx" = "GMA_DEFAULT_PANEL(0)" diff --git a/src/mainboard/system76/oryp5/include/mainboard/gpio.h b/src/mainboard/system76/oryp5/include/mainboard/gpio.h index c6393beebb..2bfbd100af 100644 --- a/src/mainboard/system76/oryp5/include/mainboard/gpio.h +++ b/src/mainboard/system76/oryp5/include/mainboard/gpio.h @@ -3,7 +3,16 @@ #ifndef MAINBOARD_GPIO_H #define MAINBOARD_GPIO_H +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_C12 +#define DGPU_SSID 0x95e61558 + +#ifndef __ACPI__ void mainboard_configure_early_gpios(void); void mainboard_configure_gpios(void); +#endif #endif diff --git a/src/mainboard/system76/oryp5/romstage.c b/src/mainboard/system76/oryp5/romstage.c index 455a2bb919..ec24f532b2 100644 --- a/src/mainboard/system76/oryp5/romstage.c +++ b/src/mainboard/system76/oryp5/romstage.c @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include #include #include @@ -20,6 +22,18 @@ static const struct cnl_mb_cfg memcfg = { void mainboard_memory_init_params(FSPM_UPD *memupd) { + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + memupd->FspmConfig.PrimaryDisplay = 0; + // Allow memory speeds higher than 2666 MT/s memupd->FspmConfig.SaOcSupport = 1; diff --git a/src/mainboard/system76/oryp6/Kconfig b/src/mainboard/system76/oryp6/Kconfig index 8fd023d56a..9bbd624bbe 100644 --- a/src/mainboard/system76/oryp6/Kconfig +++ b/src/mainboard/system76/oryp6/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_16384 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC diff --git a/src/mainboard/system76/oryp6/Makefile.mk b/src/mainboard/system76/oryp6/Makefile.mk index ab8e965d87..af0b83b615 100644 --- a/src/mainboard/system76/oryp6/Makefile.mk +++ b/src/mainboard/system76/oryp6/Makefile.mk @@ -1,6 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/oryp6/acpi/mainboard.asl b/src/mainboard/system76/oryp6/acpi/mainboard.asl index b235437c25..610cdd12ba 100644 --- a/src/mainboard/system76/oryp6/acpi/mainboard.asl +++ b/src/mainboard/system76/oryp6/acpi/mainboard.asl @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include + #define EC_GPE_SCI 0x03 /* GPP_K3 */ #define EC_GPE_SWI 0x06 /* GPP_K6 */ #include @@ -8,6 +10,10 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + Device (PEGP) { + Name (_ADR, CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 16) + #include + } } } diff --git a/src/mainboard/system76/oryp6/devicetree.cb b/src/mainboard/system76/oryp6/devicetree.cb index bcb75d0b3c..7b8e6a2329 100644 --- a/src/mainboard/system76/oryp6/devicetree.cb +++ b/src/mainboard/system76/oryp6/devicetree.cb @@ -59,6 +59,12 @@ chip soc/intel/cannonlake # PCI Express Graphics #0 x16, Clock 8 (NVIDIA GPU) register "PcieClkSrcUsage[8]" = "0x40" register "PcieClkSrcClkReq[8]" = "8" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller + end end device ref igpu on register "gfx" = "GMA_DEFAULT_PANEL(0)" diff --git a/src/mainboard/system76/oryp6/romstage.c b/src/mainboard/system76/oryp6/romstage.c index 8ea791a2d1..44da3d8c46 100644 --- a/src/mainboard/system76/oryp6/romstage.c +++ b/src/mainboard/system76/oryp6/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include #include static const struct cnl_mb_cfg memcfg = { @@ -21,6 +23,18 @@ static const struct cnl_mb_cfg memcfg = { void mainboard_memory_init_params(FSPM_UPD *memupd) { + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + memupd->FspmConfig.PrimaryDisplay = 0; + variant_configure_fspm(memupd); cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg); diff --git a/src/mainboard/system76/oryp6/variants/oryp6/include/variant/gpio.h b/src/mainboard/system76/oryp6/variants/oryp6/include/variant/gpio.h new file mode 100644 index 0000000000..697e1ecf51 --- /dev/null +++ b/src/mainboard/system76/oryp6/variants/oryp6/include/variant/gpio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_K21 +#define DGPU_SSID 0x50d31558 + +#ifndef __ACPI__ +void variant_configure_early_gpios(void); +void variant_configure_gpios(void); +#endif + +#endif diff --git a/src/mainboard/system76/oryp6/variants/oryp7/include/variant/gpio.h b/src/mainboard/system76/oryp6/variants/oryp7/include/variant/gpio.h new file mode 100644 index 0000000000..6e1d7dfa12 --- /dev/null +++ b/src/mainboard/system76/oryp6/variants/oryp7/include/variant/gpio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_K21 +#define DGPU_SSID 0x65e51558 + +#ifndef __ACPI__ +void variant_configure_early_gpios(void); +void variant_configure_gpios(void); +#endif + +#endif diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index f0799072b1..8533f14906 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -28,6 +28,8 @@ config BOARD_SYSTEM76_RPL_COMMON config BOARD_SYSTEM76_ADDW3 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select MAINBOARD_USES_IFD_GBE_REGION @@ -36,12 +38,16 @@ config BOARD_SYSTEM76_ADDW3 config BOARD_SYSTEM76_ADDW4 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S config BOARD_SYSTEM76_BONW15 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG @@ -49,6 +55,8 @@ config BOARD_SYSTEM76_BONW15 config BOARD_SYSTEM76_BONW15_B select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S @@ -65,6 +73,8 @@ config BOARD_SYSTEM76_GALP7 config BOARD_SYSTEM76_GAZE18 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select SOC_INTEL_ALDERLAKE_PCH_P @@ -76,12 +86,16 @@ config BOARD_SYSTEM76_LEMP12 config BOARD_SYSTEM76_ORYP11 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select SOC_INTEL_ALDERLAKE_PCH_P select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES config BOARD_SYSTEM76_ORYP12 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_I2C_TAS5825M select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU @@ -90,6 +104,8 @@ config BOARD_SYSTEM76_ORYP12 config BOARD_SYSTEM76_SERW13 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG @@ -158,6 +174,17 @@ config CONSOLE_POST config D3COLD_SUPPORT default n +config DRIVERS_GFX_NVIDIA_BRIDGE + default 0x02 if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP + default 45 if BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 + default 55 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_ADDW4 || BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_SERW13 + default 80 if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX + default 25 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_ADDW4 || BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B || BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 || BOARD_SYSTEM76_SERW13 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" diff --git a/src/mainboard/system76/rpl/Makefile.mk b/src/mainboard/system76/rpl/Makefile.mk index 2c8dfba322..a5011cdba0 100644 --- a/src/mainboard/system76/rpl/Makefile.mk +++ b/src/mainboard/system76/rpl/Makefile.mk @@ -2,6 +2,10 @@ CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +ifeq ($(CONFIG_DRIVERS_GFX_NVIDIA),y) +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include +endif + bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/rpl/acpi/mainboard.asl b/src/mainboard/system76/rpl/acpi/mainboard.asl index c982a9ee4c..63ccf020d5 100644 --- a/src/mainboard/system76/rpl/acpi/mainboard.asl +++ b/src/mainboard/system76/rpl/acpi/mainboard.asl @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#if CONFIG(DRIVERS_GFX_NVIDIA) +#include +#endif + #define EC_GPE_SCI 0x6E #define EC_GPE_SWI 0x6B #include @@ -8,5 +12,17 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + +#if CONFIG(DRIVERS_GFX_NVIDIA) +#if CONFIG(SOC_INTEL_ALDERLAKE_PCH_P) || CONFIG(BOARD_SYSTEM76_BONW15) || CONFIG(BOARD_SYSTEM76_BONW15_B) + Scope (PEG2) { + #include + } +#else + Scope (PEG1) { + #include + } +#endif +#endif // CONFIG(DRIVERS_GFX_NVIDIA) } } diff --git a/src/mainboard/system76/rpl/variants/addw3/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/addw3/include/variant/gpio.h new file mode 100644 index 0000000000..9ce0d6701c --- /dev/null +++ b/src/mainboard/system76/rpl/variants/addw3/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_GC6 GPP_F8 +#define DGPU_SSID 0xa6711558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/addw3/romstage.c b/src/mainboard/system76/rpl/variants/addw3/romstage.c index 30a904544c..3992095a65 100644 --- a/src/mainboard/system76/rpl/variants/addw3/romstage.c +++ b/src/mainboard/system76/rpl/variants/addw3/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/rpl/variants/addw4/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/addw4/include/variant/gpio.h new file mode 100644 index 0000000000..2ad3dfa0c4 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/addw4/include/variant/gpio.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_SSID 0x03531558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/addw4/romstage.c b/src/mainboard/system76/rpl/variants/addw4/romstage.c index fe9103240c..3f9d962b50 100644 --- a/src/mainboard/system76/rpl/variants/addw4/romstage.c +++ b/src/mainboard/system76/rpl/variants/addw4/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to hybrid graphics mupd->FspmConfig.PrimaryDisplay = 4; diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/bonw15-b/include/variant/gpio.h new file mode 100644 index 0000000000..be865bb20d --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F22 +#define DGPU_GC6 GPP_F8 +#define DGPU_SSID 0x37021558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/romstage.c b/src/mainboard/system76/rpl/variants/bonw15-b/romstage.c index 30a904544c..3992095a65 100644 --- a/src/mainboard/system76/rpl/variants/bonw15-b/romstage.c +++ b/src/mainboard/system76/rpl/variants/bonw15-b/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/rpl/variants/bonw15/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/bonw15/include/variant/gpio.h new file mode 100644 index 0000000000..be865bb20d --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F22 +#define DGPU_GC6 GPP_F8 +#define DGPU_SSID 0x37021558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/bonw15/romstage.c b/src/mainboard/system76/rpl/variants/bonw15/romstage.c index 30a904544c..3992095a65 100644 --- a/src/mainboard/system76/rpl/variants/bonw15/romstage.c +++ b/src/mainboard/system76/rpl/variants/bonw15/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/rpl/variants/gaze18/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/gaze18/include/variant/gpio.h new file mode 100644 index 0000000000..612710995c --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze18/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_F13 +#define DGPU_SSID 0x56301558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/gaze18/romstage.c b/src/mainboard/system76/rpl/variants/gaze18/romstage.c index 1e597c72a6..2c8a6737bb 100644 --- a/src/mainboard/system76/rpl/variants/gaze18/romstage.c +++ b/src/mainboard/system76/rpl/variants/gaze18/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -19,6 +21,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/rpl/variants/oryp11/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/oryp11/include/variant/gpio.h new file mode 100644 index 0000000000..070f551819 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/oryp11/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_F13 +#define DGPU_SSID 0x66a21558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/oryp11/romstage.c b/src/mainboard/system76/rpl/variants/oryp11/romstage.c index 1e597c72a6..2c8a6737bb 100644 --- a/src/mainboard/system76/rpl/variants/oryp11/romstage.c +++ b/src/mainboard/system76/rpl/variants/oryp11/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -19,6 +21,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/rpl/variants/oryp12/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/oryp12/include/variant/gpio.h new file mode 100644 index 0000000000..1ac33c5304 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/oryp12/include/variant/gpio.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_SSID 0x66a61558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/oryp12/romstage.c b/src/mainboard/system76/rpl/variants/oryp12/romstage.c index fe9103240c..3f9d962b50 100644 --- a/src/mainboard/system76/rpl/variants/oryp12/romstage.c +++ b/src/mainboard/system76/rpl/variants/oryp12/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to hybrid graphics mupd->FspmConfig.PrimaryDisplay = 4; diff --git a/src/mainboard/system76/rpl/variants/serw13/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/serw13/include/variant/gpio.h new file mode 100644 index 0000000000..014f22df51 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/serw13/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_GC6 GPP_A11 +#define DGPU_SSID 0xd5021558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/serw13/romstage.c b/src/mainboard/system76/rpl/variants/serw13/romstage.c index 30a904544c..f58abadc3d 100644 --- a/src/mainboard/system76/rpl/variants/serw13/romstage.c +++ b/src/mainboard/system76/rpl/variants/serw13/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,14 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/tgl-h/Kconfig b/src/mainboard/system76/tgl-h/Kconfig index b3cde756d8..185d95c3f0 100644 --- a/src/mainboard/system76/tgl-h/Kconfig +++ b/src/mainboard/system76/tgl-h/Kconfig @@ -9,6 +9,7 @@ config BOARD_SPECIFIC_OPTIONS select DRIVERS_GENERIC_BAYHUB_LV2 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select DRIVERS_I2C_TAS5825M if BOARD_SYSTEM76_ORYP8 select EC_SYSTEM76_EC diff --git a/src/mainboard/system76/tgl-h/Makefile.mk b/src/mainboard/system76/tgl-h/Makefile.mk index 7debd0d8c9..f2fda437b5 100644 --- a/src/mainboard/system76/tgl-h/Makefile.mk +++ b/src/mainboard/system76/tgl-h/Makefile.mk @@ -1,6 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/tgl-h/acpi/mainboard.asl b/src/mainboard/system76/tgl-h/acpi/mainboard.asl index c982a9ee4c..1cf2a28bca 100644 --- a/src/mainboard/system76/tgl-h/acpi/mainboard.asl +++ b/src/mainboard/system76/tgl-h/acpi/mainboard.asl @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include + #define EC_GPE_SCI 0x6E #define EC_GPE_SWI 0x6B #include @@ -8,5 +10,8 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + Scope (PEG1) { + #include + } } } diff --git a/src/mainboard/system76/tgl-h/romstage.c b/src/mainboard/system76/tgl-h/romstage.c index f69bae98eb..8e30435923 100644 --- a/src/mainboard/system76/tgl-h/romstage.c +++ b/src/mainboard/system76/tgl-h/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include #include static const struct mb_cfg board_cfg = { @@ -21,9 +23,21 @@ static const struct mem_spd spd_info = { void mainboard_memory_init_params(FSPM_UPD *mupd) { - variant_memory_init_params(mupd); - const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + mupd->FspmConfig.PrimaryDisplay = 0; + + variant_memory_init_params(mupd); + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); } diff --git a/src/mainboard/system76/addw1/include/variant/gpio.h b/src/mainboard/system76/tgl-h/variants/gaze16-3050/include/variant/gpio.h similarity index 53% rename from src/mainboard/system76/addw1/include/variant/gpio.h rename to src/mainboard/system76/tgl-h/variants/gaze16-3050/include/variant/gpio.h index 95d576294f..27e1dc3ef3 100644 --- a/src/mainboard/system76/addw1/include/variant/gpio.h +++ b/src/mainboard/system76/tgl-h/variants/gaze16-3050/include/variant/gpio.h @@ -3,7 +3,16 @@ #ifndef VARIANT_GPIO_H #define VARIANT_GPIO_H +#include + +#define DGPU_RST_N GPP_F8 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_GC6 GPP_K11 +#define DGPU_SSID 0x50151558 + +#ifndef __ACPI__ void variant_configure_early_gpios(void); void variant_configure_gpios(void); +#endif #endif diff --git a/src/mainboard/system76/tgl-h/variants/gaze16-3050/overridetree.cb b/src/mainboard/system76/tgl-h/variants/gaze16-3050/overridetree.cb index 8382c084a8..63783d73b1 100644 --- a/src/mainboard/system76/tgl-h/variants/gaze16-3050/overridetree.cb +++ b/src/mainboard/system76/tgl-h/variants/gaze16-3050/overridetree.cb @@ -8,15 +8,11 @@ chip soc/intel/tigerlake # PCIe PEG2 (remapped to PEG1 by FSP) x8, Clock 0 (DGPU) register "PcieClkSrcUsage[0]" = "0x42" register "PcieClkSrcClkReq[0]" = "0" - chip soc/intel/common/block/pcie/rtd3 - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F9)" # DGPU_PWR_EN - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F8)" # DGPU_RST#_PCH - register "enable_delay_ms" = "16" - register "enable_off_delay_ms" = "4" - register "reset_delay_ms" = "10" - register "reset_off_delay_ms" = "4" - register "srcclk_pin" = "0" # GFX_CLKREQ0# - device generic 0 on end + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller end end device ref igpu on diff --git a/src/mainboard/system76/gaze15/include/variant/gpio.h b/src/mainboard/system76/tgl-h/variants/gaze16-3060/include/variant/gpio.h similarity index 53% rename from src/mainboard/system76/gaze15/include/variant/gpio.h rename to src/mainboard/system76/tgl-h/variants/gaze16-3060/include/variant/gpio.h index 95d576294f..f3f8b01f59 100644 --- a/src/mainboard/system76/gaze15/include/variant/gpio.h +++ b/src/mainboard/system76/tgl-h/variants/gaze16-3060/include/variant/gpio.h @@ -3,7 +3,16 @@ #ifndef VARIANT_GPIO_H #define VARIANT_GPIO_H +#include + +#define DGPU_RST_N GPP_F8 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_GC6 GPP_K11 +#define DGPU_SSID 0x50e11558 + +#ifndef __ACPI__ void variant_configure_early_gpios(void); void variant_configure_gpios(void); +#endif #endif diff --git a/src/mainboard/system76/tgl-h/variants/gaze16-3060/overridetree.cb b/src/mainboard/system76/tgl-h/variants/gaze16-3060/overridetree.cb index 2915989eef..60816d571f 100644 --- a/src/mainboard/system76/tgl-h/variants/gaze16-3060/overridetree.cb +++ b/src/mainboard/system76/tgl-h/variants/gaze16-3060/overridetree.cb @@ -8,15 +8,11 @@ chip soc/intel/tigerlake # PCIe PEG1 x16, Clock 9 (DGPU) register "PcieClkSrcUsage[9]" = "0x41" register "PcieClkSrcClkReq[9]" = "9" - chip soc/intel/common/block/pcie/rtd3 - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F9)" # DGPU_PWR_EN - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F8)" # DGPU_RST#_PCH - register "enable_delay_ms" = "16" - register "enable_off_delay_ms" = "4" - register "reset_delay_ms" = "10" - register "reset_off_delay_ms" = "4" - register "srcclk_pin" = "9" # PEG_CLKREQ# - device generic 0 on end + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller end end device ref igpu on diff --git a/src/mainboard/system76/oryp6/include/variant/gpio.h b/src/mainboard/system76/tgl-h/variants/oryp8/include/variant/gpio.h similarity index 53% rename from src/mainboard/system76/oryp6/include/variant/gpio.h rename to src/mainboard/system76/tgl-h/variants/oryp8/include/variant/gpio.h index 95d576294f..33333f0b35 100644 --- a/src/mainboard/system76/oryp6/include/variant/gpio.h +++ b/src/mainboard/system76/tgl-h/variants/oryp8/include/variant/gpio.h @@ -3,7 +3,16 @@ #ifndef VARIANT_GPIO_H #define VARIANT_GPIO_H +#include + +#define DGPU_RST_N GPP_F8 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_GC6 GPP_K11 +#define DGPU_SSID 0x65f11558 + +#ifndef __ACPI__ void variant_configure_early_gpios(void); void variant_configure_gpios(void); +#endif #endif diff --git a/src/mainboard/system76/tgl-h/variants/oryp8/overridetree.cb b/src/mainboard/system76/tgl-h/variants/oryp8/overridetree.cb index 331fe179a7..5cee4eff90 100644 --- a/src/mainboard/system76/tgl-h/variants/oryp8/overridetree.cb +++ b/src/mainboard/system76/tgl-h/variants/oryp8/overridetree.cb @@ -21,15 +21,11 @@ chip soc/intel/tigerlake # PCIe PEG1 x16, Clock 9 (DGPU) register "PcieClkSrcUsage[9]" = "0x41" register "PcieClkSrcClkReq[9]" = "9" - chip soc/intel/common/block/pcie/rtd3 - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F9)" # DGPU_PWR_EN - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F8)" # DGPU_RST#_PCH - register "enable_delay_ms" = "16" - register "enable_off_delay_ms" = "4" - register "reset_delay_ms" = "10" - register "reset_off_delay_ms" = "4" - register "srcclk_pin" = "9" # PEG_CLKREQ# - device generic 0 on end + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller end end device ref peg0 on diff --git a/src/mainboard/system76/tgl-u/Kconfig b/src/mainboard/system76/tgl-u/Kconfig index 88ce646df7..8da727eb59 100644 --- a/src/mainboard/system76/tgl-u/Kconfig +++ b/src/mainboard/system76/tgl-u/Kconfig @@ -9,6 +9,7 @@ config BOARD_SPECIFIC_OPTIONS select DRIVERS_GENERIC_BAYHUB_LV2 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA if BOARD_SYSTEM76_GALP5 select DRIVERS_I2C_HID select DRIVERS_INTEL_PMC select DRIVERS_INTEL_USB4_RETIMER @@ -74,4 +75,15 @@ config UART_FOR_CONSOLE config USE_PM_ACPI_TIMER default n +# For galp5 with dGPU +if DRIVERS_GFX_NVIDIA + +config ONBOARD_VGA_IS_PRIMARY + default y + +config DRIVERS_GFX_NVIDIA_BRIDGE + default 0x1c + +endif # DRIVERS_GFX_NVIDIA + endif diff --git a/src/mainboard/system76/tgl-u/acpi/mainboard.asl b/src/mainboard/system76/tgl-u/acpi/mainboard.asl index c982a9ee4c..6adceba1fd 100644 --- a/src/mainboard/system76/tgl-u/acpi/mainboard.asl +++ b/src/mainboard/system76/tgl-u/acpi/mainboard.asl @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#if CONFIG(BOARD_SYSTEM76_GALP5) +#include +#endif + #define EC_GPE_SCI 0x6E #define EC_GPE_SWI 0x6B #include @@ -8,5 +12,10 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" +#if CONFIG(BOARD_SYSTEM76_GALP5) + Scope (RP01) { // Remapped from RP05 + #include + } +#endif } } diff --git a/src/mainboard/system76/tgl-u/variants/galp5/overridetree.cb b/src/mainboard/system76/tgl-u/variants/galp5/overridetree.cb index 2d5dc150d6..afceaa1023 100644 --- a/src/mainboard/system76/tgl-u/variants/galp5/overridetree.cb +++ b/src/mainboard/system76/tgl-u/variants/galp5/overridetree.cb @@ -147,15 +147,11 @@ chip soc/intel/tigerlake register "PcieRpLtrEnable[4]" = "true" register "PcieClkSrcUsage[2]" = "4" register "PcieClkSrcClkReq[2]" = "2" - chip soc/intel/common/block/pcie/rtd3 - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_U5)" # DGPU_PWR_EN - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_U4)" # DGPU_RST#_PCH - register "enable_delay_ms" = "16" - register "enable_off_delay_ms" = "4" - register "reset_delay_ms" = "10" - register "reset_off_delay_ms" = "4" - register "srcclk_pin" = "2" # PEG_CLKREQ# - device generic 0 on end + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller end end device ref pcie_rp9 on diff --git a/src/mainboard/system76/tgl-u/variants/galp5/romstage.c b/src/mainboard/system76/tgl-u/variants/galp5/romstage.c index eb4fd3974b..e747521789 100644 --- a/src/mainboard/system76/tgl-u/variants/galp5/romstage.c +++ b/src/mainboard/system76/tgl-u/variants/galp5/romstage.c @@ -1,8 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -18,5 +19,17 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + mupd->FspmConfig.PrimaryDisplay = 0; + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); } From 4bdf8dfdf1ed7ca6ebe52afea8fc5d5cd7ca3a4e Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Fri, 31 May 2024 13:59:33 -0600 Subject: [PATCH 773/789] mb/system76/rpl: Enable discrete TBT device The HX boards, using PCH-S, use a discrete Thunderbolt device (Intel Maple Ridge), as opposed to a built-in one like the boards using PCH-P. Fixes Thunderbolt on RPL-HX boards using the Maple Ridge controller. Change-Id: I53d18f3ec5a084431e1113782c791bcb42728350 Signed-off-by: Tim Crawford --- src/mainboard/system76/rpl/Kconfig | 1 + src/mainboard/system76/rpl/variants/addw3/overridetree.cb | 3 +++ src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb | 3 +++ src/mainboard/system76/rpl/variants/bonw15/overridetree.cb | 3 +++ src/mainboard/system76/rpl/variants/oryp12/overridetree.cb | 3 +++ src/mainboard/system76/rpl/variants/serw13/overridetree.cb | 3 +++ 6 files changed, 16 insertions(+) diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index 8533f14906..0f331b83d5 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -57,6 +57,7 @@ config BOARD_SYSTEM76_BONW15_B select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S diff --git a/src/mainboard/system76/rpl/variants/addw3/overridetree.cb b/src/mainboard/system76/rpl/variants/addw3/overridetree.cb index 24c272c746..903421c586 100644 --- a/src/mainboard/system76/rpl/variants/addw3/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/addw3/overridetree.cb @@ -103,6 +103,9 @@ chip soc/intel/alderlake .clk_req = 15, .flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR, }" + chip drivers/intel/dtbt + device pci 00.0 on end + end end device ref pcie_rp25 on diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb b/src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb index 0c455f60f7..a633217794 100644 --- a/src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb @@ -97,6 +97,9 @@ chip soc/intel/alderlake .clk_req = 13, .flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR, }" + chip drivers/intel/dtbt + device pci 00.0 on end + end end device ref pcie_rp21 on diff --git a/src/mainboard/system76/rpl/variants/bonw15/overridetree.cb b/src/mainboard/system76/rpl/variants/bonw15/overridetree.cb index a1191a5434..e3e59e3239 100644 --- a/src/mainboard/system76/rpl/variants/bonw15/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/bonw15/overridetree.cb @@ -99,6 +99,9 @@ chip soc/intel/alderlake .clk_req = 15, .flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR, }" + chip drivers/intel/dtbt + device pci 00.0 on end + end end device ref pcie_rp21 on diff --git a/src/mainboard/system76/rpl/variants/oryp12/overridetree.cb b/src/mainboard/system76/rpl/variants/oryp12/overridetree.cb index 54f42bee32..958ab038ad 100644 --- a/src/mainboard/system76/rpl/variants/oryp12/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/oryp12/overridetree.cb @@ -116,6 +116,9 @@ chip soc/intel/alderlake .clk_req = 15, .flags = PCIE_RP_LTR | PCIE_RP_HOTPLUG, }" + chip drivers/intel/dtbt + device pci 00.0 on end + end end end end diff --git a/src/mainboard/system76/rpl/variants/serw13/overridetree.cb b/src/mainboard/system76/rpl/variants/serw13/overridetree.cb index cc89764c7f..99ddd63cb7 100644 --- a/src/mainboard/system76/rpl/variants/serw13/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/serw13/overridetree.cb @@ -108,6 +108,9 @@ chip soc/intel/alderlake .clk_req = 15, .flags = PCIE_RP_LTR | PCIE_RP_HOTPLUG, // XXX: AER causes UnsupReq warnings }" + chip drivers/intel/dtbt + device pci 00.0 on end + end end end end From 5e5e3f0b01549d9ba373c463127d4eb4c34cbcc6 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Mon, 8 Jan 2024 16:41:32 -0700 Subject: [PATCH 774/789] mb/system76: Enable S0ix for darp8/darp9 The newer batch of these boards do not de-assert VW PLTRST# on S3 resume, causes the units to not power on in the EC code. Switch them to S0ix by default, but leave S3 available. Change-Id: I95337c1391102db9e020e82bdd938659c1a4f905 Signed-off-by: Tim Crawford --- src/mainboard/system76/adl/variants/darp8/overridetree.cb | 2 ++ src/mainboard/system76/rpl/variants/darp9/overridetree.cb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/mainboard/system76/adl/variants/darp8/overridetree.cb b/src/mainboard/system76/adl/variants/darp8/overridetree.cb index 3af580229b..d9c1a713cc 100644 --- a/src/mainboard/system76/adl/variants/darp8/overridetree.cb +++ b/src/mainboard/system76/adl/variants/darp8/overridetree.cb @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only chip soc/intel/alderlake + register "s0ix_enable" = "1" + register "power_limits_config[ADL_P_282_442_482_28W_CORE]" = "{ .tdp_pl1_override = 20, .tdp_pl2_override = 56, diff --git a/src/mainboard/system76/rpl/variants/darp9/overridetree.cb b/src/mainboard/system76/rpl/variants/darp9/overridetree.cb index 3dc27864fe..b83ad74832 100644 --- a/src/mainboard/system76/rpl/variants/darp9/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/darp9/overridetree.cb @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only chip soc/intel/alderlake + register "s0ix_enable" = "1" + register "power_limits_config[RPL_P_682_482_282_28W_CORE]" = "{ .tdp_pl1_override = 20, .tdp_pl2_override = 56, From 0a8f4015df3e1fb4d00a0a1051ce7f2c4ad8c198 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Wed, 10 Jan 2024 08:55:50 -0700 Subject: [PATCH 775/789] mb/system76: Add custom CMOS default for darp8,darp9 Since these boards will use S0ix they need to leave CSME enabled for the CPU to reach C10. Change-Id: I70c908402c9964508bb9c439d48d24773f5a35ab Signed-off-by: Tim Crawford --- src/mainboard/system76/adl/Kconfig | 4 ++++ src/mainboard/system76/adl/cmos-csme.default | 3 +++ src/mainboard/system76/rpl/Kconfig | 4 ++++ src/mainboard/system76/rpl/cmos-csme.default | 3 +++ 4 files changed, 14 insertions(+) create mode 100644 src/mainboard/system76/adl/cmos-csme.default create mode 100644 src/mainboard/system76/rpl/cmos-csme.default diff --git a/src/mainboard/system76/adl/Kconfig b/src/mainboard/system76/adl/Kconfig index 72f2d46a02..60ecc96bb9 100644 --- a/src/mainboard/system76/adl/Kconfig +++ b/src/mainboard/system76/adl/Kconfig @@ -104,6 +104,10 @@ config MAINBOARD_VERSION default "oryp9" if BOARD_SYSTEM76_ORYP9 default "oryp10" if BOARD_SYSTEM76_ORYP10 +config CMOS_DEFAULT_FILE + default "src/mainboard/\$(MAINBOARDDIR)/cmos-csme.default" if BOARD_SYSTEM76_DARP8 + default "src/mainboard/\$(MAINBOARDDIR)/cmos.default" + config CONSOLE_POST default y diff --git a/src/mainboard/system76/adl/cmos-csme.default b/src/mainboard/system76/adl/cmos-csme.default new file mode 100644 index 0000000000..62715bc6ba --- /dev/null +++ b/src/mainboard/system76/adl/cmos-csme.default @@ -0,0 +1,3 @@ +boot_option=Fallback +debug_level=Debug +me_state=Enable diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index 0f331b83d5..15f47ba7ea 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -169,6 +169,10 @@ config MAINBOARD_VERSION default "oryp12" if BOARD_SYSTEM76_ORYP12 default "serw13" if BOARD_SYSTEM76_SERW13 +config CMOS_DEFAULT_FILE + default "src/mainboard/\$(MAINBOARDDIR)/cmos-csme.default" if BOARD_SYSTEM76_DARP9 + default "src/mainboard/\$(MAINBOARDDIR)/cmos.default" + config CONSOLE_POST default y diff --git a/src/mainboard/system76/rpl/cmos-csme.default b/src/mainboard/system76/rpl/cmos-csme.default new file mode 100644 index 0000000000..62715bc6ba --- /dev/null +++ b/src/mainboard/system76/rpl/cmos-csme.default @@ -0,0 +1,3 @@ +boot_option=Fallback +debug_level=Debug +me_state=Enable From 5cfe60f0fbd038f323cad7c6468ea493bdb741dd Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Mon, 12 May 2025 12:23:24 -0600 Subject: [PATCH 776/789] mb/system76/adl,rpl: Add missing SPDX IDs Change-Id: I5873e2bd61b76331ed88023260ece3ab9c3c3eff Signed-off-by: Tim Crawford --- src/mainboard/system76/adl/cmos-csme.default | 2 ++ src/mainboard/system76/rpl/cmos-csme.default | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/mainboard/system76/adl/cmos-csme.default b/src/mainboard/system76/adl/cmos-csme.default index 62715bc6ba..d61046df6b 100644 --- a/src/mainboard/system76/adl/cmos-csme.default +++ b/src/mainboard/system76/adl/cmos-csme.default @@ -1,3 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + boot_option=Fallback debug_level=Debug me_state=Enable diff --git a/src/mainboard/system76/rpl/cmos-csme.default b/src/mainboard/system76/rpl/cmos-csme.default index 62715bc6ba..d61046df6b 100644 --- a/src/mainboard/system76/rpl/cmos-csme.default +++ b/src/mainboard/system76/rpl/cmos-csme.default @@ -1,3 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + boot_option=Fallback debug_level=Debug me_state=Enable From 3c2b7ceb612f6e157e1b99c9952c667b855eff07 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Thu, 29 May 2025 10:51:05 -0600 Subject: [PATCH 777/789] mb/system76/rpl: addw4: Disable GPU Boost Disable feature as it causing GPU to fail under load, such as running FurMark as part of Phoronix Test Suite. Change-Id: I0b04cbd8fbab2ba8ff38281b91c83aa94c7e1bf1 Signed-off-by: Tim Crawford --- src/mainboard/system76/rpl/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index 15f47ba7ea..3772b04bdd 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -39,7 +39,7 @@ config BOARD_SYSTEM76_ADDW3 config BOARD_SYSTEM76_ADDW4 select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S From 5c6547d600bed48d826b9f5d3d1ef72891886a5d Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Fri, 30 May 2025 09:14:56 -0600 Subject: [PATCH 778/789] mb/system76/rpl: addw4: Reduce GPU Boost TPP value Change-Id: I291a806912f967fa797b5fae77c5fff6610733bf Signed-off-by: Tim Crawford --- src/mainboard/system76/rpl/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index 3772b04bdd..b9a30ef486 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -39,7 +39,7 @@ config BOARD_SYSTEM76_ADDW3 config BOARD_SYSTEM76_ADDW4 select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S @@ -183,8 +183,8 @@ config DRIVERS_GFX_NVIDIA_BRIDGE default 0x02 if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP - default 45 if BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 - default 55 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_ADDW4 || BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_SERW13 + default 45 if BOARD_SYSTEM76_ADDW4 || BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 + default 55 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_SERW13 default 80 if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX From 7a1d8053baaa61643ae102717272f4c97fff551d Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Thu, 19 Jun 2025 11:03:59 -0600 Subject: [PATCH 779/789] drivers/gfx/nvidia: Require ACPI Change-Id: Ifeec06c1c79216afe840eff2d9cb91a6d4d8d5a3 Signed-off-by: Tim Crawford --- src/drivers/gfx/nvidia/Kconfig | 1 + src/drivers/gfx/nvidia/nvidia.c | 13 +++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/drivers/gfx/nvidia/Kconfig b/src/drivers/gfx/nvidia/Kconfig index 4c9c7ff08c..eb2d60dff6 100644 --- a/src/drivers/gfx/nvidia/Kconfig +++ b/src/drivers/gfx/nvidia/Kconfig @@ -1,6 +1,7 @@ config DRIVERS_GFX_NVIDIA bool default n + depends on HAVE_ACPI_TABLES help Support for NVIDIA Optimus graphics diff --git a/src/drivers/gfx/nvidia/nvidia.c b/src/drivers/gfx/nvidia/nvidia.c index 09083e83b5..42d5db07f0 100644 --- a/src/drivers/gfx/nvidia/nvidia.c +++ b/src/drivers/gfx/nvidia/nvidia.c @@ -42,16 +42,13 @@ static struct pci_operations nvidia_device_ops_pci = { }; static struct device_operations nvidia_device_ops = { - .read_resources = nvidia_read_resources, - .set_resources = pci_dev_set_resources, - .enable_resources = pci_dev_enable_resources, -#if CONFIG(HAVE_ACPI_TABLES) + .read_resources = nvidia_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, .write_acpi_tables = pci_rom_write_acpi_tables, .acpi_fill_ssdt = pci_rom_ssdt, -#endif - .init = pci_dev_init, - .ops_pci = &nvidia_device_ops_pci, - + .init = pci_dev_init, + .ops_pci = &nvidia_device_ops_pci, }; static void nvidia_enable(struct device *dev) From e73a71878ec6f3bec772f7d044f88d30b929a6f3 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Thu, 19 Jun 2025 10:58:05 -0600 Subject: [PATCH 780/789] drivers/gfx/nvidia: Updates to NVPCF - Add more inline docs - Add `_STA` method - Update field names to better match names from Clevo dumps/DG samples - Add fields for v2.4 (unimplemented) - Add `TGPA` field for `UPDATE_DYNAMIC_PARAMS` - Match proprietary behavior for "Set Controller Status" - Add objects for disabling boost on AC/DC - Add debug logs for unimplemented functions Change-Id: I2a8d791198e18fca6eb907e62f92143fbe1e3962 Signed-off-by: Tim Crawford --- src/drivers/gfx/nvidia/acpi/common/nvpcf.asl | 257 +++++++++++++------ 1 file changed, 175 insertions(+), 82 deletions(-) diff --git a/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl b/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl index 16b9fbd56d..6ecbd05191 100644 --- a/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl +++ b/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl @@ -1,113 +1,206 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #define NVPCF_DSM_GUID "36b49710-2483-11e7-9598-0800200c9a66" -#define NVPCF_REVISION_ID 0x00000200 -#define NVPCF_ERROR_SUCCESS 0x0 -#define NVPCF_ERROR_GENERIC 0x80000001 -#define NVPCF_ERROR_UNSUPPORTED 0x80000002 -#define NVPCF_FUNC_GET_SUPPORTED 0x00000000 -#define NVPCF_FUNC_GET_STATIC_CONFIG_TABLES 0x00000001 -#define NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS 0x00000002 - -Name(_HID, "NVDA0820") - -Name(_UID, "NPCF") - -Method(_DSM, 4, Serialized) { - Printf("NVPCF _DSM") - If (Arg0 == ToUUID(NVPCF_DSM_GUID)) { - If (ToInteger(Arg1) == NVPCF_REVISION_ID) { - Return(NPCF(Arg2, Arg3)) +#define NVPCF_REVISION_ID 0x200 + +#define NVPCF_ERROR_SUCCESS 0 +#define NVPCF_ERROR_GENERIC 0x80000001 +#define NVPCF_ERROR_UNSUPPORTED 0x80000002 + +#define NVPCF_FUNC_GET_SUPPORTED 0 // Required +#define NVPCF_FUNC_GET_STATIC_CONFIG_TABLES 1 // Required +#define NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS 2 // Required +#define NVPCF_FUNC_GET_WM2_TBAND_TABLES 3 +#define NVPCF_FUNC_GET_WM2_SL_MAP_TABLES 4 +#define NVPCF_FUNC_GET_WM2_DYNAMIC_PARAMS 5 +#define NVPCF_FUNC_CPU_CONTROL 6 +#define NVPCF_FUNC_GPU_INFO 7 +#define NVPCF_FUNC_GET_DC_SYSTEM_POWER_LIMITS_TABLE 8 +#define NVPCF_FUNC_CPU_TDP_CONTROL 9 +#define NVPCF_FUNC_GET_DC_TPP_LIMIT_PREFERENCE 10 +#define NVPCF_FUNC_GET_THERMAL_ZONE_STATUS 11 + +Name (DBAC, 0) // Disable GPU Boost on AC +Name (DBDC, 0) // Disable GPU Boost on DC (XXX: Proprietary default disables on DC) + +Name (_HID, "NVDA0820") +Name (_UID, "NPCF") + +Method (_STA, 0, NotSerialized) +{ + Return (0x0F) // ACPI_STATUS_DEVICE_ALL_ON +} + +Method (_DSM, 4, Serialized) +{ + If (Arg0 == ToUUID (NVPCF_DSM_GUID)) { + Printf ("NVPCF DSM") + If (ToInteger (Arg1) == NVPCF_REVISION_ID) { + Return (NPCF (Arg2, Arg3)) } Else { - Printf(" Unsupported NVPCF revision: %o", SFST(Arg1)) - Return(NVPCF_ERROR_GENERIC) + Printf (" NVPCF: Unsupported revision: %o", Arg1) } - } Else { - Printf(" Unsupported GUID: %o", IDST(Arg0)) - Return(NVPCF_ERROR_GENERIC) } + Else { + Printf (" NVPCF: Unsupported GUID: %o", IDST (Arg0)) + } + + Return (NVPCF_ERROR_GENERIC) } -Method(NPCF, 2, Serialized) { - Printf(" NVPCF NPCF") - Switch(ToInteger(Arg0)) { - Case(NVPCF_FUNC_GET_SUPPORTED) { - Printf(" Supported Functions") - Return(ITOB( +Method (NPCF, 2, Serialized) +{ + Switch (ToInteger (Arg0)) { + Case (NVPCF_FUNC_GET_SUPPORTED) { + Printf (" NVPCF[0]: GET_SUPPORTED") + Return (ITOB ( (1 << NVPCF_FUNC_GET_SUPPORTED) | (1 << NVPCF_FUNC_GET_STATIC_CONFIG_TABLES) | (1 << NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS) )) } - Case(NVPCF_FUNC_GET_STATIC_CONFIG_TABLES) { - Printf(" Get Static Config") - Return(Buffer(14) { - // Device table header + Case (NVPCF_FUNC_GET_STATIC_CONFIG_TABLES) { + Printf (" NVPCF[1]: GET_STATIC_CONFIG_TABLE") + Return (Buffer (14) { + // System Device Table Header (v2.0) 0x20, 0x03, 0x01, - // Intel + NVIDIA + // System Device Table Entries + // [3:0] CPU Type (0=Intel, 1=AMD) + // [7:4] GPU Type (0=Nvidia) 0x00, - // Controller table header + // System Controller Table Header (v2.3) 0x23, 0x04, 0x05, 0x01, - // Dynamic boost controller - 0x01, - // Supports DC + // System Controller Table Controller Entry + // Controller Flags + // [3:0] Controller Class Type + // 0=Disabled + // 1=Dynamic Boost Controller + // 2=Configurable TGP-only Controller + // [7:4] Reserved 0x01, - // Reserved - 0x00, 0x00, 0x00, - // Checksum + // Controller Params + // [0:0] DC support (0=Not supported, 1=Supported) + // [31:1] Reserved + 0x01, 0x00, 0x00, 0x00, + // Single byte checksum value 0xAD }) } - Case(NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS) { - Printf(" Update Dynamic Boost") - - CreateField(Arg1, 0x28, 2, ICMD) // Input command - - Name(PCFP, Buffer(49) { - // Table version - 0x23, - // Table header size - 0x05, - // Size of common status in bytes - 0x10, - // Size of controller entry in bytes - 0x1C, - // Other fields filled in later + Case (NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS) { + Printf (" NVPCF[2]: UPDATE_DYNAMIC_PARAMS") + + // Dynamic Params Common Status, Input + // 0=Get Controller Params + // 1=Set Controller Status + CreateField (Arg1, 0x28, 2, ICMD) + + // XXX: All input params unused? + // Controller Entry, Input + //CreateByteField (Arg1, 0x15, IIDX) // Controller index + //CreateField (Arg1, 0xB0, 0x01, PWCS) // Power control capability (0=Disabled, 1=Enabled) + //CreateField (Arg1, 0xB1, 0x01, PWTS) // Power transfer status (0=Disabled, 1=Enabled) + //CreateField (Arg1, 0xB2, 0x01, CGPS) // CTGP status (0=Disabled, 1=Enabled) + + Name (PBD2, Buffer(49) { + // Dynamic Params Table Header + 0x23, // Version 2.3 + 0x05, // Table header size in bytes + 0x10, // Size of Common Status in bytes + 0x1C, // Size of Controller Entry in bytes + 0x01, // Number of Controller Entries }) - CreateByteField(PCFP, 0x04, CCNT) // Controller count - CreateWordField(PCFP, 0x19, ATPP) // AC TPP offset - CreateWordField(PCFP, 0x1D, AMXP) // AC maximum TGP offset - CreateWordField(PCFP, 0x21, AMNP) // AC minimum TGP offset - - Switch(ToInteger(ICMD)) { - Case(0) { - Printf(" Get Controller Params") - // Number of controllers - CCNT = 1 - // AC total processor power offset from default TGP in 1/8 watt units - ATPP = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP << 3) - // AC maximum TGP offset from default TGP in 1/8 watt units - AMXP = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX << 3) - // AC minimum TGP offset from default TGP in 1/8 watt units - AMNP = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MIN << 3) - Printf("PCFP: %o", SFST(PCFP)) - Return(PCFP) + + // Dynamic Params Common Status, Output + // Baseline (configurable) TGP in AC for the intended TPP + // limit, expressed as a signed offset relative to the + // static TGP rates, AC, in 1/8-watt units. + CreateWordField (PBD2, 0x05, TGPA) + + // Controller Entry, Output - Dynamic Boost Controller + CreateByteField (PBD2, 0x15, OIDX) // Controller index + // Disable controller on AC/DC + // [0:0] Disable controller on AC (0=Enable, 1=Disable) + // [1:1] Disable controller on DC (0=Enable, 1=Disable) + CreateByteField (PBD2, 0x16, PC02) + CreateWordField (PBD2, 0x19, TPPA) // TPP target on AC + CreateWordField (PBD2, 0x1D, MAGA) // Max TGP on AC + CreateWordField (PBD2, 0x21, MIGA) // Min TGP on AC + CreateDWordField (PBD2, 0x25, DROP) // DC Rest of system reserved power + CreateDWordField (PBD2, 0x29, LTBC) // Long Timescale Battery Current Limit + CreateDWordField (PBD2, 0x2D, STBC) // Short Timescale Battery Current Limit + + Switch (ToInteger (ICMD)) { + Case (0) { + Printf (" Get Controller Params") + + TGPA = 0 + OIDX = 0 + PC02 = DBAC | (DBDC << 1) + TPPA = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP << 3) + MAGA = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX << 3) + MIGA = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MIN << 3) + + // TODO: Handle v2.3+ fields + + Printf ("PBD2: %o", SFST(PBD2)) + Return (PBD2) } - Case(1) { - Printf(" Set Controller Status") - //TODO - Printf("PCFP: %o", SFST(PCFP)) - Return(PCFP) + Case (1) { + Printf (" Set Controller Status") + + // XXX: Match proprietary firmware behavior, + // which just explicitly sets fields to zero. + TGPA = 0 + OIDX = 0 + PC02 = 0 + TPPA = 0 + MAGA = 0 + MIGA = 0 + + Printf ("PBD2: %o", SFST(PBD2)) + Return (PBD2) } Default { - Printf(" Unknown Input Command: %o", SFST(ICMD)) - Return(NV_ERROR_UNSUPPORTED) + Printf (" Unknown Input Command: %o", SFST(ICMD)) + Return (NV_ERROR_UNSUPPORTED) } } } + Case (NVPCF_FUNC_GET_WM2_TBAND_TABLES) { + Printf (" NVPCF[3]: GET_WM2_TBAND_TABLES") + } + Case (NVPCF_FUNC_GET_WM2_SL_MAP_TABLES) { + Printf (" NVPCF[4]: GET_WM2_SL_MAP_TABLES") + } + Case (NVPCF_FUNC_GET_WM2_DYNAMIC_PARAMS) { + Printf (" NVPCF[5]: GET_WM2_DYNAMIC_PARAMS") + } + Case (NVPCF_FUNC_CPU_CONTROL) { + Printf (" NVPCF[6]: CPU_CONTROL") + } + Case (NVPCF_FUNC_GPU_INFO) { + Printf (" NVPCF[7]: GPU_INFO") + } + Case (NVPCF_FUNC_GET_DC_SYSTEM_POWER_LIMITS_TABLE) { + Printf (" NVPCF[8]: GET_DC_SYSTEM_POWER_LIMITS_TABLE") + } + Case (NVPCF_FUNC_CPU_TDP_CONTROL) { + Printf (" NVPCF[9]: CPU_TDP_CONTROL") + } + Case (NVPCF_FUNC_GET_DC_TPP_LIMIT_PREFERENCE) { + Printf (" NVPCF[10]: GET_DC_TPP_LIMIT_PREFERENCE") + } + Case (NVPCF_FUNC_GET_THERMAL_ZONE_STATUS) { + Printf (" NVPCF[11]: GET_THERMAL_ZONE_STATUS") + } Default { - Printf(" Unsupported function: %o", SFST(Arg0)) - Return(NVPCF_ERROR_UNSUPPORTED) + Printf (" NVPCF: Unknown function: %o", Arg0) } } + + // XXX: DG says unsupported functions should return a + // buffer, but even the example immediately following + // this statement returns a DWORD, and this is what + // proprietary firmware also does. + Return (NVPCF_ERROR_UNSUPPORTED) } From 7fe9d1fabb8fbb0f9631b0629d54ae3afb477b80 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 2 Jul 2025 18:01:46 +0000 Subject: [PATCH 781/789] Add gaze20 (#260) --- src/mainboard/system76/rpl/Kconfig | 16 +- src/mainboard/system76/rpl/Kconfig.name | 3 + .../system76/rpl/variants/gaze20/board.fmd | 12 + .../rpl/variants/gaze20/board_info.txt | 2 + .../system76/rpl/variants/gaze20/data.vbt | Bin 0 -> 9216 bytes .../system76/rpl/variants/gaze20/gpio.c | 227 ++++++++++++++++++ .../system76/rpl/variants/gaze20/gpio_early.c | 16 ++ .../system76/rpl/variants/gaze20/hda_verb.c | 26 ++ .../variants/gaze20/include/variant/gpio.h | 13 + .../rpl/variants/gaze20/overridetree.cb | 90 +++++++ .../system76/rpl/variants/gaze20/romstage.c | 40 +++ 11 files changed, 442 insertions(+), 3 deletions(-) create mode 100644 src/mainboard/system76/rpl/variants/gaze20/board.fmd create mode 100644 src/mainboard/system76/rpl/variants/gaze20/board_info.txt create mode 100644 src/mainboard/system76/rpl/variants/gaze20/data.vbt create mode 100644 src/mainboard/system76/rpl/variants/gaze20/gpio.c create mode 100644 src/mainboard/system76/rpl/variants/gaze20/gpio_early.c create mode 100644 src/mainboard/system76/rpl/variants/gaze20/hda_verb.c create mode 100644 src/mainboard/system76/rpl/variants/gaze20/include/variant/gpio.h create mode 100644 src/mainboard/system76/rpl/variants/gaze20/overridetree.cb create mode 100644 src/mainboard/system76/rpl/variants/gaze20/romstage.c diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index b9a30ef486..ea1f24f0a9 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -79,6 +79,13 @@ config BOARD_SYSTEM76_GAZE18 select EC_SYSTEM76_EC_DGPU select SOC_INTEL_ALDERLAKE_PCH_P +config BOARD_SYSTEM76_GAZE20 + select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + select EC_SYSTEM76_EC_DGPU + select SOC_INTEL_ALDERLAKE_PCH_P + config BOARD_SYSTEM76_LEMP12 select BOARD_SYSTEM76_RPL_COMMON select HAVE_SPD_IN_CBFS @@ -125,6 +132,7 @@ config VARIANT_DIR default "darp9" if BOARD_SYSTEM76_DARP9 default "galp7" if BOARD_SYSTEM76_GALP7 default "gaze18" if BOARD_SYSTEM76_GAZE18 + default "gaze20" if BOARD_SYSTEM76_GAZE20 default "lemp12" if BOARD_SYSTEM76_LEMP12 default "oryp11" if BOARD_SYSTEM76_ORYP11 default "oryp12" if BOARD_SYSTEM76_ORYP12 @@ -141,6 +149,7 @@ config MAINBOARD_PART_NUMBER default "darp9" if BOARD_SYSTEM76_DARP9 default "galp7" if BOARD_SYSTEM76_GALP7 default "gaze18" if BOARD_SYSTEM76_GAZE18 + default "gaze20" if BOARD_SYSTEM76_GAZE20 default "lemp12" if BOARD_SYSTEM76_LEMP12 default "oryp11" if BOARD_SYSTEM76_ORYP11 default "oryp12" if BOARD_SYSTEM76_ORYP12 @@ -151,7 +160,7 @@ config MAINBOARD_SMBIOS_PRODUCT_NAME default "Bonobo WS" if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B default "Darter Pro" if BOARD_SYSTEM76_DARP9 default "Galago Pro" if BOARD_SYSTEM76_GALP7 - default "Gazelle" if BOARD_SYSTEM76_GAZE18 + default "Gazelle" if BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_GAZE20 default "Lemur Pro" if BOARD_SYSTEM76_LEMP12 default "Oryx Pro" if BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 default "Serval WS" if BOARD_SYSTEM76_SERW13 @@ -164,6 +173,7 @@ config MAINBOARD_VERSION default "darp9" if BOARD_SYSTEM76_DARP9 default "galp7" if BOARD_SYSTEM76_GALP7 default "gaze18" if BOARD_SYSTEM76_GAZE18 + default "gaze20" if BOARD_SYSTEM76_GAZE20 default "lemp12" if BOARD_SYSTEM76_LEMP12 default "oryp11" if BOARD_SYSTEM76_ORYP11 default "oryp12" if BOARD_SYSTEM76_ORYP12 @@ -183,12 +193,12 @@ config DRIVERS_GFX_NVIDIA_BRIDGE default 0x02 if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP - default 45 if BOARD_SYSTEM76_ADDW4 || BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 + default 45 if BOARD_SYSTEM76_ADDW4 || BOARD_SYSTEM76_GAZE20 || BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 default 55 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_SERW13 default 80 if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX - default 25 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_ADDW4 || BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B || BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 || BOARD_SYSTEM76_SERW13 + default 25 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_ADDW4 || BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B || BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_GAZE20 || BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 || BOARD_SYSTEM76_SERW13 config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" diff --git a/src/mainboard/system76/rpl/Kconfig.name b/src/mainboard/system76/rpl/Kconfig.name index 86ac52f945..0a09982133 100644 --- a/src/mainboard/system76/rpl/Kconfig.name +++ b/src/mainboard/system76/rpl/Kconfig.name @@ -21,6 +21,9 @@ config BOARD_SYSTEM76_GALP7 config BOARD_SYSTEM76_GAZE18 bool "gaze18" +config BOARD_SYSTEM76_GAZE20 + bool "gaze20" + config BOARD_SYSTEM76_LEMP12 bool "lemp12" diff --git a/src/mainboard/system76/rpl/variants/gaze20/board.fmd b/src/mainboard/system76/rpl/variants/gaze20/board.fmd new file mode 100644 index 0000000000..fdf1ebdf52 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/board.fmd @@ -0,0 +1,12 @@ +FLASH 32M { + SI_DESC 4K + SI_ME 4824K + SI_BIOS@16M 16M { + RW_MRC_CACHE 64K + SMMSTORE(PRESERVE) 256K + WP_RO { + FMAP 4K + COREBOOT(CBFS) + } + } +} diff --git a/src/mainboard/system76/rpl/variants/gaze20/board_info.txt b/src/mainboard/system76/rpl/variants/gaze20/board_info.txt new file mode 100644 index 0000000000..4d60ca7c13 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/board_info.txt @@ -0,0 +1,2 @@ +Board name: gaze20 +Release year: 2025 diff --git a/src/mainboard/system76/rpl/variants/gaze20/data.vbt b/src/mainboard/system76/rpl/variants/gaze20/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..f01115566a7423c1b6b6704b2542c69d332fa452 GIT binary patch literal 9216 zcmeHMT}&KR6h3!mciFCsYz4~}TD+wV1uQTuEv1B{v;5g@p)5Zo+i1d;?rMp&tdtsR zOc)~%B#p^DDQ%j#nivhf@Zz(Zm>5i7h$f8>8hO&D@x_FD%Hx=IxxkHdcZdF+oJnGj(0dJMzN1x|i)Pih{?$*TL_C-vfUD{s{az_zUot;BUa+ zfqw-50{#uWD*{N#m^n}CItOyyq14JqCRd`^sgk>pPGh>u&X(zYMl9#BFh4AsBZpZe zYFPeLB903G7*#trhR?y~ADAhFEONy$*@DLY-D9}(y?n!$|RtS^4x5T4* zRv|E5Jespb_^fVnskfv;4b7%~V7fR_kXv=kXW_%Cld3X2?^D%88o^;6a@>PdZ|q5)UB})nbgH8jo?Z)d3d{4kB3XjRE1k(flS);T}BjIUN%uwwrKI#{6Qd8 zi&o}X=*C0W9k)+s5yh>l_+syLxe~ltoI;T486hK+*&ry@>Oy!rqIi3)C4wkqOeTRK zo|oHaa^0LX5ODSr2zH(Y!u=A82YIpLR@y`>BM-8U^#}wlugRDX;*`7jtd^QJ?;A}u zYN#eX7Bb;rDSWV2*4FEyN~N$yg<+2e=S)FH6dobDyE=nI!3$TSqh~K%jy?qi5!92W zWb(y&<~Y4Tj?kQS)md6zUH=#4pL=UDOBn1=Uj^Ca&gfK-+Sy8RRXeLEFLo@?h3GpAl zHyGQx>BP}SY(+YD24j<4lksHoq%jg=I~HCpS})#Wb1j&9;baj8Rt)fF)Y3vu-$+Gg zBcp>OSA2MR9I9*~AIyzcOx$xlr*oIf_TN9lmYMmRDSUh>Ju;b+!=R>b$v72c>UMbP zM4!uHoVRv(969%M8OUWImw{Xcav8{FAeVt$2L8niG=D7ZqgRHBG)c$bS7BOW`>ij2 z;>#wHdYg#L#41Un5Nw(G53ZrR^$tGaI>Y!^81JZ#Lg>s7Eu!7hCy?#4OraP)x+>7% zT^5u83*DrhGY@nnHcy65|3T=MScqn!tH{tTPD-RY6iEfjyv>)Pd)Uor&_2gHNyoqI zWzd=bGHU4W`$a~&BTfo&V3xrX2Wm}U^z#yFd8TgOb`Y_fpCS{`+v1Gk_C*$?n=~z# z1JiuR7CI4w>R2Ez^+FdB)?gF!-Xl>|nU`kZOGQS1hw?>U;&`QpH*zsrrSnqME`0GK a_8Mxk)nv5WD%V?$-_xK&HgoiU$iN?mCU^<} literal 0 HcmV?d00001 diff --git a/src/mainboard/system76/rpl/variants/gaze20/gpio.c b/src/mainboard/system76/rpl/variants/gaze20/gpio.c new file mode 100644 index 0000000000..5e256cafa9 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/gpio.c @@ -0,0 +1,227 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config gpio_table[] = { + /* ------- GPIO Group GPD ------- */ + PAD_CFG_NF(GPD0, UP_20K, PWROK, NF1), // PM_BATLOW# + PAD_CFG_NF(GPD1, NATIVE, PWROK, NF1), // AC_PRESENT + PAD_CFG_NF(GPD2, NATIVE, DEEP, NF1), // LANRTD3_WAKE# + PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1), // PWR_BTN# + PAD_CFG_NF(GPD4, NONE, PWROK, NF1), // SUSB#_PCH + PAD_CFG_NF(GPD5, NONE, PWROK, NF1), // SUSC#_PCH + PAD_CFG_NF(GPD6, NONE, PWROK, NF1), // SLP_A# + PAD_NC(GPD7, NONE), + PAD_CFG_NF(GPD8, NONE, PWROK, NF1), // Not documented + PAD_CFG_GPI(GPD9, NONE, DEEP), // SLP_WLAN# + PAD_CFG_NF(GPD10, NONE, PWROK, NF1), // SLP_S5# + PAD_NC(GPD11, NONE), + + /* ------- GPIO Group GPP_A ------- */ + PAD_CFG_NF(GPP_A0, UP_20K, DEEP, NF1), // ESPI_IO0_EC + PAD_CFG_NF(GPP_A1, UP_20K, DEEP, NF1), // ESPI_IO1_EC + PAD_CFG_NF(GPP_A2, UP_20K, DEEP, NF1), // ESPI_IO2_EC + PAD_CFG_NF(GPP_A3, UP_20K, DEEP, NF1), // ESPI_IO3_EC + PAD_CFG_NF(GPP_A4, UP_20K, DEEP, NF1), // ESPI_CS_EC# + PAD_CFG_NF(GPP_A5, UP_20K, DEEP, NF1), // ESPI_ALRT0# + PAD_NC(GPP_A6, NONE), + PAD_NC(GPP_A7, NONE), + PAD_NC(GPP_A8, NONE), + PAD_CFG_NF(GPP_A9, DN_20K, DEEP, NF1), // ESPI_CLK_EC + PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1), // ESPI_RESET_N + PAD_NC(GPP_A11, NONE), + PAD_NC(GPP_A12, NONE), + PAD_CFG_GPO(GPP_A13, 1, PLTRST), // BT_EN + // GPP_A14 (DGPU_PWR_EN) configured in bootblock + PAD_CFG_NF(GPP_A15, NONE, DEEP, NF2), // DP_HPD + PAD_NC(GPP_A16, NONE), + PAD_CFG_GPI_INT(GPP_A17, NONE, PLTRST, LEVEL), // TP_ATTN# + PAD_CFG_NF(GPP_A18, NONE, DEEP, NF1), // MDP_B_HPD + PAD_CFG_GPI(GPP_A19, NONE, DEEP), // DGPU_PWRGD_R + _PAD_CFG_STRUCT(GPP_A20, 0x86880100, 0x0000), // HDMI_HPD + _PAD_CFG_STRUCT(GPP_A21, 0x86880100, 0x0000), // NVVDD_TALERT# + PAD_CFG_GPO(GPP_A22, 1, PLTRST), // LAN_PWR_EN + PAD_NC(GPP_A23, NONE), + + /* ------- GPIO Group GPP_B ------- */ + PAD_CFG_NF(GPP_B0, NONE, DEEP, NF1), // VCCIN_AUX_VID0 + PAD_CFG_NF(GPP_B1, NONE, DEEP, NF1), // VCCIN_AUX_VID1 + // GPP_B2 (DGPU_RST#_PCH) configured in bootblock + PAD_CFG_GPI(GPP_B3, NONE, DEEP), // SCI# + PAD_NC(GPP_B4, NONE), + PAD_CFG_GPO(GPP_B5, 0, DEEP), // PS8461_SW + PAD_NC(GPP_B6, NONE), + PAD_NC(GPP_B7, NONE), + PAD_NC(GPP_B8, NONE), + // GPP_B9 missing + // GPP_B10 missing + PAD_CFG_GPI(GPP_B11, NONE, PLTRST), // PMCALERT# + PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), // SLP_S0# + PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), // PLT_RST# + PAD_NC(GPP_B14, NONE), // TOP SWAP OVERRIDE strap + PAD_CFG_GPO(GPP_B15, 1, PLTRST), // WLAN_RST#_R + _PAD_CFG_STRUCT(GPP_B16, 0x80100100, 0x0000), // INTP_OUT + PAD_NC(GPP_B17, NONE), + PAD_NC(GPP_B18, NONE), // NO REBOOT strap + // GPP_B19 missing + // GPP_B20 missing + // GPP_B21 missing + // GPP_B22 missing + PAD_NC(GPP_B23, NONE), // CPUNSSC CLOCK FREQ strap + + /* ------- GPIO Group GPP_C ------- */ + PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), // SMB_CLK + PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), // SMB_DATA + PAD_CFG_GPO(GPP_C2, 1, PLTRST), // M2_SSD2_PWR_EN + PAD_NC(GPP_C3, NONE), + PAD_NC(GPP_C4, NONE), + PAD_CFG_GPO(GPP_C5, 1, PLTRST), // LAN_RTD3#, TLS CONFIDENTIALITY strap + PAD_NC(GPP_C6, NONE), + PAD_NC(GPP_C7, NONE), + // GPP_C8 missing + // GPP_C9 missing + // GPP_C10 missing + // GPP_C11 missing + // GPP_C12 missing + // GPP_C13 missing + // GPP_C14 missing + // GPP_C15 missing + // GPP_C16 missing + // GPP_C17 missing + // GPP_C18 missing + // GPP_C19 missing + // GPP_C20 missing + // GPP_C21 missing + // GPP_C22 missing + // GPP_C23 missing + + /* ------- GPIO Group GPP_D ------- */ + PAD_CFG_GPO(GPP_D0, 1, DEEP), // SB_BLON + PAD_CFG_GPI(GPP_D1, NONE, DEEP), // SB_KBCRST# + PAD_NC(GPP_D2, NONE), + PAD_NC(GPP_D3, NONE), + PAD_NC(GPP_D4, NONE), + // GPP_D5 (SSD1_CLKREQ#) configured by FSP + PAD_NC(GPP_D6, NONE), + PAD_NC(GPP_D7, NONE), + // GPP_D8 (GPU_PCIE_CLKREQ3#) configured by FSP + PAD_NC(GPP_D9, NONE), + PAD_NC(GPP_D10, NONE), // strap + PAD_NC(GPP_D11, NONE), + PAD_NC(GPP_D12, NONE), // strap + PAD_CFG_GPO(GPP_D13, 0, DEEP), // WLAN_WAKEUP# + PAD_CFG_GPO(GPP_D14, 1, PLTRST), // M2_SSD1_PWR_EN + PAD_NC(GPP_D15, NONE), + PAD_CFG_GPO(GPP_D16, 0, DEEP), // TEST_R + PAD_NC(GPP_D17, NONE), + PAD_NC(GPP_D18, NONE), + PAD_NC(GPP_D19, NONE), + + /* ------- GPIO Group GPP_E ------- */ + PAD_CFG_GPI(GPP_E0, NONE, DEEP), // CNVI_WAKE# + _PAD_CFG_STRUCT(GPP_E1, 0x40100100, 0x3000), // TPM_PIRQ# + PAD_NC(GPP_E2, NONE), // BOARD_ID5 + PAD_CFG_GPO(GPP_E3, 1, DEEP), // PCH_WLAN_EN + PAD_NC(GPP_E4, NONE), + PAD_NC(GPP_E5, NONE), + PAD_NC(GPP_E6, NONE), // JTAG ODT DISABLE strap + PAD_NC(GPP_E7, NONE), + PAD_CFG_GPO(GPP_E8, 0, DEEP), // SLP_DRAM# + PAD_NC(GPP_E9, NONE), // SWI# + PAD_NC(GPP_E10, NONE), // strap + PAD_NC(GPP_E11, NONE), // strap + PAD_NC(GPP_E12, NONE), // BOARD_ID4 + PAD_NC(GPP_E13, NONE), + PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), // EDP_HPD + PAD_NC(GPP_E15, NONE), + PAD_NC(GPP_E16, NONE), + PAD_NC(GPP_E17, NONE), + PAD_NC(GPP_E18, NONE), + PAD_NC(GPP_E19, NONE), // strap + PAD_NC(GPP_E20, NONE), + PAD_NC(GPP_E21, NONE), // strap + PAD_NC(GPP_E22, NONE), + PAD_NC(GPP_E23, NONE), + + /* ------- GPIO Group GPP_F ------- */ + PAD_CFG_NF(GPP_F0, NONE, DEEP, NF1), // CNVI_BRI_DT + PAD_CFG_NF(GPP_F1, UP_20K, DEEP, NF1), // CNVI_BRI_RSP + PAD_CFG_NF(GPP_F2, NONE, DEEP, NF1), // CNVI_RGI_DT + PAD_CFG_NF(GPP_F3, UP_20K, DEEP, NF1), // CNVI_RGI_RSP + PAD_CFG_NF(GPP_F4, NONE, DEEP, NF1), // CNVI_RF_RST# + // GPP_F5 (XTAL_CLKREQ) configured by FSP + PAD_CFG_NF(GPP_F6, NONE, DEEP, NF1), // CNVI_GNSS_PA_BLANKING + PAD_CFG_GPO(GPP_F7, 1, DEEP), // GPP_LAN_RST# + // GPP_F8 missing + PAD_NC(GPP_F9, NONE), + PAD_NC(GPP_F10, NONE), // strap + PAD_NC(GPP_F11, NONE), // BOARD_ID3 + PAD_CFG_GPI(GPP_F12, NONE, PLTRST), // GPIO4_GC6_NVVDD_EN_R + PAD_CFG_GPI(GPP_F13, NONE, PLTRST), // GC6_FB_EN_PCH + PAD_NC(GPP_F14, NONE), // BOARD_ID1 + PAD_NC(GPP_F15, NONE), // BOARD_ID2 + PAD_NC(GPP_F16, NONE), // BOARD_ID6 + PAD_NC(GPP_F17, NONE), // BOARD_ID7 + PAD_CFG_GPO(GPP_F18, 1, DEEP), // CCD_FW_WP# + // GPP_F19 (GLAN_CLKREQ#) configured by FSP + PAD_CFG_GPO(GPP_F20, 1, PLTRST), // M2_SSD1_RST# + PAD_CFG_GPO(GPP_F21, 1, PLTRST), // M2_SSD2_RST# + PAD_NC(GPP_F22, NONE), + PAD_NC(GPP_F23, NONE), + + /* ------- GPIO Group GPP_H ------- */ + PAD_NC(GPP_H0, NONE), // strap + PAD_NC(GPP_H1, NONE), // strap + PAD_NC(GPP_H2, NONE), // strap + PAD_CFG_GPI(GPP_H3, NONE, DEEP), // TPM_DET + PAD_CFG_NF(GPP_H4, NONE, DEEP, NF1), // I2C_SDA_TP + PAD_CFG_NF(GPP_H5, NONE, DEEP, NF1), // I2C_SCL_TP + PAD_CFG_NF(GPP_H6, NONE, DEEP, NF1), // SMD_7411 + PAD_CFG_NF(GPP_H7, NONE, DEEP, NF1), // SMC_7411 + PAD_CFG_GPO(GPP_H8, 0, DEEP), // CNVI_MFUART2_RXD + PAD_CFG_GPO(GPP_H9, 0, DEEP), // CNVI_MFUART2_TXD + // GPP_H10 (UART0_RX) configured in bootblock + // GPP_H11 (UART0_TX) configured in bootblock + PAD_NC(GPP_H12, NONE), + PAD_NC(GPP_H13, NONE), + // GPP_H14 missing + PAD_CFG_NF(GPP_H15, NONE, DEEP, NF1), // I_MDP_CLK + // GPP_H16 missing + PAD_CFG_NF(GPP_H17, NONE, DEEP, NF1), // I_MDP_DATA + PAD_CFG_NF(GPP_H18, NONE, DEEP, NF1), // CPU_C10_GATE# + // GPP_H19 (SSD2_CLKREQ4#) configured by FSP + PAD_NC(GPP_H20, NONE), + PAD_NC(GPP_H21, NONE), + PAD_NC(GPP_H22, NONE), + // GPP_H23 (WLAN_CLKREQ5#) configured by FSP + + /* ------- GPIO Group GPP_R ------- */ + PAD_CFG_NF(GPP_R0, NONE, DEEP, NF1), // HDA_BITCLK + PAD_CFG_NF(GPP_R1, NATIVE, DEEP, NF1), // HDA_SYNC + PAD_CFG_NF(GPP_R2, NATIVE, DEEP, NF1), // HDA_SDOUT / ME_WE + PAD_CFG_NF(GPP_R3, NATIVE, DEEP, NF1), // HDA_SDIN0 + PAD_CFG_NF(GPP_R4, NONE, DEEP, NF1), // AZ_RST#_R + PAD_NC(GPP_R5, NONE), + PAD_NC(GPP_R6, NONE), + PAD_NC(GPP_R7, NONE), + + /* ------- GPIO Group GPP_S ------- */ + PAD_NC(GPP_S0, NONE), + PAD_NC(GPP_S1, NONE), + PAD_NC(GPP_S2, NONE), + PAD_NC(GPP_S3, NONE), + PAD_NC(GPP_S4, NONE), + PAD_NC(GPP_S5, NONE), + PAD_NC(GPP_S6, NONE), + PAD_NC(GPP_S7, NONE), + + /* ------- GPIO Group GPP_T ------- */ + PAD_NC(GPP_T2, NONE), + PAD_NC(GPP_T3, NONE), +}; + +void mainboard_configure_gpios(void) +{ + gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); +} diff --git a/src/mainboard/system76/rpl/variants/gaze20/gpio_early.c b/src/mainboard/system76/rpl/variants/gaze20/gpio_early.c new file mode 100644 index 0000000000..85b9307d45 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/gpio_early.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config early_gpio_table[] = { + PAD_CFG_GPO(GPP_A14, 0, DEEP), // DGPU_PWR_EN + PAD_CFG_GPO(GPP_B2, 0, DEEP), // DGPU_RST#_PCH + PAD_CFG_NF(GPP_H10, NONE, DEEP, NF1), // UART0_RX + PAD_CFG_NF(GPP_H11, NONE, DEEP, NF1), // UART0_TX +}; + +void mainboard_configure_early_gpios(void) +{ + gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table)); +} diff --git a/src/mainboard/system76/rpl/variants/gaze20/hda_verb.c b/src/mainboard/system76/rpl/variants/gaze20/hda_verb.c new file mode 100644 index 0000000000..3426075354 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/hda_verb.c @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +const u32 cim_verb_data[] = { + /* Realtek, ALC255 */ + 0x10ec0255, /* Vendor ID */ + 0x15582560, /* Subsystem ID */ + 12, /* Number of entries */ + AZALIA_SUBVENDOR(0, 0x15582560), + AZALIA_RESET(1), + AZALIA_PIN_CFG(0, 0x12, 0x90a60130), + AZALIA_PIN_CFG(0, 0x14, 0x90170110), + AZALIA_PIN_CFG(0, 0x17, 0x40000000), + AZALIA_PIN_CFG(0, 0x18, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1b, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1d, 0x41e79b45), + AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x21, 0x04211020), +}; + +const u32 pc_beep_verbs[] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/system76/rpl/variants/gaze20/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/gaze20/include/variant/gpio.h new file mode 100644 index 0000000000..fcf1eef0de --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_F13 +#define DGPU_SSID 0x25601558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb new file mode 100644 index 0000000000..f520881bc5 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: GPL-2.0-only + +chip soc/intel/alderlake + device domain 0 on + subsystemid 0x1558 0x2560 inherit + + device ref xhci on + register "usb2_ports" = "{ + [0] = USB2_PORT_TYPE_C(OC_SKIP), /* USB Type-C */ + [1] = USB2_PORT_MID(OC_SKIP), /* USB 2.0 Type-A audio board */ + [2] = USB2_PORT_MID(OC_SKIP), /* USB 3.0 Type-A motherboard */ + [3] = USB2_PORT_MID(OC_SKIP), /* USB 3.0 Type-A audio board */ + [5] = USB2_PORT_MID(OC_SKIP), /* Fingerprint */ + [7] = USB2_PORT_MID(OC_SKIP), /* Camera */ + [9] = USB2_PORT_MID(OC_SKIP), /* Bluetooth */ + }" + register "usb3_ports" = "{ + [0] = USB3_PORT_DEFAULT(OC_SKIP), /* USB Type-C */ + [2] = USB3_PORT_DEFAULT(OC_SKIP), /* USB 3.0 Type-A motherboard */ + [3] = USB3_PORT_DEFAULT(OC_SKIP), /* USB 3.0 Type-A audio board */ + }" + end + + device ref i2c0 on + # Touchpad I2C bus + register "serial_io_i2c_mode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + chip drivers/i2c/hid + register "generic.hid" = ""ELAN0412"" + register "generic.desc" = ""ELAN Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A17)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 15 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""FTCS1000"" + register "generic.desc" = ""FocalTech Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A17)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 38 on end + end + end + + device ref pcie5_0 on + # CPU RP#2 x8, Clock 3 (GPU) + register "cpu_pcie_rp[CPU_RP(2)]" = "{ + .clk_src = 3, + .clk_req = 3, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref pcie4_0 on + # CPU RP#1 x4, Clock 0 (SSD1) + register "cpu_pcie_rp[CPU_RP(1)]" = "{ + .clk_src = 0, + .clk_req = 0, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M.2/M 2280 (J_SSD1)" "SlotDataBusWidth4X" + end + device ref pcie4_1 on + # CPU RP#3 x4, Clock 0 (SSD2) + register "cpu_pcie_rp[CPU_RP(3)]" = "{ + .clk_src = 4, + .clk_req = 4, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M.2/M 2280 (J_SSD2)" "SlotDataBusWidth4X" + end + device ref pcie_rp5 on + # PCH RP#5 x1, Clock 5 (WLAN) + register "pch_pcie_rp[PCH_RP(5)]" = "{ + .clk_src = 5, + .clk_req = 5, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + smbios_slot_desc "SlotTypeM2Socket1_SD" "SlotLengthOther" "M.2/E 2230 (J_WLAN1)" "SlotDataBusWidth1X" + end + device ref pcie_rp7 on + # PCH RP#7 x1, Clock 6 (GLAN) + register "pch_pcie_rp[PCH_RP(7)]" = "{ + .clk_src = 6, + .clk_req = 6, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + device pci 00.0 on end + end + end +end diff --git a/src/mainboard/system76/rpl/variants/gaze20/romstage.c b/src/mainboard/system76/rpl/variants/gaze20/romstage.c new file mode 100644 index 0000000000..2c8a6737bb --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/romstage.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + const struct mb_cfg board_cfg = { + .type = MEM_TYPE_DDR5, + .ect = true, + .LpDdrDqDqsReTraining = 1, + }; + const struct mem_spd spd_info = { + .topo = MEM_TOPO_DIMM_MODULE, + .smbus = { + [0] = { .addr_dimm[0] = 0x50, }, + [1] = { .addr_dimm[0] = 0x52, }, + }, + }; + const bool half_populated = false; + + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + mupd->FspmConfig.PrimaryDisplay = 0; + + mupd->FspmConfig.DmiMaxLinkSpeed = 4; + mupd->FspmConfig.GpioOverride = 0; + + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); +} From 8a0191a0c89f3bdc426eb23cdf6e79fb9b143a6a Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 9 Jul 2025 16:08:52 -0600 Subject: [PATCH 782/789] gaze20: do not use port reset messaging Change-Id: I9e5525d4197953c430325d813ee20d980dddab63 Signed-off-by: Jeremy Soller --- src/mainboard/system76/rpl/variants/gaze20/overridetree.cb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb index f520881bc5..f6728a21a7 100644 --- a/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb @@ -6,7 +6,7 @@ chip soc/intel/alderlake device ref xhci on register "usb2_ports" = "{ - [0] = USB2_PORT_TYPE_C(OC_SKIP), /* USB Type-C */ + [0] = USB2_PORT_MID(OC_SKIP), /* USB Type-C */ [1] = USB2_PORT_MID(OC_SKIP), /* USB 2.0 Type-A audio board */ [2] = USB2_PORT_MID(OC_SKIP), /* USB 3.0 Type-A motherboard */ [3] = USB2_PORT_MID(OC_SKIP), /* USB 3.0 Type-A audio board */ From 55497f88be536fc9d99cac85bfc5b8cf0f751988 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 10 Jul 2025 14:44:11 -0600 Subject: [PATCH 783/789] gaze20: enable DDI3 Change-Id: Iea09f90a6e53035ce379afa6d7dd4ad3a83333c6 Signed-off-by: Jeremy Soller --- .../system76/rpl/variants/gaze20/overridetree.cb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb index f6728a21a7..a9f865251f 100644 --- a/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb @@ -4,6 +4,18 @@ chip soc/intel/alderlake device domain 0 on subsystemid 0x1558 0x2560 inherit + device ref igpu on + # DDIA is eDP, DDIB is mDP, DDI3 is USB-C + register "ddi_portA_config" = "1" + register "ddi_ports_config" = "{ + [DDI_PORT_A] = DDI_ENABLE_HPD, + [DDI_PORT_B] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_3] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + }" + + register "gfx" = "GMA_DEFAULT_PANEL(0)" + end + device ref xhci on register "usb2_ports" = "{ [0] = USB2_PORT_MID(OC_SKIP), /* USB Type-C */ From 89498b2f3b7a70e4a08db3b8a7357766547e8dca Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 16 Jul 2025 14:42:22 -0600 Subject: [PATCH 784/789] gaze20: TCP3 is actually DDI4 and does not have DDC Change-Id: Iafb7d137332ee0668dfc1a3cf47a4d881b8cdfb8 Signed-off-by: Jeremy Soller --- src/mainboard/system76/rpl/variants/gaze20/overridetree.cb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb index a9f865251f..8713a8acfb 100644 --- a/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb @@ -5,12 +5,12 @@ chip soc/intel/alderlake subsystemid 0x1558 0x2560 inherit device ref igpu on - # DDIA is eDP, DDIB is mDP, DDI3 is USB-C + # DDIA is eDP, DDIB is mDP, TCP3 (DDI4) is USB-C register "ddi_portA_config" = "1" register "ddi_ports_config" = "{ [DDI_PORT_A] = DDI_ENABLE_HPD, [DDI_PORT_B] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, - [DDI_PORT_3] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_4] = DDI_ENABLE_HPD, }" register "gfx" = "GMA_DEFAULT_PANEL(0)" From bbcd82259cd992692f11d4b2e9822e441e32ff79 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Tue, 29 Jul 2025 14:28:31 -0600 Subject: [PATCH 785/789] mb/system76/rpl: gaze20: Support up to 6400 MT/s memory (#263) Change-Id: I5f0b8cf65446b275deb5207d344fde97da1dc833 Signed-off-by: Tim Crawford --- src/mainboard/system76/rpl/variants/gaze20/overridetree.cb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb index 8713a8acfb..79f858a65b 100644 --- a/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only chip soc/intel/alderlake + register "max_dram_speed_mts" = "6400" + device domain 0 on subsystemid 0x1558 0x2560 inherit From 9b9442e83e74cc5daae14376201384738ca98599 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Thu, 7 Aug 2025 08:51:43 -0600 Subject: [PATCH 786/789] soc/intel/adl: Only use channel 0 for mem-down DDR4 Fixes: c0ba1166e97d ("soc/intel/adl,mtl: Use channel 0 only for memory down in mixed topo") Change-Id: I56e7d51b4a06519376d8fe7a345bb434c6f1a24a Signed-off-by: Tim Crawford --- src/soc/intel/alderlake/meminit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/alderlake/meminit.c b/src/soc/intel/alderlake/meminit.c index 014b5db434..d7923401c7 100644 --- a/src/soc/intel/alderlake/meminit.c +++ b/src/soc/intel/alderlake/meminit.c @@ -54,8 +54,8 @@ static const struct soc_mem_cfg soc_mem_cfg[] = { * configuration. */ .half_channel = BIT(0), - /* In mixed topologies, either channel 0 or 1 can be memory-down. */ - .mixed_topo = BIT(0) | BIT(1), + /* In mixed topologies, channel 0 is memory-down. */ + .mixed_topo = BIT(0), }, }, [MEM_TYPE_DDR5] = { From f7069e7d85a0f0825311ab821cc7d69054ef63e1 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Thu, 21 Aug 2025 09:49:20 -0600 Subject: [PATCH 787/789] mb/system76: Disable GPU Boost The GPU sometimes crashes when GPU Boost is used. Disable the feature until root cause can be identified and resolved. Change-Id: Ib3624c1241921268627cfc85b4427bc9891fa0a3 Signed-off-by: Tim Crawford --- src/mainboard/system76/adl/Kconfig | 4 ++-- src/mainboard/system76/rpl/Kconfig | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/mainboard/system76/adl/Kconfig b/src/mainboard/system76/adl/Kconfig index 60ecc96bb9..ac0b704408 100644 --- a/src/mainboard/system76/adl/Kconfig +++ b/src/mainboard/system76/adl/Kconfig @@ -52,14 +52,14 @@ config BOARD_SYSTEM76_LEMP11 config BOARD_SYSTEM76_ORYP9 select BOARD_SYSTEM76_ADL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC_DGPU config BOARD_SYSTEM76_ORYP10 select BOARD_SYSTEM76_ADL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU if BOARD_SYSTEM76_ADL_COMMON diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index ea1f24f0a9..758c29a552 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -29,7 +29,7 @@ config BOARD_SYSTEM76_RPL_COMMON config BOARD_SYSTEM76_ADDW3 select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select MAINBOARD_USES_IFD_GBE_REGION @@ -39,7 +39,7 @@ config BOARD_SYSTEM76_ADDW3 config BOARD_SYSTEM76_ADDW4 select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S @@ -47,7 +47,7 @@ config BOARD_SYSTEM76_ADDW4 config BOARD_SYSTEM76_BONW15 select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG @@ -56,7 +56,7 @@ config BOARD_SYSTEM76_BONW15 config BOARD_SYSTEM76_BONW15_B select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG @@ -75,14 +75,14 @@ config BOARD_SYSTEM76_GALP7 config BOARD_SYSTEM76_GAZE18 select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select SOC_INTEL_ALDERLAKE_PCH_P config BOARD_SYSTEM76_GAZE20 select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select SOC_INTEL_ALDERLAKE_PCH_P @@ -95,7 +95,7 @@ config BOARD_SYSTEM76_LEMP12 config BOARD_SYSTEM76_ORYP11 select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select SOC_INTEL_ALDERLAKE_PCH_P select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES @@ -103,7 +103,7 @@ config BOARD_SYSTEM76_ORYP11 config BOARD_SYSTEM76_ORYP12 select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_I2C_TAS5825M select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU @@ -113,7 +113,7 @@ config BOARD_SYSTEM76_ORYP12 config BOARD_SYSTEM76_SERW13 select BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GFX_NVIDIA - select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG From 001b973a3ff2e6e3e0ff7fd860bd7ab354d7a3b8 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 5 Mar 2026 13:32:22 -0700 Subject: [PATCH 788/789] mainboard/system76/ptl: init with lemp14 --- src/mainboard/system76/ptl/Kconfig | 89 ++ src/mainboard/system76/ptl/Kconfig.name | 4 + src/mainboard/system76/ptl/Makefile.mk | 17 + src/mainboard/system76/ptl/acpi/backlight.asl | 31 + src/mainboard/system76/ptl/acpi/mainboard.asl | 12 + src/mainboard/system76/ptl/acpi/sleep.asl | 9 + src/mainboard/system76/ptl/board_info.txt | 6 + src/mainboard/system76/ptl/bootblock.c | 9 + src/mainboard/system76/ptl/cmos.default | 5 + src/mainboard/system76/ptl/cmos.layout | 43 + src/mainboard/system76/ptl/devicetree.cb | 65 + src/mainboard/system76/ptl/dsdt.asl | 36 + .../system76/ptl/include/mainboard/gpio.h | 9 + src/mainboard/system76/ptl/ramstage.c | 13 + src/mainboard/system76/ptl/spd/Makefile.mk | 6 + .../system76/ptl/variants/lemp14/board.fmd | 12 + .../ptl/variants/lemp14/board_info.txt | 2 + .../system76/ptl/variants/lemp14/data.vbt | Bin 0 -> 7680 bytes .../system76/ptl/variants/lemp14/gpio.c | 203 ++++ .../system76/ptl/variants/lemp14/gpio_early.c | 17 + .../system76/ptl/variants/lemp14/hda_verb.c | 51 + .../ptl/variants/lemp14/memory/Makefile.mk | 7 + .../lemp14/memory/dram_id.generated.txt | 7 + .../variants/lemp14/memory/mem_parts_used.txt | 12 + .../ptl/variants/lemp14/overridetree.cb | 112 ++ .../system76/ptl/variants/lemp14/ramstage.c | 18 + .../system76/ptl/variants/lemp14/romstage.c | 78 ++ .../system76/ptl/variants/lemp14/tas5825m.c | 1049 +++++++++++++++++ 28 files changed, 1922 insertions(+) create mode 100644 src/mainboard/system76/ptl/Kconfig create mode 100644 src/mainboard/system76/ptl/Kconfig.name create mode 100644 src/mainboard/system76/ptl/Makefile.mk create mode 100644 src/mainboard/system76/ptl/acpi/backlight.asl create mode 100644 src/mainboard/system76/ptl/acpi/mainboard.asl create mode 100644 src/mainboard/system76/ptl/acpi/sleep.asl create mode 100644 src/mainboard/system76/ptl/board_info.txt create mode 100644 src/mainboard/system76/ptl/bootblock.c create mode 100644 src/mainboard/system76/ptl/cmos.default create mode 100644 src/mainboard/system76/ptl/cmos.layout create mode 100644 src/mainboard/system76/ptl/devicetree.cb create mode 100644 src/mainboard/system76/ptl/dsdt.asl create mode 100644 src/mainboard/system76/ptl/include/mainboard/gpio.h create mode 100644 src/mainboard/system76/ptl/ramstage.c create mode 100644 src/mainboard/system76/ptl/spd/Makefile.mk create mode 100644 src/mainboard/system76/ptl/variants/lemp14/board.fmd create mode 100644 src/mainboard/system76/ptl/variants/lemp14/board_info.txt create mode 100644 src/mainboard/system76/ptl/variants/lemp14/data.vbt create mode 100644 src/mainboard/system76/ptl/variants/lemp14/gpio.c create mode 100644 src/mainboard/system76/ptl/variants/lemp14/gpio_early.c create mode 100644 src/mainboard/system76/ptl/variants/lemp14/hda_verb.c create mode 100644 src/mainboard/system76/ptl/variants/lemp14/memory/Makefile.mk create mode 100644 src/mainboard/system76/ptl/variants/lemp14/memory/dram_id.generated.txt create mode 100644 src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt create mode 100644 src/mainboard/system76/ptl/variants/lemp14/overridetree.cb create mode 100644 src/mainboard/system76/ptl/variants/lemp14/ramstage.c create mode 100644 src/mainboard/system76/ptl/variants/lemp14/romstage.c create mode 100644 src/mainboard/system76/ptl/variants/lemp14/tas5825m.c diff --git a/src/mainboard/system76/ptl/Kconfig b/src/mainboard/system76/ptl/Kconfig new file mode 100644 index 0000000000..da29d0a003 --- /dev/null +++ b/src/mainboard/system76/ptl/Kconfig @@ -0,0 +1,89 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_SYSTEM76_PTL_COMMON + def_bool n + select AZALIA_USE_LEGACY_VERB_TABLE + select BOARD_ROMSIZE_KB_32768 + select DRIVERS_GENERIC_BAYHUB_LV2 + select DRIVERS_GENERIC_CBFS_SERIAL + select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_I2C_HID + select EC_SYSTEM76_EC + select EC_SYSTEM76_EC_LOCKDOWN + select HAVE_ACPI_RESUME + select HAVE_ACPI_TABLES + select HAVE_CMOS_DEFAULT + select HAVE_OPTION_TABLE + select INTEL_GMA_HAVE_VBT + select INTEL_LPSS_UART_FOR_CONSOLE + select MAINBOARD_HAS_TPM2 + select MEMORY_MAPPED_TPM + select NO_UART_ON_SUPERIO + select PCIEXP_SUPPORT_RESIZABLE_BARS + select SOC_INTEL_COMMON_BLOCK_HDA_VERB + select SOC_INTEL_CRASHLOG + select SOC_INTEL_PANTHERLAKE_U_H + select SPD_READ_BY_WORD + select SYSTEM_TYPE_LAPTOP + +config BOARD_SYSTEM76_LEMP14 + select BOARD_SYSTEM76_PTL_COMMON + select DRIVERS_I2C_TAS5825M + select HAVE_SPD_IN_CBFS + select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES + +if BOARD_SYSTEM76_PTL_COMMON + +config MAINBOARD_DIR + default "system76/ptl" + +config VARIANT_DIR + default "lemp14" if BOARD_SYSTEM76_LEMP14 + +config OVERRIDE_DEVICETREE + default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" + +config MAINBOARD_PART_NUMBER + default "lemp14" if BOARD_SYSTEM76_LEMP14 + +config MAINBOARD_SMBIOS_PRODUCT_NAME + default "Lemur Pro" if BOARD_SYSTEM76_LEMP14 + +config MAINBOARD_VERSION + default "lemp14" if BOARD_SYSTEM76_LEMP14 + +config CMOS_DEFAULT_FILE + default "src/mainboard/\$(MAINBOARDDIR)/cmos.default" + +config CONSOLE_POST + default y + +config D3COLD_SUPPORT + default n + +config DIMM_SPD_SIZE + default 512 + +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" + +config ONBOARD_VGA_IS_PRIMARY + default y + +config PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS + default 36 + +config POST_DEVICE + default n + +config TPM_MEASURED_BOOT + default y + +config UART_FOR_CONSOLE + default 0 + +# PM Timer Disabled, saves power +config USE_PM_ACPI_TIMER + default n + +endif diff --git a/src/mainboard/system76/ptl/Kconfig.name b/src/mainboard/system76/ptl/Kconfig.name new file mode 100644 index 0000000000..eb83581a0d --- /dev/null +++ b/src/mainboard/system76/ptl/Kconfig.name @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_SYSTEM76_LEMP14 + bool "lemp14" diff --git a/src/mainboard/system76/ptl/Makefile.mk b/src/mainboard/system76/ptl/Makefile.mk new file mode 100644 index 0000000000..08bd6b0627 --- /dev/null +++ b/src/mainboard/system76/ptl/Makefile.mk @@ -0,0 +1,17 @@ +## SPDX-License-Identifier: GPL-2.0-only + +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include + +bootblock-y += bootblock.c +bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c + +romstage-y += variants/$(VARIANT_DIR)/romstage.c + +ramstage-y += ramstage.c +ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c +ramstage-y += variants/$(VARIANT_DIR)/gpio.c +ramstage-y += variants/$(VARIANT_DIR)/ramstage.c +ramstage-$(CONFIG_DRIVERS_I2C_TAS5825M) += variants/$(VARIANT_DIR)/tas5825m.c + +subdirs-y += variants/$(VARIANT_DIR)/memory +subdirs-$(CONFIG_HAVE_SPD_IN_CBFS) += spd diff --git a/src/mainboard/system76/ptl/acpi/backlight.asl b/src/mainboard/system76/ptl/acpi/backlight.asl new file mode 100644 index 0000000000..053ce57b5d --- /dev/null +++ b/src/mainboard/system76/ptl/acpi/backlight.asl @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +Scope (GFX0) +{ + Name (BRIG, Package (22) { + 100, /* default AC */ + 100, /* default Battery */ + 5, + 10, + 15, + 20, + 25, + 30, + 35, + 40, + 45, + 50, + 55, + 60, + 65, + 70, + 75, + 80, + 85, + 90, + 95, + 100 + }) +} diff --git a/src/mainboard/system76/ptl/acpi/mainboard.asl b/src/mainboard/system76/ptl/acpi/mainboard.asl new file mode 100644 index 0000000000..c982a9ee4c --- /dev/null +++ b/src/mainboard/system76/ptl/acpi/mainboard.asl @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define EC_GPE_SCI 0x6E +#define EC_GPE_SWI 0x6B +#include + +Scope (\_SB) { + #include "sleep.asl" + Scope (PCI0) { + #include "backlight.asl" + } +} diff --git a/src/mainboard/system76/ptl/acpi/sleep.asl b/src/mainboard/system76/ptl/acpi/sleep.asl new file mode 100644 index 0000000000..8a2a22c55b --- /dev/null +++ b/src/mainboard/system76/ptl/acpi/sleep.asl @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +External(\TBTS, MethodObj) + +Method(MPTS, 1, Serialized) { + If (CondRefOf(\TBTS)) { + \TBTS() + } +} diff --git a/src/mainboard/system76/ptl/board_info.txt b/src/mainboard/system76/ptl/board_info.txt new file mode 100644 index 0000000000..e67d880062 --- /dev/null +++ b/src/mainboard/system76/ptl/board_info.txt @@ -0,0 +1,6 @@ +Vendor name: System76 +Category: laptop +ROM package: WSON-8 +ROM protocol: SPI +ROM socketed: n +Flashrom support: y diff --git a/src/mainboard/system76/ptl/bootblock.c b/src/mainboard/system76/ptl/bootblock.c new file mode 100644 index 0000000000..8d06adc9d7 --- /dev/null +++ b/src/mainboard/system76/ptl/bootblock.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +void bootblock_mainboard_early_init(void) +{ + mainboard_configure_early_gpios(); +} diff --git a/src/mainboard/system76/ptl/cmos.default b/src/mainboard/system76/ptl/cmos.default new file mode 100644 index 0000000000..0cc5970e49 --- /dev/null +++ b/src/mainboard/system76/ptl/cmos.default @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +boot_option=Fallback +debug_level=Debug +me_state=Disable diff --git a/src/mainboard/system76/ptl/cmos.layout b/src/mainboard/system76/ptl/cmos.layout new file mode 100644 index 0000000000..b3df3808cc --- /dev/null +++ b/src/mainboard/system76/ptl/cmos.layout @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0-only + +entries + +0 384 r 0 reserved_memory + +# RTC_BOOT_BYTE (coreboot hardcoded) +384 1 e 4 boot_option +388 4 h 0 reboot_counter + +# RTC_CLK_ALTCENTURY +400 8 r 0 century + +412 4 e 6 debug_level +416 1 e 2 me_state +417 3 h 0 me_state_counter + +# CMOS_VSTART_ramtop +800 80 r 0 ramtop + +984 16 h 0 check_sum + +enumerations + +2 0 Enable +2 1 Disable + +4 0 Fallback +4 1 Normal + +6 0 Emergency +6 1 Alert +6 2 Critical +6 3 Error +6 4 Warning +6 5 Notice +6 6 Info +6 7 Debug +6 8 Spew + +checksums + +checksum 408 799 984 diff --git a/src/mainboard/system76/ptl/devicetree.cb b/src/mainboard/system76/ptl/devicetree.cb new file mode 100644 index 0000000000..2c5189ca92 --- /dev/null +++ b/src/mainboard/system76/ptl/devicetree.cb @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-only + +chip soc/intel/pantherlake + register "common_soc_config" = "{ + // Touchpad I2C bus + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 80, + .fall_time_ns = 110, + }, + }" + + # Enable Enhanced Intel SpeedStep + register "eist_enable" = "true" + + # Thermal + register "tcc_offset" = "8" + + device cpu_cluster 0 on end + + device domain 0 on + device ref system_agent on end + device ref igpu on + # DDIA is eDP, TCP3 is HDMI + register "ddi_port_A_config" = "1" + register "ddi_ports_config" = "{ + [DDI_PORT_A] = DDI_ENABLE_HPD, + [DDI_PORT_3] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + }" + + #TODO: not in pantherlake chip: register "gfx" = "GMA_DEFAULT_PANEL(0)" + end + device ref npu on end + device ref pmc_shared_sram on end + device ref cnvi_wifi on + register "cnvi_wifi_core" = "true" + register "cnvi_bt_core" = "true" + register "cnvi_bt_audio_offload" = "true" + chip drivers/wifi/generic + register "wake" = "GPE0_PME_B0" + device generic 0 on end + end + end + + device ref heci1 on end + device ref soc_espi on + register "gen1_dec" = "0x00040069" # EC PM channel + register "gen2_dec" = "0x00fc0e01" # AP/EC command + register "gen3_dec" = "0x00fc0f01" # AP/EC debug + chip drivers/pc80/tpm + device pnp 0c31.0 on end + end + end + device ref p2sb on end + device ref hda on + register "pch_hda_audio_link_hda_enable" = "1" + register "pch_hda_sdi_enable[0]" = "true" + register "pch_hda_idisp_codec_enable" = "1" + register "pch_hda_idisp_link_frequency" = "HDA_LINKFREQ_96MHZ" + register "pch_hda_idisp_link_tmode" = "HDA_TMODE_8T" + end + device ref smbus on end + device ref fast_spi on end + end +end diff --git a/src/mainboard/system76/ptl/dsdt.asl b/src/mainboard/system76/ptl/dsdt.asl new file mode 100644 index 0000000000..f6e4cf756b --- /dev/null +++ b/src/mainboard/system76/ptl/dsdt.asl @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +//TODO: HACK FOR MISSING MISCCFG_GPIO_PM_CONFIG_BITS +#include + +#include +DefinitionBlock( + "dsdt.aml", + "DSDT", + ACPI_DSDT_REV_2, + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20110725 +) +{ + #include + #include + #include + #include + + Device (\_SB.PCI0) + { + #include + #include + #include + } + + #include + + Scope (\_SB.PCI0.LPCB) + { + #include + } + + #include "acpi/mainboard.asl" +} diff --git a/src/mainboard/system76/ptl/include/mainboard/gpio.h b/src/mainboard/system76/ptl/include/mainboard/gpio.h new file mode 100644 index 0000000000..c6393beebb --- /dev/null +++ b/src/mainboard/system76/ptl/include/mainboard/gpio.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef MAINBOARD_GPIO_H +#define MAINBOARD_GPIO_H + +void mainboard_configure_early_gpios(void); +void mainboard_configure_gpios(void); + +#endif diff --git a/src/mainboard/system76/ptl/ramstage.c b/src/mainboard/system76/ptl/ramstage.c new file mode 100644 index 0000000000..a3b12bb1f2 --- /dev/null +++ b/src/mainboard/system76/ptl/ramstage.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static void mainboard_init(void *chip_info) +{ + mainboard_configure_gpios(); +} + +struct chip_operations mainboard_ops = { + .init = mainboard_init, +}; diff --git a/src/mainboard/system76/ptl/spd/Makefile.mk b/src/mainboard/system76/ptl/spd/Makefile.mk new file mode 100644 index 0000000000..be4d98bd1d --- /dev/null +++ b/src/mainboard/system76/ptl/spd/Makefile.mk @@ -0,0 +1,6 @@ +## SPDX-License-Identifier: GPL-2.0-or-later +## + +ifneq ($(SPD_SOURCES),) +LIB_SPD_DEPS := $(SPD_SOURCES) +endif diff --git a/src/mainboard/system76/ptl/variants/lemp14/board.fmd b/src/mainboard/system76/ptl/variants/lemp14/board.fmd new file mode 100644 index 0000000000..c466748dc4 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/board.fmd @@ -0,0 +1,12 @@ +FLASH 32M { + SI_DESC 16K + SI_ME 9176K + SI_BIOS@16M 16M { + RW_MRC_CACHE 64K + SMMSTORE(PRESERVE) 256K + WP_RO { + FMAP 4K + COREBOOT(CBFS) + } + } +} diff --git a/src/mainboard/system76/ptl/variants/lemp14/board_info.txt b/src/mainboard/system76/ptl/variants/lemp14/board_info.txt new file mode 100644 index 0000000000..75ed180caf --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/board_info.txt @@ -0,0 +1,2 @@ +Board name: lemp14 +Release year: 2026 diff --git a/src/mainboard/system76/ptl/variants/lemp14/data.vbt b/src/mainboard/system76/ptl/variants/lemp14/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..d7979238a977974bac0992745d65ca79f1c4c15b GIT binary patch literal 7680 zcmeHMUrbw782`>~Z|Q20Zm_Lm43DrN;DAeEj1iLE^3QeSPx&*_B}O{d&Jo!_#ta%0 zu7-!cnA|62#>8r3VlXkh_-O2t!T3UEVtmlZo6F*h32$zzzjJPB=@_gdPPe6B^WAgq z{l4=%-}jwA_q(S@M>|G%(BD6Dx_hYCf3};0BBaspW#YP(Isya3V_p6c|5!)wK<8QR zVh8B!vU|6QB8(k!YufSVz}4C4Wc5%D@0%K*n2a`bMX$XvJ2lONodNE@criK|ow+a@ zjqu^oSNvSy6}mdEPfSL5|Me^5(U~^hsA(Fsd1G^ZQ#0qj6AfBZgHLNb4oO>MOWX02 zg|4pd&VjyQpw~YV80hB%L%b_6>>nQP?(671&x1n)rvn{ z4)Tx_RRe4X>tGJ{fE92qq1+TS$30LcEAmW2lT*8+dmL0)pK4fgtv>ha*G|k?yA|%^Pd65WFq( zHko1oK_$CDXvgZ=-V3dk76(bwwdvI2h7D*a(A;xsX-)`pe6ZA`dp033Q=|>KB7E5} zw>DT>rH2+XHZW5p6Xez%%Q@I^`joDXFZ*;okwI{f%%I$(YA%ty^y28!AeC!9W@;=% zBu$YA5=_Y@4)4~R@o;ImuJP1ZAd+@-kMzPQ$i<85b|XH$TnU6)(Mrw-)s!!3cU)b_ zVLp6Z6JH%%sL+Bp4yF-o^qi<8lDQygwfahUA)Y^4!g&D9S!?nnc>WTMnYF*rRsKVm3POBRtxXj>YKD9%uxRx}T#UMd%p&kdPlq zC+EdmEjcgh`?Bc(o(n&BMWW?+HeDpD*BHgp^mJ4$_csFZpO;PYWndZ6+=30v#C{^T z*89dKnLH)OOKjr8%GK0afY_3Y=3h8fg5ej_U^{AWC#P?ss;7lf<-}DVK2gW2+sOxY z`5}uk-*YB*`Dp+9Gi;q%zgY33*D@oMU2{lky=mnV*|Mkn?&SM+2lj(Js!`9f4{6UG97XJ6~=*Cp0+aqnR#9zqrj3a z+biL@bwDm;_Bf-sy2^rdgBENRz_fBQArt=TjurCKAY>7t4W=FAl7ReZp@>TyDIlz| z9Ym{4TuQoxEnfIuN3Hg{EIU7b4`brQpD*~4qZqcxQzzNqPUH71$Pl(X?G%B30ErNY A3IG5A literal 0 HcmV?d00001 diff --git a/src/mainboard/system76/ptl/variants/lemp14/gpio.c b/src/mainboard/system76/ptl/variants/lemp14/gpio.c new file mode 100644 index 0000000000..d81813108f --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/gpio.c @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config gpio_table[] = { + PAD_CFG_NF(GPP_A00, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_A01, 1, DEEP), + PAD_CFG_GPO(GPP_A02, 1, DEEP), + PAD_CFG_GPO(GPP_A03, 1, DEEP), + PAD_CFG_GPO(GPP_A04, 1, DEEP), + PAD_CFG_GPO(GPP_A05, 1, DEEP), + PAD_CFG_GPO(GPP_A06, 1, DEEP), + PAD_CFG_GPO(GPP_A07, 1, DEEP), + PAD_CFG_NF(GPP_A08, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_A09, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_A10, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_A11, UP_20K, DEEP, NF1), + PAD_NC(GPP_A12, NATIVE), + PAD_CFG_NF(GPP_A13, NATIVE, DEEP, NF2), + _PAD_CFG_STRUCT(GPP_A14, 0x40001300, 0x3c00), + PAD_CFG_NF(GPP_A15, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_A16, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_A17, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_B00, NONE, PWROK, NF1), + PAD_CFG_NF(GPP_B01, NONE, PWROK, NF1), + PAD_CFG_GPO(GPP_B02, 1, DEEP), + PAD_CFG_GPO(GPP_B03, 1, DEEP), + PAD_CFG_GPO(GPP_B04, 1, DEEP), + PAD_CFG_GPO(GPP_B05, 1, DEEP), + PAD_CFG_GPO(GPP_B06, 0, PLTRST), + PAD_CFG_GPO(GPP_B07, 1, DEEP), + PAD_CFG_GPO(GPP_B08, 1, DEEP), + PAD_CFG_GPO(GPP_B09, 1, PLTRST), + PAD_CFG_GPO(GPP_B10, 1, PLTRST), + PAD_NC(GPP_B11, NONE), + PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_B14, NONE, DEEP, NF2), + PAD_NC(GPP_B15, NONE), + PAD_CFG_GPO(GPP_B16, 1, DEEP), + PAD_CFG_GPO(GPP_B17, 1, DEEP), + PAD_CFG_GPO(GPP_B18, 1, DEEP), + PAD_CFG_GPO(GPP_B19, 1, DEEP), + PAD_NC(GPP_B20, NONE), + PAD_CFG_GPO(GPP_B21, 0, PLTRST), + PAD_CFG_GPO(GPP_B22, 1, DEEP), + PAD_CFG_GPO(GPP_B23, 1, DEEP), + PAD_CFG_GPO(GPP_B24, 1, DEEP), + PAD_CFG_GPO(GPP_B25, 1, DEEP), + PAD_CFG_NF(GPP_C00, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_C01, UP_20K, DEEP, NF1), + PAD_CFG_GPO(GPP_C02, 1, DEEP), + PAD_CFG_NF(GPP_C03, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_C04, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_C05, 1, DEEP), + PAD_NC(GPP_C06, NONE), + PAD_NC(GPP_C07, NONE), + PAD_CFG_GPO(GPP_C08, 1, DEEP), + PAD_CFG_GPO(GPP_C09, 1, DEEP), + PAD_CFG_GPO(GPP_C10, 1, DEEP), + PAD_CFG_GPO(GPP_C11, 1, DEEP), + PAD_CFG_NF(GPP_C12, NONE, PLTRST, NF1), + PAD_CFG_NF(GPP_C13, NONE, PLTRST, NF1), + PAD_CFG_NF(GPP_C14, NONE, PLTRST, NF1), + PAD_CFG_GPO(GPP_C15, 1, DEEP), + //TODO PAD_CFG_NF(GPP_C16, NONE, TODO_0xc4000700, NF1), + //TODO PAD_CFG_NF(GPP_C17, NONE, TODO_0xc4000700, NF1), + PAD_CFG_GPO(GPP_C18, 1, DEEP), + PAD_CFG_GPO(GPP_C19, 1, DEEP), + PAD_CFG_GPO(GPP_C20, 1, DEEP), + PAD_CFG_GPO(GPP_C21, 1, DEEP), + PAD_CFG_NF(GPP_C22, NONE, DEEP, NF2), + PAD_CFG_NF(GPP_C23, NONE, DEEP, NF2), + PAD_CFG_GPO(GPP_D00, 1, PLTRST), + PAD_CFG_GPO(GPP_D01, 1, DEEP), + PAD_CFG_GPO(GPP_D02, 1, DEEP), + PAD_CFG_GPO(GPP_D03, 1, DEEP), + PAD_CFG_GPO(GPP_D04, 1, DEEP), + PAD_CFG_GPO(GPP_D05, 1, DEEP), + PAD_CFG_GPO(GPP_D06, 1, DEEP), + PAD_CFG_GPO(GPP_D07, 1, DEEP), + PAD_CFG_GPO(GPP_D08, 1, DEEP), + PAD_CFG_GPO(GPP_D09, 1, DEEP), + PAD_CFG_NF(GPP_D10, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_D11, NATIVE, DEEP, NF1), + PAD_CFG_NF(GPP_D12, NATIVE, DEEP, NF1), + PAD_CFG_NF(GPP_D13, NATIVE, DEEP, NF1), + PAD_CFG_GPO(GPP_D14, 1, DEEP), + PAD_NC(GPP_D15, NONE), + PAD_CFG_NF(GPP_D16, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_D17, 1, DEEP), + PAD_CFG_NF(GPP_D18, NONE, PLTRST, NF1), + PAD_CFG_GPO(GPP_D19, 1, PLTRST), + PAD_CFG_GPO(GPP_D20, 1, DEEP), + PAD_CFG_GPO(GPP_D21, 1, DEEP), + PAD_CFG_NF(GPP_D22, NATIVE, DEEP, NF1), + PAD_CFG_NF(GPP_D23, NATIVE, DEEP, NF1), + PAD_CFG_GPO(GPP_D24, 1, DEEP), + PAD_CFG_GPO(GPP_D25, 1, DEEP), + _PAD_CFG_STRUCT(GPP_E01, 0x42880100, 0x0000), + PAD_NC(GPP_E02, NONE), + PAD_CFG_GPO(GPP_E03, 1, DEEP), + PAD_CFG_GPO(GPP_E04, 1, DEEP), + PAD_CFG_GPO(GPP_E05, 1, DEEP), + PAD_CFG_GPO(GPP_E06, 1, DEEP), + PAD_CFG_GPO(GPP_E07, 1, DEEP), + PAD_NC(GPP_E08, NONE), + PAD_NC(GPP_E09, NONE), + PAD_CFG_GPO(GPP_E10, 1, DEEP), + PAD_CFG_GPI(GPP_E11, NONE, DEEP), + _PAD_CFG_STRUCT(GPP_E12, 0x44002300, 0x0000), + _PAD_CFG_STRUCT(GPP_E13, 0x44002300, 0x0000), + PAD_CFG_GPI(GPP_E14, NONE, DEEP), + PAD_CFG_GPI(GPP_E15, NONE, DEEP), + PAD_CFG_GPO(GPP_E16, 1, DEEP), + PAD_CFG_GPI(GPP_E17, NONE, DEEP), + PAD_CFG_GPO(GPP_E18, 1, DEEP), + PAD_CFG_GPO(GPP_E19, 1, DEEP), + PAD_CFG_GPO(GPP_E20, 1, DEEP), + PAD_CFG_NF(GPP_E21, NONE, PWROK, NF1), + PAD_CFG_GPO(GPP_E22, 1, DEEP), + PAD_CFG_NF(GPP_F00, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_F01, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_F02, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_F03, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_F04, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_F05, NONE, DEEP, NF3), + PAD_CFG_GPO(GPP_F06, 1, DEEP), + PAD_CFG_GPO(GPP_F07, 1, DEEP), + PAD_CFG_GPO(GPP_F08, 1, DEEP), + PAD_CFG_GPI(GPP_F09, NONE, DEEP), + PAD_CFG_GPO(GPP_F10, 1, DEEP), + PAD_CFG_GPO(GPP_F11, 1, DEEP), + _PAD_CFG_STRUCT(GPP_F12, 0x44002300, 0x0000), + _PAD_CFG_STRUCT(GPP_F13, 0x44002300, 0x0000), + PAD_CFG_GPO(GPP_F14, 1, DEEP), + PAD_CFG_GPO(GPP_F15, 1, DEEP), + PAD_CFG_GPO(GPP_F16, 1, PLTRST), + PAD_CFG_GPO(GPP_F17, 1, DEEP), + _PAD_CFG_STRUCT(GPP_F18, 0x80800100, 0x0000), + PAD_CFG_GPO(GPP_F19, 1, DEEP), + PAD_CFG_GPO(GPP_F20, 1, DEEP), + PAD_CFG_GPO(GPP_F21, 1, DEEP), + PAD_CFG_GPO(GPP_F22, 1, DEEP), + PAD_CFG_GPO(GPP_F23, 1, DEEP), + PAD_CFG_NF(GPP_H00, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H01, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H02, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H03, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H04, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H05, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H06, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_H07, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H09, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_H10, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_H11, DN_20K, DEEP, NF1), + //TODO: PAD_CFG_NF(GPP_H12, TODO_0x2400, DEEP, NF1), + PAD_CFG_NF(GPP_H13, DN_20K, DEEP, NF1), + PAD_CFG_NF(GPP_H14, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_H15, 1, DEEP), + PAD_CFG_GPO(GPP_H16, 1, DEEP), + PAD_CFG_GPO(GPP_H17, 1, DEEP), + PAD_NC(GPP_H18, NONE), + _PAD_CFG_STRUCT(GPP_H19, 0x44000601, 0x0000), + _PAD_CFG_STRUCT(GPP_H20, 0x44000601, 0x0000), + PAD_CFG_GPO(GPP_H21, 1, DEEP), + PAD_CFG_GPO(GPP_H22, 1, DEEP), + PAD_NC(GPP_H23, NONE), + PAD_NC(GPP_H24, NONE), + PAD_CFG_GPO(GPP_S00, 1, DEEP), + PAD_CFG_GPO(GPP_S01, 1, DEEP), + PAD_CFG_GPO(GPP_S02, 1, DEEP), + PAD_CFG_GPO(GPP_S03, 1, DEEP), + PAD_CFG_GPO(GPP_S04, 1, DEEP), + PAD_CFG_GPO(GPP_S05, 1, DEEP), + PAD_CFG_GPO(GPP_S06, 1, DEEP), + PAD_CFG_GPO(GPP_S07, 1, DEEP), + PAD_CFG_NF(GPP_V00, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_V01, NATIVE, DEEP, NF1), + PAD_CFG_NF(GPP_V02, NATIVE, DEEP, NF1), + PAD_CFG_NF(GPP_V03, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_V04, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_V05, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_V06, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_V07, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_V08, 1, DEEP), + PAD_CFG_GPO(GPP_V09, 1, DEEP), + PAD_CFG_GPO(GPP_V10, 1, DEEP), + PAD_CFG_GPO(GPP_V11, 1, DEEP), + PAD_CFG_NF(GPP_V12, NONE, DEEP, NF1), + _PAD_CFG_STRUCT(GPP_V13, 0x44000601, 0x0000), + _PAD_CFG_STRUCT(GPP_V14, 0x44000601, 0x0000), + _PAD_CFG_STRUCT(GPP_V15, 0x44000601, 0x0000), + PAD_CFG_NF(GPP_V16, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_V17, 1, DEEP), +}; + +void mainboard_configure_gpios(void) +{ + gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); +} diff --git a/src/mainboard/system76/ptl/variants/lemp14/gpio_early.c b/src/mainboard/system76/ptl/variants/lemp14/gpio_early.c new file mode 100644 index 0000000000..a2a5e5bb19 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/gpio_early.c @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config early_gpio_table[] = { + PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), // SMB_CLK + PAD_CFG_NF(GPP_C01, NONE, DEEP, NF1), // SMB_DATA + PAD_CFG_GPI(GPP_E11, NONE, DEEP), // BOARD_ID1 + PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), // UART0_RX + PAD_CFG_NF(GPP_H09, NONE, DEEP, NF1), // UART0_TX +}; + +void mainboard_configure_early_gpios(void) +{ + gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table)); +} diff --git a/src/mainboard/system76/ptl/variants/lemp14/hda_verb.c b/src/mainboard/system76/ptl/variants/lemp14/hda_verb.c new file mode 100644 index 0000000000..004c6fc685 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/hda_verb.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +const u32 cim_verb_data[] = { + /* Realtek, ALC245 */ + 0x10ec0245, /* Vendor ID */ + 0x15582a00, /* Subsystem ID */ + 34, /* Number of entries */ + + AZALIA_SUBVENDOR(0, 0x15582a00), + AZALIA_RESET(1), + AZALIA_PIN_CFG(0, 0x12, 0x90a60130), + AZALIA_PIN_CFG(0, 0x13, 0x40000000), + AZALIA_PIN_CFG(0, 0x14, 0x411111f0), + AZALIA_PIN_CFG(0, 0x17, 0x90170110), + AZALIA_PIN_CFG(0, 0x18, 0x411111f0), + AZALIA_PIN_CFG(0, 0x19, 0x411111f0), + AZALIA_PIN_CFG(0, 0x1a, 0x411111f0), + AZALIA_PIN_CFG(0, 0x1b, 0x411111f0), + AZALIA_PIN_CFG(0, 0x1d, 0x41789b2d), + AZALIA_PIN_CFG(0, 0x1e, 0x411111f0), + AZALIA_PIN_CFG(0, 0x21, 0x04211020), + + //TODO: VERIFY THESE COMMANDS + 0x05b50006, 0x05b40011, 0x0205001a, 0x0204810b, + 0x0205004a, 0x02042010, 0x02050038, 0x02046909, + 0x05c50000, 0x05c43d82, 0x05c50000, 0x05c43d82, + 0x05350000, 0x0534201a, 0x05350000, 0x0534201a, + 0x0535001d, 0x05340800, 0x0535001e, 0x05340800, + 0x05350003, 0x05341ec4, 0x05350004, 0x05340000, + 0x05450000, 0x05442000, 0x0545001d, 0x05440800, + 0x0545001e, 0x05440800, 0x05450003, 0x05441ec4, + 0x05450004, 0x05440000, 0x05350000, 0x0534a01a, + 0x0205003c, 0x0204f175, 0x0205003c, 0x0204f135, + 0x02050040, 0x02048800, 0x05a50001, 0x05a4001f, + 0x02050010, 0x02040020, 0x02050010, 0x02040020, + 0x0205006b, 0x0204a390, 0x0205006b, 0x0204a390, + 0x0205006c, 0x02040c9e, 0x0205006d, 0x02040c00, + 0x00170500, 0x00170500, 0x05a50004, 0x05a40113, + 0x02050008, 0x02046a8c, 0x02050076, 0x0204f000, + 0x0205000e, 0x020465c0, 0x02050033, 0x02048580, + 0x02050069, 0x0204fda8, 0x02050068, 0x02040000, + 0x02050003, 0x02040002, 0x02050069, 0x02040000, + 0x02050068, 0x02040001, 0x0205002e, 0x0204290e, + 0x02050010, 0x02040020, 0x02050010, 0x02040020, +}; + +const u32 pc_beep_verbs[] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/system76/ptl/variants/lemp14/memory/Makefile.mk b/src/mainboard/system76/ptl/variants/lemp14/memory/Makefile.mk new file mode 100644 index 0000000000..2909100fa2 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/memory/Makefile.mk @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# This is an auto-generated file. Do not edit!! +# Generated by: +# util/spd_tools/bin/part_id_gen PTL lp5 src/mainboard/system76/ptl/variants/lemp14/memory src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt + +SPD_SOURCES = +SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 0(0b0000) Parts = MT62F1G32D4DR-031 WT:B diff --git a/src/mainboard/system76/ptl/variants/lemp14/memory/dram_id.generated.txt b/src/mainboard/system76/ptl/variants/lemp14/memory/dram_id.generated.txt new file mode 100644 index 0000000000..4e6a073f96 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/memory/dram_id.generated.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# This is an auto-generated file. Do not edit!! +# Generated by: +# util/spd_tools/bin/part_id_gen PTL lp5 src/mainboard/system76/ptl/variants/lemp14/memory src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt + +DRAM Part Name ID to assign +MT62F1G32D4DR-031 WT:B 0 (0000) diff --git a/src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt b/src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt new file mode 100644 index 0000000000..b079d45cde --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt @@ -0,0 +1,12 @@ +# This is a CSV file containing a list of memory parts used by this variant. +# One part per line with an optional fixed ID in column 2. +# Only include a fixed ID if it is required for legacy reasons! +# Generated IDs are dependent on the order of parts in this file, +# so new parts must always be added at the end of the file! +# +# Generate an updated Makefile.mk and dram_id.generated.txt by running the +# part_id_gen tool from util/spd_tools. +# See util/spd_tools/README.md for more details and instructions. + +# Part Name +MT62F1G32D4DR-031 WT:B diff --git a/src/mainboard/system76/ptl/variants/lemp14/overridetree.cb b/src/mainboard/system76/ptl/variants/lemp14/overridetree.cb new file mode 100644 index 0000000000..3193b169a7 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/overridetree.cb @@ -0,0 +1,112 @@ +# SPDX-License-Identifier: GPL-2.0-only + +chip soc/intel/pantherlake + #TODO: POWER LIMITS + #register "power_limits_config[RPL_P_282_242_142_15W_CORE]" = "{ + # .tdp_pl1_override = 15, + # .tdp_pl2_override = 46, + #}" + + device domain 0 on + subsystemid 0x1558 0x2a00 inherit + + device ref tbt_pcie_rp0 on end + device ref tcss_xhci on + register "tcss_ports[0]" = "TCSS_PORT_DEFAULT(OC_SKIP)" + #TODO: TCP1 goes to redriver, then USB Type-C + register "tcss_ports[1]" = "TCSS_PORT_DEFAULT(OC_SKIP)" + #TODO: TCP2 is used as USB Type-A + register "tcss_ports[2]" = "TCSS_PORT_DEFAULT(OC_SKIP)" + #TODO: TCP3 is used as HDMI + chip drivers/usb/acpi + device ref tcss_root_hub on + chip drivers/usb/acpi + register "desc" = ""TBT Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + device ref tcss_usb3_port0 on end + end + chip drivers/usb/acpi + register "desc" = ""USB Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + device ref tcss_usb3_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""USB Type-A"" + register "type" = "UPC_TYPE_USB3_A" + device ref tcss_usb3_port2 on end + end + end + end + end + device ref tcss_dma0 on end + device ref xhci on + register "usb2_ports" = "{ + [0] = USB2_PORT_TYPE_C(OC_SKIP), /* USB Type-C */ + [1] = USB2_PORT_TYPE_C(OC_SKIP), /* TBT Type-C */ + [2] = USB2_PORT_MID(OC_SKIP), /* USB 3.2 Gen 2 Type-A */ + [4] = USB2_PORT_MID(OC_SKIP), /* USB 3.2 Gen 1 Type-A */ + [6] = USB2_PORT_MID(OC_SKIP), /* Camera */ + [7] = USB2_PORT_MID(OC_SKIP), /* Bluetooth */ + }" + register "usb3_ports" = "{ + [0] = USB3_PORT_DEFAULT(OC_SKIP), /* USB 3.2 Gen 1 Type-A */ + }" + end + + device ref i2c4 on + # Smart Amplifier I2C bus + register "serial_io_i2c_mode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + chip drivers/i2c/tas5825m + register "id" = "0" + device i2c 4e on end # (8bit address: 0x9c) + end + end + device ref i2c5 on + # Touchpad I2C bus + register "serial_io_i2c_mode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" + chip drivers/i2c/hid + register "generic.hid" = ""ELAN0412"" + register "generic.desc" = ""ELAN Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A17)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 15 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""FTCS1000"" + register "generic.desc" = ""FocalTech Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A17)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 38 on end + end + end + + device ref pcie_rp1 on + # CPU RP#1 x4, Clock 6 (SSD1) + register "pcie_rp[PCIE_RP(1)]" = "{ + .clk_src = 6, + .clk_req = 6, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M.2/M 2280 (J_SSD1)" "SlotDataBusWidth4X" + end + device ref pcie_rp7 on + # PCH RP#7 x1, Clock 3 (CARD) + register "pcie_rp[PCH_RP(7)]" = "{ + .clk_src = 3, + .clk_req = 3, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref pcie_rp8 on + # PCH RP#8 x1, Clock 4 (WLAN) + register "pcie_rp[PCH_RP(8)]" = "{ + .clk_src = 4, + .clk_req = 4, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + smbios_slot_desc "SlotTypeM2Socket1_SD" "SlotLengthOther" "M.2/E 2230 (J_WLAN1)" "SlotDataBusWidth1X" + end + end +end diff --git a/src/mainboard/system76/ptl/variants/lemp14/ramstage.c b/src/mainboard/system76/ptl/variants/lemp14/ramstage.c new file mode 100644 index 0000000000..9118fea7e9 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/ramstage.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void mainboard_silicon_init_params(FSP_S_CONFIG *params) +{ + // TODO: Pin Mux settings + + // Enable TCP2 USB-A conversion + // BIT 0:3 is mapping to PCH XHCI USB2 port + // BIT 4:5 is reserved + // BIT 6 is orientational + // BIT 7 is enable + params->EnableTcssCovTypeA[2] = 0x83; + + // Disable reporting CPU C10 state over eSPI (causes LED flicker). + params->PchEspiHostC10ReportEnable = 0; +} diff --git a/src/mainboard/system76/ptl/variants/lemp14/romstage.c b/src/mainboard/system76/ptl/variants/lemp14/romstage.c new file mode 100644 index 0000000000..f5413d4629 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/romstage.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +// Verified from lemp14 schematic mappings +static const struct mb_cfg board_cfg = { + .type = MEM_TYPE_LP5X, + + .lpx_dq_map = { + .ddr0 = { + .dq0 = { 13, 14, 12, 15, 11, 10, 8, 9, }, + .dq1 = { 7, 5, 4, 6, 0, 3, 1, 2 }, + }, + .ddr1 = { + .dq0 = { 1, 3, 0, 2, 7, 4, 6, 5, }, + .dq1 = { 12, 13, 14, 15, 11, 10, 9, 8 }, + }, + .ddr2 = { + .dq0 = { 0, 2, 1, 3, 6, 4, 7, 5 }, + .dq1 = { 14, 13, 15, 12, 8, 11, 10, 9, }, + }, + .ddr3 = { + .dq0 = { 6, 5, 7, 4, 2, 3, 1, 0, }, + .dq1 = { 10, 8, 11, 9, 12, 15, 13, 14 }, + }, + .ddr4 = { + .dq0 = { 2, 1, 3, 0, 4, 7, 5, 6 }, + .dq1 = { 15, 14, 12, 13, 9, 11, 10, 8, }, + }, + .ddr5 = { + .dq0 = { 6, 5, 7, 4, 3, 1, 0, 2, }, + .dq1 = { 10, 9, 11, 8, 13, 14, 12, 15 }, + }, + .ddr6 = { + .dq0 = { 9, 10, 11, 8, 14, 12, 13, 15, }, + .dq1 = { 0, 1, 2, 3, 5, 7, 4, 6 }, + }, + .ddr7 = { + .dq0 = { 0, 1, 2, 3, 7, 5, 6, 4, }, + .dq1 = { 14, 13, 15, 12, 10, 8, 11, 9 }, + }, + }, + + .lpx_dqs_map = { + .ddr0 = { .dqs0 = 1, .dqs1 = 0 }, + .ddr1 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr2 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr3 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr4 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr5 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr6 = { .dqs0 = 1, .dqs1 = 0 }, + .ddr7 = { .dqs0 = 0, .dqs1 = 1 } + }, + + .ect = true, /* Early Command Training */ + + .user_bd = BOARD_TYPE_ULT_ULX, + + .lp5x_config = { + .ccc_config = 0xFF, + }, +}; + +static const struct mem_spd spd_info = { + .topo = MEM_TOPO_MEMORY_DOWN, + .cbfs_index = 0, +}; + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + const bool half_populated = false; + + mupd->FspmConfig.GpioOverride = 0; + + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); +} diff --git a/src/mainboard/system76/ptl/variants/lemp14/tas5825m.c b/src/mainboard/system76/ptl/variants/lemp14/tas5825m.c new file mode 100644 index 0000000000..171d9c1ed2 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/tas5825m.c @@ -0,0 +1,1049 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +int tas5825m_setup(struct device *dev, int id) +{ + int res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x01, 0x11); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + mdelay(5); + + res = tas5825m_write_at(dev, 0x03, 0x12); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x48, 0x0C); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x7F, 0x64); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xFE, 0x00, 0x40, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x50, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x93, 0x00, 0xFC, 0x00, 0x00, + 0x8F, 0x00, 0xFF, 0xEF, 0x84, 0x49, 0x03, 0x27, + 0x84, 0x02, 0x04, 0x06, 0x02, 0x60, 0x00, 0x01, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x70, 0x00, 0x06, 0x02, 0x78, 0x00, 0x05, + 0x02, 0x68, 0x00, 0x02, 0x02, 0x28, 0x03, 0x4D, + 0x84, 0x2A, 0x04, 0x00, 0xE2, 0x57, 0x91, 0x9F, + 0x84, 0x82, 0x20, 0xE0, 0x84, 0x82, 0x04, 0x01, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x68, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x27, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x41, 0x03, 0x37, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x00, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x11, 0xAA, 0xF0, 0x1C, 0x11, 0xAB, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1C, 0x11, 0xAC, 0xF0, 0x1F, 0x11, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x43, 0x03, 0x37, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x51, 0x03, 0x3E, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x47, 0x84, 0xC2, 0x40, 0xE0, + 0x8C, 0xFF, 0x03, 0x23, 0xE0, 0x10, 0x11, 0xB3, + 0xF0, 0x1C, 0x51, 0xB4, 0xF0, 0x1C, 0x51, 0xB5, + 0xF0, 0x1C, 0x51, 0xB6, 0xF0, 0x1F, 0x51, 0xB7, + 0x86, 0xA1, 0x01, 0xC6, 0x80, 0x27, 0x80, 0xEA, + 0x84, 0x53, 0x03, 0x3E, 0x84, 0x82, 0x04, 0x05, + 0x84, 0x51, 0x03, 0x75, 0xE2, 0x6B, 0xC0, 0x00, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x80, 0x31, 0xB8, + 0x84, 0x82, 0x40, 0xE0, 0xF0, 0x1C, 0x51, 0xB9, + 0xF0, 0x1C, 0x51, 0xBA, 0xF0, 0x1C, 0x51, 0xBB, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1F, 0x51, 0xBC, 0x86, 0xA1, 0x01, 0xC5, + 0x80, 0x27, 0x80, 0xEA, 0x60, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x81, 0x84, 0xA1, 0x03, 0x4F, + 0xE0, 0x80, 0xA0, 0x00, 0x01, 0x07, 0x11, 0x20, + 0x08, 0x44, 0x26, 0x30, 0x08, 0x00, 0x98, 0x4A, + 0x84, 0x53, 0x03, 0x75, 0x08, 0x00, 0x30, 0x48, + 0x02, 0xCA, 0x00, 0x01, 0x08, 0x60, 0x26, 0x32, + 0x84, 0x51, 0x03, 0x45, 0xE4, 0x10, 0x40, 0x00, + 0x80, 0x40, 0xC0, 0x82, 0x84, 0xC2, 0x40, 0xE0, + 0x84, 0xC3, 0x03, 0x5E, 0x08, 0x00, 0x50, 0x48, + 0xE0, 0x10, 0x11, 0xBD, 0x02, 0xC2, 0x00, 0x02, + 0x08, 0x60, 0x06, 0x12, 0x84, 0xD3, 0x03, 0x4F, + 0xF0, 0x1C, 0x51, 0xBE, 0xF0, 0x1C, 0x51, 0xBF, + 0xF0, 0x1C, 0x51, 0xC0, 0xF0, 0x1F, 0x51, 0xC1, + 0x84, 0xA1, 0x03, 0x65, 0x80, 0x27, 0x80, 0xEA, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x83, + 0x08, 0x00, 0x98, 0x6B, 0x08, 0x00, 0x30, 0x68, + 0x84, 0x53, 0x03, 0x45, 0x08, 0x60, 0x26, 0x33, + 0x84, 0x51, 0x03, 0x25, 0xE4, 0x10, 0x60, 0x00, + 0x80, 0x40, 0xC0, 0x81, 0x02, 0x70, 0x00, 0x7F, + 0x08, 0x00, 0x50, 0x28, 0x08, 0x60, 0x06, 0x11, + 0x84, 0xCB, 0x03, 0x65, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x01, + 0x84, 0xA2, 0x04, 0x03, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x25, 0x80, 0x00, 0xC4, 0x04, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x60, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x02, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x60, 0x00, 0x01, 0x02, 0x70, 0x00, 0x04, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0x41, 0x03, 0x67, + 0x84, 0x51, 0x03, 0x6D, 0x84, 0xC0, 0x04, 0x02, + 0x04, 0x80, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x02, 0x78, 0x00, 0x03, 0x02, 0x68, 0x00, 0x02, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + 0x84, 0x49, 0x03, 0x2F, 0xE0, 0x80, 0x71, 0xA9, + 0x02, 0x28, 0x03, 0x55, 0x84, 0x82, 0x00, 0xE0, + 0x84, 0x2A, 0x04, 0x00, 0xF0, 0x1C, 0x11, 0xAA, + 0xF0, 0x1C, 0x11, 0xAB, 0xF0, 0x1C, 0x11, 0xAC, + 0xF0, 0x1F, 0x11, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xE8, 0x84, 0x82, 0x04, 0x07, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x80, 0x60, 0x00, 0x84, 0x82, 0x40, 0xE0, + 0x84, 0x43, 0x03, 0x67, 0xF0, 0x1C, 0x51, 0xAF, + 0xF0, 0x1C, 0x51, 0xB0, 0xF0, 0x1C, 0x51, 0xB1, + 0xF0, 0x1F, 0x51, 0xB2, 0x02, 0x78, 0x00, 0x05, + 0x80, 0x27, 0x80, 0xEA, 0x84, 0x82, 0x04, 0x08, + 0x02, 0x70, 0x00, 0x06, 0x84, 0x53, 0x03, 0x6D, + 0x84, 0x80, 0x04, 0x07, 0xE0, 0x00, 0x00, 0x82, + 0xF0, 0x81, 0x00, 0x80, 0x80, 0x07, 0x12, 0xBC, + 0x86, 0xA1, 0x01, 0x9F, 0xE2, 0x57, 0xA0, 0x00, + 0x84, 0x82, 0x04, 0x09, 0x84, 0x82, 0x20, 0xE0, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x08); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x6A, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x2F, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x59, 0x03, 0x3D, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x60, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x71, 0xAA, 0xF0, 0x1C, 0x71, 0xAB, + 0xF0, 0x1C, 0x71, 0xAC, 0xF0, 0x1F, 0x71, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xEB, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x5B, 0x03, 0x3D, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x59, 0x03, 0x3F, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x57, 0x84, 0xC2, 0x60, 0xE0, + 0xE0, 0x10, 0x11, 0xB3, 0xF0, 0x1C, 0x71, 0xB4, + 0xF0, 0x1C, 0x71, 0xB5, 0xF0, 0x1C, 0x71, 0xB6, + 0xF0, 0x1F, 0x71, 0xB7, 0x86, 0xA1, 0x01, 0xC6, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x09); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x80, 0x27, 0x80, 0xEB, 0x84, 0x5B, 0x03, 0x3F, + 0x84, 0x82, 0x04, 0x0D, 0x84, 0x41, 0x03, 0x76, + 0xE2, 0x6B, 0xE0, 0x00, 0x80, 0x07, 0x00, 0x80, + 0xE0, 0x81, 0x31, 0xB8, 0x84, 0x82, 0x00, 0xE0, + 0xF0, 0x1C, 0x11, 0xB9, 0xF0, 0x1C, 0x11, 0xBA, + 0xF0, 0x1C, 0x11, 0xBB, 0xF0, 0x1F, 0x11, 0xBC, + 0x86, 0xA1, 0x01, 0xC5, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x81, + 0x84, 0xA1, 0x03, 0x5D, 0xE0, 0x81, 0xA0, 0x00, + 0x01, 0x07, 0x11, 0x20, 0x08, 0x44, 0x26, 0x30, + 0x08, 0x00, 0x98, 0x4A, 0x84, 0x43, 0x03, 0x76, + 0x08, 0x00, 0x30, 0x48, 0x02, 0xCA, 0x00, 0x01, + 0x08, 0x60, 0x26, 0x32, 0x84, 0x41, 0x03, 0x46, + 0xE4, 0x10, 0x40, 0x00, 0x80, 0x40, 0xC0, 0x82, + 0x84, 0xC2, 0x00, 0xE0, 0x84, 0xC3, 0x03, 0x5F, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x50, 0x48, 0xE0, 0x10, 0x11, 0xBD, + 0x02, 0xC2, 0x00, 0x02, 0x08, 0x60, 0x06, 0x12, + 0x84, 0xD3, 0x03, 0x5D, 0xF0, 0x1C, 0x11, 0xBE, + 0xF0, 0x1C, 0x11, 0xBF, 0xF0, 0x1C, 0x11, 0xC0, + 0xF0, 0x1F, 0x11, 0xC1, 0x84, 0xA1, 0x03, 0x66, + 0x80, 0x27, 0x80, 0xE8, 0xE0, 0x00, 0x00, 0x00, + 0x80, 0x07, 0x00, 0x83, 0x08, 0x00, 0x98, 0x6B, + 0x08, 0x00, 0x30, 0x68, 0x84, 0x43, 0x03, 0x46, + 0x08, 0x60, 0x26, 0x33, 0x84, 0x51, 0x03, 0x26, + 0xE4, 0x10, 0x60, 0x00, 0x80, 0x40, 0xC0, 0x81, + 0x02, 0x70, 0x00, 0x7F, 0x08, 0x00, 0x50, 0x28, + 0x08, 0x60, 0x06, 0x11, 0x8C, 0xFF, 0x03, 0x24, + 0x84, 0xCB, 0x03, 0x66, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x09, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0xA2, 0x04, 0x0B, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x26, 0x80, 0x00, 0xC4, 0x0C, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x80, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x0A, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x70, 0x00, 0x04, 0x02, 0x68, 0x00, 0x01, + 0x02, 0x60, 0x00, 0x03, 0x02, 0x78, 0x00, 0x02, + 0x84, 0x49, 0x03, 0x6E, 0x84, 0x41, 0x03, 0x6F, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0xC0, 0x04, 0x0A, + 0x04, 0x81, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0x00, 0x04, 0x06, 0xE0, 0x81, 0x71, 0xA9, + 0x84, 0x82, 0x20, 0xE8, 0xF0, 0x1D, 0x31, 0xAA, + 0xF0, 0x1D, 0x31, 0xAB, 0xF0, 0x1D, 0x31, 0xAC, + 0xF0, 0x1C, 0x31, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xF9, 0x84, 0x82, 0x04, 0x0E, + 0xE0, 0x81, 0x60, 0x00, 0x84, 0x82, 0x00, 0xE8, + 0x84, 0x4B, 0x03, 0x6E, 0xF0, 0x1D, 0x11, 0xAF, + 0xF0, 0x1D, 0x11, 0xB0, 0xF0, 0x1D, 0x11, 0xB1, + 0xF0, 0x1C, 0x11, 0xB2, 0x02, 0xA3, 0x00, 0x1A, + 0x80, 0x27, 0x80, 0xF8, 0x84, 0x82, 0x04, 0x0F, + 0xE0, 0x81, 0xC0, 0x00, 0xF0, 0x81, 0xE0, 0x80, + 0x84, 0x43, 0x03, 0x6F, 0x80, 0x07, 0x12, 0xBD, + 0x02, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x11, 0x8F, 0x00, 0xFF, 0xFF, + 0x84, 0x58, 0x04, 0x01, 0x84, 0xC2, 0x04, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0xC2, 0x60, 0x00, 0x84, 0xA0, 0x61, 0x00, + 0xE0, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x40, 0x40, 0xA0, 0x00, 0x80, 0x00, 0xC0, 0x82, + 0x08, 0xFC, 0x48, 0x3A, 0x08, 0xFC, 0x18, 0x50, + 0x00, 0xFC, 0x00, 0x00, 0xE0, 0x10, 0x00, 0x00, + 0x86, 0xA0, 0x41, 0x00, 0x40, 0x47, 0x20, 0x00, + 0x80, 0x00, 0xC0, 0x83, 0x04, 0xE0, 0x3D, 0x1E, + 0x04, 0x80, 0x11, 0xE0, 0x08, 0x44, 0x26, 0x33, + 0x02, 0xCB, 0x00, 0x10, 0xE0, 0x10, 0x40, 0x83, + 0x08, 0x00, 0x28, 0x21, 0x84, 0xCA, 0x61, 0x00, + 0x80, 0x07, 0x00, 0x81, 0x0C, 0xE0, 0x2C, 0x09, + 0x84, 0xCA, 0x21, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x01, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x18); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x03, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x40, 0x00, 0x00, 0x03, 0x48, + 0x00, 0x00, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x54, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x03, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x74, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x0C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x03, 0x78, + 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x24, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x04, 0x88, 0x00, 0x00, 0x04, 0x90, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x44, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xA7, 0x26, 0x4A, 0x7F, 0xFF, 0xFF, 0xFF, + 0x00, 0x20, 0xC4, 0x9C, 0x00, 0x20, 0xC4, 0x9C, + 0x00, 0x00, 0x68, 0xDB, 0x00, 0x00, 0xD1, 0xB7, + 0x00, 0x00, 0x68, 0xDB, 0x0F, 0xA4, 0xA8, 0xC1, + 0xF8, 0x59, 0x7F, 0x63, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xB7, 0xE9, + 0x00, 0x5F, 0x6F, 0xD2, 0x00, 0x2F, 0xB7, 0xE9, + 0x0B, 0x1E, 0x4F, 0x76, 0xFC, 0x23, 0x05, 0x54, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x7D, 0xBF, 0x48, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x1E, 0x4F, 0x76, + 0xFC, 0x23, 0x05, 0x54, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x10); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x89, 0xA0, 0x27, 0x7F, 0xEC, 0x56, 0xD5, + 0x7F, 0xFC, 0xB9, 0x23, 0x00, 0x89, 0xA0, 0x27, + 0x7F, 0xEC, 0x56, 0xD5, 0x7F, 0xFC, 0xB9, 0x23, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x40, 0x00); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x11, 0xFF, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x7D, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x51, 0x05); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x19, 0xDF); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x46, 0x11); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x02, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x53, 0x01); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x54, 0x17); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x7F, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x71, 0x94, 0x9A, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x2C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x7A, 0x27, + 0x00, 0x28, 0x7A, 0x27, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0x62, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x28, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x03, 0x69, 0xC5, 0x00, 0xEE, 0xC9, 0x55, + 0x00, 0x22, 0x1D, 0x95, 0x00, 0x03, 0x69, 0xC5, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x7F, 0xF9, 0x2C, 0x60, 0x07, 0x77, 0x1A, 0x4F, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0xAA); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xC5, 0xCA, 0x98, + 0xF0, 0x74, 0x6A, 0xD0, 0x07, 0xC5, 0xCA, 0x98, + 0x0F, 0x8A, 0x9A, 0x1D, 0xF8, 0x73, 0x6F, 0xBD, + 0x07, 0xCC, 0x4D, 0x23, 0xF0, 0x8F, 0xEC, 0x92, + 0x07, 0xA8, 0xA9, 0xB4, 0x0F, 0x70, 0x13, 0x6E, + 0xF8, 0x8B, 0x09, 0x29, 0x08, 0x2F, 0x93, 0x82, + 0xF0, 0x34, 0x1D, 0x7A, 0x07, 0xA1, 0x4F, 0x7F, + 0x0F, 0xCD, 0x63, 0x79, 0xF8, 0x30, 0x9D, 0xF2, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xC5, 0xCA, 0x98, 0xF0, 0x74, 0x6A, 0xD0, + 0x07, 0xC5, 0xCA, 0x98, 0x0F, 0x8A, 0x9A, 0x1D, + 0xF8, 0x73, 0x6F, 0xBD, 0x07, 0xCC, 0x4D, 0x23, + 0xF0, 0x8F, 0xEC, 0x92, 0x07, 0xA8, 0xA9, 0xB4, + 0x0F, 0x70, 0x13, 0x6E, 0xF8, 0x8B, 0x09, 0x29, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x2F, 0x93, 0x82, 0xF0, 0x34, 0x1D, 0x7A, + 0x07, 0xA1, 0x4F, 0x7F, 0x0F, 0xCD, 0x63, 0x79, + 0xF8, 0x30, 0x9D, 0xF2, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x91, 0xDC, 0xC5, 0xFF, 0x04, 0xF3, 0x02, + 0x00, 0x6E, 0x34, 0x0A, 0x0F, 0xD6, 0x6C, 0x7A, + 0xF8, 0x24, 0x8F, 0xB5, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF4, 0x49, 0x81, + 0xFF, 0xE8, 0x93, 0x02, 0xFF, 0xF4, 0x49, 0x81, + 0x0D, 0x94, 0x7A, 0x64, 0xFA, 0x3C, 0xAB, 0xA1, + 0x06, 0xD5, 0xF3, 0xB1, 0xF2, 0x54, 0x18, 0x9F, + 0x06, 0xD5, 0xF3, 0xB1, 0x0D, 0x94, 0x7A, 0x64, + 0xFA, 0x3C, 0xAB, 0xA1, 0x00, 0x00, 0x38, 0xE4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xD5, 0x55, 0x55, 0xF8, 0x2A, 0x71, 0xC7, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x30, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x60, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x62, 0x09); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4C, 0x30); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x03); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x78, 0x80); + if (res < 0) + return res; + + return 0; +} From a91d2c7f79fc0d14b5818c47a070be670c63c3a3 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 6 Mar 2026 13:34:51 -0700 Subject: [PATCH 789/789] lemp14: use correct SPDs --- src/mainboard/system76/ptl/Makefile.mk | 3 +- src/mainboard/system76/ptl/spd/Makefile.mk | 6 ---- .../ptl/spd/samsung-K3KL8L80DM-MGCU.spd.hex | 33 +++++++++++++++++++ .../ptl/spd/samsung-K3KL9L90EM-MGCU.spd.hex | 33 +++++++++++++++++++ .../system76/ptl/variants/lemp14/gpio_early.c | 2 -- .../ptl/variants/lemp14/memory/Makefile.mk | 7 ---- .../lemp14/memory/dram_id.generated.txt | 7 ---- .../variants/lemp14/memory/mem_parts_used.txt | 12 ------- .../system76/ptl/variants/lemp14/romstage.c | 21 +++++++++--- 9 files changed, 84 insertions(+), 40 deletions(-) delete mode 100644 src/mainboard/system76/ptl/spd/Makefile.mk create mode 100644 src/mainboard/system76/ptl/spd/samsung-K3KL8L80DM-MGCU.spd.hex create mode 100644 src/mainboard/system76/ptl/spd/samsung-K3KL9L90EM-MGCU.spd.hex delete mode 100644 src/mainboard/system76/ptl/variants/lemp14/memory/Makefile.mk delete mode 100644 src/mainboard/system76/ptl/variants/lemp14/memory/dram_id.generated.txt delete mode 100644 src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt diff --git a/src/mainboard/system76/ptl/Makefile.mk b/src/mainboard/system76/ptl/Makefile.mk index 08bd6b0627..33c81b161c 100644 --- a/src/mainboard/system76/ptl/Makefile.mk +++ b/src/mainboard/system76/ptl/Makefile.mk @@ -13,5 +13,4 @@ ramstage-y += variants/$(VARIANT_DIR)/gpio.c ramstage-y += variants/$(VARIANT_DIR)/ramstage.c ramstage-$(CONFIG_DRIVERS_I2C_TAS5825M) += variants/$(VARIANT_DIR)/tas5825m.c -subdirs-y += variants/$(VARIANT_DIR)/memory -subdirs-$(CONFIG_HAVE_SPD_IN_CBFS) += spd +SPD_SOURCES = samsung-K3KL8L80DM-MGCU samsung-K3KL9L90EM-MGCU diff --git a/src/mainboard/system76/ptl/spd/Makefile.mk b/src/mainboard/system76/ptl/spd/Makefile.mk deleted file mode 100644 index be4d98bd1d..0000000000 --- a/src/mainboard/system76/ptl/spd/Makefile.mk +++ /dev/null @@ -1,6 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-or-later -## - -ifneq ($(SPD_SOURCES),) -LIB_SPD_DEPS := $(SPD_SOURCES) -endif diff --git a/src/mainboard/system76/ptl/spd/samsung-K3KL8L80DM-MGCU.spd.hex b/src/mainboard/system76/ptl/spd/samsung-K3KL8L80DM-MGCU.spd.hex new file mode 100644 index 0000000000..7e41dd2854 --- /dev/null +++ b/src/mainboard/system76/ptl/spd/samsung-K3KL8L80DM-MGCU.spd.hex @@ -0,0 +1,33 @@ +# Samsung K3KL8L80DM-MGCU +23 10 15 0e 86 22 95 08 00 40 00 00 02 01 00 00 +48 00 08 ff 92 55 05 00 aa 00 90 a8 90 c0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 7f c1 89 20 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 4b 33 4b 4c 38 4c 38 +30 44 4d 2d 4d 47 43 55 00 00 00 00 00 00 80 ce +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/system76/ptl/spd/samsung-K3KL9L90EM-MGCU.spd.hex b/src/mainboard/system76/ptl/spd/samsung-K3KL9L90EM-MGCU.spd.hex new file mode 100644 index 0000000000..62f8ae330c --- /dev/null +++ b/src/mainboard/system76/ptl/spd/samsung-K3KL9L90EM-MGCU.spd.hex @@ -0,0 +1,33 @@ +# Samsung K3KL9L90EM-MGCU +23 10 15 0e 86 22 b5 08 00 40 00 00 0a 01 00 00 +48 00 08 ff 92 55 05 00 aa 00 90 a8 90 c0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 7f c1 c5 78 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 4b 33 4b 4c 39 4c 39 +30 44 4d 2d 4d 47 43 55 00 00 00 00 00 00 80 ce +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/system76/ptl/variants/lemp14/gpio_early.c b/src/mainboard/system76/ptl/variants/lemp14/gpio_early.c index a2a5e5bb19..46ed8112dc 100644 --- a/src/mainboard/system76/ptl/variants/lemp14/gpio_early.c +++ b/src/mainboard/system76/ptl/variants/lemp14/gpio_early.c @@ -4,8 +4,6 @@ #include static const struct pad_config early_gpio_table[] = { - PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), // SMB_CLK - PAD_CFG_NF(GPP_C01, NONE, DEEP, NF1), // SMB_DATA PAD_CFG_GPI(GPP_E11, NONE, DEEP), // BOARD_ID1 PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), // UART0_RX PAD_CFG_NF(GPP_H09, NONE, DEEP, NF1), // UART0_TX diff --git a/src/mainboard/system76/ptl/variants/lemp14/memory/Makefile.mk b/src/mainboard/system76/ptl/variants/lemp14/memory/Makefile.mk deleted file mode 100644 index 2909100fa2..0000000000 --- a/src/mainboard/system76/ptl/variants/lemp14/memory/Makefile.mk +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# This is an auto-generated file. Do not edit!! -# Generated by: -# util/spd_tools/bin/part_id_gen PTL lp5 src/mainboard/system76/ptl/variants/lemp14/memory src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt - -SPD_SOURCES = -SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 0(0b0000) Parts = MT62F1G32D4DR-031 WT:B diff --git a/src/mainboard/system76/ptl/variants/lemp14/memory/dram_id.generated.txt b/src/mainboard/system76/ptl/variants/lemp14/memory/dram_id.generated.txt deleted file mode 100644 index 4e6a073f96..0000000000 --- a/src/mainboard/system76/ptl/variants/lemp14/memory/dram_id.generated.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# This is an auto-generated file. Do not edit!! -# Generated by: -# util/spd_tools/bin/part_id_gen PTL lp5 src/mainboard/system76/ptl/variants/lemp14/memory src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt - -DRAM Part Name ID to assign -MT62F1G32D4DR-031 WT:B 0 (0000) diff --git a/src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt b/src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt deleted file mode 100644 index b079d45cde..0000000000 --- a/src/mainboard/system76/ptl/variants/lemp14/memory/mem_parts_used.txt +++ /dev/null @@ -1,12 +0,0 @@ -# This is a CSV file containing a list of memory parts used by this variant. -# One part per line with an optional fixed ID in column 2. -# Only include a fixed ID if it is required for legacy reasons! -# Generated IDs are dependent on the order of parts in this file, -# so new parts must always be added at the end of the file! -# -# Generate an updated Makefile.mk and dram_id.generated.txt by running the -# part_id_gen tool from util/spd_tools. -# See util/spd_tools/README.md for more details and instructions. - -# Part Name -MT62F1G32D4DR-031 WT:B diff --git a/src/mainboard/system76/ptl/variants/lemp14/romstage.c b/src/mainboard/system76/ptl/variants/lemp14/romstage.c index f5413d4629..03aec23999 100644 --- a/src/mainboard/system76/ptl/variants/lemp14/romstage.c +++ b/src/mainboard/system76/ptl/variants/lemp14/romstage.c @@ -63,13 +63,26 @@ static const struct mb_cfg board_cfg = { }, }; -static const struct mem_spd spd_info = { - .topo = MEM_TOPO_MEMORY_DOWN, - .cbfs_index = 0, -}; + + +static size_t get_spd_index(void) +{ + if (gpio_get(GPP_E11)) { + // If BOARD_ID1 is high, the system has 16 GB of RAM using 4x32Gb modules + return 0; + } else { + // If BOARD_ID1 is low, the system has 32 GB of RAM using 4x64Gb modules + return 1; + } +} void mainboard_memory_init_params(FSPM_UPD *mupd) { + + const struct mem_spd spd_info = { + .topo = MEM_TOPO_MEMORY_DOWN, + .cbfs_index = get_spd_index(), + }; const bool half_populated = false; mupd->FspmConfig.GpioOverride = 0;