summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Spiegel <richard.spiegel@silverbackltd.com>2018-03-05 08:11:50 -0700
committerMartin Roth <martinroth@google.com>2018-03-16 19:01:46 +0000
commita9f49366c09f8902a13221185449a1d0870af1c6 (patch)
tree701c79a43de4c8d48cc3102bb12b980b582731e4
parent013f1024c3f96ff9a59b70ae6a83ea3d7e9071dc (diff)
downloadcoreboot-a9f49366c09f8902a13221185449a1d0870af1c6.tar.xz
soc/amd/stoneyridge: Create a HALT_THIS_AP callout
It was required for all cores use the same CAR teardown function (exit_car.S and gcccar.inc). AGESA has already been modified to do the AP to do the call out. Create assembly code to call chipset_teardown_car and then enter an endless loop with halt instruction. Then create the call out that will call this new assembly code. BUG=b:70338633 AGESA COMMIT=3313d277 TEST=Created a debug version of AGESA that would print the returned status of HALT_THIS_AP. Build code without the fix, see the return. Build code with the fix, see that there's no return. Change-Id: I05ee405812211d93dfdbdc5ee7d9978c2eb585e1 Signed-off-by: Richard Spiegel <richard.spiegel@silverbackltd.com> Reviewed-on: https://review.coreboot.org/24999 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
-rw-r--r--src/soc/amd/common/block/cpu/Makefile.inc4
-rw-r--r--src/soc/amd/common/block/cpu/car/ap_exit_car.S61
-rw-r--r--src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h1
-rw-r--r--src/soc/amd/common/block/include/amdblocks/car.h23
-rw-r--r--src/soc/amd/common/block/pi/def_callouts.c1
-rw-r--r--src/soc/amd/stoneyridge/BiosCallOuts.c19
6 files changed, 109 insertions, 0 deletions
diff --git a/src/soc/amd/common/block/cpu/Makefile.inc b/src/soc/amd/common/block/cpu/Makefile.inc
index ecc9afbc6f..fed208a378 100644
--- a/src/soc/amd/common/block/cpu/Makefile.inc
+++ b/src/soc/amd/common/block/cpu/Makefile.inc
@@ -1,3 +1,7 @@
bootblock-$(CONFIG_SOC_AMD_COMMON_BLOCK_CAR) += car/cache_as_ram.S
+bootblock-$(CONFIG_SOC_AMD_COMMON_BLOCK_CAR) += car/ap_exit_car.S
+bootblock-$(CONFIG_SOC_AMD_COMMON_BLOCK_CAR) += car/exit_car.S
+
postcar-$(CONFIG_SOC_AMD_COMMON_BLOCK_CAR) += car/exit_car.S
+
romstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_CAR) += car/exit_car.S
diff --git a/src/soc/amd/common/block/cpu/car/ap_exit_car.S b/src/soc/amd/common/block/cpu/car/ap_exit_car.S
new file mode 100644
index 0000000000..5d3e13b1a2
--- /dev/null
+++ b/src/soc/amd/common/block/cpu/car/ap_exit_car.S
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+.code32
+
+#include <cpu/x86/cr.h>
+
+.globl ap_teardown_car
+ap_teardown_car:
+ pop %esi /* return address, don't care */
+ pop %esi /* flags */
+
+ /* chipset_teardown_car() is expected to disable cache-as-ram. */
+ call chipset_teardown_car
+
+ /*
+ * Check flags requirements (0 = FALSE, 1 = TRUE) :
+ * bit 0 = ExecWbinvd
+ * bit 1 = CacheEn
+ */
+
+ /*
+ * TODO: Either use or remove this code - we'll node if the code
+ * is needed when 3 conditions happens:
+ * 1) This code is in place
+ * 2) AGESA code that calls HALT_THIS_AP is in place
+ * 3) We boot to OS, go to S3 and resume.
+ * If S3 resume fails, this code might be needed, if S3 resume
+ * is successful then the code can be removed.
+ */
+
+ /*
+ * Commented out until defined if needed or not.
+ * test %esi, 1
+ * jz 1f
+ * wbinvd
+ * 1:
+ */
+
+ test %esi, 2
+ jz 2f
+ /* Enable cache */
+ mov %cr0, %eax
+ and $(~(CR0_CD | CR0_NW)), %eax
+ mov %eax, %cr0
+2:
+ cli
+ hlt
+ jmp 2b
diff --git a/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h b/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h
index e061c63463..34131cf7ec 100644
--- a/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h
+++ b/src/soc/amd/common/block/include/amdblocks/BiosCallOuts.h
@@ -57,6 +57,7 @@ AGESA_STATUS GetBiosCallout(UINT32 Func, UINTN Data, VOID *ConfigPtr);
AGESA_STATUS agesa_fch_initreset(UINT32 Func, UINTN FchData, VOID *ConfigPtr);
AGESA_STATUS agesa_fch_initenv(UINT32 Func, UINTN FchData, VOID *ConfigPtr);
+AGESA_STATUS agesa_HaltThisAp(UINT32 Func, UINTN Data, VOID *ConfigPtr);
void platform_FchParams_reset(FCH_RESET_DATA_BLOCK *FchParams_reset);
void platform_FchParams_env(FCH_DATA_BLOCK *FchParams_env);
diff --git a/src/soc/amd/common/block/include/amdblocks/car.h b/src/soc/amd/common/block/include/amdblocks/car.h
new file mode 100644
index 0000000000..6c4049b6bf
--- /dev/null
+++ b/src/soc/amd/common/block/include/amdblocks/car.h
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __AMD_CAR_H__
+#define __AMD_CAR_H__
+
+#include <stdint.h>
+
+void ap_teardown_car(uint32_t flags);
+
+#endif /* __AMD_CAR_H__ */
diff --git a/src/soc/amd/common/block/pi/def_callouts.c b/src/soc/amd/common/block/pi/def_callouts.c
index c05d4de8cc..beb2d18c2e 100644
--- a/src/soc/amd/common/block/pi/def_callouts.c
+++ b/src/soc/amd/common/block/pi/def_callouts.c
@@ -29,6 +29,7 @@
const BIOS_CALLOUT_STRUCT BiosCallouts[] = {
{ AGESA_DO_RESET, agesa_Reset },
{ AGESA_FCH_OEM_CALLOUT, agesa_fch_initreset },
+ { AGESA_HALT_THIS_AP, agesa_HaltThisAp },
{ AGESA_GNB_PCIE_SLOT_RESET, agesa_PcieSlotResetControl }
};
#else
diff --git a/src/soc/amd/stoneyridge/BiosCallOuts.c b/src/soc/amd/stoneyridge/BiosCallOuts.c
index 4ddcedcdd9..f30ed3cb01 100644
--- a/src/soc/amd/stoneyridge/BiosCallOuts.c
+++ b/src/soc/amd/stoneyridge/BiosCallOuts.c
@@ -26,6 +26,7 @@
#include <amdlib.h>
#include <amdblocks/dimm_spd.h>
#include "chip.h"
+#include <amdblocks/car.h>
void __attribute__((weak)) platform_FchParams_reset(
FCH_RESET_DATA_BLOCK *FchParams_reset) {}
@@ -139,6 +140,24 @@ AGESA_STATUS agesa_ReadSpd(UINT32 Func, UINTN Data, VOID *ConfigPtr)
return AGESA_SUCCESS;
}
+AGESA_STATUS agesa_HaltThisAp(UINT32 Func, UINTN Data, VOID *ConfigPtr)
+{
+ AGESA_HALT_THIS_AP_PARAMS *info = ConfigPtr;
+ uint32_t flags = 0;
+
+ if (info->PrimaryCore == TRUE)
+ return AGESA_UNSUPPORTED; /* force normal path */
+ if (info->ExecWbinvd == TRUE)
+ flags |= 1;
+ if (info->CacheEn == TRUE)
+ flags |= 2;
+
+ ap_teardown_car(flags); /* does not return */
+
+ /* Should never reach here */
+ return AGESA_UNSUPPORTED;
+}
+
/* Allow mainboards to fill the SPD buffer */
__attribute__((weak)) int mainboard_read_spd(uint8_t spdAddress, char *buf,
size_t len)