1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * PlanetCore configuration data support functions |
4 | * |
5 | * Author: Scott Wood <scottwood@freescale.com> |
6 | * |
7 | * Copyright (c) 2007 Freescale Semiconductor, Inc. |
8 | */ |
9 | |
10 | #include "stdio.h" |
11 | #include "stdlib.h" |
12 | #include "ops.h" |
13 | #include "planetcore.h" |
14 | #include "io.h" |
15 | |
16 | /* PlanetCore passes information to the OS in the form of |
17 | * a table of key=value strings, separated by newlines. |
18 | * |
19 | * The list is terminated by an empty string (i.e. two |
20 | * consecutive newlines). |
21 | * |
22 | * To make it easier to parse, we first convert all the |
23 | * newlines into null bytes. |
24 | */ |
25 | |
26 | void planetcore_prepare_table(char *table) |
27 | { |
28 | do { |
29 | if (*table == '\n') |
30 | *table = 0; |
31 | |
32 | table++; |
33 | } while (*(table - 1) || *table != '\n'); |
34 | |
35 | *table = 0; |
36 | } |
37 | |
38 | const char *planetcore_get_key(const char *table, const char *key) |
39 | { |
40 | int keylen = strlen(key); |
41 | |
42 | do { |
43 | if (!strncmp(table, key, keylen) && table[keylen] == '=') |
44 | return table + keylen + 1; |
45 | |
46 | table += strlen(table) + 1; |
47 | } while (strlen(table) != 0); |
48 | |
49 | return NULL; |
50 | } |
51 | |
52 | int planetcore_get_decimal(const char *table, const char *key, u64 *val) |
53 | { |
54 | const char *str = planetcore_get_key(table, key); |
55 | if (!str) |
56 | return 0; |
57 | |
58 | *val = strtoull(ptr: str, end: NULL, base: 10); |
59 | return 1; |
60 | } |
61 | |
62 | int planetcore_get_hex(const char *table, const char *key, u64 *val) |
63 | { |
64 | const char *str = planetcore_get_key(table, key); |
65 | if (!str) |
66 | return 0; |
67 | |
68 | *val = strtoull(ptr: str, end: NULL, base: 16); |
69 | return 1; |
70 | } |
71 | |
72 | static u64 mac_table[4] = { |
73 | 0x000000000000, |
74 | 0x000000800000, |
75 | 0x000000400000, |
76 | 0x000000c00000, |
77 | }; |
78 | |
79 | void planetcore_set_mac_addrs(const char *table) |
80 | { |
81 | u8 addr[4][6]; |
82 | u64 int_addr; |
83 | u32 i; |
84 | int j; |
85 | |
86 | if (!planetcore_get_hex(table, PLANETCORE_KEY_MAC_ADDR, val: &int_addr)) |
87 | return; |
88 | |
89 | for (i = 0; i < 4; i++) { |
90 | u64 this_dev_addr = (int_addr & ~0x000000c00000) | |
91 | mac_table[i]; |
92 | |
93 | for (j = 5; j >= 0; j--) { |
94 | addr[i][j] = this_dev_addr & 0xff; |
95 | this_dev_addr >>= 8; |
96 | } |
97 | |
98 | dt_fixup_mac_address(index: i, addr: addr[i]); |
99 | } |
100 | } |
101 | |
102 | static char prop_buf[MAX_PROP_LEN]; |
103 | |
104 | void planetcore_set_stdout_path(const char *table) |
105 | { |
106 | char *path; |
107 | const char *label; |
108 | void *node, *chosen; |
109 | |
110 | label = planetcore_get_key(table, PLANETCORE_KEY_SERIAL_PORT); |
111 | if (!label) |
112 | return; |
113 | |
114 | node = find_node_by_prop_value_str(prev: NULL, propname: "linux,planetcore-label" , |
115 | propval: label); |
116 | if (!node) |
117 | return; |
118 | |
119 | path = get_path(phandle: node, buf: prop_buf, MAX_PROP_LEN); |
120 | if (!path) |
121 | return; |
122 | |
123 | chosen = finddevice(name: "/chosen" ); |
124 | if (!chosen) |
125 | chosen = create_node(parent: NULL, name: "chosen" ); |
126 | if (!chosen) |
127 | return; |
128 | |
129 | setprop_str(devp: chosen, name: "linux,stdout-path" , buf: path); |
130 | } |
131 | |