// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* * Copyright (C) 2020, STMicroelectronics - All Rights Reserved */ #include #include #include #include #include #include #include #include #include #include #include #include #define DFU_ALT_BUF_LEN SZ_1K static void board_get_alt_info_mmc(struct udevice *dev, char *buf) { struct disk_partition info; int p, len, devnum; bool first = true; const char *name; struct mmc *mmc; struct blk_desc *desc; mmc = mmc_get_mmc_dev(dev); if (!mmc) return; if (mmc_init(mmc)) return; desc = mmc_get_blk_desc(mmc); if (!desc) return; name = blk_get_uclass_name(desc->uclass_id); devnum = desc->devnum; len = strlen(buf); if (buf[0] != '\0') len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "&"); len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "%s %d=", name, devnum); if (IS_MMC(mmc) && mmc->capacity_boot) { len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "%s%d_boot1 raw 0x0 0x%llx mmcpart 1;", name, devnum, mmc->capacity_boot); len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "%s%d_boot2 raw 0x0 0x%llx mmcpart 2", name, devnum, mmc->capacity_boot); first = false; } for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { if (part_get_info(desc, p, &info)) continue; if (!first) len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ";"); first = false; len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "%s%d_%s part %d %d", name, devnum, info.name, devnum, p); } } static void board_get_alt_info_mtd(struct mtd_info *mtd, char *buf) { struct mtd_info *part; bool first = true; const char *name; int len, partnum = 0; name = mtd->name; len = strlen(buf); if (buf[0] != '\0') len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "&"); len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "mtd %s=", name); len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "%s raw 0x0 0x%llx ", name, mtd->size); list_for_each_entry(part, &mtd->partitions, node) { partnum++; if (!first) len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ";"); first = false; len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "%s_%s part %d", name, part->name, partnum); } } void set_dfu_alt_info(char *interface, char *devstr) { struct udevice *dev; struct mtd_info *mtd; ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); if (env_get("dfu_alt_info")) return; memset(buf, 0, sizeof(buf)); snprintf(buf, DFU_ALT_BUF_LEN, "ram 0=%s", CONFIG_DFU_ALT_RAM0); if (CONFIG_IS_ENABLED(MMC)) { if (!uclass_get_device(UCLASS_MMC, 0, &dev)) board_get_alt_info_mmc(dev, buf); if (!uclass_get_device(UCLASS_MMC, 1, &dev)) board_get_alt_info_mmc(dev, buf); } if (IS_ENABLED(CONFIG_MTD)) { /* probe all MTD devices */ mtd_probe_devices(); /* probe SPI flash device on a bus */ if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) { mtd = get_mtd_device_nm("nor0"); if (!IS_ERR_OR_NULL(mtd)) board_get_alt_info_mtd(mtd, buf); mtd = get_mtd_device_nm("nor1"); if (!IS_ERR_OR_NULL(mtd)) board_get_alt_info_mtd(mtd, buf); } mtd = get_mtd_device_nm("nand0"); if (!IS_ERR_OR_NULL(mtd)) board_get_alt_info_mtd(mtd, buf); mtd = get_mtd_device_nm("spi-nand0"); if (!IS_ERR_OR_NULL(mtd)) board_get_alt_info_mtd(mtd, buf); } if (IS_ENABLED(CONFIG_DFU_VIRT)) { /* virtual device id 0 is aligned with stm32mp_dfu_virt.c */ strlcat(buf, "&virt 0=OTP", DFU_ALT_BUF_LEN); if (IS_ENABLED(CONFIG_PMIC_STPMIC1)) strlcat(buf, "&virt 1=PMIC", DFU_ALT_BUF_LEN); } env_set("dfu_alt_info", buf); puts("DFU alt info setting: done\n"); }