You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
1.8 KiB
69 lines
1.8 KiB
/*
|
|
* 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);
|
|
}
|