Browse Source

fdt: look for the phandle of a cpu's nested interrupt controller

pull/53/head
Wesley W. Terpstra 9 years ago
parent
commit
52d46dd684
  1. 49
      machine/fdt.c

49
machine/fdt.c

@ -168,28 +168,34 @@ void query_mem(uintptr_t fdt)
static uint32_t hart_phandles[MAX_HARTS];
struct hart_scan {
int cpu;
int controller;
int cells;
const struct fdt_scan_node *cpu;
int hart;
const struct fdt_scan_node *controller;
int cells;
uint32_t phandle;
};
static void hart_open(const struct fdt_scan_node *node, void *extra)
{
struct hart_scan *scan = (struct hart_scan *)extra;
memset(scan, 0, sizeof(*scan));
scan->cells = -1;
scan->hart = -1;
if (!scan->cpu) {
scan->hart = -1;
}
if (!scan->controller) {
scan->cells = 0;
scan->phandle = 0;
}
}
static void hart_prop(const struct fdt_scan_prop *prop, void *extra)
{
struct hart_scan *scan = (struct hart_scan *)extra;
if (!strcmp(prop->name, "device_type") && !strcmp((const char*)prop->value, "cpu")) {
scan->cpu = 1;
assert (!scan->cpu);
scan->cpu = prop->node;
} else if (!strcmp(prop->name, "interrupt-controller")) {
scan->controller = 1;
assert (!scan->controller);
scan->controller = prop->node;
} else if (!strcmp(prop->name, "#interrupt-cells")) {
scan->cells = bswap(prop->value[0]);
} else if (!strcmp(prop->name, "phandle")) {
@ -205,26 +211,39 @@ static void hart_done(const struct fdt_scan_node *node, void *extra)
{
struct hart_scan *scan = (struct hart_scan *)extra;
if (!scan->cpu) return;
assert (scan->controller == 1);
assert (scan->cells == 1);
assert (scan->hart >= 0);
if (scan->cpu == node) {
assert (scan->hart >= 0);
}
if (scan->controller == node && scan->cpu) {
assert (scan->phandle > 0);
assert (scan->cells == 1);
if (scan->hart < MAX_HARTS) {
hart_phandles[scan->hart] = scan->phandle;
if (scan->hart >= num_harts) num_harts = scan->hart + 1;
if (scan->hart < MAX_HARTS) {
hart_phandles[scan->hart] = scan->phandle;
if (scan->hart >= num_harts) num_harts = scan->hart + 1;
}
}
}
static void hart_close(const struct fdt_scan_node *node, void *extra)
{
struct hart_scan *scan = (struct hart_scan *)extra;
if (scan->cpu == node) scan->cpu = 0;
if (scan->controller == node) scan->controller = 0;
}
void query_harts(uintptr_t fdt)
{
struct fdt_cb cb;
struct hart_scan scan;
memset(&cb, 0, sizeof(cb));
memset(&scan, 0, sizeof(scan));
cb.open = hart_open;
cb.prop = hart_prop;
cb.done = hart_done;
cb.close= hart_close;
cb.extra = &scan;
num_harts = 0;

Loading…
Cancel
Save