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 } 167