the following patch was just integrated into master:
commit 73639e27170355a2bb9a54a340f5bcd2f3dac161
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Wed Apr 9 12:24:39 2014 -0500
hp/pavilion_m6_1035dx: Add SMI handler and handle EC requests
The EC may disable some functionality, such as Caps Lock LED and
battery charging if it never receives a command to go in APM mode. If
we start it in APM mode, then immediately switch to ACPI mode, it will
not get its SCIs serviced until an ACPI OS boots. If its SCIs are not
serviced, it may assume the OS has hung.
The way we solve this is to initalize the EC in APM mode, and only
switch it to ACPI when an ACPI-capable OS issues the ACPI_ENABLE
command. The switch has to be handled in SMM.
Although we aren't yet processing SMIs from the EC, we are reading the
status in order to satisfy the EC that the event is handled.
Change-Id: Iffaeb9a6f57841f456c4bce8337dc09b287f8758
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Reviewed-on: http://review.coreboot.org/5512
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Reviewed-by: Aaron Durbin <adurbin(a)gmail.com>
See http://review.coreboot.org/5512 for details.
-gerrit
the following patch was just integrated into master:
commit 62abbe909d27c7351107b0466acc9ea07b490930
Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Date: Wed Apr 16 18:32:07 2014 +0300
roda/rk9: Drop MAX_PHYSICAL_CPUS
Change-Id: I9c41cccf9058c48006b247aca705a3f869ae82a6
Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Reviewed-on: http://review.coreboot.org/5524
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
See http://review.coreboot.org/5524 for details.
-gerrit
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5527
-gerrit
commit a3feeff31cb60d939adf745755bb00b7c8b2492b
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Thu Apr 17 00:47:47 2014 -0500
hp/pavilion_m6_1035dx: Shutdown on low battery with non-ACPI OS
Intercept the low battery SMI from the EC, and shut down the system
immediately. The EC only sends this SMI when the OS did not enable
ACPI mode, so ACPI OSes are not affected by this.
On the other hand, payloads such as GRUB or SeaBIOS will experience
the shutdown. This behavior is helpful for protecting the battery, for
example, when the OS fails to boot and we are stuck in the payload.
The low battery SMI is triggered at 10% charge, at which point the risk
of cell degradation exists.
Change-Id: I4c6c1a4feed8576cbdbb1945768de0805a1f5e42
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c b/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c
index bb9cc2e..7c1a602 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c
+++ b/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c
@@ -6,14 +6,18 @@
*/
#include "ec.h"
+#include <arch/io.h>
#include <console/console.h>
#include <cpu/x86/smm.h>
#include <delay.h>
#include <ec/compal/ene932/ec.h>
#include <southbridge/amd/agesa/hudson/hudson.h>
+#define ACPI_PM1_CNT_SLEEP(state) ((1 << 13) | (state & 0x7) << 10)
+
enum ec_smi_event {
EC_SMI_EVENT_IDLE = 0x80,
+ EC_SMI_BATTERY_LOW = 0xb3,
};
/* Tell EC to operate in APM mode. Events generate SMIs instead of SCIs */
@@ -37,12 +41,18 @@ static uint8_t ec_get_smi_event(void)
static void ec_process_smi(uint8_t src)
{
- /*
- * Stub: We aren't processing any events yet, but reading the SMI source
- * satisfies the EC in terms of responding to the event.
+ /* Reading the SMI source satisfies the EC in terms of responding to
+ * the event, regardless of whether we take an action or not.
*/
- printk(BIOS_DEBUG, "EC_SMI event 0x%x\n", src);
+ switch (src) {
+ case EC_SMI_BATTERY_LOW:
+ printk(BIOS_DEBUG, "Battery low. Shutting down\n");
+ outl(ACPI_PM1_CNT_SLEEP(5), ACPI_PM1_CNT_BLK);
+ break;
+ default:
+ printk(BIOS_DEBUG, "EC_SMI event 0x%x\n", src);
+ }
}
static void handle_ec_smi(void)
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5512
-gerrit
commit e72c3eec14b5772936d2608ede4e1dbed8198949
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Wed Apr 9 12:24:39 2014 -0500
hp/pavilion_m6_1035dx: Add SMI handler and handle EC requests
The EC may disable some functionality, such as Caps Lock LED and
battery charging if it never receives a command to go in APM mode. If
we start it in APM mode, then immediately switch to ACPI mode, it will
not get its SCIs serviced until an ACPI OS boots. If its SCIs are not
serviced, it may assume the OS has hung.
The way we solve this is to initalize the EC in APM mode, and only
switch it to ACPI when an ACPI-capable OS issues the ACPI_ENABLE
command. The switch has to be handled in SMM.
Although we aren't yet processing SMIs from the EC, we are reading the
status in order to satisfy the EC that the event is handled.
Change-Id: Iffaeb9a6f57841f456c4bce8337dc09b287f8758
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/mainboard/hp/pavilion_m6_1035dx/Kconfig | 1 +
src/mainboard/hp/pavilion_m6_1035dx/Makefile.inc | 2 +
src/mainboard/hp/pavilion_m6_1035dx/ec.c | 18 +++--
src/mainboard/hp/pavilion_m6_1035dx/ec.h | 4 ++
src/mainboard/hp/pavilion_m6_1035dx/mainboard.c | 5 ++
.../hp/pavilion_m6_1035dx/mainboard_smi.c | 77 ++++++++++++++++++++++
6 files changed, 102 insertions(+), 5 deletions(-)
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/Kconfig b/src/mainboard/hp/pavilion_m6_1035dx/Kconfig
index 87e8212..d6cdb10 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/Kconfig
+++ b/src/mainboard/hp/pavilion_m6_1035dx/Kconfig
@@ -30,6 +30,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select HAVE_PIRQ_TABLE
select HAVE_MP_TABLE
select HAVE_ACPI_RESUME
+ select HAVE_SMI_HANDLER
select SERIAL_CPU_INIT
select HAVE_ACPI_TABLES
select BOARD_ROMSIZE_KB_4096
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/Makefile.inc b/src/mainboard/hp/pavilion_m6_1035dx/Makefile.inc
index 07ea765..7039c72 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/Makefile.inc
+++ b/src/mainboard/hp/pavilion_m6_1035dx/Makefile.inc
@@ -27,3 +27,5 @@ ramstage-y += agesawrapper.c
ramstage-y += BiosCallOuts.c
ramstage-y += PlatformGnbPcie.c
ramstage-y += ec.c
+
+smm-y += mainboard_smi.c
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/ec.c b/src/mainboard/hp/pavilion_m6_1035dx/ec.c
index d61a2e5..2dd0009 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/ec.c
+++ b/src/mainboard/hp/pavilion_m6_1035dx/ec.c
@@ -13,16 +13,24 @@ static void set_keyboard_matrix_us(void)
ec_kbc_write_ib(0xE5);
}
-/* Tell EC to operate in ACPI mode, thus generating SCIs on events, not SMIs */
-static void enter_acpi_mode(void)
+/* Tell EC to operate in APM mode. Events generate SMIs instead of SCIs */
+static void enter_apm_mode(void)
{
ec_kbc_write_cmd(0x59);
- ec_kbc_write_ib(0xE8);
+ ec_kbc_write_ib(0xE9);
}
void pavilion_m6_1035dx_ec_init(void)
{
set_keyboard_matrix_us();
- /* This could also be done in an SMI, should we decide to use SMM */
- enter_acpi_mode();
+
+ /*
+ * The EC has a special "blinking Caps Lock LED" mode which it normally
+ * enters when it believes the OS is not responding. It occasionally
+ * disables battery charging when in this mode, although other
+ * functionality is unaffected. Although the EC starts in APM mode by
+ * default, it only leaves the "blinking Caps Lock LED" mode after
+ * receiving the following command.
+ */
+ enter_apm_mode();
}
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/ec.h b/src/mainboard/hp/pavilion_m6_1035dx/ec.h
index 0c00d7a..579bf7e 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/ec.h
+++ b/src/mainboard/hp/pavilion_m6_1035dx/ec.h
@@ -6,6 +6,10 @@
#ifndef _MAINBOARD_HP_PAVILION_M6_1035DX_EC_H
#define _MAINBOARD_HP_PAVILION_M6_1035DX_EC_H
+#define EC_SMI_GEVENT 23
+
+#ifndef __SMM__
void pavilion_m6_1035dx_ec_init(void);
+#endif
#endif /* _MAINBOARD_HP_PAVILION_M6_1035DX_EC_H */
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c b/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c
index 2e2b72b..756b443 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c
+++ b/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c
@@ -30,6 +30,8 @@
#include <device/pci.h>
#include <device/pci_def.h>
+#include <southbridge/amd/agesa/hudson/smi.h>
+
/*************************************************
* enable the dedicated function in parmer board.
*************************************************/
@@ -39,6 +41,9 @@ static void mainboard_enable(device_t dev)
pavilion_m6_1035dx_ec_init();
+ hudson_enable_gevent_smi(EC_SMI_GEVENT);
+ hudson_enable_smi_generation();
+
/*
* The mainboard is the first place that we get control in ramstage. Check
* for S3 resume and call the approriate AGESA/CIMx resume functions.
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c b/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c
new file mode 100644
index 0000000..bb9cc2e
--- /dev/null
+++ b/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c
@@ -0,0 +1,77 @@
+/*
+ * SMI handler -- mostly takes care of SMIs from the EC
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+#include "ec.h"
+
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+#include <delay.h>
+#include <ec/compal/ene932/ec.h>
+#include <southbridge/amd/agesa/hudson/hudson.h>
+
+enum ec_smi_event {
+ EC_SMI_EVENT_IDLE = 0x80,
+};
+
+/* Tell EC to operate in APM mode. Events generate SMIs instead of SCIs */
+static void ec_enter_apm_mode(void)
+{
+ ec_kbc_write_cmd(0x59);
+ ec_kbc_write_ib(0xE9);
+}
+/* Tell EC to operate in ACPI mode, thus generating SCIs on events, not SMIs */
+static void ec_enter_acpi_mode(void)
+{
+ ec_kbc_write_cmd(0x59);
+ ec_kbc_write_ib(0xE8);
+}
+
+static uint8_t ec_get_smi_event(void)
+{
+ ec_kbc_write_cmd(0x56);
+ return ec_kbc_read_ob();
+}
+
+static void ec_process_smi(uint8_t src)
+{
+ /*
+ * Stub: We aren't processing any events yet, but reading the SMI source
+ * satisfies the EC in terms of responding to the event.
+ */
+
+ printk(BIOS_DEBUG, "EC_SMI event 0x%x\n", src);
+}
+
+static void handle_ec_smi(void)
+{
+ uint8_t src;
+
+ while ((src = ec_get_smi_event()) != EC_SMI_EVENT_IDLE)
+ ec_process_smi(src);
+}
+
+int mainboard_smi_apmc(uint8_t data)
+{
+ switch (data) {
+ case ACPI_SMI_CMD_ENABLE:
+ printk(BIOS_DEBUG, "Enable ACPI mode\n");
+ ec_enter_acpi_mode();
+ break;
+ case ACPI_SMI_CMD_DISABLE:
+ printk(BIOS_DEBUG, "Disable ACPI mode\n");
+ ec_enter_apm_mode();
+ break;
+ default:
+ printk(BIOS_DEBUG, "Unhandled ACPI command: 0x%x\n", data);
+ }
+ return 0;
+}
+
+void mainboard_smi_gpi(uint32_t gpi_sts)
+{
+ if (gpi_sts & (1 << EC_SMI_GEVENT))
+ handle_ec_smi();
+}
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5512
-gerrit
commit c57a30b310ab14780d0da244100ab6c63dd1a392
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Wed Apr 9 12:24:39 2014 -0500
hp/pavilion_m6_1035dx: Add SMI handler and handle EC requests
The EC may disable some functionality, such as Caps Lock LED and
battery charging if it never receives a command to go in APM mode. If
we start it in APM mode, then immediately switch to ACPI mode, it will
not get its SCIs serviced until an ACPI OS boots. If its SCIs are not
serviced, it may assume the OS has hung.
The way we solve this is to initalize the EC in APM mode, and only
switch it to ACPI when an ACPI-capable OS issues the ACPI_ENABLE
command. The switch has to be handled in SMM.
Although we aren't yet processing SMIs from the EC, we are reading the
status in order to satisfy the EC that the event is handled.
Change-Id: Iffaeb9a6f57841f456c4bce8337dc09b287f8758
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/mainboard/hp/pavilion_m6_1035dx/Kconfig | 1 +
src/mainboard/hp/pavilion_m6_1035dx/Makefile.inc | 2 +
src/mainboard/hp/pavilion_m6_1035dx/ec.c | 18 +++--
src/mainboard/hp/pavilion_m6_1035dx/ec.h | 4 ++
src/mainboard/hp/pavilion_m6_1035dx/mainboard.c | 5 ++
.../hp/pavilion_m6_1035dx/mainboard_smi.c | 77 ++++++++++++++++++++++
6 files changed, 102 insertions(+), 5 deletions(-)
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/Kconfig b/src/mainboard/hp/pavilion_m6_1035dx/Kconfig
index 87e8212..d6cdb10 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/Kconfig
+++ b/src/mainboard/hp/pavilion_m6_1035dx/Kconfig
@@ -30,6 +30,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select HAVE_PIRQ_TABLE
select HAVE_MP_TABLE
select HAVE_ACPI_RESUME
+ select HAVE_SMI_HANDLER
select SERIAL_CPU_INIT
select HAVE_ACPI_TABLES
select BOARD_ROMSIZE_KB_4096
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/Makefile.inc b/src/mainboard/hp/pavilion_m6_1035dx/Makefile.inc
index 07ea765..7039c72 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/Makefile.inc
+++ b/src/mainboard/hp/pavilion_m6_1035dx/Makefile.inc
@@ -27,3 +27,5 @@ ramstage-y += agesawrapper.c
ramstage-y += BiosCallOuts.c
ramstage-y += PlatformGnbPcie.c
ramstage-y += ec.c
+
+smm-y += mainboard_smi.c
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/ec.c b/src/mainboard/hp/pavilion_m6_1035dx/ec.c
index d61a2e5..2dd0009 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/ec.c
+++ b/src/mainboard/hp/pavilion_m6_1035dx/ec.c
@@ -13,16 +13,24 @@ static void set_keyboard_matrix_us(void)
ec_kbc_write_ib(0xE5);
}
-/* Tell EC to operate in ACPI mode, thus generating SCIs on events, not SMIs */
-static void enter_acpi_mode(void)
+/* Tell EC to operate in APM mode. Events generate SMIs instead of SCIs */
+static void enter_apm_mode(void)
{
ec_kbc_write_cmd(0x59);
- ec_kbc_write_ib(0xE8);
+ ec_kbc_write_ib(0xE9);
}
void pavilion_m6_1035dx_ec_init(void)
{
set_keyboard_matrix_us();
- /* This could also be done in an SMI, should we decide to use SMM */
- enter_acpi_mode();
+
+ /*
+ * The EC has a special "blinking Caps Lock LED" mode which it normally
+ * enters when it believes the OS is not responding. It occasionally
+ * disables battery charging when in this mode, although other
+ * functionality is unaffected. Although the EC starts in APM mode by
+ * default, it only leaves the "blinking Caps Lock LED" mode after
+ * receiving the following command.
+ */
+ enter_apm_mode();
}
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/ec.h b/src/mainboard/hp/pavilion_m6_1035dx/ec.h
index 0c00d7a..579bf7e 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/ec.h
+++ b/src/mainboard/hp/pavilion_m6_1035dx/ec.h
@@ -6,6 +6,10 @@
#ifndef _MAINBOARD_HP_PAVILION_M6_1035DX_EC_H
#define _MAINBOARD_HP_PAVILION_M6_1035DX_EC_H
+#define EC_SMI_GEVENT 23
+
+#ifndef __SMM__
void pavilion_m6_1035dx_ec_init(void);
+#endif
#endif /* _MAINBOARD_HP_PAVILION_M6_1035DX_EC_H */
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c b/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c
index 2e2b72b..756b443 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c
+++ b/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c
@@ -30,6 +30,8 @@
#include <device/pci.h>
#include <device/pci_def.h>
+#include <southbridge/amd/agesa/hudson/smi.h>
+
/*************************************************
* enable the dedicated function in parmer board.
*************************************************/
@@ -39,6 +41,9 @@ static void mainboard_enable(device_t dev)
pavilion_m6_1035dx_ec_init();
+ hudson_enable_gevent_smi(EC_SMI_GEVENT);
+ hudson_enable_smi_generation();
+
/*
* The mainboard is the first place that we get control in ramstage. Check
* for S3 resume and call the approriate AGESA/CIMx resume functions.
diff --git a/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c b/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c
new file mode 100644
index 0000000..640e9d5
--- /dev/null
+++ b/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c
@@ -0,0 +1,77 @@
+/*
+ * SMI handler -- mostly takes care of SMIs from the EC
+ *
+ * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+#include "ec.h"
+
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+#include <delay.h>
+#include <ec/compal/ene932/ec.h>
+#include <southbridge/amd/agesa/hudson/hudson.h>
+
+enum ec_smi_event {
+ EC_SMI_EVENT_IDLE = 0x80,
+};
+
+/* Tell EC to operate in APM mode. Events generate SMIs instead of SCIs */
+static void ec_enter_apm_mode(void)
+{
+ ec_kbc_write_cmd(0x59);
+ ec_kbc_write_ib(0xE9);
+}
+/* Tell EC to operate in ACPI mode, thus generating SCIs on events, not SMIs */
+static void ec_enter_acpi_mode(void)
+{
+ ec_kbc_write_cmd(0x59);
+ ec_kbc_write_ib(0xE8);
+}
+
+static uint8_t ec_get_smi_event(void)
+{
+ ec_kbc_write_cmd(0x56);
+ return ec_kbc_read_ob();
+}
+
+static void ec_process_smi(uint8_t src)
+{
+ /*
+ * Stub: We aren't processing any events yet, but reading the SMI source
+ * from satisfies the EC in terms of responding to the event.
+ */
+
+ printk(BIOS_DEBUG, "EC_SMI event 0x%x\n", src);
+}
+
+static void handle_ec_smi(void)
+{
+ uint8_t src;
+
+ while ((src = ec_get_smi_event()) != EC_SMI_EVENT_IDLE)
+ ec_process_smi(src);
+}
+
+int mainboard_smi_apmc(uint8_t data)
+{
+ switch (data) {
+ case ACPI_SMI_CMD_ENABLE:
+ printk(BIOS_DEBUG, "Enable ACPI mode\n");
+ ec_enter_acpi_mode();
+ break;
+ case ACPI_SMI_CMD_DISABLE:
+ printk(BIOS_DEBUG, "Disable ACPI mode\n");
+ ec_enter_apm_mode();
+ break;
+ default:
+ printk(BIOS_DEBUG, "Unhandled ACPI command: 0x%x\n", data);
+ }
+ return 0;
+}
+
+void mainboard_smi_gpi(uint32_t gpi_sts)
+{
+ if (gpi_sts & EC_SMI_GEVENT)
+ handle_ec_smi();
+}