From d99b693c965abb13aa57c5701bfd08547fa93cb5 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Fri, 12 Mar 2021 17:37:42 +0100 Subject: [PATCH] nb/intel/haswell: Confine `pei_data` uses to raminit.c Reorganize romstage.c to resemble sandybridge, and move everything that needs `pei_data` into raminit.c function `perform_raminit`. Barring USB settings, coreboot code no longer depends on pei_data.h definitions. It still depends on MRC, though. For now. Tested on Asrock B85M Pro4, still boots and still resumes from S3. Change-Id: I433f88db5fe7a7533ab6837015647ec31fb45e88 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/51449 Reviewed-by: Patrick Georgi Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/northbridge/intel/haswell/raminit.c | 124 ++++++++++++++++++++- src/northbridge/intel/haswell/raminit.h | 6 +- src/northbridge/intel/haswell/romstage.c | 130 +---------------------- 3 files changed, 127 insertions(+), 133 deletions(-) diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c index c85ca5bb7b..d84d3fb12a 100644 --- a/src/northbridge/intel/haswell/raminit.c +++ b/src/northbridge/intel/haswell/raminit.c @@ -9,13 +9,18 @@ #include #include #include +#include #include #include #include +#include #include #include #include #include +#include +#include +#include #include #include "raminit.h" @@ -24,7 +29,7 @@ #define MRC_CACHE_VERSION 1 -void save_mrc_data(struct pei_data *pei_data) +static void save_mrc_data(struct pei_data *pei_data) { /* Save the MRC S3 restore data to cbmem */ mrc_cache_stash_data(MRC_TRAINING_DATA, MRC_CACHE_VERSION, pei_data->mrc_output, @@ -105,7 +110,7 @@ static void report_memory_config(void) * * @param pei_data: configuration data for UEFI PEI reference code */ -void sdram_initialize(struct pei_data *pei_data) +static void sdram_initialize(struct pei_data *pei_data) { int (*entry)(struct pei_data *pei_data) __attribute__((regparm(1))); @@ -206,7 +211,7 @@ static uint32_t nb_max_chan_capacity_mib(const uint32_t capid0_a) return (ddrsz / 2) * nb_slots_per_channel(capid0_a); } -void setup_sdram_meminfo(struct pei_data *pei_data) +static void setup_sdram_meminfo(struct pei_data *pei_data) { struct memory_info *mem_info; struct dimm_info *dimm; @@ -261,3 +266,116 @@ void setup_sdram_meminfo(struct pei_data *pei_data) mem_info->max_capacity_mib = channels * nb_max_chan_capacity_mib(capid0_a); mem_info->number_of_devices = channels * nb_slots_per_channel(capid0_a); } + +/* Copy SPD data for on-board memory */ +static void copy_spd(struct pei_data *pei_data, struct spd_info *spdi) +{ + if (!CONFIG(HAVE_SPD_IN_CBFS)) + return; + + printk(BIOS_DEBUG, "SPD index %d\n", spdi->spd_index); + + size_t spd_file_len; + uint8_t *spd_file = cbfs_map("spd.bin", &spd_file_len); + + if (!spd_file) + die("SPD data not found."); + + if (spd_file_len < ((spdi->spd_index + 1) * SPD_LEN)) { + printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); + spdi->spd_index = 0; + } + + if (spd_file_len < SPD_LEN) + die("Missing SPD data."); + + /* MRC only uses index 0, but coreboot uses the other indices */ + memcpy(pei_data->spd_data[0], spd_file + (spdi->spd_index * SPD_LEN), SPD_LEN); + + for (size_t i = 1; i < ARRAY_SIZE(spdi->addresses); i++) { + if (spdi->addresses[i] == SPD_MEMORY_DOWN) + memcpy(pei_data->spd_data[i], pei_data->spd_data[0], SPD_LEN); + } +} + +/* + * 0 = leave channel enabled + * 1 = disable dimm 0 on channel + * 2 = disable dimm 1 on channel + * 3 = disable dimm 0+1 on channel + */ +static int make_channel_disabled_mask(const struct pei_data *pd, int ch) +{ + return (!pd->spd_addresses[ch + ch] << 0) | (!pd->spd_addresses[ch + ch + 1] << 1); +} + +void perform_raminit(const int s3resume) +{ + const struct device *gbe = pcidev_on_root(0x19, 0); + + const struct northbridge_intel_haswell_config *cfg = config_of_soc(); + + struct pei_data pei_data = { + .pei_version = PEI_VERSION, + .mchbar = CONFIG_FIXED_MCHBAR_MMIO_BASE, + .dmibar = CONFIG_FIXED_DMIBAR_MMIO_BASE, + .epbar = CONFIG_FIXED_EPBAR_MMIO_BASE, + .pciexbar = CONFIG_MMCONF_BASE_ADDRESS, + .smbusbar = CONFIG_FIXED_SMBUS_IO_BASE, + .hpet_address = CONFIG_HPET_ADDRESS, + .rcba = CONFIG_FIXED_RCBA_MMIO_BASE, + .pmbase = DEFAULT_PMBASE, + .gpiobase = DEFAULT_GPIOBASE, + .temp_mmio_base = 0xfed08000, + .system_type = get_pch_platform_type(), + .tseg_size = CONFIG_SMM_TSEG_SIZE, + .ec_present = cfg->ec_present, + .gbe_enable = gbe && gbe->enabled, + .ddr_refresh_2x = CONFIG(ENABLE_DDR_2X_REFRESH), + .dq_pins_interleaved = cfg->dq_pins_interleaved, + .max_ddr3_freq = 1600, + .usb_xhci_on_resume = cfg->usb_xhci_on_resume, + }; + + memcpy(pei_data.usb2_ports, mainboard_usb2_ports, sizeof(mainboard_usb2_ports)); + memcpy(pei_data.usb3_ports, mainboard_usb3_ports, sizeof(mainboard_usb3_ports)); + + /* MRC has hardcoded assumptions of 2 meaning S3 wake. Normalize it here. */ + pei_data.boot_mode = s3resume ? 2 : 0; + + /* Obtain the SPD addresses from mainboard code */ + struct spd_info spdi = {0}; + mb_get_spd_map(&spdi); + + for (size_t i = 0; i < ARRAY_SIZE(spdi.addresses); i++) + pei_data.spd_addresses[i] = spdi.addresses[i]; + + /* Calculate unimplemented DIMM slots for each channel */ + pei_data.dimm_channel0_disabled = make_channel_disabled_mask(&pei_data, 0); + pei_data.dimm_channel1_disabled = make_channel_disabled_mask(&pei_data, 1); + + timestamp_add_now(TS_BEFORE_INITRAM); + + copy_spd(&pei_data, &spdi); + + sdram_initialize(&pei_data); + + timestamp_add_now(TS_AFTER_INITRAM); + + post_code(0x3b); + + intel_early_me_status(); + + int cbmem_was_initted = !cbmem_recovery(s3resume); + if (s3resume && !cbmem_was_initted) { + /* Failed S3 resume, reset to come up cleanly */ + printk(BIOS_CRIT, "Failed to recover CBMEM in S3 resume.\n"); + system_reset(); + } + + /* Save data returned from MRC on non-S3 resumes. */ + if (!s3resume) + save_mrc_data(&pei_data); + + setup_sdram_meminfo(&pei_data); +} diff --git a/src/northbridge/intel/haswell/raminit.h b/src/northbridge/intel/haswell/raminit.h index ff95a453fb..7eb3980544 100644 --- a/src/northbridge/intel/haswell/raminit.h +++ b/src/northbridge/intel/haswell/raminit.h @@ -20,10 +20,6 @@ extern const struct usb3_port_setting mainboard_usb3_ports[MAX_USB3_PORTS]; /* Mainboard callback to fill in the SPD addresses in MRC format */ void mb_get_spd_map(struct spd_info *spdi); -void sdram_initialize(struct pei_data *pei_data); -void setup_sdram_meminfo(struct pei_data *pei_data); - -/* save_mrc_data() must be called after cbmem has been initialized. */ -void save_mrc_data(struct pei_data *pei_data); +void perform_raminit(const int s3resume); #endif /* RAMINIT_H */ diff --git a/src/northbridge/intel/haswell/romstage.c b/src/northbridge/intel/haswell/romstage.c index f65098f6fc..28a0c7903e 100644 --- a/src/northbridge/intel/haswell/romstage.c +++ b/src/northbridge/intel/haswell/romstage.c @@ -1,153 +1,51 @@ /* 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 - -/* Copy SPD data for on-board memory */ -static void copy_spd(struct pei_data *pei_data, struct spd_info *spdi) -{ - if (!CONFIG(HAVE_SPD_IN_CBFS)) - return; - - printk(BIOS_DEBUG, "SPD index %d\n", spdi->spd_index); - - size_t spd_file_len; - uint8_t *spd_file = cbfs_map("spd.bin", &spd_file_len); - - if (!spd_file) - die("SPD data not found."); - - if (spd_file_len < ((spdi->spd_index + 1) * SPD_LEN)) { - printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); - spdi->spd_index = 0; - } - - if (spd_file_len < SPD_LEN) - die("Missing SPD data."); - - /* MRC only uses index 0, but coreboot uses the other indices */ - memcpy(pei_data->spd_data[0], spd_file + (spdi->spd_index * SPD_LEN), SPD_LEN); - - for (size_t i = 1; i < ARRAY_SIZE(spdi->addresses); i++) { - if (spdi->addresses[i] == SPD_MEMORY_DOWN) - memcpy(pei_data->spd_data[i], pei_data->spd_data[0], SPD_LEN); - } -} void __weak mb_late_romstage_setup(void) { } -/* - * 0 = leave channel enabled - * 1 = disable dimm 0 on channel - * 2 = disable dimm 1 on channel - * 3 = disable dimm 0+1 on channel - */ -static int make_channel_disabled_mask(const struct pei_data *pd, int ch) -{ - return (!pd->spd_addresses[ch + ch] << 0) | (!pd->spd_addresses[ch + ch + 1] << 1); -} - /* The romstage entry point for this platform is not mainboard-specific, hence the name */ void mainboard_romstage_entry(void) { - const struct device *gbe = pcidev_on_root(0x19, 0); - - const struct northbridge_intel_haswell_config *cfg = config_of_soc(); - - struct pei_data pei_data = { - .pei_version = PEI_VERSION, - .mchbar = CONFIG_FIXED_MCHBAR_MMIO_BASE, - .dmibar = CONFIG_FIXED_DMIBAR_MMIO_BASE, - .epbar = CONFIG_FIXED_EPBAR_MMIO_BASE, - .pciexbar = CONFIG_MMCONF_BASE_ADDRESS, - .smbusbar = CONFIG_FIXED_SMBUS_IO_BASE, - .hpet_address = CONFIG_HPET_ADDRESS, - .rcba = CONFIG_FIXED_RCBA_MMIO_BASE, - .pmbase = DEFAULT_PMBASE, - .gpiobase = DEFAULT_GPIOBASE, - .temp_mmio_base = 0xfed08000, - .system_type = get_pch_platform_type(), - .tseg_size = CONFIG_SMM_TSEG_SIZE, - .ec_present = cfg->ec_present, - .gbe_enable = gbe && gbe->enabled, - .ddr_refresh_2x = CONFIG(ENABLE_DDR_2X_REFRESH), - .dq_pins_interleaved = cfg->dq_pins_interleaved, - .max_ddr3_freq = 1600, - .usb_xhci_on_resume = cfg->usb_xhci_on_resume, - }; - - memcpy(pei_data.usb2_ports, mainboard_usb2_ports, sizeof(mainboard_usb2_ports)); - memcpy(pei_data.usb3_ports, mainboard_usb3_ports, sizeof(mainboard_usb3_ports)); - enable_lapic(); early_pch_init(); - const int s3resume = southbridge_detect_s3_resume(); - - elog_boot_notify(s3resume); - /* Perform some early chipset initialization required * before RAM initialization can work */ haswell_early_initialization(); printk(BIOS_DEBUG, "Back from haswell_early_initialization()\n"); + const int s3resume = southbridge_detect_s3_resume(); + + elog_boot_notify(s3resume); + /* Prepare USB controller early in S3 resume */ if (s3resume) enable_usb_bar(); post_code(0x3a); - /* MRC has hardcoded assumptions of 2 meaning S3 wake. Normalize it here. */ - pei_data.boot_mode = s3resume ? 2 : 0; - - /* Obtain the SPD addresses from mainboard code */ - struct spd_info spdi = {0}; - mb_get_spd_map(&spdi); - - for (size_t i = 0; i < ARRAY_SIZE(spdi.addresses); i++) - pei_data.spd_addresses[i] = spdi.addresses[i]; - - /* Calculate unimplemented DIMM slots for each channel */ - pei_data.dimm_channel0_disabled = make_channel_disabled_mask(&pei_data, 0); - pei_data.dimm_channel1_disabled = make_channel_disabled_mask(&pei_data, 1); - - timestamp_add_now(TS_BEFORE_INITRAM); - report_platform_info(); if (CONFIG(INTEL_TXT)) intel_txt_romstage_init(); - copy_spd(&pei_data, &spdi); - - sdram_initialize(&pei_data); - - timestamp_add_now(TS_AFTER_INITRAM); + perform_raminit(s3resume); if (CONFIG(INTEL_TXT)) { printk(BIOS_DEBUG, "Check TXT_ERROR register after MRC\n"); @@ -161,26 +59,8 @@ void mainboard_romstage_entry(void) txt_dump_regions(); } - post_code(0x3b); - - intel_early_me_status(); - - int cbmem_was_initted = !cbmem_recovery(s3resume); - if (s3resume && !cbmem_was_initted) { - /* Failed S3 resume, reset to come up cleanly */ - printk(BIOS_CRIT, "Failed to recover CBMEM in S3 resume.\n"); - system_reset(); - } - - /* Save data returned from MRC on non-S3 resumes. */ - if (!s3resume) - save_mrc_data(&pei_data); - - haswell_unhide_peg(); - setup_sdram_meminfo(&pei_data); - romstage_handoff_init(s3resume); mb_late_romstage_setup();