:: commit f7a8bbd7f65cdaadc4d373590dd26319ed45d998

mintsuki <mintsuki@protonmail.com> — 2021-03-03 21:38

parents: 54862a8269

A lot of changes

diff --git a/stage23/drivers/disk.h b/stage23/drivers/disk.h
index 3a883d31..1357a315 100644
--- a/stage23/drivers/disk.h
+++ b/stage23/drivers/disk.h
@@ -6,17 +6,6 @@
 #include <stdbool.h>
 #include <lib/part.h>
 
-struct bios_drive_params {
-    uint16_t buf_size;
-    uint16_t info_flags;
-    uint32_t cyl;
-    uint32_t heads;
-    uint32_t sects;
-    uint64_t lba_count;
-    uint16_t bytes_per_sect;
-    uint32_t edd;
-} __attribute__((packed));
-
 size_t disk_create_index(struct volume **ret);
 bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t count);
 
diff --git a/stage23/drivers/disk.s2.c b/stage23/drivers/disk.s2.c
index 92a0ac2c..ab3cc829 100644
--- a/stage23/drivers/disk.s2.c
+++ b/stage23/drivers/disk.s2.c
@@ -1,14 +1,29 @@
-#if defined(bios)
-
 #include <stdint.h>
 #include <stddef.h>
 #include <drivers/disk.h>
 #include <lib/libc.h>
-#include <lib/real.h>
+#if defined (bios)
+#  include <lib/real.h>
+#elif defined (uefi)
+#  include <efi.h>
+#endif
 #include <lib/blib.h>
 #include <lib/print.h>
 #include <mm/pmm.h>
 
