diff options
| author | Leah Rowe <leah@libreboot.org> | 2024-04-20 21:50:56 +0100 | 
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2024-04-20 22:12:04 +0100 | 
| commit | 9e3b217cfdce5e32c6c6d6e1c79786555ee4eb1c (patch) | |
| tree | 18984923887f90859a237cedc34868c5e51b3de8 /config/coreboot/haswell | |
| parent | 6da91df6b9473628b02f4d5a1e0a801a49a2e6da (diff) | |
update coreboot/haswell (NRI)
the t440p/w541 configs were re-done from scratch, because
the coreboot revisions are nearly two years apart.
i also added corebootfb configs.
hell updated their patchset. this patchset uses the following patch:
https://review.coreboot.org/c/coreboot/+/81948/1
it uses this, along with parent patches in the haswell nri patch series
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'config/coreboot/haswell')
34 files changed, 1649 insertions, 3922 deletions
| diff --git a/config/coreboot/haswell/patches/0001-commonlib-clamp.h-Add-more-clamping-functions.patch b/config/coreboot/haswell/patches/0001-commonlib-clamp.h-Add-more-clamping-functions.patch deleted file mode 100644 index 96e4c14d..00000000 --- a/config/coreboot/haswell/patches/0001-commonlib-clamp.h-Add-more-clamping-functions.patch +++ /dev/null @@ -1,54 +0,0 @@ -From dd58f5e9108bc596c93071705d2b53233d13ade6 Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Sat, 7 May 2022 20:36:10 +0200 -Subject: [PATCH 01/26] commonlib/clamp.h: Add more clamping functions - -Add more clamping functions that work with different types. - -Change-Id: I14cf335d5a54f769f8fd9184450957e876affd6b -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - src/commonlib/include/commonlib/clamp.h | 26 +++++++++++++++++-------- - 1 file changed, 18 insertions(+), 8 deletions(-) - -diff --git a/src/commonlib/include/commonlib/clamp.h b/src/commonlib/include/commonlib/clamp.h -index e01a107ed4..526185195c 100644 ---- a/src/commonlib/include/commonlib/clamp.h -+++ b/src/commonlib/include/commonlib/clamp.h -@@ -8,15 +8,25 @@ - /* -  * Clamp a value, so that it is between a lower and an upper bound. -  */ --static inline u32 clamp_u32(const u32 min, const u32 val, const u32 max) --{ --	if (val > max) --		return max; -+#define __MAKE_CLAMP_FUNC(type) \ -+	static inline type clamp_##type(const type min, const type val, const type max) \ -+	{				\ -+		if (val > max)		\ -+			return max;	\ -+		if (val < min)		\ -+			return min;	\ -+		return val;		\ -+	}				\ -  --	if (val < min) --		return min; -+__MAKE_CLAMP_FUNC(s8)	/* clamp_s8  */ -+__MAKE_CLAMP_FUNC(u8)	/* clamp_u8  */ -+__MAKE_CLAMP_FUNC(s16)	/* clamp_s16 */ -+__MAKE_CLAMP_FUNC(u16)	/* clamp_u16 */ -+__MAKE_CLAMP_FUNC(s32)	/* clamp_s32 */ -+__MAKE_CLAMP_FUNC(u32)	/* clamp_u32 */ -+__MAKE_CLAMP_FUNC(s64)	/* clamp_s64 */ -+__MAKE_CLAMP_FUNC(u64)	/* clamp_u64 */ -  --	return val; --} -+#undef __MAKE_CLAMP_FUNC -  - #endif /* COMMONLIB_CLAMP_H */ ---  -2.39.2 - diff --git a/config/coreboot/haswell/patches/0011-haswell-NRI-Initialise-MPLL.patch b/config/coreboot/haswell/patches/0001-haswell-NRI-Initialise-MPLL.patch index 1fec2e38..0de1a4ec 100644 --- a/config/coreboot/haswell/patches/0011-haswell-NRI-Initialise-MPLL.patch +++ b/config/coreboot/haswell/patches/0001-haswell-NRI-Initialise-MPLL.patch @@ -1,7 +1,7 @@ -From 77a89d55ab7a715dc20c34a6edacaaf781b56087 Mon Sep 17 00:00:00 2001 +From cce5392f272b0acc493f47f9b5ca3cf90ce901e8 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com> -Date: Sat, 7 May 2022 14:36:10 +0200 -Subject: [PATCH 11/26] haswell NRI: Initialise MPLL +Date: Thu, 11 Apr 2024 17:25:07 +0200 +Subject: [PATCH 01/20] haswell NRI: Initialise MPLL  Add code to initialise the MPLL (Memory PLL). The procedure is similar  to the one for Sandy/Ivy Bridge, but it is not worth factoring out. @@ -9,20 +9,20 @@ to the one for Sandy/Ivy Bridge, but it is not worth factoring out.  Change-Id: I978c352de68f6d8cecc76f4ae3c12daaf4be9ed6  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   2 + + .../intel/haswell/native_raminit/Makefile.mk  |   2 +   .../intel/haswell/native_raminit/init_mpll.c  | 210 ++++++++++++++++++   .../haswell/native_raminit/io_comp_control.c  |  22 ++ - .../haswell/native_raminit/raminit_main.c     |   1 + + .../haswell/native_raminit/raminit_main.c     |   3 +-   .../haswell/native_raminit/raminit_native.h   |  11 +   .../intel/haswell/registers/mchbar.h          |   3 + - 6 files changed, 249 insertions(+) + 6 files changed, 250 insertions(+), 1 deletion(-)   create mode 100644 src/northbridge/intel/haswell/native_raminit/init_mpll.c   create mode 100644 src/northbridge/intel/haswell/native_raminit/io_comp_control.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index ebf7abc6ec..c125d84f0b 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -1,5 +1,7 @@   ## SPDX-License-Identifier: GPL-2.0-or-later @@ -33,13 +33,13 @@ index ebf7abc6ec..c125d84f0b 100644   romstage-y += spd_bitmunching.c  diff --git a/src/northbridge/intel/haswell/native_raminit/init_mpll.c b/src/northbridge/intel/haswell/native_raminit/init_mpll.c  new file mode 100644 -index 0000000000..2faa183724 +index 0000000000..1f3f2c29a9  --- /dev/null  +++ b/src/northbridge/intel/haswell/native_raminit/init_mpll.c  @@ -0,0 +1,210 @@  +/* SPDX-License-Identifier: GPL-2.0-or-later */  + -+#include <commonlib/clamp.h> ++#include <commonlib/bsd/clamp.h>  +#include <console/console.h>  +#include <delay.h>  +#include <device/pci_ops.h> @@ -249,13 +249,13 @@ index 0000000000..2faa183724  +}  diff --git a/src/northbridge/intel/haswell/native_raminit/io_comp_control.c b/src/northbridge/intel/haswell/native_raminit/io_comp_control.c  new file mode 100644 -index 0000000000..7e96c08938 +index 0000000000..d45b608dd3  --- /dev/null  +++ b/src/northbridge/intel/haswell/native_raminit/io_comp_control.c  @@ -0,0 +1,22 @@  +/* SPDX-License-Identifier: GPL-2.0-or-later */  + -+#include <commonlib/clamp.h> ++#include <commonlib/bsd/clamp.h>  +#include <console/console.h>  +#include <northbridge/intel/haswell/haswell.h>  +#include <timer.h> @@ -276,13 +276,15 @@ index 0000000000..7e96c08938  +	return RAMINIT_STATUS_POLL_TIMEOUT;  +}  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -index 2d2cfa48bb..09545422c0 100644 +index 19ec5859ac..bf745e943f 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -@@ -21,6 +21,7 @@ struct task_entry { +@@ -19,7 +19,8 @@ struct task_entry { + };   static const struct task_entry cold_boot[] = { - 	{ collect_spd_info,                                       true, "PROCSPD",    }, +-	{ collect_spd_info,           true, "PROCSPD",    }, ++	{ collect_spd_info,                                       true, "PROCSPD",    },  +	{ initialise_mpll,                                        true, "INITMPLL",   },   }; diff --git a/config/coreboot/haswell/patches/0012-haswell-NRI-Post-process-selected-timings.patch b/config/coreboot/haswell/patches/0002-haswell-NRI-Post-process-selected-timings.patch index e38f8e57..0cc95cdd 100644 --- a/config/coreboot/haswell/patches/0012-haswell-NRI-Post-process-selected-timings.patch +++ b/config/coreboot/haswell/patches/0002-haswell-NRI-Post-process-selected-timings.patch @@ -1,7 +1,7 @@ -From faabed9ca8974b2e7192c55b59a9d28d75e72df6 Mon Sep 17 00:00:00 2001 +From 42b21fdce8c8bade53d9d86515f88b0665a4c1b1 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sat, 7 May 2022 16:29:55 +0200 -Subject: [PATCH 12/26] haswell NRI: Post-process selected timings +Subject: [PATCH 02/20] haswell NRI: Post-process selected timings  Once the MPLL has been initialised, convert the timings from the SPD to  be in DCLKs, which is what the hardware expects. In addition, calculate @@ -10,7 +10,7 @@ the values for tREFI and tXP.  Change-Id: Id02caf858f75b9e08016762b3aefda282b274386  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   1 + + .../intel/haswell/native_raminit/Makefile.mk  |   1 +   .../haswell/native_raminit/lookup_timings.c   |  62 +++++++++++   .../haswell/native_raminit/raminit_main.c     |   1 +   .../haswell/native_raminit/raminit_native.h   |   8 ++ @@ -18,10 +18,10 @@ Signed-off-by: Angel Pons <th3fanbus@gmail.com>   5 files changed, 172 insertions(+)   create mode 100644 src/northbridge/intel/haswell/native_raminit/lookup_timings.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index c125d84f0b..2769e0bbb4 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -1,5 +1,6 @@   ## SPDX-License-Identifier: GPL-2.0-or-later @@ -31,13 +31,13 @@ index c125d84f0b..2769e0bbb4 100644   romstage-y += raminit_main.c  diff --git a/src/northbridge/intel/haswell/native_raminit/lookup_timings.c b/src/northbridge/intel/haswell/native_raminit/lookup_timings.c  new file mode 100644 -index 0000000000..038686c844 +index 0000000000..8b81c7c341  --- /dev/null  +++ b/src/northbridge/intel/haswell/native_raminit/lookup_timings.c  @@ -0,0 +1,62 @@  +/* SPDX-License-Identifier: GPL-2.0-or-later */  + -+#include <commonlib/clamp.h> ++#include <commonlib/bsd/clamp.h>  +#include <types.h>  +  +#include "raminit_native.h" @@ -98,10 +98,10 @@ index 0000000000..038686c844  +	return lookup_timing(mem_clock_mhz, lut, ARRAY_SIZE(lut));  +}  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -index 09545422c0..5f2be980d4 100644 +index bf745e943f..2fea658415 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -@@ -22,6 +22,7 @@ struct task_entry { +@@ -21,6 +21,7 @@ struct task_entry {   static const struct task_entry cold_boot[] = {   	{ collect_spd_info,                                       true, "PROCSPD",    },   	{ initialise_mpll,                                        true, "INITMPLL",   }, @@ -137,7 +137,7 @@ index a54581abc7..01e5ed1bd6 100644  +   #endif  diff --git a/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c b/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c -index dbe02c72d0..becbea0725 100644 +index 2dab8504c4..7d98341a7e 100644  --- a/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c  +++ b/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c  @@ -204,3 +204,103 @@ enum raminit_status collect_spd_info(struct sysinfo *ctrl) @@ -221,7 +221,7 @@ index dbe02c72d0..becbea0725 100644  +	 */  +  +	/* tCK is special */ -+	printk(BIOS_DEBUG, "Selected tCK          : %u ns\n", ctrl->tCK / 256); ++	printk(BIOS_DEBUG, "Selected tCK          : %u ps\n", ctrl->tCK * 1000 / 256);  +  +	/* Primary timings */  +	printk(BIOS_DEBUG, "Selected tAA          : %uT\n", ctrl->tAA); diff --git a/config/coreboot/haswell/patches/0002-nb-intel-haswell-Introduce-option-to-not-use-MRC.bin.patch b/config/coreboot/haswell/patches/0002-nb-intel-haswell-Introduce-option-to-not-use-MRC.bin.patch deleted file mode 100644 index 35d5c89e..00000000 --- a/config/coreboot/haswell/patches/0002-nb-intel-haswell-Introduce-option-to-not-use-MRC.bin.patch +++ /dev/null @@ -1,143 +0,0 @@ -From c07391821c32cafea950574b85468f5b3284b6df Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Fri, 6 May 2022 21:12:14 +0200 -Subject: [PATCH 02/26] nb/intel/haswell: Introduce option to not use MRC.bin - -Introduce the `USE_NATIVE_RAMINIT` Kconfig option, which should allow -booting coreboot on Haswell mainboards without the need of the closed -source MRC.bin. For now, this option does not work at all; the needed -magic will be implemented in subsequent commits. Add a config file to -make sure the newly-introduced option gets build-tested. - -Change-Id: I46c77586f9b5771624082e07c60c205e578edd8e -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - configs/config.asrock_b85m_pro4.native_raminit    |  5 +++++ - src/northbridge/intel/haswell/Kconfig             | 13 +++++++++++++ - src/northbridge/intel/haswell/Makefile.inc        |  7 ++++++- - .../intel/haswell/native_raminit/Makefile.inc     |  3 +++ - .../intel/haswell/native_raminit/raminit_native.c | 15 +++++++++++++++ - 5 files changed, 42 insertions(+), 1 deletion(-) - create mode 100644 configs/config.asrock_b85m_pro4.native_raminit - create mode 100644 src/northbridge/intel/haswell/native_raminit/Makefile.inc - create mode 100644 src/northbridge/intel/haswell/native_raminit/raminit_native.c - -diff --git a/configs/config.asrock_b85m_pro4.native_raminit b/configs/config.asrock_b85m_pro4.native_raminit -new file mode 100644 -index 0000000000..2de538926f ---- /dev/null -+++ b/configs/config.asrock_b85m_pro4.native_raminit -@@ -0,0 +1,5 @@ -+# Configuration used to build-test native raminit -+CONFIG_VENDOR_ASROCK=y -+CONFIG_BOARD_ASROCK_B85M_PRO4=y -+CONFIG_USE_NATIVE_RAMINIT=y -+CONFIG_DEBUG_RAM_SETUP=y -diff --git a/src/northbridge/intel/haswell/Kconfig b/src/northbridge/intel/haswell/Kconfig -index 50acb09a91..b659bf6d98 100644 ---- a/src/northbridge/intel/haswell/Kconfig -+++ b/src/northbridge/intel/haswell/Kconfig -@@ -9,6 +9,14 @@ config NORTHBRIDGE_INTEL_HASWELL -  - if NORTHBRIDGE_INTEL_HASWELL -  -+config USE_NATIVE_RAMINIT -+	bool "[NOT WORKING] Use native raminit" -+	default n -+	select HAVE_DEBUG_RAM_SETUP -+	help -+	  Select if you want to use coreboot implementation of raminit rather than -+	  MRC.bin. Currently incomplete and does not boot. -+ - config HASWELL_VBOOT_IN_BOOTBLOCK - 	depends on VBOOT - 	bool "Start verstage in bootblock" -@@ -45,6 +53,7 @@ config DCACHE_RAM_BASE -  - config DCACHE_RAM_SIZE - 	hex -+	default 0x40000 if USE_NATIVE_RAMINIT - 	default 0x10000 - 	help - 	  The size of the cache-as-ram region required during bootblock -@@ -53,12 +62,14 @@ config DCACHE_RAM_SIZE -  - config DCACHE_RAM_MRC_VAR_SIZE - 	hex -+	default 0x0 if USE_NATIVE_RAMINIT - 	default 0x30000 - 	help - 	  The amount of cache-as-ram region required by the reference code. -  - config DCACHE_BSP_STACK_SIZE - 	hex -+	default 0x20000 if USE_NATIVE_RAMINIT - 	default 0x2000 - 	help - 	  The amount of anticipated stack usage in CAR by bootblock and -@@ -66,6 +77,7 @@ config DCACHE_BSP_STACK_SIZE -  - config HAVE_MRC - 	bool "Add a System Agent binary" -+	depends on !USE_NATIVE_RAMINIT - 	help - 	  Select this option to add a System Agent binary to - 	  the resulting coreboot image. -@@ -82,6 +94,7 @@ config MRC_FILE -  - config HASWELL_HIDE_PEG_FROM_MRC - 	bool "Hide PEG devices from MRC to work around hardcoded MRC behavior" -+	depends on !USE_NATIVE_RAMINIT - 	default y - 	help - 	  If set, hides all PEG devices from MRC. This allows the iGPU -diff --git a/src/northbridge/intel/haswell/Makefile.inc b/src/northbridge/intel/haswell/Makefile.inc -index 2d1532be05..329f1f7ffe 100644 ---- a/src/northbridge/intel/haswell/Makefile.inc -+++ b/src/northbridge/intel/haswell/Makefile.inc -@@ -19,6 +19,11 @@ romstage-y += report_platform.c -  - postcar-y += memmap.c -  --subdirs-y += haswell_mrc -+ifeq ($(CONFIG_USE_NATIVE_RAMINIT),y) -+subdirs-y  += native_raminit -+ -+else -+subdirs-y  += haswell_mrc -+endif -  - endif -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc -new file mode 100644 -index 0000000000..8cfb4fb33e ---- /dev/null -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc -@@ -0,0 +1,3 @@ -+## SPDX-License-Identifier: GPL-2.0-or-later -+ -+romstage-y += raminit_native.c -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -new file mode 100644 -index 0000000000..1aafdf8659 ---- /dev/null -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -@@ -0,0 +1,15 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <console/console.h> -+#include <northbridge/intel/haswell/raminit.h> -+ -+void perform_raminit(const int s3resume) -+{ -+	/* -+	 * See, this function's name is a lie. There are more things to -+	 * do that memory initialisation, but they are relatively easy. -+	 */ -+ -+	/** TODO: Implement the required magic **/ -+	die("NATIVE RAMINIT: More Magic (tm) required.\n"); -+} ---  -2.39.2 - diff --git a/config/coreboot/haswell/patches/0013-haswell-NRI-Configure-initial-MC-settings.patch b/config/coreboot/haswell/patches/0003-haswell-NRI-Configure-initial-MC-settings.patch index b1c33328..f44eb029 100644 --- a/config/coreboot/haswell/patches/0013-haswell-NRI-Configure-initial-MC-settings.patch +++ b/config/coreboot/haswell/patches/0003-haswell-NRI-Configure-initial-MC-settings.patch @@ -1,7 +1,7 @@ -From 1b0b17d85256193de825fa7ff0e04767c818f2fc Mon Sep 17 00:00:00 2001 +From 574f4965976b56f98a825dea71e919fefb2c8547 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sat, 7 May 2022 17:22:07 +0200 -Subject: [PATCH 13/26] haswell NRI: Configure initial MC settings +Subject: [PATCH 03/20] haswell NRI: Configure initial MC settings  Program initial memory controller settings. Many of these values will be  adjusted later during training. @@ -9,7 +9,7 @@ adjusted later during training.  Change-Id: If33846b51cb1bab5d0458fe626e13afb1bdc900e  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   2 + + .../intel/haswell/native_raminit/Makefile.mk  |   2 +   .../haswell/native_raminit/configure_mc.c     | 822 ++++++++++++++++++   .../haswell/native_raminit/raminit_main.c     |   2 +   .../haswell/native_raminit/raminit_native.h   | 101 +++ @@ -21,10 +21,10 @@ Signed-off-by: Angel Pons <th3fanbus@gmail.com>   create mode 100644 src/northbridge/intel/haswell/native_raminit/reg_structs.h   create mode 100644 src/northbridge/intel/haswell/native_raminit/timings_refresh.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index 2769e0bbb4..fc55277a65 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -1,8 +1,10 @@   ## SPDX-License-Identifier: GPL-2.0-or-later @@ -38,14 +38,14 @@ index 2769e0bbb4..fc55277a65 100644  +romstage-y += timings_refresh.c  diff --git a/src/northbridge/intel/haswell/native_raminit/configure_mc.c b/src/northbridge/intel/haswell/native_raminit/configure_mc.c  new file mode 100644 -index 0000000000..2a667b075b +index 0000000000..88249725a7  --- /dev/null  +++ b/src/northbridge/intel/haswell/native_raminit/configure_mc.c  @@ -0,0 +1,822 @@  +/* SPDX-License-Identifier: GPL-2.0-or-later */  +  +#include <assert.h> -+#include <commonlib/clamp.h> ++#include <commonlib/bsd/clamp.h>  +#include <console/console.h>  +#include <delay.h>  +#include <lib.h> @@ -131,22 +131,22 @@ index 0000000000..2a667b075b  +  +static const uint8_t rxb_trad[2][5][4] = {  +	{	/* Vdd low */ -+		/*  1067 MHz,     1333 MHz,     1600 MHz,     1867 MHz,     2133 MHz, */ ++		/* 1067 MT/s,    1333 MT/s,    1600 MT/s,    1867 MT/s,    2133 MT/s, */  +		{4, 3, 3, 2}, {4, 4, 3, 2}, {5, 4, 3, 3}, {5, 4, 4, 3}, {5, 4, 4, 3},  +	},  +	{	/* Vdd hi */ -+		/*  1067 MHz,     1333 MHz,     1600 MHz,     1867 MHz,     2133 MHz, */ ++		/* 1067 MT/s,    1333 MT/s,    1600 MT/s,    1867 MT/s,    2133 MT/s, */  +		{4, 3, 3, 2}, {4, 4, 3, 2}, {5, 4, 3, 3}, {5, 4, 4, 3}, {4, 4, 3, 3},  +	},  +};  +  +static const uint8_t rxb_ultx[2][3][4] = {  +	{	/* Vdd low */ -+		/*  1067 MHz,     1333 MHz,     1600 MHz, */ ++		/* 1067 MT/s,    1333 MT/s,    1600 MT/s, */  +		{5, 6, 6, 5}, {5, 6, 6, 5}, {4, 6, 6, 6},  +	},  +	{	/* Vdd hi */ -+		/*  1067 MHz,     1333 MHz,     1600 MHz, */ ++		/* 1067 MT/s,    1333 MT/s,    1600 MT/s, */  +		{7, 6, 6, 5}, {7, 6, 6, 5}, {7, 6, 6, 6},  +	},  +}; @@ -277,7 +277,7 @@ index 0000000000..2a667b075b  +	const int16_t coding[] = {0, -125, -62, -31, 250, 125, 62, 31};  +	*best_a = 0;  +	*best_b = 0; -+	int16_t	best_err = slope; ++	int16_t best_err = slope;  +	for (uint8_t b = 0; b < ARRAY_SIZE(coding); b++) {  +		for (uint8_t a = b; a < ARRAY_SIZE(coding); a++) {  +			int16_t	error = slope - (coding[a] + coding[b]); @@ -865,10 +865,10 @@ index 0000000000..2a667b075b  +	return RAMINIT_STATUS_SUCCESS;  +}  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -index 5f2be980d4..3a773cfa19 100644 +index 2fea658415..fcc981ad04 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -@@ -23,6 +23,7 @@ static const struct task_entry cold_boot[] = { +@@ -22,6 +22,7 @@ static const struct task_entry cold_boot[] = {   	{ collect_spd_info,                                       true, "PROCSPD",    },   	{ initialise_mpll,                                        true, "INITMPLL",   },   	{ convert_timings,                                        true, "CONVTIM",    }, @@ -876,7 +876,7 @@ index 5f2be980d4..3a773cfa19 100644   };   /* Return a generic stepping value to make stepping checks simpler */ -@@ -54,6 +55,7 @@ static void initialize_ctrl(struct sysinfo *ctrl) +@@ -53,6 +54,7 @@ static void initialize_ctrl(struct sysinfo *ctrl)   	ctrl->cpu = cpu_get_cpuid();   	ctrl->stepping = get_stepping(ctrl->cpu); diff --git a/config/coreboot/haswell/patches/0003-haswell-lynxpoint-Add-native-DMI-init.patch b/config/coreboot/haswell/patches/0003-haswell-lynxpoint-Add-native-DMI-init.patch deleted file mode 100644 index 4e70407c..00000000 --- a/config/coreboot/haswell/patches/0003-haswell-lynxpoint-Add-native-DMI-init.patch +++ /dev/null @@ -1,615 +0,0 @@ -From 6ec71c6df97eded010e96c4ea2bd37cc6a13849d Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Fri, 6 May 2022 21:56:48 +0200 -Subject: [PATCH 03/26] haswell/lynxpoint: Add native DMI init - -Implement native DMI init for Haswell and Lynx Point. This is only -needed on non-ULT platforms, and only when MRC.bin is not used. - -TEST=Verify DMI initialises correctly on Asrock B85M Pro4. - -Change-Id: I5fb1a2adc4ffbf0ebbf0d2d3a444055c53765faa -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - src/northbridge/intel/haswell/Makefile.inc    |   1 + - src/northbridge/intel/haswell/early_dmi.c     |  96 ++++++++++++ - src/northbridge/intel/haswell/early_pcie.c    | 121 ++++++++++++++ - src/northbridge/intel/haswell/haswell.h       |   3 + - .../haswell/native_raminit/raminit_native.c   |  15 ++ - src/northbridge/intel/haswell/vcu_mailbox.c   | 147 ++++++++++++++++++ - src/northbridge/intel/haswell/vcu_mailbox.h   |  16 ++ - src/southbridge/intel/lynxpoint/Makefile.inc  |   2 + - .../intel/lynxpoint/early_pch_native.c        |  52 +++++++ - src/southbridge/intel/lynxpoint/pch.h         |  20 ++- - 10 files changed, 472 insertions(+), 1 deletion(-) - create mode 100644 src/northbridge/intel/haswell/early_dmi.c - create mode 100644 src/northbridge/intel/haswell/early_pcie.c - create mode 100644 src/northbridge/intel/haswell/vcu_mailbox.c - create mode 100644 src/northbridge/intel/haswell/vcu_mailbox.h - create mode 100644 src/southbridge/intel/lynxpoint/early_pch_native.c - -diff --git a/src/northbridge/intel/haswell/Makefile.inc b/src/northbridge/intel/haswell/Makefile.inc -index 329f1f7ffe..df0b097296 100644 ---- a/src/northbridge/intel/haswell/Makefile.inc -+++ b/src/northbridge/intel/haswell/Makefile.inc -@@ -20,6 +20,7 @@ romstage-y += report_platform.c - postcar-y += memmap.c -  - ifeq ($(CONFIG_USE_NATIVE_RAMINIT),y) -+romstage-y += early_dmi.c early_pcie.c vcu_mailbox.c - subdirs-y  += native_raminit -  - else -diff --git a/src/northbridge/intel/haswell/early_dmi.c b/src/northbridge/intel/haswell/early_dmi.c -new file mode 100644 -index 0000000000..9941242fd5 ---- /dev/null -+++ b/src/northbridge/intel/haswell/early_dmi.c -@@ -0,0 +1,96 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <console/console.h> -+#include <northbridge/intel/haswell/haswell.h> -+#include <southbridge/intel/lynxpoint/pch.h> -+#include <types.h> -+ -+static void dmi_print_link_status(int loglevel) -+{ -+	const uint16_t dmilsts = dmibar_read16(DMILSTS); -+	printk(loglevel, "DMI: Running at Gen%u x%u\n", dmilsts & 0xf, dmilsts >> 4 & 0x1f); -+} -+ -+#define RETRAIN	(1 << 5) -+ -+#define LTRN	(1 << 11) -+ -+static void dmi_setup_physical_layer(void) -+{ -+	/* Program DMI AFE settings, which are needed for DMI to work */ -+	peg_dmi_recipe(false, 0); -+ -+	/* Additional DMI programming steps */ -+	dmibar_setbits32(0x258, 1 << 29); -+	dmibar_clrsetbits32(0x208, 0x7ff, 0x6b5); -+	dmibar_clrsetbits32(0x22c, 0xffff, 0x2020); -+ -+	/* Write SA reference code version */ -+	dmibar_write32(0x71c, 0x0000000f); -+	dmibar_write32(0x720, 0x01060200); -+ -+	/* We also have to bring up the PCH side of the DMI link */ -+	pch_dmi_setup_physical_layer(); -+ -+	/* Write-once settings */ -+	dmibar_clrsetbits32(DMILCAP, 0x3f00f, 2 << 0); -+ -+	printk(BIOS_DEBUG, "Retraining DMI at Gen2 speeds...\n"); -+	dmi_print_link_status(BIOS_DEBUG); -+ -+	/* Retrain link */ -+	dmibar_setbits16(DMILCTL, RETRAIN); -+	do {} while (dmibar_read16(DMILSTS) & LTRN); -+	dmi_print_link_status(BIOS_DEBUG); -+ -+	/* Retrain link again for DMI Gen2 speeds */ -+	dmibar_setbits16(DMILCTL, RETRAIN); -+	do {} while (dmibar_read16(DMILSTS) & LTRN); -+	dmi_print_link_status(BIOS_INFO); -+} -+ -+#define VC_ACTIVE	(1U << 31) -+ -+#define VCNEGPND	(1 << 1) -+ -+#define DMI_VC_CFG(vcid, tcmap)	(VC_ACTIVE | ((vcid) << 24) | (tcmap)) -+ -+static void dmi_tc_vc_mapping(void) -+{ -+	printk(BIOS_DEBUG, "Programming SA  DMI VC/TC mappings...\n"); -+ -+	if (CONFIG(INTEL_LYNXPOINT_LP)) -+		dmibar_setbits8(0xa78, 1 << 1); -+ -+	/* Each TC is mapped to one and only one VC */ -+	const u32 vc0 = DMI_VC_CFG(0, (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 0)); -+	const u32 vc1 = DMI_VC_CFG(1, (1 << 1)); -+	const u32 vcp = DMI_VC_CFG(2, (1 << 2)); -+	const u32 vcm = DMI_VC_CFG(7, (1 << 7)); -+	dmibar_write32(DMIVC0RCTL, vc0); -+	dmibar_write32(DMIVC1RCTL, vc1); -+	dmibar_write32(DMIVCPRCTL, vcp); -+	dmibar_write32(DMIVCMRCTL, vcm); -+ -+	/* Set Extended VC Count (EVCC) to 1 if VC1 is active */ -+	dmibar_clrsetbits8(DMIPVCCAP1, 7, !!(vc1 & VC_ACTIVE)); -+ -+	/* -+	 * We also have to program the PCH side of the DMI link. Since both ends -+	 * must use the same Virtual Channel settings, we pass them as arguments. -+	 */ -+	pch_dmi_tc_vc_mapping(vc0, vc1, vcp, vcm); -+ -+	printk(BIOS_DEBUG, "Waiting for SA  DMI VC negotiation... "); -+	do {} while (dmibar_read16(DMIVC0RSTS) & VCNEGPND); -+	do {} while (dmibar_read16(DMIVC1RSTS) & VCNEGPND); -+	do {} while (dmibar_read16(DMIVCPRSTS) & VCNEGPND); -+	do {} while (dmibar_read16(DMIVCMRSTS) & VCNEGPND); -+	printk(BIOS_DEBUG, "done!\n"); -+} -+ -+void dmi_early_init(void) -+{ -+	dmi_setup_physical_layer(); -+	dmi_tc_vc_mapping(); -+} -diff --git a/src/northbridge/intel/haswell/early_pcie.c b/src/northbridge/intel/haswell/early_pcie.c -new file mode 100644 -index 0000000000..d3940e3fac ---- /dev/null -+++ b/src/northbridge/intel/haswell/early_pcie.c -@@ -0,0 +1,121 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <console/console.h> -+#include <device/pci_def.h> -+#include <device/pci_mmio_cfg.h> -+#include <device/pci_ops.h> -+#include <northbridge/intel/haswell/haswell.h> -+#include <northbridge/intel/haswell/vcu_mailbox.h> -+#include <types.h> -+ -+#define PEG_DEV(func)		PCI_DEV(0, 1, func) -+ -+#define MAX_PEG_FUNC		3 -+ -+static void peg_dmi_unset_and_set_mask_pcicfg( -+	volatile union pci_bank *const bank, -+	const uint32_t offset, -+	const uint32_t unset_mask, -+	const uint32_t set_mask, -+	const uint32_t shift, -+	const bool valid) -+{ -+	if (!valid) -+		return; -+ -+	volatile uint32_t *const addr = &bank->reg32[offset / sizeof(uint32_t)]; -+	clrsetbits32(addr, unset_mask << shift, set_mask << shift); -+} -+ -+static void peg_dmi_unset_and_set_mask_common( -+	const bool is_peg, -+	const uint32_t offset, -+	const uint32_t unset, -+	const uint32_t set, -+	const uint32_t shift, -+	const bool valid) -+{ -+	const uint32_t unset_mask = unset << shift; -+	const uint32_t   set_mask =   set << shift; -+	if (is_peg) { -+		for (uint8_t i = 0; i < MAX_PEG_FUNC; i++) -+			pci_update_config32(PEG_DEV(i), offset, ~unset_mask, set_mask); -+	} else { -+		dmibar_clrsetbits32(offset, unset_mask, set_mask); -+	} -+} -+ -+static void peg_dmi_unset_and_set_mask_vcu_mmio( -+	const uint32_t addr, -+	const uint32_t unset_mask, -+	const uint32_t set_mask, -+	const uint32_t shift, -+	const bool valid) -+{ -+	if (!valid) -+		return; -+ -+	vcu_update_mmio(addr, ~(unset_mask << shift), set_mask << shift); -+} -+ -+#define BUNDLE_STEP	0x20 -+ -+static void *const dmibar = (void *)(uintptr_t)CONFIG_FIXED_DMIBAR_MMIO_BASE; -+ -+void peg_dmi_recipe(const bool is_peg, const pci_devfn_t dev) -+{ -+	const bool always = true; -+	const bool is_dmi = !is_peg; -+ -+	/* Treat DMIBAR and PEG devices the same way */ -+	volatile union pci_bank *const bank = is_peg ? pci_map_bus(dev) : dmibar; -+ -+	const size_t bundles = (is_peg ? 8 : 2) * BUNDLE_STEP; -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) { -+		/* These are actually per-lane */ -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0xa00 + i, 0x1f, 0x0c,  0, always); -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0xa10 + i, 0x1f, 0x0c,  0, always); -+	} -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x904 + i, 0x1f, 0x02,  0, is_peg); -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x904 + i, 0x1f, 0x03,  5, is_peg); -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x90c + i, 0x3f, 0x09,  5, always); -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x90c + i, 0x0f, 0x05, 21, is_peg); -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x910 + i, 0x0f, 0x08,  6, is_peg); -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x910 + i, 0x0f, 0x00, 10, always); -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x910 + i, 0x07, 0x00, 18, always); -+ -+	peg_dmi_unset_and_set_mask_vcu_mmio(0x0c008001, 0x1f, 0x03, 25, is_peg); -+	peg_dmi_unset_and_set_mask_vcu_mmio(0x0c0c8001, 0x3f, 0x00, 23, is_dmi); -+ -+	peg_dmi_unset_and_set_mask_pcicfg(bank, 0xc28, 0x1f, 0x13, 18, always); -+ -+	peg_dmi_unset_and_set_mask_common(is_peg, 0xc38, 0x01, 0x00,  6, always); -+	peg_dmi_unset_and_set_mask_common(is_peg, 0x260, 0x03, 0x02,  0, always); -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x900 + i, 0x03, 0x00, 26, always); -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x904 + i, 0x03, 0x03, 10, always); -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x90c + i, 0x1f, 0x07, 25, is_peg); -+ -+	for (size_t i = 0; i < bundles; i += BUNDLE_STEP) -+		peg_dmi_unset_and_set_mask_pcicfg(bank, 0x91c + i, 0x07, 0x05, 27, is_peg); -+} -diff --git a/src/northbridge/intel/haswell/haswell.h b/src/northbridge/intel/haswell/haswell.h -index 1b29f6baf0..30b4abd0a7 100644 ---- a/src/northbridge/intel/haswell/haswell.h -+++ b/src/northbridge/intel/haswell/haswell.h -@@ -34,6 +34,9 @@ void haswell_early_initialization(void); - void haswell_late_initialization(void); - void haswell_unhide_peg(void); -  -+void dmi_early_init(void); -+void peg_dmi_recipe(const bool is_peg, const pci_devfn_t dev); -+ - void report_platform_info(void); -  - struct acpi_rsdp; -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -index 1aafdf8659..0938e026e3 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -@@ -1,7 +1,19 @@ - /* SPDX-License-Identifier: GPL-2.0-or-later */ -  - #include <console/console.h> -+#include <northbridge/intel/haswell/haswell.h> - #include <northbridge/intel/haswell/raminit.h> -+#include <types.h> -+ -+static bool early_init_native(int s3resume) -+{ -+	printk(BIOS_DEBUG, "Starting native platform initialisation\n"); -+ -+	if (!CONFIG(INTEL_LYNXPOINT_LP)) -+		dmi_early_init(); -+ -+	return false; -+} -  - void perform_raminit(const int s3resume) - { -@@ -9,6 +21,9 @@ void perform_raminit(const int s3resume) - 	 * See, this function's name is a lie. There are more things to - 	 * do that memory initialisation, but they are relatively easy. - 	 */ -+	const bool cpu_replaced = early_init_native(s3resume); -+ -+	(void)cpu_replaced; -  - 	/** TODO: Implement the required magic **/ - 	die("NATIVE RAMINIT: More Magic (tm) required.\n"); -diff --git a/src/northbridge/intel/haswell/vcu_mailbox.c b/src/northbridge/intel/haswell/vcu_mailbox.c -new file mode 100644 -index 0000000000..aead144023 ---- /dev/null -+++ b/src/northbridge/intel/haswell/vcu_mailbox.c -@@ -0,0 +1,147 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <assert.h> -+#include <console/console.h> -+#include <delay.h> -+#include <northbridge/intel/haswell/haswell.h> -+#include <northbridge/intel/haswell/vcu_mailbox.h> -+#include <stdint.h> -+ -+/* -+ * This is a library for the VCU (Validation Control Unit) mailbox. This -+ * mailbox is primarily used to adjust some magic PCIe tuning parameters. -+ * -+ * There are two revisions of the VCU mailbox. Rev1 is specific to Haswell -+ * stepping A0, and all other steppings use Rev2. Haswell stepping A0 CPUs -+ * are early Engineering Samples with undocumented errata, and most likely -+ * need special microcode updates to boot. Thus, the code does not support -+ * VCU mailbox Rev1, because no one should need it anymore. -+ */ -+ -+#define VCU_MAILBOX_INTERFACE	0x6c00 -+#define VCU_MAILBOX_DATA	0x6c04 -+ -+#define VCU_RUN_BUSY		(1 << 31) -+ -+enum vcu_opcode { -+	VCU_OPCODE_READ_VCU_API_VER_ID	= 0x01, -+	VCU_OPCODE_OPEN_SEQ		= 0x02, -+	VCU_OPCODE_CLOSE_SEQ		= 0x03, -+	VCU_OPCODE_READ_DATA		= 0x07, -+	VCU_OPCODE_WRITE_DATA		= 0x08, -+	VCU_OPCODE_READ_CSR		= 0x13, -+	VCU_OPCODE_WRITE_CSR		= 0x14, -+	VCU_OPCODE_READ_MMIO		= 0x15, -+	VCU_OPCODE_WRITE_MMIO		= 0x16, -+}; -+ -+enum vcu_sequence { -+	SEQ_ID_READ_CSR		= 0x1, -+	SEQ_ID_WRITE_CSR	= 0x2, -+	SEQ_ID_READ_MMIO	= 0x3, -+	SEQ_ID_WRITE_MMIO	= 0x4, -+}; -+ -+#define VCU_RESPONSE_MASK		0xffff -+#define VCU_RESPONSE_SUCCESS		0x40 -+#define VCU_RESPONSE_BUSY		0x80 -+#define VCU_RESPONSE_THREAD_UNAVAILABLE	0x82 -+#define VCU_RESPONSE_ILLEGAL		0x90 -+ -+/* FIXME: Use timer API */ -+static void send_vcu_command(const enum vcu_opcode opcode, const uint32_t data) -+{ -+	for (unsigned int i = 0; i < 10; i++) { -+		mchbar_write32(VCU_MAILBOX_DATA, data); -+		mchbar_write32(VCU_MAILBOX_INTERFACE, opcode | VCU_RUN_BUSY); -+		uint32_t vcu_interface; -+		for (unsigned int j = 0; j < 100; j++) { -+			vcu_interface = mchbar_read32(VCU_MAILBOX_INTERFACE); -+			if (!(vcu_interface & VCU_RUN_BUSY)) -+				break; -+ -+			udelay(10); -+		} -+		if (vcu_interface & VCU_RUN_BUSY) -+			continue; -+ -+		if ((vcu_interface & VCU_RESPONSE_MASK) == VCU_RESPONSE_SUCCESS) -+			return; -+	} -+	printk(BIOS_ERR, "VCU: Failed to send command\n"); -+} -+ -+static enum vcu_opcode get_register_opcode(enum vcu_sequence seq) -+{ -+	switch (seq) { -+	case SEQ_ID_READ_CSR: -+		return VCU_OPCODE_READ_CSR; -+	case SEQ_ID_WRITE_CSR: -+		return VCU_OPCODE_WRITE_CSR; -+	case SEQ_ID_READ_MMIO: -+		return VCU_OPCODE_READ_MMIO; -+	case SEQ_ID_WRITE_MMIO: -+		return VCU_OPCODE_WRITE_MMIO; -+	default: -+		return dead_code_t(enum vcu_opcode); -+	} -+} -+ -+static enum vcu_opcode get_data_opcode(enum vcu_sequence seq) -+{ -+	switch (seq) { -+	case SEQ_ID_READ_CSR: -+	case SEQ_ID_READ_MMIO: -+		return VCU_OPCODE_READ_DATA; -+	case SEQ_ID_WRITE_CSR: -+	case SEQ_ID_WRITE_MMIO: -+		return VCU_OPCODE_WRITE_DATA; -+	default: -+		return dead_code_t(enum vcu_opcode); -+	} -+} -+ -+static uint32_t send_vcu_sequence(uint32_t addr, enum vcu_sequence seq, uint32_t wr_data) -+{ -+	send_vcu_command(VCU_OPCODE_OPEN_SEQ, seq); -+ -+	send_vcu_command(get_register_opcode(seq), addr); -+ -+	send_vcu_command(get_data_opcode(seq), wr_data); -+ -+	const uint32_t rd_data = mchbar_read32(VCU_MAILBOX_DATA); -+ -+	send_vcu_command(VCU_OPCODE_CLOSE_SEQ, seq); -+ -+	return rd_data; -+} -+ -+uint32_t vcu_read_csr(uint32_t addr) -+{ -+	return send_vcu_sequence(addr, SEQ_ID_READ_CSR, 0); -+} -+ -+void vcu_write_csr(uint32_t addr, uint32_t data) -+{ -+	send_vcu_sequence(addr, SEQ_ID_WRITE_CSR, data); -+} -+ -+void vcu_update_csr(uint32_t addr, uint32_t andvalue, uint32_t orvalue) -+{ -+	vcu_write_csr(addr, (vcu_read_csr(addr) & andvalue) | orvalue); -+} -+ -+uint32_t vcu_read_mmio(uint32_t addr) -+{ -+	return send_vcu_sequence(addr, SEQ_ID_READ_MMIO, 0); -+} -+ -+void vcu_write_mmio(uint32_t addr, uint32_t data) -+{ -+	send_vcu_sequence(addr, SEQ_ID_WRITE_MMIO, data); -+} -+ -+void vcu_update_mmio(uint32_t addr, uint32_t andvalue, uint32_t orvalue) -+{ -+	vcu_write_mmio(addr, (vcu_read_mmio(addr) & andvalue) | orvalue); -+} -diff --git a/src/northbridge/intel/haswell/vcu_mailbox.h b/src/northbridge/intel/haswell/vcu_mailbox.h -new file mode 100644 -index 0000000000..ba0a62e486 ---- /dev/null -+++ b/src/northbridge/intel/haswell/vcu_mailbox.h -@@ -0,0 +1,16 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#ifndef HASWELL_VCU_MAILBOX_H -+#define HASWELL_VCU_MAILBOX_H -+ -+#include <stdint.h> -+ -+uint32_t vcu_read_csr(uint32_t addr); -+void vcu_write_csr(uint32_t addr, uint32_t data); -+void vcu_update_csr(uint32_t addr, uint32_t andvalue, uint32_t orvalue); -+ -+uint32_t vcu_read_mmio(uint32_t addr); -+void vcu_write_mmio(uint32_t addr, uint32_t data); -+void vcu_update_mmio(uint32_t addr, uint32_t andvalue, uint32_t orvalue); -+ -+#endif /* HASWELL_VCU_MAILBOX_H */ -diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc -index 02022d348d..b8503ac8bc 100644 ---- a/src/southbridge/intel/lynxpoint/Makefile.inc -+++ b/src/southbridge/intel/lynxpoint/Makefile.inc -@@ -37,6 +37,8 @@ bootblock-y += early_pch.c - romstage-y += early_usb.c early_me.c me_status.c early_pch.c - romstage-y += pmutil.c -  -+romstage-$(CONFIG_USE_NATIVE_RAMINIT) += early_pch_native.c -+ - ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y) - romstage-y += lp_gpio.c - ramstage-y += lp_gpio.c -diff --git a/src/southbridge/intel/lynxpoint/early_pch_native.c b/src/southbridge/intel/lynxpoint/early_pch_native.c -new file mode 100644 -index 0000000000..c28ddfcf5d ---- /dev/null -+++ b/src/southbridge/intel/lynxpoint/early_pch_native.c -@@ -0,0 +1,52 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <console/console.h> -+#include <device/pci_ops.h> -+#include <southbridge/intel/lynxpoint/pch.h> -+#include <types.h> -+ -+void pch_dmi_setup_physical_layer(void) -+{ -+	/* FIXME: We need to make sure the SA supports Gen2 as well */ -+	if ((RCBA32(0x21a4) & 0x0f) == 0x02) { -+		/* Set Gen 2 Common Clock N_FTS */ -+		RCBA32_AND_OR(0x2340, ~0x00ff0000, 0x3a << 16); -+ -+		/* Set Target Link Speed to DMI Gen2 */ -+		RCBA8_AND_OR(DLCTL2, ~0x07, 0x02); -+	} -+} -+ -+#define VC_ACTIVE	(1U << 31) -+ -+#define VCNEGPND	(1 << 1) -+ -+void pch_dmi_tc_vc_mapping(const u32 vc0, const u32 vc1, const u32 vcp, const u32 vcm) -+{ -+	printk(BIOS_DEBUG, "Programming PCH DMI VC/TC mappings...\n"); -+ -+	RCBA32_AND_OR(CIR0050, ~(0xf << 20), 2 << 20); -+	if (vcp & VC_ACTIVE) -+		RCBA32_OR(CIR0050, 1 << 19 | 1 << 17); -+ -+	RCBA32(CIR0050);	/* Posted Write */ -+ -+	/* Use the same virtual channel mapping on both ends of the DMI link */ -+	RCBA32(V0CTL) = vc0; -+	RCBA32(V1CTL) = vc1; -+	RCBA32(V1CTL);		/* Posted Write */ -+	RCBA32(VPCTL) = vcp; -+	RCBA32(VPCTL);		/* Posted Write */ -+	RCBA32(VMCTL) = vcm; -+ -+	/* Lock the registers */ -+	RCBA32_OR(CIR0050, 1U << 31); -+	RCBA32(CIR0050);	/* Posted Write */ -+ -+	printk(BIOS_DEBUG, "Waiting for PCH DMI VC negotiation... "); -+	do {} while (RCBA16(V0STS) & VCNEGPND); -+	do {} while (RCBA16(V1STS) & VCNEGPND); -+	do {} while (RCBA16(VPSTS) & VCNEGPND); -+	do {} while (RCBA16(VMSTS) & VCNEGPND); -+	printk(BIOS_DEBUG, "done!\n"); -+} -diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h -index 7d9fc6d6af..b5e0c2a830 100644 ---- a/src/southbridge/intel/lynxpoint/pch.h -+++ b/src/southbridge/intel/lynxpoint/pch.h -@@ -113,6 +113,9 @@ enum pch_platform_type { - 	PCH_TYPE_ULT	 = 5, - }; -  -+void pch_dmi_setup_physical_layer(void); -+void pch_dmi_tc_vc_mapping(u32 vc0, u32 vc1, u32 vcp, u32 vcm); -+ - void usb_ehci_sleep_prepare(pci_devfn_t dev, u8 slp_typ); - void usb_ehci_disable(pci_devfn_t dev); - void usb_xhci_sleep_prepare(pci_devfn_t dev, u8 slp_typ); -@@ -406,9 +409,10 @@ void mainboard_config_rcba(void); -  - /* Southbridge IO BARs */ -  -+#define PMBASE			0x40 - #define GPIOBASE		0x48 -  --#define PMBASE		0x40 -+#define CIR0050		0x0050	/* 32bit */ -  - #define RPC		0x0400	/* 32bit */ - #define RPFN		0x0404	/* 32bit */ -@@ -431,6 +435,20 @@ void mainboard_config_rcba(void); - #define IOTR2		0x1e90	/* 64bit */ - #define IOTR3		0x1e98	/* 64bit */ -  -+#define V0CTL		0x2014	/* 32bit */ -+#define V0STS		0x201a	/* 16bit */ -+ -+#define V1CTL		0x2020	/* 32bit */ -+#define V1STS		0x2026	/* 16bit */ -+ -+#define VPCTL		0x2030	/* 32bit */ -+#define VPSTS		0x2038	/* 16bit */ -+ -+#define VMCTL		0x2040	/* 32bit */ -+#define VMSTS		0x2048	/* 16bit */ -+ -+#define DLCTL2		0x21b0 -+ - #define TCTL		0x3000	/*  8bit */ -  - #define NOINT		0 ---  -2.39.2 - diff --git a/config/coreboot/haswell/patches/0014-haswell-NRI-Add-timings-refresh-programming.patch b/config/coreboot/haswell/patches/0004-haswell-NRI-Add-timings-refresh-programming.patch index 1b88f350..74c21227 100644 --- a/config/coreboot/haswell/patches/0014-haswell-NRI-Add-timings-refresh-programming.patch +++ b/config/coreboot/haswell/patches/0004-haswell-NRI-Add-timings-refresh-programming.patch @@ -1,7 +1,7 @@ -From b64d728bfe7c8ee44af252338257e95d87864659 Mon Sep 17 00:00:00 2001 +From d94843c7c0e25cb6da4040b845556034fdb0e2c3 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sat, 7 May 2022 20:59:58 +0200 -Subject: [PATCH 14/26] haswell NRI: Add timings/refresh programming +Subject: [PATCH 04/20] haswell NRI: Add timings/refresh programming  Program the registers with timing and refresh parameters. @@ -16,7 +16,7 @@ Signed-off-by: Angel Pons <th3fanbus@gmail.com>   5 files changed, 452 insertions(+), 2 deletions(-)  diff --git a/src/northbridge/intel/haswell/native_raminit/lookup_timings.c b/src/northbridge/intel/haswell/native_raminit/lookup_timings.c -index 038686c844..afe2c615d2 100644 +index 8b81c7c341..b8d6c1ef40 100644  --- a/src/northbridge/intel/haswell/native_raminit/lookup_timings.c  +++ b/src/northbridge/intel/haswell/native_raminit/lookup_timings.c  @@ -60,3 +60,105 @@ uint32_t get_tXP(const uint32_t mem_clock_mhz) @@ -262,14 +262,14 @@ index d11cda4b3d..70487e1640 100644   	struct __packed {   		uint32_t enable_cmd_limit :  1; // Bits  0:0  diff --git a/src/northbridge/intel/haswell/native_raminit/timings_refresh.c b/src/northbridge/intel/haswell/native_raminit/timings_refresh.c -index a9d960f31b..20a05b359b 100644 +index a9d960f31b..54fee0121d 100644  --- a/src/northbridge/intel/haswell/native_raminit/timings_refresh.c  +++ b/src/northbridge/intel/haswell/native_raminit/timings_refresh.c  @@ -1,13 +1,242 @@   /* SPDX-License-Identifier: GPL-2.0-or-later */  +#include <assert.h> -+#include <commonlib/clamp.h> ++#include <commonlib/bsd/clamp.h>  +#include <console/console.h>  +#include <delay.h>  +#include <device/pci_ops.h> @@ -458,7 +458,7 @@ index a9d960f31b..20a05b359b 100644   {  -	/** TODO: Stub **/  +	if (ctrl->lpddr) -+		die("%s: Missing support for LPDDR\n"); ++		die("%s: Missing support for LPDDR\n", __func__);  +  +	const uint8_t odt_stretch = get_odt_stretch(ctrl);  +	const union tc_bank_reg tc_bank = make_tc_bank(ctrl); diff --git a/config/coreboot/haswell/patches/0004-haswell-lynxpoint-Add-native-early-ME-init.patch b/config/coreboot/haswell/patches/0004-haswell-lynxpoint-Add-native-early-ME-init.patch deleted file mode 100644 index 28dbc02a..00000000 --- a/config/coreboot/haswell/patches/0004-haswell-lynxpoint-Add-native-early-ME-init.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 98142e01fc8ebb3b762974e9e4de75e7f5c073b4 Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Fri, 6 May 2022 22:18:21 +0200 -Subject: [PATCH 04/26] haswell/lynxpoint: Add native early ME init - -Implement native early ME init for Lynx Point. This is only needed when -MRC.bin is not used. - -Change-Id: If416e2078f139f26b4742c564b70e018725bf003 -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - .../haswell/native_raminit/raminit_native.c   | 17 ++++++++++- - src/southbridge/intel/lynxpoint/early_me.c    | 30 ++++++++++++++++++- - src/southbridge/intel/lynxpoint/me.h          |  7 +++-- - 3 files changed, 50 insertions(+), 4 deletions(-) - -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -index 0938e026e3..6a002548c1 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -@@ -1,18 +1,24 @@ - /* SPDX-License-Identifier: GPL-2.0-or-later */ -  - #include <console/console.h> -+#include <delay.h> - #include <northbridge/intel/haswell/haswell.h> - #include <northbridge/intel/haswell/raminit.h> -+#include <southbridge/intel/lynxpoint/me.h> - #include <types.h> -  - static bool early_init_native(int s3resume) - { - 	printk(BIOS_DEBUG, "Starting native platform initialisation\n"); -  -+	intel_early_me_init(); -+	/** TODO: CPU replacement check must be skipped in warm boots and S3 resumes **/ -+	const bool cpu_replaced = !s3resume && intel_early_me_cpu_replacement_check(); -+ - 	if (!CONFIG(INTEL_LYNXPOINT_LP)) - 		dmi_early_init(); -  --	return false; -+	return cpu_replaced; - } -  - void perform_raminit(const int s3resume) -@@ -25,6 +31,15 @@ void perform_raminit(const int s3resume) -  - 	(void)cpu_replaced; -  -+	/** 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; -+		intel_early_me_init_done(me_status); -+	} -+ -+	intel_early_me_status(); -+ - 	/** TODO: Implement the required magic **/ - 	die("NATIVE RAMINIT: More Magic (tm) required.\n"); - } -diff --git a/src/southbridge/intel/lynxpoint/early_me.c b/src/southbridge/intel/lynxpoint/early_me.c -index 947c570e16..07013c5539 100644 ---- a/src/southbridge/intel/lynxpoint/early_me.c -+++ b/src/southbridge/intel/lynxpoint/early_me.c -@@ -1,11 +1,12 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ -  - #include <arch/io.h> -+#include <cf9_reset.h> - #include <device/pci_ops.h> - #include <console/console.h> - #include <delay.h> - #include <halt.h> -- -+#include <timer.h> - #include "me.h" - #include "pch.h" -  -@@ -60,6 +61,33 @@ int intel_early_me_init(void) - 	return 0; - } -  -+bool intel_early_me_cpu_replacement_check(void) -+{ -+	printk(BIOS_DEBUG, "ME: Checking whether CPU was replaced... "); -+ -+	struct stopwatch timer; -+	stopwatch_init_msecs_expire(&timer, 50); -+ -+	union me_hfs2 hfs2; -+	do { -+		hfs2.raw = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS2); -+		if (stopwatch_expired(&timer)) { -+			/* Assume CPU was replaced just in case */ -+			printk(BIOS_DEBUG, "timed out, assuming CPU was replaced\n"); -+			return true; -+		} -+		udelay(ME_DELAY); -+	} while (!hfs2.cpu_replaced_valid); -+ -+	if (hfs2.warm_reset_request) { -+		printk(BIOS_DEBUG, "warm reset needed for dynamic fusing\n"); -+		system_reset(); -+	} -+ -+	printk(BIOS_DEBUG, "%sreplaced\n", hfs2.cpu_replaced_sts ? "" : "not "); -+	return hfs2.cpu_replaced_sts; -+} -+ - int intel_early_me_uma_size(void) - { - 	union me_uma uma = { .raw = pci_read_config32(PCH_ME_DEV, PCI_ME_UMA) }; -diff --git a/src/southbridge/intel/lynxpoint/me.h b/src/southbridge/intel/lynxpoint/me.h -index fe8b0260c4..6990322651 100644 ---- a/src/southbridge/intel/lynxpoint/me.h -+++ b/src/southbridge/intel/lynxpoint/me.h -@@ -177,14 +177,16 @@ union me_did { - union me_hfs2 { - 	struct __packed { - 		u32 bist_in_progress: 1; --		u32 reserved1: 2; -+		u32 icc_prog_sts: 2; - 		u32 invoke_mebx: 1; - 		u32 cpu_replaced_sts: 1; - 		u32 mbp_rdy: 1; - 		u32 mfs_failure: 1; - 		u32 warm_reset_request: 1; - 		u32 cpu_replaced_valid: 1; --		u32 reserved2: 4; -+		u32 reserved: 2; -+		u32 fw_upd_ipu: 1; -+		u32 reserved2: 1; - 		u32 mbp_cleared: 1; - 		u32 reserved3: 2; - 		u32 current_state: 8; -@@ -338,6 +340,7 @@ void intel_me_status(union me_hfs hfs, union me_hfs2 hfs2); -  - void intel_early_me_status(void); - int intel_early_me_init(void); -+bool intel_early_me_cpu_replacement_check(void); - int intel_early_me_uma_size(void); - int intel_early_me_init_done(u8 status); -  ---  -2.39.2 - diff --git a/config/coreboot/haswell/patches/0015-haswell-NRI-Program-memory-map.patch b/config/coreboot/haswell/patches/0005-haswell-NRI-Program-memory-map.patch index ad8527b2..e095417c 100644 --- a/config/coreboot/haswell/patches/0015-haswell-NRI-Program-memory-map.patch +++ b/config/coreboot/haswell/patches/0005-haswell-NRI-Program-memory-map.patch @@ -1,7 +1,7 @@ -From 89ff35083af68d1b24c1633886202ecc153af67d Mon Sep 17 00:00:00 2001 +From b872fb9fc10d1789989072b8533b797152e6cb54 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sat, 7 May 2022 21:24:50 +0200 -Subject: [PATCH 15/26] haswell NRI: Program memory map +Subject: [PATCH 05/20] haswell NRI: Program memory map  This is very similar to Sandy/Ivy Bridge, except that there's several  registers to program in GDXCBAR. One of these GDXCBAR registers has a @@ -12,7 +12,7 @@ bit was the only reason why native raminit did not work.  Change-Id: I3af73a018a7ba948701a542e661e7fefd57591fe  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   1 + + .../intel/haswell/native_raminit/Makefile.mk  |   1 +   .../intel/haswell/native_raminit/memory_map.c | 183 ++++++++++++++++++   .../haswell/native_raminit/raminit_main.c     |   1 +   .../haswell/native_raminit/raminit_native.h   |   1 + @@ -20,10 +20,10 @@ Signed-off-by: Angel Pons <th3fanbus@gmail.com>   5 files changed, 188 insertions(+)   create mode 100644 src/northbridge/intel/haswell/native_raminit/memory_map.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index fc55277a65..37d527e972 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -4,6 +4,7 @@ romstage-y += configure_mc.c   romstage-y += lookup_timings.c   romstage-y += init_mpll.c @@ -222,10 +222,10 @@ index 0000000000..e3aded2b37  +	return 0;  +}  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -index 3a773cfa19..136a8ba989 100644 +index fcc981ad04..559dfc3a4e 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -@@ -24,6 +24,7 @@ static const struct task_entry cold_boot[] = { +@@ -23,6 +23,7 @@ static const struct task_entry cold_boot[] = {   	{ initialise_mpll,                                        true, "INITMPLL",   },   	{ convert_timings,                                        true, "CONVTIM",    },   	{ configure_mc,                                           true, "CONFMC",     }, diff --git a/config/coreboot/haswell/patches/0005-sb-intel-lynxpoint-Add-native-USB-init.patch b/config/coreboot/haswell/patches/0005-sb-intel-lynxpoint-Add-native-USB-init.patch deleted file mode 100644 index d9c2570b..00000000 --- a/config/coreboot/haswell/patches/0005-sb-intel-lynxpoint-Add-native-USB-init.patch +++ /dev/null @@ -1,783 +0,0 @@ -From 9bfb8614dbf1d9800ef8251cb3d839bcdbe5577f Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Fri, 6 May 2022 23:17:39 +0200 -Subject: [PATCH 05/26] sb/intel/lynxpoint: Add native USB init - -Implement native USB initialisation for Lynx Point. This is only needed -when MRC.bin is not used. - -TO DO: Figure out how to deal with the FIXME's and TODO's lying around. - -Change-Id: Ie0fbeeca7b1ca1557173772d733fd2fa27703373 -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - .../haswell/native_raminit/raminit_native.c   |   3 + - src/southbridge/intel/lynxpoint/Makefile.inc  |   2 +- - src/southbridge/intel/lynxpoint/early_usb.c   |  11 - - .../intel/lynxpoint/early_usb_native.c        | 584 ++++++++++++++++++ - src/southbridge/intel/lynxpoint/pch.h         |  49 ++ - 5 files changed, 637 insertions(+), 12 deletions(-) - create mode 100644 src/southbridge/intel/lynxpoint/early_usb_native.c - -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -index 6a002548c1..ef61d4ee09 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -@@ -5,6 +5,7 @@ - #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> -  - static bool early_init_native(int s3resume) -@@ -15,6 +16,8 @@ static bool early_init_native(int s3resume) - 	/** TODO: CPU replacement check must be skipped in warm boots and S3 resumes **/ - 	const bool cpu_replaced = !s3resume && intel_early_me_cpu_replacement_check(); -  -+	early_usb_init(); -+ - 	if (!CONFIG(INTEL_LYNXPOINT_LP)) - 		dmi_early_init(); -  -diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc -index b8503ac8bc..0e1f2fe4eb 100644 ---- a/src/southbridge/intel/lynxpoint/Makefile.inc -+++ b/src/southbridge/intel/lynxpoint/Makefile.inc -@@ -37,7 +37,7 @@ bootblock-y += early_pch.c - romstage-y += early_usb.c early_me.c me_status.c early_pch.c - romstage-y += pmutil.c -  --romstage-$(CONFIG_USE_NATIVE_RAMINIT) += early_pch_native.c -+romstage-$(CONFIG_USE_NATIVE_RAMINIT) += early_pch_native.c early_usb_native.c iobp.c -  - ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y) - romstage-y += lp_gpio.c -diff --git a/src/southbridge/intel/lynxpoint/early_usb.c b/src/southbridge/intel/lynxpoint/early_usb.c -index a753681ce0..52e8ac17f8 100644 ---- a/src/southbridge/intel/lynxpoint/early_usb.c -+++ b/src/southbridge/intel/lynxpoint/early_usb.c -@@ -4,17 +4,6 @@ - #include <device/pci_def.h> - #include "pch.h" -  --/* HCD_INDEX == 2 selects 0:1a.0 (PCH_EHCI2), any other index -- * selects 0:1d.0 (PCH_EHCI1) for usbdebug use. -- */ --#if CONFIG_USBDEBUG_HCD_INDEX != 2 --#define PCH_EHCI1_TEMP_BAR0 CONFIG_EHCI_BAR --#define PCH_EHCI2_TEMP_BAR0 (PCH_EHCI1_TEMP_BAR0 + 0x400) --#else --#define PCH_EHCI2_TEMP_BAR0 CONFIG_EHCI_BAR --#define PCH_EHCI1_TEMP_BAR0 (PCH_EHCI2_TEMP_BAR0 + 0x400) --#endif -- - /* -  * Setup USB controller MMIO BAR to prevent the -  * reference code from resetting the controller. -diff --git a/src/southbridge/intel/lynxpoint/early_usb_native.c b/src/southbridge/intel/lynxpoint/early_usb_native.c -new file mode 100644 -index 0000000000..cb6f6ee8e6 ---- /dev/null -+++ b/src/southbridge/intel/lynxpoint/early_usb_native.c -@@ -0,0 +1,584 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <console/console.h> -+#include <delay.h> -+#include <device/mmio.h> -+#include <device/pci_def.h> -+#include <device/pci_ops.h> -+#include <northbridge/intel/haswell/haswell.h> -+#include <northbridge/intel/haswell/raminit.h> -+#include <southbridge/intel/lynxpoint/iobp.h> -+#include <southbridge/intel/lynxpoint/pch.h> -+#include <timer.h> -+#include <types.h> -+ -+static unsigned int is_usbr_enabled(void) -+{ -+	return !!(pci_read_config32(PCH_XHCI_DEV, XHCI_USB3FUS) & BIT(5)); -+} -+ -+static char *const xhci_bar = (char *)PCH_XHCI_TEMP_BAR0; -+ -+static void ehci_hcs_init(const pci_devfn_t dev, const uintptr_t ehci_bar) -+{ -+	pci_write_config32(dev, PCI_BASE_ADDRESS_0, ehci_bar); -+ -+	/** FIXME: Determine whether Bus Master is required (or clean it up afterwards) **/ -+	pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); -+ -+	char *const mem_bar = (char *)ehci_bar; -+ -+	/** -+	 * Shared EHCI/XHCI ports w/a. -+	 * This step is required when some of the ports are routed to EHCI -+	 * and other ports are routed XHCI at the same time. -+	 * -+	 * FIXME: Under which conditions should this be done? -+	 */ -+	pci_and_config16(dev, 0x78, ~0x03); -+ -+	/* Skip reset if usbdebug is enabled */ -+	if (!CONFIG(USBDEBUG_IN_PRE_RAM)) -+		setbits32(mem_bar + EHCI_USB_CMD, EHCI_USB_CMD_HCRESET); -+ -+	/* 2: Configure number of controllers and ports */ -+	pci_or_config16(dev, EHCI_ACCESS_CNTL, ACCESS_CNTL_ENABLE); -+	clrsetbits32(mem_bar + EHCI_HCS_PARAMS, 0xf << 12, 0); -+	clrsetbits32(mem_bar + EHCI_HCS_PARAMS, 0xf <<  0, 2 + is_usbr_enabled()); -+	pci_and_config16(dev, EHCI_ACCESS_CNTL, ~ACCESS_CNTL_ENABLE); -+ -+	pci_or_config16(dev, 0x78, BIT(2)); -+	pci_or_config16(dev, 0x7c, BIT(14) | BIT(7)); -+	pci_update_config32(dev, 0x8c, ~(0xf << 8), (4 << 8)); -+	pci_update_config32(dev, 0x8c, ~BIT(26), BIT(17)); -+} -+ -+static inline unsigned int physical_port_count(void) -+{ -+	return MAX_USB2_PORTS; -+} -+ -+static unsigned int hs_port_count(void) -+{ -+	/** TODO: Apparently, WPT-LP has 10 USB2 ports **/ -+	if (CONFIG(INTEL_LYNXPOINT_LP)) -+		return 8; -+ -+	switch ((pci_read_config32(PCH_XHCI_DEV, XHCI_USB3FUS) >> 1) & 3) { -+	case 3: -+		return 8; -+	case 2: -+		return 10; -+	case 1: -+		return 12; -+	case 0: -+	default: -+		return 14; -+	} -+} -+ -+static unsigned int ss_port_count(void) -+{ -+	if (CONFIG(INTEL_LYNXPOINT_LP)) -+		return 4; -+ -+	switch ((pci_read_config32(PCH_XHCI_DEV, XHCI_USB3FUS) >> 3) & 3) { -+	case 3: -+		return 0; -+	case 2: -+		return 2; -+	case 1: -+		return 4; -+	case 0: -+	default: -+		return 6; -+	} -+} -+ -+static void common_ehci_hcs_init(void) -+{ -+	const bool is_lp = CONFIG(INTEL_LYNXPOINT_LP); -+ -+	ehci_hcs_init(PCH_EHCI1_DEV, PCH_EHCI1_TEMP_BAR0); -+	if (!is_lp) -+		ehci_hcs_init(PCH_EHCI2_DEV, PCH_EHCI2_TEMP_BAR0); -+ -+	pch_iobp_update(0xe5007f04, 0, 0x00004481); -+ -+	for (unsigned int port = 0; port < physical_port_count(); port++) -+		pch_iobp_update(0xe500400f + port * 0x100, ~(1 << 0), 0 << 0); -+ -+	pch_iobp_update(0xe5007f14, ~(3 << 19), (3 << 19)); -+ -+	if (is_lp) -+		pch_iobp_update(0xe5007f02, ~(3 << 22), (0 << 22)); -+} -+ -+static void xhci_open_memory_space(void) -+{ -+	/** FIXME: Determine whether Bus Master is required (or clean it up afterwards) **/ -+	pci_write_config32(PCH_XHCI_DEV, PCI_BASE_ADDRESS_0, (uintptr_t)xhci_bar); -+	pci_or_config16(PCH_XHCI_DEV, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); -+} -+ -+static void xhci_close_memory_space(void) -+{ -+	pci_and_config16(PCH_XHCI_DEV, PCI_COMMAND, ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY)); -+	pci_write_config32(PCH_XHCI_DEV, PCI_BASE_ADDRESS_0, 0); -+} -+ -+static void common_xhci_hc_init(void) -+{ -+	const bool is_lp = CONFIG(INTEL_LYNXPOINT_LP); -+ -+	if (!is_lp) { -+		const unsigned int max_ports = 15 + ss_port_count(); -+		clrsetbits32(xhci_bar + XHCI_HCS_PARAMS_1, 0xf << 28, max_ports << 28); -+	} -+ -+	clrsetbits32(xhci_bar + XHCI_HCS_PARAMS_3, 0xffff << 16 | 0xff, 0x200 << 16 | 0x0a); -+	clrsetbits32(xhci_bar + XHCI_HCC_PARAMS, BIT(5), BIT(10) | BIT(9)); -+ -+	if (!is_lp) -+		clrsetbits32(xhci_bar + 0x8008, BIT(19), 0); -+ -+	if (is_lp) -+		clrsetbits32(xhci_bar + 0x8058, BIT(8), BIT(16)); -+	else -+		clrsetbits32(xhci_bar + 0x8058, BIT(8), BIT(16) | BIT(20)); -+ -+	clrsetbits32(xhci_bar + 0x8060, 0, BIT(25) | BIT(18)); -+	clrsetbits32(xhci_bar + 0x8090, 0, BIT(14) | BIT(8)); -+	clrsetbits32(xhci_bar + 0x8094, 0, BIT(23) | BIT(21) | BIT(14)); -+	clrsetbits32(xhci_bar + 0x80e0, BIT(16), BIT(6)); -+	clrsetbits32(xhci_bar + 0x80ec, (7 << 12) | (7 << 9), (0 << 12) | (6 << 9)); -+	clrsetbits32(xhci_bar + 0x80f0, BIT(20), 0); -+ -+	if (is_lp) -+		clrsetbits32(xhci_bar + 0x80fc, 0, BIT(25)); -+ -+	if (is_lp) -+		clrsetbits32(xhci_bar + 0x8110, BIT(8) | BIT(2), BIT(20) | BIT(11)); -+	else -+		clrsetbits32(xhci_bar + 0x8110, BIT(2), BIT(20) | BIT(11)); -+ -+	if (is_lp) -+		write32(xhci_bar + 0x8140, 0xff00f03c); -+	else -+		write32(xhci_bar + 0x8140, 0xff03c132); -+ -+	if (is_lp) -+		clrsetbits32(xhci_bar + 0x8154, BIT(21), BIT(13)); -+	else -+		clrsetbits32(xhci_bar + 0x8154, BIT(21) | BIT(13), 0); -+ -+	clrsetbits32(xhci_bar + 0x8154, BIT(3), 0); -+ -+	if (is_lp) { -+		clrsetbits32(xhci_bar + 0x8164, 0, BIT(1) | BIT(0)); -+		write32(xhci_bar + 0x8174, 0x01400c0a); -+		write32(xhci_bar + 0x817c, 0x033200a3); -+		write32(xhci_bar + 0x8180, 0x00cb0028); -+		write32(xhci_bar + 0x8184, 0x0064001e); -+	} -+ -+	/* -+	 * Note: Register at offset 0x44 is 32-bit, but bit 31 is write-once. -+	 * We use these weird partial accesses here to avoid locking bit 31. -+	 */ -+	pci_or_config16(PCH_XHCI_DEV, 0x44, BIT(15) | BIT(14) | BIT(10) | BIT(0)); -+	pci_or_config8(PCH_XHCI_DEV, 0x44 + 2, 0x0f); -+ -+	/* LPT-LP >= B0 */ -+	if (is_lp) -+		clrsetbits32(xhci_bar + 0x8188, 0, BIT(26) | BIT(24)); -+ -+	/* LPT-H >= C0 */ -+	if (!is_lp) -+		clrsetbits32(xhci_bar + 0x8188, 0, BIT(24)); -+} -+ -+static inline bool is_mem_sr(void) -+{ -+	return pci_read_config16(PCH_LPC_DEV, GEN_PMCON_2) & GEN_PMCON_2_MEM_SR; -+} -+ -+static bool should_restore_xhci_smart_auto(void) -+{ -+	if (!is_mem_sr()) -+		return false; -+ -+	return pci_read_config32(PCH_LPC_DEV, PMIR) & PMIR_XHCI_SMART_AUTO; -+} -+ -+enum usb_port_route { -+	ROUTE_TO_EHCI, -+	ROUTE_TO_XHCI, -+}; -+ -+/* Returns whether port reset was successful */ -+static bool reset_usb2_ports(const unsigned int ehci_ports) -+{ -+	for (unsigned int port = 0; port < ehci_ports; port++) { -+		/* Initiate port reset for all USB2 ports */ -+		clrsetbits32( -+			xhci_bar + XHCI_USB2_PORTSC(port), -+			XHCI_USB2_PORTSC_PED, -+			XHCI_USB2_PORTSC_PR); -+	} -+	/* Poll for port reset bit to be cleared or time out at 100ms */ -+	struct stopwatch timer; -+	stopwatch_init_msecs_expire(&timer, 100); -+	uint32_t reg32; -+	do { -+		reg32 = 0; -+		for (unsigned int port = 0; port < ehci_ports; port++) -+			reg32 |= read32(xhci_bar + XHCI_USB2_PORTSC(port)); -+ -+		reg32 &= XHCI_USB2_PORTSC_PR; -+		if (!reg32) { -+			const long elapsed_time = stopwatch_duration_usecs(&timer); -+			printk(BIOS_DEBUG, "%s: took %lu usecs\n", __func__, elapsed_time); -+			return true; -+		} -+		/* Reference code has a 10 ms delay here, but a smaller delay works too */ -+		udelay(100); -+	} while (!stopwatch_expired(&timer)); -+	printk(BIOS_ERR, "%s: timed out\n", __func__); -+	return !reg32; -+} -+ -+/* Returns whether warm reset was successful */ -+static bool warm_reset_usb3_ports(const unsigned int xhci_ports) -+{ -+	for (unsigned int port = 0; port < xhci_ports; port++) { -+		/* Initiate warm reset for all USB3 ports */ -+		clrsetbits32( -+			xhci_bar + XHCI_USB3_PORTSC(port), -+			XHCI_USB3_PORTSC_PED, -+			XHCI_USB3_PORTSC_WPR); -+	} -+	/* Poll for port reset bit to be cleared or time out at 100ms */ -+	struct stopwatch timer; -+	stopwatch_init_msecs_expire(&timer, 100); -+	uint32_t reg32; -+	do { -+		reg32 = 0; -+		for (unsigned int port = 0; port < xhci_ports; port++) -+			reg32 |= read32(xhci_bar + XHCI_USB3_PORTSC(port)); -+ -+		reg32 &= XHCI_USB3_PORTSC_PR; -+		if (!reg32) { -+			const long elapsed_time = stopwatch_duration_usecs(&timer); -+			printk(BIOS_DEBUG, "%s: took %lu usecs\n", __func__, elapsed_time); -+			return true; -+		} -+		/* Reference code has a 10 ms delay here, but a smaller delay works too */ -+		udelay(100); -+	} while (!stopwatch_expired(&timer)); -+	printk(BIOS_ERR, "%s: timed out\n", __func__); -+	return !reg32; -+} -+ -+static void perform_xhci_ehci_switching_flow(const enum usb_port_route usb_route) -+{ -+	const pci_devfn_t dev = PCH_XHCI_DEV; -+ -+	const unsigned int ehci_ports = hs_port_count() + is_usbr_enabled(); -+	const unsigned int xhci_ports = ss_port_count(); -+ -+	const uint32_t ehci_mask = BIT(ehci_ports) - 1; -+	const uint32_t xhci_mask = BIT(xhci_ports) - 1; -+ -+	/** TODO: Handle USBr port? How, though? **/ -+	pci_update_config32(dev, XHCI_USB2PRM, ~XHCI_USB2PR_HCSEL, ehci_mask); -+	pci_update_config32(dev, XHCI_USB3PRM, ~XHCI_USB3PR_SSEN,  xhci_mask); -+ -+	/* -+	 * Workaround for USB2PR / USB3PR value not surviving warm reset. -+	 * Restore USB Port Routing registers if OS HC Switch driver has been executed. -+	 */ -+	if (should_restore_xhci_smart_auto()) { -+		/** FIXME: Derive values from mainboard code instead? **/ -+		pci_update_config32(dev, XHCI_USB2PR, ~XHCI_USB2PR_HCSEL, ehci_mask); -+		pci_update_config32(dev, XHCI_USB3PR, ~XHCI_USB3PR_SSEN,  xhci_mask); -+	} -+ -+	/* Later stages shouldn't need the value of this bit */ -+	pci_and_config32(PCH_LPC_DEV, PMIR, ~PMIR_XHCI_SMART_AUTO); -+ -+	/** -+	 * FIXME: Things here depend on the chosen routing mode. -+	 *        For now, implement both functions. -+	 */ -+ -+	/* Route to EHCI if xHCI disabled or auto mode */ -+	if (usb_route == ROUTE_TO_EHCI) { -+		if (!reset_usb2_ports(ehci_ports)) -+			printk(BIOS_ERR, "USB2 port reset timed out\n"); -+ -+		pci_and_config32(dev, XHCI_USB2PR, ~XHCI_USB2PR_HCSEL); -+ -+		for (unsigned int port = 0; port < ehci_ports; port++) { -+			clrsetbits32( -+				xhci_bar + XHCI_USB2_PORTSC(port), -+				XHCI_USB2_PORTSC_PED, -+				XHCI_USB2_PORTSC_CHST); -+		} -+ -+		if (!warm_reset_usb3_ports(xhci_ports)) -+			printk(BIOS_ERR, "USB3 warm reset timed out\n"); -+ -+		/* FIXME: BWG says this should be inside the warm reset function */ -+		pci_and_config32(dev, XHCI_USB3PR, ~XHCI_USB3PR_SSEN); -+ -+		for (unsigned int port = 0; port < ehci_ports; port++) { -+			clrsetbits32( -+				xhci_bar + XHCI_USB3_PORTSC(port), -+				XHCI_USB3_PORTSC_PED, -+				XHCI_USB3_PORTSC_CHST); -+		} -+ -+		setbits32(xhci_bar + XHCI_USBCMD, BIT(0)); -+		clrbits32(xhci_bar + XHCI_USBCMD, BIT(0)); -+	} -+ -+	/* Route to xHCI if xHCI enabled */ -+	if (usb_route == ROUTE_TO_XHCI) { -+		if (is_mem_sr()) { -+			if (!warm_reset_usb3_ports(xhci_ports)) -+				printk(BIOS_ERR, "USB3 warm reset timed out\n"); -+		} -+ -+		const uint32_t xhci_port_mask = pci_read_config32(dev, XHCI_USB3PRM) & 0x3f; -+		pci_update_config32(dev, XHCI_USB3PR, ~XHCI_USB3PR_SSEN, xhci_port_mask); -+ -+		const uint32_t ehci_port_mask = pci_read_config32(dev, XHCI_USB2PRM) & 0x7fff; -+		pci_update_config32(dev, XHCI_USB2PR, ~XHCI_USB2PR_HCSEL, ehci_port_mask); -+	} -+} -+ -+/* Do not shift in this macro, as it can cause undefined behaviour for bad port/oc values */ -+#define PORT_TO_OC_SHIFT(port, oc)	((oc) * 8 + (port)) -+ -+/* Avoid shifting into undefined behaviour */ -+static inline bool shift_ok(const int shift) -+{ -+	return shift >= 0 && shift < 32; -+} -+ -+static void usb_overcurrent_mapping(void) -+{ -+	const bool is_lp = CONFIG(INTEL_LYNXPOINT_LP); -+ -+	uint32_t ehci_1_ocmap = 0; -+	uint32_t ehci_2_ocmap = 0; -+	uint32_t xhci_1_ocmap = 0; -+	uint32_t xhci_2_ocmap = 0; -+ -+	/* -+	 * EHCI -+	 */ -+	for (unsigned int idx = 0; idx < physical_port_count(); idx++) { -+		const struct usb2_port_config *const port = &mainboard_usb2_ports[idx]; -+		printk(BIOS_DEBUG, "USB2 port %u => ", idx); -+		if (!port->enable) { -+			printk(BIOS_DEBUG, "disabled\n"); -+			continue; -+		} -+		const unsigned short oc_pin = port->oc_pin; -+		if (oc_pin == USB_OC_PIN_SKIP) { -+			printk(BIOS_DEBUG, "not mapped to OC pin\n"); -+			continue; -+		} -+		/* Ports 0 .. 7 => OC 0 .. 3 */ -+		if (idx < 8 && oc_pin <= 3) { -+			const int shift = PORT_TO_OC_SHIFT(idx, oc_pin); -+			if (shift_ok(shift)) { -+				printk(BIOS_DEBUG, "mapped to OC pin %u\n", oc_pin); -+				ehci_1_ocmap |= 1 << shift; -+				continue; -+			} -+		} -+		/* Ports 8 .. 13 => OC 4 .. 7 (LPT-H only) */ -+		if (!is_lp && idx >= 8 && oc_pin >= 4) { -+			const int shift = PORT_TO_OC_SHIFT(idx, oc_pin - 4); -+			if (shift_ok(shift)) { -+				printk(BIOS_DEBUG, "mapped to OC pin %u\n", oc_pin); -+				ehci_2_ocmap |= 1 << shift; -+				continue; -+			} -+		} -+		printk(BIOS_ERR, "Invalid OC pin %u for USB2 port %u\n", oc_pin, idx); -+	} -+	printk(BIOS_DEBUG, "\n"); -+	pci_write_config32(PCH_EHCI1_DEV, EHCI_OCMAP, ehci_1_ocmap); -+	if (!is_lp) -+		pci_write_config32(PCH_EHCI2_DEV, EHCI_OCMAP, ehci_2_ocmap); -+ -+	/* -+	 * xHCI -+	 */ -+	for (unsigned int idx = 0; idx < ss_port_count(); idx++) { -+		const struct usb3_port_config *const port = &mainboard_usb3_ports[idx]; -+		printk(BIOS_DEBUG, "USB3 port %u => ", idx); -+		if (!port->enable) { -+			printk(BIOS_DEBUG, "disabled\n"); -+			continue; -+		} -+		const unsigned short oc_pin = port->oc_pin; -+		if (oc_pin == USB_OC_PIN_SKIP) { -+			printk(BIOS_DEBUG, "not mapped to OC pin\n"); -+			continue; -+		} -+		/* Ports 0 .. 5 => OC 0 .. 3 */ -+		if (oc_pin <= 3) { -+			const int shift = PORT_TO_OC_SHIFT(idx, oc_pin); -+			if (shift_ok(shift)) { -+				printk(BIOS_DEBUG, "mapped to OC pin %u\n", oc_pin); -+				xhci_1_ocmap |= 1 << shift; -+				continue; -+			} -+		} -+		/* Ports 0 .. 5 => OC 4 .. 7 (LPT-H only) */ -+		if (!is_lp && oc_pin >= 4) { -+			const int shift = PORT_TO_OC_SHIFT(idx, oc_pin - 4); -+			if (shift_ok(shift)) { -+				printk(BIOS_DEBUG, "mapped to OC pin %u\n", oc_pin); -+				xhci_2_ocmap |= 1 << shift; -+				continue; -+			} -+		} -+		printk(BIOS_ERR, "Invalid OC pin %u for USB3 port %u\n", oc_pin, idx); -+	} -+	printk(BIOS_DEBUG, "\n"); -+	pci_write_config32(PCH_XHCI_DEV, XHCI_U2OCM1, ehci_1_ocmap); -+	pci_write_config32(PCH_XHCI_DEV, XHCI_U3OCM1, xhci_1_ocmap); -+	if (!is_lp) { -+		pci_write_config32(PCH_XHCI_DEV, XHCI_U2OCM2, ehci_2_ocmap); -+		pci_write_config32(PCH_XHCI_DEV, XHCI_U3OCM2, xhci_2_ocmap); -+	} -+} -+ -+static uint8_t get_ehci_tune_param_1(const struct usb2_port_config *const port) -+{ -+	const bool is_lp = CONFIG(INTEL_LYNXPOINT_LP); -+ -+	const enum pch_platform_type plat_type = get_pch_platform_type(); -+	const enum usb2_port_location location = port->location; -+	const uint16_t length = port->length; -+	if (!is_lp) { -+		if (plat_type == PCH_TYPE_DESKTOP) { -+			if (location == USB_PORT_BACK_PANEL) -+				return 4; /* Back Panel */ -+			else -+				return 3; /* Front Panel */ -+ -+		} else if (plat_type == PCH_TYPE_MOBILE) { -+			if (location == USB_PORT_INTERNAL) -+				return 5; /* Internal Topology */ -+			else if (location == USB_PORT_DOCK) -+				return 4; /* Dock */ -+			else if (length < 0x70) -+				return 5; /* Back Panel, less than 7" */ -+			else -+				return 6; /* Back Panel, 7" or more */ -+		} -+	} else { -+		if (location == USB_PORT_BACK_PANEL || location == USB_PORT_MINI_PCIE) { -+			if (length < 0x70) -+				return 5; /* Back Panel, less than 7" */ -+			else -+				return 6; /* Back Panel, 7" or more */ -+		} else if (location == USB_PORT_DOCK) { -+			return 4; /* Dock */ -+		} else { -+			return 5; /* Internal Topology */ -+		} -+	} -+	printk(BIOS_ERR, "%s: Unhandled case\n", __func__); -+	return 0; -+} -+ -+static uint8_t get_ehci_tune_param_2(const struct usb2_port_config *const port) -+{ -+	const bool is_lp = CONFIG(INTEL_LYNXPOINT_LP); -+ -+	const enum pch_platform_type plat_type = get_pch_platform_type(); -+	const enum usb2_port_location location = port->location; -+	const uint16_t length = port->length; -+	if (!is_lp) { -+		if (plat_type == PCH_TYPE_DESKTOP) { -+			if (location == USB_PORT_BACK_PANEL) { -+				if (length < 0x80) -+					return 2; /* Back Panel, less than 8" */ -+				else if (length < 0x130) -+					return 3; /* Back Panel, 8"-13" */ -+				else -+					return 4; /* Back Panel, 13" or more */ -+			} else { -+				return 2; /* Front Panel */ -+			} -+ -+		} else if (plat_type == PCH_TYPE_MOBILE) { -+			if (location == USB_PORT_INTERNAL) { -+				return 2; /* Internal Topology */ -+			} else if (location == USB_PORT_DOCK) { -+				if (length < 0x50) -+					return 1; /* Dock, less than 5" */ -+				else -+					return 2; /* Dock, 5" or more */ -+			} else { -+				if (length < 0x100) -+					return 2; /* Back Panel, less than 10" */ -+				else -+					return 3; /* Back Panel, 10" or more */ -+			} -+		} -+	} else { -+		if (location == USB_PORT_BACK_PANEL || location == USB_PORT_MINI_PCIE) { -+			if (length < 0x100) -+				return 2; /* Back Panel, less than 10" */ -+			else -+				return 3; /* Back Panel, 10" or more */ -+		} else if (location == USB_PORT_DOCK) { -+			if (length < 0x50) -+				return 1; /* Dock, less than 5" */ -+			else -+				return 2; /* Dock, 5" or more */ -+		} else { -+			return 2; /* Internal Topology */ -+		} -+	} -+	printk(BIOS_ERR, "%s: Unhandled case\n", __func__); -+	return 0; -+} -+ -+static void program_ehci_port_length(void) -+{ -+	for (unsigned int port = 0; port < physical_port_count(); port++) { -+		if (!mainboard_usb2_ports[port].enable) -+			continue; -+		const uint32_t addr = 0xe5004000 + (port + 1) * 0x100; -+		const uint8_t param_1 = get_ehci_tune_param_1(&mainboard_usb2_ports[port]); -+		const uint8_t param_2 = get_ehci_tune_param_2(&mainboard_usb2_ports[port]); -+		pch_iobp_update(addr, ~0x7f00, param_2 << 11 | param_1 << 8); -+	} -+} -+ -+void early_usb_init(void) -+{ -+	/** TODO: Make this configurable? How do the modes affect usbdebug? **/ -+	const enum usb_port_route usb_route = ROUTE_TO_XHCI; -+	///(pd->boot_mode == 2 && pd->usb_xhci_on_resume) ? ROUTE_TO_XHCI : ROUTE_TO_EHCI; -+ -+	common_ehci_hcs_init(); -+	xhci_open_memory_space(); -+	common_xhci_hc_init(); -+	perform_xhci_ehci_switching_flow(usb_route); -+	usb_overcurrent_mapping(); -+	program_ehci_port_length(); -+	/** FIXME: USB per port control is missing, is it needed? **/ -+	xhci_close_memory_space(); -+	/** TODO: Close EHCI memory space? **/ -+} -diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h -index b5e0c2a830..ad983d86cf 100644 ---- a/src/southbridge/intel/lynxpoint/pch.h -+++ b/src/southbridge/intel/lynxpoint/pch.h -@@ -115,6 +115,7 @@ enum pch_platform_type { -  - void pch_dmi_setup_physical_layer(void); - void pch_dmi_tc_vc_mapping(u32 vc0, u32 vc1, u32 vcp, u32 vcm); -+void early_usb_init(void); -  - void usb_ehci_sleep_prepare(pci_devfn_t dev, u8 slp_typ); - void usb_ehci_disable(pci_devfn_t dev); -@@ -202,6 +203,8 @@ void mainboard_config_rcba(void); - #define GEN_PMCON_1		0xa0 - #define  SMI_LOCK		(1 << 4) - #define GEN_PMCON_2		0xa2 -+#define  GEN_PMCON_2_DISB	(1 << 7) -+#define  GEN_PMCON_2_MEM_SR	(1 << 5) - #define  SYSTEM_RESET_STS	(1 << 4) - #define  THERMTRIP_STS		(1 << 3) - #define  SYSPWR_FLR		(1 << 1) -@@ -215,6 +218,7 @@ void mainboard_config_rcba(void); - #define PMIR			0xac - #define  PMIR_CF9LOCK		(1 << 31) - #define  PMIR_CF9GR		(1 << 20) -+#define  PMIR_XHCI_SMART_AUTO	(1 << 16) /* c.f. LPT BWG or WPT-LP BIOS spec */ -  - /* GEN_PMCON_3 bits */ - #define RTC_BATTERY_DEAD	(1 << 2) -@@ -282,6 +286,20 @@ void mainboard_config_rcba(void); - #define SATA_DTLE_DATA_SHIFT	24 - #define SATA_DTLE_EDGE_SHIFT	16 -  -+/* -+ * HCD_INDEX == 2 selects 0:1a.0 (PCH_EHCI2), any other index -+ * selects 0:1d.0 (PCH_EHCI1) for usbdebug use. -+ */ -+#if CONFIG_USBDEBUG_HCD_INDEX != 2 -+#define PCH_EHCI1_TEMP_BAR0 CONFIG_EHCI_BAR -+#define PCH_EHCI2_TEMP_BAR0 (PCH_EHCI1_TEMP_BAR0 + 0x400) -+#else -+#define PCH_EHCI2_TEMP_BAR0 CONFIG_EHCI_BAR -+#define PCH_EHCI1_TEMP_BAR0 (PCH_EHCI2_TEMP_BAR0 + 0x400) -+#endif -+ -+#define PCH_XHCI_TEMP_BAR0	0xe8100000 -+ - /* EHCI PCI Registers */ - #define EHCI_PWR_CTL_STS	0x54 - #define  PWR_CTL_SET_MASK	0x3 -@@ -289,10 +307,15 @@ void mainboard_config_rcba(void); - #define  PWR_CTL_SET_D3		0x3 - #define  PWR_CTL_ENABLE_PME	(1 << 8) - #define  PWR_CTL_STATUS_PME	(1 << 15) -+#define EHCI_OCMAP		0x74 -+#define EHCI_ACCESS_CNTL	0x80 -+#define  ACCESS_CNTL_ENABLE	(1 << 0) -  - /* EHCI Memory Registers */ -+#define EHCI_HCS_PARAMS		0x04 - #define EHCI_USB_CMD		0x20 - #define  EHCI_USB_CMD_RUN	(1 << 0) -+#define  EHCI_USB_CMD_HCRESET	(1 << 1) - #define  EHCI_USB_CMD_PSE	(1 << 4) - #define  EHCI_USB_CMD_ASE	(1 << 5) - #define EHCI_PORTSC(port)	(0x64 + (port) * 4) -@@ -301,6 +324,10 @@ void mainboard_config_rcba(void); -  - /* XHCI PCI Registers */ - #define XHCI_PWR_CTL_STS	0x74 -+#define XHCI_U2OCM1		0xc0 -+#define XHCI_U2OCM2		0xc4 -+#define XHCI_U3OCM1		0xc8 -+#define XHCI_U3OCM2		0xcc - #define XHCI_USB2PR		0xd0 - #define XHCI_USB2PRM		0xd4 - #define  XHCI_USB2PR_HCSEL	0x7fff -@@ -313,6 +340,27 @@ void mainboard_config_rcba(void); - #define XHCI_USB3PDO		0xe8 -  - /* XHCI Memory Registers */ -+#define XHCI_HCS_PARAMS_1	0x04 -+#define XHCI_HCS_PARAMS_2	0x08 -+#define XHCI_HCS_PARAMS_3	0x0c -+#define XHCI_HCC_PARAMS		0x10 -+#define XHCI_USBCMD		0x80 -+#define XHCI_USB2_PORTSC(port)	(0x480 + ((port) * 0x10)) -+#define  XHCI_USB2_PORTSC_WPR	(1 << 31)	/* Warm Port Reset */ -+#define  XHCI_USB2_PORTSC_CEC	(1 << 23)	/* Port Config Error Change */ -+#define  XHCI_USB2_PORTSC_PLC	(1 << 22)	/* Port Link State Change */ -+#define  XHCI_USB2_PORTSC_PRC	(1 << 21)	/* Port Reset Change */ -+#define  XHCI_USB2_PORTSC_OCC	(1 << 20)	/* Over-current Change */ -+#define  XHCI_USB2_PORTSC_WRC	(1 << 19)	/* Warm Port Reset Change */ -+#define  XHCI_USB2_PORTSC_PEC	(1 << 18)	/* Port Enabled Disabled Change */ -+#define  XHCI_USB2_PORTSC_CSC	(1 << 17)	/* Connect Status Change */ -+#define  XHCI_USB2_PORTSC_CHST	(0x7f << 17) -+#define  XHCI_USB2_PORTSC_LWS	(1 << 16)	/* Port Link State Write Strobe */ -+#define  XHCI_USB2_PORTSC_PP	(1 <<  9) -+#define  XHCI_USB2_PORTSC_PR	(1 <<  4)	/* Port Reset */ -+#define  XHCI_USB2_PORTSC_PED	(1 <<  1)	/* Port Enable/Disabled */ -+#define  XHCI_USB2_PORTSC_CCS	(1 <<  0)	/* Current Connect Status */ -+ - #define XHCI_USB3_PORTSC(port)	((pch_is_lp() ? 0x510 : 0x570) + ((port) * 0x10)) - #define  XHCI_USB3_PORTSC_CHST	(0x7f << 17) - #define  XHCI_USB3_PORTSC_WCE	(1 << 25)	/* Wake on Connect */ -@@ -320,6 +368,7 @@ void mainboard_config_rcba(void); - #define  XHCI_USB3_PORTSC_WOE	(1 << 27)	/* Wake on Overcurrent */ - #define  XHCI_USB3_PORTSC_WRC	(1 << 19)	/* Warm Reset Complete */ - #define  XHCI_USB3_PORTSC_LWS	(1 << 16)	/* Link Write Strobe */ -+#define  XHCI_USB3_PORTSC_PR	(1 << 4)	/* Port Reset */ - #define  XHCI_USB3_PORTSC_PED	(1 << 1)	/* Port Enabled/Disabled */ - #define  XHCI_USB3_PORTSC_WPR	(1 << 31)	/* Warm Port Reset */ - #define  XHCI_USB3_PORTSC_PLS	(0xf << 5)	/* Port Link State */ ---  -2.39.2 - diff --git a/config/coreboot/haswell/patches/0016-haswell-NRI-Add-DDR3-JEDEC-reset-and-init.patch b/config/coreboot/haswell/patches/0006-haswell-NRI-Add-DDR3-JEDEC-reset-and-init.patch index c321d239..ea46364f 100644 --- a/config/coreboot/haswell/patches/0016-haswell-NRI-Add-DDR3-JEDEC-reset-and-init.patch +++ b/config/coreboot/haswell/patches/0006-haswell-NRI-Add-DDR3-JEDEC-reset-and-init.patch @@ -1,7 +1,7 @@ -From d24def01ec15f41a48331ef1e236270b2df90b84 Mon Sep 17 00:00:00 2001 +From 1ea9b05694da7ee61d49d9cd2b7e533a98e42321 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sat, 7 May 2022 21:49:40 +0200 -Subject: [PATCH 16/26] haswell NRI: Add DDR3 JEDEC reset and init +Subject: [PATCH 06/20] haswell NRI: Add DDR3 JEDEC reset and init  Implement JEDEC reset and init sequence for DDR3. The MRS commands are  issued through the REUT (Robust Electrical Unified Testing) hardware. @@ -9,25 +9,25 @@ issued through the REUT (Robust Electrical Unified Testing) hardware.  Change-Id: I2a0c066537021b587599228086727cb1e041bff5  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   3 + + .../intel/haswell/native_raminit/Makefile.mk  |   3 +   .../intel/haswell/native_raminit/ddr3.c       | 217 ++++++++++++++++++   .../haswell/native_raminit/io_comp_control.c  |  19 ++   .../haswell/native_raminit/jedec_reset.c      | 120 ++++++++++   .../haswell/native_raminit/raminit_main.c     |   2 + - .../haswell/native_raminit/raminit_native.h   | 101 ++++++++ + .../haswell/native_raminit/raminit_native.h   |  99 ++++++++   .../haswell/native_raminit/reg_structs.h      | 154 +++++++++++++   .../intel/haswell/native_raminit/reut.c       | 196 ++++++++++++++++   .../intel/haswell/registers/mchbar.h          |  21 ++   src/southbridge/intel/lynxpoint/pch.h         |   2 + - 10 files changed, 835 insertions(+) + 10 files changed, 833 insertions(+)   create mode 100644 src/northbridge/intel/haswell/native_raminit/ddr3.c   create mode 100644 src/northbridge/intel/haswell/native_raminit/jedec_reset.c   create mode 100644 src/northbridge/intel/haswell/native_raminit/reut.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index 37d527e972..e9212df9e6 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -1,11 +1,14 @@   ## SPDX-License-Identifier: GPL-2.0-or-later @@ -267,7 +267,7 @@ index 0000000000..6ddb11488b  +	return reut_issue_zq(ctrl, ctrl->chanmap, ZQ_INIT);  +}  diff --git a/src/northbridge/intel/haswell/native_raminit/io_comp_control.c b/src/northbridge/intel/haswell/native_raminit/io_comp_control.c -index 7e96c08938..ad8c848e57 100644 +index d45b608dd3..8a55fd81b2 100644  --- a/src/northbridge/intel/haswell/native_raminit/io_comp_control.c  +++ b/src/northbridge/intel/haswell/native_raminit/io_comp_control.c  @@ -8,6 +8,25 @@ @@ -423,10 +423,10 @@ index 0000000000..de0f676758  +	return status;  +}  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -index 136a8ba989..73ff180b8c 100644 +index 559dfc3a4e..94b268468c 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -@@ -25,6 +25,7 @@ static const struct task_entry cold_boot[] = { +@@ -24,6 +24,7 @@ static const struct task_entry cold_boot[] = {   	{ convert_timings,                                        true, "CONVTIM",    },   	{ configure_mc,                                           true, "CONFMC",     },   	{ configure_memory_map,                                   true, "MEMMAP",     }, @@ -434,7 +434,7 @@ index 136a8ba989..73ff180b8c 100644   };   /* Return a generic stepping value to make stepping checks simpler */ -@@ -58,6 +59,7 @@ static void initialize_ctrl(struct sysinfo *ctrl) +@@ -57,6 +58,7 @@ static void initialize_ctrl(struct sysinfo *ctrl)   	ctrl->stepping = get_stepping(ctrl->cpu);   	ctrl->vdd_mv = is_hsw_ult() ? 1350 : 1500; /** FIXME: Hardcoded, does it matter? **/   	ctrl->dq_pins_interleaved = cfg->dq_pins_interleaved; @@ -443,7 +443,7 @@ index 136a8ba989..73ff180b8c 100644   }  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index 4763b25e8d..e3cf4254a0 100644 +index 4763b25e8d..4bc2a4955f 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h  @@ -27,6 +27,30 @@ @@ -498,25 +498,23 @@ index 4763b25e8d..e3cf4254a0 100644   	union tc_bank_rank_c_reg tc_bankrank_c[NUM_CHANNELS];   	union tc_bank_rank_d_reg tc_bankrank_d[NUM_CHANNELS];  + -+	uint16_t mr0[NUM_CHANNELS][NUM_SLOTRANKS]; -+	uint16_t mr1[NUM_CHANNELS][NUM_SLOTRANKS]; -+	uint16_t mr2[NUM_CHANNELS][NUM_SLOTRANKS]; -+	uint16_t mr3[NUM_CHANNELS][NUM_SLOTRANKS]; ++	uint16_t mr0[NUM_CHANNELS][NUM_SLOTS]; ++	uint16_t mr1[NUM_CHANNELS][NUM_SLOTS]; ++	uint16_t mr2[NUM_CHANNELS][NUM_SLOTS]; ++	uint16_t mr3[NUM_CHANNELS][NUM_SLOTS];   };   static inline bool is_hsw_ult(void) -@@ -196,6 +227,55 @@ static inline void clear_data_offset_train_all(struct sysinfo *ctrl) +@@ -196,6 +227,53 @@ static inline void clear_data_offset_train_all(struct sysinfo *ctrl)   	memset(ctrl->data_offset_train, 0, sizeof(ctrl->data_offset_train));   }  +/* Number of ticks to wait in units of 69.841279 ns (citation needed) */  +static inline void tick_delay(const uint32_t delay)  +{ -+	volatile uint32_t junk; -+  +	/* Just perform reads to a random register */  +	for (uint32_t start = 0; start <= delay; start++) -+		junk = mchbar_read32(REUT_ERR_DATA_STATUS); ++		mchbar_read32(REUT_ERR_DATA_STATUS);  +}  +  +/* @@ -561,7 +559,7 @@ index 4763b25e8d..e3cf4254a0 100644   void raminit_main(enum raminit_boot_mode bootmode);   enum raminit_status collect_spd_info(struct sysinfo *ctrl); -@@ -203,6 +283,7 @@ enum raminit_status initialise_mpll(struct sysinfo *ctrl); +@@ -203,6 +281,7 @@ enum raminit_status initialise_mpll(struct sysinfo *ctrl);   enum raminit_status convert_timings(struct sysinfo *ctrl);   enum raminit_status configure_mc(struct sysinfo *ctrl);   enum raminit_status configure_memory_map(struct sysinfo *ctrl); @@ -569,7 +567,7 @@ index 4763b25e8d..e3cf4254a0 100644   void configure_timings(struct sysinfo *ctrl);   void configure_refresh(struct sysinfo *ctrl); -@@ -215,8 +296,28 @@ uint32_t get_tXS_offset(uint32_t mem_clock_mhz); +@@ -215,8 +294,28 @@ uint32_t get_tXS_offset(uint32_t mem_clock_mhz);   uint32_t get_tZQOPER(uint32_t mem_clock_mhz, bool lpddr);   uint32_t get_tZQCS(uint32_t mem_clock_mhz, bool lpddr); @@ -779,7 +777,7 @@ index 70487e1640..9929f617fe 100644   	struct __packed {  diff --git a/src/northbridge/intel/haswell/native_raminit/reut.c b/src/northbridge/intel/haswell/native_raminit/reut.c  new file mode 100644 -index 0000000000..c55cdd9c7e +index 0000000000..31019f74a1  --- /dev/null  +++ b/src/northbridge/intel/haswell/native_raminit/reut.c  @@ -0,0 +1,196 @@ @@ -938,9 +936,9 @@ index 0000000000..c55cdd9c7e  +{  +	/** TODO: Issuing ZQ commands differs for LPDDR **/  +	if (ctrl->lpddr) -+		die("%s: LPDDR not yet supported in ZQ calibration\n"); ++		die("%s: LPDDR not yet supported in ZQ calibration\n", __func__);  + -+	uint8_t opcode; /* NOTE: Only used for LPDDR */ ++	__maybe_unused uint8_t opcode; /* NOTE: Only used for LPDDR */  +	uint16_t zq = 0;  +	switch (zq_type) {  +	case ZQ_INIT: @@ -958,7 +956,7 @@ index 0000000000..c55cdd9c7e  +		opcode = 0xc3;  +		break;  +	default: -+		die("%s: ZQ type %u is invalid\n", zq_type); ++		die("%s: ZQ type %u is invalid\n", __func__, zq_type);  +	}  +  +	/* ZQCS on single-channel needs a longer delay */ @@ -1021,7 +1019,7 @@ index 2acc5cbbc8..4fc78a7f43 100644   /* MCDECS */  diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h -index 74b4d50017..16bef5032a 100644 +index 07f4b9dc16..5b3696347c 100644  --- a/src/southbridge/intel/lynxpoint/pch.h  +++ b/src/southbridge/intel/lynxpoint/pch.h  @@ -586,6 +586,8 @@ void mainboard_config_rcba(void); diff --git a/config/coreboot/haswell/patches/0006-sb-intel-lynxpoint-Add-native-thermal-init.patch b/config/coreboot/haswell/patches/0006-sb-intel-lynxpoint-Add-native-thermal-init.patch deleted file mode 100644 index 157d2999..00000000 --- a/config/coreboot/haswell/patches/0006-sb-intel-lynxpoint-Add-native-thermal-init.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 92be49d8422b4bc1c89bb49535f4dc6a01d47295 Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Fri, 6 May 2022 23:22:11 +0200 -Subject: [PATCH 06/26] sb/intel/lynxpoint: Add native thermal init - -Implement native thermal initialisation for Lynx Point. This is only -needed when MRC.bin is not used. - -Change-Id: I4a67a3092d0c2e56bfdacb513a899ef838193cbd -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - .../haswell/native_raminit/raminit_native.c   |  1 + - src/southbridge/intel/lynxpoint/Makefile.inc  |  2 +- - src/southbridge/intel/lynxpoint/pch.h         |  1 + - src/southbridge/intel/lynxpoint/thermal.c     | 64 +++++++++++++++++++ - 4 files changed, 67 insertions(+), 1 deletion(-) - create mode 100644 src/southbridge/intel/lynxpoint/thermal.c - -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -index ef61d4ee09..dd1f1ec14e 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -@@ -16,6 +16,7 @@ static bool early_init_native(int s3resume) - 	/** TODO: CPU replacement check must be skipped in warm boots and S3 resumes **/ - 	const bool cpu_replaced = !s3resume && intel_early_me_cpu_replacement_check(); -  -+	early_thermal_init(); - 	early_usb_init(); -  - 	if (!CONFIG(INTEL_LYNXPOINT_LP)) -diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc -index 0e1f2fe4eb..a9a9b153d6 100644 ---- a/src/southbridge/intel/lynxpoint/Makefile.inc -+++ b/src/southbridge/intel/lynxpoint/Makefile.inc -@@ -37,7 +37,7 @@ bootblock-y += early_pch.c - romstage-y += early_usb.c early_me.c me_status.c early_pch.c - romstage-y += pmutil.c -  --romstage-$(CONFIG_USE_NATIVE_RAMINIT) += early_pch_native.c early_usb_native.c iobp.c -+romstage-$(CONFIG_USE_NATIVE_RAMINIT) += early_pch_native.c early_usb_native.c iobp.c thermal.c -  - ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y) - romstage-y += lp_gpio.c -diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h -index ad983d86cf..38a9349220 100644 ---- a/src/southbridge/intel/lynxpoint/pch.h -+++ b/src/southbridge/intel/lynxpoint/pch.h -@@ -116,6 +116,7 @@ enum pch_platform_type { - void pch_dmi_setup_physical_layer(void); - void pch_dmi_tc_vc_mapping(u32 vc0, u32 vc1, u32 vcp, u32 vcm); - void early_usb_init(void); -+void early_thermal_init(void); -  - void usb_ehci_sleep_prepare(pci_devfn_t dev, u8 slp_typ); - void usb_ehci_disable(pci_devfn_t dev); -diff --git a/src/southbridge/intel/lynxpoint/thermal.c b/src/southbridge/intel/lynxpoint/thermal.c -new file mode 100644 -index 0000000000..e71969ea0c ---- /dev/null -+++ b/src/southbridge/intel/lynxpoint/thermal.c -@@ -0,0 +1,64 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <device/mmio.h> -+#include <device/pci_ops.h> -+#include <southbridge/intel/lynxpoint/pch.h> -+#include <types.h> -+ -+#define TBARB_TEMP 0x40000000 -+ -+#define THERMAL_DEV PCI_DEV(0, 0x1f, 6) -+ -+/* Early thermal init, it may need to be done prior to giving ME its memory */ -+void early_thermal_init(void) -+{ -+	/* Program address for temporary BAR */ -+	pci_write_config32(THERMAL_DEV, 0x40, TBARB_TEMP); -+	pci_write_config32(THERMAL_DEV, 0x44, 0); -+ -+	/* Activate temporary BAR */ -+	pci_or_config32(THERMAL_DEV, 0x40, 1); -+ -+	/* -+	 * BWG section 17.3.1 says: -+	 * -+	 * ### Initializing Lynx Point Thermal Sensors ### -+	 * -+	 * The System BIOS must perform the following steps to initialize the Lynx -+	 * Point thermal subsystem device, D31:F6. The System BIOS is required to -+	 * repeat this process on a resume from Sx. BIOS may enable any or all of -+	 * the registers below based on OEM's platform configuration. Intel does -+	 * not recommend a value on some of the registers, since each platform has -+	 * different temperature trip points and one may enable a trip to cause an -+	 * SMI while another platform would cause an interrupt instead. -+	 * -+	 * The recommended flow for enabling thermal sensor is by setting up various -+	 * temperature trip points first, followed by enabling the desired trip -+	 * alert method and then enable the actual sensors from TSEL registers. -+	 * If this flow is not followed, software will need to take special care -+	 * to handle false events during setting up those registers. -+	 */ -+ -+	/* Step 1: Program CTT */ -+	write16p(TBARB_TEMP + 0x10, 0x0154); -+ -+	/* Step 2: Clear trip status from TSS and TAS */ -+	write8p(TBARB_TEMP + 0x06, 0xff); -+	write8p(TBARB_TEMP + 0x80, 0xff); -+ -+	/* Step 3: Program TSGPEN and TSPIEN to zero */ -+	write8p(TBARB_TEMP + 0x84, 0x00); -+	write8p(TBARB_TEMP + 0x82, 0x00); -+ -+	/* -+	 * Step 4: If thermal reporting to an EC over SMBus is supported, -+	 *         then write 0x01 to TSREL, else leave at default. -+	 */ -+	write8p(TBARB_TEMP + 0x0a, 0x01); -+ -+	/* Disable temporary BAR */ -+	pci_and_config32(THERMAL_DEV, 0x40, ~1); -+ -+	/* Clear temporary BAR address */ -+	pci_write_config32(THERMAL_DEV, 0x40, 0); -+} ---  -2.39.2 - diff --git a/config/coreboot/haswell/patches/0017-haswell-NRI-Add-pre-training-steps.patch b/config/coreboot/haswell/patches/0007-haswell-NRI-Add-pre-training-steps.patch index e4cea123..8b73df88 100644 --- a/config/coreboot/haswell/patches/0017-haswell-NRI-Add-pre-training-steps.patch +++ b/config/coreboot/haswell/patches/0007-haswell-NRI-Add-pre-training-steps.patch @@ -1,7 +1,7 @@ -From 42e43eb210bbb172af8e5ad064326c4570be8654 Mon Sep 17 00:00:00 2001 +From 936d432822fcd9aa2f018444cdc89e48e6d257d5 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sat, 7 May 2022 23:12:18 +0200 -Subject: [PATCH 17/26] haswell NRI: Add pre-training steps +Subject: [PATCH 07/20] haswell NRI: Add pre-training steps  Implement pre-training steps, which consist of enabling ECC I/O and  filling the WDB (Write Data Buffer, stores test patterns) through a @@ -10,19 +10,19 @@ magic LDAT port.  Change-Id: Ie2e09e3b218c4569ed8de5c5e1b05d491032e0f1  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   1 + - .../haswell/native_raminit/raminit_main.c     |  34 ++++ + .../intel/haswell/native_raminit/Makefile.mk  |   1 + + .../haswell/native_raminit/raminit_main.c     |  35 ++++   .../haswell/native_raminit/raminit_native.h   |  24 +++   .../haswell/native_raminit/reg_structs.h      |  45 +++++   .../intel/haswell/native_raminit/setup_wdb.c  | 159 ++++++++++++++++++   .../intel/haswell/registers/mchbar.h          |   9 + - 6 files changed, 272 insertions(+) + 6 files changed, 273 insertions(+)   create mode 100644 src/northbridge/intel/haswell/native_raminit/setup_wdb.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index e9212df9e6..8d7d4e4db0 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -10,5 +10,6 @@ romstage-y += memory_map.c   romstage-y += raminit_main.c   romstage-y += raminit_native.c @@ -31,10 +31,18 @@ index e9212df9e6..8d7d4e4db0 100644   romstage-y += spd_bitmunching.c   romstage-y += timings_refresh.c  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -index 73ff180b8c..5e4674957d 100644 +index 94b268468c..5e4674957d 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -@@ -13,6 +13,39 @@ +@@ -3,6 +3,7 @@ + #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> +@@ -12,6 +13,39 @@   #include "raminit_native.h" @@ -74,7 +82,7 @@ index 73ff180b8c..5e4674957d 100644   struct task_entry {   	enum raminit_status (*task)(struct sysinfo *);   	bool is_enabled; -@@ -26,6 +59,7 @@ static const struct task_entry cold_boot[] = { +@@ -25,6 +59,7 @@ static const struct task_entry cold_boot[] = {   	{ configure_mc,                                           true, "CONFMC",     },   	{ configure_memory_map,                                   true, "MEMMAP",     },   	{ do_jedec_init,                                          true, "JEDECINIT",  }, @@ -83,7 +91,7 @@ index 73ff180b8c..5e4674957d 100644   /* Return a generic stepping value to make stepping checks simpler */  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index e3cf4254a0..f29c2ec366 100644 +index 4bc2a4955f..1971b44b66 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h  @@ -35,6 +35,13 @@ @@ -100,7 +108,7 @@ index e3cf4254a0..f29c2ec366 100644   /* ZQ calibration types */   enum {   	ZQ_INIT,	/* DDR3: ZQCL with tZQinit, LPDDR3: ZQ Init  with tZQinit  */ -@@ -318,6 +325,23 @@ void reut_issue_mrs_all( +@@ -316,6 +323,23 @@ void reut_issue_mrs_all(   enum raminit_status reut_issue_zq(struct sysinfo *ctrl, uint8_t chanmask, uint8_t zq_type); diff --git a/config/coreboot/haswell/patches/0007-sb-intel-lynxpoint-Add-native-PCH-init.patch b/config/coreboot/haswell/patches/0007-sb-intel-lynxpoint-Add-native-PCH-init.patch deleted file mode 100644 index 74427f5d..00000000 --- a/config/coreboot/haswell/patches/0007-sb-intel-lynxpoint-Add-native-PCH-init.patch +++ /dev/null @@ -1,785 +0,0 @@ -From 7378cb4fefc87b9a096bb14820a44f26f3a628f5 Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Fri, 6 May 2022 23:43:46 +0200 -Subject: [PATCH 07/26] sb/intel/lynxpoint: Add native PCH init - -Implement native PCH initialisation for Lynx Point. This is only needed -when MRC.bin is not used. - -Change-Id: I36867bdc8b20000e44ff9d0d7b2c0d63952bd561 -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - .../haswell/native_raminit/raminit_native.c   |   3 +- - src/southbridge/intel/lynxpoint/Makefile.inc  |   1 + - .../intel/lynxpoint/early_pch_native.c        | 123 +++++++++ - .../intel/lynxpoint/hsio/Makefile.inc         |   8 + - src/southbridge/intel/lynxpoint/hsio/common.c |  52 ++++ - src/southbridge/intel/lynxpoint/hsio/hsio.h   |  46 ++++ - .../intel/lynxpoint/hsio/lpt_h_cx.c           | 244 ++++++++++++++++++ - .../intel/lynxpoint/hsio/lpt_lp_bx.c          | 180 +++++++++++++ - src/southbridge/intel/lynxpoint/pch.h         |   6 + - 9 files changed, 661 insertions(+), 2 deletions(-) - create mode 100644 src/southbridge/intel/lynxpoint/hsio/Makefile.inc - create mode 100644 src/southbridge/intel/lynxpoint/hsio/common.c - create mode 100644 src/southbridge/intel/lynxpoint/hsio/hsio.h - create mode 100644 src/southbridge/intel/lynxpoint/hsio/lpt_h_cx.c - create mode 100644 src/southbridge/intel/lynxpoint/hsio/lpt_lp_bx.c - -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -index dd1f1ec14e..b6efb6b40d 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -@@ -16,8 +16,7 @@ static bool early_init_native(int s3resume) - 	/** TODO: CPU replacement check must be skipped in warm boots and S3 resumes **/ - 	const bool cpu_replaced = !s3resume && intel_early_me_cpu_replacement_check(); -  --	early_thermal_init(); --	early_usb_init(); -+	early_pch_init_native(s3resume); -  - 	if (!CONFIG(INTEL_LYNXPOINT_LP)) - 		dmi_early_init(); -diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc -index a9a9b153d6..63243ecc86 100644 ---- a/src/southbridge/intel/lynxpoint/Makefile.inc -+++ b/src/southbridge/intel/lynxpoint/Makefile.inc -@@ -38,6 +38,7 @@ romstage-y += early_usb.c early_me.c me_status.c early_pch.c - romstage-y += pmutil.c -  - romstage-$(CONFIG_USE_NATIVE_RAMINIT) += early_pch_native.c early_usb_native.c iobp.c thermal.c -+subdirs-$(CONFIG_USE_NATIVE_RAMINIT) += hsio -  - ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y) - romstage-y += lp_gpio.c -diff --git a/src/southbridge/intel/lynxpoint/early_pch_native.c b/src/southbridge/intel/lynxpoint/early_pch_native.c -index c28ddfcf5d..421821fa5d 100644 ---- a/src/southbridge/intel/lynxpoint/early_pch_native.c -+++ b/src/southbridge/intel/lynxpoint/early_pch_native.c -@@ -1,10 +1,133 @@ - /* SPDX-License-Identifier: GPL-2.0-or-later */ -  - #include <console/console.h> -+#include <device/pci_def.h> - #include <device/pci_ops.h> -+#include <southbridge/intel/lynxpoint/hsio/hsio.h> - #include <southbridge/intel/lynxpoint/pch.h> - #include <types.h> -  -+static void early_sata_init(const uint8_t pch_revision) -+{ -+	const bool is_mobile = get_pch_platform_type() != PCH_TYPE_DESKTOP; -+ -+	const uint8_t lane_owner = pci_read_config8(PCI_DEV(0, 0x1c, 0), 0x410); -+	printk(BIOS_DEBUG, "HSIO lane owner: 0x%02x\n", lane_owner); -+ -+	/* BWG Step 2 */ -+	pci_update_config32(PCH_SATA_DEV, SATA_SCLKG, ~0x1ff, 0x183); -+ -+	/* BWG Step 3: Set OOB Retry Mode */ -+	pci_or_config16(PCH_SATA_DEV, SATA_PCS, 1 << 15); -+ -+	/* BWG Step 4: Program the SATA mPHY tables */ -+	if (pch_is_lp()) { -+		if (pch_revision >= LPT_LP_STEP_B0 && pch_revision <= LPT_LP_STEP_B2) { -+			program_hsio_sata_lpt_lp_bx(is_mobile); -+		} else { -+			printk(BIOS_ERR, "Unsupported PCH-LP stepping 0x%02x\n", pch_revision); -+		} -+	} else { -+		if (pch_revision >= LPT_H_STEP_C0) { -+			program_hsio_sata_lpt_h_cx(is_mobile); -+		} else { -+			printk(BIOS_ERR, "Unsupported PCH-H stepping 0x%02x\n", pch_revision); -+		} -+	} -+ -+	/** FIXME: Program SATA RxEq tables **/ -+ -+	/* BWG Step 5 */ -+	/** FIXME: Only for desktop and mobile (skip this on workstation and server) **/ -+	pci_or_config32(PCH_SATA_DEV, 0x98, BIT(22)); -+ -+	/* BWG Step 6 */ -+	pci_or_config32(PCH_SATA_DEV, 0x98, BIT(19)); -+ -+	/* BWG Step 7 */ -+	pci_update_config32(PCH_SATA_DEV, 0x98, ~(0x3f << 7), 0x04 << 7); -+ -+	/* BWG Step 8 */ -+	pci_or_config32(PCH_SATA_DEV, 0x98, BIT(20)); -+ -+	/* BWG Step 9 */ -+	pci_update_config32(PCH_SATA_DEV, 0x98, ~(3 << 5), 1 << 5); -+ -+	/* BWG Step 10 */ -+	pci_or_config32(PCH_SATA_DEV, 0x98, BIT(18)); -+ -+	/* Enable SATA ports */ -+	uint8_t sata_pcs = 0; -+	if (CONFIG(INTEL_LYNXPOINT_LP)) { -+		for (uint8_t i = 0; i < 4; i++) { -+			if ((lane_owner & BIT(7 - i)) == 0) { -+				sata_pcs |= BIT(i); -+			} -+		} -+	} else { -+		sata_pcs |= 0x0f; -+		for (uint8_t i = 4; i < 6; i++) { -+			if ((lane_owner & BIT(i)) == 0) { -+				sata_pcs |= BIT(i); -+			} -+		} -+	} -+	printk(BIOS_DEBUG, "SATA port enables: 0x%02x\n", sata_pcs); -+	pci_or_config8(PCH_SATA_DEV, SATA_PCS, sata_pcs); -+} -+ -+void early_pch_init_native(int s3resume) -+{ -+	const uint8_t pch_revision = pci_read_config8(PCH_LPC_DEV, PCI_REVISION_ID); -+ -+	RCBA16(DISPBDF) = 0x0010; -+	RCBA32_OR(FD2, PCH_ENABLE_DBDF); -+ -+	/** FIXME: Check GEN_PMCON_3 and handle RTC failure? **/ -+ -+	RCBA32(PRSTS) = BIT(4); -+ -+	early_sata_init(pch_revision); -+ -+	pci_or_config8(PCH_LPC_DEV, 0xa6, 1 << 1); -+	pci_and_config8(PCH_LPC_DEV, 0xdc, ~(1 << 5 | 1 << 1)); -+ -+	/** TODO: Send GET HSIO VER and update ChipsetInit table? Is it needed? **/ -+ -+	/** FIXME: GbE handling? **/ -+ -+	pci_update_config32(PCH_LPC_DEV, 0xac, ~(1 << 20), 0); -+ -+	for (uint8_t i = 0; i < 8; i++) -+		pci_update_config32(PCI_DEV(0, 0x1c, i), 0x338, ~(1 << 26), 0); -+ -+	pci_update_config8(PCI_DEV(0, 0x1c, 0), 0xf4, ~(3 << 5), 1 << 7); -+ -+	pci_update_config8(PCI_DEV(0, 26, 0), 0x88, ~(1 << 2), 0); -+	pci_update_config8(PCI_DEV(0, 29, 0), 0x88, ~(1 << 2), 0); -+ -+	/** FIXME: Disable SATA2 device? **/ -+ -+	if (pch_is_lp()) { -+		if (pch_revision >= LPT_LP_STEP_B0 && pch_revision <= LPT_LP_STEP_B2) { -+			program_hsio_xhci_lpt_lp_bx(); -+			program_hsio_igbe_lpt_lp_bx(); -+		} else { -+			printk(BIOS_ERR, "Unsupported PCH-LP stepping 0x%02x\n", pch_revision); -+		} -+	} else { -+		if (pch_revision >= LPT_H_STEP_C0) { -+			program_hsio_xhci_lpt_h_cx(); -+			program_hsio_igbe_lpt_h_cx(); -+		} else { -+			printk(BIOS_ERR, "Unsupported PCH-H stepping 0x%02x\n", pch_revision); -+		} -+	} -+ -+	early_thermal_init(); -+	early_usb_init(); -+} -+ - void pch_dmi_setup_physical_layer(void) - { - 	/* FIXME: We need to make sure the SA supports Gen2 as well */ -diff --git a/src/southbridge/intel/lynxpoint/hsio/Makefile.inc b/src/southbridge/intel/lynxpoint/hsio/Makefile.inc -new file mode 100644 -index 0000000000..6b74997511 ---- /dev/null -+++ b/src/southbridge/intel/lynxpoint/hsio/Makefile.inc -@@ -0,0 +1,8 @@ -+## SPDX-License-Identifier: GPL-2.0-or-later -+ -+romstage-y += common.c -+ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y) -+romstage-y += lpt_lp_bx.c -+else -+romstage-y += lpt_h_cx.c -+endif -diff --git a/src/southbridge/intel/lynxpoint/hsio/common.c b/src/southbridge/intel/lynxpoint/hsio/common.c -new file mode 100644 -index 0000000000..9935ca347a ---- /dev/null -+++ b/src/southbridge/intel/lynxpoint/hsio/common.c -@@ -0,0 +1,52 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <device/pci_ops.h> -+#include <southbridge/intel/lynxpoint/hsio/hsio.h> -+#include <types.h> -+ -+/* -+ * FIXME: Ask Intel whether all lanes need to be programmed as specified -+ * in the PCH BWG. If not, make separate tables and only check this once. -+ */ -+void hsio_sata_shared_update(const uint32_t addr, const uint32_t and, const uint32_t or) -+{ -+	const uint8_t lane_owner = pci_read_config8(PCI_DEV(0, 0x1c, 0), 0x410); -+ -+	if ((addr & 0xfe00) == 0x2000 && (lane_owner & (1 << 4))) -+		return; -+ -+	if ((addr & 0xfe00) == 0x2200 && (lane_owner & (1 << 5))) -+		return; -+ -+	if (CONFIG(INTEL_LYNXPOINT_LP)) { -+		if ((addr & 0xfe00) == 0x2400 && (lane_owner & (1 << 6))) -+			return; -+ -+		if ((addr & 0xfe00) == 0x2600 && (lane_owner & (1 << 7))) -+			return; -+	} -+	hsio_update(addr, and, or); -+} -+ -+/* -+ * FIXME: Ask Intel whether all lanes need to be programmed as specified -+ * in the PCH BWG. If not, make separate tables and only check this once. -+ */ -+void hsio_xhci_shared_update(const uint32_t addr, const uint32_t and, const uint32_t or) -+{ -+	const uint8_t lane_owner = pci_read_config8(PCI_DEV(0, 0x1c, 0), 0x410); -+	if (CONFIG(INTEL_LYNXPOINT_LP)) { -+		if ((addr & 0xfe00) == 0x2400 && ((lane_owner >> 0) & 3) != 2) -+			return; -+ -+		if ((addr & 0xfe00) == 0x2600 && ((lane_owner >> 2) & 3) != 2) -+			return; -+	} else { -+		if ((addr & 0xfe00) == 0x2c00 && ((lane_owner >> 2) & 3) != 2) -+			return; -+ -+		if ((addr & 0xfe00) == 0x2e00 && ((lane_owner >> 0) & 3) != 2) -+			return; -+	} -+	hsio_update(addr, and, or); -+} -diff --git a/src/southbridge/intel/lynxpoint/hsio/hsio.h b/src/southbridge/intel/lynxpoint/hsio/hsio.h -new file mode 100644 -index 0000000000..689ef4a05b ---- /dev/null -+++ b/src/southbridge/intel/lynxpoint/hsio/hsio.h -@@ -0,0 +1,46 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#ifndef SOUTHBRIDGE_INTEL_LYNXPOINT_HSIO_H -+#define SOUTHBRIDGE_INTEL_LYNXPOINT_HSIO_H -+ -+#include <southbridge/intel/lynxpoint/iobp.h> -+#include <types.h> -+ -+struct hsio_table_row { -+	uint32_t addr; -+	uint32_t and; -+	uint32_t or; -+}; -+ -+static inline void hsio_update(const uint32_t addr, const uint32_t and, const uint32_t or) -+{ -+	pch_iobp_update(addr, and, or); -+} -+ -+static inline void hsio_update_row(const struct hsio_table_row row) -+{ -+	hsio_update(row.addr, row.and, row.or); -+} -+ -+void hsio_xhci_shared_update(const uint32_t addr, const uint32_t and, const uint32_t or); -+void hsio_sata_shared_update(const uint32_t addr, const uint32_t and, const uint32_t or); -+ -+static inline void hsio_sata_shared_update_row(const struct hsio_table_row row) -+{ -+	hsio_sata_shared_update(row.addr, row.and, row.or); -+} -+ -+static inline void hsio_xhci_shared_update_row(const struct hsio_table_row row) -+{ -+	hsio_xhci_shared_update(row.addr, row.and, row.or); -+} -+ -+void program_hsio_sata_lpt_h_cx(const bool is_mobile); -+void program_hsio_xhci_lpt_h_cx(void); -+void program_hsio_igbe_lpt_h_cx(void); -+ -+void program_hsio_sata_lpt_lp_bx(const bool is_mobile); -+void program_hsio_xhci_lpt_lp_bx(void); -+void program_hsio_igbe_lpt_lp_bx(void); -+ -+#endif -diff --git a/src/southbridge/intel/lynxpoint/hsio/lpt_h_cx.c b/src/southbridge/intel/lynxpoint/hsio/lpt_h_cx.c -new file mode 100644 -index 0000000000..b5dd402742 ---- /dev/null -+++ b/src/southbridge/intel/lynxpoint/hsio/lpt_h_cx.c -@@ -0,0 +1,244 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <device/pci_ops.h> -+#include <southbridge/intel/lynxpoint/hsio/hsio.h> -+#include <types.h> -+ -+const struct hsio_table_row hsio_sata_shared_lpt_h_cx[] = { -+	{ 0xea002008, ~0xfffc6108, 0xea6c6108 }, -+	{ 0xea002208, ~0xfffc6108, 0xea6c6108 }, -+	{ 0xea002038, ~0x3f00000f, 0x0700000d }, -+	{ 0xea002238, ~0x3f00000f, 0x0700000d }, -+	{ 0xea00202c, ~0x00020f00, 0x00020100 }, -+	{ 0xea00222c, ~0x00020f00, 0x00020100 }, -+	{ 0xea002040, ~0x1f000000, 0x01000000 }, -+	{ 0xea002240, ~0x1f000000, 0x01000000 }, -+	{ 0xea002010, ~0xffff0000, 0x0d510000 }, -+	{ 0xea002210, ~0xffff0000, 0x0d510000 }, -+	{ 0xea002018, ~0xffff0300, 0x38250100 }, -+	{ 0xea002218, ~0xffff0300, 0x38250100 }, -+	{ 0xea002000, ~0xcf030000, 0xcf030000 }, -+	{ 0xea002200, ~0xcf030000, 0xcf030000 }, -+	{ 0xea002028, ~0xff1f0000, 0x580e0000 }, -+	{ 0xea002228, ~0xff1f0000, 0x580e0000 }, -+	{ 0xea00201c, ~0x00007c00, 0x00002400 }, -+	{ 0xea00221c, ~0x00007c00, 0x00002400 }, -+	{ 0xea00208c, ~0x00ff0000, 0x00800000 }, -+	{ 0xea00228c, ~0x00ff0000, 0x00800000 }, -+	{ 0xea0020a4, ~0x0030ff00, 0x00308300 }, -+	{ 0xea0022a4, ~0x0030ff00, 0x00308300 }, -+	{ 0xea0020ac, ~0x00000030, 0x00000020 }, -+	{ 0xea0022ac, ~0x00000030, 0x00000020 }, -+	{ 0xea002140, ~0x00ffffff, 0x00140718 }, -+	{ 0xea002340, ~0x00ffffff, 0x00140718 }, -+	{ 0xea002144, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002344, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002148, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002348, ~0x00ffffff, 0x00140998 }, -+	{ 0xea00217c, ~0x03000000, 0x03000000 }, -+	{ 0xea00237c, ~0x03000000, 0x03000000 }, -+	{ 0xea002178, ~0x00001f00, 0x00001800 }, -+	{ 0xea002378, ~0x00001f00, 0x00001800 }, -+	{ 0xea00210c, ~0x0038000f, 0x00000005 }, -+	{ 0xea00230c, ~0x0038000f, 0x00000005 }, -+}; -+ -+const struct hsio_table_row hsio_sata_lpt_h_cx[] = { -+	{ 0xea008008, ~0xff000000, 0x1c000000 }, -+	{ 0xea002408, ~0xfffc6108, 0xea6c6108 }, -+	{ 0xea002608, ~0xfffc6108, 0xea6c6108 }, -+	{ 0xea000808, ~0xfffc6108, 0xea6c6108 }, -+	{ 0xea000a08, ~0xfffc6108, 0xea6c6108 }, -+	{ 0xea002438, ~0x3f00000f, 0x0700000d }, -+	{ 0xea002638, ~0x3f00000f, 0x0700000d }, -+	{ 0xea000838, ~0x3f00000f, 0x0700000d }, -+	{ 0xea000a38, ~0x3f00000f, 0x0700000d }, -+	{ 0xea002440, ~0x1f000000, 0x01000000 }, -+	{ 0xea002640, ~0x1f000000, 0x01000000 }, -+	{ 0xea000840, ~0x1f000000, 0x01000000 }, -+	{ 0xea000a40, ~0x1f000000, 0x01000000 }, -+	{ 0xea002410, ~0xffff0000, 0x0d510000 }, -+	{ 0xea002610, ~0xffff0000, 0x0d510000 }, -+	{ 0xea000810, ~0xffff0000, 0x0d510000 }, -+	{ 0xea000a10, ~0xffff0000, 0x0d510000 }, -+	{ 0xea00242c, ~0x00020800, 0x00020000 }, -+	{ 0xea00262c, ~0x00020800, 0x00020000 }, -+	{ 0xea00082c, ~0x00020800, 0x00020000 }, -+	{ 0xea000a2c, ~0x00020800, 0x00020000 }, -+	{ 0xea002418, ~0xffff0300, 0x38250100 }, -+	{ 0xea002618, ~0xffff0300, 0x38250100 }, -+	{ 0xea000818, ~0xffff0300, 0x38250100 }, -+	{ 0xea000a18, ~0xffff0300, 0x38250100 }, -+	{ 0xea002400, ~0xcf030000, 0xcf030000 }, -+	{ 0xea002600, ~0xcf030000, 0xcf030000 }, -+	{ 0xea000800, ~0xcf030000, 0xcf030000 }, -+	{ 0xea000a00, ~0xcf030000, 0xcf030000 }, -+	{ 0xea002428, ~0xff1f0000, 0x580e0000 }, -+	{ 0xea002628, ~0xff1f0000, 0x580e0000 }, -+	{ 0xea000828, ~0xff1f0000, 0x580e0000 }, -+	{ 0xea000a28, ~0xff1f0000, 0x580e0000 }, -+	{ 0xea00241c, ~0x00007c00, 0x00002400 }, -+	{ 0xea00261c, ~0x00007c00, 0x00002400 }, -+	{ 0xea00081c, ~0x00007c00, 0x00002400 }, -+	{ 0xea000a1c, ~0x00007c00, 0x00002400 }, -+	{ 0xea00248c, ~0x00ff0000, 0x00800000 }, -+	{ 0xea00268c, ~0x00ff0000, 0x00800000 }, -+	{ 0xea00088c, ~0x00ff0000, 0x00800000 }, -+	{ 0xea000a8c, ~0x00ff0000, 0x00800000 }, -+	{ 0xea0024a4, ~0x0030ff00, 0x00308300 }, -+	{ 0xea0026a4, ~0x0030ff00, 0x00308300 }, -+	{ 0xea0008a4, ~0x0030ff00, 0x00308300 }, -+	{ 0xea000aa4, ~0x0030ff00, 0x00308300 }, -+	{ 0xea0024ac, ~0x00000030, 0x00000020 }, -+	{ 0xea0026ac, ~0x00000030, 0x00000020 }, -+	{ 0xea0008ac, ~0x00000030, 0x00000020 }, -+	{ 0xea000aac, ~0x00000030, 0x00000020 }, -+	{ 0xea002540, ~0x00ffffff, 0x00140718 }, -+	{ 0xea002740, ~0x00ffffff, 0x00140718 }, -+	{ 0xea000940, ~0x00ffffff, 0x00140718 }, -+	{ 0xea000b40, ~0x00ffffff, 0x00140718 }, -+	{ 0xea002544, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002744, ~0x00ffffff, 0x00140998 }, -+	{ 0xea000944, ~0x00ffffff, 0x00140998 }, -+	{ 0xea000b44, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002548, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002748, ~0x00ffffff, 0x00140998 }, -+	{ 0xea000948, ~0x00ffffff, 0x00140998 }, -+	{ 0xea000b48, ~0x00ffffff, 0x00140998 }, -+	{ 0xea00257c, ~0x03000000, 0x03000000 }, -+	{ 0xea00277c, ~0x03000000, 0x03000000 }, -+	{ 0xea00097c, ~0x03000000, 0x03000000 }, -+	{ 0xea000b7c, ~0x03000000, 0x03000000 }, -+	{ 0xea002578, ~0x00001f00, 0x00001800 }, -+	{ 0xea002778, ~0x00001f00, 0x00001800 }, -+	{ 0xea000978, ~0x00001f00, 0x00001800 }, -+	{ 0xea000b78, ~0x00001f00, 0x00001800 }, -+	{ 0xea00250c, ~0x0038000f, 0x00000005 }, -+	{ 0xea00270c, ~0x0038000f, 0x00000005 }, -+	{ 0xea00090c, ~0x0038000f, 0x00000005 }, -+	{ 0xea000b0c, ~0x0038000f, 0x00000005 }, -+}; -+ -+const struct hsio_table_row hsio_xhci_shared_lpt_h_cx[] = { -+	{ 0xe9002c2c, ~0x00000700, 0x00000100 }, -+	{ 0xe9002e2c, ~0x00000700, 0x00000100 }, -+	{ 0xe9002dcc, ~0x00001407, 0x00001407 }, -+	{ 0xe9002fcc, ~0x00001407, 0x00001407 }, -+	{ 0xe9002d68, ~0x01000f3c, 0x00000a28 }, -+	{ 0xe9002f68, ~0x01000f3c, 0x00000a28 }, -+	{ 0xe9002d6c, ~0x000000ff, 0x0000003f }, -+	{ 0xe9002f6c, ~0x000000ff, 0x0000003f }, -+	{ 0xe9002d4c, ~0x00ffff00, 0x00120500 }, -+	{ 0xe9002f4c, ~0x00ffff00, 0x00120500 }, -+	{ 0xe9002d14, ~0x38000700, 0x00000100 }, -+	{ 0xe9002f14, ~0x38000700, 0x00000100 }, -+	{ 0xe9002d64, ~0x0000f000, 0x00005000 }, -+	{ 0xe9002f64, ~0x0000f000, 0x00005000 }, -+	{ 0xe9002d70, ~0x00000018, 0x00000000 }, -+	{ 0xe9002f70, ~0x00000018, 0x00000000 }, -+	{ 0xe9002c38, ~0x3f00000f, 0x0700000b }, -+	{ 0xe9002e38, ~0x3f00000f, 0x0700000b }, -+	{ 0xe9002d40, ~0x00800000, 0x00000000 }, -+	{ 0xe9002f40, ~0x00800000, 0x00000000 }, -+}; -+ -+const struct hsio_table_row hsio_xhci_lpt_h_cx[] = { -+	{ 0xe90031cc, ~0x00001407, 0x00001407 }, -+	{ 0xe90033cc, ~0x00001407, 0x00001407 }, -+	{ 0xe90015cc, ~0x00001407, 0x00001407 }, -+	{ 0xe90017cc, ~0x00001407, 0x00001407 }, -+	{ 0xe9003168, ~0x01000f3c, 0x00000a28 }, -+	{ 0xe9003368, ~0x01000f3c, 0x00000a28 }, -+	{ 0xe9001568, ~0x01000f3c, 0x00000a28 }, -+	{ 0xe9001768, ~0x01000f3c, 0x00000a28 }, -+	{ 0xe900316c, ~0x000000ff, 0x0000003f }, -+	{ 0xe900336c, ~0x000000ff, 0x0000003f }, -+	{ 0xe900156c, ~0x000000ff, 0x0000003f }, -+	{ 0xe900176c, ~0x000000ff, 0x0000003f }, -+	{ 0xe900314c, ~0x00ffff00, 0x00120500 }, -+	{ 0xe900334c, ~0x00ffff00, 0x00120500 }, -+	{ 0xe900154c, ~0x00ffff00, 0x00120500 }, -+	{ 0xe900174c, ~0x00ffff00, 0x00120500 }, -+	{ 0xe9003114, ~0x38000700, 0x00000100 }, -+	{ 0xe9003314, ~0x38000700, 0x00000100 }, -+	{ 0xe9001514, ~0x38000700, 0x00000100 }, -+	{ 0xe9001714, ~0x38000700, 0x00000100 }, -+	{ 0xe9003164, ~0x0000f000, 0x00005000 }, -+	{ 0xe9003364, ~0x0000f000, 0x00005000 }, -+	{ 0xe9001564, ~0x0000f000, 0x00005000 }, -+	{ 0xe9001764, ~0x0000f000, 0x00005000 }, -+	{ 0xe9003170, ~0x00000018, 0x00000000 }, -+	{ 0xe9003370, ~0x00000018, 0x00000000 }, -+	{ 0xe9001570, ~0x00000018, 0x00000000 }, -+	{ 0xe9001770, ~0x00000018, 0x00000000 }, -+	{ 0xe9003038, ~0x3f00000f, 0x0700000b }, -+	{ 0xe9003238, ~0x3f00000f, 0x0700000b }, -+	{ 0xe9001438, ~0x3f00000f, 0x0700000b }, -+	{ 0xe9001638, ~0x3f00000f, 0x0700000b }, -+	{ 0xe9003140, ~0x00800000, 0x00000000 }, -+	{ 0xe9003340, ~0x00800000, 0x00000000 }, -+	{ 0xe9001540, ~0x00800000, 0x00000000 }, -+	{ 0xe9001740, ~0x00800000, 0x00000000 }, -+}; -+ -+void program_hsio_sata_lpt_h_cx(const bool is_mobile) -+{ -+	const struct hsio_table_row *pch_hsio_table; -+	size_t len; -+ -+	pch_hsio_table = hsio_sata_lpt_h_cx; -+	len = ARRAY_SIZE(hsio_sata_lpt_h_cx); -+	for (size_t i = 0; i < len; i++) -+		hsio_update_row(pch_hsio_table[i]); -+ -+	pch_hsio_table = hsio_sata_shared_lpt_h_cx; -+	len = ARRAY_SIZE(hsio_sata_shared_lpt_h_cx); -+	for (size_t i = 0; i < len; i++) -+		hsio_sata_shared_update_row(pch_hsio_table[i]); -+ -+	const uint32_t hsio_sata_value = is_mobile ? 0x00004c5a : 0x00003e67; -+ -+	hsio_update(0xea002490, ~0x0000ffff, hsio_sata_value); -+	hsio_update(0xea002690, ~0x0000ffff, hsio_sata_value); -+	hsio_update(0xea000890, ~0x0000ffff, hsio_sata_value); -+	hsio_update(0xea000a90, ~0x0000ffff, hsio_sata_value); -+ -+	hsio_sata_shared_update(0xea002090, ~0x0000ffff, hsio_sata_value); -+	hsio_sata_shared_update(0xea002290, ~0x0000ffff, hsio_sata_value); -+} -+ -+void program_hsio_xhci_lpt_h_cx(void) -+{ -+	const struct hsio_table_row *pch_hsio_table; -+	size_t len; -+ -+	pch_hsio_table = hsio_xhci_lpt_h_cx; -+	len = ARRAY_SIZE(hsio_xhci_lpt_h_cx); -+ -+	for (size_t i = 0; i < len; i++) -+		hsio_update_row(pch_hsio_table[i]); -+ -+	pch_hsio_table = hsio_xhci_shared_lpt_h_cx; -+	len = ARRAY_SIZE(hsio_xhci_shared_lpt_h_cx); -+ -+	for (size_t i = 0; i < len; i++) -+		hsio_xhci_shared_update_row(pch_hsio_table[i]); -+} -+ -+void program_hsio_igbe_lpt_h_cx(void) -+{ -+	const uint32_t strpfusecfg1 = pci_read_config32(PCI_DEV(0, 0x1c, 0), 0xfc); -+	if (!(strpfusecfg1 & (1 << 19))) -+		return; -+ -+	const uint8_t gbe_port = (strpfusecfg1 >> 16) & 0x7; -+	const uint8_t lane_owner = pci_read_config8(PCI_DEV(0, 0x1c, 0), 0x410); -+	if (gbe_port == 0 && ((lane_owner >> 0) & 3) != 1) -+		return; -+ -+	if (gbe_port == 1 && ((lane_owner >> 2) & 3) != 1) -+		return; -+ -+	const uint32_t gbe_hsio_base = 0xe900 << 16 | (0x2e - 2 * gbe_port) << 8; -+	hsio_update(gbe_hsio_base + 0x08, ~0xf0000100, 0xe0000100); -+} -diff --git a/src/southbridge/intel/lynxpoint/hsio/lpt_lp_bx.c b/src/southbridge/intel/lynxpoint/hsio/lpt_lp_bx.c -new file mode 100644 -index 0000000000..24679e791a ---- /dev/null -+++ b/src/southbridge/intel/lynxpoint/hsio/lpt_lp_bx.c -@@ -0,0 +1,180 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <device/pci_ops.h> -+#include <southbridge/intel/lynxpoint/iobp.h> -+#include <southbridge/intel/lynxpoint/hsio/hsio.h> -+#include <types.h> -+ -+const struct hsio_table_row hsio_sata_shared_lpt_lp_bx[] = { -+	{ 0xea008008, ~0xff000000, 0x1c000000 }, -+	{ 0xea002008, ~0xfffc6108, 0xea6c6108 }, -+	{ 0xea002208, ~0xfffc6108, 0xea6c6108 }, -+	{ 0xea002408, ~0xfffc6108, 0xea6c6108 }, -+	{ 0xea002608, ~0xfffc6108, 0xea6c6108 }, -+	{ 0xea002038, ~0x0000000f, 0x0000000d }, -+	{ 0xea002238, ~0x0000000f, 0x0000000d }, -+	{ 0xea002438, ~0x0000000f, 0x0000000d }, -+	{ 0xea002638, ~0x0000000f, 0x0000000d }, -+	{ 0xea00202c, ~0x00020f00, 0x00020100 }, -+	{ 0xea00222c, ~0x00020f00, 0x00020100 }, -+	{ 0xea00242c, ~0x00020f00, 0x00020100 }, -+	{ 0xea00262c, ~0x00020f00, 0x00020100 }, -+	{ 0xea002040, ~0x1f000000, 0x01000000 }, -+	{ 0xea002240, ~0x1f000000, 0x01000000 }, -+	{ 0xea002440, ~0x1f000000, 0x01000000 }, -+	{ 0xea002640, ~0x1f000000, 0x01000000 }, -+	{ 0xea002010, ~0xffff0000, 0x55510000 }, -+	{ 0xea002210, ~0xffff0000, 0x55510000 }, -+	{ 0xea002410, ~0xffff0000, 0x55510000 }, -+	{ 0xea002610, ~0xffff0000, 0x55510000 }, -+	{ 0xea002140, ~0x00ffffff, 0x00140718 }, -+	{ 0xea002340, ~0x00ffffff, 0x00140718 }, -+	{ 0xea002540, ~0x00ffffff, 0x00140718 }, -+	{ 0xea002740, ~0x00ffffff, 0x00140718 }, -+	{ 0xea002144, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002344, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002544, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002744, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002148, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002348, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002548, ~0x00ffffff, 0x00140998 }, -+	{ 0xea002748, ~0x00ffffff, 0x00140998 }, -+	{ 0xea00217c, ~0x03000000, 0x03000000 }, -+	{ 0xea00237c, ~0x03000000, 0x03000000 }, -+	{ 0xea00257c, ~0x03000000, 0x03000000 }, -+	{ 0xea00277c, ~0x03000000, 0x03000000 }, -+	{ 0xea00208c, ~0x00ff0000, 0x00800000 }, -+	{ 0xea00228c, ~0x00ff0000, 0x00800000 }, -+	{ 0xea00248c, ~0x00ff0000, 0x00800000 }, -+	{ 0xea00268c, ~0x00ff0000, 0x00800000 }, -+	{ 0xea0020a4, ~0x0030ff00, 0x00308300 }, -+	{ 0xea0022a4, ~0x0030ff00, 0x00308300 }, -+	{ 0xea0024a4, ~0x0030ff00, 0x00308300 }, -+	{ 0xea0026a4, ~0x0030ff00, 0x00308300 }, -+	{ 0xea0020ac, ~0x00000030, 0x00000020 }, -+	{ 0xea0022ac, ~0x00000030, 0x00000020 }, -+	{ 0xea0024ac, ~0x00000030, 0x00000020 }, -+	{ 0xea0026ac, ~0x00000030, 0x00000020 }, -+	{ 0xea002018, ~0xffff0300, 0x38250100 }, -+	{ 0xea002218, ~0xffff0300, 0x38250100 }, -+	{ 0xea002418, ~0xffff0300, 0x38250100 }, -+	{ 0xea002618, ~0xffff0300, 0x38250100 }, -+	{ 0xea002000, ~0xcf030000, 0xcf030000 }, -+	{ 0xea002200, ~0xcf030000, 0xcf030000 }, -+	{ 0xea002400, ~0xcf030000, 0xcf030000 }, -+	{ 0xea002600, ~0xcf030000, 0xcf030000 }, -+	{ 0xea002028, ~0xff1f0000, 0x580e0000 }, -+	{ 0xea002228, ~0xff1f0000, 0x580e0000 }, -+	{ 0xea002428, ~0xff1f0000, 0x580e0000 }, -+	{ 0xea002628, ~0xff1f0000, 0x580e0000 }, -+	{ 0xea00201c, ~0x00007c00, 0x00002400 }, -+	{ 0xea00221c, ~0x00007c00, 0x00002400 }, -+	{ 0xea00241c, ~0x00007c00, 0x00002400 }, -+	{ 0xea00261c, ~0x00007c00, 0x00002400 }, -+	{ 0xea002178, ~0x00001f00, 0x00001800 }, -+	{ 0xea002378, ~0x00001f00, 0x00001800 }, -+	{ 0xea002578, ~0x00001f00, 0x00001800 }, -+	{ 0xea002778, ~0x00001f00, 0x00001800 }, -+	{ 0xea00210c, ~0x0038000f, 0x00000005 }, -+	{ 0xea00230c, ~0x0038000f, 0x00000005 }, -+	{ 0xea00250c, ~0x0038000f, 0x00000005 }, -+	{ 0xea00270c, ~0x0038000f, 0x00000005 }, -+}; -+ -+const struct hsio_table_row hsio_xhci_shared_lpt_lp_bx[] = { -+	{ 0xe90025cc, ~0x00001407, 0x00001407 }, -+	{ 0xe90027cc, ~0x00001407, 0x00001407 }, -+	{ 0xe9002568, ~0x01000f3c, 0x00000a28 }, -+	{ 0xe9002768, ~0x01000f3c, 0x00000a28 }, -+	{ 0xe900242c, ~0x00000700, 0x00000100 }, -+	{ 0xe900262c, ~0x00000700, 0x00000100 }, -+	{ 0xe900256c, ~0x000000ff, 0x0000003f }, -+	{ 0xe900276c, ~0x000000ff, 0x0000003f }, -+	{ 0xe900254c, ~0x00ffff00, 0x00120500 }, -+	{ 0xe900274c, ~0x00ffff00, 0x00120500 }, -+	{ 0xe9002564, ~0x0000f000, 0x00005000 }, -+	{ 0xe9002764, ~0x0000f000, 0x00005000 }, -+	{ 0xe9002570, ~0x00000018, 0x00000000 }, -+	{ 0xe9002770, ~0x00000018, 0x00000000 }, -+	{ 0xe9002514, ~0x38000700, 0x00000100 }, -+	{ 0xe9002714, ~0x38000700, 0x00000100 }, -+	{ 0xe9002438, ~0x0000000f, 0x0000000b }, -+	{ 0xe9002638, ~0x0000000f, 0x0000000b }, -+	{ 0xe9002414, ~0x0000fe00, 0x00006600 }, -+	{ 0xe9002614, ~0x0000fe00, 0x00006600 }, -+	{ 0xe9002540, ~0x00800000, 0x00000000 }, -+	{ 0xe9002740, ~0x00800000, 0x00000000 }, -+}; -+ -+const struct hsio_table_row hsio_xhci_lpt_lp_bx[] = { -+	{ 0xe90021cc, ~0x00001407, 0x00001407 }, -+	{ 0xe90023cc, ~0x00001407, 0x00001407 }, -+	{ 0xe9002168, ~0x01000f3c, 0x00000a28 }, -+	{ 0xe9002368, ~0x01000f3c, 0x00000a28 }, -+	{ 0xe900216c, ~0x000000ff, 0x0000003f }, -+	{ 0xe900236c, ~0x000000ff, 0x0000003f }, -+	{ 0xe900214c, ~0x00ffff00, 0x00120500 }, -+	{ 0xe900234c, ~0x00ffff00, 0x00120500 }, -+	{ 0xe9002164, ~0x0000f000, 0x00005000 }, -+	{ 0xe9002364, ~0x0000f000, 0x00005000 }, -+	{ 0xe9002170, ~0x00000018, 0x00000000 }, -+	{ 0xe9002370, ~0x00000018, 0x00000000 }, -+	{ 0xe9002114, ~0x38000700, 0x00000100 }, -+	{ 0xe9002314, ~0x38000700, 0x00000100 }, -+	{ 0xe9002038, ~0x0000000f, 0x0000000b }, -+	{ 0xe9002238, ~0x0000000f, 0x0000000b }, -+	{ 0xe9002014, ~0x0000fe00, 0x00006600 }, -+	{ 0xe9002214, ~0x0000fe00, 0x00006600 }, -+	{ 0xe9002140, ~0x00800000, 0x00000000 }, -+	{ 0xe9002340, ~0x00800000, 0x00000000 }, -+}; -+ -+void program_hsio_sata_lpt_lp_bx(const bool is_mobile) -+{ -+	const struct hsio_table_row *pch_hsio_table; -+	size_t len; -+ -+	pch_hsio_table = hsio_sata_shared_lpt_lp_bx; -+	len = ARRAY_SIZE(hsio_sata_shared_lpt_lp_bx); -+	for (size_t i = 0; i < len; i++) -+		hsio_sata_shared_update_row(pch_hsio_table[i]); -+ -+	const uint32_t hsio_sata_value = is_mobile ? 0x00004c5a : 0x00003e67; -+ -+	hsio_sata_shared_update(0xea002090, ~0x0000ffff, hsio_sata_value); -+	hsio_sata_shared_update(0xea002290, ~0x0000ffff, hsio_sata_value); -+	hsio_sata_shared_update(0xea002490, ~0x0000ffff, hsio_sata_value); -+	hsio_sata_shared_update(0xea002690, ~0x0000ffff, hsio_sata_value); -+} -+ -+void program_hsio_xhci_lpt_lp_bx(void) -+{ -+	const struct hsio_table_row *pch_hsio_table; -+	size_t len; -+ -+	pch_hsio_table = hsio_xhci_lpt_lp_bx; -+	len = ARRAY_SIZE(hsio_xhci_lpt_lp_bx); -+ -+	for (size_t i = 0; i < len; i++) -+		hsio_update_row(pch_hsio_table[i]); -+ -+	pch_hsio_table = hsio_xhci_shared_lpt_lp_bx; -+	len = ARRAY_SIZE(hsio_xhci_shared_lpt_lp_bx); -+ -+	for (size_t i = 0; i < len; i++) -+		hsio_xhci_shared_update_row(pch_hsio_table[i]); -+} -+ -+void program_hsio_igbe_lpt_lp_bx(void) -+{ -+	const uint32_t strpfusecfg1 = pci_read_config32(PCI_DEV(0, 0x1c, 0), 0xfc); -+	if (!(strpfusecfg1 & (1 << 19))) -+		return; -+ -+	const uint8_t gbe_port = (strpfusecfg1 >> 16) & 0x7; -+	if (gbe_port > 5) -+		return; -+ -+	const uint32_t gbe_hsio_base = 0xe900 << 16 | (0x08 + 2 * gbe_port) << 8; -+	hsio_update(gbe_hsio_base + 0x08, ~0xf0000100, 0xe0000100); -+} -diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h -index 38a9349220..74b4d50017 100644 ---- a/src/southbridge/intel/lynxpoint/pch.h -+++ b/src/southbridge/intel/lynxpoint/pch.h -@@ -117,6 +117,7 @@ void pch_dmi_setup_physical_layer(void); - void pch_dmi_tc_vc_mapping(u32 vc0, u32 vc1, u32 vcp, u32 vcm); - void early_usb_init(void); - void early_thermal_init(void); -+void early_pch_init_native(int s3resume); -  - void usb_ehci_sleep_prepare(pci_devfn_t dev, u8 slp_typ); - void usb_ehci_disable(pci_devfn_t dev); -@@ -271,6 +272,10 @@ void mainboard_config_rcba(void); - #define   IDE_DECODE_ENABLE	(1 << 15) - #define IDE_TIM_SEC		0x42	/* IDE timings, secondary */ -  -+#define SATA_MAP		0x90 -+#define SATA_PCS		0x92 -+#define SATA_SCLKG		0x94 -+ - #define SATA_SIRI		0xa0 /* SATA Indexed Register Index */ - #define SATA_SIRD		0xa4 /* SATA Indexed Register Data */ - #define SATA_SP			0xd0 /* Scratchpad */ -@@ -580,6 +585,7 @@ void mainboard_config_rcba(void); - #define D19IR		0x3168	/* 16bit */ - #define ACPIIRQEN	0x31e0	/* 32bit */ - #define OIC		0x31fe	/* 16bit */ -+#define PRSTS		0x3310	/* 32bit */ - #define PMSYNC_CONFIG	0x33c4	/* 32bit */ - #define PMSYNC_CONFIG2	0x33cc	/* 32bit */ - #define SOFT_RESET_CTRL 0x38f4 ---  -2.39.2 - diff --git a/config/coreboot/haswell/patches/0018-haswell-NRI-Add-REUT-I-O-test-library.patch b/config/coreboot/haswell/patches/0008-haswell-NRI-Add-REUT-I-O-test-library.patch index 5df22ed3..2225f18c 100644 --- a/config/coreboot/haswell/patches/0018-haswell-NRI-Add-REUT-I-O-test-library.patch +++ b/config/coreboot/haswell/patches/0008-haswell-NRI-Add-REUT-I-O-test-library.patch @@ -1,25 +1,25 @@ -From f4dd460d609276de7cb7db91f145a404451a2301 Mon Sep 17 00:00:00 2001 +From 49a7ef2401922a8492ba577a43235bcfba7ea822 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sun, 8 May 2022 00:11:29 +0200 -Subject: [PATCH 18/26] haswell NRI: Add REUT I/O test library +Subject: [PATCH 08/20] haswell NRI: Add REUT I/O test library  Implement a library to run I/O tests using the REUT hardware.  Change-Id: Id7b207cd0a3989ddd23c88c6b1f0cfa79d2c861f  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   1 + + .../intel/haswell/native_raminit/Makefile.mk  |   1 +   .../haswell/native_raminit/raminit_native.h   | 110 +++   .../haswell/native_raminit/reg_structs.h      | 121 +++ - .../intel/haswell/native_raminit/testing_io.c | 742 ++++++++++++++++++ + .../intel/haswell/native_raminit/testing_io.c | 744 ++++++++++++++++++   .../intel/haswell/registers/mchbar.h          |  30 + - 5 files changed, 1004 insertions(+) + 5 files changed, 1006 insertions(+)   create mode 100644 src/northbridge/intel/haswell/native_raminit/testing_io.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index 8d7d4e4db0..6e1b365602 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -12,4 +12,5 @@ romstage-y += raminit_native.c   romstage-y += reut.c   romstage-y += setup_wdb.c @@ -27,7 +27,7 @@ index 8d7d4e4db0..6e1b365602 100644  +romstage-y += testing_io.c   romstage-y += timings_refresh.c  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index f29c2ec366..56df36ca8d 100644 +index 1971b44b66..7f19fde4cc 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h  @@ -58,6 +58,88 @@ enum { @@ -120,9 +120,9 @@ index f29c2ec366..56df36ca8d 100644   	CT_ITERATION_CLOCK = 0,   	CT_ITERATION_CMD_NORTH,  @@ -199,6 +281,10 @@ struct sysinfo { - 	uint16_t mr1[NUM_CHANNELS][NUM_SLOTRANKS]; - 	uint16_t mr2[NUM_CHANNELS][NUM_SLOTRANKS]; - 	uint16_t mr3[NUM_CHANNELS][NUM_SLOTRANKS]; + 	uint16_t mr1[NUM_CHANNELS][NUM_SLOTS]; + 	uint16_t mr2[NUM_CHANNELS][NUM_SLOTS]; + 	uint16_t mr3[NUM_CHANNELS][NUM_SLOTS];  +  +	uint8_t dq_pat;  + @@ -130,7 +130,7 @@ index f29c2ec366..56df36ca8d 100644   };   static inline bool is_hsw_ult(void) -@@ -342,6 +428,30 @@ void write_wdb_va_pat( +@@ -340,6 +426,30 @@ void write_wdb_va_pat(   void program_wdb_lfsr(const struct sysinfo *ctrl, bool cleanup);   void setup_wdb(const struct sysinfo *ctrl); @@ -309,10 +309,10 @@ index 7aa8d8c8b2..b943259b91 100644   		uint32_t start_test    :  1; // Bits  0:0  diff --git a/src/northbridge/intel/haswell/native_raminit/testing_io.c b/src/northbridge/intel/haswell/native_raminit/testing_io.c  new file mode 100644 -index 0000000000..7716fc4285 +index 0000000000..2632c238f8  --- /dev/null  +++ b/src/northbridge/intel/haswell/native_raminit/testing_io.c -@@ -0,0 +1,742 @@ +@@ -0,0 +1,744 @@  +/* SPDX-License-Identifier: GPL-2.0-or-later */  +  +#include <console/console.h> @@ -535,8 +535,10 @@ index 0000000000..7716fc4285  +	const uint8_t en_cadb,  +	const uint8_t subseq_wait)  +{ -+	if (!chanmask) -+		die("\n%s: invalid chanmask\n", __func__, chanmask); ++	if (!chanmask) { ++		printk(BIOS_ERR, "\n%s: chanmask is invalid\n", __func__); ++		return; ++	}  +  +	/*  +	 * Prepare variables needed for both channels. 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 - diff --git a/config/coreboot/haswell/patches/0019-haswell-NRI-Add-range-tracking-library.patch b/config/coreboot/haswell/patches/0009-haswell-NRI-Add-range-tracking-library.patch index f433b043..9c3fe1c9 100644 --- a/config/coreboot/haswell/patches/0019-haswell-NRI-Add-range-tracking-library.patch +++ b/config/coreboot/haswell/patches/0009-haswell-NRI-Add-range-tracking-library.patch @@ -1,7 +1,7 @@ -From 9fba0468e75877cbda62f5eaeef1946d6489a8f9 Mon Sep 17 00:00:00 2001 +From 7f5c3f8c6c8960d1c374b9c95821c19f230fa34f Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sun, 8 May 2022 00:56:00 +0200 -Subject: [PATCH 19/26] haswell NRI: Add range tracking library +Subject: [PATCH 09/20] haswell NRI: Add range tracking library  Implement a small library used to keep track of passing ranges. This  will be used by 1D training algorithms when margining some parameter. @@ -9,17 +9,17 @@ will be used by 1D training algorithms when margining some parameter.  Change-Id: I8718e85165160afd7c0c8e730b5ce6c9c00f8a60  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   1 + + .../intel/haswell/native_raminit/Makefile.mk  |   1 +   .../intel/haswell/native_raminit/ranges.c     | 109 ++++++++++++++++++   .../intel/haswell/native_raminit/ranges.h     |  68 +++++++++++   3 files changed, 178 insertions(+)   create mode 100644 src/northbridge/intel/haswell/native_raminit/ranges.c   create mode 100644 src/northbridge/intel/haswell/native_raminit/ranges.h -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index 6e1b365602..2da950771d 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -9,6 +9,7 @@ romstage-y += io_comp_control.c   romstage-y += memory_map.c   romstage-y += raminit_main.c diff --git a/config/coreboot/haswell/patches/0009-nb-intel-haswell-nri-Only-do-CPU-replacement-check-o.patch b/config/coreboot/haswell/patches/0009-nb-intel-haswell-nri-Only-do-CPU-replacement-check-o.patch deleted file mode 100644 index 07525d18..00000000 --- a/config/coreboot/haswell/patches/0009-nb-intel-haswell-nri-Only-do-CPU-replacement-check-o.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 731216aef3129ae27ad5adc7266cb8a58090c9fc Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Sun, 26 Jun 2022 10:32:12 +0200 -Subject: [PATCH 09/26] nb/intel/haswell/nri: Only do CPU replacement check on - cold boots - -CPU replacement check should only be done on cold boots. - -Change-Id: I98efa105f4df755b23febe12dd7b356787847852 -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - .../intel/haswell/native_raminit/raminit_native.c   | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -index 0869db3902..bd9bc8e692 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -@@ -40,15 +40,14 @@ static enum raminit_boot_mode get_boot_mode(void) - 	return (pmcon_2 & bitmask) == bitmask ? BOOTMODE_WARM : BOOTMODE_COLD; - } -  --static bool early_init_native(int s3resume) -+static bool early_init_native(enum raminit_boot_mode bootmode) - { - 	printk(BIOS_DEBUG, "Starting native platform initialisation\n"); -  - 	intel_early_me_init(); --	/** TODO: CPU replacement check must be skipped in warm boots and S3 resumes **/ --	const bool cpu_replaced = !s3resume && intel_early_me_cpu_replacement_check(); -+	bool cpu_replaced = bootmode == BOOTMODE_COLD && intel_early_me_cpu_replacement_check(); -  --	early_pch_init_native(s3resume); -+	early_pch_init_native(bootmode == BOOTMODE_S3); -  - 	if (!CONFIG(INTEL_LYNXPOINT_LP)) - 		dmi_early_init(); -@@ -176,13 +175,13 @@ void perform_raminit(const int s3resume) - 	 * See, this function's name is a lie. There are more things to - 	 * do that memory initialisation, but they are relatively easy. - 	 */ --	const bool cpu_replaced = early_init_native(s3resume); -+	const enum raminit_boot_mode orig_bootmode = get_boot_mode(); -+ -+	const bool cpu_replaced = early_init_native(s3resume ? BOOTMODE_S3 : orig_bootmode); -  - 	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 = ---  -2.39.2 - diff --git a/config/coreboot/haswell/patches/0020-haswell-NRI-Add-library-to-change-margins.patch b/config/coreboot/haswell/patches/0010-haswell-NRI-Add-library-to-change-margins.patch index 30926494..622fac5a 100644 --- a/config/coreboot/haswell/patches/0020-haswell-NRI-Add-library-to-change-margins.patch +++ b/config/coreboot/haswell/patches/0010-haswell-NRI-Add-library-to-change-margins.patch @@ -1,24 +1,24 @@ -From 54cfbe4cf53d16f747bfcfadd20445a0f5f1e5db Mon Sep 17 00:00:00 2001 +From 8ad18cc335f60a78f47ab9e5a7994f6075b6a176 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sun, 8 May 2022 01:11:03 +0200 -Subject: [PATCH 20/26] haswell NRI: Add library to change margins +Subject: [PATCH 10/20] haswell NRI: Add library to change margins  Implement a library to change Rx/Tx margins. It will be expanded later.  Change-Id: I0b55aba428d8b4d4e16d2fbdec57235ce3ce8adf  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   1 + + .../intel/haswell/native_raminit/Makefile.mk  |   1 +   .../haswell/native_raminit/change_margin.c    | 154 ++++++++++++++++++   .../haswell/native_raminit/raminit_native.h   |  50 ++++++   .../intel/haswell/registers/mchbar.h          |   9 +   4 files changed, 214 insertions(+)   create mode 100644 src/northbridge/intel/haswell/native_raminit/change_margin.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index 2da950771d..ebe9e9b762 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -1,5 +1,6 @@   ## SPDX-License-Identifier: GPL-2.0-or-later @@ -28,13 +28,13 @@ index 2da950771d..ebe9e9b762 100644   romstage-y += jedec_reset.c  diff --git a/src/northbridge/intel/haswell/native_raminit/change_margin.c b/src/northbridge/intel/haswell/native_raminit/change_margin.c  new file mode 100644 -index 0000000000..12da59580f +index 0000000000..055c666eee  --- /dev/null  +++ b/src/northbridge/intel/haswell/native_raminit/change_margin.c  @@ -0,0 +1,154 @@  +/* SPDX-License-Identifier: GPL-2.0-or-later */  + -+#include <commonlib/clamp.h> ++#include <commonlib/bsd/clamp.h>  +#include <console/console.h>  +#include <delay.h>  +#include <northbridge/intel/haswell/haswell.h> @@ -187,7 +187,7 @@ index 0000000000..12da59580f  +	mchbar_write32(reg, ddr_data_control_0.raw);  +}  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index 56df36ca8d..7c1a786780 100644 +index 7f19fde4cc..906b3143b9 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h  @@ -117,6 +117,30 @@ enum test_stop { @@ -221,7 +221,7 @@ index 56df36ca8d..7c1a786780 100644   struct wdb_pat {   	uint32_t start_ptr;	/* Starting pointer in WDB */   	uint32_t stop_ptr;	/* Stopping pointer in WDB */ -@@ -452,6 +476,32 @@ uint8_t select_reut_ranks(struct sysinfo *ctrl, uint8_t channel, uint8_t rankmas +@@ -450,6 +474,32 @@ uint8_t select_reut_ranks(struct sysinfo *ctrl, uint8_t channel, uint8_t rankmas   void run_mpr_io_test(bool clear_errors);   uint8_t run_io_test(struct sysinfo *ctrl, uint8_t chanmask, uint8_t dq_pat, bool clear_errors); diff --git a/config/coreboot/haswell/patches/0010-haswell-NRI-Collect-SPD-info.patch b/config/coreboot/haswell/patches/0010-haswell-NRI-Collect-SPD-info.patch deleted file mode 100644 index 4c2a2670..00000000 --- a/config/coreboot/haswell/patches/0010-haswell-NRI-Collect-SPD-info.patch +++ /dev/null @@ -1,344 +0,0 @@ -From 354969af4361bcc7dc240ef5871d169728f7f0cc Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Sat, 7 May 2022 13:48:53 +0200 -Subject: [PATCH 10/26] haswell NRI: Collect SPD info - -Collect SPD data from DIMMs and memory-down, and find the common -supported settings. - -Change-Id: I4e6a1408a638a463ecae37a447cfed1d6556e44a -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - .../intel/haswell/native_raminit/Makefile.inc |   1 + - .../haswell/native_raminit/raminit_main.c     |   1 + - .../haswell/native_raminit/raminit_native.h   |  57 +++++ - .../haswell/native_raminit/spd_bitmunching.c  | 206 ++++++++++++++++++ - 4 files changed, 265 insertions(+) - create mode 100644 src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c - -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc -index 90af951c5a..ebf7abc6ec 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc -@@ -2,3 +2,4 @@ -  - romstage-y += raminit_main.c - romstage-y += raminit_native.c -+romstage-y += spd_bitmunching.c -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -index 9b42c25b40..2d2cfa48bb 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -@@ -20,6 +20,7 @@ struct task_entry { - }; -  - static const struct task_entry cold_boot[] = { -+	{ collect_spd_info,                                       true, "PROCSPD",    }, - }; -  - /* Return a generic stepping value to make stepping checks simpler */ -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index 885f0184f4..1a0793947e 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -@@ -3,6 +3,15 @@ - #ifndef HASWELL_RAMINIT_NATIVE_H - #define HASWELL_RAMINIT_NATIVE_H -  -+#include <device/dram/ddr3.h> -+#include <northbridge/intel/haswell/haswell.h> -+ -+#define SPD_LEN 256 -+ -+/* 8 data lanes + 1 ECC lane */ -+#define NUM_LANES		9 -+#define NUM_LANES_NO_ECC	8 -+ - enum raminit_boot_mode { - 	BOOTMODE_COLD, - 	BOOTMODE_WARM, -@@ -12,6 +21,8 @@ enum raminit_boot_mode { -  - enum raminit_status { - 	RAMINIT_STATUS_SUCCESS = 0, -+	RAMINIT_STATUS_NO_MEMORY_INSTALLED, -+	RAMINIT_STATUS_UNSUPPORTED_MEMORY, - 	RAMINIT_STATUS_UNSPECIFIED_ERROR, /** TODO: Deprecated in favor of specific values **/ - }; -  -@@ -21,14 +32,60 @@ enum generic_stepping { - 	STEPPING_C0 = 3, - }; -  -+struct raminit_dimm_info { -+	spd_raw_data raw_spd; -+	struct dimm_attr_ddr3_st data; -+	uint8_t spd_addr; -+	bool valid; -+}; -+ - struct sysinfo { - 	enum raminit_boot_mode bootmode; - 	enum generic_stepping stepping; - 	uint32_t cpu;		/* CPUID value */ -  - 	bool dq_pins_interleaved; -+ -+	/** TODO: ECC support untested **/ -+	bool is_ecc; -+ -+	/** -+	 * FIXME: LPDDR support is incomplete. The largest chunks are missing, -+	 * but some LPDDR-specific variations in algorithms have been handled. -+	 * LPDDR-specific functions have stubs which will halt upon execution. -+	 */ -+	bool lpddr; -+ -+	struct raminit_dimm_info dimms[NUM_CHANNELS][NUM_SLOTS]; -+	union dimm_flags_ddr3_st flags; -+	uint16_t cas_supported; -+ -+	/* Except for tCK, everything is eventually stored in DCLKs */ -+	uint32_t tCK; -+	uint32_t tAA;			/* Also known as tCL */ -+	uint32_t tWR; -+	uint32_t tRCD; -+	uint32_t tRRD; -+	uint32_t tRP; -+	uint32_t tRAS; -+	uint32_t tRC; -+	uint32_t tRFC; -+	uint32_t tWTR; -+	uint32_t tRTP; -+	uint32_t tFAW; -+	uint32_t tCWL; -+	uint32_t tCMD; -+ -+	uint8_t lanes;			/* 8 or 9 */ -+	uint8_t chanmap; -+	uint8_t dpc[NUM_CHANNELS];	/* DIMMs per channel */ -+	uint8_t rankmap[NUM_CHANNELS]; -+	uint8_t rank_mirrored[NUM_CHANNELS]; -+	uint32_t channel_size_mb[NUM_CHANNELS]; - }; -  - void raminit_main(enum raminit_boot_mode bootmode); -  -+enum raminit_status collect_spd_info(struct sysinfo *ctrl); -+ - #endif -diff --git a/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c b/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c -new file mode 100644 -index 0000000000..dbe02c72d0 ---- /dev/null -+++ b/src/northbridge/intel/haswell/native_raminit/spd_bitmunching.c -@@ -0,0 +1,206 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <cbfs.h> -+#include <commonlib/clamp.h> -+#include <console/console.h> -+#include <device/dram/ddr3.h> -+#include <device/smbus_host.h> -+#include <northbridge/intel/haswell/haswell.h> -+#include <northbridge/intel/haswell/raminit.h> -+#include <string.h> -+#include <types.h> -+ -+#include "raminit_native.h" -+ -+static const uint8_t *get_spd_data_from_cbfs(struct spd_info *spdi) -+{ -+	if (!CONFIG(HAVE_SPD_IN_CBFS)) -+		return NULL; -+ -+	printk(RAM_DEBUG, "SPD index %u\n", spdi->spd_index); -+ -+	size_t spd_file_len; -+	uint8_t *spd_file = cbfs_map("spd.bin", &spd_file_len); -+ -+	if (!spd_file) { -+		printk(BIOS_ERR, "SPD data not found in CBFS\n"); -+		return NULL; -+	} -+ -+	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) { -+		printk(BIOS_ERR, "Invalid SPD data in CBFS\n"); -+		return NULL; -+	} -+ -+	return spd_file + (spdi->spd_index * SPD_LEN); -+} -+ -+static void get_spd_for_dimm(struct raminit_dimm_info *const dimm, const uint8_t *cbfs_spd) -+{ -+	if (dimm->spd_addr == SPD_MEMORY_DOWN) { -+		if (cbfs_spd) { -+			memcpy(dimm->raw_spd, cbfs_spd, SPD_LEN); -+			dimm->valid = true; -+			printk(RAM_DEBUG, "memory-down\n"); -+			return; -+		} else { -+			printk(RAM_DEBUG, "memory-down but no CBFS SPD data, ignoring\n"); -+			return; -+		} -+	} -+	printk(RAM_DEBUG, "slotted "); -+	const uint8_t spd_mem_type = smbus_read_byte(dimm->spd_addr, SPD_MEMORY_TYPE); -+	if (spd_mem_type != SPD_MEMORY_TYPE_SDRAM_DDR3) { -+		printk(RAM_DEBUG, "and not DDR3, ignoring\n"); -+		return; -+	} -+	printk(RAM_DEBUG, "and DDR3\n"); -+	if (i2c_eeprom_read(dimm->spd_addr, 0, SPD_LEN, dimm->raw_spd) != SPD_LEN) { -+		printk(BIOS_WARNING, "I2C block read failed, trying SMBus byte reads\n"); -+		for (uint32_t i = 0; i < SPD_LEN; i++) -+			dimm->raw_spd[i] = smbus_read_byte(dimm->spd_addr, i); -+	} -+	dimm->valid = true; -+} -+ -+static void get_spd_data(struct sysinfo *ctrl) -+{ -+	struct spd_info spdi = {0}; -+	mb_get_spd_map(&spdi); -+	const uint8_t *cbfs_spd = get_spd_data_from_cbfs(&spdi); -+	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { -+		for (uint8_t slot = 0; slot < NUM_SLOTS; slot++) { -+			struct raminit_dimm_info *const dimm = &ctrl->dimms[channel][slot]; -+			dimm->spd_addr = spdi.addresses[channel + channel + slot]; -+			if (!dimm->spd_addr) -+				continue; -+ -+			printk(RAM_DEBUG, "CH%uS%u is ", channel, slot); -+			get_spd_for_dimm(dimm, cbfs_spd); -+		} -+	} -+} -+ -+static void decode_spd(struct raminit_dimm_info *const dimm) -+{ -+	/** TODO: Hook up somewhere, and handle lack of XMP data **/ -+	const bool enable_xmp = false; -+	memset(&dimm->data, 0, sizeof(dimm->data)); -+	if (enable_xmp) -+		spd_xmp_decode_ddr3(&dimm->data, dimm->raw_spd, DDR3_XMP_PROFILE_1); -+	else -+		spd_decode_ddr3(&dimm->data, dimm->raw_spd); -+ -+	if (CONFIG(DEBUG_RAM_SETUP)) -+		dram_print_spd_ddr3(&dimm->data); -+} -+ -+static enum raminit_status find_common_spd_parameters(struct sysinfo *ctrl) -+{ -+	ctrl->cas_supported = 0xffff; -+	ctrl->flags.raw = 0xffffffff; -+ -+	ctrl->tCK  = 0; -+	ctrl->tAA  = 0; -+	ctrl->tWR  = 0; -+	ctrl->tRCD = 0; -+	ctrl->tRRD = 0; -+	ctrl->tRP  = 0; -+	ctrl->tRAS = 0; -+	ctrl->tRC  = 0; -+	ctrl->tRFC = 0; -+	ctrl->tWTR = 0; -+	ctrl->tRTP = 0; -+	ctrl->tFAW = 0; -+	ctrl->tCWL = 0; -+	ctrl->tCMD = 0; -+	ctrl->chanmap = 0; -+ -+	bool yes_ecc = false; -+	bool not_ecc = false; -+ -+	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { -+		ctrl->dpc[channel] = 0; -+		ctrl->rankmap[channel] = 0; -+		ctrl->rank_mirrored[channel] = 0; -+		ctrl->channel_size_mb[channel] = 0; -+		for (uint8_t slot = 0; slot < NUM_SLOTS; slot++) { -+			struct raminit_dimm_info *const dimm = &ctrl->dimms[channel][slot]; -+			if (!dimm->valid) -+				continue; -+ -+			printk(RAM_DEBUG, "\nCH%uS%u SPD:\n", channel, slot); -+			decode_spd(dimm); -+ -+			ctrl->chanmap |= BIT(channel); -+			ctrl->dpc[channel]++; -+			ctrl->channel_size_mb[channel] += dimm->data.size_mb; -+ -+			/* The first rank of a populated slot is always present */ -+			const uint8_t rank = slot + slot; -+			assert(dimm->data.ranks); -+			ctrl->rankmap[channel] |= (BIT(dimm->data.ranks) - 1) << rank; -+ -+			if (dimm->data.flags.pins_mirrored) -+				ctrl->rank_mirrored[channel] |= BIT(rank + 1); -+ -+			/* Find common settings */ -+			ctrl->cas_supported &= dimm->data.cas_supported; -+			ctrl->flags.raw &= dimm->data.flags.raw; -+			ctrl->tCK  = MAX(ctrl->tCK,  dimm->data.tCK); -+			ctrl->tAA  = MAX(ctrl->tAA,  dimm->data.tAA); -+			ctrl->tWR  = MAX(ctrl->tWR,  dimm->data.tWR); -+			ctrl->tRCD = MAX(ctrl->tRCD, dimm->data.tRCD); -+			ctrl->tRRD = MAX(ctrl->tRRD, dimm->data.tRRD); -+			ctrl->tRP  = MAX(ctrl->tRP,  dimm->data.tRP); -+			ctrl->tRAS = MAX(ctrl->tRAS, dimm->data.tRAS); -+			ctrl->tRC  = MAX(ctrl->tRC,  dimm->data.tRC); -+			ctrl->tRFC = MAX(ctrl->tRFC, dimm->data.tRFC); -+			ctrl->tWTR = MAX(ctrl->tWTR, dimm->data.tWTR); -+			ctrl->tRTP = MAX(ctrl->tRTP, dimm->data.tRTP); -+			ctrl->tFAW = MAX(ctrl->tFAW, dimm->data.tFAW); -+			ctrl->tCWL = MAX(ctrl->tCWL, dimm->data.tCWL); -+			ctrl->tCMD = MAX(ctrl->tCMD, dimm->data.tCMD); -+ -+			yes_ecc |=  dimm->data.flags.is_ecc; -+			not_ecc |= !dimm->data.flags.is_ecc; -+		} -+	} -+ -+	if (!ctrl->chanmap) { -+		printk(BIOS_ERR, "No DIMMs were found\n"); -+		return RAMINIT_STATUS_NO_MEMORY_INSTALLED; -+	} -+	if (!ctrl->cas_supported) { -+		printk(BIOS_ERR, "Could not resolve common CAS latency\n"); -+		return RAMINIT_STATUS_UNSUPPORTED_MEMORY; -+	} -+	/** TODO: Properly handle ECC support and ECC forced **/ -+	if (yes_ecc && not_ecc) { -+		/** TODO: Test if the ECC DIMMs can be operated as non-ECC DIMMs **/ -+		printk(BIOS_ERR, "Both ECC and non-ECC DIMMs present, this is unsupported\n"); -+		return RAMINIT_STATUS_UNSUPPORTED_MEMORY; -+	} -+	if (yes_ecc) -+		ctrl->lanes = NUM_LANES; -+	else -+		ctrl->lanes = NUM_LANES_NO_ECC; -+ -+	ctrl->is_ecc = yes_ecc; -+ -+	/** TODO: Complete LPDDR support **/ -+	ctrl->lpddr = false; -+ -+	return RAMINIT_STATUS_SUCCESS; -+} -+ -+enum raminit_status collect_spd_info(struct sysinfo *ctrl) -+{ -+	get_spd_data(ctrl); -+	return find_common_spd_parameters(ctrl); -+} ---  -2.39.2 - diff --git a/config/coreboot/haswell/patches/0021-haswell-NRI-Add-RcvEn-training.patch b/config/coreboot/haswell/patches/0011-haswell-NRI-Add-RcvEn-training.patch index 9139a67e..4815be9a 100644 --- a/config/coreboot/haswell/patches/0021-haswell-NRI-Add-RcvEn-training.patch +++ b/config/coreboot/haswell/patches/0011-haswell-NRI-Add-RcvEn-training.patch @@ -1,14 +1,14 @@ -From ac8843553af34855d0331554c03280e66c4ea582 Mon Sep 17 00:00:00 2001 +From 4254a9ff03658d7a6f1a4e32cfe4c65dbfc072f8 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sun, 8 May 2022 00:05:41 +0200 -Subject: [PATCH 21/26] haswell NRI: Add RcvEn training +Subject: [PATCH 11/20] haswell NRI: Add RcvEn training  Implement the RcvEn (Receive Enable) calibration procedure.  Change-Id: Ifbfa520f3e0486c56d0988ce67af2ddb9cf29888  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   1 + + .../intel/haswell/native_raminit/Makefile.mk  |   1 +   .../haswell/native_raminit/raminit_main.c     |   1 +   .../haswell/native_raminit/raminit_native.h   |  14 +   .../haswell/native_raminit/reg_structs.h      |  13 + @@ -17,10 +17,10 @@ Signed-off-by: Angel Pons <th3fanbus@gmail.com>   6 files changed, 593 insertions(+)   create mode 100644 src/northbridge/intel/haswell/native_raminit/train_receive_enable.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index ebe9e9b762..e2fbfb4211 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -16,3 +16,4 @@ romstage-y += setup_wdb.c   romstage-y += spd_bitmunching.c   romstage-y += testing_io.c @@ -39,7 +39,7 @@ index 5e4674957d..7d444659c3 100644   /* Return a generic stepping value to make stepping checks simpler */  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index 7c1a786780..a36ebfacd1 100644 +index 906b3143b9..b4e8c7de5a 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h  @@ -42,6 +42,9 @@ @@ -83,7 +83,7 @@ index 7c1a786780..a36ebfacd1 100644   /* Number of ticks to wait in units of 69.841279 ns (citation needed) */   static inline void tick_delay(const uint32_t delay)   { -@@ -401,6 +414,7 @@ enum raminit_status convert_timings(struct sysinfo *ctrl); +@@ -399,6 +412,7 @@ enum raminit_status convert_timings(struct sysinfo *ctrl);   enum raminit_status configure_mc(struct sysinfo *ctrl);   enum raminit_status configure_memory_map(struct sysinfo *ctrl);   enum raminit_status do_jedec_init(struct sysinfo *ctrl); diff --git a/config/coreboot/haswell/patches/0022-haswell-NRI-Add-function-to-change-margins.patch b/config/coreboot/haswell/patches/0012-haswell-NRI-Add-function-to-change-margins.patch index 2e6de17c..f4f5161e 100644 --- a/config/coreboot/haswell/patches/0022-haswell-NRI-Add-function-to-change-margins.patch +++ b/config/coreboot/haswell/patches/0012-haswell-NRI-Add-function-to-change-margins.patch @@ -1,7 +1,7 @@ -From 8c3874195c0fc1af9d0b84611496689da1c19d8c Mon Sep 17 00:00:00 2001 +From c24b26594bfab47a8709ed7fb5cb77307fb73a53 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sun, 8 May 2022 11:58:59 +0200 -Subject: [PATCH 22/26] haswell NRI: Add function to change margins +Subject: [PATCH 12/20] haswell NRI: Add function to change margins  Implement a function to change margin parameters. Haswell provides a  register to apply an offset to margin parameters during training, so @@ -19,14 +19,14 @@ Signed-off-by: Angel Pons <th3fanbus@gmail.com>   4 files changed, 188 insertions(+)  diff --git a/src/northbridge/intel/haswell/native_raminit/change_margin.c b/src/northbridge/intel/haswell/native_raminit/change_margin.c -index 12da59580f..4ba9cfa5c6 100644 +index 055c666eee..299c44a6b0 100644  --- a/src/northbridge/intel/haswell/native_raminit/change_margin.c  +++ b/src/northbridge/intel/haswell/native_raminit/change_margin.c  @@ -1,5 +1,6 @@   /* SPDX-License-Identifier: GPL-2.0-or-later */  +#include <assert.h> - #include <commonlib/clamp.h> + #include <commonlib/bsd/clamp.h>   #include <console/console.h>   #include <delay.h>  @@ -152,3 +153,138 @@ void download_regfile( @@ -169,7 +169,7 @@ index 12da59580f..4ba9cfa5c6 100644  +	change_margin(ctrl, param, value0, true, 0, rank, 0, update_ctrl, regfile);  +}  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index a36ebfacd1..500fc28909 100644 +index b4e8c7de5a..5242b16f28 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h  @@ -35,6 +35,18 @@ @@ -206,7 +206,7 @@ index a36ebfacd1..500fc28909 100644   /* ZQ calibration types */   enum {   	ZQ_INIT,	/* DDR3: ZQCL with tZQinit, LPDDR3: ZQ Init  with tZQinit  */ -@@ -516,6 +536,25 @@ void download_regfile( +@@ -514,6 +534,25 @@ void download_regfile(   	bool read_rf_rd,   	bool read_rf_wr); diff --git a/config/coreboot/haswell/patches/0023-haswell-NRI-Add-read-MPR-training.patch b/config/coreboot/haswell/patches/0013-haswell-NRI-Add-read-MPR-training.patch index b13eb2db..5f154bcc 100644 --- a/config/coreboot/haswell/patches/0023-haswell-NRI-Add-read-MPR-training.patch +++ b/config/coreboot/haswell/patches/0013-haswell-NRI-Add-read-MPR-training.patch @@ -1,25 +1,25 @@ -From 6781cec818501f7afd6ee26464fd4556ac3068cb Mon Sep 17 00:00:00 2001 +From e263f0d2e9d6d016d603342651da261bbcb6af1f Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sun, 8 May 2022 11:35:49 +0200 -Subject: [PATCH 23/26] haswell NRI: Add read MPR training +Subject: [PATCH 13/20] haswell NRI: Add read MPR training  Implement read training using DDR3 MPR (Multi-Purpose Register).  Change-Id: Id17cb2c4c399ac9bcc937b595b58f863c152461b  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   1 + + .../intel/haswell/native_raminit/Makefile.mk  |   1 +   .../haswell/native_raminit/raminit_main.c     |   1 +   .../haswell/native_raminit/raminit_native.h   |   4 + - .../haswell/native_raminit/train_read_mpr.c   | 240 ++++++++++++++++++ + .../haswell/native_raminit/train_read_mpr.c   | 241 ++++++++++++++++++   .../intel/haswell/registers/mchbar.h          |   2 +- - 5 files changed, 247 insertions(+), 1 deletion(-) + 5 files changed, 248 insertions(+), 1 deletion(-)   create mode 100644 src/northbridge/intel/haswell/native_raminit/train_read_mpr.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index e2fbfb4211..c442be0728 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -16,4 +16,5 @@ romstage-y += setup_wdb.c   romstage-y += spd_bitmunching.c   romstage-y += testing_io.c @@ -39,7 +39,7 @@ index 7d444659c3..264d1468f5 100644   /* Return a generic stepping value to make stepping checks simpler */  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index 500fc28909..a7551ad63c 100644 +index 5242b16f28..49e9214656 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h  @@ -27,6 +27,8 @@ @@ -59,7 +59,7 @@ index 500fc28909..a7551ad63c 100644   	RAMINIT_STATUS_UNSPECIFIED_ERROR, /** TODO: Deprecated in favor of specific values **/   }; -@@ -435,6 +438,7 @@ enum raminit_status configure_mc(struct sysinfo *ctrl); +@@ -433,6 +436,7 @@ enum raminit_status configure_mc(struct sysinfo *ctrl);   enum raminit_status configure_memory_map(struct sysinfo *ctrl);   enum raminit_status do_jedec_init(struct sysinfo *ctrl);   enum raminit_status train_receive_enable(struct sysinfo *ctrl); @@ -69,13 +69,13 @@ index 500fc28909..a7551ad63c 100644   void configure_refresh(struct sysinfo *ctrl);  diff --git a/src/northbridge/intel/haswell/native_raminit/train_read_mpr.c b/src/northbridge/intel/haswell/native_raminit/train_read_mpr.c  new file mode 100644 -index 0000000000..0225e1a384 +index 0000000000..ade1e36148  --- /dev/null  +++ b/src/northbridge/intel/haswell/native_raminit/train_read_mpr.c -@@ -0,0 +1,240 @@ +@@ -0,0 +1,241 @@  +/* SPDX-License-Identifier: GPL-2.0-or-later */  + -+#include <commonlib/clamp.h> ++#include <commonlib/bsd/clamp.h>  +#include <console/console.h>  +#include <delay.h>  +#include <northbridge/intel/haswell/haswell.h> @@ -206,7 +206,8 @@ index 0000000000..0225e1a384  +		for (dqs_delay = RMPR_START; dqs_delay < RMPR_STOP; dqs_delay += RMPR_STEP) {  +			printk(RMPR_PLOT, "% 5d", dqs_delay);  +			const enum regfile_mode regfile = REG_FILE_USE_START; -+			change_1d_margin_multicast(ctrl, RdT, dqs_delay, 0, false, regfile); ++			/* Looks like MRC uses rank 0 here, but it feels wrong */ ++			change_1d_margin_multicast(ctrl, RdT, dqs_delay, rank, false, regfile);  +			for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) {  +				if (!rank_in_ch(ctrl, rank, channel))  +					continue; diff --git a/config/coreboot/haswell/patches/0024-haswell-NRI-Add-write-leveling.patch b/config/coreboot/haswell/patches/0014-haswell-NRI-Add-write-leveling.patch index 59e9af9d..5a96cd1f 100644 --- a/config/coreboot/haswell/patches/0024-haswell-NRI-Add-write-leveling.patch +++ b/config/coreboot/haswell/patches/0014-haswell-NRI-Add-write-leveling.patch @@ -1,7 +1,7 @@ -From 20fe4fa852d3e13851a01b51dc984ec5976c864e Mon Sep 17 00:00:00 2001 +From bebe0b74bede64b03aa1e3781310ef539465627b Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sun, 8 May 2022 12:56:04 +0200 -Subject: [PATCH 24/26] haswell NRI: Add write leveling +Subject: [PATCH 14/20] haswell NRI: Add write leveling  Implement JEDEC write leveling, which is done in two steps. The first  step uses the JEDEC procedure to do "fine" write leveling, i.e. align @@ -11,18 +11,18 @@ read-write test to correct "coarse" cycle errors.  Change-Id: I27678523fe22c38173a688e2a4751c259a20f009  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  --- - .../intel/haswell/native_raminit/Makefile.inc |   1 + + .../intel/haswell/native_raminit/Makefile.mk  |   1 +   .../haswell/native_raminit/raminit_main.c     |   1 +   .../haswell/native_raminit/raminit_native.h   |  10 + - .../train_jedec_write_leveling.c              | 580 ++++++++++++++++++ + .../train_jedec_write_leveling.c              | 581 ++++++++++++++++++   .../intel/haswell/registers/mchbar.h          |   2 + - 5 files changed, 594 insertions(+) + 5 files changed, 595 insertions(+)   create mode 100644 src/northbridge/intel/haswell/native_raminit/train_jedec_write_leveling.c -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index c442be0728..40c2f5e014 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -16,5 +16,6 @@ romstage-y += setup_wdb.c   romstage-y += spd_bitmunching.c   romstage-y += testing_io.c @@ -43,7 +43,7 @@ index 264d1468f5..1ff23be615 100644   /* Return a generic stepping value to make stepping checks simpler */  diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index a7551ad63c..666b233c45 100644 +index 49e9214656..86d89f2120 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h  @@ -59,6 +59,9 @@ @@ -76,7 +76,7 @@ index a7551ad63c..666b233c45 100644   /* Number of ticks to wait in units of 69.841279 ns (citation needed) */   static inline void tick_delay(const uint32_t delay)   { -@@ -439,6 +448,7 @@ enum raminit_status configure_memory_map(struct sysinfo *ctrl); +@@ -437,6 +446,7 @@ enum raminit_status configure_memory_map(struct sysinfo *ctrl);   enum raminit_status do_jedec_init(struct sysinfo *ctrl);   enum raminit_status train_receive_enable(struct sysinfo *ctrl);   enum raminit_status train_read_mpr(struct sysinfo *ctrl); @@ -86,10 +86,10 @@ index a7551ad63c..666b233c45 100644   void configure_refresh(struct sysinfo *ctrl);  diff --git a/src/northbridge/intel/haswell/native_raminit/train_jedec_write_leveling.c b/src/northbridge/intel/haswell/native_raminit/train_jedec_write_leveling.c  new file mode 100644 -index 0000000000..1ba28a3bd4 +index 0000000000..ef6483e2bd  --- /dev/null  +++ b/src/northbridge/intel/haswell/native_raminit/train_jedec_write_leveling.c -@@ -0,0 +1,580 @@ +@@ -0,0 +1,581 @@  +/* SPDX-License-Identifier: GPL-2.0-or-later */  +  +#include <assert.h> @@ -106,7 +106,8 @@ index 0000000000..1ba28a3bd4  +  +static void reset_dram_dll(struct sysinfo *ctrl, const uint8_t channel, const uint8_t rank)  +{ -+	reut_issue_mrs(ctrl, channel, BIT(rank), 0, ctrl->mr0[channel][rank] | MR0_DLL_RESET); ++	const uint16_t mr0reg = ctrl->mr0[channel][rank / 2]; ++	reut_issue_mrs(ctrl, channel, BIT(rank), 0, mr0reg | MR0_DLL_RESET);  +}  +  +static void program_wdb_pattern(struct sysinfo *ctrl, const bool invert) @@ -463,7 +464,7 @@ index 0000000000..1ba28a3bd4  +				continue;  +  +			/** TODO: Differs for LPDDR **/ -+			uint16_t mr1reg = ctrl->mr1[channel][rank]; ++			uint16_t mr1reg = ctrl->mr1[channel][rank / 2];  +			mr1reg &= ~MR1_QOFF_ENABLE;  +			mr1reg |= MR1_WL_ENABLE;  +			if (is_hsw_ult()) { @@ -605,7 +606,7 @@ index 0000000000..1ba28a3bd4  +			mchbar_write32(REUT_ch_MISC_ODT_CTRL(channel), 0);  +  +			/** TODO: Differs for LPDDR **/ -+			const uint16_t mr1reg = ctrl->mr1[channel][rank] | MR1_QOFF_ENABLE; ++			const uint16_t mr1reg = ctrl->mr1[channel][rank / 2] | MR1_QOFF_ENABLE;  +			reut_issue_mrs(ctrl, channel, BIT(rank), 1, mr1reg);  +  +			printk(BIOS_DEBUG, "\nC%u.R%u:  LftEdge Width\n", channel, rank); diff --git a/config/coreboot/haswell/patches/0025-haswell-NRI-Add-final-raminit-steps.patch b/config/coreboot/haswell/patches/0015-haswell-NRI-Add-final-raminit-steps.patch index d15ea5d1..3626bf6d 100644 --- a/config/coreboot/haswell/patches/0025-haswell-NRI-Add-final-raminit-steps.patch +++ b/config/coreboot/haswell/patches/0015-haswell-NRI-Add-final-raminit-steps.patch @@ -1,7 +1,7 @@ -From d041b14f3af69db5f4598c84e3f53c9cd572ffb5 Mon Sep 17 00:00:00 2001 +From eba8680d618db95028e3f984f25881df0e67abf7 Mon Sep 17 00:00:00 2001  From: Angel Pons <th3fanbus@gmail.com>  Date: Sun, 8 May 2022 14:29:05 +0200 -Subject: [PATCH 25/26] haswell NRI: Add final raminit steps +Subject: [PATCH 15/20] haswell NRI: Add final raminit steps  Implement the remaining raminit steps. Although many training steps are  missing, this is enough to boot on the Asrock B85M Pro4. @@ -10,7 +10,7 @@ Change-Id: I94f3b65f0218d4da4fda4d84592dfd91f77f8f21  Signed-off-by: Angel Pons <th3fanbus@gmail.com>  ---   src/northbridge/intel/haswell/Kconfig         |   4 +- - .../intel/haswell/native_raminit/Makefile.inc |   1 + + .../intel/haswell/native_raminit/Makefile.mk  |   1 +   .../haswell/native_raminit/activate_mc.c      | 388 ++++++++++++++++++   .../haswell/native_raminit/raminit_main.c     |   5 +-   .../haswell/native_raminit/raminit_native.c   |   5 +- @@ -21,10 +21,10 @@ Signed-off-by: Angel Pons <th3fanbus@gmail.com>   create mode 100644 src/northbridge/intel/haswell/native_raminit/activate_mc.c  diff --git a/src/northbridge/intel/haswell/Kconfig b/src/northbridge/intel/haswell/Kconfig -index b659bf6d98..61f2a3c64c 100644 +index 4b83a25bc1..c6ab27184e 100644  --- a/src/northbridge/intel/haswell/Kconfig  +++ b/src/northbridge/intel/haswell/Kconfig -@@ -10,12 +10,12 @@ config NORTHBRIDGE_INTEL_HASWELL +@@ -11,12 +11,12 @@ config NORTHBRIDGE_INTEL_HASWELL   if NORTHBRIDGE_INTEL_HASWELL   config USE_NATIVE_RAMINIT @@ -39,10 +39,10 @@ index b659bf6d98..61f2a3c64c 100644   config HASWELL_VBOOT_IN_BOOTBLOCK   	depends on VBOOT -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.inc b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  index 40c2f5e014..d97da72890 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.inc -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.inc +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk  @@ -1,5 +1,6 @@   ## SPDX-License-Identifier: GPL-2.0-or-later @@ -466,10 +466,10 @@ index 1ff23be615..3a65fb01fb 100644  -	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 bd9bc8e692..1ea729b23d 100644 +index 2fed93de5b..5f7ceec222 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -@@ -200,8 +200,6 @@ void perform_raminit(const int s3resume) +@@ -199,8 +199,6 @@ void perform_raminit(const int s3resume)   		else   			me_status = ME_INIT_STATUS_SUCCESS; @@ -478,7 +478,7 @@ index bd9bc8e692..1ea729b23d 100644   		intel_early_me_init_done(me_status);   	} -@@ -217,7 +215,8 @@ void perform_raminit(const int s3resume) +@@ -214,7 +212,8 @@ void perform_raminit(const int s3resume)   	}   	/* Save training data on non-S3 resumes */ @@ -489,10 +489,10 @@ index bd9bc8e692..1ea729b23d 100644   	/** 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 -index 666b233c45..98e39cb76e 100644 +index 86d89f2120..9bab57b518 100644  --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h  +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -@@ -449,6 +449,8 @@ enum raminit_status do_jedec_init(struct sysinfo *ctrl); +@@ -447,6 +447,8 @@ enum raminit_status do_jedec_init(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); diff --git a/config/coreboot/haswell/patches/0016-Haswell-NRI-Implement-fast-boot-path.patch b/config/coreboot/haswell/patches/0016-Haswell-NRI-Implement-fast-boot-path.patch new file mode 100644 index 00000000..c2fd8b60 --- /dev/null +++ b/config/coreboot/haswell/patches/0016-Haswell-NRI-Implement-fast-boot-path.patch @@ -0,0 +1,722 @@ +From c7d6a901edf648f0f02dd2053337bcf3a319e49b Mon Sep 17 00:00:00 2001 +From: Angel Pons <th3fanbus@gmail.com> +Date: Sat, 13 Apr 2024 01:16:30 +0200 +Subject: [PATCH 16/20] Haswell NRI: Implement fast boot path + +When the memory configuration hasn't changed, there is no need to do +full memory training. Instead, boot firmware can use saved training +data to reinitialise the memory controller and memory. + +Unlike native RAM init for other platforms, Haswell does not save the +main structure (the "mighty ctrl" struct) to flash. Instead, separate +structures define the data to be saved, which can be smaller than the +main structure. + +This makes S3 suspend and resume work: RAM contents MUST be preserved +for a S3 resume to succeed, but RAM training destroys RAM contents. + +Change-Id: I06f6cd39ceecdca104fae89159f28e85cf7ff4e6 +Signed-off-by: Angel Pons <th3fanbus@gmail.com> +--- + .../intel/haswell/native_raminit/Makefile.mk  |   1 + + .../haswell/native_raminit/activate_mc.c      |  17 + + .../intel/haswell/native_raminit/ddr3.c       |  41 ++ + .../haswell/native_raminit/raminit_main.c     |  34 +- + .../haswell/native_raminit/raminit_native.c   |  30 +- + .../haswell/native_raminit/raminit_native.h   |  18 + + .../haswell/native_raminit/save_restore.c     | 387 ++++++++++++++++++ + 7 files changed, 504 insertions(+), 24 deletions(-) + create mode 100644 src/northbridge/intel/haswell/native_raminit/save_restore.c + +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk +index d97da72890..8fdd17c542 100644 +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk +@@ -13,6 +13,7 @@ romstage-y += raminit_main.c + romstage-y += raminit_native.c + romstage-y += ranges.c + romstage-y += reut.c ++romstage-y += save_restore.c + romstage-y += setup_wdb.c + romstage-y += spd_bitmunching.c + romstage-y += testing_io.c +diff --git a/src/northbridge/intel/haswell/native_raminit/activate_mc.c b/src/northbridge/intel/haswell/native_raminit/activate_mc.c +index 78a7ad27ef..0b3eb917da 100644 +--- a/src/northbridge/intel/haswell/native_raminit/activate_mc.c ++++ b/src/northbridge/intel/haswell/native_raminit/activate_mc.c +@@ -333,6 +333,23 @@ enum raminit_status activate_mc(struct sysinfo *ctrl) + 	return RAMINIT_STATUS_SUCCESS; + } +  ++enum raminit_status normal_state(struct sysinfo *ctrl) ++{ ++	/* Enable periodic COMP */ ++	mchbar_write32(M_COMP, (union pcu_comp_reg) { ++		.comp_interval = COMP_INT, ++	}.raw); ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		if (!does_ch_exist(ctrl, channel)) ++			continue; ++ ++		/* Set MC to normal mode and clean the ODT and CKE */ ++		mchbar_write32(REUT_ch_SEQ_CFG(channel), REUT_MODE_NOP << 12); ++	} ++	power_down_config(ctrl); ++	return RAMINIT_STATUS_SUCCESS; ++} ++ + static void mc_lockdown(void) + { + 	/* Lock memory controller registers */ +diff --git a/src/northbridge/intel/haswell/native_raminit/ddr3.c b/src/northbridge/intel/haswell/native_raminit/ddr3.c +index 6ddb11488b..9b6368edb1 100644 +--- a/src/northbridge/intel/haswell/native_raminit/ddr3.c ++++ b/src/northbridge/intel/haswell/native_raminit/ddr3.c +@@ -2,6 +2,7 @@ +  + #include <assert.h> + #include <console/console.h> ++#include <delay.h> + #include <northbridge/intel/haswell/haswell.h> + #include <types.h> +  +@@ -215,3 +216,43 @@ enum raminit_status ddr3_jedec_init(struct sysinfo *ctrl) + 	ddr3_program_mr0(ctrl, 1); + 	return reut_issue_zq(ctrl, ctrl->chanmap, ZQ_INIT); + } ++ ++enum raminit_status exit_selfrefresh(struct sysinfo *ctrl) ++{ ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		if (!does_ch_exist(ctrl, channel)) ++			continue; ++ ++		/* Fields in ctrl aren't populated on a warm boot */ ++		union ddr_data_control_0_reg data_control_0 = { ++			.raw = mchbar_read32(DQ_CONTROL_0(channel, 0)), ++		}; ++		data_control_0.read_rf_rd = 1; ++		for (uint8_t rank = 0; rank < NUM_SLOTRANKS; rank++) { ++			if (!rank_in_ch(ctrl, rank, channel)) ++				continue; ++ ++			data_control_0.read_rf_rank = rank; ++			mchbar_write32(DDR_DATA_ch_CONTROL_0(channel), data_control_0.raw); ++		} ++	} ++ ++	/* Time needed to stabilize the DCLK (~6 us) */ ++	udelay(6); ++ ++	/* Pull the DIMMs out of self refresh by asserting CKE high */ ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		const union reut_misc_cke_ctrl_reg reut_misc_cke_ctrl = { ++			.cke_on = ctrl->rankmap[channel], ++		}; ++		mchbar_write32(REUT_ch_MISC_CKE_CTRL(channel), reut_misc_cke_ctrl.raw); ++	} ++	mchbar_write32(REUT_MISC_ODT_CTRL, 0); ++ ++	const enum raminit_status status = reut_issue_zq(ctrl, ctrl->chanmap, ZQ_LONG); ++	if (status) { ++		/* ZQCL errors don't seem to be a fatal problem here */ ++		printk(BIOS_ERR, "ZQ Long failed during S3 resume or warm reset flow\n"); ++	} ++	return RAMINIT_STATUS_SUCCESS; ++} +diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c +index 3a65fb01fb..056dde1adc 100644 +--- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c ++++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c +@@ -64,6 +64,22 @@ static const struct task_entry cold_boot[] = { + 	{ train_read_mpr,                                         true, "RDMPRT",     }, + 	{ train_jedec_write_leveling,                             true, "JWRL",       }, + 	{ activate_mc,                                            true, "ACTIVATE",   }, ++	{ save_training_values,                                   true, "SAVE_TRAIN", }, ++	{ save_non_training,                                      true, "SAVE_NONT",  }, ++	{ raminit_done,                                           true, "RAMINITEND", }, ++}; ++ ++static const struct task_entry fast_boot[] = { ++	{ collect_spd_info,                                       true, "PROCSPD",    }, ++	{ restore_non_training,                                   true, "RST_NONT",   }, ++	{ initialise_mpll,                                        true, "INITMPLL",   }, ++	{ configure_mc,                                           true, "CONFMC",     }, ++	{ configure_memory_map,                                   true, "MEMMAP",     }, ++	{ do_jedec_init,                                          true, "JEDECINIT",  }, ++	{ pre_training,                                           true, "PRETRAIN",   }, ++	{ restore_training_values,                                true, "RST_TRAIN",  }, ++	{ exit_selfrefresh,                                       true, "EXIT_SR",    }, ++	{ normal_state,                                           true, "NORMALMODE", }, + 	{ raminit_done,                                           true, "RAMINITEND", }, + }; +  +@@ -102,11 +118,11 @@ static void initialize_ctrl(struct sysinfo *ctrl) + 	ctrl->bootmode = bootmode; + } +  +-static enum raminit_status try_raminit(struct sysinfo *ctrl) ++static enum raminit_status try_raminit( ++	struct sysinfo *ctrl, ++	const struct task_entry *const schedule, ++	const size_t length) + { +-	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++) { +@@ -140,8 +156,16 @@ void raminit_main(const enum raminit_boot_mode bootmode) + 	mighty_ctrl.bootmode = bootmode; + 	initialize_ctrl(&mighty_ctrl); +  ++	enum raminit_status status = RAMINIT_STATUS_UNSPECIFIED_ERROR; ++ ++	if (bootmode != BOOTMODE_COLD) { ++		status = try_raminit(&mighty_ctrl, fast_boot, ARRAY_SIZE(fast_boot)); ++		if (status == RAMINIT_STATUS_SUCCESS) ++			return; ++	} ++ + 	/** TODO: Try more than once **/ +-	enum raminit_status status = try_raminit(&mighty_ctrl); ++	status = try_raminit(&mighty_ctrl, cold_boot, ARRAY_SIZE(cold_boot)); +  + 	if (status != RAMINIT_STATUS_SUCCESS) + 		die("Memory initialization was met with utmost failure and misery\n"); +diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c +index 5f7ceec222..3ad8ce29e7 100644 +--- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c ++++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c +@@ -54,23 +54,17 @@ static bool early_init_native(enum raminit_boot_mode bootmode) + 	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) ++static void save_mrc_data(void) + { +-	mrc_cache_stash_data(MRC_TRAINING_DATA, MRC_CACHE_VERSION, md->buffer, md->buffer_len); ++	mrc_cache_stash_data(MRC_TRAINING_DATA, reg_frame_rev(), ++			     reg_frame_ptr(), reg_frame_size()); + } +  + 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, ++						reg_frame_rev(), + 						&md.buffer_len); + 	return md; + } +@@ -94,14 +88,15 @@ static void raminit_reset(void) + } +  + 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) + { ++	struct mrc_data md = prepare_mrc_cache(); ++ + 	enum raminit_boot_mode bootmode = orig_bootmode; +  +-	bool save_data_valid = md->buffer && md->buffer_len == USHRT_MAX; /** TODO: sizeof() **/ ++	bool save_data_valid = md.buffer && md.buffer_len == reg_frame_size(); +  + 	if (s3resume) { + 		if (bootmode == BOOTMODE_COLD) { +@@ -154,7 +149,7 @@ static enum raminit_boot_mode do_actual_raminit( + 	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"); ++		memcpy(reg_frame_ptr(), md.buffer, reg_frame_size()); + 	} + 	printk(RAM_DEBUG, "Initial bootmode: %s\n", bm_names[orig_bootmode]); + 	printk(RAM_DEBUG, "Current bootmode: %s\n", bm_names[bootmode]); +@@ -181,10 +176,8 @@ void perform_raminit(const int s3resume) + 	wait_txt_clear(); + 	wrmsr(0x2e6, (msr_t) {.lo = 0, .hi = 0}); +  +-	struct mrc_data md = prepare_mrc_cache(); +- + 	const enum raminit_boot_mode bootmode = +-			do_actual_raminit(&md, s3resume, cpu_replaced, orig_bootmode); ++			do_actual_raminit(s3resume, cpu_replaced, orig_bootmode); +  + 	/** TODO: report_memory_config **/ +  +@@ -212,9 +205,8 @@ void perform_raminit(const int s3resume) + 	} +  + 	/* Save training data on non-S3 resumes */ +-	/** TODO: Enable this once training data is populated **/ +-	if (0 && !s3resume) +-		save_mrc_data(&md); ++	if (!s3resume) ++		save_mrc_data(); +  + 	/** 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 +index 9bab57b518..0750904aec 100644 +--- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h ++++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h +@@ -169,6 +169,8 @@ enum regfile_mode { + 	REG_FILE_USE_CURRENT,	/* Used when changing parameters after the test */ + }; +  ++struct register_save_frame; ++ + struct wdb_pat { + 	uint32_t start_ptr;	/* Starting pointer in WDB */ + 	uint32_t stop_ptr;	/* Stopping pointer in WDB */ +@@ -219,6 +221,7 @@ enum raminit_status { + 	RAMINIT_STATUS_RCVEN_FAILURE, + 	RAMINIT_STATUS_RMPR_FAILURE, + 	RAMINIT_STATUS_JWRL_FAILURE, ++	RAMINIT_STATUS_INVALID_CACHE, + 	RAMINIT_STATUS_UNSPECIFIED_ERROR, /** TODO: Deprecated in favor of specific values **/ + }; +  +@@ -228,6 +231,11 @@ enum generic_stepping { + 	STEPPING_C0 = 3, + }; +  ++struct mrc_data { ++	const void *buffer; ++	size_t buffer_len; ++}; ++ + struct raminit_dimm_info { + 	spd_raw_data raw_spd; + 	struct dimm_attr_ddr3_st data; +@@ -447,12 +455,22 @@ enum raminit_status do_jedec_init(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 save_training_values(struct sysinfo *ctrl); ++enum raminit_status restore_training_values(struct sysinfo *ctrl); ++enum raminit_status save_non_training(struct sysinfo *ctrl); ++enum raminit_status restore_non_training(struct sysinfo *ctrl); ++enum raminit_status exit_selfrefresh(struct sysinfo *ctrl); ++enum raminit_status normal_state(struct sysinfo *ctrl); + enum raminit_status activate_mc(struct sysinfo *ctrl); + enum raminit_status raminit_done(struct sysinfo *ctrl); +  + void configure_timings(struct sysinfo *ctrl); + void configure_refresh(struct sysinfo *ctrl); +  ++struct register_save_frame *reg_frame_ptr(void); ++size_t reg_frame_size(void); ++uint32_t reg_frame_rev(void); ++ + uint32_t get_tCKE(uint32_t mem_clock_mhz, bool lpddr); + uint32_t get_tXPDLL(uint32_t mem_clock_mhz); + uint32_t get_tAONPD(uint32_t mem_clock_mhz); +diff --git a/src/northbridge/intel/haswell/native_raminit/save_restore.c b/src/northbridge/intel/haswell/native_raminit/save_restore.c +new file mode 100644 +index 0000000000..f1f50e3ff8 +--- /dev/null ++++ b/src/northbridge/intel/haswell/native_raminit/save_restore.c +@@ -0,0 +1,387 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#include <assert.h> ++#include <console/console.h> ++#include <northbridge/intel/haswell/haswell.h> ++#include <types.h> ++ ++#include "raminit_native.h" ++ ++uint32_t reg_frame_rev(void) ++{ ++	/* ++	 * Equivalent to MRC_CACHE_REVISION, but hidden via abstraction. ++	 * The structures that get saved to flash are contained within ++	 * this translation unit, so changes outside this file shouldn't ++	 * require invalidating the cache. ++	 */ ++	return 1; ++} ++ ++struct register_save { ++	uint16_t lower; ++	uint16_t upper; ++}; ++ ++/** TODO: Haswell DDRIO aliases writes: 0x80 .. 0xff => 0x00 .. 0x7f **/ ++static const struct register_save ddrio_per_byte_list[] = { ++	{0x0000, 0x003c}, /* 16 registers */ ++//	{0x0048, 0x0084}, /* 16 registers */	/** TODO: BDW support **/ ++	{0x0048, 0x004c}, /*  2 registers */ ++	{0x005c, 0x0078}, /*  8 registers */ ++}; ++#define DDRIO_PER_BYTE_REGISTER_COUNT	(16 + 2 + 8) ++ ++static const struct register_save ddrio_per_ch_list[] = { ++	/* CKE */ ++	{0x1204, 0x1208}, /* 2 registers */ ++	{0x1214, 0x121c}, /* 3 registers */ ++	/* CMD North */ ++	{0x1404, 0x140c}, /* 3 registers */ ++	/* CLK */ ++	{0x1808, 0x1810}, /* 3 registers */ ++	/* CMD South */ ++	{0x1a04, 0x1a0c}, /* 3 registers */ ++	/* CTL */ ++	{0x1c14, 0x1c1c}, /* 3 registers */ ++}; ++#define DDRIO_PER_CH_REGISTER_COUNT	(2 + 3 * 5) ++ ++static const struct register_save ddrio_common_list[] = { ++	{0x2000, 0x2008}, /* 3 registers */ ++	{0x3a14, 0x3a1c}, /* 3 registers */ ++	{0x3a24, 0x3a24}, /* 1 registers */ ++}; ++ ++#define DDRIO_COMMON_REGISTER_COUNT	(3 + 3 + 1) ++ ++static const struct register_save mcmain_per_ch_list[] = { ++	{0x4000, 0x4014}, /* 6 registers */ ++	{0x4024, 0x4028}, /* 2 registers */ ++	{0x40d0, 0x40d0}, /* 1 registers */ ++	{0x4220, 0x4224}, /* 2 registers */ ++	{0x4294, 0x4294}, /* 1 registers */ ++	{0x429c, 0x42a0}, /* 2 registers */ ++	{0x42ec, 0x42fc}, /* 5 registers */ ++	{0x4328, 0x4328}, /* 1 registers */ ++	{0x438c, 0x4390}, /* 2 registers */ ++}; ++#define MCMAIN_PER_CH_REGISTER_COUNT	(6 + 2 + 1 + 2 + 1 + 2 + 5 + 1 + 2) ++ ++static const struct register_save misc_common_list[] = { ++	{0x5884, 0x5888}, /*  2 registers */ ++	{0x5890, 0x589c}, /*  4 registers */ ++	{0x58a4, 0x58a4}, /*  1 registers */ ++	{0x58d0, 0x58e4}, /*  6 registers */ ++	{0x5880, 0x5880}, /*  1 registers */ ++	{0x5000, 0x50dc}, /* 56 registers */ ++	{0x59b8, 0x59b8}  /*  1 registers */ ++}; ++#define MISC_COMMON_REGISTER_COUNT	(2 + 4 + 1 + 6 + 1 + 56 + 1) ++ ++struct save_params { ++	bool is_initialised; ++ ++	/* Memory base frequency, either 100 or 133 MHz */ ++	uint8_t base_freq; ++ ++	/* Multiplier */ ++	uint32_t multiplier; ++ ++	/* Memory clock in MHz */ ++	uint32_t mem_clock_mhz; ++ ++	/* Memory clock in femtoseconds */ ++	uint32_t mem_clock_fs; ++ ++	/* Quadrature clock in picoseconds */ ++	uint16_t qclkps; ++ ++	/* Bitfield of supported CAS latencies */ ++	uint16_t cas_supported; ++ ++	/* CPUID value */ ++	uint32_t cpu; ++ ++	/* Cached CPU stepping value */ ++	uint8_t stepping; ++ ++	uint16_t vdd_mv; ++ ++	union dimm_flags_ddr3_st flags; ++ ++	/* Except for tCK, everything is stored in DCLKs */ ++	uint32_t tCK; ++	uint32_t tAA; ++	uint32_t tWR; ++	uint32_t tRCD; ++	uint32_t tRRD; ++	uint32_t tRP; ++	uint32_t tRAS; ++	uint32_t tRC; ++	uint32_t tRFC; ++	uint32_t tWTR; ++	uint32_t tRTP; ++	uint32_t tFAW; ++	uint32_t tCWL; ++	uint32_t tCMD; ++ ++	uint32_t tREFI; ++	uint32_t tXP; ++ ++	uint8_t lpddr_cke_rank_map[NUM_CHANNELS]; ++ ++	struct raminit_dimm_info dimms[NUM_CHANNELS][NUM_SLOTS]; ++ ++	uint8_t chanmap; ++ ++	uint32_t channel_size_mb[NUM_CHANNELS]; ++ ++	/* DIMMs per channel */ ++	uint8_t dpc[NUM_CHANNELS]; ++ ++	uint8_t rankmap[NUM_CHANNELS]; ++ ++	/* Whether a rank is mirrored or not (only rank 1 of each DIMM can be) */ ++	uint8_t rank_mirrored[NUM_CHANNELS]; ++ ++	/* ++	 * FIXME: LPDDR support is incomplete. The largest chunks are missing, ++	 * but some LPDDR-specific variations in algorithms have been handled. ++	 * LPDDR-specific functions have stubs which will halt upon execution. ++	 */ ++	bool lpddr; ++ ++	uint8_t lanes; ++ ++	/* FIXME: ECC support missing */ ++	bool is_ecc; ++}; ++ ++struct register_save_frame { ++	uint32_t ddrio_per_byte[NUM_CHANNELS][NUM_LANES][DDRIO_PER_BYTE_REGISTER_COUNT]; ++	uint32_t ddrio_per_ch[NUM_CHANNELS][DDRIO_PER_CH_REGISTER_COUNT]; ++	uint32_t ddrio_common[DDRIO_COMMON_REGISTER_COUNT]; ++	uint32_t mcmain_per_ch[NUM_CHANNELS][MCMAIN_PER_CH_REGISTER_COUNT]; ++	uint32_t misc_common[MISC_COMMON_REGISTER_COUNT]; ++	struct save_params params; ++}; ++ ++struct register_save_frame *reg_frame_ptr(void) ++{ ++	/* The chonky register save frame struct, used for fast boot and S3 resume */ ++	static struct register_save_frame register_frame = { 0 }; ++	return ®ister_frame; ++} ++ ++size_t reg_frame_size(void) ++{ ++	return sizeof(struct register_save_frame); ++} ++ ++typedef void (*reg_func_t)(const uint16_t offset, uint32_t *const value); ++ ++static void save_value(const uint16_t offset, uint32_t *const value) ++{ ++	*value = mchbar_read32(offset); ++} ++ ++static void restore_value(const uint16_t offset, uint32_t *const value) ++{ ++	mchbar_write32(offset, *value); ++} ++ ++static void save_restore( ++	uint32_t *reg_frame, ++	const uint16_t g_offset, ++	const struct register_save *reg_save_list, ++	const size_t reg_save_length, ++	reg_func_t handle_reg) ++{ ++	for (size_t i = 0; i < reg_save_length; i++) { ++		const struct register_save *entry = ®_save_list[i]; ++		for (uint16_t offset = entry->lower; offset <= entry->upper; offset += 4) { ++			handle_reg(offset + g_offset, reg_frame++); ++		} ++	} ++} ++ ++static void save_restore_all(struct register_save_frame *reg_frame, reg_func_t handle_reg) ++{ ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		for (uint8_t byte = 0; byte < NUM_LANES; byte++) { ++			const uint16_t g_offset = _DDRIO_C_R_B(0, channel, 0, byte); ++			save_restore( ++				reg_frame->ddrio_per_byte[channel][byte], ++				g_offset, ++				ddrio_per_byte_list, ++				ARRAY_SIZE(ddrio_per_byte_list), ++				handle_reg); ++		} ++	} ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		const uint16_t g_offset = _DDRIO_C_R_B(0, channel, 0, 0); ++		save_restore( ++			reg_frame->ddrio_per_ch[channel], ++			g_offset, ++			ddrio_per_ch_list, ++			ARRAY_SIZE(ddrio_per_ch_list), ++			handle_reg); ++	} ++	save_restore( ++		reg_frame->ddrio_common, ++		0, ++		ddrio_common_list, ++		ARRAY_SIZE(ddrio_common_list), ++		handle_reg); ++ ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		const uint16_t g_offset = _MCMAIN_C(0, channel); ++		save_restore( ++			reg_frame->mcmain_per_ch[channel], ++			g_offset, ++			mcmain_per_ch_list, ++			ARRAY_SIZE(mcmain_per_ch_list), ++			handle_reg); ++	} ++	save_restore( ++		reg_frame->misc_common, ++		0, ++		misc_common_list, ++		ARRAY_SIZE(misc_common_list), ++		handle_reg); ++} ++ ++enum raminit_status save_training_values(struct sysinfo *ctrl) ++{ ++	save_restore_all(reg_frame_ptr(), save_value); ++	return RAMINIT_STATUS_SUCCESS; ++} ++ ++enum raminit_status restore_training_values(struct sysinfo *ctrl) ++{ ++	save_restore_all(reg_frame_ptr(), restore_value); ++	return RAMINIT_STATUS_SUCCESS; ++} ++ ++enum raminit_status save_non_training(struct sysinfo *ctrl) ++{ ++	struct register_save_frame *reg_frame = reg_frame_ptr(); ++	struct save_params *params = ®_frame->params; ++ ++	params->is_initialised = true; ++ ++	params->base_freq     = ctrl->base_freq; ++	params->multiplier    = ctrl->multiplier; ++	params->mem_clock_mhz = ctrl->mem_clock_mhz; ++	params->mem_clock_fs  = ctrl->mem_clock_fs; ++	params->qclkps        = ctrl->qclkps; ++	params->cas_supported = ctrl->cas_supported; ++	params->cpu           = ctrl->cpu; ++	params->stepping      = ctrl->stepping; ++	params->vdd_mv        = ctrl->vdd_mv; ++	params->flags         = ctrl->flags; ++ ++	params->tCK       = ctrl->tCK; ++	params->tAA       = ctrl->tAA; ++	params->tWR       = ctrl->tWR; ++	params->tRCD      = ctrl->tRCD; ++	params->tRRD      = ctrl->tRRD; ++	params->tRP       = ctrl->tRP; ++	params->tRAS      = ctrl->tRAS; ++	params->tRC       = ctrl->tRC; ++	params->tRFC      = ctrl->tRFC; ++	params->tWTR      = ctrl->tWTR; ++	params->tRTP      = ctrl->tRTP; ++	params->tFAW      = ctrl->tFAW; ++	params->tCWL      = ctrl->tCWL; ++	params->tCMD      = ctrl->tCMD; ++	params->tREFI     = ctrl->tREFI; ++	params->tXP       = ctrl->tXP; ++ ++	params->chanmap = ctrl->chanmap; ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		params->lpddr_cke_rank_map[channel] = ctrl->lpddr_cke_rank_map[channel]; ++		for (uint8_t slot = 0; slot < NUM_SLOTS; slot++) ++			params->dimms[channel][slot] = ctrl->dimms[channel][slot]; ++	} ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		params->dpc[channel] = ctrl->dpc[channel]; ++		params->rankmap[channel] = ctrl->rankmap[channel]; ++		params->rank_mirrored[channel] = ctrl->rank_mirrored[channel]; ++		params->channel_size_mb[channel] = ctrl->channel_size_mb[channel]; ++	} ++	params->lpddr = ctrl->lpddr; ++	params->lanes = ctrl->lanes; ++	params->is_ecc = ctrl->is_ecc; ++	return RAMINIT_STATUS_SUCCESS; ++} ++ ++#define RAMINIT_COMPARE(_s1, _s2) \ ++	((sizeof(_s1) == sizeof(_s2)) && !memcmp(_s1, _s2, sizeof(_s1))) ++ ++enum raminit_status restore_non_training(struct sysinfo *ctrl) ++{ ++	struct register_save_frame *reg_frame = reg_frame_ptr(); ++	struct save_params *params = ®_frame->params; ++ ++	if (!params->is_initialised) { ++		printk(BIOS_WARNING, "Cannot fast boot: saved data is invalid\n"); ++		return RAMINIT_STATUS_INVALID_CACHE; ++	} ++ ++	if (!RAMINIT_COMPARE(ctrl->dimms, params->dimms)) { ++		printk(BIOS_WARNING, "Cannot fast boot: DIMMs have changed\n"); ++		return RAMINIT_STATUS_INVALID_CACHE; ++	} ++ ++	if (ctrl->cpu != params->cpu) { ++		printk(BIOS_WARNING, "Cannot fast boot: CPU has changed\n"); ++		return RAMINIT_STATUS_INVALID_CACHE; ++	} ++ ++	ctrl->base_freq     = params->base_freq; ++	ctrl->multiplier    = params->multiplier; ++	ctrl->mem_clock_mhz = params->mem_clock_mhz; ++	ctrl->mem_clock_fs  = params->mem_clock_fs; ++	ctrl->qclkps        = params->qclkps; ++	ctrl->cas_supported = params->cas_supported; ++	ctrl->cpu           = params->cpu; ++	ctrl->stepping      = params->stepping; ++	ctrl->vdd_mv        = params->vdd_mv; ++	ctrl->flags         = params->flags; ++ ++	ctrl->tCK       = params->tCK; ++	ctrl->tAA       = params->tAA; ++	ctrl->tWR       = params->tWR; ++	ctrl->tRCD      = params->tRCD; ++	ctrl->tRRD      = params->tRRD; ++	ctrl->tRP       = params->tRP; ++	ctrl->tRAS      = params->tRAS; ++	ctrl->tRC       = params->tRC; ++	ctrl->tRFC      = params->tRFC; ++	ctrl->tWTR      = params->tWTR; ++	ctrl->tRTP      = params->tRTP; ++	ctrl->tFAW      = params->tFAW; ++	ctrl->tCWL      = params->tCWL; ++	ctrl->tCMD      = params->tCMD; ++	ctrl->tREFI     = params->tREFI; ++	ctrl->tXP       = params->tXP; ++ ++	ctrl->chanmap = params->chanmap; ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		ctrl->lpddr_cke_rank_map[channel] = params->lpddr_cke_rank_map[channel]; ++		for (uint8_t slot = 0; slot < NUM_SLOTS; slot++) ++			ctrl->dimms[channel][slot] = params->dimms[channel][slot]; ++	} ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		ctrl->dpc[channel] = params->dpc[channel]; ++		ctrl->rankmap[channel] = params->rankmap[channel]; ++		ctrl->rank_mirrored[channel] = params->rank_mirrored[channel]; ++		ctrl->channel_size_mb[channel] = params->channel_size_mb[channel]; ++	} ++	ctrl->lpddr = params->lpddr; ++	ctrl->lanes = params->lanes; ++	ctrl->is_ecc = params->is_ecc; ++	return RAMINIT_STATUS_SUCCESS; ++} +--  +2.39.2 + diff --git a/config/coreboot/haswell/patches/0017-haswell-NRI-Do-sense-amplifier-offset-training.patch b/config/coreboot/haswell/patches/0017-haswell-NRI-Do-sense-amplifier-offset-training.patch new file mode 100644 index 00000000..846fe9a3 --- /dev/null +++ b/config/coreboot/haswell/patches/0017-haswell-NRI-Do-sense-amplifier-offset-training.patch @@ -0,0 +1,476 @@ +From be58501141aa97aa544b670e566cd6cf6797c18e Mon Sep 17 00:00:00 2001 +From: Angel Pons <th3fanbus@gmail.com> +Date: Wed, 17 Apr 2024 13:20:32 +0200 +Subject: [PATCH 17/20] haswell NRI: Do sense amplifier offset training + +Quoting Wikipedia: + +  A sense amplifier is a circuit that is used to amplify and detect +  small signals in electronic systems. It is commonly used in memory +  circuits, such as dynamic random access memory (DRAM), to read and +  amplify the weak signals stored in memory cells. + +In this case, we're calibrating the sense amplifiers in the memory +controller. This training procedure uses a magic "sense amp offset +cancel" mode of the DDRIO to observe the sampled logic levels, and +sweeps Vref to find the low-high transition for each bit lane. The +procedure consists of two stages: the first stage centers per-byte +Vref (to ensure per-bit Vref offsets are as small as possible) and +the second stage centers per-bit Vref. + +Because this procedure uses the "sense amp offset cancel" mode, it +does not rely on DRAM being trained. It is assumed that the memory +controller simply makes sense amp output levels observable via the +`DDR_DATA_TRAIN_FEEDBACK` register and that the memory bus is idle +during this training step (so the lane voltage is Vdd / 2). + +Note: This procedure will need to be adapted for Broadwell because +it has per-rank per-bit RxVref registers, whereas Haswell only has +a single per-bit RxVref register for all ranks. + +Change-Id: Ia07db68763f90e9701c8a376e01279ada8dbbe07 +Signed-off-by: Angel Pons <th3fanbus@gmail.com> +--- + .../intel/haswell/native_raminit/Makefile.mk  |   1 + + .../haswell/native_raminit/raminit_main.c     |   1 + + .../haswell/native_raminit/raminit_native.h   |  12 + + .../native_raminit/train_sense_amp_offset.c   | 341 ++++++++++++++++++ + .../intel/haswell/registers/mchbar.h          |   2 + + 5 files changed, 357 insertions(+) + create mode 100644 src/northbridge/intel/haswell/native_raminit/train_sense_amp_offset.c + +diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk +index 8fdd17c542..4bd668a2d6 100644 +--- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk ++++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk +@@ -21,3 +21,4 @@ romstage-y += timings_refresh.c + 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 +diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c +index 056dde1adc..ce637e2d03 100644 +--- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c ++++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c +@@ -60,6 +60,7 @@ static const struct task_entry cold_boot[] = { + 	{ configure_memory_map,                                   true, "MEMMAP",     }, + 	{ do_jedec_init,                                          true, "JEDECINIT",  }, + 	{ pre_training,                                           true, "PRETRAIN",   }, ++	{ train_sense_amp_offset,                                 true, "SOT",        }, + 	{ train_receive_enable,                                   true, "RCVET",      }, + 	{ train_read_mpr,                                         true, "RDMPRT",     }, + 	{ train_jedec_write_leveling,                             true, "JWRL",       }, +diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h +index 0750904aec..95ccd0a8b3 100644 +--- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h ++++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h +@@ -22,6 +22,8 @@ + #define NUM_LANES		9 + #define NUM_LANES_NO_ECC	8 +  ++#define NUM_BITS		8 ++ + #define COMP_INT		10 +  + /* Always use 12 legs for emphasis (not trained) */ +@@ -218,6 +220,7 @@ enum raminit_status { + 	RAMINIT_STATUS_MPLL_INIT_FAILURE, + 	RAMINIT_STATUS_POLL_TIMEOUT, + 	RAMINIT_STATUS_REUT_ERROR, ++	RAMINIT_STATUS_SAMP_OFFSET_FAILURE, + 	RAMINIT_STATUS_RCVEN_FAILURE, + 	RAMINIT_STATUS_RMPR_FAILURE, + 	RAMINIT_STATUS_JWRL_FAILURE, +@@ -243,6 +246,12 @@ struct raminit_dimm_info { + 	bool valid; + }; +  ++struct vref_margin { ++	uint8_t low; ++	uint8_t center; ++	uint8_t high; ++}; ++ + struct sysinfo { + 	enum raminit_boot_mode bootmode; + 	enum generic_stepping stepping; +@@ -330,6 +339,8 @@ struct sysinfo { + 	uint8_t rxdqsn[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES]; + 	int8_t  rxvref[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES]; +  ++	struct vref_margin rxdqvrefpb[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES][NUM_BITS]; ++ + 	uint8_t clk_pi_code[NUM_CHANNELS][NUM_SLOTRANKS]; + 	uint8_t ctl_pi_code[NUM_CHANNELS][NUM_SLOTRANKS]; + 	uint8_t cke_pi_code[NUM_CHANNELS][NUM_SLOTRANKS]; +@@ -452,6 +463,7 @@ enum raminit_status convert_timings(struct sysinfo *ctrl); + enum raminit_status configure_mc(struct sysinfo *ctrl); + enum raminit_status configure_memory_map(struct sysinfo *ctrl); + enum raminit_status do_jedec_init(struct sysinfo *ctrl); ++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); +diff --git a/src/northbridge/intel/haswell/native_raminit/train_sense_amp_offset.c b/src/northbridge/intel/haswell/native_raminit/train_sense_amp_offset.c +new file mode 100644 +index 0000000000..d4f199fefb +--- /dev/null ++++ b/src/northbridge/intel/haswell/native_raminit/train_sense_amp_offset.c +@@ -0,0 +1,341 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#include <assert.h> ++#include <commonlib/bsd/clamp.h> ++#include <console/console.h> ++#include <delay.h> ++#include <lib.h> ++#include <types.h> ++ ++#include "raminit_native.h" ++ ++#define VREF_OFFSET_PLOT	RAM_DEBUG ++#define SAMP_OFFSET_PLOT	RAM_DEBUG ++ ++struct vref_train_data { ++	int8_t best_sum; ++	int8_t best_vref; ++	int8_t sum_bits; ++	uint8_t high_mask; ++	uint8_t low_mask; ++}; ++ ++static enum raminit_status train_vref_offset(struct sysinfo *ctrl) ++{ ++	const int8_t vref_start = -15; ++	const int8_t vref_stop  = 15; ++	const struct vref_train_data initial_vref_values = { ++		.best_sum  = -NUM_LANES, ++		.best_vref = 0, ++		.high_mask = 0, ++		.low_mask  = 0xff, ++	}; ++	struct vref_train_data vref_data[NUM_CHANNELS][NUM_LANES]; ++ ++	printk(VREF_OFFSET_PLOT, "Plot of sum_bits across Vref settings\nChannel"); ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		if (!does_ch_exist(ctrl, channel)) ++			continue; ++ ++		printk(VREF_OFFSET_PLOT, "\t%u\t\t", channel); ++	} ++ ++	printk(VREF_OFFSET_PLOT, "\nByte"); ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		if (!does_ch_exist(ctrl, channel)) ++			continue; ++ ++		printk(VREF_OFFSET_PLOT, "\t"); ++		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { ++			printk(VREF_OFFSET_PLOT, "%u ", byte); ++			vref_data[channel][byte] = initial_vref_values; ++			union ddr_data_control_2_reg data_control_2 = { ++				.raw = ctrl->dq_control_2[channel][byte], ++			}; ++			data_control_2.force_bias_on = 1; ++			data_control_2.force_rx_on   = 1; ++			mchbar_write32(DQ_CONTROL_2(channel, byte), data_control_2.raw); ++		} ++	} ++ ++	/* Sweep through Vref settings and find point SampOffset of +/- 7 passes */ ++	printk(VREF_OFFSET_PLOT, "\n1/2 Vref"); ++	for (int8_t vref = vref_start; vref <= vref_stop; vref++) { ++		printk(VREF_OFFSET_PLOT, "\n% 3d", vref); ++ ++		/* ++		 * To perform this test, enable offset cancel mode and enable ODT. ++		 * Check results and update variables. Ideal result is all zeroes. ++		 * Clear offset cancel mode at end of test to write RX_OFFSET_VDQ. ++		 */ ++		change_1d_margin_multicast(ctrl, RdV, vref, 0, false, REG_FILE_USE_RANK); ++ ++		/* Program settings for Vref and SampOffset = 7 (8 + 7) */ ++		mchbar_write32(DDR_DATA_RX_OFFSET_VDQ, 0xffffffff); ++		for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++			if (!does_ch_exist(ctrl, channel)) ++				continue; ++ ++			/* Propagate delay values (without a read command) */ ++			union ddr_data_control_0_reg data_control_0 = { ++				.raw = ctrl->dq_control_0[channel], ++			}; ++			data_control_0.read_rf_rd      = 1; ++			data_control_0.read_rf_wr      = 0; ++			data_control_0.read_rf_rank    = 0; ++			data_control_0.force_odt_on    = 1; ++			data_control_0.samp_train_mode = 1; ++			mchbar_write32(DDR_DATA_ch_CONTROL_0(channel), data_control_0.raw); ++			udelay(1); ++			data_control_0.samp_train_mode = 0; ++			mchbar_write32(DDR_DATA_ch_CONTROL_0(channel), data_control_0.raw); ++			for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { ++				const uint8_t feedback = get_data_train_feedback(channel, byte); ++				struct vref_train_data *curr_data = &vref_data[channel][byte]; ++				curr_data->low_mask &= feedback; ++				curr_data->sum_bits = -popcnt(feedback); ++			} ++		} ++ ++		/* Program settings for Vref and SampOffset = -7 (8 - 7) */ ++		mchbar_write32(DDR_DATA_RX_OFFSET_VDQ, 0x11111111); ++		for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++			if (!does_ch_exist(ctrl, channel)) ++				continue; ++ ++			/* Propagate delay values (without a read command) */ ++			union ddr_data_control_0_reg data_control_0 = { ++				.raw = ctrl->dq_control_0[channel], ++			}; ++			data_control_0.read_rf_rd      = 1; ++			data_control_0.read_rf_wr      = 0; ++			data_control_0.read_rf_rank    = 0; ++			data_control_0.force_odt_on    = 1; ++			data_control_0.samp_train_mode = 1; ++			mchbar_write32(DDR_DATA_ch_CONTROL_0(channel), data_control_0.raw); ++			udelay(1); ++			data_control_0.samp_train_mode = 0; ++			mchbar_write32(DDR_DATA_ch_CONTROL_0(channel), data_control_0.raw); ++			printk(VREF_OFFSET_PLOT, "\t"); ++			for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { ++				const uint8_t feedback = get_data_train_feedback(channel, byte); ++				struct vref_train_data *curr_data = &vref_data[channel][byte]; ++				curr_data->high_mask |= feedback; ++				curr_data->sum_bits += popcnt(feedback); ++				printk(VREF_OFFSET_PLOT, "%d ", curr_data->sum_bits); ++				if (curr_data->sum_bits > curr_data->best_sum) { ++					curr_data->best_sum  = curr_data->sum_bits; ++					curr_data->best_vref = vref; ++					ctrl->rxvref[channel][0][byte] = vref; ++				} else if (curr_data->sum_bits == curr_data->best_sum) { ++					curr_data->best_vref = vref; ++				} ++			} ++		} ++	} ++	printk(BIOS_DEBUG, "\n\nHi-Lo (XOR):"); ++	enum raminit_status status = RAMINIT_STATUS_SUCCESS; ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		if (!does_ch_exist(ctrl, channel)) ++			continue; ++ ++		printk(BIOS_DEBUG, "\n  C%u:", channel); ++		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { ++			struct vref_train_data *const curr_data = &vref_data[channel][byte]; ++			const uint8_t bit_xor = curr_data->high_mask ^ curr_data->low_mask; ++			printk(BIOS_DEBUG, "\t0x%02x", bit_xor); ++			if (bit_xor == 0xff) ++				continue; ++ ++			/* Report an error if any bit did not change */ ++			status = RAMINIT_STATUS_SAMP_OFFSET_FAILURE; ++		} ++	} ++	if (status) ++		printk(BIOS_ERR, "\nUnexpected bit error in Vref offset training\n"); ++ ++	printk(BIOS_DEBUG, "\n\nRdVref:"); ++	change_1d_margin_multicast(ctrl, RdV, 0, 0, false, REG_FILE_USE_RANK); ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		if (!does_ch_exist(ctrl, channel)) ++			continue; ++ ++		printk(BIOS_DEBUG, "\n  C%u:", channel); ++		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { ++			struct vref_train_data *const curr_data = &vref_data[channel][byte]; ++			const int8_t vref_width = ++				curr_data->best_vref - ctrl->rxvref[channel][0][byte]; ++ ++			/* ++			 * Step size for Rx Vref in DATA_OFFSET_TRAIN is about 3.9 mV ++			 * whereas Rx Vref step size in RX_TRAIN_RANK is about 7.8 mV ++			 */ ++			int8_t vref = ctrl->rxvref[channel][0][byte] + vref_width / 2; ++			if (vref < 0) ++				vref--; ++			else ++				vref++; ++ ++			for (uint8_t rank = 0; rank < NUM_SLOTRANKS; rank++) { ++				if (!rank_in_ch(ctrl, rank, channel)) ++					continue; ++ ++				ctrl->rxvref[channel][rank][byte] = vref / 2; ++				update_rxt(ctrl, channel, rank, byte, RXT_RESTORE, 0); ++			} ++			printk(BIOS_DEBUG, "\t% 4d", ctrl->rxvref[channel][0][byte]); ++		} ++	} ++	printk(BIOS_DEBUG, "\n\n"); ++	return status; ++} ++ ++/** ++ * LPDDR has an additional bit for DQS per each byte. ++ * ++ * TODO: The DQS value must be written into Data Control 2. ++ */ ++#define NUM_OFFSET_TRAIN_BITS	(NUM_BITS + 1) ++ ++#define PLOT_CH_SPACE		"  " ++ ++struct samp_train_data { ++	uint8_t first_zero; ++	uint8_t last_one; ++}; ++ ++static void train_samp_offset(struct sysinfo *ctrl) ++{ ++	const uint8_t max_train_bits = ctrl->lpddr ? NUM_OFFSET_TRAIN_BITS : NUM_BITS; ++ ++	struct samp_train_data samp_data[NUM_CHANNELS][NUM_LANES][NUM_OFFSET_TRAIN_BITS] = {0}; ++ ++	printk(BIOS_DEBUG, "Channel "); ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		if (!does_ch_exist(ctrl, channel)) ++			continue; ++ ++		printk(BIOS_DEBUG, "%u ", channel); /* Same length as PLOT_CH_SPACE */ ++		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) ++			printk(BIOS_DEBUG, "        %s ", ctrl->lpddr ? " " : ""); ++	} ++	printk(BIOS_DEBUG, "\nByte    "); ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		if (!does_ch_exist(ctrl, channel)) ++			continue; ++ ++		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) ++			printk(BIOS_DEBUG, "%u       %s ", byte, ctrl->lpddr ? " " : ""); ++ ++		printk(BIOS_DEBUG, PLOT_CH_SPACE); ++	} ++	printk(SAMP_OFFSET_PLOT, "\nBits    "); ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) ++			printk(SAMP_OFFSET_PLOT, "01234567%s ", ctrl->lpddr ? "S" : ""); ++ ++		printk(SAMP_OFFSET_PLOT, PLOT_CH_SPACE); ++	} ++	printk(SAMP_OFFSET_PLOT, "\n SAmp\n"); ++	for (uint8_t samp_offset = 1; samp_offset <= 15; samp_offset++) { ++		printk(SAMP_OFFSET_PLOT, "% 5d\t", samp_offset); ++ ++		uint32_t rx_offset_vdq = 0; ++		for (uint8_t bit = 0; bit < NUM_BITS; bit++) { ++			rx_offset_vdq += samp_offset << (4 * bit); ++		} ++		mchbar_write32(DDR_DATA_RX_OFFSET_VDQ, rx_offset_vdq); ++		for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++			if (!does_ch_exist(ctrl, channel)) ++				continue; ++ ++			/* Propagate delay values (without a read command) */ ++			union ddr_data_control_0_reg data_control_0 = { ++				.raw = ctrl->dq_control_0[channel], ++			}; ++			data_control_0.read_rf_rd      = 1; ++			data_control_0.read_rf_wr      = 0; ++			data_control_0.read_rf_rank    = 0; ++			data_control_0.force_odt_on    = 1; ++			data_control_0.samp_train_mode = 1; ++			mchbar_write32(DDR_DATA_ch_CONTROL_0(channel), data_control_0.raw); ++			udelay(1); ++			for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { ++				const uint32_t feedback = ++					get_data_train_feedback(channel, byte); ++ ++				for (uint8_t bit = 0; bit < max_train_bits; bit++) { ++					struct samp_train_data *const curr_data = ++							&samp_data[channel][byte][bit]; ++					const bool result = feedback & BIT(bit); ++					if (result) { ++						curr_data->last_one = samp_offset; ++					} else if (curr_data->first_zero == 0) { ++						curr_data->first_zero = samp_offset; ++					} ++					printk(SAMP_OFFSET_PLOT, result ? "." : "#"); ++				} ++				printk(SAMP_OFFSET_PLOT, " "); ++			} ++			printk(SAMP_OFFSET_PLOT, PLOT_CH_SPACE); ++			data_control_0.samp_train_mode = 0; ++			mchbar_write32(DDR_DATA_ch_CONTROL_0(channel), data_control_0.raw); ++		} ++		printk(SAMP_OFFSET_PLOT, "\n"); ++	} ++	printk(BIOS_DEBUG, "\nBitSAmp "); ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		if (!does_ch_exist(ctrl, channel)) ++			continue; ++ ++		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { ++			uint32_t rx_offset_vdq = 0; ++			for (uint8_t bit = 0; bit < max_train_bits; bit++) { ++				struct samp_train_data *const curr_data = ++						&samp_data[channel][byte][bit]; ++ ++				uint8_t vref = curr_data->first_zero + curr_data->last_one; ++				vref = clamp_u8(0, vref / 2, 15); ++				/* ++				 * Check for saturation conditions to make sure ++				 * we are as close as possible to Vdd/2 (750 mV). ++				 */ ++				if (curr_data->first_zero == 0) ++					vref = 15; ++				if (curr_data->last_one == 0) ++					vref = 0; ++ ++				ctrl->rxdqvrefpb[channel][0][byte][bit].center = vref; ++				rx_offset_vdq += vref & 0xf << (4 * bit); ++				printk(BIOS_DEBUG, "%x", vref); ++			} ++			mchbar_write32(RX_OFFSET_VDQ(channel, byte), rx_offset_vdq); ++			printk(BIOS_DEBUG, " "); ++			download_regfile(ctrl, channel, 1, 0, REG_FILE_USE_RANK, 0, 1, 0); ++		} ++		printk(BIOS_DEBUG, PLOT_CH_SPACE); ++	} ++	printk(BIOS_DEBUG, "\n"); ++} ++ ++enum raminit_status train_sense_amp_offset(struct sysinfo *ctrl) ++{ ++	printk(BIOS_DEBUG, "Stage 1: Vref offset training\n"); ++	const enum raminit_status status = train_vref_offset(ctrl); ++ ++	printk(BIOS_DEBUG, "Stage 2: Samp offset training\n"); ++	train_samp_offset(ctrl); ++ ++	/* Clean up after test */ ++	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { ++		if (!does_ch_exist(ctrl, channel)) ++			continue; ++ ++		mchbar_write32(DDR_DATA_ch_CONTROL_0(channel), ctrl->dq_control_0[channel]); ++		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) ++			mchbar_write32(DQ_CONTROL_2(channel, byte), ++				ctrl->dq_control_2[channel][byte]); ++	} ++	io_reset(); ++	return status; ++} +diff --git a/src/northbridge/intel/haswell/registers/mchbar.h b/src/northbridge/intel/haswell/registers/mchbar.h +index 49a215aa71..1a168a3fc8 100644 +--- a/src/northbridge/intel/haswell/registers/mchbar.h ++++ b/src/northbridge/intel/haswell/registers/mchbar.h +@@ -18,6 +18,8 @@ + #define RX_TRAIN_ch_r_b(ch, rank, byte)		_DDRIO_C_R_B(0x0000, ch, rank, byte) + #define TX_TRAIN_ch_r_b(ch, rank, byte)		_DDRIO_C_R_B(0x0020, ch, rank, byte) +  ++#define RX_OFFSET_VDQ(ch, byte)			_DDRIO_C_R_B(0x004c, ch, 0, byte) ++ + #define DDR_DATA_TRAIN_FEEDBACK(ch, byte)	_DDRIO_C_R_B(0x0054, ch, 0, byte) +  + #define DQ_CONTROL_1(ch, byte)			_DDRIO_C_R_B(0x0060, ch, 0, byte) +--  +2.39.2 + diff --git a/config/coreboot/haswell/patches/0026-Remove-warning-for-coreboot-images-built-without-a-p.patch b/config/coreboot/haswell/patches/0018-Remove-warning-for-coreboot-images-built-without-a-p.patch index 547c6392..34309242 100644 --- a/config/coreboot/haswell/patches/0026-Remove-warning-for-coreboot-images-built-without-a-p.patch +++ b/config/coreboot/haswell/patches/0018-Remove-warning-for-coreboot-images-built-without-a-p.patch @@ -1,26 +1,27 @@ -From 1ce4f118b024a6367382b46016781f30fe622e3e Mon Sep 17 00:00:00 2001 +From c25dcd8ac80598939edffd011df0fd9ba3d8a1a8 Mon Sep 17 00:00:00 2001  From: Nicholas Chin <nic.c3.14@gmail.com>  Date: Fri, 12 May 2023 19:55:15 -0600 -Subject: [PATCH] Remove warning for coreboot images built without a payload +Subject: [PATCH 18/20] Remove warning for coreboot images built without a + payload  I added this in upstream to prevent people from accidentally flashing  roms without a payload resulting in a no boot situation, but in  libreboot lbmk handles the payload and thus this warning always comes  up. This has caused confusion and concern so just patch it out.  --- - payloads/Makefile.inc | 13 +------------ + payloads/Makefile.mk | 13 +------------   1 file changed, 1 insertion(+), 12 deletions(-) -diff --git a/payloads/Makefile.inc b/payloads/Makefile.inc -index e735443a76..4f1692a873 100644 ---- a/payloads/Makefile.inc -+++ b/payloads/Makefile.inc +diff --git a/payloads/Makefile.mk b/payloads/Makefile.mk +index a2336aa876..4f1692a873 100644 +--- a/payloads/Makefile.mk ++++ b/payloads/Makefile.mk  @@ -49,16 +49,5 @@ distclean-payloads:   print-repo-info-payloads:   	-$(foreach payload, $(PAYLOADS_LIST), $(MAKE) -C $(payload) print-repo-info 2>/dev/null; )  -ifeq ($(CONFIG_PAYLOAD_NONE),y) --files_added:: warn_no_payload +-show_notices:: warn_no_payload  -endif  -  -warn_no_payload: @@ -34,5 +35,5 @@ index e735443a76..4f1692a873 100644  -.PHONY: clean-payloads distclean-payloads print-repo-info-payloads warn_no_payload  +.PHONY: clean-payloads distclean-payloads print-repo-info-payloads  --  -2.40.1 +2.39.2 diff --git a/config/coreboot/haswell/patches/0019-use-mirrorservice.org-for-gcc-downloads.patch b/config/coreboot/haswell/patches/0019-use-mirrorservice.org-for-gcc-downloads.patch new file mode 100644 index 00000000..e197b3f3 --- /dev/null +++ b/config/coreboot/haswell/patches/0019-use-mirrorservice.org-for-gcc-downloads.patch @@ -0,0 +1,36 @@ +From 081890bab8d454247b6f7e9cb209f46159c45c8b Mon Sep 17 00:00:00 2001 +From: Leah Rowe <leah@libreboot.org> +Date: Sun, 5 Nov 2023 23:19:42 +0000 +Subject: [PATCH 19/20] use mirrorservice.org for gcc downloads + +the gnu.org 302 redirect often fails + +Signed-off-by: Leah Rowe <leah@libreboot.org> +--- + util/crossgcc/buildgcc | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc +index 0a0462e2f6..6ae201239d 100755 +--- a/util/crossgcc/buildgcc ++++ b/util/crossgcc/buildgcc +@@ -69,11 +69,11 @@ NASM_ARCHIVE="nasm-${NASM_VERSION}.tar.bz2" + # to the jenkins build as well, or the builder won't download it. +  + # GCC toolchain archive locations +-GMP_BASE_URL="https://ftpmirror.gnu.org/gmp" +-MPFR_BASE_URL="https://ftpmirror.gnu.org/mpfr" +-MPC_BASE_URL="https://ftpmirror.gnu.org/mpc" +-GCC_BASE_URL="https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}" +-BINUTILS_BASE_URL="https://ftpmirror.gnu.org/binutils" ++GMP_BASE_URL="https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/gmp" ++MPFR_BASE_URL="https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/mpfr" ++MPC_BASE_URL="https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/mpc" ++GCC_BASE_URL="https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}" ++BINUTILS_BASE_URL="https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/binutils" + IASL_BASE_URL="https://github.com/acpica/acpica/archive/refs/tags" + # CLANG toolchain archive locations + LLVM_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" +--  +2.39.2 + diff --git a/config/coreboot/haswell/patches/0020-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch b/config/coreboot/haswell/patches/0020-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch new file mode 100644 index 00000000..60490608 --- /dev/null +++ b/config/coreboot/haswell/patches/0020-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch @@ -0,0 +1,204 @@ +From 1a4f454e05b613cb080cdd063dd3efb1fdbb748b Mon Sep 17 00:00:00 2001 +From: Leah Rowe <leah@libreboot.org> +Date: Sun, 19 Feb 2023 18:21:43 +0000 +Subject: [PATCH 20/20] util/ifdtool: add --nuke flag (all 0xFF on region) + +When this option is used, the region's contents are overwritten +with all ones (0xFF). + +Example: + +./ifdtool --nuke gbe coreboot.rom +./ifdtool --nuke bios coreboot.com +./ifdtool --nuke me coreboot.com + +Rebased since the last revision update in lbmk. + +Signed-off-by: Leah Rowe <leah@libreboot.org> +--- + util/ifdtool/ifdtool.c | 113 ++++++++++++++++++++++++++++++----------- + 1 file changed, 82 insertions(+), 31 deletions(-) + +diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c +index 516570e0a3..1638e1710e 100644 +--- a/util/ifdtool/ifdtool.c ++++ b/util/ifdtool/ifdtool.c +@@ -2143,6 +2143,7 @@ static void print_usage(const char *name) + 	       "                                         tgl    - Tiger Lake\n" + 	       "                                         wbg    - Wellsburg\n" + 	       "   -S | --setpchstrap                    Write a PCH strap\n" ++	       "   -N | --nuke <region>                  Overwrite the specified region with 0xFF (all ones)\n" + 	       "   -V | --newvalue                       The new value to write into PCH strap specified by -S\n" + 	       "   -v | --version:                       print the version\n" + 	       "   -h | --help:                          print this help\n\n" +@@ -2151,6 +2152,60 @@ static void print_usage(const char *name) + 	       "\n"); + } +  ++static int ++get_region_type_string(const char *region_type_string) ++{ ++       if (!strcasecmp("Descriptor", region_type_string)) ++               return 0; ++       else if (!strcasecmp("BIOS", region_type_string)) ++               return 1; ++       else if (!strcasecmp("ME", region_type_string)) ++               return 2; ++       else if (!strcasecmp("GbE", region_type_string)) ++               return 3; ++       else if (!strcasecmp("Platform Data", region_type_string)) ++               return 4; ++       else if (!strcasecmp("Device Exp1", region_type_string)) ++               return 5; ++       else if (!strcasecmp("Secondary BIOS", region_type_string)) ++               return 6; ++       else if (!strcasecmp("Reserved", region_type_string)) ++               return 7; ++       else if (!strcasecmp("EC", region_type_string)) ++               return 8; ++       else if (!strcasecmp("Device Exp2", region_type_string)) ++               return 9; ++       else if (!strcasecmp("IE", region_type_string)) ++               return 10; ++       else if (!strcasecmp("10GbE_0", region_type_string)) ++               return 11; ++       else if (!strcasecmp("10GbE_1", region_type_string)) ++               return 12; ++       else if (!strcasecmp("PTT", region_type_string)) ++               return 15; ++       return -1; ++} ++ ++static void ++nuke(const char *filename, char *image, int size, int region_type) ++{ ++       int i; ++       struct region region; ++       const struct frba *frba = find_frba(image, size); ++       if (!frba) ++               exit(EXIT_FAILURE); ++ ++       region = get_region(frba, region_type); ++       if (region.size > 0) { ++               for (i = region.base; i <= region.limit; i++) { ++                       if ((i + 1) > (size)) ++                               break; ++                       image[i] = 0xFF; ++               } ++               write_image(filename, image, size); ++       } ++} ++ + int main(int argc, char *argv[]) + { + 	int opt, option_index = 0; +@@ -2158,6 +2213,7 @@ int main(int argc, char *argv[]) + 	int mode_em100 = 0, mode_locked = 0, mode_unlocked = 0, mode_validate = 0; + 	int mode_layout = 0, mode_newlayout = 0, mode_density = 0, mode_setstrap = 0; + 	int mode_read = 0, mode_altmedisable = 0, altmedisable = 0, mode_fmap_template = 0; ++	int mode_nuke = 0; + 	int mode_gpr0_disable = 0, mode_gpr0_enable = 0; + 	char *region_type_string = NULL, *region_fname = NULL; + 	const char *layout_fname = NULL; +@@ -2192,6 +2248,7 @@ int main(int argc, char *argv[]) + 		{"validate", 0, NULL, 't'}, + 		{"setpchstrap", 1, NULL, 'S'}, + 		{"newvalue", 1, NULL, 'V'}, ++		{"nuke", 1, NULL, 'N'}, + 		{0, 0, 0, 0} + 	}; +  +@@ -2241,35 +2298,8 @@ int main(int argc, char *argv[]) + 			region_fname++; + 			// Descriptor, BIOS, ME, GbE, Platform + 			// valid type? +-			if (!strcasecmp("Descriptor", region_type_string)) +-				region_type = 0; +-			else if (!strcasecmp("BIOS", region_type_string)) +-				region_type = 1; +-			else if (!strcasecmp("ME", region_type_string)) +-				region_type = 2; +-			else if (!strcasecmp("GbE", region_type_string)) +-				region_type = 3; +-			else if (!strcasecmp("Platform Data", region_type_string)) +-				region_type = 4; +-			else if (!strcasecmp("Device Exp1", region_type_string)) +-				region_type = 5; +-			else if (!strcasecmp("Secondary BIOS", region_type_string)) +-				region_type = 6; +-			else if (!strcasecmp("Reserved", region_type_string)) +-				region_type = 7; +-			else if (!strcasecmp("EC", region_type_string)) +-				region_type = 8; +-			else if (!strcasecmp("Device Exp2", region_type_string)) +-				region_type = 9; +-			else if (!strcasecmp("IE", region_type_string)) +-				region_type = 10; +-			else if (!strcasecmp("10GbE_0", region_type_string)) +-				region_type = 11; +-			else if (!strcasecmp("10GbE_1", region_type_string)) +-				region_type = 12; +-			else if (!strcasecmp("PTT", region_type_string)) +-				region_type = 15; +-			if (region_type == -1) { ++			if ((region_type = ++			    get_region_type_string(region_type_string)) == -1) { + 				fprintf(stderr, "No such region type: '%s'\n\n", + 					region_type_string); + 				fprintf(stderr, "run '%s -h' for usage\n", argv[0]); +@@ -2441,6 +2471,22 @@ int main(int argc, char *argv[]) + 		case 't': + 			mode_validate = 1; + 			break; ++               case 'N': ++                       region_type_string = strdup(optarg); ++                       if (!region_type_string) { ++                               fprintf(stderr, "No region specified\n"); ++                               print_usage(argv[0]); ++                               exit(EXIT_FAILURE); ++                       } ++                       if ((region_type = ++                           get_region_type_string(region_type_string)) == -1) { ++                               fprintf(stderr, "No such region type: '%s'\n\n", ++                                       region_type_string); ++                               print_usage(argv[0]); ++                               exit(EXIT_FAILURE); ++                       } ++                       mode_nuke = 1; ++                       break; + 		case 'v': + 			print_version(); + 			exit(EXIT_SUCCESS); +@@ -2457,7 +2503,7 @@ int main(int argc, char *argv[]) + 	if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject + + 			mode_setstrap + mode_newlayout + (mode_spifreq | mode_em100 | + 			mode_unlocked | mode_locked) + mode_altmedisable + mode_validate + +-			(mode_gpr0_disable | mode_gpr0_enable)) > 1) { ++			(mode_gpr0_disable | mode_gpr0_enable) + mode_nuke) > 1) { + 		fprintf(stderr, "You may not specify more than one mode.\n\n"); + 		fprintf(stderr, "run '%s -h' for usage\n", argv[0]); + 		exit(EXIT_FAILURE); +@@ -2466,7 +2512,8 @@ int main(int argc, char *argv[]) + 	if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject + + 			mode_setstrap + mode_newlayout + mode_spifreq + mode_em100 + + 			mode_locked + mode_unlocked + mode_density + mode_altmedisable + +-			mode_validate + (mode_gpr0_disable | mode_gpr0_enable)) == 0) { ++			mode_validate + (mode_gpr0_disable | mode_gpr0_enable) + ++			mode_nuke) == 0) { + 		fprintf(stderr, "You need to specify a mode.\n\n"); + 		fprintf(stderr, "run '%s -h' for usage\n", argv[0]); + 		exit(EXIT_FAILURE); +@@ -2576,6 +2623,10 @@ int main(int argc, char *argv[]) + 		write_image(new_filename, image, size); + 	} +  ++	if (mode_nuke) { ++		nuke(new_filename, image, size, region_type); ++	} ++ + 	if (mode_altmedisable) { + 		struct fpsba *fpsba = find_fpsba(image, size); + 		struct fmsba *fmsba = find_fmsba(image, size); +--  +2.39.2 + diff --git a/config/coreboot/haswell/patches/0027-coreboot-haswell-fix-acpica-downloads.patch b/config/coreboot/haswell/patches/0027-coreboot-haswell-fix-acpica-downloads.patch deleted file mode 100644 index 9f22c06d..00000000 --- a/config/coreboot/haswell/patches/0027-coreboot-haswell-fix-acpica-downloads.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 29c1116ebd5879568010a8386e4838294a78b408 Mon Sep 17 00:00:00 2001 -From: Leah Rowe <leah@libreboot.org> -Date: Sun, 16 Jul 2023 03:48:23 +0100 -Subject: [PATCH 1/1] coreboot/haswell: fix acpica downloads - -the upstream link died. i now host the relevant acpica -tarball myself, on libreboot rsync. this patch makes -coreboot crossgcc use that - -Signed-off-by: Leah Rowe <leah@libreboot.org> ---- - util/crossgcc/buildgcc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc -index 3c4b10cc92..0c4262b7b1 100755 ---- a/util/crossgcc/buildgcc -+++ b/util/crossgcc/buildgcc -@@ -52,7 +52,7 @@ MPFR_ARCHIVE="https://ftpmirror.gnu.org/mpfr/mpfr-${MPFR_VERSION}.tar.xz" - MPC_ARCHIVE="https://ftpmirror.gnu.org/mpc/mpc-${MPC_VERSION}.tar.gz" - GCC_ARCHIVE="https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.xz" - BINUTILS_ARCHIVE="https://ftpmirror.gnu.org/binutils/binutils-${BINUTILS_VERSION}.tar.xz" --IASL_ARCHIVE="https://acpica.org/sites/acpica/files/acpica-unix2-${IASL_VERSION}.tar.gz" -+IASL_ARCHIVE="https://www.mirrorservice.org/sites/libreboot.org/release/misc/acpica/acpica-unix2-${IASL_VERSION}.tar.gz" - # CLANG toolchain archive locations - LLVM_ARCHIVE="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}/llvm-${CLANG_VERSION}.src.tar.xz" - CLANG_ARCHIVE="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}/clang-${CLANG_VERSION}.src.tar.xz" ---  -2.40.1 - diff --git a/config/coreboot/haswell/patches/0028-use-mirrorservice.org-for-gcc-downloads.patch b/config/coreboot/haswell/patches/0028-use-mirrorservice.org-for-gcc-downloads.patch deleted file mode 100644 index 0d0a66a1..00000000 --- a/config/coreboot/haswell/patches/0028-use-mirrorservice.org-for-gcc-downloads.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ca1bd48a87ab46ebfb444b0e092442bf6270ec7a Mon Sep 17 00:00:00 2001 -From: Leah Rowe <leah@libreboot.org> -Date: Sun, 5 Nov 2023 23:19:42 +0000 -Subject: [PATCH 1/1] use mirrorservice.org for gcc downloads - -the gnu.org 302 redirect often fails - -Signed-off-by: Leah Rowe <leah@libreboot.org> ---- - util/crossgcc/buildgcc | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc -index d4cc8b2a24..526940acfa 100755 ---- a/util/crossgcc/buildgcc -+++ b/util/crossgcc/buildgcc -@@ -47,11 +47,11 @@ NASM_VERSION=2.15.05 - # These are sanitized by the jenkins toolchain test builder, so if - # a completely new URL is added here, it probably needs to be added - # to the jenkins build as well, or the builder won't download it. --GMP_ARCHIVE="https://ftpmirror.gnu.org/gmp/gmp-${GMP_VERSION}.tar.xz" --MPFR_ARCHIVE="https://ftpmirror.gnu.org/mpfr/mpfr-${MPFR_VERSION}.tar.xz" --MPC_ARCHIVE="https://ftpmirror.gnu.org/mpc/mpc-${MPC_VERSION}.tar.gz" --GCC_ARCHIVE="https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.xz" --BINUTILS_ARCHIVE="https://ftpmirror.gnu.org/binutils/binutils-${BINUTILS_VERSION}.tar.xz" -+GMP_ARCHIVE="https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/gmp/gmp-${GMP_VERSION}.tar.xz" -+MPFR_ARCHIVE="https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/mpfr/mpfr-${MPFR_VERSION}.tar.xz" -+MPC_ARCHIVE="https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/mpc/mpc-${MPC_VERSION}.tar.gz" -+GCC_ARCHIVE="https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.xz" -+BINUTILS_ARCHIVE="https://www.mirrorservice.org/sites/ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.xz" - IASL_ARCHIVE="https://www.mirrorservice.org/sites/libreboot.org/release/misc/acpica/acpica-unix2-${IASL_VERSION}.tar.gz" - # CLANG toolchain archive locations - LLVM_ARCHIVE="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}/llvm-${CLANG_VERSION}.src.tar.xz" ---  -2.39.2 - diff --git a/config/coreboot/haswell/patches/0029-ifdtool-nuke-option.patch b/config/coreboot/haswell/patches/0029-ifdtool-nuke-option.patch deleted file mode 100644 index 18d6a21e..00000000 --- a/config/coreboot/haswell/patches/0029-ifdtool-nuke-option.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 6f94e9aa38a5d6589b1a64642dfcb5ccbf90b8d3 Mon Sep 17 00:00:00 2001 -From: Leah Rowe <leah@libreboot.org> -Date: Tue, 9 Jan 2024 01:53:54 +0000 -Subject: [PATCH 1/1] ifdtool nuke option - -Signed-off-by: Leah Rowe <leah@libreboot.org> ---- - util/ifdtool/ifdtool.c | 114 ++++++++++++++++++++++++++++++----------- - 1 file changed, 83 insertions(+), 31 deletions(-) - -diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c -index e97efcc206..ee27e7f2e6 100644 ---- a/util/ifdtool/ifdtool.c -+++ b/util/ifdtool/ifdtool.c -@@ -1711,6 +1711,7 @@ static void print_usage(const char *name) - 	       "                                         tgl    - Tiger Lake\n" - 	       "   -S | --setpchstrap                    Write a PCH strap\n" - 	       "   -V | --newvalue                       The new value to write into PCH strap specified by -S\n" -+	       "   -N | --nuke <region>                  Overwrite the specified region with 0xFF (all ones)\n" - 	       "   -v | --version:                       print the version\n" - 	       "   -h | --help:                          print this help\n\n" - 	       "<region> is one of Descriptor, BIOS, ME, GbE, Platform Data, Secondary BIOS, " -@@ -1718,6 +1719,60 @@ static void print_usage(const char *name) - 	       "\n"); - } -  -+static int -+get_region_type_string(const char *region_type_string) -+{ -+	if (!strcasecmp("Descriptor", region_type_string)) -+		return 0; -+	else if (!strcasecmp("BIOS", region_type_string)) -+		return 1; -+	else if (!strcasecmp("ME", region_type_string)) -+		return 2; -+	else if (!strcasecmp("GbE", region_type_string)) -+		return 3; -+	else if (!strcasecmp("Platform Data", region_type_string)) -+		return 4; -+	else if (!strcasecmp("Device Exp1", region_type_string)) -+		return 5; -+	else if (!strcasecmp("Secondary BIOS", region_type_string)) -+		return 6; -+	else if (!strcasecmp("Reserved", region_type_string)) -+		return 7; -+	else if (!strcasecmp("EC", region_type_string)) -+		return 8; -+	else if (!strcasecmp("Device Exp2", region_type_string)) -+		return 9; -+	else if (!strcasecmp("IE", region_type_string)) -+		return 10; -+	else if (!strcasecmp("10GbE_0", region_type_string)) -+		return 11; -+	else if (!strcasecmp("10GbE_1", region_type_string)) -+		return 12; -+	else if (!strcasecmp("PTT", region_type_string)) -+		return 15; -+	return -1; -+} -+ -+static void -+nuke(const char *filename, char *image, int size, int region_type) -+{ -+	int i; -+	region_t region; -+	const frba_t *frba = find_frba(image, size); -+	if (!frba) -+		exit(EXIT_FAILURE); -+ -+	region = get_region(frba, region_type); -+	if (region.size > 0) { -+		for (i = region.base; i <= region.limit; i++) { -+			if ((i + 1) > (size)) -+				break; -+			image[i] = 0xFF; -+		} -+		write_image(filename, image, size); -+	} -+} -+ - int main(int argc, char *argv[]) - { - 	int opt, option_index = 0; -@@ -1725,6 +1780,7 @@ int main(int argc, char *argv[]) - 	int mode_em100 = 0, mode_locked = 0, mode_unlocked = 0, mode_validate = 0; - 	int mode_layout = 0, mode_newlayout = 0, mode_density = 0, mode_setstrap = 0; - 	int mode_read = 0, mode_altmedisable = 0, altmedisable = 0; -+	int mode_nuke = 0; - 	char *region_type_string = NULL, *region_fname = NULL; - 	const char *layout_fname = NULL; - 	char *new_filename = NULL; -@@ -1755,6 +1811,7 @@ int main(int argc, char *argv[]) - 		{"validate", 0, NULL, 't'}, - 		{"setpchstrap", 1, NULL, 'S'}, - 		{"newvalue", 1, NULL, 'V'}, -+		{"nuke", 1, NULL, 'N'}, - 		{0, 0, 0, 0} - 	}; -  -@@ -1795,35 +1852,8 @@ int main(int argc, char *argv[]) - 			region_fname++; - 			// Descriptor, BIOS, ME, GbE, Platform - 			// valid type? --			if (!strcasecmp("Descriptor", region_type_string)) --				region_type = 0; --			else if (!strcasecmp("BIOS", region_type_string)) --				region_type = 1; --			else if (!strcasecmp("ME", region_type_string)) --				region_type = 2; --			else if (!strcasecmp("GbE", region_type_string)) --				region_type = 3; --			else if (!strcasecmp("Platform Data", region_type_string)) --				region_type = 4; --			else if (!strcasecmp("Device Exp1", region_type_string)) --				region_type = 5; --			else if (!strcasecmp("Secondary BIOS", region_type_string)) --				region_type = 6; --			else if (!strcasecmp("Reserved", region_type_string)) --				region_type = 7; --			else if (!strcasecmp("EC", region_type_string)) --				region_type = 8; --			else if (!strcasecmp("Device Exp2", region_type_string)) --				region_type = 9; --			else if (!strcasecmp("IE", region_type_string)) --				region_type = 10; --			else if (!strcasecmp("10GbE_0", region_type_string)) --				region_type = 11; --			else if (!strcasecmp("10GbE_1", region_type_string)) --				region_type = 12; --			else if (!strcasecmp("PTT", region_type_string)) --				region_type = 15; --			if (region_type == -1) { -+			if ((region_type = -+			    get_region_type_string(region_type_string)) == -1) { - 				fprintf(stderr, "No such region type: '%s'\n\n", - 					region_type_string); - 				print_usage(argv[0]); -@@ -1988,6 +2018,22 @@ int main(int argc, char *argv[]) - 		case 't': - 			mode_validate = 1; - 			break; -+               case 'N': -+                       region_type_string = strdup(optarg); -+                       if (!region_type_string) { -+                               fprintf(stderr, "No region specified\n"); -+                               print_usage(argv[0]); -+                               exit(EXIT_FAILURE); -+                       } -+                       if ((region_type = -+                           get_region_type_string(region_type_string)) == -1) { -+                               fprintf(stderr, "No such region type: '%s'\n\n", -+                                       region_type_string); -+                               print_usage(argv[0]); -+                               exit(EXIT_FAILURE); -+                       } -+                       mode_nuke = 1; -+                       break; - 		case 'v': - 			print_version(); - 			exit(EXIT_SUCCESS); -@@ -2003,7 +2049,8 @@ int main(int argc, char *argv[]) -  - 	if ((mode_dump + mode_layout + mode_extract + mode_inject + mode_setstrap + - 		mode_newlayout + (mode_spifreq | mode_em100 | mode_unlocked | --		 mode_locked) + mode_altmedisable + mode_validate) > 1) { -+		 mode_locked) + mode_altmedisable + mode_validate + -+		 mode_nuke) > 1) { - 		fprintf(stderr, "You may not specify more than one mode.\n\n"); - 		print_usage(argv[0]); - 		exit(EXIT_FAILURE); -@@ -2011,7 +2058,8 @@ int main(int argc, char *argv[]) -  - 	if ((mode_dump + mode_layout + mode_extract + mode_inject + mode_setstrap + - 	     mode_newlayout + mode_spifreq + mode_em100 + mode_locked + --	     mode_unlocked + mode_density + mode_altmedisable + mode_validate) == 0) { -+	     mode_unlocked + mode_density + mode_altmedisable + -+	     mode_validate + mode_nuke) == 0) { - 		fprintf(stderr, "You need to specify a mode.\n\n"); - 		print_usage(argv[0]); - 		exit(EXIT_FAILURE); -@@ -2109,6 +2157,10 @@ int main(int argc, char *argv[]) - 		write_image(new_filename, image, size); - 	} -  -+	if (mode_nuke) { -+               nuke(new_filename, image, size, region_type); -+	} -+ - 	if (mode_altmedisable) { - 		fpsba_t *fpsba = find_fpsba(image, size); - 		fmsba_t *fmsba = find_fmsba(image, size); ---  -2.39.2 - diff --git a/config/coreboot/haswell/target.cfg b/config/coreboot/haswell/target.cfg index b3196341..a38399e4 100644 --- a/config/coreboot/haswell/target.cfg +++ b/config/coreboot/haswell/target.cfg @@ -1,3 +1,3 @@  tree="haswell" -rev="1411ecf6f0b2c7395bcb96b856dcfdddb1b0c81b" +rev="b7341da19133991efd29880849bdaab29a6e243d"  xarch="i386-elf" | 
