1// See LICENSE for license details. 2 3#include <string.h> 4#include "finisher.h" 5#include "fdt.h" 6 7volatile uint32_t* finisher; 8 9void finisher_exit(uint16_t code) 10{ 11 if (!finisher) return; 12 if (code == 0) { 13 *finisher = FINISHER_PASS; 14 } else { 15 *finisher = code << 16 | FINISHER_FAIL; 16 } 17} 18 19struct finisher_scan 20{ 21 int compat; 22 uint64_t reg; 23}; 24 25static void finisher_open(const struct fdt_scan_node *node, void *extra) 26{ 27 struct finisher_scan *scan = (struct finisher_scan *)extra; 28 memset(scan, 0, sizeof(*scan)); 29} 30 31static void finisher_prop(const struct fdt_scan_prop *prop, void *extra) 32{ 33 struct finisher_scan *scan = (struct finisher_scan *)extra; 34 if (!strcmp(prop->name, "compatible") && !strcmp((const char*)prop->value, "sifive,test0")) { 35 scan->compat = 1; 36 } else if (!strcmp(prop->name, "reg")) { 37 fdt_get_address(prop->node->parent, prop->value, &scan->reg); 38 } 39} 40 41static void finisher_done(const struct fdt_scan_node *node, void *extra) 42{ 43 struct finisher_scan *scan = (struct finisher_scan *)extra; 44 if (!scan->compat || !scan->reg || finisher) return; 45 finisher = (uint32_t*)(uintptr_t)scan->reg; 46} 47 48void query_finisher(uintptr_t fdt) 49{ 50 struct fdt_cb cb; 51 struct finisher_scan scan; 52 53 memset(&cb, 0, sizeof(cb)); 54 cb.open = finisher_open; 55 cb.prop = finisher_prop; 56 cb.done = finisher_done; 57 cb.extra = &scan; 58 59 fdt_scan(fdt, &cb); 60} 61