aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.d/edk2.yml27
-rw-r--r--MAINTAINERS4
-rw-r--r--hw/i386/Kconfig4
-rw-r--r--hw/i386/meson.build2
-rw-r--r--hw/i386/pc_sysfw.c107
-rw-r--r--hw/i386/pc_sysfw_ovmf-stubs.c26
-rw-r--r--hw/i386/pc_sysfw_ovmf.c151
-rw-r--r--include/hw/i386/pc.h1
8 files changed, 201 insertions, 121 deletions
diff --git a/.gitlab-ci.d/edk2.yml b/.gitlab-ci.d/edk2.yml
index ba7280605c..aae2f7ad88 100644
--- a/.gitlab-ci.d/edk2.yml
+++ b/.gitlab-ci.d/edk2.yml
@@ -1,10 +1,22 @@
-docker-edk2:
- stage: containers
- rules: # Only run this job when the Dockerfile is modified
+# All jobs needing docker-edk2 must use the same rules it uses.
+.edk2_job_rules:
+ rules: # Only run this job when ...
- changes:
+ # this file is modified
- .gitlab-ci.d/edk2.yml
+ # or the Dockerfile is modified
- .gitlab-ci.d/edk2/Dockerfile
+ # or roms/edk2/ is modified (submodule updated)
+ - roms/edk2/*
when: always
+ - if: '$CI_COMMIT_REF_NAME =~ /^edk2/' # or the branch/tag starts with 'edk2'
+ when: always
+ - if: '$CI_COMMIT_MESSAGE =~ /edk2/i' # or last commit description contains 'EDK2'
+ when: always
+
+docker-edk2:
+ extends: .edk2_job_rules
+ stage: containers
image: docker:19.03.1
services:
- docker:19.03.1-dind
@@ -24,16 +36,9 @@ docker-edk2:
- docker push $IMAGE_TAG
build-edk2:
+ extends: .edk2_job_rules
stage: build
needs: ['docker-edk2']
- rules: # Only run this job when ...
- - changes: # ... roms/edk2/ is modified (submodule updated)
- - roms/edk2/*
- when: always
- - if: '$CI_COMMIT_REF_NAME =~ /^edk2/' # or the branch/tag starts with 'edk2'
- when: always
- - if: '$CI_COMMIT_MESSAGE =~ /edk2/i' # or last commit description contains 'EDK2'
- when: always
artifacts:
paths: # 'artifacts.zip' will contains the following files:
- pc-bios/edk2*bz2
diff --git a/MAINTAINERS b/MAINTAINERS
index 148153d74f..4181ee75ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2202,7 +2202,6 @@ F: include/hw/southbridge/piix.h
Firmware configuration (fw_cfg)
M: Philippe Mathieu-Daudé <philmd@redhat.com>
-R: Laszlo Ersek <lersek@redhat.com>
R: Gerd Hoffmann <kraxel@redhat.com>
S: Supported
F: docs/specs/fw_cfg.txt
@@ -2934,7 +2933,6 @@ F: include/hw/i2c/smbus_slave.h
F: include/hw/i2c/smbus_eeprom.h
Firmware schema specifications
-M: Laszlo Ersek <lersek@redhat.com>
M: Philippe Mathieu-Daudé <philmd@redhat.com>
R: Daniel P. Berrange <berrange@redhat.com>
R: Kashyap Chamarthy <kchamart@redhat.com>
@@ -2942,9 +2940,9 @@ S: Maintained
F: docs/interop/firmware.json
EDK2 Firmware
-M: Laszlo Ersek <lersek@redhat.com>
M: Philippe Mathieu-Daudé <philmd@redhat.com>
S: Supported
+F: hw/i386/*ovmf*
F: pc-bios/descriptors/??-edk2-*.json
F: pc-bios/edk2-*
F: roms/Makefile.edk2
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index aacb6f6d96..bad6cf5b4e 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -1,5 +1,9 @@
+config X86_FW_OVMF
+ bool
+
config SEV
bool
+ select X86_FW_OVMF
depends on KVM
config PC
diff --git a/hw/i386/meson.build b/hw/i386/meson.build
index e5d109f5c6..80dad29f2b 100644
--- a/hw/i386/meson.build
+++ b/hw/i386/meson.build
@@ -24,6 +24,8 @@ i386_ss.add(when: 'CONFIG_PC', if_true: files(
'pc_sysfw.c',
'acpi-build.c',
'port92.c'))
+i386_ss.add(when: 'CONFIG_X86_FW_OVMF', if_true: files('pc_sysfw_ovmf.c'),
+ if_false: files('pc_sysfw_ovmf-stubs.c'))
subdir('kvm')
subdir('xen')
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 6ce37a2b05..68d6b1f783 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -124,113 +124,6 @@ void pc_system_flash_cleanup_unused(PCMachineState *pcms)
}
}
-#define OVMF_TABLE_FOOTER_GUID "96b582de-1fb2-45f7-baea-a366c55a082d"
-
-static uint8_t *ovmf_table;
-static int ovmf_table_len;
-
-static void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size)
-{
- uint8_t *ptr;
- QemuUUID guid;
- int tot_len;
-
- /* should only be called once */
- if (ovmf_table) {
- return;
- }
-
- if (flash_size < TARGET_PAGE_SIZE) {
- return;
- }
-
- /*
- * if this is OVMF there will be a table footer
- * guid 48 bytes before the end of the flash file. If it's
- * not found, silently abort the flash parsing.
- */
- qemu_uuid_parse(OVMF_TABLE_FOOTER_GUID, &guid);
- guid = qemu_uuid_bswap(guid); /* guids are LE */
- ptr = flash_ptr + flash_size - 48;
- if (!qemu_uuid_is_equal((QemuUUID *)ptr, &guid)) {
- return;
- }
-
- /* if found, just before is two byte table length */
- ptr -= sizeof(uint16_t);
- tot_len = le16_to_cpu(*(uint16_t *)ptr) - sizeof(guid) - sizeof(uint16_t);
-
- if (tot_len <= 0) {
- return;
- }
-
- ovmf_table = g_malloc(tot_len);
- ovmf_table_len = tot_len;
-
- /*
- * ptr is the foot of the table, so copy it all to the newly
- * allocated ovmf_table and then set the ovmf_table pointer
- * to the table foot
- */
- memcpy(ovmf_table, ptr - tot_len, tot_len);
- ovmf_table += tot_len;
-}
-
-bool pc_system_ovmf_table_find(const char *entry, uint8_t **data,
- int *data_len)
-{
- uint8_t *ptr = ovmf_table;
- int tot_len = ovmf_table_len;
- QemuUUID entry_guid;
-
- if (qemu_uuid_parse(entry, &entry_guid) < 0) {
- return false;
- }
-
- if (!ptr) {
- return false;
- }
-
- entry_guid = qemu_uuid_bswap(entry_guid); /* guids are LE */
- while (tot_len >= sizeof(QemuUUID) + sizeof(uint16_t)) {
- int len;
- QemuUUID *guid;
-
- /*
- * The data structure is
- * arbitrary length data
- * 2 byte length of entire entry
- * 16 byte guid
- */
- guid = (QemuUUID *)(ptr - sizeof(QemuUUID));
- len = le16_to_cpu(*(uint16_t *)(ptr - sizeof(QemuUUID) -
- sizeof(uint16_t)));
-
- /*
- * just in case the table is corrupt, wouldn't want to spin in
- * the zero case
- */
- if (len < sizeof(QemuUUID) + sizeof(uint16_t)) {
- return false;
- } else if (len > tot_len) {
- return false;
- }
-
- ptr -= len;
- tot_len -= len;
- if (qemu_uuid_is_equal(guid, &entry_guid)) {
- if (data) {
- *data = ptr;
- }
- if (data_len) {
- *data_len = len - sizeof(QemuUUID) - sizeof(uint16_t);
- }
- return true;
- }
- }
- return false;
-}
-
/*
* Map the pcms->flash[] from 4GiB downward, and realize.
* Map them in descending order, i.e. pcms->flash[0] at the top,
diff --git a/hw/i386/pc_sysfw_ovmf-stubs.c b/hw/i386/pc_sysfw_ovmf-stubs.c
new file mode 100644
index 0000000000..aabe78b271
--- /dev/null
+++ b/hw/i386/pc_sysfw_ovmf-stubs.c
@@ -0,0 +1,26 @@
+/*
+ * QEMU PC System Firmware (OVMF stubs)
+ *
+ * Copyright (c) 2021 Red Hat, Inc.
+ *
+ * Author:
+ * Philippe Mathieu-Daudé <philmd@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/i386/pc.h"
+
+bool pc_system_ovmf_table_find(const char *entry, uint8_t **data, int *data_len)
+{
+ g_assert_not_reached();
+}
+
+void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size)
+{
+ g_assert_not_reached();
+}
diff --git a/hw/i386/pc_sysfw_ovmf.c b/hw/i386/pc_sysfw_ovmf.c
new file mode 100644
index 0000000000..f4dd92c588
--- /dev/null
+++ b/hw/i386/pc_sysfw_ovmf.c
@@ -0,0 +1,151 @@
+/*
+ * QEMU PC System Firmware (OVMF specific)
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2011-2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/i386/pc.h"
+#include "cpu.h"
+
+#define OVMF_TABLE_FOOTER_GUID "96b582de-1fb2-45f7-baea-a366c55a082d"
+
+static bool ovmf_flash_parsed;
+static uint8_t *ovmf_table;
+static int ovmf_table_len;
+
+void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size)
+{
+ uint8_t *ptr;
+ QemuUUID guid;
+ int tot_len;
+
+ /* should only be called once */
+ if (ovmf_flash_parsed) {
+ return;
+ }
+
+ ovmf_flash_parsed = true;
+
+ if (flash_size < TARGET_PAGE_SIZE) {
+ return;
+ }
+
+ /*
+ * if this is OVMF there will be a table footer
+ * guid 48 bytes before the end of the flash file. If it's
+ * not found, silently abort the flash parsing.
+ */
+ qemu_uuid_parse(OVMF_TABLE_FOOTER_GUID, &guid);
+ guid = qemu_uuid_bswap(guid); /* guids are LE */
+ ptr = flash_ptr + flash_size - 48;
+ if (!qemu_uuid_is_equal((QemuUUID *)ptr, &guid)) {
+ return;
+ }
+
+ /* if found, just before is two byte table length */
+ ptr -= sizeof(uint16_t);
+ tot_len = le16_to_cpu(*(uint16_t *)ptr) - sizeof(guid) - sizeof(uint16_t);
+
+ if (tot_len <= 0) {
+ return;
+ }
+
+ ovmf_table = g_malloc(tot_len);
+ ovmf_table_len = tot_len;
+
+ /*
+ * ptr is the foot of the table, so copy it all to the newly
+ * allocated ovmf_table and then set the ovmf_table pointer
+ * to the table foot
+ */
+ memcpy(ovmf_table, ptr - tot_len, tot_len);
+ ovmf_table += tot_len;
+}
+
+/**
+ * pc_system_ovmf_table_find - Find the data associated with an entry in OVMF's
+ * reset vector GUIDed table.
+ *
+ * @entry: GUID string of the entry to lookup
+ * @data: Filled with a pointer to the entry's value (if not NULL)
+ * @data_len: Filled with the length of the entry's value (if not NULL). Pass
+ * NULL here if the length of data is known.
+ *
+ * Return: true if the entry was found in the OVMF table; false otherwise.
+ */
+bool pc_system_ovmf_table_find(const char *entry, uint8_t **data,
+ int *data_len)
+{
+ uint8_t *ptr = ovmf_table;
+ int tot_len = ovmf_table_len;
+ QemuUUID entry_guid;
+
+ assert(ovmf_flash_parsed);
+
+ if (qemu_uuid_parse(entry, &entry_guid) < 0) {
+ return false;
+ }
+
+ if (!ptr) {
+ return false;
+ }
+
+ entry_guid = qemu_uuid_bswap(entry_guid); /* guids are LE */
+ while (tot_len >= sizeof(QemuUUID) + sizeof(uint16_t)) {
+ int len;
+ QemuUUID *guid;
+
+ /*
+ * The data structure is
+ * arbitrary length data
+ * 2 byte length of entire entry
+ * 16 byte guid
+ */
+ guid = (QemuUUID *)(ptr - sizeof(QemuUUID));
+ len = le16_to_cpu(*(uint16_t *)(ptr - sizeof(QemuUUID) -
+ sizeof(uint16_t)));
+
+ /*
+ * just in case the table is corrupt, wouldn't want to spin in
+ * the zero case
+ */
+ if (len < sizeof(QemuUUID) + sizeof(uint16_t)) {
+ return false;
+ } else if (len > tot_len) {
+ return false;
+ }
+
+ ptr -= len;
+ tot_len -= len;
+ if (qemu_uuid_is_equal(guid, &entry_guid)) {
+ if (data) {
+ *data = ptr;
+ }
+ if (data_len) {
+ *data_len = len - sizeof(QemuUUID) - sizeof(uint16_t);
+ }
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 87294f2632..0775f945d7 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -188,6 +188,7 @@ void pc_system_flash_cleanup_unused(PCMachineState *pcms);
void pc_system_firmware_init(PCMachineState *pcms, MemoryRegion *rom_memory);
bool pc_system_ovmf_table_find(const char *entry, uint8_t **data,
int *data_len);
+void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size);
/* acpi-build.c */