+#if defined(bios)
+
+struct bios_drive_params {
+    uint16_t buf_size;
+    uint16_t info_flags;
+    uint32_t cyl;
+    uint32_t heads;
+    uint32_t sects;
+    uint64_t lba_count;
+    uint16_t bytes_per_sect;
+    uint32_t edd;
+} __attribute__((packed));
+
 struct dap {
     uint16_t size;
     uint16_t count;
@@ -31,7 +46,7 @@ bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t
 
     if (dap == NULL) {
         dap = conv_mem_alloc(sizeof(struct dap));
-        dap->size  = 16;
+        dap->size = 16;
     }
 
     dap->count = count;
@@ -91,7 +106,7 @@ size_t disk_create_index(struct volume **ret) {
 
         volume_count++;
 
-        struct volume block;
+        struct volume block = {0};
 
         block.drive = drive;
         block.sector_size = drive_params.bytes_per_sect;
@@ -106,7 +121,7 @@ size_t disk_create_index(struct volume **ret) {
         }
 
         for (int part = 0; ; part++) {
-            struct volume p;
+            struct volume p = {0};
             int ret = part_get(&p, &block, part);
 
             if (ret == END_OF_TABLE || ret == INVALID_TABLE)
@@ -155,7 +170,114 @@ size_t disk_create_index(struct volume **ret) {
         }
 
         for (int part = 0; ; part++) {
-            struct volume p;
+            struct volume p = {0};
+            int ret = part_get(&p, block, part);
+
+            if (ret == END_OF_TABLE || ret == INVALID_TABLE)
+                break;
+            if (ret == NO_PARTITION)
+                continue;
+
+            volume_index[volume_index_i++] = p;
+        }
+    }
+
+    *ret = volume_index;
+    return volume_count;
+}
+
+#endif
+
+#if defined (uefi)
+
+bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t count) {
+    EFI_STATUS status;
+
+    status = uefi_call_wrapper(volume->drive->ReadBlocks, 5, volume->drive,
+                               volume->drive->Media->MediaId,
+                               block, count * volume->sector_size, buf);
+
+    if (status != 0) {
+        return false;
+    }
+
+    return true;
+}
+
+size_t disk_create_index(struct volume **ret) {
+    EFI_STATUS status;
+
+    struct volume *volume_index = NULL;
+    size_t volume_index_i = 0;
+    size_t volume_count = 0;
+
+    EFI_GUID block_io_guid = BLOCK_IO_PROTOCOL;
+    EFI_HANDLE *handles = NULL;
+    UINTN handles_size = 0;
+
+    uefi_call_wrapper(gBS->LocateHandle, 5, ByProtocol, &block_io_guid,
+                      NULL, &handles_size, handles);
+
+    handles = ext_mem_alloc(handles_size);
+
+    uefi_call_wrapper(gBS->LocateHandle, 5, ByProtocol, &block_io_guid,
+                      NULL, &handles_size, handles);
+
+    for (size_t i = 0; i < handles_size / sizeof(EFI_HANDLE); i++) {
+        struct volume block = {0};
+
+        status = uefi_call_wrapper(gBS->HandleProtocol, 3, handles[i],
+                                   &block_io_guid, &block.drive);
+
+        if (status != 0 || block.drive == NULL || block.drive->Media->LastBlock == 0)
+            continue;
+
+        if (block.drive->Media->LogicalPartition)
+            continue;
+
+        volume_count++;
+
+        block.sector_size = block.drive->Media->BlockSize;
+        block.first_sect = 0;
+        block.sect_count = block.drive->Media->LastBlock + 1;
+
+        for (int part = 0; ; part++) {
+            struct volume p = {0};
+            int ret = part_get(&p, &block, part);
+
+            if (ret == END_OF_TABLE || ret == INVALID_TABLE)
+                break;
+            if (ret == NO_PARTITION)
+                continue;
+
+            volume_count++;
+        }
+    }
+
+    volume_index = ext_mem_alloc(sizeof(struct volume) * volume_count);
+
+    for (size_t i = 0; i < handles_size / sizeof(EFI_HANDLE); i++) {
+        EFI_BLOCK_IO *drive;
+
+        status = uefi_call_wrapper(gBS->HandleProtocol, 3, handles[i],
+                                   &block_io_guid, &drive);
+
+        if (status != 0 || drive == NULL || drive->Media->LastBlock == 0)
+            continue;
+
+        if (drive->Media->LogicalPartition)
+            continue;
+
+        struct volume *block = &volume_index[volume_index_i++];
+
+        block->drive = drive;
+        block->partition = -1;
+        block->sector_size = drive->Media->BlockSize;
+        block->first_sect = 0;
+        block->sect_count = drive->Media->LastBlock + 1;
+
+        for (int part = 0; ; part++) {
+            struct volume p = {0};
             int ret = part_get(&p, block, part);
 
             if (ret == END_OF_TABLE || ret == INVALID_TABLE)
diff --git a/stage23/entry.s3.c b/stage23/entry.s3.c
index 8de693ff..30e97c0e 100644
--- a/stage23/entry.s3.c
+++ b/stage23/entry.s3.c
@@ -20,6 +20,8 @@
 #include <pxe/pxe.h>
 #include <pxe/tftp.h>
 
+void stage3_common(void);
+
 #if defined (uefi)
 __attribute__((ms_abi))
 EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
@@ -29,12 +31,41 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
     gBS = SystemTable->BootServices;
     gRT = SystemTable->RuntimeServices;
 
-    print("hello world\n");
+    print("Limine " LIMINE_VERSION "\n\n");
+
+    //volume_create_index();
+
+    EFI_GUID loaded_img_prot_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
+    EFI_LOADED_IMAGE_PROTOCOL *loaded_image = NULL;
+
+    uefi_call_wrapper(gBS->HandleProtocol, 3, ImageHandle, &loaded_img_prot_guid,
+                      &loaded_image);
+
+    EFI_GUID block_io_guid = BLOCK_IO_PROTOCOL;
+    EFI_BLOCK_IO *drive;
+
+    uefi_call_wrapper(gBS->HandleProtocol, 3, loaded_image->DeviceHandle,
+                      &block_io_guid, &drive);
+
+    struct volume boot_volume;
+    boot_volume.drive = drive;
+    boot_volume.partition = -1;
+    boot_volume.sector_size = drive->Media->BlockSize;
+    boot_volume.first_sect = 0;
+    boot_volume.sect_count = drive->Media->LastBlock + 1;
+
+    if (!init_config_disk(&boot_volume)) {
+        print("Config file found and loaded.\n");
+    } else {
+        panic("Config file not found.");
+    }
 
     for (;;);
+    //stage3_common();
 }
 #endif
 
+#if defined (bios)
 __attribute__((section(".stage3_build_id")))
 uint64_t stage3_build_id = BUILD_ID;
 
@@ -48,19 +79,15 @@ void stage3_entry(int boot_from) {
         case BOOT_FROM_CD: {
             struct volume boot_volume = {0};
             volume_get_by_coord(&boot_volume, boot_drive, -1);
-            struct volume part = boot_volume;
-            for (int i = 0; ; i++) {
-                if (!init_config_disk(&part)) {
+
+            if (!volume_iterate_parts(boot_volume,
+                if (!init_config_disk(&_PART_)) {
                     print("Config file found and loaded.\n");
-                    boot_partition = i - 1;
+                    boot_partition = _PARTNUM_;
                     break;
                 }
-                int ret = part_get(&part, &boot_volume, i);
-                switch (ret) {
-                    case INVALID_TABLE:
-                    case END_OF_TABLE:
-                        panic("Config file not found.");
-                }
+            )) {
+                panic("Config file not found.");
             }
             break;
         case BOOT_FROM_PXE:
@@ -73,6 +100,12 @@ void stage3_entry(int boot_from) {
         }
     }
 
+    stage3_common();
+}
+#endif
+
+__attribute__((noreturn))
+void stage3_common(void) {
     char *cmdline;
     char *config = menu(&cmdline);
 
@@ -81,17 +114,19 @@ void stage3_entry(int boot_from) {
         panic("PROTOCOL not specified");
     }
 
-    if (!strcmp(proto, "stivale")) {
+    if (0) {
+
+    } else if (!strcmp(proto, "stivale")) {
         stivale_load(config, cmdline);
     } else if (!strcmp(proto, "stivale2")) {
         stivale2_load(config, cmdline, booted_from_pxe);
+#if defined (bios)
     } else if (!strcmp(proto, "linux")) {
         linux_load(config, cmdline);
     } else if (!strcmp(proto, "chainload")) {
         chainload(config);
-    } else {
-        panic("Invalid protocol specified");
+#endif
     }
 
-    for (;;);
+    panic("Invalid protocol specified");
 }
diff --git a/stage23/fs/file.s2.c b/stage23/fs/file.s2.c
index 8fbc65c4..95b328ea 100644
--- a/stage23/fs/file.s2.c
+++ b/stage23/fs/file.s2.c
@@ -5,6 +5,7 @@
 #include <fs/ext2.h>
 #include <fs/fat32.h>
 #include <fs/iso9660.h>
+#include <lib/print.h>
 #include <lib/blib.h>
 #include <mm/pmm.h>
 #include <lib/part.h>
diff --git a/stage23/lib/part.h b/stage23/lib/part.h
index ddab7085..6bebb57e 100644
--- a/stage23/lib/part.h
+++ b/stage23/lib/part.h
@@ -15,7 +15,7 @@
 #if defined (bios)
 typedef int drive_t;
 #elif defined (uefi)
-typedef EFI_HANDLE drive_t;
+typedef EFI_BLOCK_IO *drive_t;
 #endif
 
 struct volume {
@@ -43,4 +43,23 @@ bool volume_get_by_coord(struct volume *part, drive_t drive, int partition);
 
 bool volume_read(struct volume *part, void *buffer, uint64_t loc, uint64_t count);
 
+#define volume_iterate_parts(_VOLUME_, _BODY_) ({   \
+    bool _OK_ = true;                               \
+    struct volume _PART_ = _VOLUME_;                \
+    for (int i = 0; ; i++) {                        \
+        int _PARTNUM_ = i - 1;                      \
+        _BODY_ ;                                    \
+        switch (part_get(&_PART_, &_VOLUME_, i)) {  \
+            case INVALID_TABLE:                     \
+            case END_OF_TABLE:                      \
+                _OK_ = false;                       \
+                break;                              \
+            default:                                \
+                continue;                           \
+        }                                           \
+        break;                                      \
+    }                                               \
+    _OK_;                                           \
+})
+
 #endif
diff --git a/stage23/lib/part.s2.c b/stage23/lib/part.s2.c
index 97f35db8..61a4f8f4 100644
--- a/stage23/lib/part.s2.c
+++ b/stage23/lib/part.s2.c
@@ -1,9 +1,9 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <lib/part.h>
+#include <drivers/disk.h>
 #if defined (bios)
-#  include <drivers/disk.h>
-#include <lib/real.h>
+#  include <lib/real.h>
 #endif
 #include <lib/libc.h>
 #include <lib/blib.h>
@@ -295,11 +295,7 @@ static struct volume *volume_index = NULL;
 static size_t volume_index_i = 0;
 
 void volume_create_index(void) {
-#if defined (bios)
     volume_index_i = disk_create_index(&volume_index);
-#elif defined (uefi)
-
-#endif
 }
 
 bool volume_get_by_guid(struct volume *part, struct guid *guid) {
diff --git a/stage23/linker_nomap_uefi.ld b/stage23/linker_nomap_uefi.ld
index 2546559f..cd6878a7 100644
--- a/stage23/linker_nomap_uefi.ld
+++ b/stage23/linker_nomap_uefi.ld
@@ -8,6 +8,7 @@ SECTIONS
     .text : {
         *(.text*)
         *(.realmode*)
+        *(.stage3_entry*)
     }
 
     .rodata : {
diff --git a/stage23/linker_uefi.ld b/stage23/linker_uefi.ld
index 6e7b0e01..73a13f8b 100644
--- a/stage23/linker_uefi.ld
+++ b/stage23/linker_uefi.ld
@@ -8,6 +8,7 @@ SECTIONS
     .text : {
         *(.text*)
         *(.realmode*)
+        *(.stage3_entry*)
     }
 
     .rodata : {
diff --git a/stage23/mm/pmm.s2.c b/stage23/mm/pmm.s2.c
index 4baa5414..31e2cc74 100644
--- a/stage23/mm/pmm.s2.c
+++ b/stage23/mm/pmm.s2.c
@@ -263,15 +263,23 @@ void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type)
 void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type) {
     (void)type;
 
+    EFI_STATUS status;
+
     void *ret;
 
     if (alignment && alignment % 4096 == 0) {
-        uefi_call_wrapper(gBS->AllocatePages, 4, 0, 2, DIV_ROUNDUP(count, 4096),
-                          &ret);
+        status = uefi_call_wrapper(gBS->AllocatePages, 4, 0, 2,
+                                   DIV_ROUNDUP(count, 4096), &ret);
     } else {
-        uefi_call_wrapper(gBS->AllocatePool, 3, 4, count, &ret);
+        status = uefi_call_wrapper(gBS->AllocatePool, 3, 4, count, &ret);
+    }
+
+    if (status) {
+        panic("Memory allocation error %x\n", status);
     }
 
+    memset(ret, 0, count);
+
     return ret;
 }
 #endif
tab: 248 wrap: offon