diff options
Diffstat (limited to 'config/coreboot/haswell/patches/0008-nb-intel-haswell-Add-native-raminit-scaffolding.patch')
-rw-r--r-- | config/coreboot/haswell/patches/0008-nb-intel-haswell-Add-native-raminit-scaffolding.patch | 407 |
1 files changed, 0 insertions, 407 deletions
diff --git a/config/coreboot/haswell/patches/0008-nb-intel-haswell-Add-native-raminit-scaffolding.patch b/config/coreboot/haswell/patches/0008-nb-intel-haswell-Add-native-raminit-scaffolding.patch deleted file mode 100644 index 6df828eb..00000000 --- a/config/coreboot/haswell/patches/0008-nb-intel-haswell-Add-native-raminit-scaffolding.patch +++ /dev/null @@ -1,407 +0,0 @@ -From 46cdec8cbce15ca11ad9a49a3ee415a78f781997 Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Sat, 7 May 2022 00:26:10 +0200 -Subject: [PATCH 08/26] nb/intel/haswell: Add native raminit scaffolding - -Implement some scaffolding for Haswell native raminit, like bootmode -selection, handling of MRC cache and CPU detection. - -Change-Id: Icd96649fa045ea7f0f32ae9bfe1e60498d93975b -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - .../intel/haswell/native_raminit/Makefile.inc | 1 + - .../haswell/native_raminit/raminit_main.c | 104 ++++++++++ - .../haswell/native_raminit/raminit_native.c | 189 +++++++++++++++++- - .../haswell/native_raminit/raminit_native.h | 34 ++++ - 4 files changed, 322 insertions(+), 6 deletions(-) - create mode 100644 src/northbridge/intel/haswell/native_raminit/raminit_main.c - create mode 100644 src/northbridge/intel/haswell/native_raminit/raminit_native.h - -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc -index 8cfb4fb33e..90af951c5a 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc -@@ -1,3 +1,4 @@ - ## SPDX-License-Identifier: GPL-2.0-or-later - -+romstage-y += raminit_main.c - romstage-y += raminit_native.c -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -new file mode 100644 -index 0000000000..9b42c25b40 ---- /dev/null -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -@@ -0,0 +1,104 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <assert.h> -+#include <console/console.h> -+#include <cpu/intel/haswell/haswell.h> -+#include <delay.h> -+#include <device/pci_ops.h> -+#include <northbridge/intel/haswell/chip.h> -+#include <northbridge/intel/haswell/haswell.h> -+#include <northbridge/intel/haswell/raminit.h> -+#include <string.h> -+#include <types.h> -+ -+#include "raminit_native.h" -+ -+struct task_entry { -+ enum raminit_status (*task)(struct sysinfo *); -+ bool is_enabled; -+ const char *name; -+}; -+ -+static const struct task_entry cold_boot[] = { -+}; -+ -+/* Return a generic stepping value to make stepping checks simpler */ -+static enum generic_stepping get_stepping(const uint32_t cpuid) -+{ -+ switch (cpuid) { -+ case CPUID_HASWELL_A0: -+ die("Haswell stepping A0 is not supported\n"); -+ case CPUID_HASWELL_B0: -+ case CPUID_HASWELL_ULT_B0: -+ case CPUID_CRYSTALWELL_B0: -+ return STEPPING_B0; -+ case CPUID_HASWELL_C0: -+ case CPUID_HASWELL_ULT_C0: -+ case CPUID_CRYSTALWELL_C0: -+ return STEPPING_C0; -+ default: -+ /** TODO: Add Broadwell support someday **/ -+ die("Unknown CPUID 0x%x\n", cpuid); -+ } -+} -+ -+static void initialize_ctrl(struct sysinfo *ctrl) -+{ -+ const struct northbridge_intel_haswell_config *cfg = config_of_soc(); -+ const enum raminit_boot_mode bootmode = ctrl->bootmode; -+ -+ memset(ctrl, 0, sizeof(*ctrl)); -+ -+ ctrl->cpu = cpu_get_cpuid(); -+ ctrl->stepping = get_stepping(ctrl->cpu); -+ ctrl->dq_pins_interleaved = cfg->dq_pins_interleaved; -+ ctrl->bootmode = bootmode; -+} -+ -+static enum raminit_status try_raminit(struct sysinfo *ctrl) -+{ -+ const struct task_entry *const schedule = cold_boot; -+ const size_t length = ARRAY_SIZE(cold_boot); -+ -+ enum raminit_status status = RAMINIT_STATUS_UNSPECIFIED_ERROR; -+ -+ for (size_t i = 0; i < length; i++) { -+ const struct task_entry *const entry = &schedule[i]; -+ assert(entry); -+ assert(entry->name); -+ if (!entry->is_enabled) -+ continue; -+ -+ assert(entry->task); -+ printk(RAM_DEBUG, "\nExecuting raminit task %s\n", entry->name); -+ status = entry->task(ctrl); -+ printk(RAM_DEBUG, "\n"); -+ if (status) { -+ printk(BIOS_ERR, "raminit failed on step %s\n", entry->name); -+ break; -+ } -+ } -+ -+ return status; -+} -+ -+void raminit_main(const enum raminit_boot_mode bootmode) -+{ -+ /* -+ * The mighty_ctrl struct. Will happily nuke the pre-RAM stack -+ * if left unattended. Make it static and pass pointers to it. -+ */ -+ static struct sysinfo mighty_ctrl; -+ -+ mighty_ctrl.bootmode = bootmode; -+ initialize_ctrl(&mighty_ctrl); -+ -+ /** TODO: Try more than once **/ -+ enum raminit_status status = try_raminit(&mighty_ctrl); -+ -+ if (status != RAMINIT_STATUS_SUCCESS) -+ die("Memory initialization was met with utmost failure and misery\n"); -+ -+ /** TODO: Implement the required magic **/ -+ die("NATIVE RAMINIT: More Magic (tm) required.\n"); -+} -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -index b6efb6b40d..0869db3902 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -@@ -1,13 +1,45 @@ - /* SPDX-License-Identifier: GPL-2.0-or-later */ - -+#include <arch/cpu.h> -+#include <assert.h> -+#include <cbmem.h> -+#include <cf9_reset.h> - #include <console/console.h> -+#include <cpu/x86/msr.h> - #include <delay.h> -+#include <device/pci_ops.h> -+#include <mrc_cache.h> - #include <northbridge/intel/haswell/haswell.h> - #include <northbridge/intel/haswell/raminit.h> - #include <southbridge/intel/lynxpoint/me.h> - #include <southbridge/intel/lynxpoint/pch.h> - #include <types.h> - -+#include "raminit_native.h" -+ -+static void wait_txt_clear(void) -+{ -+ const struct cpuid_result cpuid = cpuid_ext(1, 0); -+ -+ /* Check if TXT is supported */ -+ if (!(cpuid.ecx & BIT(6))) -+ return; -+ -+ /* Some TXT public bit */ -+ if (!(read32p(0xfed30010) & 1)) -+ return; -+ -+ /* Wait for TXT clear */ -+ do {} while (!(read8p(0xfed40000) & (1 << 7))); -+} -+ -+static enum raminit_boot_mode get_boot_mode(void) -+{ -+ const uint16_t pmcon_2 = pci_read_config16(PCH_LPC_DEV, GEN_PMCON_2); -+ const uint16_t bitmask = GEN_PMCON_2_DISB | GEN_PMCON_2_MEM_SR; -+ return (pmcon_2 & bitmask) == bitmask ? BOOTMODE_WARM : BOOTMODE_COLD; -+} -+ - static bool early_init_native(int s3resume) - { - printk(BIOS_DEBUG, "Starting native platform initialisation\n"); -@@ -24,6 +56,120 @@ static bool early_init_native(int s3resume) - return cpu_replaced; - } - -+#define MRC_CACHE_VERSION 1 -+ -+struct mrc_data { -+ const void *buffer; -+ size_t buffer_len; -+}; -+ -+static void save_mrc_data(struct mrc_data *md) -+{ -+ mrc_cache_stash_data(MRC_TRAINING_DATA, MRC_CACHE_VERSION, md->buffer, md->buffer_len); -+} -+ -+static struct mrc_data prepare_mrc_cache(void) -+{ -+ struct mrc_data md = {0}; -+ md.buffer = mrc_cache_current_mmap_leak(MRC_TRAINING_DATA, -+ MRC_CACHE_VERSION, -+ &md.buffer_len); -+ return md; -+} -+ -+static const char *const bm_names[] = { -+ "BOOTMODE_COLD", -+ "BOOTMODE_WARM", -+ "BOOTMODE_S3", -+ "BOOTMODE_FAST", -+}; -+ -+static void clear_disb(void) -+{ -+ pci_and_config16(PCH_LPC_DEV, GEN_PMCON_2, ~GEN_PMCON_2_DISB); -+} -+ -+static void raminit_reset(void) -+{ -+ clear_disb(); -+ system_reset(); -+} -+ -+static enum raminit_boot_mode do_actual_raminit( -+ struct mrc_data *md, -+ const bool s3resume, -+ const bool cpu_replaced, -+ const enum raminit_boot_mode orig_bootmode) -+{ -+ enum raminit_boot_mode bootmode = orig_bootmode; -+ -+ bool save_data_valid = md->buffer && md->buffer_len == USHRT_MAX; /** TODO: sizeof() **/ -+ -+ if (s3resume) { -+ if (bootmode == BOOTMODE_COLD) { -+ printk(BIOS_EMERG, "Memory may not be in self-refresh for S3 resume\n"); -+ printk(BIOS_EMERG, "S3 resume and cold boot are mutually exclusive\n"); -+ raminit_reset(); -+ } -+ /* Only a true mad hatter would replace a CPU in S3 */ -+ if (cpu_replaced) { -+ printk(BIOS_EMERG, "Oh no, CPU was replaced during S3\n"); -+ /* -+ * No reason to continue, memory consistency is most likely lost -+ * and ME will probably request a reset through DID response too. -+ */ -+ /** TODO: Figure out why past self commented this out **/ -+ //raminit_reset(); -+ } -+ bootmode = BOOTMODE_S3; -+ if (!save_data_valid) { -+ printk(BIOS_EMERG, "No training data, S3 resume is impossible\n"); -+ /* Failed S3 resume, reset to come up cleanly */ -+ raminit_reset(); -+ } -+ } -+ if (!s3resume && cpu_replaced) { -+ printk(BIOS_NOTICE, "CPU was replaced, forcing a cold boot\n"); -+ /* -+ * Looks like the ME will get angry if raminit takes too long. -+ * It will report that the CPU has been replaced on next boot. -+ * Try to continue anyway. This should not happen in most cases. -+ */ -+ /** TODO: Figure out why past self commented this out **/ -+ //save_data_valid = false; -+ } -+ if (bootmode == BOOTMODE_COLD) { -+ /* If possible, promote to a fast boot */ -+ if (save_data_valid) -+ bootmode = BOOTMODE_FAST; -+ -+ clear_disb(); -+ } else if (bootmode == BOOTMODE_WARM) { -+ /* If a warm reset happened before raminit is done, force a cold boot */ -+ if (mchbar_read32(SSKPD) == 0 && mchbar_read32(SSKPD + 4) == 0) { -+ printk(BIOS_NOTICE, "Warm reset occurred early in cold boot\n"); -+ save_data_valid = false; -+ } -+ if (!save_data_valid) -+ bootmode = BOOTMODE_COLD; -+ } -+ assert(save_data_valid != (bootmode == BOOTMODE_COLD)); -+ if (save_data_valid) { -+ printk(BIOS_INFO, "Using cached memory parameters\n"); -+ die("RAMINIT: Fast boot is not yet implemented\n"); -+ } -+ printk(RAM_DEBUG, "Initial bootmode: %s\n", bm_names[orig_bootmode]); -+ printk(RAM_DEBUG, "Current bootmode: %s\n", bm_names[bootmode]); -+ -+ /* -+ * And now, the actual memory initialization thing. -+ */ -+ printk(RAM_DEBUG, "\nStarting native raminit\n"); -+ raminit_main(bootmode); -+ -+ return bootmode; -+} -+ - void perform_raminit(const int s3resume) - { - /* -@@ -32,17 +178,48 @@ void perform_raminit(const int s3resume) - */ - const bool cpu_replaced = early_init_native(s3resume); - -- (void)cpu_replaced; -+ wait_txt_clear(); -+ wrmsr(0x2e6, (msr_t) {.lo = 0, .hi = 0}); -+ -+ const enum raminit_boot_mode orig_bootmode = get_boot_mode(); -+ -+ struct mrc_data md = prepare_mrc_cache(); -+ -+ const enum raminit_boot_mode bootmode = -+ do_actual_raminit(&md, s3resume, cpu_replaced, orig_bootmode); -+ -+ /** TODO: report_memory_config **/ - -- /** TODO: Move after raminit */ - if (intel_early_me_uma_size() > 0) { -- /** TODO: Update status once raminit is implemented **/ -- uint8_t me_status = ME_INIT_STATUS_ERROR; -+ /* -+ * The 'other' success value is to report loss of memory -+ * consistency to ME if warm boot was downgraded to cold. -+ */ -+ uint8_t me_status; -+ if (BOOTMODE_WARM == orig_bootmode && BOOTMODE_COLD == bootmode) -+ me_status = ME_INIT_STATUS_SUCCESS_OTHER; -+ else -+ me_status = ME_INIT_STATUS_SUCCESS; -+ -+ /** TODO: Remove this once raminit is implemented **/ -+ me_status = ME_INIT_STATUS_ERROR; - intel_early_me_init_done(me_status); - } - -+ post_code(0x3b); -+ - intel_early_me_status(); - -- /** TODO: Implement the required magic **/ -- die("NATIVE RAMINIT: More Magic (tm) required.\n"); -+ const bool 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 training data on non-S3 resumes */ -+ if (!s3resume) -+ save_mrc_data(&md); -+ -+ /** TODO: setup_sdram_meminfo **/ - } -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -new file mode 100644 -index 0000000000..885f0184f4 ---- /dev/null -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -@@ -0,0 +1,34 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#ifndef HASWELL_RAMINIT_NATIVE_H -+#define HASWELL_RAMINIT_NATIVE_H -+ -+enum raminit_boot_mode { -+ BOOTMODE_COLD, -+ BOOTMODE_WARM, -+ BOOTMODE_S3, -+ BOOTMODE_FAST, -+}; -+ -+enum raminit_status { -+ RAMINIT_STATUS_SUCCESS = 0, -+ RAMINIT_STATUS_UNSPECIFIED_ERROR, /** TODO: Deprecated in favor of specific values **/ -+}; -+ -+enum generic_stepping { -+ STEPPING_A0 = 1, -+ STEPPING_B0 = 2, -+ STEPPING_C0 = 3, -+}; -+ -+struct sysinfo { -+ enum raminit_boot_mode bootmode; -+ enum generic_stepping stepping; -+ uint32_t cpu; /* CPUID value */ -+ -+ bool dq_pins_interleaved; -+}; -+ -+void raminit_main(enum raminit_boot_mode bootmode); -+ -+#endif --- -2.39.2 - |