blob: c270857667122df006bb63e48355d0d412d1840e [file] [log] [blame]
Angel Pons274a0372020-04-03 01:23:27 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Xiang Wang411a8b72019-01-23 11:45:06 +08003
4#include <stdint.h>
Elyes HAOUAS70a03dd2019-12-02 20:47:50 +01005#include <stdlib.h>
Xiang Wang411a8b72019-01-23 11:45:06 +08006#include <string.h>
Jacob Garber7da638c2019-05-30 16:11:41 -06007#include <console/console.h>
Xiang Wang411a8b72019-01-23 11:45:06 +08008#include <soc/otp.h>
9#include <soc/sdram.h>
10#include <cbfs.h>
11#include <device_tree.h>
12#include <bootstate.h>
13#include <mcall.h>
14
15static void do_fixup_mac(struct device_tree_node *node)
16{
17 uint32_t serial = otp_read_serial();
18 static unsigned char mac[6] = { 0x70, 0xb3, 0xd5, 0x92, 0xf0, 0x00 };
19 if (serial != ~0) {
20 mac[5] |= (serial >> 0) & 0xff;
21 mac[4] |= (serial >> 8) & 0xff;
22 mac[3] |= (serial >> 16) & 0xff;
23 }
24 dt_add_bin_prop(node, "local-mac-address", mac, 6);
25}
26
27static void fixup_mac(struct device_tree_node *parent)
28{
29 struct device_tree_property *prop;
30 const char *name = "local-mac-address";
31
32 list_for_each(prop, parent->properties, list_node) {
33 if (!strcmp(name, prop->prop.name))
34 do_fixup_mac(parent);
35 }
36
37 struct device_tree_node *child;
38 list_for_each(child, parent->children, list_node) {
39 fixup_mac(child);
40 }
41}
42
43static void do_fixup_memory(struct device_tree_node *node)
44{
45 u64 addrs[1], sizes[1];
46 addrs[0] = 0x80000000;
47 sizes[0] = sdram_size_mb() * 1024 * 1024;
48 dt_add_reg_prop(node, addrs, sizes, 1, 2, 2);
49}
50
51
52static void fixup_memory(struct device_tree_node *parent)
53{
54 struct device_tree_property *prop;
55 const char *name = "device_type";
56 const char *value = "memory";
57
58 list_for_each(prop, parent->properties, list_node) {
59 if (!strcmp(name, prop->prop.name)) {
60 if (!strcmp(value, (char *)prop->prop.data))
61 do_fixup_memory(parent);
62 }
63 }
64
65 struct device_tree_node *child;
66 list_for_each(child, parent->children, list_node) {
67 fixup_memory(child);
68 }
69}
70
71static void fixup_fdt(void *unused)
72{
73 void *fdt_rom;
74 struct device_tree *tree;
75
76 /* load flat dt from cbfs */
77 fdt_rom = cbfs_boot_map_with_leak("fallback/DTB", CBFS_TYPE_RAW, NULL);
78
Jacob Garber7da638c2019-05-30 16:11:41 -060079 if (fdt_rom == NULL) {
80 printk(BIOS_ERR, "Unable to load fallback/DTB from CBFS\n");
81 return;
82 }
83
Xiang Wang411a8b72019-01-23 11:45:06 +080084 /* Expand DT into a tree */
85 tree = fdt_unflatten(fdt_rom);
86
87 /* fixup tree */
88 fixup_mac(tree->root);
89 fixup_memory(tree->root);
90
91 /* convert the tree to a flat dt */
92 void *dt = malloc(dt_flat_size(tree));
Jacob Garber7da638c2019-05-30 16:11:41 -060093
94 if (dt == NULL) {
95 printk(BIOS_ERR, "Unable to allocate memory for flat device tree\n");
96 return;
97 }
98
Xiang Wang411a8b72019-01-23 11:45:06 +080099 dt_flatten(tree, dt);
100
101 /* update HLS */
102 for (int i = 0; i < CONFIG_MAX_CPUS; i++)
103 OTHER_HLS(i)->fdt = dt;
104}
105
106BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_EXIT, fixup_fdt, NULL);