diff options
author | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-05-22 02:37:33 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-05-22 02:37:33 -0700 |
commit | 113d00e652fe6486a0ff76d0fa00557840529d58 (patch) | |
tree | f629b74d2f96874d30ffeb94f7ad386a28e1c791 /machine | |
parent | 1bcab7872c6ae98ab86cdc1a3f567fd263e723d7 (diff) | |
download | pk-113d00e652fe6486a0ff76d0fa00557840529d58.zip pk-113d00e652fe6486a0ff76d0fa00557840529d58.tar.gz pk-113d00e652fe6486a0ff76d0fa00557840529d58.tar.bz2 |
Add preliminary support for the interrupt controller
Diffstat (limited to 'machine')
-rw-r--r-- | machine/configstring.c | 40 | ||||
-rw-r--r-- | machine/encoding.h | 9 | ||||
-rw-r--r-- | machine/minit.c | 37 | ||||
-rw-r--r-- | machine/mtrap.h | 8 |
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 |