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