barebox as EFI loader can use the information about which partitions are
bootable to guide its decision. Record this information.

Signed-off-by: Ahmad Fatoum <a.fat...@pengutronix.de>
---
 common/partitions.c        |  4 ++--
 common/partitions/dos.c    | 10 ++++++++++
 common/partitions/efi.c    | 18 ++++++++++++++++++
 common/partitions/parser.h |  3 +++
 include/driver.h           |  5 +++++
 include/efi/partition.h    |  6 ++++--
 6 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/common/partitions.c b/common/partitions.c
index 8a245a1eee3d..53001a64770f 100644
--- a/common/partitions.c
+++ b/common/partitions.c
@@ -52,8 +52,8 @@ static int register_one_partition(struct block_device *blk,
                goto out;
        }
 
-       cdev->flags |= DEVFS_PARTITION_FROM_TABLE;
-
+       cdev->flags |= DEVFS_PARTITION_FROM_TABLE | part->flags;
+       cdev->typeflags |= part->typeflags;
        cdev->typeuuid = part->typeuuid;
        strcpy(cdev->partuuid, part->partuuid);
 
diff --git a/common/partitions/dos.c b/common/partitions/dos.c
index 7472824b00b9..bf37b2852b9e 100644
--- a/common/partitions/dos.c
+++ b/common/partitions/dos.c
@@ -163,6 +163,15 @@ static void dos_extended_partition(struct block_device 
*blk, struct partition_de
        return;
 }
 
+static void extract_flags(const struct partition_entry *p,
+                         struct partition *pentry)
+{
+       if (p->boot_indicator == 0x80)
+               pentry->flags |= DEVFS_PARTITION_BOOTABLE_LEGACY;
+       if (p->type == 0xef)
+               pentry->flags |= DEVFS_PARTITION_BOOTABLE_ESP;
+}
+
 /**
  * Check if a DOS like partition describes this block device
  * @param blk Block device to register to
@@ -199,6 +208,7 @@ static void dos_partition(void *buf, struct block_device 
*blk,
                        pd->parts[n].first_sec = pentry.first_sec;
                        pd->parts[n].size = pentry.size;
                        pd->parts[n].dos_partition_type = 
pentry.dos_partition_type;
+                       extract_flags(&table[i], &pd->parts[n]);
                        if (signature)
                                sprintf(pd->parts[n].partuuid, "%08x-%02d",
                                                signature, i + 1);
diff --git a/common/partitions/efi.c b/common/partitions/efi.c
index 0add66e6e4a6..6260702577f9 100644
--- a/common/partitions/efi.c
+++ b/common/partitions/efi.c
@@ -431,6 +431,23 @@ static void part_set_efi_name(gpt_entry *pte, char *dest)
        dest[i] = 0;
 }
 
+static void extract_flags(const gpt_entry *p, struct partition *pentry)
+{
+       static const guid_t system_guid = PARTITION_SYSTEM_GUID;
+
+       if (p->attributes.required_to_function)
+               pentry->flags |= DEVFS_PARTITION_REQUIRED;
+       if (p->attributes.no_block_io_protocol)
+               pentry->flags |= DEVFS_PARTITION_NO_EXPORT;
+       if (p->attributes.legacy_bios_bootable)
+               pentry->flags |= DEVFS_PARTITION_BOOTABLE_LEGACY;
+
+       if (guid_equal(&p->partition_type_guid, &system_guid))
+               pentry->flags |=  DEVFS_PARTITION_BOOTABLE_ESP;
+
+       pentry->typeflags = p->attributes.type_guid_specific;
+}
+
 static void efi_partition(void *buf, struct block_device *blk,
                          struct partition_desc *pd)
 {
@@ -466,6 +483,7 @@ static void efi_partition(void *buf, struct block_device 
*blk,
                }
 
                pentry = &pd->parts[pd->used_entries];
+               extract_flags(&ptes[i], pentry);
                pentry->first_sec = le64_to_cpu(ptes[i].starting_lba);
                pentry->size = le64_to_cpu(ptes[i].ending_lba) - 
pentry->first_sec;
                pentry->size++;
diff --git a/common/partitions/parser.h b/common/partitions/parser.h
index 9cc41a7573fe..fce368156400 100644
--- a/common/partitions/parser.h
+++ b/common/partitions/parser.h
@@ -11,6 +11,7 @@
 #include <filetype.h>
 #include <linux/uuid.h>
 #include <linux/list.h>
+#include <driver.h>
 
 #define MAX_PARTITION          128
 #define MAX_PARTITION_NAME     38
@@ -24,6 +25,8 @@ struct partition {
                u8 dos_partition_type;
                guid_t typeuuid;
        };
+       unsigned int flags;
+       unsigned int typeflags;
 };
 
 struct partition_desc {
diff --git a/include/driver.h b/include/driver.h
index c6da5a3d0d54..b6fe8712837b 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -543,6 +543,7 @@ struct cdev {
        loff_t offset;
        loff_t size;
        unsigned int flags;
+       u16 typeflags; /* GPT type-specific attributes */
        int open;
        struct mtd_info *mtd;
        struct cdev *link;
@@ -615,6 +616,10 @@ extern struct list_head cdev_list;
 #define DEVFS_PARTITION_FROM_TABLE     (1U << 6)
 #define DEVFS_IS_MBR_PARTITIONED       (1U << 7)
 #define DEVFS_IS_GPT_PARTITIONED       (1U << 8)
+#define DEVFS_PARTITION_REQUIRED       (1U << 9)
+#define DEVFS_PARTITION_NO_EXPORT      (1U << 10)
+#define DEVFS_PARTITION_BOOTABLE_LEGACY        (1U << 11)
+#define DEVFS_PARTITION_BOOTABLE_ESP   (1U << 12)
 
 static inline bool cdev_is_mbr_partitioned(const struct cdev *master)
 {
diff --git a/include/efi/partition.h b/include/efi/partition.h
index 0ca2a72eb9b7..29175673e351 100644
--- a/include/efi/partition.h
+++ b/include/efi/partition.h
@@ -95,8 +95,10 @@ typedef struct _gpt_header {
 
 typedef struct _gpt_entry_attributes {
        u64 required_to_function:1;
-       u64 reserved:47;
-        u64 type_guid_specific:16;
+       u64 no_block_io_protocol:1;
+       u64 legacy_bios_bootable:1;
+       u64 reserved:45;
+       u64 type_guid_specific:16;
 } __attribute__ ((packed)) gpt_entry_attributes;
 
 #define GPT_PARTNAME_MAX_SIZE  (72 / sizeof (wchar_t))
-- 
2.39.2


Reply via email to