[SeaBIOS] [PATCH v5 5/5] QEMU fw_cfg: Write fw_cfg back on S3 resume
ben at skyportsystems.com
ben at skyportsystems.com
Sat Feb 18 07:21:59 CET 2017
From: Ben Warren <ben at skyportsystems.com>
Any pointers to BIOS-allocated memory that were written back to QEMU
fw_cfg files are replayed when resuming from S3 sleep.
Signed-off-by: Ben Warren <ben at skyportsystems.com>
---
src/fw/romfile_loader.c | 35 +++++++++++++++++++++++++++++++++++
src/fw/romfile_loader.h | 2 ++
src/resume.c | 4 ++++
3 files changed, 41 insertions(+)
diff --git a/src/fw/romfile_loader.c b/src/fw/romfile_loader.c
index 30e7b58..33aaec4 100644
--- a/src/fw/romfile_loader.c
+++ b/src/fw/romfile_loader.c
@@ -4,6 +4,7 @@
#include "string.h" // strcmp
#include "romfile.h" // struct romfile_s
#include "malloc.h" // Zone*, _malloc
+#include "list.h" // struct hlist_node
#include "output.h" // warn_*
#include "paravirt.h" // qemu_cfg_write_file
@@ -16,6 +17,16 @@ struct romfile_loader_files {
struct romfile_loader_file files[];
};
+// Data structures for storing "write pointer" entries for possible replay
+struct romfile_wr_pointer_entry {
+ u64 pointer;
+ u32 offset;
+ u16 key;
+ u8 ptr_size;
+ struct hlist_node node;
+};
+static struct hlist_head romfile_pointer_list;
+
static struct romfile_loader_file *
romfile_loader_find(const char *name,
struct romfile_loader_files *files)
@@ -29,6 +40,16 @@ romfile_loader_find(const char *name,
return NULL;
}
+// Replay "write pointer" entries back to QEMU
+void romfile_fw_cfg_resume(void)
+{
+ struct romfile_wr_pointer_entry *entry;
+ hlist_for_each_entry(entry, &romfile_pointer_list, node) {
+ qemu_cfg_write_file_simple(&entry->pointer, entry->key,
+ entry->offset, entry->ptr_size);
+ }
+}
+
static void romfile_loader_allocate(struct romfile_loader_entry_s *entry,
struct romfile_loader_files *files)
{
@@ -163,6 +184,20 @@ static void romfile_loader_write_pointer(struct romfile_loader_entry_s *entry,
entry->wr_pointer.size) != entry->wr_pointer.size) {
goto err;
}
+
+ /* Store the info so it can replayed later if necessary */
+ struct romfile_wr_pointer_entry *store = _malloc(&ZoneHigh,
+ sizeof(*store), 4);
+ struct hlist_node **pprev = &romfile_pointer_list.first;
+ store->pointer = pointer;
+ store->key = qemu_get_romfile_key(dest_file);
+ if (store->key == 0) {
+ goto err;
+ }
+ store->offset = dst_offset;
+ store->ptr_size = entry->wr_pointer.size;
+ hlist_add(&store->node, pprev);
+
return;
err:
warn_internalerror();
diff --git a/src/fw/romfile_loader.h b/src/fw/romfile_loader.h
index 4dc50ab..fcd4ab2 100644
--- a/src/fw/romfile_loader.h
+++ b/src/fw/romfile_loader.h
@@ -86,4 +86,6 @@ enum {
int romfile_loader_execute(const char *name);
+void romfile_fw_cfg_resume(void);
+
#endif
diff --git a/src/resume.c b/src/resume.c
index e67cfce..99fa34f 100644
--- a/src/resume.c
+++ b/src/resume.c
@@ -17,6 +17,7 @@
#include "string.h" // memset
#include "util.h" // dma_setup
#include "tcgbios.h" // tpm_s3_resume
+#include "fw/romfile_loader.h" // romfile_fw_cfg_resume
// Handler for post calls that look like a resume.
void VISIBLE16
@@ -105,6 +106,9 @@ s3_resume(void)
tpm_s3_resume();
s3_resume_vga();
+ /* Replay any fw_cfg entries that go back to the host */
+ romfile_fw_cfg_resume();
+
make_bios_readonly();
// Invoke the resume vector.
--
2.7.4
More information about the SeaBIOS
mailing list