Quentin Schulz | 1e1a92b | 2024-01-17 18:59:10 +0100 | [diff] [blame] | 1 | // 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 | */ |
| 20 | int setup_boottargets(void) |
| 21 | { |
| 22 | const char *boot_device = |
| 23 | ofnode_read_chosen_string("u-boot,spl-boot-device"); |
Quentin Schulz | f3e450b | 2024-01-17 18:59:13 +0100 | [diff] [blame] | 24 | char env_default[sizeof(BOOT_TARGETS)]; |
| 25 | char *env; |
| 26 | int ret; |
Quentin Schulz | 1e1a92b | 2024-01-17 18:59:10 +0100 | [diff] [blame] | 27 | |
| 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 Schulz | f3e450b | 2024-01-17 18:59:13 +0100 | [diff] [blame] | 35 | ret = env_get_default_into("boot_targets", env_default, sizeof(env_default)); |
| 36 | if (ret < 0) |
| 37 | env_default[0] = '\0'; |
Quentin Schulz | 1e1a92b | 2024-01-17 18:59:10 +0100 | [diff] [blame] | 38 | 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 Schulz | 1e1a92b | 2024-01-17 18:59:10 +0100 | [diff] [blame] | 92 | enum 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 | } |