[platform][qemu-riscv] Fixup qemu-riscv target

-Fix plic driver to handle machine vs supervisor mode
-Add switch to scripts/do-qemuriscv to run in supervisor mode (with OpenSBI)
-Use the FDT to detect the number of cpus and size of memory
This commit is contained in:
Travis Geiselbrecht
2020-01-19 14:47:25 -08:00
parent 4d080aaef9
commit 9c71a0ec57
6 changed files with 85 additions and 24 deletions

View File

@@ -6,6 +6,7 @@
* https://opensource.org/licenses/MIT
*/
#include <lk/reg.h>
#include <lk/trace.h>
#include <kernel/thread.h>
#include <kernel/novm.h>
#include <platform.h>
@@ -18,16 +19,23 @@
#include "platform_p.h"
#define LOCAL_TRACE 1
extern ulong lk_boot_args[4];
static int cpu_count = 0;
void platform_early_init(void) {
plic_early_init();
LTRACEF("starting FDT scan\n");
/* look for a flattened device tree in the second arg passed to us */
bool found_mem = false;
const void *fdt = (void *)lk_boot_args[1];
int err = fdt_check_header(fdt);
if (err >= 0) {
/* walk the nodes, looking for 'memory@*' */
/* walk the nodes */
int depth = 0;
int offset = 0;
for (;;) {
@@ -40,23 +48,42 @@ void platform_early_init(void) {
if (!name)
continue;
LTRACEF_LEVEL(2, "name '%s', depth %d\n", name, depth);
/* look for the 'memory@*' property */
if (strncmp(name, "memory@", 7) == 0) {
if (!found_mem && strncmp(name, "memory@", 7) == 0 && depth == 1) {
int lenp;
const void *prop_ptr = fdt_getprop(fdt, offset, "reg", &lenp);
if (prop_ptr && lenp == 0x10) {
/* we're looking at a memory descriptor */
uint64_t base = fdt64_to_cpu(*(uint64_t *)prop_ptr);
uint64_t base = fdt64_to_cpu(*(const uint64_t *)prop_ptr);
uint64_t len = fdt64_to_cpu(*((const uint64_t *)prop_ptr + 1));
/* add another novm arena */
printf("FDT: found memory arena, base %#llx size %#llx\n", base, len);
novm_add_arena("fdt", base, len);
break; // stop searching after the first one
found_mem = true; // stop searching after the first one
}
}
/* look for a cpu leaf and count the number of cpus */
if (strncmp(name, "cpu@", 4) == 0 && depth == 2) {
int lenp;
const void *prop_ptr = fdt_getprop(fdt, offset, "reg", &lenp);
if (prop_ptr && lenp == 0x4) {
uint32_t id = fdt32_to_cpu(*(const uint32_t *)prop_ptr);
printf("FDT: found cpu id %u\n", id);
cpu_count++;
}
}
}
}
if (cpu_count > 0) {
riscv_set_secondary_count(cpu_count - 1);
}
LTRACEF("done scanning FDT\n");
}
void platform_init(void) {