the following patch was just integrated into master:
commit 065b7da298953feaec3563bf753f45cf00fba2c0
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Tue Apr 15 15:41:38 2014 -0500
cpu/amd/agesa/family15tn: Add udelay implementation for SMM
This is a small implementation which uses only MSRs and rdtsc, without
relying on northbridge or other system hardware. It's SMM safe in that
it only reads registers, and doesn't modify the state of the hardware.
Change-Id: Ifa02ca73455b382f830c9b30b80b4f1bb18706b4
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Reviewed-on: http://review.coreboot.org/5501
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)gmail.com>
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
See http://review.coreboot.org/5501 for details.
-gerrit
the following patch was just integrated into master:
commit 53072d869ad9234781b5a479dfcc9a9288723da6
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Sat Apr 12 21:57:18 2014 -0500
cpu/amd/agesa/family15tn: Add initial support for SMM mode
This is the minimal setup needed to be able to execute SMI handlers.
Only support for ASEG handlers is added, which should be sufficient
for Trinity (up to 4 cores).
There are a few hacks which need to be introduced in generic code in
order to make this work properly, but these hacks are self-contained.
They are a not a result of any special needs of this CPU, but rather
from a poorly designed infrastructure. Comments are added to explain
how such code could be refactored in the future.
Change-Id: Iefd4ae17cf0206cae8848cadba3a12cbe3b2f8b6
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Reviewed-on: http://review.coreboot.org/5493
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)gmail.com>
See http://review.coreboot.org/5493 for details.
-gerrit
the following patch was just integrated into master:
commit 342ac64a5d6f5ab639fb140ae69f9b3597878cba
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Mon Apr 14 16:44:19 2014 -0500
southbridge/hudson: Use MMIO instead of PIO to access PM space
The MMIO region is set up by AGESA very early on, so we can use it to
access the PM register space in ramstage. 16-bit accessors are also
provided to simplify some setup tasks. 16-bit accesses are not
possible via PIO.
The pm2_iowrite/read accessors are removed, as they are not used.
Change-Id: Ie7967b5086eb004525c39721338c6495aedc8165
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Reviewed-on: http://review.coreboot.org/5503
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)gmail.com>
See http://review.coreboot.org/5503 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/5501
-gerrit
commit aded7ad643fd8275827ef748156c06ff355d3de4
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Tue Apr 15 15:41:38 2014 -0500
cpu/amd/agesa/family15tn: Add udelay implementation for SMM
This is a small implementation which uses only MSRs and rdtsc, without
relying on northbridge or other system hardware. It's SMM safe in that
it only reads registers, and doesn't modify the state of the hardware.
Change-Id: Ifa02ca73455b382f830c9b30b80b4f1bb18706b4
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/cpu/amd/agesa/family15tn/Makefile.inc | 2 ++
src/cpu/amd/agesa/family15tn/udelay.c | 45 +++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/src/cpu/amd/agesa/family15tn/Makefile.inc b/src/cpu/amd/agesa/family15tn/Makefile.inc
index 19a2f0f..a8f644d 100644
--- a/src/cpu/amd/agesa/family15tn/Makefile.inc
+++ b/src/cpu/amd/agesa/family15tn/Makefile.inc
@@ -20,6 +20,8 @@
ramstage-y += chip_name.c
ramstage-y += model_15_init.c
+smm-$(CONFIG_HAVE_SMI_HANDLER) += udelay.c
+
subdirs-y += ../../mtrr
subdirs-y += ../../smm
subdirs-y += ../../../x86/tsc
diff --git a/src/cpu/amd/agesa/family15tn/udelay.c b/src/cpu/amd/agesa/family15tn/udelay.c
new file mode 100644
index 0000000..5873237
--- /dev/null
+++ b/src/cpu/amd/agesa/family15tn/udelay.c
@@ -0,0 +1,45 @@
+/*
+ * udelay() impementation for SMI handlers
+ * This is neat in that it never writes to hardware registers, and thus does not
+ * modify the state of the hardware while servicing SMIs.
+ *
+ * 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 <cpu/x86/msr.h>
+#include <cpu/x86/tsc.h>
+#include <delay.h>
+#include <stdint.h>
+
+void udelay(uint32_t us)
+{
+ uint8_t fid, did, pstate_idx;
+ uint64_t tsc_clock, tsc_start, tsc_now, tsc_wait_ticks;
+ msr_t msr;
+ const uint64_t tsc_base = 100000000;
+
+ /* Get initial timestamp before we do the math */
+ tsc_start = rdtscll();
+
+ /* Get the P-state. This determines which MSR to read */
+ msr = rdmsr(0xc0010063);
+ pstate_idx = msr.lo & 0x07;
+
+ /* Get FID and VID for current P-State */
+ msr = rdmsr(0xc0010064 + pstate_idx);
+
+ /* Extract the FID and VID values */
+ fid = msr.lo & 0x3f;
+ did = (msr.lo >> 6) & 0x7;
+
+ /* Calculate the CPU clock (from base freq of 100MHz) */
+ tsc_clock = tsc_base * (fid + 0x10) / (1 << did);
+
+ /* Now go on and wait */
+ tsc_wait_ticks = (tsc_clock / 1000000) * us;
+
+ do {
+ tsc_now = rdtscll();
+ } while (tsc_now - tsc_wait_ticks < tsc_start);
+}
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 65942a4dfbc32cd3eac4f2151546136f7d72838d
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/mainboard.c | 7 ++
.../hp/pavilion_m6_1035dx/mainboard_smi.c | 79 ++++++++++++++++++++++
5 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 ff9e7bb..917fdf2 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 SB_HT_CHAIN_UNITID_OFFSET_ONLY
select LIFT_BSP_APIC_ID
select SERIAL_CPU_INIT
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/mainboard.c b/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c
index 2e2b72b..08cc155 100644
--- a/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c
+++ b/src/mainboard/hp/pavilion_m6_1035dx/mainboard.c
@@ -30,6 +30,10 @@
#include <device/pci.h>
#include <device/pci_def.h>
+#include <southbridge/amd/agesa/hudson/smi.h>
+
+#define EC_SMI_GEVENT 23
+
/*************************************************
* enable the dedicated function in parmer board.
*************************************************/
@@ -39,6 +43,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..8c7fd3f
--- /dev/null
+++ b/src/mainboard/hp/pavilion_m6_1035dx/mainboard_smi.c
@@ -0,0 +1,79 @@
+/*
+ * 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 <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 EC_SMI_GEVENT (1 << 23)
+
+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();
+}