blob: ea58e02b2e2f4dc8ee45835dd5caa336771c8ce1 [file] [log] [blame]
Xiang Wang411a8b72019-01-23 11:45:06 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2019 HardenedLinux
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <stdint.h>
17#include <string.h>
18#include <soc/otp.h>
19#include <soc/sdram.h>
20#include <cbfs.h>
21#include <device_tree.h>
22#include <bootstate.h>
23#include <mcall.h>
24
25static void do_fixup_mac(struct device_tree_node *node)
26{
27 uint32_t serial = otp_read_serial();
28 static unsigned char mac[6] = { 0x70, 0xb3, 0xd5, 0x92, 0xf0, 0x00 };
29 if (serial != ~0) {
30 mac[5] |= (serial >> 0) & 0xff;
31 mac[4] |= (serial >> 8) & 0xff;
32 mac[3] |= (serial >> 16) & 0xff;
33 }
34 dt_add_bin_prop(node, "local-mac-address", mac, 6);
35}
36
37static void fixup_mac(struct device_tree_node *parent)
38{
39 struct device_tree_property *prop;
40 const char *name = "local-mac-address";
41
42 list_for_each(prop, parent->properties, list_node) {
43 if (!strcmp(name, prop->prop.name))
44 do_fixup_mac(parent);
45 }
46
47 struct device_tree_node *child;
48 list_for_each(child, parent->children, list_node) {
49 fixup_mac(child);
50 }
51}
52
53static void do_fixup_memory(struct device_tree_node *node)
54{
55 u64 addrs[1], sizes[1];
56 addrs[0] = 0x80000000;
57 sizes[0] = sdram_size_mb() * 1024 * 1024;
58 dt_add_reg_prop(node, addrs, sizes, 1, 2, 2);
59}
60
61
62static void fixup_memory(struct device_tree_node *parent)
63{
64 struct device_tree_property *prop;
65 const char *name = "device_type";
66 const char *value = "memory";
67
68 list_for_each(prop, parent->properties, list_node) {
69 if (!strcmp(name, prop->prop.name)) {
70 if (!strcmp(value, (char *)prop->prop.data))
71 do_fixup_memory(parent);
72 }
73 }
74
75 struct device_tree_node *child;
76 list_for_each(child, parent->children, list_node) {
77 fixup_memory(child);
78 }
79}
80
81static void fixup_fdt(void *unused)
82{
83 void *fdt_rom;
84 struct device_tree *tree;
85
86 /* load flat dt from cbfs */
87 fdt_rom = cbfs_boot_map_with_leak("fallback/DTB", CBFS_TYPE_RAW, NULL);
88
89 /* Expand DT into a tree */
90 tree = fdt_unflatten(fdt_rom);
91
92 /* fixup tree */
93 fixup_mac(tree->root);
94 fixup_memory(tree->root);
95
96 /* convert the tree to a flat dt */
97 void *dt = malloc(dt_flat_size(tree));
98 dt_flatten(tree, dt);
99
100 /* update HLS */
101 for (int i = 0; i < CONFIG_MAX_CPUS; i++)
102 OTHER_HLS(i)->fdt = dt;
103}
104
105BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_EXIT, fixup_fdt, NULL);