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 832a8abcf03938ac2d6394d058ec201888ab3024
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/include/arch/encoding.h | 6 +++
src/arch/riscv/trap_handler.c | 79 +++++++++++++++++++++++++++++++++-
src/arch/riscv/virtual_memory.c | 13 +++++-
3 files changed, 94 insertions(+), 4 deletions(-)
diff --git a/src/arch/riscv/include/arch/encoding.h b/src/arch/riscv/include/arch/encoding.h
index 9f9d8ca..d40446b 100644
--- a/src/arch/riscv/include/arch/encoding.h
+++ b/src/arch/riscv/include/arch/encoding.h
@@ -48,6 +48,11 @@
#define MSTATUS32_SD 0x80000000
#define MSTATUS64_SD 0x8000000000000000
+#define MIE_UTIE 0x00000010
+#define MIE_STIE 0x00000020
+#define MIE_HTIE 0x00000040
+#define MIE_MTIE 0x00000080
+
#define SSTATUS_UIE 0x00000001
#define SSTATUS_SIE 0x00000002
#define SSTATUS_UPIE 0x00000010
@@ -126,6 +131,7 @@
#define SIP_SSIP MIP_SSIP
#define SIP_STIP MIP_STIP
+#define SIE_STIE MIE_STIE
#define PRV_U 0
#define PRV_S 1
diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c
index c7a11c6..5681209 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 */
@@ -70,7 +74,7 @@ void handle_supervisor_call(trapframe *tf) {
returnValue = mcall_query_memory(arg0, (memory_block_info*) arg1);
break;
default:
- printk(BIOS_DEBUG, "ERROR! Unrecognized system call\n");
+ printk(BIOS_DEBUG, "ERROR! Unrecognized SBI call\n");
returnValue = 0;
break; // note: system call we do not know how to handle
}
@@ -130,8 +134,76 @@ 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 ssip, ssie;
+
+ switch (cause) {
+ case IRQ_M_TIMER:
+ // 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.
+
+ // This hart may have disabled timer interrupts. If
+ // so, just return. Kernels should only enable timer
+ // interrupts on one hart, and that should be hart 0
+ // at present, as we only search for
+ // "core{0{0{timecmp" above.
+ ssie = read_csr(sie);
+ if (!(ssie & SIE_STIE))
+ break;
+
+ if (!timecmp)
+ gettimer();
+ *timecmp = (uint64_t) -1;
+ ssip = read_csr(sip);
+ ssip |= SIP_STIP;
+ write_csr(sip, ssip);
+ break;
+ default:
+ printk(BIOS_EMERG, "======================================\n");
+ printk(BIOS_EMERG, "Coreboot: Unknown machine 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 +231,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..aceb72e 100644
--- a/src/arch/riscv/virtual_memory.c
+++ b/src/arch/riscv/virtual_memory.c
@@ -292,12 +292,21 @@ void initVirtualMemory(void) {
void mstatus_init(void)
{
uintptr_t ms = 0;
+
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 any pending timer interrupts.
+ clear_csr(mip, MIP_STIP | MIP_SSIP);
+
+ // enable machine and supervisor timer and
+ // all other supervisor interrupts.
+ set_csr(mie, MIP_MTIP | MIP_STIP | MIP_SSIP);
+
+ // Delegate supervisor timer and other interrupts
+ // to supervisor mode.
+ set_csr(mideleg, MIP_STIP | MIP_SSIP);
set_csr(medeleg, delegate);
Matt DeVillier (matt.devillier(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17912
-gerrit
commit ea8e611d5a716d4f1dd7ce75b7d2c1cb55237886
Author: Matt DeVillier <matt.devillier(a)gmail.com>
Date: Sat Dec 17 17:42:28 2016 -0600
soc/broadwell/acpi: Only include ec.asl if board has an EC
Conditional inclusion of board's ec.asl allows for removal of blank
ec.asl files for Broadwell devices without an EC (e.g., Chromeboxes)
Change-Id: I980bbc19c7c5b717fb8b7b1c36fee2621ec9c62e
Signed-off-by: Matt DeVillier <matt.devillier(a)gmail.com>
---
src/soc/intel/broadwell/acpi/lpc.asl | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/soc/intel/broadwell/acpi/lpc.asl b/src/soc/intel/broadwell/acpi/lpc.asl
index 70dd6e5..446dc90 100644
--- a/src/soc/intel/broadwell/acpi/lpc.asl
+++ b/src/soc/intel/broadwell/acpi/lpc.asl
@@ -199,6 +199,8 @@ Device (LPCB)
#include "gpio.asl"
#include "irqlinks.asl"
+#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
#include <acpi/ec.asl>
+#endif
#include <acpi/superio.asl>
}
the following patch was just integrated into master:
commit a01695bf9ac5ad401950af96682b494127ad8a8d
Author: Nico Huber <nico.h(a)gmx.de>
Date: Wed Dec 14 23:48:09 2016 +0100
Revert "arch/x86/smbios: Correct manufacturer ID"
This reverts commit c86da67436827c25919a2f5966049485a58fc984.
Alas, I have to disagree with this in every single line. The comment
added to the top of the file only applies to a single function therein
which sits over a hundred lines below. That's not much helpful. More-
over, the link in the comment is already down ofc.
The comment is also irritating as it doesn't state in which way (enco-
ding!) it applies to the code, which presumably led to the wrong in-
terpretation of the IDs.
At last, if anything should have changed it is the strings, the IDs
are resolved to. `smbios_fill_dimm_manufacturer_from_id()` has to
resolve the IDs it gets actually fed and not a random selection from
any spec.
Since I digged into it, here's why the numbers are correct: The func-
tion started with the SPD encoding of DDR3 in mind. There, the lower
byte is the number of a "bank" of IDs with an odd-parity in the upper
most bit. The upper byte is the ID within the bank. The "correction"
was to clear the parity bit for naught. The function was later exten-
ded with IDs in the DDR2-SPD encoding (which is actually 64-bit not
16). There, a byte, starting from the lowest, is either an ID below
127 plus odd-parity, or 127 which means look in the next byte/bank.
Unused bytes seem to be filled with 0xff, I guess from the 0xff2c.
Change-Id: Icdb48e4f2c102f619fbdca856e938e85135cfb18
Reviewed-on: https://review.coreboot.org/17873
Tested-by: build bot (Jenkins)
Reviewed-by: Matt DeVillier <matt.devillier(a)gmail.com>
Reviewed-by: HAOUAS Elyes <ehaouas(a)noos.fr>
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Reviewed-by: Martin Roth <martinroth(a)google.com>
See https://review.coreboot.org/17873 for details.
-gerrit