18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * PlanetCore configuration data support functions 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Author: Scott Wood <scottwood@freescale.com> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (c) 2007 Freescale Semiconductor, Inc. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include "stdio.h" 118c2ecf20Sopenharmony_ci#include "stdlib.h" 128c2ecf20Sopenharmony_ci#include "ops.h" 138c2ecf20Sopenharmony_ci#include "planetcore.h" 148c2ecf20Sopenharmony_ci#include "io.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* PlanetCore passes information to the OS in the form of 178c2ecf20Sopenharmony_ci * a table of key=value strings, separated by newlines. 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * The list is terminated by an empty string (i.e. two 208c2ecf20Sopenharmony_ci * consecutive newlines). 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * To make it easier to parse, we first convert all the 238c2ecf20Sopenharmony_ci * newlines into null bytes. 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_civoid planetcore_prepare_table(char *table) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci do { 298c2ecf20Sopenharmony_ci if (*table == '\n') 308c2ecf20Sopenharmony_ci *table = 0; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci table++; 338c2ecf20Sopenharmony_ci } while (*(table - 1) || *table != '\n'); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci *table = 0; 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ciconst char *planetcore_get_key(const char *table, const char *key) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci int keylen = strlen(key); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci do { 438c2ecf20Sopenharmony_ci if (!strncmp(table, key, keylen) && table[keylen] == '=') 448c2ecf20Sopenharmony_ci return table + keylen + 1; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci table += strlen(table) + 1; 478c2ecf20Sopenharmony_ci } while (strlen(table) != 0); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci return NULL; 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ciint planetcore_get_decimal(const char *table, const char *key, u64 *val) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci const char *str = planetcore_get_key(table, key); 558c2ecf20Sopenharmony_ci if (!str) 568c2ecf20Sopenharmony_ci return 0; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci *val = strtoull(str, NULL, 10); 598c2ecf20Sopenharmony_ci return 1; 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ciint planetcore_get_hex(const char *table, const char *key, u64 *val) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci const char *str = planetcore_get_key(table, key); 658c2ecf20Sopenharmony_ci if (!str) 668c2ecf20Sopenharmony_ci return 0; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci *val = strtoull(str, NULL, 16); 698c2ecf20Sopenharmony_ci return 1; 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic u64 mac_table[4] = { 738c2ecf20Sopenharmony_ci 0x000000000000, 748c2ecf20Sopenharmony_ci 0x000000800000, 758c2ecf20Sopenharmony_ci 0x000000400000, 768c2ecf20Sopenharmony_ci 0x000000c00000, 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_civoid planetcore_set_mac_addrs(const char *table) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci u8 addr[4][6]; 828c2ecf20Sopenharmony_ci u64 int_addr; 838c2ecf20Sopenharmony_ci u32 i; 848c2ecf20Sopenharmony_ci int j; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci if (!planetcore_get_hex(table, PLANETCORE_KEY_MAC_ADDR, &int_addr)) 878c2ecf20Sopenharmony_ci return; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci for (i = 0; i < 4; i++) { 908c2ecf20Sopenharmony_ci u64 this_dev_addr = (int_addr & ~0x000000c00000) | 918c2ecf20Sopenharmony_ci mac_table[i]; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci for (j = 5; j >= 0; j--) { 948c2ecf20Sopenharmony_ci addr[i][j] = this_dev_addr & 0xff; 958c2ecf20Sopenharmony_ci this_dev_addr >>= 8; 968c2ecf20Sopenharmony_ci } 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci dt_fixup_mac_address(i, addr[i]); 998c2ecf20Sopenharmony_ci } 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cistatic char prop_buf[MAX_PROP_LEN]; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_civoid planetcore_set_stdout_path(const char *table) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci char *path; 1078c2ecf20Sopenharmony_ci const char *label; 1088c2ecf20Sopenharmony_ci void *node, *chosen; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci label = planetcore_get_key(table, PLANETCORE_KEY_SERIAL_PORT); 1118c2ecf20Sopenharmony_ci if (!label) 1128c2ecf20Sopenharmony_ci return; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci node = find_node_by_prop_value_str(NULL, "linux,planetcore-label", 1158c2ecf20Sopenharmony_ci label); 1168c2ecf20Sopenharmony_ci if (!node) 1178c2ecf20Sopenharmony_ci return; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci path = get_path(node, prop_buf, MAX_PROP_LEN); 1208c2ecf20Sopenharmony_ci if (!path) 1218c2ecf20Sopenharmony_ci return; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci chosen = finddevice("/chosen"); 1248c2ecf20Sopenharmony_ci if (!chosen) 1258c2ecf20Sopenharmony_ci chosen = create_node(NULL, "chosen"); 1268c2ecf20Sopenharmony_ci if (!chosen) 1278c2ecf20Sopenharmony_ci return; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci setprop_str(chosen, "linux,stdout-path", path); 1308c2ecf20Sopenharmony_ci} 131