diff options
author | Patrick Rudolph <patrick.rudolph@9elements.com> | 2023-12-27 10:59:25 +0100 |
---|---|---|
committer | Lean Sheng Tan <sheng.tan@9elements.com> | 2024-01-03 00:38:05 +0000 |
commit | b14b96d29a5ed196b2205a1bbd239c23d684fa47 (patch) | |
tree | 9d523abad4fecdd0552ff84905e183a1cda8fa63 /src/northbridge/intel/sandybridge | |
parent | a611634de819bac9e0ad475d245392c8cbb1e0b3 (diff) |
northbridge/intel/sandybridge/raminit: Prepare MRC path for x86_64
- Remove pointers in argument list passed to MRC to make sure the struct
has the same size on x86_64 as on x86_32.
- Add assembly wrapper to call the MRC with argument in EAX.
- Wrap calling MRC in protected_mode_call_2arg, which is a stub on x86_32
Tested: Boots on Lenovo X220 using MRC in x86_32 and x86_64 mode.
Change-Id: Id755e7381c5a94360e3511c53432d68b7687df67
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/79751
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jérémy Compostella <jeremy.compostella@intel.com>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Diffstat (limited to 'src/northbridge/intel/sandybridge')
-rw-r--r-- | src/northbridge/intel/sandybridge/Makefile.inc | 1 | ||||
-rw-r--r-- | src/northbridge/intel/sandybridge/mrc_wrapper.S | 27 | ||||
-rw-r--r-- | src/northbridge/intel/sandybridge/pei_data.h | 8 | ||||
-rw-r--r-- | src/northbridge/intel/sandybridge/raminit_mrc.c | 29 |
4 files changed, 50 insertions, 15 deletions
diff --git a/src/northbridge/intel/sandybridge/Makefile.inc b/src/northbridge/intel/sandybridge/Makefile.inc index 36fc16b4c4..6ecb17a378 100644 --- a/src/northbridge/intel/sandybridge/Makefile.inc +++ b/src/northbridge/intel/sandybridge/Makefile.inc @@ -27,6 +27,7 @@ romstage-y += raminit_native.c romstage-y += raminit_tables.c else romstage-y += raminit_mrc.c +romstage-y += mrc_wrapper.S cbfs-files-y += mrc.bin mrc.bin-file := $(call strip_quotes,$(CONFIG_MRC_FILE)) mrc.bin-position := 0xfffa0000 diff --git a/src/northbridge/intel/sandybridge/mrc_wrapper.S b/src/northbridge/intel/sandybridge/mrc_wrapper.S new file mode 100644 index 0000000000..860526b03c --- /dev/null +++ b/src/northbridge/intel/sandybridge/mrc_wrapper.S @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Functions to call MRC.bin from x86_64 */ + +.text +.code32 + .section ".text.mrc_wrapper", "ax", @progbits + .globl mrc_wrapper +mrc_wrapper: + /* Set up new stack frame */ + pushal + mov %esp, %ebp + + /* Align stack */ + andl $0xfffffff0, %esp + + movl 36(%ebp), %ebx /* Get function pointer */ + movl 40(%ebp), %eax /* Get argument */ + + call *%ebx + + /* Place return value on stack so that popal fetches it */ + movl %eax, 28(%ebp) + + /* Restore stack pointer */ + mov %ebp, %esp + popal + ret diff --git a/src/northbridge/intel/sandybridge/pei_data.h b/src/northbridge/intel/sandybridge/pei_data.h index 7abc25f8b6..0309cf3b89 100644 --- a/src/northbridge/intel/sandybridge/pei_data.h +++ b/src/northbridge/intel/sandybridge/pei_data.h @@ -50,10 +50,10 @@ struct pei_data uint32_t scrambler_seed; uint32_t scrambler_seed_s3; /* Data read from flash and passed into MRC */ - unsigned char *mrc_input; + uint32_t mrc_input_ptr; unsigned int mrc_input_len; /* Data from MRC that should be saved to flash */ - unsigned char *mrc_output; + uint32_t mrc_output_ptr; unsigned int mrc_output_len; /* * Max frequency DDR3 could be ran at. Could be one of four values: @@ -87,7 +87,9 @@ struct pei_data * which DIMMs should use the SPD from spd_data[0]. */ uint8_t spd_data[4][256]; - tx_byte_func tx_byte; + /* 32 bit pointer to tx_byte_func */ + uint32_t tx_byte_ptr; + int ddr3lv_support; /* * pcie_init needs to be set to 1 to have the system agent initialize PCIe. diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c index 68b02b81bc..d59aa8687f 100644 --- a/src/northbridge/intel/sandybridge/raminit_mrc.c +++ b/src/northbridge/intel/sandybridge/raminit_mrc.c @@ -28,6 +28,7 @@ #include <security/vboot/vboot_common.h> #include <southbridge/intel/bd82x6x/pch.h> #include <memory_info.h> +#include <mode_switch.h> /* Management Engine is in the southbridge */ #include <southbridge/intel/bd82x6x/me.h> @@ -49,13 +50,17 @@ #define MRC_CACHE_VERSION 0 +/* Assembly functions: */ +void mrc_wrapper(void *func_ptr, uint32_t arg1); + static void save_mrc_data(struct pei_data *pei_data) { u16 c1, c2, checksum; /* Save the MRC S3 restore data to cbmem */ - mrc_cache_stash_data(MRC_TRAINING_DATA, MRC_CACHE_VERSION, pei_data->mrc_output, - pei_data->mrc_output_len); + mrc_cache_stash_data(MRC_TRAINING_DATA, MRC_CACHE_VERSION, + (void *)(uintptr_t)pei_data->mrc_output_ptr, + pei_data->mrc_output_len); /* Save the MRC seed values to CMOS */ cmos_write32(pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED); @@ -81,7 +86,7 @@ static void prepare_mrc_cache(struct pei_data *pei_data) size_t mrc_size; /* Preset just in case there is an error */ - pei_data->mrc_input = NULL; + pei_data->mrc_input_ptr = 0; pei_data->mrc_input_len = 0; /* Read scrambler seeds from CMOS */ @@ -108,18 +113,18 @@ static void prepare_mrc_cache(struct pei_data *pei_data) return; } - pei_data->mrc_input = mrc_cache_current_mmap_leak(MRC_TRAINING_DATA, + pei_data->mrc_input_ptr = (uintptr_t)mrc_cache_current_mmap_leak(MRC_TRAINING_DATA, MRC_CACHE_VERSION, &mrc_size); - if (!pei_data->mrc_input) { + if (!pei_data->mrc_input_ptr) { /* Error message printed in find_current_mrc_cache */ return; } pei_data->mrc_input_len = mrc_size; - printk(BIOS_DEBUG, "%s: at %p, size %zx\n", __func__, - pei_data->mrc_input, mrc_size); + printk(BIOS_DEBUG, "%s: at 0x%x, size %zx\n", __func__, + pei_data->mrc_input_ptr, mrc_size); } /** @@ -129,7 +134,7 @@ static void prepare_mrc_cache(struct pei_data *pei_data) */ static void sdram_initialize(struct pei_data *pei_data) { - int (*entry)(struct pei_data *pei_data) __attribute__((regparm(1))); + int (*entry)(struct pei_data *pei_data); /* Wait for ME to be ready */ intel_early_me_init(); @@ -144,19 +149,19 @@ static void sdram_initialize(struct pei_data *pei_data) prepare_mrc_cache(pei_data); /* If MRC data is not found we cannot continue S3 resume. */ - if (pei_data->boot_mode == 2 && !pei_data->mrc_input) { + if (pei_data->boot_mode == 2 && !pei_data->mrc_input_ptr) { printk(BIOS_DEBUG, "Giving up in %s: No MRC data\n", __func__); system_reset(); } /* Pass console handler in pei_data */ - pei_data->tx_byte = do_putchar; + pei_data->tx_byte_ptr = (uintptr_t)do_putchar; /* Locate and call UEFI System Agent binary. */ entry = cbfs_map("mrc.bin", NULL); if (entry) { int rv; - rv = entry(pei_data); + rv = protected_mode_call_2arg(mrc_wrapper, (uintptr_t)entry, (uintptr_t)pei_data); if (rv) { switch (rv) { case -1: @@ -403,7 +408,7 @@ void perform_raminit(int s3resume) /* Sanity check mrc_var location by verifying a known field */ mrc_var = (void *)DCACHE_RAM_MRC_VAR_BASE; - if (mrc_var->tx_byte == (uintptr_t)pei_data.tx_byte) { + if (mrc_var->tx_byte == pei_data.tx_byte_ptr) { printk(BIOS_DEBUG, "MRC_VAR pool occupied [%08x,%08x]\n", mrc_var->pool_base, mrc_var->pool_base + mrc_var->pool_used); |