[flashrom] [PATCH] Board enable (EC sleep) for Acer Ferrari 3400

Michael Karcher flashrom at mkarcher.dialup.fu-berlin.de
Mon Apr 12 00:55:44 CEST 2010


BE WARNED: FLASHROM COMES WITH NO WARRANTY! THIS IS ESPECIALLY TRUE FOR
LAPTOPS, AND ESPECIALLY ESPECIALLY TRUE FOR LAPTOPS WITH SHARED EC.
Nevertheless, I think that trying to *read* flash contents with this patch
is not more unsafe than reading without this patch. Be warned that a crashed
EC might mean no fan control. Don't even *THINK* about erase/write until
read works fine!

This is the first system with EC sleep support in flashrom, and the first
user of the register_shutdown infrastructure.

PCI match uses one out of many chips with subsystem ID Acer:0x0057, and
also the northbridge (with bogus subsystem ID). DMI match added just for
safety, as fiddling with the KBC is dangerous.

Signed-off-by: Michael Karcher <flashrom at mkarcher.dialup.fu-berlin.de>
---
 board_enable.c |  100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 100 insertions(+), 0 deletions(-)

diff --git a/board_enable.c b/board_enable.c
index f1f7953..ce82131 100644
--- a/board_enable.c
+++ b/board_enable.c
@@ -29,6 +29,66 @@
 #include "flash.h"
 
 /*
+ * Functions for EC/KBC communication
+ *  port = 0x60 for KBC, port = 0x62 (typically) for EC
+ */
+static int wait_uc_writebuf_empty(uint16_t port)
+{
+	int count;
+	for (count = 0; count < 50; count++)
+	{
+		/* quit if OBF bit clear */
+		if (!(INB(port + 4) & 2))
+			return 0;
+		usleep(10000);
+	}
+	return -1;
+}
+
+static int wait_uc_readbuf_full(uint16_t port)
+{
+	int count;
+	for (count = 0; count < 50; count++)
+	{
+		/* quit if IBF bit set */
+		if (INB(port + 4) & 1)
+			return 0;
+		usleep(10000);
+	}
+	return -1;
+}
+
+static int uc_send_command(uint16_t port, uint8_t command)
+{
+	if (wait_uc_writebuf_empty(port) != 0)
+		return -1;
+	OUTB(command, port + 4);
+	return 0;
+}
+
+#if 0
+static int uc_send_data(uint16_t port, uint8_t command)
+{
+	if (wait_uc_writebuf_empty(port) != 0)
+		return -1;
+	OUTB(command, port);
+	return 0;
+}
+#endif
+
+static int uc_read_data(uint16_t port)
+{
+	if (wait_uc_readbuf_full(port) != 0)
+		return -1;
+	return INB(port);
+}
+
+static void uc_flush_data(uint16_t port)
+{
+	INB(port);
+}
+
+/*
  * Helper functions for many Winbond Super I/Os of the W836xx range.
  */
 /* Enter extended functions */
@@ -1307,6 +1367,45 @@ static int it8712f_gpio3_1_raise(const char *name)
 	return it8712f_gpio_set(32, 1);
 }
 
+static void send_kbc_command(void * cmdptr)
+{
+	uc_send_command(0x60, *(uint8_t*)cmdptr);
+}
+
+static int board_acer_ferrari3400(const char *name)
+{
+	static uint8_t enable_command = 0xAA;
+	uint16_t pmio_base;
+	struct pci_dev * dev;
+
+	dev = pci_dev_find(0x1106, 0x3177);
+	if (!dev)
+	{
+		fprintf(stderr, "ERROR: %s - Can't find VT8235\n", name);
+		return -1;
+	}
+	pmio_base = pci_read_word(dev, 0x88) & 0xFF80;
+	if (pmio_base == 0 || pmio_base == 0xFF80)
+	{
+		fprintf(stderr, "ERROR: %s - invalid PMIO base %04x\n",
+		                name, pmio_base);
+		return -1;
+	}
+
+	usleep(100000);	/* Give the user a fair chance to release enter
+	                   before killing keyboard/mouse */
+
+        uc_flush_data(0x60);
+	register_shutdown(send_kbc_command, &enable_command);
+	if (INB(pmio_base + 4) & 1)
+		uc_send_command(0x60, 0xE5);	/* ACPI mode */
+	else
+		uc_send_command(0x60, 0xD8);	/* APM/legacy mode */
+
+	uc_read_data(0x60);		/* wait for EC shutdown */
+	return 0;
+}
+
 /**
  * Below is the list of boards which need a special "board enable" code in
  * flashrom before their ROM chip can be accessed/written to.
@@ -1356,6 +1455,7 @@ struct board_pciid_enable board_pciid_enables[] = {
 	{0x10de, 0x0050, 0x147b, 0x1c1a,       0,      0,      0,      0, NULL,          NULL,         NULL,          "Abit",        "KN8 Ultra",             0,   NT, nvidia_mcp_gpio2_lower},
 	{0x10de, 0x01e0, 0x147b, 0x1c00,  0x10de, 0x0060, 0x147B, 0x1c00, NULL,          NULL,         NULL,          "Abit",        "NF7-S",                 0,   OK, nvidia_mcp_gpio8_raise},
 	{0x1106, 0x0691,      0,      0,  0x1106, 0x3057,      0,      0, NULL,          "abit",       "vt6x4",       "Abit",        "VT6X4",                 0,   OK, via_apollo_gpo4_lower},
+	{0x1106, 0x3177, 0x1025, 0x0057,  0x1106, 0x3188, 0x1106, 0x3188, "^Ferrari 3400", NULL,       NULL,          "Acer",        "Ferrari 3400",          0,   OK, board_acer_ferrari3400},
 	{0x105a, 0x0d30, 0x105a, 0x4d33,  0x8086, 0x1130, 0x8086,      0, NULL,          NULL,         NULL,          "Acorp",       "6A815EPD",              0,   OK, board_acorp_6a815epd},
 	{0x8086, 0x24D4, 0x1849, 0x24D0,  0x8086, 0x24D5, 0x1849, 0x9739, NULL,          NULL,         NULL,          "ASRock",      "P4i65GV",               0,   OK, intel_ich_gpio23_raise},
 	{0x1022, 0x746B,      0,      0,       0,      0,      0,      0, NULL,          "AGAMI",      "ARUMA",       "agami",       "Aruma",                 0,   OK, w83627hf_gpio24_raise_2e},
-- 
1.7.0





More information about the flashrom mailing list