linux/arch/powerpc/boot/planetcore.c
<<
>>
Prefs
   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
  29void 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
  41const 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
  55int 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
  65int 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
  75static u64 mac_table[4] = {
  76        0x000000000000,
  77        0x000000800000,
  78        0x000000400000,
  79        0x000000c00000,
  80};
  81
  82void 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
 105static char prop_buf[MAX_PROP_LEN];
 106
 107void 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
 135void 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