blob: 585da43884542296079022c7ce62c2e460ec9c07 [file] [log] [blame]
Quentin Schulz1e1a92b2024-01-17 18:59:10 +01001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
4 */
5
6#include <dm.h>
7#include <env.h>
8#include <env_internal.h>
9#include <dm/uclass-internal.h>
10
11/*
12 * Swap mmc0 and mmc1 in boot_targets if booted from SD-Card.
13 *
14 * If bootsource is uSD-card we can assume that we want to use the
15 * SD-Card instead of the eMMC as first boot_target for distroboot.
16 * We only want to swap the defaults and not any custom environment a
17 * user has set. We exit early if a changed boot_targets environment
18 * is detected.
19 */
20int setup_boottargets(void)
21{
22 const char *boot_device =
23 ofnode_read_chosen_string("u-boot,spl-boot-device");
Quentin Schulzf3e450b2024-01-17 18:59:13 +010024 char env_default[sizeof(BOOT_TARGETS)];
25 char *env;
26 int ret;
Quentin Schulz1e1a92b2024-01-17 18:59:10 +010027
28 if (!boot_device) {
29 debug("%s: /chosen/u-boot,spl-boot-device not set\n",
30 __func__);
31 return -1;
32 }
33 debug("%s: booted from %s\n", __func__, boot_device);
34
Quentin Schulzf3e450b2024-01-17 18:59:13 +010035 ret = env_get_default_into("boot_targets", env_default, sizeof(env_default));
36 if (ret < 0)
37 env_default[0] = '\0';
Quentin Schulz1e1a92b2024-01-17 18:59:10 +010038 env = env_get("boot_targets");
39 if (!env) {
40 debug("%s: boot_targets does not exist\n", __func__);
41 return -1;
42 }
43 debug("%s: boot_targets current: %s - default: %s\n",
44 __func__, env, env_default);
45
46 if (strcmp(env_default, env) != 0) {
47 debug("%s: boot_targets not default, don't change it\n",
48 __func__);
49 return 0;
50 }
51
52 /*
53 * Make the default boot medium between SD Card and eMMC, the one that
54 * was used to load U-Boot proper. If SPI-NOR flash was used, keep
55 * original default order.
56 */
57 struct udevice *devp;
58
59 if (uclass_find_device_by_ofnode(UCLASS_MMC, ofnode_path(boot_device), &devp)) {
60 debug("%s: not reordering boot_targets, bootdev %s != MMC\n",
61 __func__, boot_device);
62 return 0;
63 }
64
65 char *mmc0, *mmc1;
66
67 mmc0 = strstr(env, "mmc0");
68 mmc1 = strstr(env, "mmc1");
69
70 if (!mmc0 || !mmc1) {
71 debug("%s: only one mmc boot_target found\n", __func__);
72 return -1;
73 }
74
75 /*
76 * If mmc0 comes first in the boot order and U-Boot proper was
77 * loaded from mmc1, swap mmc0 and mmc1 in the list.
78 * If mmc1 comes first in the boot order and U-Boot proper was
79 * loaded from mmc0, swap mmc0 and mmc1 in the list.
80 */
81 if ((mmc0 < mmc1 && devp->seq_ == 1) ||
82 (mmc0 > mmc1 && devp->seq_ == 0)) {
83 mmc0[3] = '1';
84 mmc1[3] = '0';
85 debug("%s: set boot_targets to: %s\n", __func__, env);
86 env_set("boot_targets", env);
87 }
88
89 return 0;
90}
91
Quentin Schulz1e1a92b2024-01-17 18:59:10 +010092enum env_location arch_env_get_location(enum env_operation op, int prio)
93{
94 const char *boot_device =
95 ofnode_read_chosen_string("u-boot,spl-boot-device");
96 struct udevice *devp;
97
98 if (prio > 0)
99 return ENVL_UNKNOWN;
100
101 if (!boot_device) {
102 debug("%s: /chosen/u-boot,spl-boot-device not set\n",
103 __func__);
104 return ENVL_NOWHERE;
105 }
106
107 debug("%s: booted from %s\n", __func__, boot_device);
108
109 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH) &&
110 !uclass_find_device_by_ofnode(UCLASS_SPI_FLASH, ofnode_path(boot_device), &devp))
111 return ENVL_SPI_FLASH;
112
113 if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC) &&
114 !uclass_find_device_by_ofnode(UCLASS_MMC, ofnode_path(boot_device), &devp))
115 return ENVL_MMC;
116
117 printf("%s: No environment available: booted from %s but U-Boot config does not allow loading environment from it.",
118 __func__, boot_device);
119
120 return ENVL_NOWHERE;
121}