blob: 3d431812face071b7502da091e4b83b6a1608c91 [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>
Elyes HAOUAS70a03dd2019-12-02 20:47:50 +010017#include <stdlib.h>
Xiang Wang411a8b72019-01-23 11:45:06 +080018#include <string.h>
Jacob Garber7da638c2019-05-30 16:11:41 -060019#include <console/console.h>
Xiang Wang411a8b72019-01-23 11:45:06 +080020#include <soc/otp.h>
21#include <soc/sdram.h>
22#include <cbfs.h>
23#include <device_tree.h>
24#include <bootstate.h>
25#include <mcall.h>
26
27static void do_fixup_mac(struct device_tree_node *node)
28{
29 uint32_t serial = otp_read_serial();
30 static unsigned char mac[6] = { 0x70, 0xb3, 0xd5, 0x92, 0xf0, 0x00 };
31 if (serial != ~0) {
32 mac[5] |= (serial >> 0) & 0xff;
33 mac[4] |= (serial >> 8) & 0xff;
34 mac[3] |= (serial >> 16) & 0xff;
35 }
36 dt_add_bin_prop(node, "local-mac-address", mac, 6);
37}
38
39static void fixup_mac(struct device_tree_node *parent)
40{
41 struct device_tree_property *prop;
42 const char *name = "local-mac-address";
43
44 list_for_each(prop, parent->properties, list_node) {
45 if (!strcmp(name, prop->prop.name))
46 do_fixup_mac(parent);
47 }
48
49 struct device_tree_node *child;
50 list_for_each(child, parent->children, list_node) {
51 fixup_mac(child);
52 }
53}
54
55static void do_fixup_memory(struct device_tree_node *node)
56{
57 u64 addrs[1], sizes[1];
58 addrs[0] = 0x80000000;
59 sizes[0] = sdram_size_mb() * 1024 * 1024;
60 dt_add_reg_prop(node, addrs, sizes, 1, 2, 2);
61}
62
63
64static void fixup_memory(struct device_tree_node *parent)
65{
66 struct device_tree_property *prop;
67 const char *name = "device_type";
68 const char *value = "memory";
69
70 list_for_each(prop, parent->properties, list_node) {
71 if (!strcmp(name, prop->prop.name)) {
72 if (!strcmp(value, (char *)prop->prop.data))
73 do_fixup_memory(parent);
74 }
75 }
76
77 struct device_tree_node *child;
78 list_for_each(child, parent->children, list_node) {
79 fixup_memory(child);
80 }
81}
82
83static void fixup_fdt(void *unused)
84{
85 void *fdt_rom;
86 struct device_tree *tree;
87
88 /* load flat dt from cbfs */
89 fdt_rom = cbfs_boot_map_with_leak("fallback/DTB", CBFS_TYPE_RAW, NULL);
90
Jacob Garber7da638c2019-05-30 16:11:41 -060091 if (fdt_rom == NULL) {
92 printk(BIOS_ERR, "Unable to load fallback/DTB from CBFS\n");
93 return;
94 }
95
Xiang Wang411a8b72019-01-23 11:45:06 +080096 /* Expand DT into a tree */
97 tree = fdt_unflatten(fdt_rom);
98
99 /* fixup tree */
100 fixup_mac(tree->root);
101 fixup_memory(tree->root);
102
103 /* convert the tree to a flat dt */
104 void *dt = malloc(dt_flat_size(tree));
Jacob Garber7da638c2019-05-30 16:11:41 -0600105
106 if (dt == NULL) {
107 printk(BIOS_ERR, "Unable to allocate memory for flat device tree\n");
108 return;
109 }
110
Xiang Wang411a8b72019-01-23 11:45:06 +0800111 dt_flatten(tree, dt);
112
113 /* update HLS */
114 for (int i = 0; i < CONFIG_MAX_CPUS; i++)
115 OTHER_HLS(i)->fdt = dt;
116}
117
118BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_EXIT, fixup_fdt, NULL);