:: commit 7ee7e3425c7983279bf84203b16db5ff3ab7c9a5

mintsuki <mintsuki@protonmail.com> — 2021-03-13 08:08

parents: de4fd786dd

pxe: Make it work again

diff --git a/stage23/entry.s2.c b/stage23/entry.s2.c
index d8f91aae..a1724444 100644
--- a/stage23/entry.s2.c
+++ b/stage23/entry.s2.c
@@ -84,6 +84,9 @@ void entry(uint8_t boot_drive, int boot_from) {
 
     if (boot_from == BOOTED_FROM_HDD || boot_from == BOOTED_FROM_CD) {
         boot_volume = volume_get_by_coord(boot_drive, -1);
+    } else if (boot_from == BOOTED_FROM_PXE) {
+        pxe_init();
+        boot_volume = pxe_bind_volume();
     }
 
     volume_iterate_parts(boot_volume,
diff --git a/stage23/fs/file.s2.c b/stage23/fs/file.s2.c
index 95b328ea..a369bf2d 100644
--- a/stage23/fs/file.s2.c
+++ b/stage23/fs/file.s2.c
@@ -10,6 +10,7 @@
 #include <mm/pmm.h>
 #include <lib/part.h>
 #include <lib/libc.h>
+#include <pxe/tftp.h>
 
 bool fs_get_guid(struct guid *guid, struct volume *part) {
     if (echfs_check_signature(part)) {
@@ -25,6 +26,20 @@ bool fs_get_guid(struct guid *guid, struct volume *part) {
 int fopen(struct file_handle *ret, struct volume *part, const char *filename) {
     ret->is_memfile = false;
 
+    if (part->pxe) {
+        struct tftp_file_handle *fd = ext_mem_alloc(sizeof(struct tftp_file_handle));
+
+        int r = tftp_open(fd, 0, 69, filename);
+        if (r)
+            return r;
+
+        ret->fd = (void *)fd;
+        ret->read = (void *)tftp_read;
+        ret->size = fd->file_size;
+
+        return 0;
+    }
+
     if (iso9660_check_signature(part)) {
         struct iso9660_file_handle *fd = ext_mem_alloc(sizeof(struct iso9660_file_handle));
 
diff --git a/stage23/lib/part.h b/stage23/lib/part.h
index 38c26be8..28f8fd46 100644
--- a/stage23/lib/part.h
+++ b/stage23/lib/part.h
@@ -18,6 +18,8 @@ struct volume {
     EFI_HANDLE efi_handle;
 #endif
 
+    bool pxe;
+
     int drive;
     int partition;
     int sector_size;
@@ -52,22 +54,29 @@ bool volume_read(struct volume *part, void *buffer, uint64_t loc, uint64_t count
 
 #define volume_iterate_parts(_VOLUME_, _BODY_) ({   \
     struct volume *_VOLUME = _VOLUME_;   \
-    while (_VOLUME->backing_dev != NULL) { \
-        _VOLUME = _VOLUME->backing_dev; \
-    } \
+    if (_VOLUME->pxe) { \
+        do { \
+            struct volume *_PART = _VOLUME; \
+            _BODY_ \
+        } while (0); \
+    } else { \
+        while (_VOLUME->backing_dev != NULL) { \
+            _VOLUME = _VOLUME->backing_dev; \
+        } \
  \
-    int _PART_CNT = -1; \
-    for (size_t _PARTNO = -1; ; _PARTNO++) { \
-        if (_PART_CNT > _VOLUME->max_partition) \
-            break; \
+        int _PART_CNT = -1; \
+        for (size_t _PARTNO = -1; ; _PARTNO++) { \
+            if (_PART_CNT > _VOLUME->max_partition) \
+                break; \
  \
-        struct volume *_PART = volume_get_by_coord(_VOLUME->drive, _PARTNO); \
-        if (_PART == NULL) \
-            continue; \
+            struct volume *_PART = volume_get_by_coord(_VOLUME->drive, _PARTNO); \
+            if (_PART == NULL) \
+                continue; \
  \
-        _PART_CNT++; \
+            _PART_CNT++; \
  \
-        _BODY_ \
+            _BODY_ \
+        } \
     } \
 })
 
diff --git a/stage23/lib/part.s2.c b/stage23/lib/part.s2.c
index 7d918f0a..43f68fdf 100644
--- a/stage23/lib/part.s2.c
+++ b/stage23/lib/part.s2.c
@@ -41,6 +41,10 @@ static bool cache_block(struct volume *volume, uint64_t block) {
 }
 
 bool volume_read(struct volume *volume, void *buffer, uint64_t loc, uint64_t count) {
+    if (volume->pxe) {
+        panic("Attempted volume_read() on pxe");
+    }
+
     uint64_t block_size = BLOCK_SIZE_IN_SECTORS * volume->sector_size;
 
     uint64_t progress = 0;
diff --git a/stage23/lib/uri.c b/stage23/lib/uri.c
index 409d3d37..cd311a5c 100644
--- a/stage23/lib/uri.c
+++ b/stage23/lib/uri.c
@@ -177,7 +177,7 @@ static bool uri_tftp_dispatch(struct file_handle *fd, char *root, char *path) {
 
 static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path) {
 #if defined (bios)
-    if (false /*booted_from_pxe*/)
+    if (boot_volume->pxe)
         return uri_tftp_dispatch(fd, s_part, path);
 #endif
 
diff --git a/stage23/mm/pmm.s2.c b/stage23/mm/pmm.s2.c
index 2ed1fd7e..6c1f2a0d 100644
--- a/stage23/mm/pmm.s2.c
+++ b/stage23/mm/pmm.s2.c
@@ -406,6 +406,9 @@ void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type)
 }
 
 bool memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free_only, bool do_panic) {
+    if (length == 0)
+        return true;
+
     uint64_t top = base + length;
 
 #if defined (bios)
diff --git a/stage23/pxe/pxe.h b/stage23/pxe/pxe.h
index a1a9ab65..84c86510 100644
--- a/stage23/pxe/pxe.h
+++ b/stage23/pxe/pxe.h
@@ -2,7 +2,9 @@
 #define PXE_H
 
 #include <stdint.h>
+#include <lib/part.h>
 
+struct volume *pxe_bind_volume(void);
 void pxe_init(void);
 int pxe_call(uint16_t opcode, uint16_t buf_seg, uint16_t buf_off) __attribute__((regparm(3)));
 
@@ -56,18 +58,18 @@ struct pxenv {
     uint8_t checksum;
     uint32_t rm_entry;
     uint32_t pm_offset;
-    uint16_t pm_selector; 
-    uint16_t stack_seg; 
-    uint16_t stack_size; 
-    uint16_t bc_code_seg; 
-    uint16_t bc_code_size; 
-    uint16_t bc_data_seg; 
-    uint16_t bc_data_size; 
-    uint16_t undi_data_seg; 
-    uint16_t undi_data_size; 
-    uint16_t undi_code_seg; 
-    uint16_t undi_code_size; 
-    uint32_t pxe_ptr; 
+    uint16_t pm_selector;
+    uint16_t stack_seg;
+    uint16_t stack_size;
+    uint16_t bc_code_seg;
+    uint16_t bc_code_size;
+    uint16_t bc_data_seg;
+    uint16_t bc_data_size;
+    uint16_t undi_data_seg;
+    uint16_t undi_data_size;
+    uint16_t undi_code_seg;
+    uint16_t undi_code_size;
+    uint32_t pxe_ptr;
 } __attribute__((packed));
 
 #define PXE_BANGPXE_SIGNATURE "!PXE"
diff --git a/stage23/pxe/pxe.c b/stage23/pxe/pxe.s2.c
similarity index 87%
rename from stage23/pxe/pxe.c
rename to stage23/pxe/pxe.s2.c
index 60070f48..dac2c765 100644
--- a/stage23/pxe/pxe.c
+++ b/stage23/pxe/pxe.s2.c
@@ -5,9 +5,18 @@
 #include <pxe/pxe.h>
 #include <lib/libc.h>
 #include <lib/blib.h>
+#include <mm/pmm.h>
 
 void set_pxe_fp(uint32_t fp);
 
+struct volume *pxe_bind_volume(void) {
+    struct volume *volume = ext_mem_alloc(sizeof(struct volume));
+
+    volume->pxe = true;
+
+    return volume;
+}
+
 void pxe_init(void) {
     //pxe installation check
     struct rm_regs r = { 0 };
diff --git a/stage23/pxe/tftp.h b/stage23/pxe/tftp.h
index 0d0a64f3..08d9cc26 100644
--- a/stage23/pxe/tftp.h
+++ b/stage23/pxe/tftp.h
@@ -47,6 +47,6 @@ struct pxenv_get_file_size {
 //server_ip and server_port can be 0 for default
 int tftp_open(struct tftp_file_handle* handle, uint32_t server_ip, uint16_t server_port, const char* name);
 int tftp_read(void *fd, void *buf, uint64_t loc, uint64_t count);
-uint32_t get_boot_server_info();
+uint32_t get_boot_server_info(void);
 
 #endif
diff --git a/stage23/pxe/tftp.c b/stage23/pxe/tftp.s2.c
similarity index 98%
rename from stage23/pxe/tftp.c
rename to stage23/pxe/tftp.s2.c
index aab56e94..8ac88265 100644
--- a/stage23/pxe/tftp.c
+++ b/stage23/pxe/tftp.s2.c
@@ -8,7 +8,7 @@
 #include <mm/pmm.h>
 #include <lib/blib.h>
 
-uint32_t get_boot_server_info() {
+uint32_t get_boot_server_info(void) {
     struct pxenv_get_cached_info cachedinfo = { 0 };
     cachedinfo.packet_type = 2;
     pxe_call(PXENV_GET_CACHED_INFO, ((uint16_t)rm_seg(&cachedinfo)), (uint16_t)rm_off(&cachedinfo));
tab: 248 wrap: offon