Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /* Copyright 2013-2017 IBM Corp. */
3 : :
4 : : #include <stdint.h>
5 : : #include <stdlib.h>
6 : : #include <stdio.h>
7 : :
8 : : #include <libfdt/libfdt.h>
9 : : #include <skiboot.h>
10 : : #include <device.h>
11 : : #include <compiler.h>
12 : : #include <hostservices.h>
13 : :
14 : : #include "spira.h"
15 : : #include "hdata.h"
16 : :
17 : 3 : static void merge_property(const struct dt_node *src_root,
18 : : struct dt_node *dst_root,
19 : : const char *name)
20 : : {
21 : : const struct dt_property *src;
22 : : struct dt_property *dst;
23 : :
24 : : /* Nothing to merge if old one doesn't exist. */
25 : 3 : src = dt_find_property(src_root, name);
26 : 3 : if (!src)
27 : 3 : return;
28 : :
29 : : /* Just create a new one if there's none in dst. */
30 : 3 : dst = __dt_find_property(dst_root, name);
31 : 3 : if (!dst) {
32 : 3 : dt_add_property(dst_root, name, src->prop, src->len);
33 : 3 : return;
34 : : }
35 : :
36 : : /* Append src to dst. */
37 : 0 : dt_resize_property(&dst, dst->len + src->len);
38 : 0 : memcpy(dst->prop + dst->len, src->prop, src->len);
39 : : }
40 : :
41 : 1 : static void hservice_parse_dt_tree(const struct dt_node *src)
42 : : {
43 : : const struct dt_property *sprop;
44 : :
45 : : /* Copy/merge reserved names & ranges properties. */
46 : 6 : list_for_each(&src->properties, sprop, list) {
47 : 5 : if (streq(sprop->name, "reserved-names") ||
48 : 4 : streq(sprop->name, "reserved-ranges") ||
49 : 3 : streq(sprop->name, "ibm,enabled-idle-states"))
50 : 3 : merge_property(src, dt_root, sprop->name);
51 : : }
52 : 1 : }
53 : :
54 : : /* Get host services information from hdat. */
55 : 1 : bool hservices_from_hdat(const void *fdt, size_t size)
56 : : {
57 : : int err;
58 : : struct dt_node *hservices;
59 : :
60 : 1 : prlog(PR_DEBUG, "HBRT: Found mini-DT at 0x%p size: 0x%08lx\n",
61 : : fdt, size);
62 : :
63 : : /* For diagnostic purposes, we copy the whole blob over */
64 : 1 : dt_add_property(dt_root, "ibm,hbrt-mini-fdt", fdt, size);
65 : :
66 : : /* Parse & extract relevant properties */
67 : 1 : err = fdt_check_header(fdt);
68 : 1 : if (err) {
69 : 0 : prerror("HBRT: fdt blob %p hdr error %d\n", fdt, err);
70 : 0 : return false;
71 : : }
72 : :
73 : 1 : hservices = dt_new_root("ibm,hostservices");
74 : 1 : err = dt_expand_node(hservices, fdt, 0);
75 : 1 : if (err < 0) {
76 : 0 : prerror("HBRT: fdt blob %p parse error %d\n", fdt, err);
77 : 0 : return false;
78 : : }
79 : :
80 : 1 : hservice_parse_dt_tree(hservices);
81 : 1 : dt_free(hservices);
82 : 1 : return true;
83 : : }
84 : :
|