summaryrefslogtreecommitdiff
path: root/disk
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-04-23 18:42:00 -0400
committerTom Rini <trini@konsulko.com>2022-04-23 18:42:00 -0400
commit46a06ed82a81dfcb451fe82381c59c1d0a6667a1 (patch)
treea4b23b20380a7850521338c5dfe5a5ab6ae47d09 /disk
parent9bb99fa95826d1a608737ca821977b4136a1a278 (diff)
parentd97e98c887ed8fa4a339350c02f093f03cd1cf4d (diff)
Merge tag 'efi-2022-07-rc1-3' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request for efi-2022-07-rc1-3 Documentation: * Document image size parameter of bootefi command UEFI: * avoid building partition support in SPL/TPL where not required * improve integration of EFI subsystem and driver model * restore ability to boot arbitrary blob
Diffstat (limited to 'disk')
-rw-r--r--disk/Kconfig37
-rw-r--r--disk/Makefile3
-rw-r--r--disk/disk-uclass.c247
3 files changed, 269 insertions, 18 deletions
diff --git a/disk/Kconfig b/disk/Kconfig
index 13700322e97..359af3b27e6 100644
--- a/disk/Kconfig
+++ b/disk/Kconfig
@@ -2,8 +2,7 @@
menu "Partition Types"
config PARTITIONS
- bool "Enable Partition Labels (disklabels) support"
- default y
+ bool
help
Partition Labels (disklabels) Supported:
Zero or more of the following:
@@ -20,8 +19,7 @@ config PARTITIONS
as well.
config SPL_PARTITIONS
- bool "Enable Partition Labels (disklabels) support in SPL"
- default y if PARTITIONS
+ bool
select SPL_SPRINTF
select SPL_STRTO
help
@@ -30,8 +28,7 @@ config SPL_PARTITIONS
small amount of size to SPL, typically 500 bytes.
config TPL_PARTITIONS
- bool "Enable Partition Labels (disklabels) support in TPL"
- default y if PARTITIONS
+ bool
select TPL_SPRINTF
select TPL_STRTO
help
@@ -41,57 +38,61 @@ config TPL_PARTITIONS
config MAC_PARTITION
bool "Enable Apple's MacOS partition table"
- depends on PARTITIONS
+ select PARTITIONS
help
Say Y here if you would like to use device under U-Boot which
were partitioned on a Macintosh.
config SPL_MAC_PARTITION
bool "Enable Apple's MacOS partition table for SPL"
- depends on SPL && PARTITIONS
+ depends on SPL
default y if MAC_PARTITION
+ select SPL_PARTITIONS
config DOS_PARTITION
bool "Enable MS Dos partition table"
- depends on PARTITIONS
default y if DISTRO_DEFAULTS
default y if x86 || CMD_FAT || USB_STORAGE
+ select PARTITIONS
help
traditional on the Intel architecture, USB sticks, etc.
config SPL_DOS_PARTITION
bool "Enable MS Dos partition table for SPL"
- depends on SPL && PARTITIONS
+ depends on SPL
default n if ARCH_SUNXI
default y if DOS_PARTITION
+ select SPL_PARTITIONS
config ISO_PARTITION
bool "Enable ISO partition table"
- depends on PARTITIONS
default y if DISTRO_DEFAULTS
default y if MIPS || ARCH_TEGRA
+ select PARTITIONS
config SPL_ISO_PARTITION
bool "Enable ISO partition table for SPL"
- depends on SPL && PARTITIONS
+ depends on SPL
+ select SPL_PARTITIONS
config AMIGA_PARTITION
bool "Enable AMIGA partition table"
- depends on PARTITIONS
+ select PARTITIONS
help
Say Y here if you would like to use device under U-Boot which
were partitioned under AmigaOS.
config SPL_AMIGA_PARTITION
bool "Enable AMIGA partition table for SPL"
- depends on SPL && PARTITIONS
+ depends on SPL
default y if AMIGA_PARTITION
+ select SPL_PARTITIONS
config EFI_PARTITION
bool "Enable EFI GPT partition table"
- depends on PARTITIONS
default y if DISTRO_DEFAULTS
default y if ARCH_TEGRA
+ select PARTITIONS
select LIB_UUID
help
Say Y here if you would like to use device under U-Boot which
@@ -128,9 +129,10 @@ config EFI_PARTITION_ENTRIES_OFF
config SPL_EFI_PARTITION
bool "Enable EFI GPT partition table for SPL"
- depends on SPL && PARTITIONS
+ depends on SPL
default n if ARCH_SUNXI
default y if EFI_PARTITION
+ select SPL_PARTITIONS
config PARTITION_UUIDS
bool "Enable support of UUID for partition"
@@ -143,12 +145,11 @@ config PARTITION_UUIDS
config SPL_PARTITION_UUIDS
bool "Enable support of UUID for partition in SPL"
- depends on SPL && PARTITIONS
+ depends on SPL_PARTITIONS
default y if SPL_EFI_PARTITION
config PARTITION_TYPE_GUID
bool "Enable support of GUID for partition type"
- depends on PARTITIONS
depends on EFI_PARTITION
help
Activate the configuration of GUID type
diff --git a/disk/Makefile b/disk/Makefile
index 5ca10c55762..ec148832b33 100644
--- a/disk/Makefile
+++ b/disk/Makefile
@@ -6,6 +6,9 @@
#ccflags-y += -DET_DEBUG -DDEBUG
obj-$(CONFIG_$(SPL_TPL_)PARTITIONS) += part.o
+ifdef CONFIG_$(SPL_TPL_)BLK
+obj-$(CONFIG_$(SPL_TPL_)PARTITIONS) += disk-uclass.o
+endif
obj-$(CONFIG_$(SPL_TPL_)MAC_PARTITION) += part_mac.o
obj-$(CONFIG_$(SPL_TPL_)DOS_PARTITION) += part_dos.o
obj-$(CONFIG_$(SPL_TPL_)ISO_PARTITION) += part_iso.o
diff --git a/disk/disk-uclass.c b/disk/disk-uclass.c
new file mode 100644
index 00000000000..72ff62ebf58
--- /dev/null
+++ b/disk/disk-uclass.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Software partition device (UCLASS_PARTITION)
+ *
+ * Copyright (c) 2021 Linaro Limited
+ * Author: AKASHI Takahiro
+ */
+
+#define LOG_CATEGORY UCLASS_PARTITION
+
+#include <blk.h>
+#include <dm.h>
+#include <log.h>
+#include <part.h>
+#include <vsprintf.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+
+int part_create_block_devices(struct udevice *blk_dev)
+{
+ int part, count;
+ struct blk_desc *desc = dev_get_uclass_plat(blk_dev);
+ struct disk_partition info;
+ struct disk_part *part_data;
+ char devname[32];
+ struct udevice *dev;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(PARTITIONS) ||
+ !CONFIG_IS_ENABLED(HAVE_BLOCK_DEVICE))
+ return 0;
+
+ if (device_get_uclass_id(blk_dev) != UCLASS_BLK)
+ return 0;
+
+ /* Add devices for each partition */
+ for (count = 0, part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
+ if (part_get_info(desc, part, &info))
+ continue;
+ snprintf(devname, sizeof(devname), "%s:%d", blk_dev->name,
+ part);
+
+ ret = device_bind_driver(blk_dev, "blk_partition",
+ strdup(devname), &dev);
+ if (ret)
+ return ret;
+
+ part_data = dev_get_uclass_plat(dev);
+ part_data->partnum = part;
+ part_data->gpt_part_info = info;
+ count++;
+
+ ret = device_probe(dev);
+ if (ret) {
+ debug("Can't probe\n");
+ count--;
+ device_unbind(dev);
+
+ continue;
+ }
+ }
+ debug("%s: %d partitions found in %s\n", __func__, count,
+ blk_dev->name);
+
+ return 0;
+}
+
+static ulong blk_part_read(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt, void *buffer)
+{
+ struct udevice *parent;
+ struct disk_part *part;
+ const struct blk_ops *ops;
+
+ parent = dev_get_parent(dev);
+ ops = blk_get_ops(parent);
+ if (!ops->read)
+ return -ENOSYS;
+
+ part = dev_get_uclass_plat(dev);
+ if (start >= part->gpt_part_info.size)
+ return 0;
+
+ if ((start + blkcnt) > part->gpt_part_info.size)
+ blkcnt = part->gpt_part_info.size - start;
+ start += part->gpt_part_info.start;
+
+ return ops->read(parent, start, blkcnt, buffer);
+}
+
+static ulong blk_part_write(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt, const void *buffer)
+{
+ struct udevice *parent;
+ struct disk_part *part;
+ const struct blk_ops *ops;
+
+ parent = dev_get_parent(dev);
+ ops = blk_get_ops(parent);
+ if (!ops->write)
+ return -ENOSYS;
+
+ part = dev_get_uclass_plat(dev);
+ if (start >= part->gpt_part_info.size)
+ return 0;
+
+ if ((start + blkcnt) > part->gpt_part_info.size)
+ blkcnt = part->gpt_part_info.size - start;
+ start += part->gpt_part_info.start;
+
+ return ops->write(parent, start, blkcnt, buffer);
+}
+
+static ulong blk_part_erase(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt)
+{
+ struct udevice *parent;
+ struct disk_part *part;
+ const struct blk_ops *ops;
+
+ parent = dev_get_parent(dev);
+ ops = blk_get_ops(parent);
+ if (!ops->erase)
+ return -ENOSYS;
+
+ part = dev_get_uclass_plat(dev);
+ if (start >= part->gpt_part_info.size)
+ return 0;
+
+ if ((start + blkcnt) > part->gpt_part_info.size)
+ blkcnt = part->gpt_part_info.size - start;
+ start += part->gpt_part_info.start;
+
+ return ops->erase(parent, start, blkcnt);
+}
+
+static const struct blk_ops blk_part_ops = {
+ .read = blk_part_read,
+ .write = blk_part_write,
+ .erase = blk_part_erase,
+};
+
+U_BOOT_DRIVER(blk_partition) = {
+ .name = "blk_partition",
+ .id = UCLASS_PARTITION,
+ .ops = &blk_part_ops,
+};
+
+/*
+ * BLOCK IO APIs
+ */
+static struct blk_desc *dev_get_blk(struct udevice *dev)
+{
+ struct blk_desc *block_dev;
+
+ switch (device_get_uclass_id(dev)) {
+ /*
+ * We won't support UCLASS_BLK with dev_* interfaces.
+ */
+ case UCLASS_PARTITION:
+ block_dev = dev_get_uclass_plat(dev_get_parent(dev));
+ break;
+ default:
+ block_dev = NULL;
+ break;
+ }
+
+ return block_dev;
+}
+
+unsigned long dev_read(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt, void *buffer)
+{
+ struct blk_desc *block_dev;
+ const struct blk_ops *ops;
+ struct disk_part *part;
+ lbaint_t start_in_disk;
+ ulong blks_read;
+
+ block_dev = dev_get_blk(dev);
+ if (!block_dev)
+ return -ENOSYS;
+
+ ops = blk_get_ops(dev);
+ if (!ops->read)
+ return -ENOSYS;
+
+ start_in_disk = start;
+ if (device_get_uclass_id(dev) == UCLASS_PARTITION) {
+ part = dev_get_uclass_plat(dev);
+ start_in_disk += part->gpt_part_info.start;
+ }
+
+ if (blkcache_read(block_dev->if_type, block_dev->devnum,
+ start_in_disk, blkcnt, block_dev->blksz, buffer))
+ return blkcnt;
+ blks_read = ops->read(dev, start, blkcnt, buffer);
+ if (blks_read == blkcnt)
+ blkcache_fill(block_dev->if_type, block_dev->devnum,
+ start_in_disk, blkcnt, block_dev->blksz, buffer);
+
+ return blks_read;
+}
+
+unsigned long dev_write(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt, const void *buffer)
+{
+ struct blk_desc *block_dev;
+ const struct blk_ops *ops;
+
+ block_dev = dev_get_blk(dev);
+ if (!block_dev)
+ return -ENOSYS;
+
+ ops = blk_get_ops(dev);
+ if (!ops->write)
+ return -ENOSYS;
+
+ blkcache_invalidate(block_dev->if_type, block_dev->devnum);
+
+ return ops->write(dev, start, blkcnt, buffer);
+}
+
+unsigned long dev_erase(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt)
+{
+ struct blk_desc *block_dev;
+ const struct blk_ops *ops;
+
+ block_dev = dev_get_blk(dev);
+ if (!block_dev)
+ return -ENOSYS;
+
+ ops = blk_get_ops(dev);
+ if (!ops->erase)
+ return -ENOSYS;
+
+ blkcache_invalidate(block_dev->if_type, block_dev->devnum);
+
+ return ops->erase(dev, start, blkcnt);
+}
+
+UCLASS_DRIVER(partition) = {
+ .id = UCLASS_PARTITION,
+ .per_device_plat_auto = sizeof(struct disk_part),
+ .name = "partition",
+};