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