summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu-Ping Wu <yupingso@chromium.org>2024-07-17 11:01:15 +0800
committerFelix Held <felix-coreboot@felixheld.de>2024-07-25 20:53:32 +0000
commitb6e1007e27d695985950b0284ea56680afab42e3 (patch)
tree5a2ac049778fc33f69d357ce44196312b9b75316
parent5085fe647835e1f0166ea067becd76aaee625b73 (diff)
soc/amd: Ensure bank 0 is selected before accessing VBNV in CMOS
In AMD platforms, the bit 4 of CMOS's Register A (0x0a) is DV0 bank selection (0 for Bank 0; 1 for Bank 1) [1]. Since the MC146818 driver accesses VBNV via Bank 0, the bit must be cleared before we can save VBNV to CMOS in verstage. Usually there's no problem with that, because the Register A is configured in cmos_init() in ramstage. However, if CMOS has lost power, then in the first boot after that, the bit may contain arbitrary data in verstage. If that bit happens to be 1, then CMOS writes in verstage will fail. To fix the problem, define vbnv_platform_init_cmos() to call cmos_init(0), which will configure the Register A and therefore allow saving VBNV to CMOS in verstage. [1] 48751_16h_bkdg.pdf BUG=b:346716300 TEST=CMOS writes succeeded in verstage after battery cutoff BRANCH=skyrim Change-Id: Idf167387b403be1977ebc08daa1f40646dd8c83f Signed-off-by: Yu-Ping Wu <yupingso@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/83495 Reviewed-by: Matt DeVillier <matt.devillier@amd.corp-partner.google.com> Reviewed-by: Karthik Ramasubramanian <kramasub@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/soc/amd/common/vboot/vbnv_cmos.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/soc/amd/common/vboot/vbnv_cmos.c b/src/soc/amd/common/vboot/vbnv_cmos.c
index 5baf923939..31c8128d65 100644
--- a/src/soc/amd/common/vboot/vbnv_cmos.c
+++ b/src/soc/amd/common/vboot/vbnv_cmos.c
@@ -3,6 +3,12 @@
#include <security/vboot/vbnv.h>
#include <pc80/mc146818rtc.h>
+void vbnv_platform_init_cmos(void)
+{
+ /* The 0 argument tells cmos_init not to update CMOS unless it is invalid. */
+ cmos_init(0);
+}
+
int vbnv_cmos_failed(void)
{
/* If CMOS power has failed, the century will be set to 0xff */