Commit | Line | Data |
---|---|---|
fec60470 SW |
1 | /* |
2 | * PlanetCore configuration data support functions | |
3 | * | |
4 | * Author: Scott Wood <scottwood@freescale.com> | |
5 | * | |
6 | * Copyright (c) 2007 Freescale Semiconductor, Inc. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License version 2 as published | |
10 | * by the Free Software Foundation. | |
11 | */ | |
12 | ||
13 | #include "stdio.h" | |
14 | #include "stdlib.h" | |
15 | #include "ops.h" | |
16 | #include "planetcore.h" | |
17 | #include "io.h" | |
18 | ||
19 | /* PlanetCore passes information to the OS in the form of | |
20 | * a table of key=value strings, separated by newlines. | |
21 | * | |
22 | * The list is terminated by an empty string (i.e. two | |
23 | * consecutive newlines). | |
24 | * | |
25 | * To make it easier to parse, we first convert all the | |
26 | * newlines into null bytes. | |
27 | */ | |
28 | ||
29 | void planetcore_prepare_table(char *table) | |
30 | { | |
31 | do { | |
32 | if (*table == '\n') | |
33 | *table = 0; | |
34 | ||
35 | table++; | |
36 | } while (*(table - 1) || *table != '\n'); | |
37 | ||
38 | *table = 0; | |
39 | } | |
40 | ||
41 | const char *planetcore_get_key(const char *table, const char *key) | |
42 | { | |
43 | int keylen = strlen(key); | |
44 | ||
45 | do { | |
46 | if (!strncmp(table, key, keylen) && table[keylen] == '=') | |
47 | return table + keylen + 1; | |
48 | ||
49 | table += strlen(table) + 1; | |
50 | } while (strlen(table) != 0); | |
51 | ||
52 | return NULL; | |
53 | } | |
54 | ||
55 | int planetcore_get_decimal(const char *table, const char *key, u64 *val) | |
56 | { | |
57 | const char *str = planetcore_get_key(table, key); | |
58 | if (!str) | |
59 | return 0; | |
60 | ||
61 | *val = strtoull(str, NULL, 10); | |
62 | return 1; | |
63 | } | |
64 | ||
65 | int planetcore_get_hex(const char *table, const char *key, u64 *val) | |
66 | { | |
67 | const char *str = planetcore_get_key(table, key); | |
68 | if (!str) | |
69 | return 0; | |
70 | ||
71 | *val = strtoull(str, NULL, 16); | |
72 | return 1; | |
73 | } | |
74 | ||
75 | static u64 mac_table[4] = { | |
76 | 0x000000000000, | |
77 | 0x000000800000, | |
78 | 0x000000400000, | |
79 | 0x000000c00000, | |
80 | }; | |
81 | ||
82 | void planetcore_set_mac_addrs(const char *table) | |
83 | { | |
84 | u8 addr[4][6]; | |
85 | u64 int_addr; | |
86 | u32 i; | |
87 | int j; | |
88 | ||
89 | if (!planetcore_get_hex(table, PLANETCORE_KEY_MAC_ADDR, &int_addr)) | |
90 | return; | |
91 | ||
92 | for (i = 0; i < 4; i++) { | |
93 | u64 this_dev_addr = (int_addr & ~0x000000c00000) | | |
94 | mac_table[i]; | |
95 | ||
96 | for (j = 5; j >= 0; j--) { | |
97 | addr[i][j] = this_dev_addr & 0xff; | |
98 | this_dev_addr >>= 8; | |
99 | } | |
100 | ||
101 | dt_fixup_mac_address(i, addr[i]); | |
102 | } | |
103 | } | |
104 | ||
105 | static char prop_buf[MAX_PROP_LEN]; | |
106 | ||
107 | void planetcore_set_stdout_path(const char *table) | |
108 | { | |
109 | char *path; | |
110 | const char *label; | |
111 | void *node, *chosen; | |
112 | ||
113 | label = planetcore_get_key(table, PLANETCORE_KEY_SERIAL_PORT); | |
114 | if (!label) | |
115 | return; | |
116 | ||
117 | node = find_node_by_prop_value_str(NULL, "linux,planetcore-label", | |
118 | label); | |
119 | if (!node) | |
120 | return; | |
121 | ||
122 | path = get_path(node, prop_buf, MAX_PROP_LEN); | |
123 | if (!path) | |
124 | return; | |
125 | ||
126 | chosen = finddevice("/chosen"); | |
127 | if (!chosen) | |
128 | chosen = create_node(NULL, "chosen"); | |
129 | if (!chosen) | |
130 | return; | |
131 | ||
132 | setprop_str(chosen, "linux,stdout-path", path); | |
133 | } | |
134 | ||
135 | void planetcore_set_serial_speed(const char *table) | |
136 | { | |
137 | void *chosen, *stdout; | |
138 | u64 baud; | |
139 | u32 baud32; | |
140 | int len; | |
141 | ||
142 | chosen = finddevice("/chosen"); | |
143 | if (!chosen) | |
144 | return; | |
145 | ||
146 | len = getprop(chosen, "linux,stdout-path", prop_buf, MAX_PROP_LEN); | |
147 | if (len <= 0) | |
148 | return; | |
149 | ||
150 | stdout = finddevice(prop_buf); | |
151 | if (!stdout) { | |
152 | printf("planetcore_set_serial_speed: " | |
153 | "Bad /chosen/linux,stdout-path.\r\n"); | |
154 | ||
155 | return; | |
156 | } | |
157 | ||
158 | if (!planetcore_get_decimal(table, PLANETCORE_KEY_SERIAL_BAUD, | |
159 | &baud)) { | |
160 | printf("planetcore_set_serial_speed: No SB tag.\r\n"); | |
161 | return; | |
162 | } | |
163 | ||
164 | baud32 = baud; | |
165 | setprop(stdout, "current-speed", &baud32, 4); | |
166 | } |