From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: pbonzini@redhat.com, afaerber@suse.de, kraxel@redhat.com
Subject: [Qemu-devel] [PATCH v6 16/26] i386: add bios linker/loader
Date: Sun, 29 Sep 2013 13:59:09 +0300 [thread overview]
Message-ID: <1380452123-5989-17-git-send-email-mst@redhat.com> (raw)
In-Reply-To: <1380452123-5989-1-git-send-email-mst@redhat.com>
This adds a dynamic bios linker/loader.
This will be used by acpi table generation
code to:
- load each table in the appropriate memory segment
- link tables to each other
- fix up checksums after said linking
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/i386/bios-linker-loader.h | 27 ++++++++
hw/i386/bios-linker-loader.c | 158 +++++++++++++++++++++++++++++++++++++++++++
hw/i386/Makefile.objs | 1 +
3 files changed, 186 insertions(+)
create mode 100644 hw/i386/bios-linker-loader.h
create mode 100644 hw/i386/bios-linker-loader.c
diff --git a/hw/i386/bios-linker-loader.h b/hw/i386/bios-linker-loader.h
new file mode 100644
index 0000000..498c0af
--- /dev/null
+++ b/hw/i386/bios-linker-loader.h
@@ -0,0 +1,27 @@
+#ifndef BIOS_LINKER_LOADER_H
+#define BIOS_LINKER_LOADER_H
+
+#include <glib.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+GArray *bios_linker_loader_init(void);
+
+void bios_linker_loader_alloc(GArray *linker,
+ const char *file,
+ uint32_t alloc_align,
+ bool alloc_fseg);
+
+void bios_linker_loader_add_checksum(GArray *linker, const char *file,
+ void *table,
+ void *start, unsigned size,
+ uint8_t *checksum);
+
+void bios_linker_loader_add_pointer(GArray *linker,
+ const char *dest_file,
+ const char *src_file,
+ GArray *table, void *pointer,
+ uint8_t pointer_size);
+
+void *bios_linker_loader_cleanup(GArray *linker);
+#endif
diff --git a/hw/i386/bios-linker-loader.c b/hw/i386/bios-linker-loader.c
new file mode 100644
index 0000000..0833853
--- /dev/null
+++ b/hw/i386/bios-linker-loader.c
@@ -0,0 +1,158 @@
+/* Dynamic linker/loader of ACPI tables
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bios-linker-loader.h"
+#include "hw/nvram/fw_cfg.h"
+
+#include <string.h>
+#include <assert.h>
+#include "qemu/bswap.h"
+
+#define BIOS_LINKER_LOADER_FILESZ FW_CFG_MAX_FILE_PATH
+
+struct BiosLinkerLoaderEntry {
+ uint32_t command;
+ union {
+ /*
+ * COMMAND_ALLOCATE - allocate a table from @alloc.file
+ * subject to @alloc.align alignment (must be power of 2)
+ * and @alloc.zone (can be HIGH or FSEG) requirements.
+ *
+ * Must appear exactly once for each file, and before
+ * this file is referenced by any other command.
+ */
+ struct {
+ char file[BIOS_LINKER_LOADER_FILESZ];
+ uint32_t align;
+ uint8_t zone;
+ } alloc;
+
+ /*
+ * COMMAND_ADD_POINTER - patch the table (originating from
+ * @dest_file) at @pointer.offset, by adding a pointer to the table
+ * originating from @src_file. 1,2,4 or 8 byte unsigned
+ * addition is used depending on @pointer.size.
+ */
+ struct {
+ char dest_file[BIOS_LINKER_LOADER_FILESZ];
+ char src_file[BIOS_LINKER_LOADER_FILESZ];
+ uint32_t offset;
+ uint8_t size;
+ } pointer;
+
+ /*
+ * COMMAND_ADD_CHECKSUM - calculate checksum of the range specified by
+ * @cksum_start and @cksum_length fields,
+ * and then add the value at @cksum.offset.
+ * Checksum simply sums -X for each byte X in the range
+ * using 8-bit math.
+ */
+ struct {
+ char file[BIOS_LINKER_LOADER_FILESZ];
+ uint32_t offset;
+ uint32_t start;
+ uint32_t length;
+ } cksum;
+
+ /* padding */
+ char pad[124];
+ };
+} QEMU_PACKED;
+typedef struct BiosLinkerLoaderEntry BiosLinkerLoaderEntry;
+
+enum {
+ BIOS_LINKER_LOADER_COMMAND_ALLOCATE = 0x1,
+ BIOS_LINKER_LOADER_COMMAND_ADD_POINTER = 0x2,
+ BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3,
+};
+
+enum {
+ BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH = 0x1,
+ BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG = 0x2,
+};
+
+GArray *bios_linker_loader_init(void)
+{
+ return g_array_new(false, true /* clear */, sizeof(BiosLinkerLoaderEntry));
+}
+
+/* Free linker wrapper and return the linker array. */
+void *bios_linker_loader_cleanup(GArray *linker)
+{
+ return g_array_free(linker, false);
+}
+
+void bios_linker_loader_alloc(GArray *linker,
+ const char *file,
+ uint32_t alloc_align,
+ bool alloc_fseg)
+{
+ BiosLinkerLoaderEntry entry;
+
+ memset(&entry, 0, sizeof entry);
+ strncpy(entry.alloc.file, file, sizeof entry.alloc.file - 1);
+ entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ALLOCATE);
+ entry.alloc.align = cpu_to_le32(alloc_align);
+ entry.alloc.zone = cpu_to_le32(alloc_fseg ?
+ BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG :
+ BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH);
+
+ /* Alloc entries must come first, so prepend them */
+ g_array_prepend_val(linker, entry);
+}
+
+void bios_linker_loader_add_checksum(GArray *linker, const char *file,
+ void *table,
+ void *start, unsigned size,
+ uint8_t *checksum)
+{
+ BiosLinkerLoaderEntry entry;
+
+ memset(&entry, 0, sizeof entry);
+ strncpy(entry.cksum.file, file, sizeof entry.cksum.file - 1);
+ entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM);
+ entry.cksum.offset = cpu_to_le32(checksum - (uint8_t *)table);
+ entry.cksum.start = cpu_to_le32((uint8_t *)start - (uint8_t *)table);
+ entry.cksum.length = cpu_to_le32(size);
+
+ g_array_append_val(linker, entry);
+}
+
+void bios_linker_loader_add_pointer(GArray *linker,
+ const char *dest_file,
+ const char *src_file,
+ GArray *table, void *pointer,
+ uint8_t pointer_size)
+{
+ BiosLinkerLoaderEntry entry;
+
+ memset(&entry, 0, sizeof entry);
+ strncpy(entry.pointer.dest_file, dest_file,
+ sizeof entry.pointer.dest_file - 1);
+ strncpy(entry.pointer.src_file, src_file,
+ sizeof entry.pointer.src_file - 1);
+ entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_POINTER);
+ entry.pointer.offset = cpu_to_le32((gchar *)pointer - table->data);
+ entry.pointer.size = pointer_size;
+ assert(pointer_size == 1 || pointer_size == 2 ||
+ pointer_size == 4 || pointer_size == 8);
+
+ g_array_append_val(linker, entry);
+}
diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index f950707..b9ca380 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -5,6 +5,7 @@ obj-y += pc_sysfw.o
obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o
obj-y += kvmvapic.o
+obj-y += bios-linker-loader.o
iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
; then echo "$(2)"; else echo "$(3)"; fi ;)
--
MST
next prev parent reply other threads:[~2013-09-29 10:57 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-29 10:58 [Qemu-devel] [PATCH v6 00/26] qemu: generate acpi tables for the guest Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 01/26] qemu: add Error to typedefs Michael S. Tsirkin
2013-09-30 13:10 ` Igor Mammedov
2013-09-30 14:40 ` Michael S. Tsirkin
2013-09-30 15:00 ` Igor Mammedov
2013-09-30 15:10 ` Peter Maydell
2013-09-30 15:49 ` Markus Armbruster
2013-09-30 16:09 ` Michael S. Tsirkin
2013-09-30 17:38 ` Markus Armbruster
2013-09-30 15:50 ` Michael S. Tsirkin
2013-09-30 15:55 ` Andreas Färber
2013-09-30 16:09 ` Michael S. Tsirkin
2013-10-01 13:46 ` Igor Mammedov
2013-10-01 14:15 ` Michael S. Tsirkin
2013-10-01 15:44 ` [Qemu-devel] [PATCH] cleanup object.h: include error.h directly Igor Mammedov
2013-09-30 16:16 ` [Qemu-devel] [PATCH v6 01/26] qemu: add Error to typedefs Markus Armbruster
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 02/26] qom: pull in qemu/typedefs Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 03/26] qom: cleanup struct Error references Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 04/26] qom: add pointer to int property helpers Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 05/26] fw_cfg: interface to trigger callback on read Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 06/26] loader: support for unmapped ROM blobs Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 07/26] pcie_host: expose UNMAPPED macro Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 08/26] pcie_host: expose address format Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 09/26] q35: use macro for MCFG property name Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 10/26] q35: expose mmcfg size as a property Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 11/26] i386: add ACPI table files from seabios Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 12/26] acpi: add rules to compile ASL source Michael S. Tsirkin
2013-09-29 10:58 ` [Qemu-devel] [PATCH v6 13/26] acpi: pre-compiled ASL files Michael S. Tsirkin
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 14/26] acpi: ssdt pcihp: updat generated file Michael S. Tsirkin
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 15/26] loader: use file path size from fw_cfg.h Michael S. Tsirkin
2013-09-29 10:59 ` Michael S. Tsirkin [this message]
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 17/26] loader: allow adding ROMs in done callbacks Michael S. Tsirkin
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 18/26] i386: define pc guest info Michael S. Tsirkin
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 19/26] acpi/piix: add macros for acpi property names Michael S. Tsirkin
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 20/26] piix: APIs for pc guest info Michael S. Tsirkin
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 21/26] ich9: " Michael S. Tsirkin
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 22/26] pvpanic: add API to access io port Michael S. Tsirkin
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 23/26] hpet: add API to find it Michael S. Tsirkin
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 24/26] i386: ACPI table generation code from seabios Michael S. Tsirkin
2013-09-29 10:59 ` [Qemu-devel] [PATCH v6 25/26] ssdt: fix PBLK length Michael S. Tsirkin
2013-09-29 11:01 ` [Qemu-devel] [PATCH v6 26/26] ssdt-proc: update generated file Michael S. Tsirkin
2013-09-30 7:51 ` [Qemu-devel] [PATCH v6 00/26] qemu: generate acpi tables for the guest Gerd Hoffmann
2013-10-01 10:03 ` Igor Mammedov
2013-10-01 12:16 ` Michael S. Tsirkin
2013-10-01 12:38 ` Michael S. Tsirkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1380452123-5989-17-git-send-email-mst@redhat.com \
--to=mst@redhat.com \
--cc=afaerber@suse.de \
--cc=kraxel@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.