]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
drivers: partition: Add simple MBR partition entries support
authorLoh Tien Hock <tien.hock.loh@intel.com>
Mon, 11 Feb 2019 02:56:28 +0000 (10:56 +0800)
committerLoh Tien Hock <tien.hock.loh@intel.com>
Wed, 13 Feb 2019 06:26:15 +0000 (14:26 +0800)
This is to add simple MBR partition entry support. This will read all four
MBR partition into the partition list, and the partition type will be saved
in the list.name[0] entry.

Signed-off-by: Loh Tien Hock <tien.hock.loh@intel.com>
drivers/partition/partition.c

index 6fa3df0f268cdf1e2919df812086e1ce3c866a4a..7fdbf5385aa7fe10ea62422133094d6abdf26ffc 100644 (file)
@@ -105,6 +105,57 @@ static int load_gpt_header(uintptr_t image_handle)
        return 0;
 }
 
+static int load_mbr_entry(uintptr_t image_handle, mbr_entry_t *mbr_entry,
+                       int part_number)
+{
+       size_t bytes_read;
+       uintptr_t offset;
+       int result;
+
+       assert(mbr_entry != NULL);
+       /* MBR partition table is in LBA0. */
+       result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
+       if (result != 0) {
+               WARN("Failed to seek (%i)\n", result);
+               return result;
+       }
+       result = io_read(image_handle, (uintptr_t)&mbr_sector,
+                        PARTITION_BLOCK_SIZE, &bytes_read);
+       if (result != 0) {
+               WARN("Failed to read data (%i)\n", result);
+               return result;
+       }
+
+       /* Check MBR boot signature. */
+       if ((mbr_sector[PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
+           (mbr_sector[PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
+               return -ENOENT;
+       }
+       offset = (uintptr_t)&mbr_sector +
+               MBR_PRIMARY_ENTRY_OFFSET +
+               MBR_PRIMARY_ENTRY_SIZE * part_number;
+       memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t));
+
+       return 0;
+}
+
+static int load_mbr_entries(uintptr_t image_handle)
+{
+       mbr_entry_t mbr_entry;
+       int i;
+
+       list.entry_count = MBR_PRIMARY_ENTRY_NUMBER;
+
+       for (i = 0; i < list.entry_count; i++) {
+               load_mbr_entry(image_handle, &mbr_entry, i);
+               list.list[i].start = mbr_entry.first_lba * 512;
+               list.list[i].length = mbr_entry.sector_nums * 512;
+               list.list[i].name[0] = mbr_entry.type;
+       }
+
+       return 0;
+}
+
 static int load_gpt_entry(uintptr_t image_handle, gpt_entry_t *entry)
 {
        size_t bytes_read;
@@ -175,11 +226,9 @@ int load_partition_table(unsigned int image_id)
                assert(result == 0);
                result = verify_partition_gpt(image_handle);
        } else {
-               /* MBR type isn't supported yet. */
-               result = -EINVAL;
-               goto exit;
+               result = load_mbr_entries(image_handle);
        }
-exit:
+
        io_close(image_handle);
        return result;
 }