aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-05-22 02:37:33 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-05-22 02:37:33 -0700
commit113d00e652fe6486a0ff76d0fa00557840529d58 (patch)
treef629b74d2f96874d30ffeb94f7ad386a28e1c791
parent1bcab7872c6ae98ab86cdc1a3f567fd263e723d7 (diff)
downloadpk-113d00e652fe6486a0ff76d0fa00557840529d58.zip
pk-113d00e652fe6486a0ff76d0fa00557840529d58.tar.gz
pk-113d00e652fe6486a0ff76d0fa00557840529d58.tar.bz2
Add preliminary support for the interrupt controller
-rw-r--r--machine/configstring.c40
-rw-r--r--machine/encoding.h9
-rw-r--r--machine/minit.c37
-rw-r--r--machine/mtrap.h8
4 files changed, 90 insertions, 4 deletions
diff --git a/machine/configstring.c b/machine/configstring.c
index 2805c21..b47d067 100644
--- a/machine/configstring.c
+++ b/machine/configstring.c
@@ -20,6 +20,43 @@ static void query_rtc(const char* config_string)
mtime = (void*)(uintptr_t)get_uint(res);
}
+static void query_plic(const char* config_string)
+{
+ query_result res = query_config_string(config_string, "plic{priority");
+ if (!res.start)
+ return;
+ plic_priorities = (uint16_t*)(uintptr_t)get_uint(res);
+
+ res = query_config_string(config_string, "plic{ndevs");
+ if (!res.start)
+ return;
+ plic_ndevs = get_uint(res);
+}
+
+static void query_hart_plic(const char* config_string, hls_t* hls, int core, int hart)
+{
+ char buf[32];
+ snprintf(buf, sizeof buf, "core{%d{%d{plic{m{ie", core, hart);
+ query_result res = query_config_string(config_string, buf);
+ if (res.start)
+ hls->plic_m_ie = (void*)(uintptr_t)get_uint(res);
+
+ snprintf(buf, sizeof buf, "core{%d{%d{plic{m{thresh", core, hart);
+ res = query_config_string(config_string, buf);
+ if (res.start)
+ hls->plic_m_thresh = (void*)(uintptr_t)get_uint(res);
+
+ snprintf(buf, sizeof buf, "core{%d{%d{plic{s{ie", core, hart);
+ res = query_config_string(config_string, buf);
+ if (res.start)
+ hls->plic_s_ie = (void*)(uintptr_t)get_uint(res);
+
+ snprintf(buf, sizeof buf, "core{%d{%d{plic{s{thresh", core, hart);
+ res = query_config_string(config_string, buf);
+ if (res.start)
+ hls->plic_s_thresh = (void*)(uintptr_t)get_uint(res);
+}
+
static void query_harts(const char* config_string)
{
for (int core = 0, hart; ; core++) {
@@ -32,6 +69,8 @@ static void query_harts(const char* config_string)
hls_t* hls = hls_init(num_harts);
hls->ipi = (void*)(uintptr_t)get_uint(res);
+ query_hart_plic(config_string, hls, core, hart);
+
snprintf(buf, sizeof buf, "core{%d{%d{timecmp", core, hart);
res = query_config_string(config_string, buf);
assert(res.start);
@@ -51,6 +90,7 @@ void parse_config_string()
uint32_t addr = *(uint32_t*)CONFIG_STRING_ADDR;
const char* s = (const char*)(uintptr_t)addr;
query_mem(s);
+ query_plic(s);
query_rtc(s);
query_harts(s);
}
diff --git a/machine/encoding.h b/machine/encoding.h
index 5405148..bdba5f2 100644
--- a/machine/encoding.h
+++ b/machine/encoding.h
@@ -39,6 +39,9 @@
#define MIP_STIP (1 << IRQ_S_TIMER)
#define MIP_HTIP (1 << IRQ_H_TIMER)
#define MIP_MTIP (1 << IRQ_M_TIMER)
+#define MIP_SEIP (1 << IRQ_S_EXT)
+#define MIP_HEIP (1 << IRQ_H_EXT)
+#define MIP_MEIP (1 << IRQ_M_EXT)
#define SIP_SSIP MIP_SSIP
#define SIP_STIP MIP_STIP
@@ -61,9 +64,9 @@
#define IRQ_S_TIMER 5
#define IRQ_H_TIMER 6
#define IRQ_M_TIMER 7
-#define IRQ_S_DEV 9
-#define IRQ_H_DEV 10
-#define IRQ_M_DEV 11
+#define IRQ_S_EXT 9
+#define IRQ_H_EXT 10
+#define IRQ_M_EXT 11
#define IRQ_COP 12
#define IRQ_HOST 13
diff --git a/machine/minit.c b/machine/minit.c
index b8a67c0..661a20a 100644
--- a/machine/minit.c
+++ b/machine/minit.c
@@ -3,12 +3,15 @@
#include "vm.h"
#include "fp_emulation.h"
#include <string.h>
+#include <limits.h>
pte_t* root_page_table;
uintptr_t first_free_paddr;
uintptr_t mem_size;
uintptr_t num_harts;
volatile uint64_t* mtime;
+volatile uint16_t* plic_priorities;
+size_t plic_ndevs;
static void mstatus_init()
{
@@ -31,7 +34,7 @@ static void mstatus_init()
// send S-mode interrupts and most exceptions straight to S-mode
static void delegate_traps()
{
- uintptr_t interrupts = MIP_SSIP | MIP_STIP;
+ uintptr_t interrupts = MIP_SSIP | MIP_STIP | MIP_SEIP;
uintptr_t exceptions =
(1U << CAUSE_MISALIGNED_FETCH) |
(1U << CAUSE_FAULT_FETCH) |
@@ -89,11 +92,42 @@ static void hart_init()
delegate_traps();
}
+static void plic_init()
+{
+ for (size_t i = 1; i <= plic_ndevs; i++)
+ plic_priorities[i] = 1;
+}
+
+static void hart_plic_init()
+{
+ if (!plic_ndevs)
+ return;
+
+ size_t ie_words = plic_ndevs / sizeof(uintptr_t) + 1;
+ for (size_t i = 0; i < ie_words; i++)
+ HLS()->plic_s_ie[i] = ULONG_MAX;
+ *HLS()->plic_m_thresh = 1;
+ *HLS()->plic_s_thresh = 0;
+
+ int x;
+ while ((x = HLS()->plic_s_thresh[1]))
+ printm("%d\n", x);
+ HLS()->plic_s_thresh[1] = 1;
+ HLS()->plic_s_thresh[1] = 3;
+ *((char*)plic_priorities + 0x805) = 1;
+ while ((x = HLS()->plic_s_thresh[1])) {
+ printm("%d\n", x);
+ *HLS()->plic_s_thresh = 1;
+ }
+}
+
void init_first_hart()
{
hart_init();
hls_init(0); // this might get called again from parse_config_string
parse_config_string();
+ plic_init();
+ hart_plic_init();
memory_init();
boot_loader();
}
@@ -106,6 +140,7 @@ void init_other_hart()
while (*(uint64_t * volatile *)&HLS()->timecmp == NULL)
;
+ hart_plic_init();
boot_other_hart();
}
diff --git a/machine/mtrap.h b/machine/mtrap.h
index b859a63..3a6fb22 100644
--- a/machine/mtrap.h
+++ b/machine/mtrap.h
@@ -13,6 +13,7 @@
#include "sbi.h"
#include <stdint.h>
+#include <stddef.h>
#define read_const_csr(reg) ({ unsigned long __tmp; \
asm ("csrr %0, " #reg : "=r"(__tmp)); \
@@ -32,6 +33,8 @@ extern uintptr_t first_free_paddr;
extern uintptr_t mem_size;
extern uintptr_t num_harts;
extern volatile uint64_t* mtime;
+extern volatile uint16_t* plic_priorities;
+extern size_t plic_ndevs;
typedef struct {
uint64_t* timecmp;
@@ -46,6 +49,11 @@ typedef struct {
uint64_t stime_delta;
uint64_t scycle_delta;
uint64_t sinstret_delta;
+
+ volatile uint16_t* plic_m_thresh;
+ volatile uintptr_t* plic_m_ie;
+ volatile uint16_t* plic_s_thresh;
+ volatile uintptr_t* plic_s_ie;
} hls_t;
#define IPI_SOFT 0x1