diff options
Diffstat (limited to 'common/bootsource.c')
-rw-r--r-- | common/bootsource.c | 164 |
1 files changed, 112 insertions, 52 deletions
diff --git a/common/bootsource.c b/common/bootsource.c index 4ef8d8ad95..6808c9c51d 100644 --- a/common/bootsource.c +++ b/common/bootsource.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* - * * Copyright (C) 2011 Marc Reilly <marc@cpdesign.com.au> * Copyright (C) 2013 Marc Kleine-Budde <mkl@pengutronix.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> @@ -21,7 +10,7 @@ #include <magicvar.h> #include <init.h> -static const char *bootsource_str[] = { +static const char *bootsource_str[BOOTSOURCE_MAX] = { [BOOTSOURCE_UNKNOWN] = "unknown", [BOOTSOURCE_NAND] = "nand", [BOOTSOURCE_NOR] = "nor", @@ -37,12 +26,49 @@ static const char *bootsource_str[] = { [BOOTSOURCE_USB] = "usb", [BOOTSOURCE_NET] = "net", [BOOTSOURCE_CAN] = "can", + [BOOTSOURCE_JTAG] = "jtag", }; static enum bootsource bootsource = BOOTSOURCE_UNKNOWN; static int bootsource_instance = BOOTSOURCE_INSTANCE_UNKNOWN; const char *bootsource_alias_name = NULL; +const char *bootsource_to_string(enum bootsource src) +{ + if (src >= ARRAY_SIZE(bootsource_str)) + return NULL; + + return bootsource_str[src]; +} + +const char *bootsource_get_alias_stem(enum bootsource src) +{ + switch (src) { + /* + * For I2C and SPI EEPROMs we set the stem to be 'i2c' + * and 'spi' correspondingly. The resulting alias will + * be pointing at the controller said EEPROM is + * attached to. + * + * NOTE: This code assumes single bootable EEPROM per + * controller + */ + case BOOTSOURCE_I2C_EEPROM: + return bootsource_str[BOOTSOURCE_I2C]; + case BOOTSOURCE_SPI_EEPROM: + case BOOTSOURCE_SPI_NOR: + return bootsource_str[BOOTSOURCE_SPI]; + case BOOTSOURCE_SERIAL: /* FALLTHROUGH */ + case BOOTSOURCE_I2C: /* FALLTHROUGH */ + case BOOTSOURCE_MMC: /* FALLTHROUGH */ + case BOOTSOURCE_SPI: /* FALLTHROUGH */ + case BOOTSOURCE_CAN: + return bootsource_str[src]; + default: + return NULL; + } +} + /** * bootsource_get_alias_name() - Get the name of the bootsource alias * @@ -68,37 +94,13 @@ char *bootsource_get_alias_name(void) if (bootsource_alias_name) return strdup(bootsource_alias_name); - switch (bootsource) { - /* - * For I2C and SPI EEPROMs we set the stem to be 'i2c' - * and 'spi' correspondingly. The resulting alias will - * be pointing at the controller said EEPROM is - * attached to. - * - * NOTE: This code assumes single bootable EEPROM per - * controller - */ - case BOOTSOURCE_I2C_EEPROM: - stem = bootsource_str[BOOTSOURCE_I2C]; - break; - case BOOTSOURCE_SPI_EEPROM: - case BOOTSOURCE_SPI_NOR: - stem = bootsource_str[BOOTSOURCE_SPI]; - break; - case BOOTSOURCE_SERIAL: /* FALLTHROUGH */ - case BOOTSOURCE_I2C: /* FALLTHROUGH */ - case BOOTSOURCE_MMC: /* FALLTHROUGH */ - case BOOTSOURCE_SPI: /* FALLTHROUGH */ - case BOOTSOURCE_CAN: - stem = bootsource_str[bootsource]; - break; - default: + stem = bootsource_get_alias_stem(bootsource); + if (!stem) return NULL; - } /* - * We expect SoC specific bootsource detction code to properly - * initalize bootsource_instance, so we bail out if it didn't + * We expect SoC specific bootsource detection code to properly + * initialize bootsource_instance, so we bail out if it didn't */ if (bootsource_instance == BOOTSOURCE_INSTANCE_UNKNOWN) return NULL; @@ -106,33 +108,92 @@ char *bootsource_get_alias_name(void) return basprintf("%s%d", stem, bootsource_instance); } +struct device_node *bootsource_of_node_get(struct device_node *root) +{ + struct device_node *np; + char *alias_name; + + alias_name = bootsource_get_alias_name(); + if (!alias_name) + return NULL; + + np = of_find_node_by_alias(root, alias_name); + + free(alias_name); + + return np; +} + void bootsource_set_alias_name(const char *name) { bootsource_alias_name = name; } -void bootsource_set(enum bootsource src) +void bootsource_set_raw(enum bootsource src, int instance) { - if (src >= ARRAY_SIZE(bootsource_str)) + if (src >= BOOTSOURCE_MAX) src = BOOTSOURCE_UNKNOWN; bootsource = src; - setenv("bootsource", bootsource_str[src]); + setenv("bootsource", bootsource_to_string(src)); + + bootsource_set_raw_instance(instance); } -void bootsource_set_instance(int instance) +void bootsource_set_raw_instance(int instance) { - char buf[32]; - bootsource_instance = instance; if (instance < 0) - sprintf(buf, "unknown"); + setenv("bootsource_instance","unknown"); else - snprintf(buf, sizeof(buf), "%d", instance); + pr_setenv("bootsource_instance", "%d", instance); +} + +int bootsource_of_alias_xlate(enum bootsource src, int instance) +{ + char chosen[sizeof("barebox,bootsource-harddisk4294967295")]; + const char *bootsource_stem; + struct device_node *np; + int alias_id; + + if (!IS_ENABLED(CONFIG_OFDEVICE)) + return BOOTSOURCE_INSTANCE_UNKNOWN; + + if (src == BOOTSOURCE_UNKNOWN || + instance == BOOTSOURCE_INSTANCE_UNKNOWN) + return BOOTSOURCE_INSTANCE_UNKNOWN; + + bootsource_stem = bootsource_get_alias_stem(src); + if (!bootsource_stem) + return BOOTSOURCE_INSTANCE_UNKNOWN; + + scnprintf(chosen, sizeof(chosen), "barebox,bootsource-%s%u", + bootsource_stem, instance); + + np = of_find_node_by_chosen(chosen, NULL); + if (!np) + return BOOTSOURCE_INSTANCE_UNKNOWN; + + alias_id = of_alias_get_id(np, bootsource_stem); + if (alias_id < 0) + return BOOTSOURCE_INSTANCE_UNKNOWN; + + return alias_id; +} + +int bootsource_set(enum bootsource src, int instance) +{ + int alias_id; + + alias_id = bootsource_of_alias_xlate(src, instance); + if (alias_id == BOOTSOURCE_INSTANCE_UNKNOWN) + alias_id = instance; + + bootsource_set_raw(src, alias_id); - setenv("bootsource_instance", buf); + return alias_id; } enum bootsource bootsource_get(void) @@ -151,8 +212,7 @@ BAREBOX_MAGICVAR(bootsource_instance, "The instance of the source barebox has be static int bootsource_init(void) { - bootsource_set(bootsource); - bootsource_set_instance(bootsource_instance); + bootsource_set_raw(bootsource, bootsource_instance); export("bootsource"); export("bootsource_instance"); |