From 8998999eb31a35efbc987d5bc597156fb5c50042 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sat, 28 Feb 2026 20:22:49 +0100 Subject: [PATCH] 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