[SeaBIOS] [PATCH v2 2/2] QEMU fw_cfg: Add command to write back address of file

ben at skyportsystems.com ben at skyportsystems.com
Fri Jan 20 23:33:16 CET 2017


From: Ben Warren <ben at skyportsystems.com>

The command allows the memory allocation of a fw_cfg file by BIOS and
subsequent return of the allocated address to QEMU.

Signed-off-by: Ben Warren <ben at skyportsystems.com>
---
 src/fw/romfile_loader.c | 38 ++++++++++++++++++++++++++++++++++++++
 src/fw/romfile_loader.h | 23 ++++++++++++++++++++---
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/src/fw/romfile_loader.c b/src/fw/romfile_loader.c
index f4b17ff..1b3fb3e 100644
--- a/src/fw/romfile_loader.c
+++ b/src/fw/romfile_loader.c
@@ -5,6 +5,7 @@
 #include "romfile.h" // struct romfile_s
 #include "malloc.h" // Zone*, _malloc
 #include "output.h" // warn_*
+#include "paravirt.h" // qemu_cfg_write_file
 
 struct romfile_loader_file {
     struct romfile_s *file;
@@ -127,6 +128,38 @@ err:
     warn_internalerror();
 }
 
+static void romfile_loader_return_addr(struct romfile_loader_entry_s *entry,
+                                        struct romfile_loader_files *files)
+{
+    struct romfile_loader_file *alloc_file;
+    struct romfile_loader_file *addr_file;
+    u64 addr;
+    int ret;
+
+    alloc_file = romfile_loader_find(entry->alloc_ret_file, files);
+    addr_file = romfile_loader_find(entry->alloc_ret_addr_file, files);
+
+    if (!alloc_file || !addr_file || !alloc_file->data || !addr_file->data ||
+        addr_file->file->size < sizeof(addr))
+        goto err;
+
+    /* Get the address of the just-allocated file
+     * and stuff it in the address file */
+    void *data_ptr = alloc_file->data;
+
+    memcpy(&addr, &data_ptr, sizeof(data_ptr));
+    addr = cpu_to_le64(addr);
+    memcpy(addr_file->data, &addr, sizeof(addr));
+
+    /* Only supported on QEMU */
+    ret = qemu_cfg_write_file(&addr, addr_file->file, sizeof(addr));
+    if (ret != sizeof(addr))
+        goto err;
+    return;
+err:
+    warn_internalerror();
+}
+
 int romfile_loader_execute(const char *name)
 {
     struct romfile_loader_entry_s *entry;
@@ -161,6 +194,11 @@ int romfile_loader_execute(const char *name)
                         break;
                 case ROMFILE_LOADER_COMMAND_ADD_CHECKSUM:
                         romfile_loader_add_checksum(entry, files);
+                        break;
+                case ROMFILE_LOADER_COMMAND_ALLOCATE_RET_ADDR:
+                        romfile_loader_allocate(entry, files);
+                        romfile_loader_return_addr(entry, files);
+                        break;
                 default:
                         /* Skip commands that we don't recognize. */
                         break;
diff --git a/src/fw/romfile_loader.h b/src/fw/romfile_loader.h
index 15eab2a..44a6cb8 100644
--- a/src/fw/romfile_loader.h
+++ b/src/fw/romfile_loader.h
@@ -51,15 +51,32 @@ struct romfile_loader_entry_s {
             u32 cksum_length;
         };
 
+        /*
+         * COMMAND_ALLOCATE_RETURN_ADDR - allocate a table from @alloc_file
+         * subject to @alloc_ret_align alignment (must be power of 2)
+         * and @alloc_ret_zone (can be HIGH or FSEG) requirements.
+         * Additionally, return the address of the allocation in
+         * @addr_file.
+         *
+         * This may be used instead of COMMAND_ALLOCATE
+         */
+        struct {
+            char alloc_ret_file[ROMFILE_LOADER_FILESZ];
+            u32 alloc_ret_align;
+            u8 alloc_ret_zone;
+            char alloc_ret_addr_file[ROMFILE_LOADER_FILESZ];
+        };
+
         /* padding */
         char pad[124];
     };
 };
 
 enum {
-    ROMFILE_LOADER_COMMAND_ALLOCATE     = 0x1,
-    ROMFILE_LOADER_COMMAND_ADD_POINTER  = 0x2,
-    ROMFILE_LOADER_COMMAND_ADD_CHECKSUM = 0x3,
+    ROMFILE_LOADER_COMMAND_ALLOCATE          = 0x1,
+    ROMFILE_LOADER_COMMAND_ADD_POINTER       = 0x2,
+    ROMFILE_LOADER_COMMAND_ADD_CHECKSUM      = 0x3,
+    ROMFILE_LOADER_COMMAND_ALLOCATE_RET_ADDR = 0x4,
 };
 
 enum {
-- 
2.7.4




More information about the SeaBIOS mailing list