3 changed files with 0 additions and 270 deletions
@ -1,102 +0,0 @@ |
|||
#include "configstring.h" |
|||
#include "encoding.h" |
|||
#include "mtrap.h" |
|||
#include "atomic.h" |
|||
#include <stdio.h> |
|||
|
|||
static void query_mem(const char* config_string) |
|||
{ |
|||
query_result res = query_config_string(config_string, "ram{0{addr"); |
|||
assert(res.start); |
|||
uintptr_t base = get_uint(res); |
|||
assert(base == DRAM_BASE); |
|||
res = query_config_string(config_string, "ram{0{size"); |
|||
mem_size = get_uint(res); |
|||
} |
|||
|
|||
static void query_rtc(const char* config_string) |
|||
{ |
|||
query_result res = query_config_string(config_string, "rtc{addr"); |
|||
assert(res.start); |
|||
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 = (uint32_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[48]; |
|||
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++) { |
|||
for (hart = 0; ; hart++) { |
|||
char buf[40]; |
|||
snprintf(buf, sizeof buf, "core{%d{%d{ipi", core, hart); |
|||
query_result res = query_config_string(config_string, buf); |
|||
if (!res.start) |
|||
break; |
|||
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); |
|||
hls->timecmp = (void*)(uintptr_t)get_uint(res); |
|||
|
|||
mb(); |
|||
|
|||
// wake up the hart
|
|||
*hls->ipi = 1; |
|||
|
|||
num_harts++; |
|||
} |
|||
if (!hart) |
|||
break; |
|||
} |
|||
assert(num_harts); |
|||
assert(num_harts <= MAX_HARTS); |
|||
} |
|||
|
|||
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); |
|||
} |
|||
@ -1,166 +0,0 @@ |
|||
#ifndef RISCV_CONFIG_STRING_H |
|||
#define RISCV_CONFIG_STRING_H |
|||
|
|||
#include <stddef.h> |
|||
#include <stdint.h> |
|||
|
|||
static const char* skip_whitespace(const char* str) |
|||
{ |
|||
while (*str && *str <= ' ') |
|||
str++; |
|||
return str; |
|||
} |
|||
|
|||
static const char* skip_string(const char* str) |
|||
{ |
|||
while (*str && *str++ != '"') |
|||
; |
|||
return str; |
|||
} |
|||
|
|||
static int is_hex(char ch) |
|||
{ |
|||
return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); |
|||
} |
|||
|
|||
static int parse_hex(char ch) |
|||
{ |
|||
return (ch >= '0' && ch <= '9') ? ch - '0' : |
|||
(ch >= 'a' && ch <= 'f') ? ch - 'a' + 10 : |
|||
ch - 'A' + 10; |
|||
} |
|||
|
|||
static const char* skip_key(const char* str) |
|||
{ |
|||
while (*str >= 35 && *str <= 122 && *str != ';') |
|||
str++; |
|||
return str; |
|||
} |
|||
|
|||
typedef struct { |
|||
const char* start; |
|||
const char* end; |
|||
} query_result; |
|||
|
|||
static query_result query_config_string(const char* str, const char* k) |
|||
{ |
|||
size_t ksize = 0; |
|||
while (k[ksize] && k[ksize] != '{') |
|||
ksize++; |
|||
int last = !k[ksize]; |
|||
|
|||
query_result res = {0, 0}; |
|||
while (1) { |
|||
const char* key_start = str = skip_whitespace(str); |
|||
const char* key_end = str = skip_key(str); |
|||
int match = (size_t)(key_end - key_start) == ksize; |
|||
if (match) |
|||
for (size_t i = 0; i < ksize; i++) |
|||
if (key_start[i] != k[i]) |
|||
match = 0; |
|||
const char* value_start = str = skip_whitespace(str); |
|||
while (*str != ';') { |
|||
if (!*str) { |
|||
return res; |
|||
} else if (*str == '"') { |
|||
str = skip_string(str+1); |
|||
} else if (*str == '{') { |
|||
const char* search_key = match && !last ? k + ksize + 1 : ""; |
|||
query_result inner_res = query_config_string(str + 1, search_key); |
|||
if (inner_res.start) |
|||
return inner_res; |
|||
str = inner_res.end + 1; |
|||
} else { |
|||
str = skip_key(str); |
|||
} |
|||
str = skip_whitespace(str); |
|||
} |
|||
res.end = str; |
|||
if (match && last) { |
|||
res.start = value_start; |
|||
return res; |
|||
} |
|||
str = skip_whitespace(str+1); |
|||
if (*str == '}') { |
|||
res.end = str; |
|||
return res; |
|||
} |
|||
} |
|||
} |
|||
|
|||
static void parse_string(query_result r, char* buf) |
|||
{ |
|||
if (r.start < r.end) { |
|||
if (*r.start == '"') { |
|||
for (const char* p = r.start + 1; p < r.end && *p != '"'; p++) { |
|||
char ch = p[0]; |
|||
if (ch == '\\' && p[1] == 'x' && is_hex(p[2])) { |
|||
ch = parse_hex(p[2]); |
|||
if (is_hex(p[3])) { |
|||
ch = (ch << 4) + parse_hex(p[3]); |
|||
p++; |
|||
} |
|||
p += 2; |
|||
} |
|||
*buf++ = ch; |
|||
} |
|||
} else { |
|||
for (const char* p = r.start; p < r.end && *p > ' '; p++) |
|||
*buf++ = *p; |
|||
} |
|||
} |
|||
*buf = 0; |
|||
} |
|||
|
|||
#define get_string(name, search_res) \ |
|||
char name[(search_res).end - (search_res).start + 1]; \ |
|||
parse_string(search_res, name) |
|||
|
|||
static uint64_t __get_uint_hex(const char* s) |
|||
{ |
|||
uint64_t res = 0; |
|||
while (*s) { |
|||
if (is_hex(*s)) |
|||
res = (res << 4) + parse_hex(*s); |
|||
else if (*s != '_') |
|||
break; |
|||
s++; |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
static uint64_t __get_uint_dec(const char* s) |
|||
{ |
|||
uint64_t res = 0; |
|||
while (*s) { |
|||
if (*s >= '0' && *s <= '9') |
|||
res = res * 10 + (*s - '0'); |
|||
else |
|||
break; |
|||
s++; |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
static uint64_t __get_uint(const char* s) |
|||
{ |
|||
if (s[0] == '0' && s[1] == 'x') |
|||
return __get_uint_hex(s+2); |
|||
return __get_uint_dec(s); |
|||
} |
|||
|
|||
static inline uint64_t get_uint(query_result res) |
|||
{ |
|||
get_string(s, res); |
|||
return __get_uint(s); |
|||
} |
|||
|
|||
static inline int64_t get_sint(query_result res) |
|||
{ |
|||
get_string(s, res); |
|||
if (s[0] == '-') |
|||
return -__get_uint(s+1); |
|||
return __get_uint(s); |
|||
} |
|||
|
|||
#endif |
|||
Loading…
Reference in new issue