Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17807
-gerrit
commit 89eedeca495e13118242019254c55a0aa71d6779
Author: Ronald G. Minnich <rminnich(a)gmail.com>
Date: Mon Dec 12 15:09:42 2016 -0800
riscv: Add support for timer interrupts
RISCV requires that timer interrupts be handled in machine
mode and delegated as necessary. Also you can only reset the
timer interrupt by writing to mtimecmp. Further, you must
write a number > mtime, not just != mtime. This rather clumsy
situation requires that we write some value into the future
into mtimecmp lest we never be able to leave machine mode as
the interrupt either is not cleared or instantly reoccurs.
This current code is tested and works for harvey (Plan 9)
timer interrupts.
Change-Id: I8538d5fd8d80d9347773c638f5cbf0da18dc1cae
Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com>
---
src/arch/riscv/trap_handler.c | 68 ++++++++++++++++++++++++++++++++++++++++-
src/arch/riscv/virtual_memory.c | 6 ++--
2 files changed, 71 insertions(+), 3 deletions(-)
diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c
index c7a11c6..ec11c06 100644
--- a/src/arch/riscv/trap_handler.c
+++ b/src/arch/riscv/trap_handler.c
@@ -20,6 +20,10 @@
#include <mcall.h>
#include <string.h>
#include <vm.h>
+#include <commonlib/configstring.h>
+
+static uint64_t *time;
+static uint64_t *timecmp;
void handle_supervisor_call(trapframe *tf) {
uintptr_t call = tf->gpr[17]; /* a7 */
@@ -130,8 +134,67 @@ static void print_trap_information(const trapframe *tf)
printk(BIOS_DEBUG, "Stored sp: %p\n", (void*) tf->gpr[2]);
}
-void trap_handler(trapframe *tf) {
+static void gettimer(void)
+{
+ query_result res;
+ const char *config;
+
+ config = configstring();
+ query_rtc(config, (uintptr_t *)&time);
+ if (!time)
+ die("Got timer interrupt but found no timer.");
+ res = query_config_string(config, "core{0{0{timecmp");
+ timecmp = (void *)get_uint(res);
+ if (!timecmp)
+ die("Got a timer interrupt but found no timecmp.");
+}
+
+static void interrupt_handler(trapframe *tf)
+{
+ uint64_t cause = tf->cause & ~0x8000000000000000ULL;
+ uint32_t c;
+
+ switch (cause) {
+ case 7:
+ // The only way to reset the timer interrupt is to
+ // write mtimecmp. But we also have to ensure the
+ // comparison fails, for a long time, to let
+ // supervisor interrupt handler compute a new value
+ // and set it. Finally, it fires if mtimecmp is <=
+ // mtime, not =, so setting mtimecmp to 0 won't work
+ // to clear the interrupt and disable a new one. We
+ // have to set the mtimecmp far into the future.
+ // Akward!
+ //
+ // Further, maybe the platform doesn't have the
+ // hardware or the payload never uses it. We hold off
+ // querying some things until we are sure we need
+ // them. What to do if we can not find them? There are
+ // no good options.
+ if (!timecmp)
+ gettimer();
+ *timecmp = *time + 0x10000;
+ c = read_csr(mip);
+ c |= MIP_STIP;
+ c &= ~MIP_MTIP;
+ write_csr(sip, c);
+ break;
+ default:
+ printk(BIOS_EMERG, "======================================\n");
+ printk(BIOS_EMERG, "Coreboot: can not interrupt: 0x%llx\n",
+ cause);
+ printk(BIOS_EMERG, "======================================\n");
+ print_trap_information(tf);
+ break;
+ }
+}
+void trap_handler(trapframe *tf)
+{
write_csr(mscratch, tf);
+ if (tf->cause & 0x8000000000000000ULL) {
+ interrupt_handler(tf);
+ return;
+ }
switch(tf->cause) {
case CAUSE_MISALIGNED_FETCH:
@@ -159,6 +222,9 @@ void trap_handler(trapframe *tf) {
handle_supervisor_call(tf);
break;
default:
+ printk(BIOS_EMERG, "================================\n");
+ printk(BIOS_EMERG, "Coreboot: can not handle a trap:\n");
+ printk(BIOS_EMERG, "================================\n");
print_trap_information(tf);
break;
}
diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c
index 26a0169..8ee3ece 100644
--- a/src/arch/riscv/virtual_memory.c
+++ b/src/arch/riscv/virtual_memory.c
@@ -292,12 +292,14 @@ void initVirtualMemory(void) {
void mstatus_init(void)
{
uintptr_t ms = 0;
+ uintptr_t ints = MIP_STIP | MIP_SSIP;
ms = INSERT_FIELD(ms, MSTATUS_FS, 3);
ms = INSERT_FIELD(ms, MSTATUS_XS, 3);
write_csr(mstatus, ms);
- clear_csr(mip, MIP_MSIP);
- set_csr(mie, MIP_MSIP);
+ clear_csr(mip, ints);
+ set_csr(mie, MIP_MTIP | ints);
+ set_csr(mideleg, ints);
set_csr(medeleg, delegate);
Kyösti Mälkki (kyosti.malkki(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17805
-gerrit
commit 462469bd2a30bd54cb688407350e4fd1ceee131b
Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Date: Sun Dec 11 15:54:11 2016 +0200
intel/i82801ix: Add HAVE_INTEL_FIRMWARE
Select this to provide menu in menuconfig to add flash
descriptor file. ME or GbE firmwares themselves are not
required, but integrated NIC MAC and SPI configuration
fields are still useful.
Change-Id: I14b86e2f38ec39924d2cbf0932d82f66ed356a03
Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
---
src/southbridge/intel/i82801ix/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/southbridge/intel/i82801ix/Kconfig b/src/southbridge/intel/i82801ix/Kconfig
index b3e5069..e4d1f91 100644
--- a/src/southbridge/intel/i82801ix/Kconfig
+++ b/src/southbridge/intel/i82801ix/Kconfig
@@ -24,6 +24,7 @@ config SOUTHBRIDGE_INTEL_I82801IX
select HAVE_SMI_HANDLER
select HAVE_USBDEBUG_OPTIONS
select SOUTHBRIDGE_INTEL_COMMON_GPIO
+ select HAVE_INTEL_FIRMWARE
if SOUTHBRIDGE_INTEL_I82801IX
Kyösti Mälkki (kyosti.malkki(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17794
-gerrit
commit 86e6407bf9f8dde6e1c66e76f58a91ea7d8a547c
Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Date: Sun Dec 11 13:31:17 2016 +0200
ACPI S3: Signal successful boot
Just before jumping to OS wakeup vector do the same
tasks to signal coreboot completion that would be done
before entry to payload on normal boot path.
Change-Id: I7514c498f40f2d93a4e83a232ef4665f5c21f062
Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
---
src/arch/x86/acpi_s3.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/arch/x86/acpi_s3.c b/src/arch/x86/acpi_s3.c
index 0fc1914..0001885 100644
--- a/src/arch/x86/acpi_s3.c
+++ b/src/arch/x86/acpi_s3.c
@@ -18,6 +18,7 @@
#include <arch/acpi.h>
#include <cbmem.h>
#include <cpu/cpu.h>
+#include <fallback.h>
#include <timestamp.h>
#include <program_loading.h>
#include <romstage_handoff.h>
@@ -230,6 +231,8 @@ static void acpi_jump_to_wakeup(void *vector)
/* Copy wakeup trampoline in place. */
memcpy((void *)WAKEUP_BASE, &__wakeup, __wakeup_size);
+ set_boot_successful();
+
timestamp_add_now(TS_ACPI_WAKE_JUMP);
acpi_do_wakeup((uintptr_t)vector, source, target, size);