riscv-pke/spike_interface/spike_memory.c

69 lines
1.8 KiB
C

/*
* scanning the emulated memory from the DTS (Device Tree String).
* output: the availability and the size (stored in "uint64 g_mem_size") of emulated memory.
*
* codes are borrowed from riscv-pk (https://github.com/riscv/riscv-pk)
*/
#include "dts_parse.h"
#include "spike_interface/spike_utils.h"
#include "string.h"
uint64 g_mem_size;
struct mem_scan {
int memory;
const uint32 *reg_value;
int reg_len;
};
static void mem_open(const struct fdt_scan_node *node, void *extra) {
struct mem_scan *scan = (struct mem_scan *)extra;
memset(scan, 0, sizeof(*scan));
}
static void mem_prop(const struct fdt_scan_prop *prop, void *extra) {
struct mem_scan *scan = (struct mem_scan *)extra;
if (!strcmp(prop->name, "device_type") && !strcmp((const char *)prop->value, "memory")) {
scan->memory = 1;
} else if (!strcmp(prop->name, "reg")) {
scan->reg_value = prop->value;
scan->reg_len = prop->len;
}
}
static void mem_done(const struct fdt_scan_node *node, void *extra) {
struct mem_scan *scan = (struct mem_scan *)extra;
const uint32 *value = scan->reg_value;
const uint32 *end = value + scan->reg_len / 4;
uint64 self = (uint64)mem_done;
if (!scan->memory) return;
assert(scan->reg_value && scan->reg_len % 4 == 0);
while (end - value > 0) {
uint64 base, size;
value = fdt_get_address(node->parent, value, &base);
value = fdt_get_size(node->parent, value, &size);
if (base <= self && self <= base + size) {
g_mem_size = size;
}
}
assert(end == value);
}
// scanning the emulated memory
void query_mem(uint64 fdt) {
struct fdt_cb cb;
struct mem_scan scan;
memset(&cb, 0, sizeof(cb));
cb.open = mem_open;
cb.prop = mem_prop;
cb.done = mem_done;
cb.extra = &scan;
g_mem_size = 0;
fdt_scan(fdt, &cb);
assert(g_mem_size > 0);
}