summaryrefslogtreecommitdiffstats
path: root/common/bootsource.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/bootsource.c')
-rw-r--r--common/bootsource.c164
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");