amd_imc/sb600spi: Move handle_imc() into amd_imc.c
Move handle_imc() to make it easier to share it with other drivers.
Change-Id: I72dff5feda199e1d258c067e230abdf33c451249
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/72575
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/amd_imc.c b/amd_imc.c
index ce0d667..2095eb5 100644
--- a/amd_imc.c
+++ b/amd_imc.c
@@ -15,6 +15,9 @@
* GNU General Public License for more details.
*/
+#include <stdlib.h>
+#include <string.h>
+
#include "flash.h"
#include "programmer.h"
#include "hwaccess_x86_io.h"
@@ -128,7 +131,7 @@
return ret;
}
-int amd_imc_shutdown(struct pci_dev *dev)
+static int amd_imc_shutdown(struct pci_dev *dev)
{
/* Try to put IMC to sleep */
int ret = imc_send_cmd(dev, 0xb4);
@@ -150,3 +153,48 @@
return ret;
}
+
+int handle_imc(struct pci_dev *dev)
+{
+ bool amd_imc_force = false;
+ char *arg = extract_programmer_param("amd_imc_force");
+ if (arg && !strcmp(arg, "yes")) {
+ amd_imc_force = true;
+ msg_pspew("amd_imc_force enabled.\n");
+ } else if (arg && !strlen(arg)) {
+ msg_perr("Missing argument for amd_imc_force.\n");
+ free(arg);
+ return 1;
+ } else if (arg) {
+ msg_perr("Unknown argument for amd_imc_force: \"%s\" (not \"yes\").\n", arg);
+ free(arg);
+ return 1;
+ }
+ free(arg);
+
+ /* TODO: we should not only look at IntegratedImcPresent (LPC Dev 20, Func 3, 40h) but also at
+ * IMCEnable(Strap) and Override EcEnable(Strap) (sb8xx, sb9xx?, a50, Bolton: Misc_Reg: 80h-87h;
+ * sb7xx, sp5100: PM_Reg: B0h-B1h) etc. */
+ uint8_t reg = pci_read_byte(dev, 0x40);
+ if ((reg & (1 << 7)) == 0) {
+ msg_pdbg("IMC is not active.\n");
+ return 0;
+ }
+
+ if (!amd_imc_force)
+ programmer_may_write = false;
+ msg_pinfo("Writes have been disabled for safety reasons because the presence of the IMC\n"
+ "was detected and it could interfere with accessing flash memory. Flashrom will\n"
+ "try to disable it temporarily but even then this might not be safe:\n"
+ "when it is re-enabled and after a reboot it expects to find working code\n"
+ "in the flash and it is unpredictable what happens if there is none.\n"
+ "\n"
+ "To be safe make sure that there is a working IMC firmware at the right\n"
+ "location in the image you intend to write and do not attempt to erase.\n"
+ "\n"
+ "You can enforce write support with the amd_imc_force programmer option.\n");
+ if (amd_imc_force)
+ msg_pinfo("Continuing with write support because the user forced us to!\n");
+
+ return amd_imc_shutdown(dev);
+}
diff --git a/include/programmer.h b/include/programmer.h
index 64e01f8..b349e32 100644
--- a/include/programmer.h
+++ b/include/programmer.h
@@ -361,7 +361,7 @@
int via_init_spi(uint32_t mmio_base);
/* amd_imc.c */
-int amd_imc_shutdown(struct pci_dev *dev);
+int handle_imc(struct pci_dev *);
/* amd_spi100.c */
int amd_spi100_probe(void *const spibar, void *const memory_mapping, const size_t mapped_len);
diff --git a/sb600spi.c b/sb600spi.c
index 0ba3cfb..8d071be 100644
--- a/sb600spi.c
+++ b/sb600spi.c
@@ -485,55 +485,6 @@
return set_speed(dev, &spispeeds[spispeed_idx]);
}
-static int handle_imc(struct pci_dev *dev)
-{
- /* Handle IMC everywhere but sb600 which does not have one. */
- if (amd_gen == CHIPSET_SB6XX)
- return 0;
-
- bool amd_imc_force = false;
- char *arg = extract_programmer_param("amd_imc_force");
- if (arg && !strcmp(arg, "yes")) {
- amd_imc_force = true;
- msg_pspew("amd_imc_force enabled.\n");
- } else if (arg && !strlen(arg)) {
- msg_perr("Missing argument for amd_imc_force.\n");
- free(arg);
- return 1;
- } else if (arg) {
- msg_perr("Unknown argument for amd_imc_force: \"%s\" (not \"yes\").\n", arg);
- free(arg);
- return 1;
- }
- free(arg);
-
- /* TODO: we should not only look at IntegratedImcPresent (LPC Dev 20, Func 3, 40h) but also at
- * IMCEnable(Strap) and Override EcEnable(Strap) (sb8xx, sb9xx?, a50, Bolton: Misc_Reg: 80h-87h;
- * sb7xx, sp5100: PM_Reg: B0h-B1h) etc. */
- uint8_t reg = pci_read_byte(dev, 0x40);
- if ((reg & (1 << 7)) == 0) {
- msg_pdbg("IMC is not active.\n");
- return 0;
- }
-
- if (!amd_imc_force)
- programmer_may_write = false;
- msg_pinfo("Writes have been disabled for safety reasons because the presence of the IMC\n"
- "was detected and it could interfere with accessing flash memory. Flashrom will\n"
- "try to disable it temporarily but even then this might not be safe:\n"
- "when it is re-enabled and after a reboot it expects to find working code\n"
- "in the flash and it is unpredictable what happens if there is none.\n"
- "\n"
- "To be safe make sure that there is a working IMC firmware at the right\n"
- "location in the image you intend to write and do not attempt to erase.\n"
- "\n"
- "You can enforce write support with the amd_imc_force programmer option.\n");
- if (amd_imc_force)
- msg_pinfo("Continuing with write support because the user forced us to!\n");
-
- return amd_imc_shutdown(dev);
-}
-
int sb600_probe_spi(struct pci_dev *dev)
{
struct pci_dev *smbus_dev;
@@ -695,7 +646,8 @@
if (handle_speed(dev) != 0)
return ERROR_FATAL;
- if (handle_imc(dev) != 0)
+ /* Handle IMC everywhere but sb600 which does not have one. */
+ if (amd_gen != CHIPSET_SB6XX && handle_imc(dev) != 0)
return ERROR_FATAL;
/* Starting with Yangtze the SPI controller got a different interface with a much bigger buffer. */