diff --git a/.gitignore b/.gitignore index 59a760f..2114b13 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/seabios-1.7.2.2.tar.gz +SOURCES/seabios-1.7.5.tar.gz diff --git a/.seabios.metadata b/.seabios.metadata index 0166abd..d1c44ef 100644 --- a/.seabios.metadata +++ b/.seabios.metadata @@ -1 +1 @@ -4d50b512c589fc7786d398fbc6e3935d4fa66530 SOURCES/seabios-1.7.2.2.tar.gz +456e418482044b19fe397075ca093ebcae0200c5 SOURCES/seabios-1.7.5.tar.gz diff --git a/SOURCES/Add-pvpanic-device-driver.patch b/SOURCES/Add-pvpanic-device-driver.patch deleted file mode 100644 index 85b58a2..0000000 --- a/SOURCES/Add-pvpanic-device-driver.patch +++ /dev/null @@ -1,111 +0,0 @@ -Add pvpanic device driver - -Message-id: <1370958628-888-1-git-send-email-lersek@redhat.com> -Patchwork-id: 51850 -O-Subject: [RHEL7 seabios PATCH] Add pvpanic device driver -Bugzilla: 967777 -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Gerd Hoffmann - -From: Hu Tao - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=967777 -Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=5890930 -Testing: https://bugzilla.redhat.com/show_bug.cgi?id=967777#c3 - -pvpanic device is used to notify host(qemu) when guest panic happens. - -Signed-off-by: Paolo Bonzini -Signed-off-by: Hu Tao -(cherry picked from commit e9725dd76d5d7212cb4a97fd18ff2599538955cf) - -Conflicts: - - src/acpi.c - -RHEL-7 note: - -Gerd already ported this patch to 1.7.2 (which is where RHEL-7 is at -currently). See -and for details. - -I cherry picked his port from , commit -5d01ca924a5c8fcd898ddc5813d88b3c32043882. Unfortunately this seems to -introduce a compile error. I fixed that up. - -Signed-off-by: Laszlo Ersek ---- - src/acpi.c | 4 ++++ - src/ssdt-susp.dsl | 46 ++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 50 insertions(+), 0 deletions(-) -diff --git a/src/acpi.c b/src/acpi.c -index 6267d7b..9b09118 100644 ---- a/src/acpi.c -+++ b/src/acpi.c -@@ -535,6 +535,10 @@ build_ssdt(void) - ssdt_ptr[acpi_s4_name[0]] = 'X'; - else - ssdt_ptr[acpi_s4_pkg[0] + 1] = ssdt[acpi_s4_pkg[0] + 3] = sys_states[4] & 127; -+ -+ int pvpanic_port = romfile_loadint("etc/pvpanic-port", 0x0); -+ *(u16 *)(ssdt_ptr + *ssdt_isa_pest) = pvpanic_port; -+ - ssdt_ptr += sizeof(ssdp_susp_aml); - - // build Scope(_SB_) header -diff --git a/src/ssdt-susp.dsl b/src/ssdt-susp.dsl -index ca9428f..b8e9cf4 100644 ---- a/src/ssdt-susp.dsl -+++ b/src/ssdt-susp.dsl -@@ -35,4 +35,50 @@ DefinitionBlock ("ssdt-susp.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) - Zero /* reserved */ - }) - } -+ -+ External(\_SB.PCI0, DeviceObj) -+ External(\_SB.PCI0.ISA, DeviceObj) -+ -+ Scope(\_SB.PCI0.ISA) { -+ Device(PEVT) { -+ Name(_HID, "QEMU0001") -+ /* PEST will be patched to be Zero if no such device */ -+ ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest -+ Name(PEST, 0xFFFF) -+ OperationRegion(PEOR, SystemIO, PEST, 0x01) -+ Field(PEOR, ByteAcc, NoLock, Preserve) { -+ PEPT, 8, -+ } -+ -+ Method(_STA, 0, NotSerialized) { -+ Store(PEST, Local0) -+ If (LEqual(Local0, Zero)) { -+ Return (0x00) -+ } Else { -+ Return (0x0F) -+ } -+ } -+ -+ Method(RDPT, 0, NotSerialized) { -+ Store(PEPT, Local0) -+ Return (Local0) -+ } -+ -+ Method(WRPT, 1, NotSerialized) { -+ Store(Arg0, PEPT) -+ } -+ -+ Name(_CRS, ResourceTemplate() { -+ IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO) -+ }) -+ -+ CreateWordField(_CRS, IO._MIN, IOMN) -+ CreateWordField(_CRS, IO._MAX, IOMX) -+ -+ Method(_INI, 0, NotSerialized) { -+ Store(PEST, IOMN) -+ Store(PEST, IOMX) -+ } -+ } -+ } - } diff --git a/SOURCES/config.vga.cirrus b/SOURCES/config.vga.cirrus index c8fe582..d284a8b 100644 --- a/SOURCES/config.vga.cirrus +++ b/SOURCES/config.vga.cirrus @@ -1,3 +1,4 @@ CONFIG_BUILD_VGABIOS=y CONFIG_VGA_CIRRUS=y CONFIG_VGA_PCI=y +CONFIG_VGA_ALLOCATE_EXTRA_STACK=n diff --git a/SOURCES/config.vga.isavga b/SOURCES/config.vga.isavga index e55e294..2704ef2 100644 --- a/SOURCES/config.vga.isavga +++ b/SOURCES/config.vga.isavga @@ -1,3 +1,4 @@ CONFIG_BUILD_VGABIOS=y CONFIG_VGA_BOCHS=y CONFIG_VGA_PCI=n +CONFIG_VGA_ALLOCATE_EXTRA_STACK=n diff --git a/SOURCES/config.vga.qxl b/SOURCES/config.vga.qxl index d393f0c..23dde3d 100644 --- a/SOURCES/config.vga.qxl +++ b/SOURCES/config.vga.qxl @@ -4,3 +4,4 @@ CONFIG_VGA_PCI=y CONFIG_OVERRIDE_PCI_ID=y CONFIG_VGA_VID=0x1b36 CONFIG_VGA_DID=0x0100 +CONFIG_VGA_ALLOCATE_EXTRA_STACK=n diff --git a/SOURCES/config.vga.stdvga b/SOURCES/config.vga.stdvga index 7d063b7..fdc0ff9 100644 --- a/SOURCES/config.vga.stdvga +++ b/SOURCES/config.vga.stdvga @@ -1,3 +1,4 @@ CONFIG_BUILD_VGABIOS=y CONFIG_VGA_BOCHS=y CONFIG_VGA_PCI=y +CONFIG_VGA_ALLOCATE_EXTRA_STACK=n diff --git a/SOURCES/config.vga.vmware b/SOURCES/config.vga.vmware index eb10427..d2f7dd7 100644 --- a/SOURCES/config.vga.vmware +++ b/SOURCES/config.vga.vmware @@ -4,3 +4,4 @@ CONFIG_VGA_PCI=y CONFIG_OVERRIDE_PCI_ID=y CONFIG_VGA_VID=0x15ad CONFIG_VGA_DID=0x0405 +CONFIG_VGA_ALLOCATE_EXTRA_STACK=n diff --git a/SOURCES/seabios-Another-fix-for-hlist_for_each_entry_safe.patch b/SOURCES/seabios-Another-fix-for-hlist_for_each_entry_safe.patch deleted file mode 100644 index 9735c36..0000000 --- a/SOURCES/seabios-Another-fix-for-hlist_for_each_entry_safe.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 71db0de897afe747d396134334e87a806be0beff Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 2 Oct 2013 07:00:15 +0200 -Subject: [PATCH 3/8] Another fix for hlist_for_each_entry_safe. - -RH-Author: Gerd Hoffmann -Message-id: <1380697219-1860-4-git-send-email-kraxel@redhat.com> -Patchwork-id: 54627 -O-Subject: [RHEL-7 seabios PATCH 3/7] Another fix for hlist_for_each_entry_safe. -Bugzilla: 947051 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Bandan Das -RH-Acked-by: Miroslav Rezanina - -From: Kevin O'Connor - -Although the previous patch does fix hlist_for_each_entry_safe for the -common case, it doesn't work correctly when deleting the current -node. To fix this, introduce two macros - hlist_for_each_entry_safe -for iterating through a list that can be modified, and -hlist_for_each_entry_pprev for those users that only need access to -the "pprev" pointer. - -Signed-off-by: Kevin O'Connor -(cherry picked from commit 030a58a05e595694dccfa958563103d2f0644231) - -[ rhel-6: pick list.h changes only ] - -Conflicts: - src/boot.c - src/pciinit.c - src/pmm.c ---- - src/list.h | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -Signed-off-by: Miroslav Rezanina ---- - src/list.h | 8 +++++++- - 1 files changed, 7 insertions(+), 1 deletions(-) - -diff --git a/src/list.h b/src/list.h -index 0f0909b..de656b9 100644 ---- a/src/list.h -+++ b/src/list.h -@@ -66,7 +66,13 @@ hlist_add_after(struct hlist_node *n, struct hlist_node *prev) - ; pos != container_of(NULL, typeof(*pos), member) \ - ; pos = container_of(pos->member.next, typeof(*pos), member)) - --#define hlist_for_each_entry_safe(pos, pprev, head, member) \ -+#define hlist_for_each_entry_safe(pos, n, head, member) \ -+ for (pos = container_of((head)->first, typeof(*pos), member) \ -+ ; pos != container_of(NULL, typeof(*pos), member) \ -+ && ({ n = pos->member.next; 1; }) \ -+ ; pos = container_of(n, typeof(*pos), member)) -+ -+#define hlist_for_each_entry_pprev(pos, pprev, head, member) \ - for (pprev = &(head)->first \ - ; *pprev && ({ pos=container_of(*pprev, typeof(*pos), member); 1; }) \ - ; pprev = &(*pprev)->next) --- -1.7.1 - diff --git a/SOURCES/seabios-Fix-error-in-hlist_for_each_entry_safe-macro.patch b/SOURCES/seabios-Fix-error-in-hlist_for_each_entry_safe-macro.patch deleted file mode 100644 index 3860efb..0000000 --- a/SOURCES/seabios-Fix-error-in-hlist_for_each_entry_safe-macro.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 8cd6a54fc05d726cc84c6c5b3dc551d208d1ddc1 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 2 Oct 2013 07:00:14 +0200 -Subject: [PATCH 2/8] Fix error in hlist_for_each_entry_safe macro. - -RH-Author: Gerd Hoffmann -Message-id: <1380697219-1860-3-git-send-email-kraxel@redhat.com> -Patchwork-id: 54629 -O-Subject: [RHEL-7 seabios PATCH 2/7] Fix error in hlist_for_each_entry_safe macro. -Bugzilla: 947051 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Bandan Das -RH-Acked-by: Miroslav Rezanina - -From: Kevin O'Connor - -Fix broken macro - it did not work correctly at all. - -Signed-off-by: Kevin O'Connor -(cherry picked from commit 9539e41c4d8701c19434457288c38109da163ffc) ---- - src/list.h | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - src/list.h | 3 +-- - 1 files changed, 1 insertions(+), 2 deletions(-) - -diff --git a/src/list.h b/src/list.h -index db7e962..0f0909b 100644 ---- a/src/list.h -+++ b/src/list.h -@@ -68,8 +68,7 @@ hlist_add_after(struct hlist_node *n, struct hlist_node *prev) - - #define hlist_for_each_entry_safe(pos, pprev, head, member) \ - for (pprev = &(head)->first \ -- ; *pprev \ -- && ({ pos=container_of((*pprev)->next, typeof(*pos), member); 1; }) \ -+ ; *pprev && ({ pos=container_of(*pprev, typeof(*pos), member); 1; }) \ - ; pprev = &(*pprev)->next) - - --- -1.7.1 - diff --git a/SOURCES/seabios-Introduce-and-convert-pmm-code-to-use-standard-list-.patch b/SOURCES/seabios-Introduce-and-convert-pmm-code-to-use-standard-list-.patch deleted file mode 100644 index f8a8246..0000000 --- a/SOURCES/seabios-Introduce-and-convert-pmm-code-to-use-standard-list-.patch +++ /dev/null @@ -1,135 +0,0 @@ -From cd24f3be4bcb388fd6b4ed48fc9a076ef0e1cee9 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 2 Oct 2013 07:00:13 +0200 -Subject: [PATCH 1/8] Introduce and convert pmm code to use standard list helpers. - -RH-Author: Gerd Hoffmann -Message-id: <1380697219-1860-2-git-send-email-kraxel@redhat.com> -Patchwork-id: 54628 -O-Subject: [RHEL-7 seabios PATCH 1/7] Introduce and convert pmm code to use standard list helpers. -Bugzilla: 947051 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Bandan Das -RH-Acked-by: Miroslav Rezanina - -From: Kevin O'Connor - -Signed-off-by: Kevin O'Connor -(cherry picked from commit e097a75ef0de08ad6d8660c41efe10c1133f1865) - -[ rhel6: skip ppm.c changes ] - -Conflicts: - src/pmm.c ---- - src/list.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/types.h | 3 +++ - 2 files changed, 79 insertions(+) - create mode 100644 src/list.h - -Signed-off-by: Miroslav Rezanina ---- - src/list.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/types.h | 3 ++ - 2 files changed, 79 insertions(+), 0 deletions(-) - create mode 100644 src/list.h - -diff --git a/src/list.h b/src/list.h -new file mode 100644 -index 0000000..db7e962 ---- /dev/null -+++ b/src/list.h -@@ -0,0 +1,76 @@ -+#ifndef __LIST_H -+#define __LIST_H -+ -+#include "types.h" // container_of -+ -+ -+/**************************************************************** -+ * hlist - Double linked lists with a single pointer list head -+ ****************************************************************/ -+ -+struct hlist_node { -+ struct hlist_node *next, **pprev; -+}; -+ -+struct hlist_head { -+ struct hlist_node *first; -+}; -+ -+static inline int -+hlist_empty(const struct hlist_head *h) -+{ -+ return !h->first; -+} -+ -+static inline void -+hlist_del(struct hlist_node *n) -+{ -+ struct hlist_node *next = n->next; -+ struct hlist_node **pprev = n->pprev; -+ *pprev = next; -+ if (next) -+ next->pprev = pprev; -+} -+ -+static inline void -+hlist_add(struct hlist_node *n, struct hlist_node **pprev) -+{ -+ struct hlist_node *next = *pprev; -+ n->pprev = pprev; -+ n->next = next; -+ if (next) -+ next->pprev = &n->next; -+ *pprev = n; -+} -+ -+static inline void -+hlist_add_head(struct hlist_node *n, struct hlist_head *h) -+{ -+ hlist_add(n, &h->first); -+} -+ -+static inline void -+hlist_add_before(struct hlist_node *n, struct hlist_node *next) -+{ -+ hlist_add(n, next->pprev); -+} -+ -+static inline void -+hlist_add_after(struct hlist_node *n, struct hlist_node *prev) -+{ -+ hlist_add(n, &prev->next); -+} -+ -+#define hlist_for_each_entry(pos, head, member) \ -+ for (pos = container_of((head)->first, typeof(*pos), member) \ -+ ; pos != container_of(NULL, typeof(*pos), member) \ -+ ; pos = container_of(pos->member.next, typeof(*pos), member)) -+ -+#define hlist_for_each_entry_safe(pos, pprev, head, member) \ -+ for (pprev = &(head)->first \ -+ ; *pprev \ -+ && ({ pos=container_of((*pprev)->next, typeof(*pos), member); 1; }) \ -+ ; pprev = &(*pprev)->next) -+ -+ -+#endif // list.h -diff --git a/src/types.h b/src/types.h -index 24b078e..e5ab4bf 100644 ---- a/src/types.h -+++ b/src/types.h -@@ -121,6 +121,9 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; - #define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) -+#define container_of_or_null(ptr, type, member) ({ \ -+ const typeof( ((type *)0)->member ) *___mptr = (ptr); \ -+ ___mptr ? container_of(___mptr, type, member) : NULL; }) - - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) --- -1.7.1 - diff --git a/SOURCES/seabios-Place-rpm-version-info-into-version-banner.patch b/SOURCES/seabios-Place-rpm-version-info-into-version-banner.patch index 3eeb0bb..1e5f210 100644 --- a/SOURCES/seabios-Place-rpm-version-info-into-version-banner.patch +++ b/SOURCES/seabios-Place-rpm-version-info-into-version-banner.patch @@ -1,7 +1,7 @@ -From 25c134c1c2e5966ed9ba604fb73e4c828131146f Mon Sep 17 00:00:00 2001 +From af34ffb86a1b8717e542edca97d7d96e6bd90f08 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Thu, 22 Aug 2013 12:06:40 +0200 -Subject: [PATCH 4/5] Place rpm version info into version banner +Subject: Place rpm version info into version banner RH-Author: Miroslav Rezanina Message-id: <1377173200-17433-1-git-send-email-mrezanin@redhat.com> @@ -32,15 +32,17 @@ Signed-off-by: Miroslav Rezanina 2 files changed, 2 insertions(+), 4 deletions(-) Signed-off-by: Miroslav Rezanina + +Conflicts: + redhat/seabios.spec.template - We solved 1) in rebase commit --- - redhat/seabios.spec.template | 5 ++--- - tools/buildversion.sh | 1 - - 2 files changed, 2 insertions(+), 4 deletions(-) + scripts/buildversion.sh | 1 - + 1 file changed, 1 deletion(-) -diff --git a/tools/buildversion.sh b/tools/buildversion.sh -index c8c1725..395e6d6 100755 ---- a/tools/buildversion.sh -+++ b/tools/buildversion.sh +diff --git a/scripts/buildversion.sh b/scripts/buildversion.sh +index e5ce96c..338b7f0 100755 +--- a/scripts/buildversion.sh ++++ b/scripts/buildversion.sh @@ -11,7 +11,6 @@ elif [ -f .version ]; then else VERSION="?" @@ -50,5 +52,5 @@ index c8c1725..395e6d6 100755 # Build header file -- -1.7.1 +1.9.3 diff --git a/SOURCES/seabios-Workaround-for-a-win8.1-32-S4-resume-bug.patch b/SOURCES/seabios-Workaround-for-a-win8.1-32-S4-resume-bug.patch index 918e0c8..2d7deeb 100644 --- a/SOURCES/seabios-Workaround-for-a-win8.1-32-S4-resume-bug.patch +++ b/SOURCES/seabios-Workaround-for-a-win8.1-32-S4-resume-bug.patch @@ -1,7 +1,7 @@ -From 5ce33ae3fd67eb576918f0b1a0e3a5df5715c7a4 Mon Sep 17 00:00:00 2001 +From ce6fabfc8e1d11c70d83404c56464252c6eacac6 Mon Sep 17 00:00:00 2001 From: Radim Krcmar Date: Mon, 10 Mar 2014 15:14:27 +0100 -Subject: [PATCH] Workaround for a win8.1-32 S4 resume bug +Subject: [PATCH 1/2] Workaround for a win8.1-32 S4 resume bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -50,10 +50,10 @@ Signed-off-by: Miroslav Rezanina 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/src/clock.c b/src/clock.c -index 71b913e..e066ecf 100644 +index 9ab0ac0..456849e 100644 --- a/src/clock.c +++ b/src/clock.c -@@ -570,7 +570,13 @@ handle_08(void) +@@ -289,7 +289,13 @@ handle_08(void) struct bregs br; memset(&br, 0, sizeof(br)); br.flags = F_IF; @@ -66,7 +66,7 @@ index 71b913e..e066ecf 100644 + else + call16_int(0x1c, &br); - eoi_pic1(); + pic_eoi1(); } -- 1.7.1 diff --git a/SOURCES/seabios-acpi-load-and-link-tables-through-romfile-loader.patch b/SOURCES/seabios-acpi-load-and-link-tables-through-romfile-loader.patch deleted file mode 100644 index 4839a73..0000000 --- a/SOURCES/seabios-acpi-load-and-link-tables-through-romfile-loader.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 3abbb783be92edcc07a999d50eac4e7ff5b6c7ba Mon Sep 17 00:00:00 2001 -Message-Id: <3abbb783be92edcc07a999d50eac4e7ff5b6c7ba.1387280747.git.minovotn@redhat.com> -In-Reply-To: -References: -From: Michal Novotny -Date: Tue, 17 Dec 2013 12:45:03 +0100 -Subject: [PATCH 3/3] acpi: load and link tables through romfile loader - -Load files through romfile loader and use for acpi tables. -We need the RSDP pointer to hang the rest of the tables off it, -to detect that we simply scan all memory in FSEG. - -Add an option to disable this feature (useful for old QEMU versions). -This saves about 1Kbytes. - -enabled: -Total size: 134932 Fixed: 61571 Free: 127212 (used 51.5% of 256KiB rom) - -disabled: -Total size: 133836 Fixed: 61563 Free: 128308 (used 51.1% of 256KiB rom) - -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Gerd Hoffmann -(cherry-picked from commit 11948748495841bd54721b250d68c7b3cb0475ef) -Signed-off-by: Michal Novotny ---- - src/Kconfig | 11 +++++++++++ - src/acpi.c | 21 +++++++++++++++++++++ - 2 files changed, 32 insertions(+) - -diff --git a/src/Kconfig b/src/Kconfig -index 0b112ed..9fa848c 100644 ---- a/src/Kconfig -+++ b/src/Kconfig -@@ -365,6 +365,17 @@ menu "BIOS Tables" - default y - help - Support generation of ACPI tables. -+ config FW_ROMFILE_LOAD -+ bool "Load BIOS tables from ROM files" -+ depends on QEMU -+ default y -+ help -+ Support loading BIOS firmware tables from ROM files. -+ At the moment, only ACPI tables can be loaded in this way. -+ Required for QEMU 1.7 and newer. -+ This option can be disabled for QEMU 1.6 and older -+ to save some space in the ROM file. -+ If unsure, say Y. - endmenu - - source vgasrc/Kconfig -diff --git a/src/acpi.c b/src/acpi.c -index 6267d7b..c62fa3a 100644 ---- a/src/acpi.c -+++ b/src/acpi.c -@@ -14,6 +14,7 @@ - #include "ioport.h" // inl - #include "paravirt.h" // qemu_cfg_irq0_override - #include "dev-q35.h" // qemu_cfg_irq0_override -+#include "romfile_loader.h" // romfile_loader_execute - - /****************************************************/ - /* ACPI tables init */ -@@ -798,6 +799,26 @@ struct rsdp_descriptor *RsdpAddr; - void - acpi_bios_init(void) - { -+ if (CONFIG_FW_ROMFILE_LOAD) { -+ int loader_err; -+ -+ dprintf(3, "load ACPI tables\n"); -+ -+ loader_err = romfile_loader_execute("etc/table-loader"); -+ -+ RsdpAddr = find_acpi_rsdp(); -+ -+ if (RsdpAddr) -+ return; -+ -+ /* If present, loader should have installed an RSDP. -+ * Not installed? We might still be able to continue -+ * using the builtin RSDP. -+ */ -+ if (!loader_err) -+ warn_internalerror(); -+ } -+ - if (! CONFIG_ACPI) - return; - --- -1.7.11.7 - diff --git a/SOURCES/seabios-ahci-add-missing-check-for-allocation-failure.patch b/SOURCES/seabios-ahci-add-missing-check-for-allocation-failure.patch deleted file mode 100644 index c83356c..0000000 --- a/SOURCES/seabios-ahci-add-missing-check-for-allocation-failure.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 48c296e7b9851c07ef277d7d37a05e20da3ef76d Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 17 Sep 2013 09:42:30 +0200 -Subject: [PATCH 5/5] ahci: add missing check for allocation failure - -RH-Author: Gerd Hoffmann -Message-id: <1379410950-22494-2-git-send-email-kraxel@redhat.com> -Patchwork-id: 54411 -O-Subject: [RHEL-7 seabios PATCH 1/1] ahci: add missing check for allocation failure -Bugzilla: 1005747 -RH-Acked-by: Bandan Das -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Paolo Bonzini - -Triggerable by creating a virtual machine with -*lots* of ahci controllers and disks. - -Signed-off-by: Gerd Hoffmann -(cherry picked from commit ce12eaf2044d6aae08795403ecbb888d2b6527ff) ---- - src/ahci.c | 25 ++++++++++++++++--------- - 1 file changed, 16 insertions(+), 9 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - src/ahci.c | 25 ++++++++++++++++--------- - 1 files changed, 16 insertions(+), 9 deletions(-) - -diff --git a/src/ahci.c b/src/ahci.c -index 4a8eafb..056d894 100644 ---- a/src/ahci.c -+++ b/src/ahci.c -@@ -381,12 +381,26 @@ ahci_port_alloc(struct ahci_ctrl_s *ctrl, u32 pnr) - return port; - } - -+static void ahci_port_release(struct ahci_port_s *port) -+{ -+ ahci_port_reset(port->ctrl, port->pnr); -+ free(port->list); -+ free(port->fis); -+ free(port->cmd); -+ free(port); -+} -+ - static struct ahci_port_s* ahci_port_realloc(struct ahci_port_s *port) - { - struct ahci_port_s *tmp; - u32 cmd; - - tmp = malloc_fseg(sizeof(*port)); -+ if (!tmp) { -+ warn_noalloc(); -+ ahci_port_release(port); -+ return NULL; -+ } - *tmp = *port; - free(port); - port = tmp; -@@ -410,15 +424,6 @@ static struct ahci_port_s* ahci_port_realloc(struct ahci_port_s *port) - return port; - } - --static void ahci_port_release(struct ahci_port_s *port) --{ -- ahci_port_reset(port->ctrl, port->pnr); -- free(port->list); -- free(port->fis); -- free(port->cmd); -- free(port); --} -- - #define MAXMODEL 40 - - /* See ahci spec chapter 10.1 "Software Initialization of HBA" */ -@@ -554,6 +559,8 @@ ahci_port_detect(void *data) - ahci_port_release(port); - else { - port = ahci_port_realloc(port); -+ if (port == NULL) -+ return; - dprintf(1, "AHCI/%d: registering: \"%s\"\n", port->pnr, port->desc); - if (!port->atapi) { - // Register with bcv system. --- -1.7.1 - diff --git a/SOURCES/seabios-allow-1TB-of-RAM.patch b/SOURCES/seabios-allow-1TB-of-RAM.patch index 017b051..b069dc0 100644 --- a/SOURCES/seabios-allow-1TB-of-RAM.patch +++ b/SOURCES/seabios-allow-1TB-of-RAM.patch @@ -1,7 +1,7 @@ -From 90414ef38b1f32b5b844e1fc27d30bd6d229f5de Mon Sep 17 00:00:00 2001 +From f8461b3d0468a0ff2807ba1445513f3725ba350a Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Tue, 8 Oct 2013 17:07:23 +0200 -Subject: [PATCH 8/8] allow >1TB of RAM +Subject: allow >1TB of RAM RH-Author: Andrea Arcangeli Message-id: <1381252043-13480-2-git-send-email-aarcange@redhat.com> @@ -22,15 +22,33 @@ Signed-off-by: Andrea Arcangeli Signed-off-by: Miroslav Rezanina --- - src/cmos.h | 7 ++++--- - src/post.c | 7 ++++--- + src/fw/paravirt.c | 7 ++++--- + src/hw/rtc.h | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) -diff --git a/src/cmos.h b/src/cmos.h -index e4b6462..e810534 100644 ---- a/src/cmos.h -+++ b/src/cmos.h -@@ -36,9 +36,10 @@ +diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c +index db22ae8..34fd0ac 100644 +--- a/src/fw/paravirt.c ++++ b/src/fw/paravirt.c +@@ -334,9 +334,10 @@ qemu_cfg_e820(void) + } + + // Check for memory over 4Gig in cmos +- u64 high = ((rtc_read(CMOS_MEM_HIGHMEM_LOW) << 16) +- | ((u32)rtc_read(CMOS_MEM_HIGHMEM_MID) << 24) +- | ((u64)rtc_read(CMOS_MEM_HIGHMEM_HIGH) << 32)); ++ u64 high = ((rtc_read(CMOS_MEM_HIGHMEM_16) << 16) ++ | ((u32)rtc_read(CMOS_MEM_HIGHMEM_24) << 24) ++ | ((u64)rtc_read(CMOS_MEM_HIGHMEM_32) << 32) ++ | ((u64)rtc_read(CMOS_MEM_HIGHMEM_40) << 40)); + RamSizeOver4G = high; + add_e820(0x100000000ull, high, E820_RAM); + dprintf(1, "RamSizeOver4G: 0x%016llx [cmos]\n", RamSizeOver4G); +diff --git a/src/hw/rtc.h b/src/hw/rtc.h +index 252e73a..c4369f8 100644 +--- a/src/hw/rtc.h ++++ b/src/hw/rtc.h +@@ -41,9 +41,10 @@ #define CMOS_BIOS_BOOTFLAG1 0x38 #define CMOS_BIOS_DISKTRANSFLAG 0x39 #define CMOS_BIOS_BOOTFLAG2 0x3d @@ -43,25 +61,7 @@ index e4b6462..e810534 100644 +#define CMOS_MEM_HIGHMEM_40 0x5e #define CMOS_BIOS_SMP_COUNT 0x5f - // CMOS_FLOPPY_DRIVE_TYPE bitdefs -diff --git a/src/post.c b/src/post.c -index f3b56b8..737c16d 100644 ---- a/src/post.c -+++ b/src/post.c -@@ -122,9 +122,10 @@ ram_probe(void) - add_e820(0, rs, E820_RAM); - - // Check for memory over 4Gig -- u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16) -- | ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24) -- | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32)); -+ u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_16) << 16) -+ | ((u32)inb_cmos(CMOS_MEM_HIGHMEM_24) << 24) -+ | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_32) << 32) -+ | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_40) << 40)); - RamSizeOver4G = high; - add_e820(0x100000000ull, high, E820_RAM); - + // RTC register flags -- -1.7.1 +1.9.3 diff --git a/SOURCES/seabios-biostables-support-looking-up-RSDP.patch b/SOURCES/seabios-biostables-support-looking-up-RSDP.patch deleted file mode 100644 index bc65503..0000000 --- a/SOURCES/seabios-biostables-support-looking-up-RSDP.patch +++ /dev/null @@ -1,117 +0,0 @@ -From c2d55efd8a9a156fe14fd477924fadb765ac9438 Mon Sep 17 00:00:00 2001 -Message-Id: -From: "Michael S. Tsirkin" -Date: Wed, 11 Dec 2013 15:16:27 +0100 -Subject: [PATCH 1/3] biostables: support looking up RSDP - -RH-Author: Michael S. Tsirkin -Message-id: <1386774929-25693-2-git-send-email-mst@redhat.com> -Patchwork-id: 56224 -O-Subject: [RHEL7.0 seabios PATCH 1/3] biostables: support looking up RSDP -Bugzilla: 1034877 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Gerd Hoffmann -RH-Acked-by: Marcel Apfelbaum - -Will be used when it's loaded from QEMU. - -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Gerd Hoffmann -(cherry-picked from commit ff5f7921d904dd2ddbaded3941643da8ba5fa9aa) - -In rhel7 codebase we don't know the exact fseg -range. Just scan all of the ROM range. - -Signed-off-by: Michael S. Tsirkin ---- - src/util.h | 1 + - src/biostables.c | 41 ++++++++++++++++++++++++++++++++++------- - 2 files changed, 35 insertions(+), 7 deletions(-) - -Signed-off-by: Michal Novotny ---- - src/biostables.c | 41 ++++++++++++++++++++++++++++++++++------- - src/util.h | 1 + - 2 files changed, 35 insertions(+), 7 deletions(-) - -diff --git a/src/biostables.c b/src/biostables.c -index 81cc79b..2352ba4 100644 ---- a/src/biostables.c -+++ b/src/biostables.c -@@ -57,22 +57,35 @@ copy_mptable(void *pos) - memcpy((void*)newpos + length, (void*)p->physaddr, mpclength); - } - --static void --copy_acpi_rsdp(void *pos) -+static int -+get_acpi_rsdp_length(void *pos, unsigned size) - { -- if (RsdpAddr) -- return; - struct rsdp_descriptor *p = pos; - if (p->signature != RSDP_SIGNATURE) -- return; -+ return -1; - u32 length = 20; -+ if (length > size) -+ return -1; - if (checksum(pos, length) != 0) -- return; -+ return -1; - if (p->revision > 1) { - length = p->length; -+ if (length > size) -+ return -1; - if (checksum(pos, length) != 0) -- return; -+ return -1; - } -+ return length; -+} -+ -+static void -+copy_acpi_rsdp(void *pos) -+{ -+ if (RsdpAddr) -+ return; -+ int length = get_acpi_rsdp_length(pos, -1); -+ if (length < 0) -+ return; - void *newpos = malloc_fseg(length); - if (!newpos) { - warn_noalloc(); -@@ -115,3 +128,17 @@ copy_table(void *pos) - copy_acpi_rsdp(pos); - copy_smbios(pos); - } -+ -+void *find_acpi_rsdp(void) -+{ -+ /* The BIOS read-only memory space is between 0E0000h and 0FFFFFh. */ -+ unsigned long start = 0xE0000; -+ unsigned long end = 0xFFFFF; -+ unsigned long pos; -+ -+ for (pos = ALIGN(start, 0x10); pos <= ALIGN_DOWN(end, 0x10); pos += 0x10) -+ if (get_acpi_rsdp_length((void *)pos, end - pos) >= 0) -+ return (void *)pos; -+ -+ return NULL; -+} -diff --git a/src/util.h b/src/util.h -index 7723bb1..e46d298 100644 ---- a/src/util.h -+++ b/src/util.h -@@ -339,6 +339,7 @@ void coreboot_cbfs_setup(void); - - // biostable.c - void copy_table(void *pos); -+void *find_acpi_rsdp(void); - - // vgahooks.c - void handle_155f(struct bregs *regs); --- -1.7.11.7 - diff --git a/SOURCES/seabios-boot-Fix-boot-order-for-SCSI-target-lun-9.patch b/SOURCES/seabios-boot-Fix-boot-order-for-SCSI-target-lun-9.patch new file mode 100644 index 0000000..d5688cd --- /dev/null +++ b/SOURCES/seabios-boot-Fix-boot-order-for-SCSI-target-lun-9.patch @@ -0,0 +1,74 @@ +From 4ca7fbed401c2aa39fea49859f4b89c839a36684 Mon Sep 17 00:00:00 2001 +From: Markus Armbruster +Date: Fri, 15 Aug 2014 15:05:26 +0200 +Subject: [PATCH 2/2] boot: Fix boot order for SCSI target, lun > 9 + +Message-id: <1408115126-2841-2-git-send-email-armbru@pond.sub.org> +Patchwork-id: 60594 +O-Subject: [PATCH RHEL-7.1 seabios 1/1] boot: Fix boot order for SCSI target, lun > 9 +Bugzilla: 1096560 +RH-Acked-by: Amos Kong +RH-Acked-by: Jeff Nelson +RH-Acked-by: Laszlo Ersek + +From: Markus Armbruster + +We identify devices by their Open Firmware device paths. The path +component for the logical unit on a bus is incorrect: +bootprio_find_scsi_device() and bootprio_find_usb() format target +(a.k.a. SCSI ID) and lun in decimal, while QEMU uses hexadecimal. +Bootorder list entries with target, lun > 9 aren't found (lucky case), +or attributed to the wrong logical unit (unlucky case). + +The relevant spec[*] agrees with QEMU (and OVMF, for that matter). +Change %d to %x. + +No actual impact on USB, because QEMU only uses LUN 0 there. + +RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1096560 + +[*] Open Firmware Recommended Practice: SCSI-3 Parallel Interface, +Version 1, Section 3.1 Physical Address Formats and Representations +http://www.openfirmware.org/1275/practice/spi/spi1_0.ps +IEEE Standard for Boot (Initialization Configuration) Firmware: Core +Requirements and Practices, IEEE Std 1275-1994, Annex E SCSI host +adapter package class, section E.2.1 Physical address formats and +representations + +Signed-off-by: Markus Armbruster +(cherry picked from commit 275672eb70efdf81c51b997d41a4409b404aa8f6) +Signed-off-by: Markus Armbruster +--- + src/boot.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Signed-off-by: Miroslav Rezanina +--- + src/boot.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/boot.c b/src/boot.c +index 133e206..e60ed3e 100644 +--- a/src/boot.c ++++ b/src/boot.c +@@ -145,7 +145,7 @@ int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun) + // Find scsi drive - for example: /pci@i0cf8/scsi@5/channel@0/disk@1,0 + char desc[256], *p; + p = build_pci_path(desc, sizeof(desc), "*", pci); +- snprintf(p, desc+sizeof(desc)-p, "/*@0/*@%d,%d", target, lun); ++ snprintf(p, desc+sizeof(desc)-p, "/*@0/*@%x,%x", target, lun); + return find_prio(desc); + } + +@@ -224,7 +224,7 @@ int bootprio_find_usb(struct usbdevice_s *usbdev, int lun) + char desc[256], *p; + p = build_pci_path(desc, sizeof(desc), "usb", usbdev->hub->cntl->pci); + p = build_usb_path(p, desc+sizeof(desc)-p, usbdev->hub); +- snprintf(p, desc+sizeof(desc)-p, "/storage@%x/*@0/*@0,%d" ++ snprintf(p, desc+sizeof(desc)-p, "/storage@%x/*@0/*@0,%x" + , usbdev->port+1, lun); + int ret = find_prio(desc); + if (ret >= 0) +-- +1.7.1 + diff --git a/SOURCES/seabios-build-explicitly-set-ROM-size.patch b/SOURCES/seabios-build-explicitly-set-ROM-size.patch deleted file mode 100644 index d34c828..0000000 --- a/SOURCES/seabios-build-explicitly-set-ROM-size.patch +++ /dev/null @@ -1,113 +0,0 @@ -From f1afa918b6f5d3069cc8c772b4cca254d21cba6b Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 9 Dec 2013 09:14:24 +0100 -Subject: [PATCH 1/2] build: explicitly set ROM size - -RH-Author: Gerd Hoffmann -Message-id: <1386580465-6692-2-git-send-email-kraxel@redhat.com> -Patchwork-id: 56028 -O-Subject: [RHEL-7 seabios PATCH 1/2] build: explicitly set ROM size -Bugzilla: 1038604 -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Eduardo Habkost -RH-Acked-by: Miroslav Rezanina - -Add a config option to specify the rom size wanted. Default is zero, -which will automatically figure the needed size. - -Signed-off-by: Gerd Hoffmann -(cherry picked from commit 85f8fac87526341d775b02a0bfbc29d97f3ba22a) - -Conflicts: - Makefile ---- - Makefile | 3 ++- - src/Kconfig | 11 +++++++++++ - tools/checkrom.py | 21 +++++++++++++++------ - 3 files changed, 28 insertions(+), 7 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - Makefile | 3 ++- - src/Kconfig | 11 +++++++++++ - tools/checkrom.py | 21 +++++++++++++++------ - 3 files changed, 28 insertions(+), 7 deletions(-) - -diff --git a/Makefile b/Makefile -index 409aefa..b82bd58 100644 ---- a/Makefile -+++ b/Makefile -@@ -167,7 +167,8 @@ $(OUT)bios.bin.elf $(OUT)bios.bin: $(OUT)rom.o tools/checkrom.py - @echo " Prepping $@" - $(Q)$(OBJDUMP) -thr $< > $<.objdump - $(Q)$(OBJCOPY) -O binary $< $(OUT)bios.bin.raw -- $(Q)$(PYTHON) ./tools/checkrom.py $<.objdump $(OUT)bios.bin.raw $(OUT)bios.bin -+ $(Q)$(PYTHON) ./tools/checkrom.py $<.objdump $(CONFIG_ROM_SIZE) \ -+ $(OUT)bios.bin.raw $(OUT)bios.bin - $(Q)$(STRIP) -R .comment $< -o $(OUT)bios.bin.elf - - -diff --git a/src/Kconfig b/src/Kconfig -index d00c66c..f5dce60 100644 ---- a/src/Kconfig -+++ b/src/Kconfig -@@ -90,6 +90,17 @@ endchoice - help - Support floppy images in coreboot flash. - -+ config ROM_SIZE -+ int "ROM size (in KB)" -+ default 0 -+ help -+ Set the ROM size. Say '0' here to make seabios figure the -+ needed size automatically. -+ -+ Currently SeaBIOS will easily fit into 256 KB. To make it fit -+ it into 128 KB (which was big enough for a long time) you'll -+ probably have to disable some featues such as xhci support. -+ - endmenu - - menu "Hardware support" -diff --git a/tools/checkrom.py b/tools/checkrom.py -index 69d65e8..b997e8c 100755 ---- a/tools/checkrom.py -+++ b/tools/checkrom.py -@@ -10,7 +10,7 @@ import layoutrom - - def main(): - # Get args -- objinfo, rawfile, outfile = sys.argv[1:] -+ objinfo, finalsize, rawfile, outfile = sys.argv[1:] - - # Read in symbols - objinfofile = open(objinfo, 'rb') -@@ -21,11 +21,20 @@ def main(): - rawdata = f.read() - f.close() - datasize = len(rawdata) -- finalsize = 64*1024 -- if datasize > 64*1024: -- finalsize = 128*1024 -- if datasize > 128*1024: -- finalsize = 256*1024 -+ finalsize = int(finalsize) * 1024 -+ if finalsize == 0: -+ finalsize = 64*1024 -+ if datasize > 64*1024: -+ finalsize = 128*1024 -+ if datasize > 128*1024: -+ finalsize = 256*1024 -+ if datasize > finalsize: -+ print "Error! ROM doesn't fit (%d > %d)" % (datasize, finalsize) -+ print " You have to either increase the size (CONFIG_ROM_SIZE)" -+ print " or turn off some features (such as hardware support not" -+ print " needed) to make it fit. Trying a more recent gcc version" -+ print " might work too." -+ sys.exit(1) - - # Sanity checks - start = symbols['code32flat_start'].offset --- -1.7.1 - diff --git a/SOURCES/seabios-floppy-Cleanup-floppy-irq-wait-handling.patch b/SOURCES/seabios-floppy-Cleanup-floppy-irq-wait-handling.patch deleted file mode 100644 index bc4e9c2..0000000 --- a/SOURCES/seabios-floppy-Cleanup-floppy-irq-wait-handling.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 46ceee9e43c842627ac0f684e1d9d6244edb2a10 Mon Sep 17 00:00:00 2001 -From: Fam Zheng -Date: Thu, 22 Aug 2013 02:15:58 +0200 -Subject: [PATCH 2/5] floppy: Cleanup floppy irq wait handling. - -RH-Author: Fam Zheng -Message-id: <1377137759-16089-3-git-send-email-famz@redhat.com> -Patchwork-id: 53680 -O-Subject: [RHEL-7 seabios PATCH 2/3] floppy: Cleanup floppy irq wait handling. -Bugzilla: 920140 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Markus Armbruster - -From: Kevin O'Connor - -Rename FRS_TIMEOUT to FRS_IRQ - the flag indicates that an irq has -been received - it isn't directly related to timeouts. - -On a timeout event, disable the floppy controller instead of doing a -full reset. Also, perform the disable directly in floppy_wait_irq(). - -Always wait for the floppy irq after enabling the controller and after -a recalibrate command. - -Signed-off-by: Kevin O'Connor -(cherry picked from commit 6e529bdae4922f48c0d7eaa31613b7a9230e8f95) -Signed-off-by: Fam Zheng ---- - src/biosvar.h | 2 +- - src/floppy.c | 88 +++++++++++++++++++++++++++++------------------------------ - 2 files changed, 45 insertions(+), 45 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - src/biosvar.h | 2 +- - src/floppy.c | 88 ++++++++++++++++++++++++++++---------------------------- - 2 files changed, 45 insertions(+), 45 deletions(-) - -diff --git a/src/biosvar.h b/src/biosvar.h -index f0a0fd2..252d4d1 100644 ---- a/src/biosvar.h -+++ b/src/biosvar.h -@@ -120,7 +120,7 @@ struct bios_data_area_s { - } PACKED; - - // BDA floppy_recalibration_status bitdefs --#define FRS_TIMEOUT (1<<7) -+#define FRS_IRQ (1<<7) - - // BDA rtc_wait_flag bitdefs - #define RWS_WAIT_PENDING (1<<0) -diff --git a/src/floppy.c b/src/floppy.c -index 458bb7a..429ccb5 100644 ---- a/src/floppy.c -+++ b/src/floppy.c -@@ -164,63 +164,59 @@ find_floppy_type(u32 size) - ****************************************************************/ - - static void --floppy_reset_controller(void) -+floppy_disable_controller(void) - { -- // Reset controller -- u8 val8 = inb(PORT_FD_DOR); -- outb(val8 & ~0x04, PORT_FD_DOR); -- outb(val8 | 0x04, PORT_FD_DOR); -- -- // Wait for controller to come out of reset -- while ((inb(PORT_FD_STATUS) & 0xc0) != 0x80) -- ; -+ outb(inb(PORT_FD_DOR) & ~0x04, PORT_FD_DOR); - } - - static int --wait_floppy_irq(void) -+floppy_wait_irq(void) - { -- ASSERT16(); -- u8 frs; -+ u8 frs = GET_BDA(floppy_recalibration_status); -+ SET_BDA(floppy_recalibration_status, frs & ~FRS_IRQ); - for (;;) { -- if (!GET_BDA(floppy_motor_counter)) -- return -1; -+ if (!GET_BDA(floppy_motor_counter)) { -+ floppy_disable_controller(); -+ return DISK_RET_ETIMEOUT; -+ } - frs = GET_BDA(floppy_recalibration_status); -- if (frs & FRS_TIMEOUT) -+ if (frs & FRS_IRQ) - break; - // Could use yield_toirq() here, but that causes issues on - // bochs, so use yield() instead. - yield(); - } - -- frs &= ~FRS_TIMEOUT; -- SET_BDA(floppy_recalibration_status, frs); -- return 0; -+ SET_BDA(floppy_recalibration_status, frs & ~FRS_IRQ); -+ return DISK_RET_SUCCESS; - } - --static void --floppy_prepare_controller(u8 floppyid) -+static int -+floppy_enable_controller(void) - { -- u8 frs = GET_BDA(floppy_recalibration_status); -- SET_BDA(floppy_recalibration_status, frs & ~FRS_TIMEOUT); -- -- // turn on motor of selected drive, DMA & int enabled, normal operation -- u8 prev_reset = inb(PORT_FD_DOR) & 0x04; -- u8 dor = 0x10; -- if (floppyid) -- dor = 0x20; -- dor |= 0x0c; -- dor |= floppyid; -- outb(dor, PORT_FD_DOR); -+ outb(inb(PORT_FD_DOR) | 0x04, PORT_FD_DOR); -+ return floppy_wait_irq(); -+} - -+static int -+floppy_select_drive(u8 floppyid) -+{ - // reset the disk motor timeout value of INT 08 - SET_BDA(floppy_motor_counter, FLOPPY_MOTOR_TICKS); - -- // wait for drive readiness -- while ((inb(PORT_FD_STATUS) & 0xc0) != 0x80) -- ; -+ // Enable controller if it isn't running. -+ u8 dor = inb(PORT_FD_DOR); -+ if (!(dor & 0x04)) { -+ int ret = floppy_enable_controller(); -+ if (ret) -+ return ret; -+ } - -- if (!prev_reset) -- wait_floppy_irq(); -+ // Turn on motor of selected drive, DMA & int enabled, normal operation -+ dor = (floppyid ? 0x20 : 0x10) | 0x0c | floppyid; -+ outb(dor, PORT_FD_DOR); -+ -+ return DISK_RET_SUCCESS; - } - - struct floppy_pio_s { -@@ -233,7 +229,13 @@ struct floppy_pio_s { - static int - floppy_pio(struct floppy_pio_s *pio) - { -- floppy_prepare_controller(pio->data[1] & 1); -+ int ret = floppy_select_drive(pio->data[1] & 1); -+ if (ret) -+ return ret; -+ -+ // wait for drive readiness -+ while ((inb(PORT_FD_STATUS) & 0xc0) != 0x80) -+ ; - - // send command to controller - int i; -@@ -241,11 +243,9 @@ floppy_pio(struct floppy_pio_s *pio) - outb(pio->data[i], PORT_FD_DATA); - - if (pio->waitirq) { -- int ret = wait_floppy_irq(); -- if (ret) { -- floppy_reset_controller(); -- return DISK_RET_ETIMEOUT; -- } -+ int ret = floppy_wait_irq(); -+ if (ret) -+ return ret; - } - - if (!pio->resplen) -@@ -330,7 +330,7 @@ floppy_drive_recal(u8 floppyid) - struct floppy_pio_s pio; - pio.cmdlen = 2; - pio.resplen = 0; -- pio.waitirq = 0; -+ pio.waitirq = 1; - pio.data[0] = 0x07; // 07: Recalibrate - pio.data[1] = floppyid; // 0=drive0, 1=drive1 - floppy_pio(&pio); -@@ -617,7 +617,7 @@ handle_0e(void) - } - // diskette interrupt has occurred - u8 frs = GET_BDA(floppy_recalibration_status); -- SET_BDA(floppy_recalibration_status, frs | FRS_TIMEOUT); -+ SET_BDA(floppy_recalibration_status, frs | FRS_IRQ); - - eoi_pic1(); - } --- -1.7.1 - diff --git a/SOURCES/seabios-floppy-Implement-media-format-sensing.patch b/SOURCES/seabios-floppy-Implement-media-format-sensing.patch deleted file mode 100644 index a0acc37..0000000 --- a/SOURCES/seabios-floppy-Implement-media-format-sensing.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 51d219681f4e073bbaf0a6e540f42447f1a18edf Mon Sep 17 00:00:00 2001 -From: Fam Zheng -Date: Thu, 22 Aug 2013 02:15:59 +0200 -Subject: [PATCH 3/5] floppy: Implement media format sensing. - -RH-Author: Fam Zheng -Message-id: <1377137759-16089-4-git-send-email-famz@redhat.com> -Patchwork-id: 53681 -O-Subject: [RHEL-7 seabios PATCH 3/3] floppy: Implement media format sensing. -Bugzilla: 920140 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Markus Armbruster - -From: Kevin O'Connor - -Check for lower capacity media in the floppy drive and set the -corresponding controller data rate for it. - -Signed-off-by: Kevin O'Connor -(cherry picked from commit e7c5a7ef782673f00faf3371721562806e931cdb) -Signed-off-by: Fam Zheng - -Conflicts: - src/floppy.c - Context conflict. Upstream 89a2f96d converted VAR16VISIBLE - to VARFSEG, which we don't have yet. So keep the original - type. - -Signed-off-by: Fam Zheng ---- - src/floppy.c | 123 +++++++++++++++++++++++++++++++++++++---------------------- - 1 file changed, 78 insertions(+), 45 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - src/floppy.c | 123 ++++++++++++++++++++++++++++++++++++--------------------- - 1 files changed, 78 insertions(+), 45 deletions(-) - -diff --git a/src/floppy.c b/src/floppy.c -index 429ccb5..f00349d 100644 ---- a/src/floppy.c -+++ b/src/floppy.c -@@ -51,29 +51,37 @@ struct floppy_dbt_s diskette_param_table VAR16FIXED(0xefc7); - - struct floppyinfo_s { - struct chs_s chs; -- u8 config_data; -- u8 media_state; -+ u8 floppy_size; -+ u8 data_rate; - }; - -+#define FLOPPY_SIZE_525 0x01 -+#define FLOPPY_SIZE_350 0x02 -+ -+#define FLOPPY_RATE_500K 0x00 -+#define FLOPPY_RATE_300K 0x01 -+#define FLOPPY_RATE_250K 0x02 -+#define FLOPPY_RATE_1M 0x03 -+ - struct floppyinfo_s FloppyInfo[] VAR16VISIBLE = { - // Unknown - { {0, 0, 0}, 0x00, 0x00}, - // 1 - 360KB, 5.25" - 2 heads, 40 tracks, 9 sectors -- { {2, 40, 9}, 0x00, 0x25}, -+ { {2, 40, 9}, FLOPPY_SIZE_525, FLOPPY_RATE_300K}, - // 2 - 1.2MB, 5.25" - 2 heads, 80 tracks, 15 sectors -- { {2, 80, 15}, 0x00, 0x25}, -+ { {2, 80, 15}, FLOPPY_SIZE_525, FLOPPY_RATE_500K}, - // 3 - 720KB, 3.5" - 2 heads, 80 tracks, 9 sectors -- { {2, 80, 9}, 0x00, 0x17}, -+ { {2, 80, 9}, FLOPPY_SIZE_350, FLOPPY_RATE_250K}, - // 4 - 1.44MB, 3.5" - 2 heads, 80 tracks, 18 sectors -- { {2, 80, 18}, 0x00, 0x17}, -+ { {2, 80, 18}, FLOPPY_SIZE_350, FLOPPY_RATE_500K}, - // 5 - 2.88MB, 3.5" - 2 heads, 80 tracks, 36 sectors -- { {2, 80, 36}, 0xCC, 0xD7}, -+ { {2, 80, 36}, FLOPPY_SIZE_350, FLOPPY_RATE_1M}, - // 6 - 160k, 5.25" - 1 heads, 40 tracks, 8 sectors -- { {1, 40, 8}, 0x00, 0x27}, -+ { {1, 40, 8}, FLOPPY_SIZE_525, FLOPPY_RATE_250K}, - // 7 - 180k, 5.25" - 1 heads, 40 tracks, 9 sectors -- { {1, 40, 9}, 0x00, 0x27}, -+ { {1, 40, 9}, FLOPPY_SIZE_525, FLOPPY_RATE_300K}, - // 8 - 320k, 5.25" - 2 heads, 40 tracks, 8 sectors -- { {2, 40, 8}, 0x00, 0x27}, -+ { {2, 40, 8}, FLOPPY_SIZE_525, FLOPPY_RATE_250K}, - }; - - struct drive_s * -@@ -341,44 +349,69 @@ floppy_drive_recal(u8 floppyid) - } - - static int -+floppy_drive_readid(u8 floppyid, u8 data_rate, u8 head) -+{ -+ int ret = floppy_select_drive(floppyid); -+ if (ret) -+ return ret; -+ -+ // Set data rate. -+ outb(data_rate, PORT_FD_DIR); -+ -+ // send Read Sector Id command -+ struct floppy_pio_s pio; -+ pio.cmdlen = 2; -+ pio.resplen = 7; -+ pio.waitirq = 1; -+ pio.data[0] = 0x4a; // 0a: Read Sector Id -+ pio.data[1] = (head << 2) | floppyid; // HD DR1 DR2 -+ ret = floppy_pio(&pio); -+ if (ret) -+ return ret; -+ if (pio.data[0] & 0xc0) -+ return -1; -+ return 0; -+} -+ -+static int - floppy_media_sense(struct drive_s *drive_g) - { -- // for now cheat and get drive type from CMOS, -- // assume media is same as drive type -- -- // ** config_data ** -- // Bitfields for diskette media control: -- // Bit(s) Description (Table M0028) -- // 7-6 last data rate set by controller -- // 00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps -- // 5-4 last diskette drive step rate selected -- // 00=0Ch, 01=0Dh, 10=0Eh, 11=0Ah -- // 3-2 {data rate at start of operation} -- // 1-0 reserved -- -- // ** media_state ** -- // Bitfields for diskette drive media state: -- // Bit(s) Description (Table M0030) -- // 7-6 data rate -- // 00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps -- // 5 double stepping required (e.g. 360kB in 1.2MB) -- // 4 media type established -- // 3 drive capable of supporting 4MB media -- // 2-0 on exit from BIOS, contains -- // 000 trying 360kB in 360kB -- // 001 trying 360kB in 1.2MB -- // 010 trying 1.2MB in 1.2MB -- // 011 360kB in 360kB established -- // 100 360kB in 1.2MB established -- // 101 1.2MB in 1.2MB established -- // 110 reserved -- // 111 all other formats/drives -- -- u8 ftype = GET_GLOBAL(drive_g->floppy_type); -- SET_BDA(floppy_last_data_rate, GET_GLOBAL(FloppyInfo[ftype].config_data)); -+ u8 ftype = GET_GLOBAL(drive_g->floppy_type), stype = ftype; - u8 floppyid = GET_GLOBAL(drive_g->cntl_id); -- SET_BDA(floppy_media_state[floppyid] -- , GET_GLOBAL(FloppyInfo[ftype].media_state)); -+ -+ u8 data_rate = GET_GLOBAL(FloppyInfo[stype].data_rate); -+ int ret = floppy_drive_readid(floppyid, data_rate, 0); -+ if (ret) { -+ // Attempt media sense. -+ for (stype=1; ; stype++) { -+ if (stype >= ARRAY_SIZE(FloppyInfo)) -+ return DISK_RET_EMEDIA; -+ if (stype==ftype -+ || (GET_GLOBAL(FloppyInfo[stype].floppy_size) -+ != GET_GLOBAL(FloppyInfo[ftype].floppy_size)) -+ || (GET_GLOBAL(FloppyInfo[stype].chs.heads) -+ > GET_GLOBAL(FloppyInfo[ftype].chs.heads)) -+ || (GET_GLOBAL(FloppyInfo[stype].chs.cylinders) -+ > GET_GLOBAL(FloppyInfo[ftype].chs.cylinders)) -+ || (GET_GLOBAL(FloppyInfo[stype].chs.spt) -+ > GET_GLOBAL(FloppyInfo[ftype].chs.spt))) -+ continue; -+ data_rate = GET_GLOBAL(FloppyInfo[stype].data_rate); -+ ret = floppy_drive_readid(floppyid, data_rate, 0); -+ if (!ret) -+ break; -+ } -+ } -+ -+ u8 old_data_rate = GET_BDA(floppy_media_state[floppyid]) >> 6; -+ SET_BDA(floppy_last_data_rate, (old_data_rate<<2) | (data_rate<<6)); -+ u8 media = (stype == 1 ? 0x04 : (stype == 2 ? 0x05 : 0x07)); -+ u8 fms = (data_rate<<6) | FMS_MEDIA_DRIVE_ESTABLISHED | media; -+ if (GET_GLOBAL(FloppyInfo[stype].chs.cylinders) -+ < GET_GLOBAL(FloppyInfo[ftype].chs.cylinders)) -+ fms |= FMS_DOUBLE_STEPPING; -+ SET_BDA(floppy_media_state[floppyid], fms); -+ - return DISK_RET_SUCCESS; - } - --- -1.7.1 - diff --git a/SOURCES/seabios-floppy-Introduce-struct-floppy_pio_s-for-floppy-PIO-.patch b/SOURCES/seabios-floppy-Introduce-struct-floppy_pio_s-for-floppy-PIO-.patch deleted file mode 100644 index d3aec63..0000000 --- a/SOURCES/seabios-floppy-Introduce-struct-floppy_pio_s-for-floppy-PIO-.patch +++ /dev/null @@ -1,265 +0,0 @@ -From 946dd96997625598fd814500e5fbfd457c6d670d Mon Sep 17 00:00:00 2001 -From: Fam Zheng -Date: Thu, 22 Aug 2013 02:15:57 +0200 -Subject: [PATCH 1/5] floppy: Introduce 'struct floppy_pio_s' for floppy PIO ops. - -RH-Author: Fam Zheng -Message-id: <1377137759-16089-2-git-send-email-famz@redhat.com> -Patchwork-id: 53679 -O-Subject: [RHEL-7 seabios PATCH 1/3] floppy: Introduce 'struct floppy_pio_s' for floppy PIO ops. -Bugzilla: 920140 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Markus Armbruster - -From: Kevin O'Connor - -Populate a struct for the PIO operations and move the PIO manipulation -done in floppy_cmd() to floppy_pio(). - -Signed-off-by: Kevin O'Connor -(cherry picked from commit 9ba374ce1d864b7a50f3657e6b06e7b2d1ec2934) -Signed-off-by: Fam Zheng ---- - src/floppy.c | 158 ++++++++++++++++++++++++++++++++++------------------------- - 1 file changed, 90 insertions(+), 68 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - src/floppy.c | 158 +++++++++++++++++++++++++++++++++------------------------- - 1 files changed, 90 insertions(+), 68 deletions(-) - -diff --git a/src/floppy.c b/src/floppy.c -index e9f8916..458bb7a 100644 ---- a/src/floppy.c -+++ b/src/floppy.c -@@ -223,27 +223,48 @@ floppy_prepare_controller(u8 floppyid) - wait_floppy_irq(); - } - -+struct floppy_pio_s { -+ u8 cmdlen; -+ u8 resplen; -+ u8 waitirq; -+ u8 data[9]; -+}; -+ - static int --floppy_pio(u8 *cmd, u8 cmdlen) -+floppy_pio(struct floppy_pio_s *pio) - { -- floppy_prepare_controller(cmd[1] & 1); -+ floppy_prepare_controller(pio->data[1] & 1); - - // send command to controller -- u8 i; -- for (i=0; icmdlen; i++) -+ outb(pio->data[i], PORT_FD_DATA); -+ -+ if (pio->waitirq) { -+ int ret = wait_floppy_irq(); -+ if (ret) { -+ floppy_reset_controller(); -+ return DISK_RET_ETIMEOUT; -+ } - } - -- return 0; -+ if (!pio->resplen) -+ return DISK_RET_SUCCESS; -+ -+ // check port 3f4 for accessibility to status bytes -+ if ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0) -+ return DISK_RET_ECONTROLLER; -+ -+ // read return status bytes from controller -+ for (i=0; iresplen; i++) -+ pio->data[i] = inb(PORT_FD_DATA); -+ -+ return DISK_RET_SUCCESS; - } - -+// Perform a floppy transfer command (setup DMA and issue PIO). - static int --floppy_cmd(struct disk_op_s *op, u16 count, u8 *cmd, u8 cmdlen) -+floppy_cmd(struct disk_op_s *op, int count, struct floppy_pio_s *pio) - { - // es:bx = pointer to where to place information from diskette - u32 addr = (u32)op->buf_fl; -@@ -255,7 +276,7 @@ floppy_cmd(struct disk_op_s *op, u16 count, u8 *cmd, u8 cmdlen) - return DISK_RET_EBOUNDARY; - - u8 mode_register = 0x4a; // single mode, increment, autoinit disable, -- if (cmd[0] == 0xe6) -+ if (pio->data[0] == 0xe6) - // read - mode_register = 0x46; - -@@ -277,21 +298,16 @@ floppy_cmd(struct disk_op_s *op, u16 count, u8 *cmd, u8 cmdlen) - - outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2 - -- int ret = floppy_pio(cmd, cmdlen); -+ pio->resplen = 7; -+ pio->waitirq = 1; -+ int ret = floppy_pio(pio); - if (ret) -- return DISK_RET_ETIMEOUT; -- -- // check port 3f4 for accessibility to status bytes -- if ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0) -- return DISK_RET_ECONTROLLER; -+ return ret; - -- // read 7 return status bytes from controller -- u8 i; -- for (i=0; i<7; i++) { -- u8 v = inb(PORT_FD_DATA); -- cmd[i] = v; -- SET_BDA(floppy_return_status[i], v); -- } -+ // Populate floppy_return_status in BDA -+ int i; -+ for (i=0; i<7; i++) -+ SET_BDA(floppy_return_status[i], pio->data[i]); - - return DISK_RET_SUCCESS; - } -@@ -311,10 +327,13 @@ static void - floppy_drive_recal(u8 floppyid) - { - // send Recalibrate command (2 bytes) to controller -- u8 data[12]; -- data[0] = 0x07; // 07: Recalibrate -- data[1] = floppyid; // 0=drive0, 1=drive1 -- floppy_pio(data, 2); -+ struct floppy_pio_s pio; -+ pio.cmdlen = 2; -+ pio.resplen = 0; -+ pio.waitirq = 0; -+ pio.data[0] = 0x07; // 07: Recalibrate -+ pio.data[1] = floppyid; // 0=drive0, 1=drive1 -+ floppy_pio(&pio); - - u8 frs = GET_BDA(floppy_recalibration_status); - SET_BDA(floppy_recalibration_status, frs | (1<drive_g->cntl_id); -- u8 data[12]; -- data[0] = 0xe6; // e6: read normal data -- data[1] = (head << 2) | floppyid; // HD DR1 DR2 -- data[2] = track; -- data[3] = head; -- data[4] = sector; -- data[5] = FLOPPY_SIZE_CODE; -- data[6] = sector + op->count - 1; // last sector to read on track -- data[7] = FLOPPY_GAPLEN; -- data[8] = FLOPPY_DATALEN; -- -- res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, data, 9); -+ struct floppy_pio_s pio; -+ pio.cmdlen = 9; -+ pio.data[0] = 0xe6; // e6: read normal data -+ pio.data[1] = (head << 2) | floppyid; // HD DR1 DR2 -+ pio.data[2] = track; -+ pio.data[3] = head; -+ pio.data[4] = sector; -+ pio.data[5] = FLOPPY_SIZE_CODE; -+ pio.data[6] = sector + op->count - 1; // last sector to read on track -+ pio.data[7] = FLOPPY_GAPLEN; -+ pio.data[8] = FLOPPY_DATALEN; -+ -+ res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, &pio); - if (res) - goto fail; - -- if (data[0] & 0xc0) { -+ if (pio.data[0] & 0xc0) { - res = DISK_RET_ECONTROLLER; - goto fail; - } -@@ -464,23 +484,24 @@ floppy_write(struct disk_op_s *op) - - // send write-normal-data command (9 bytes) to controller - u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); -- u8 data[12]; -- data[0] = 0xc5; // c5: write normal data -- data[1] = (head << 2) | floppyid; // HD DR1 DR2 -- data[2] = track; -- data[3] = head; -- data[4] = sector; -- data[5] = FLOPPY_SIZE_CODE; -- data[6] = sector + op->count - 1; // last sector to write on track -- data[7] = FLOPPY_GAPLEN; -- data[8] = FLOPPY_DATALEN; -- -- res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, data, 9); -+ struct floppy_pio_s pio; -+ pio.cmdlen = 9; -+ pio.data[0] = 0xc5; // c5: write normal data -+ pio.data[1] = (head << 2) | floppyid; // HD DR1 DR2 -+ pio.data[2] = track; -+ pio.data[3] = head; -+ pio.data[4] = sector; -+ pio.data[5] = FLOPPY_SIZE_CODE; -+ pio.data[6] = sector + op->count - 1; // last sector to write on track -+ pio.data[7] = FLOPPY_GAPLEN; -+ pio.data[8] = FLOPPY_DATALEN; -+ -+ res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, &pio); - if (res) - goto fail; - -- if (data[0] & 0xc0) { -- if (data[1] & 0x02) -+ if (pio.data[0] & 0xc0) { -+ if (pio.data[1] & 0x02) - res = DISK_RET_EWRITEPROTECT; - else - res = DISK_RET_ECONTROLLER; -@@ -527,20 +548,21 @@ floppy_format(struct disk_op_s *op) - - // send format-track command (6 bytes) to controller - u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); -- u8 data[12]; -- data[0] = 0x4d; // 4d: format track -- data[1] = (head << 2) | floppyid; // HD DR1 DR2 -- data[2] = FLOPPY_SIZE_CODE; -- data[3] = op->count; // number of sectors per track -- data[4] = FLOPPY_FORMAT_GAPLEN; -- data[5] = FLOPPY_FILLBYTE; -- -- ret = floppy_cmd(op, op->count * 4, data, 6); -+ struct floppy_pio_s pio; -+ pio.cmdlen = 6; -+ pio.data[0] = 0x4d; // 4d: format track -+ pio.data[1] = (head << 2) | floppyid; // HD DR1 DR2 -+ pio.data[2] = FLOPPY_SIZE_CODE; -+ pio.data[3] = op->count; // number of sectors per track -+ pio.data[4] = FLOPPY_FORMAT_GAPLEN; -+ pio.data[5] = FLOPPY_FILLBYTE; -+ -+ ret = floppy_cmd(op, op->count * 4, &pio); - if (ret) - return ret; - -- if (data[0] & 0xc0) { -- if (data[1] & 0x02) -+ if (pio.data[0] & 0xc0) { -+ if (pio.data[1] & 0x02) - return DISK_RET_EWRITEPROTECT; - return DISK_RET_ECONTROLLER; - } --- -1.7.1 - diff --git a/SOURCES/seabios-init_virtio_scsi-reset-the-HBA-before-freeing-its-vi.patch b/SOURCES/seabios-init_virtio_scsi-reset-the-HBA-before-freeing-its-vi.patch deleted file mode 100644 index 1704905..0000000 --- a/SOURCES/seabios-init_virtio_scsi-reset-the-HBA-before-freeing-its-vi.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 395b6a18728feca247bad3adea3b7c6884eb30fd Mon Sep 17 00:00:00 2001 -From: Laszlo Ersek -Date: Fri, 17 Jan 2014 19:15:23 -0500 -Subject: [PATCH 1/6] init_virtio_scsi(): reset the HBA before freeing its - virtio ring - -Message-id: <1389986123-16290-1-git-send-email-lersek@redhat.com> -Patchwork-id: 56797 -O-Subject: [RHEL-7.0 seabios PATCH] init_virtio_scsi(): reset the HBA before freeing its virtio ring -Bugzilla: 1013418 -RH-Acked-by: Michael S. Tsirkin -RH-Acked-by: Kevin Wolf -RH-Acked-by: Paolo Bonzini - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1013418 -Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=6893168 - -When init_virtio_scsi() finds no SCSI targets connected to the HBA, it -frees the virtio ring. Other code in SeaBIOS proceeds to overwrite the -area. However, the ring is in use by qemu at that point -- not only did we -report the (ACK|DRIVER|DRIVER_OK) status earlier, we even communicated -over the ring. - -Of course SeaBIOS doesn't "kick" the HBA ever again, hence qemu has no -reason to look at the ring. However, when qemu uses KVM acceleration, and -ioeventfd is enabled for the HBA, then a vmstate change to "running" -(including stop->cont monitor commands and incoming migration) "forces" a -kick (see qemu commit 25db9ebe). Qemu then tries to interpret whatever -unrelated guest data is in the HBA's original ring area, as virtio -protocol. Qemu exits upon seeing the garbage. - -init_virtio_scsi() should reset the HBA before allowing the virtio ring -memory to be reused. Device reset causes the hypervisor to drop its -references. - -This change is justified / underpinned by pure virtio-spec compliance as -well. - -Related RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1013418 - -Signed-off-by: Laszlo Ersek -(cherry picked from commit 5f2d17d35b2339526f3b3d580b279ea78e406a25) ---- - src/virtio-scsi.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -Signed-off-by: Miroslav Rezanina ---- - src/virtio-scsi.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/virtio-scsi.c b/src/virtio-scsi.c -index bf6c68b..7caf405 100644 ---- a/src/virtio-scsi.c -+++ b/src/virtio-scsi.c -@@ -154,8 +154,10 @@ init_virtio_scsi(struct pci_device *pci) - for (tot = 0, i = 0; i < 256; i++) - tot += virtio_scsi_scan_target(pci, ioaddr, vq, i); - -- if (!tot) -+ if (!tot) { -+ vp_reset(ioaddr); - goto fail; -+ } - - return; - --- -1.8.3.1 - diff --git a/SOURCES/seabios-pci-align-64bit-pci-regions-to-1G.patch b/SOURCES/seabios-pci-align-64bit-pci-regions-to-1G.patch deleted file mode 100644 index 10b5339..0000000 --- a/SOURCES/seabios-pci-align-64bit-pci-regions-to-1G.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 3c0e8f345d3653dd0a93212961b2417cb5623403 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 27 Jan 2014 15:31:26 -0500 -Subject: [PATCH 4/6] pci: align 64bit pci regions to 1G - -Message-id: <1390836688-16749-2-git-send-email-kraxel@redhat.com> -Patchwork-id: 56957 -O-Subject: [RHEL-7 seabios PATCH 1/3] pci: align 64bit pci regions to 1G -Bugzilla: 1055832 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Michael S. Tsirkin - -So they are hugepage aligned. - -Signed-off-by: Gerd Hoffmann -(cherry picked from commit f21c0066df641c2d0e383254bb69a42a60c0616c) ---- - src/pciinit.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - src/pciinit.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/src/pciinit.c b/src/pciinit.c -index e501964..15744e7 100644 ---- a/src/pciinit.c -+++ b/src/pciinit.c -@@ -761,10 +761,15 @@ static void pci_bios_map_devices(struct pci_bus *busses) - u64 align_mem = pci_region_align(&r64_mem); - u64 align_pref = pci_region_align(&r64_pref); - -- r64_mem.base = ALIGN(0x100000000LL + RamSizeOver4G, align_mem); -- r64_pref.base = ALIGN(r64_mem.base + sum_mem, align_pref); -+ r64_mem.base = 0x100000000LL + RamSizeOver4G; -+ r64_mem.base = ALIGN(r64_mem.base, align_mem); -+ r64_mem.base = ALIGN(r64_mem.base, (1LL<<30)); // 1G hugepage -+ r64_pref.base = r64_mem.base + sum_mem; -+ r64_pref.base = ALIGN(r64_pref.base, align_pref); -+ r64_pref.base = ALIGN(r64_pref.base, (1LL<<30)); // 1G hugepage - pcimem64_start = r64_mem.base; - pcimem64_end = r64_pref.base + sum_pref; -+ pcimem64_end = ALIGN(pcimem64_end, (1LL<<30)); // 1G hugepage - - pci_region_map_entries(busses, &r64_mem); - pci_region_map_entries(busses, &r64_pref); --- -1.8.3.1 - diff --git a/SOURCES/seabios-pci-improve-io-address-space-allocation.patch b/SOURCES/seabios-pci-improve-io-address-space-allocation.patch deleted file mode 100644 index 856e715..0000000 --- a/SOURCES/seabios-pci-improve-io-address-space-allocation.patch +++ /dev/null @@ -1,111 +0,0 @@ -From b2d132c9e3a65858fb745bdeafd1700a58db9bdc Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 27 Jan 2014 15:31:28 -0500 -Subject: [PATCH 6/6] pci: improve io address space allocation - -Message-id: <1390836688-16749-4-git-send-email-kraxel@redhat.com> -Patchwork-id: 56958 -O-Subject: [RHEL-7 seabios PATCH 3/3] pci: improve io address space allocation -Bugzilla: 1055832 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Michael S. Tsirkin - -This patch improves the io address space allocation. It adds a check -that the region above 0xc000 which is traditionally used for pci io -is actually big enougth. If it isn't it tries the larger window at -0x1000. If that is to small too it errors out. - -When creating guests with multiple pci-pci bridges (and devices with -io regions behind them) the 0xc000 -> 0xffff region quickly becomes -too small. - -While being at it document the io address space layout used by -qemu/seabios. - -Signed-off-by: Gerd Hoffmann -(cherry picked from commit fc3cd00045cbe96ca1e6b6601d26901f040bfcdb) ---- - src/pciinit.c | 45 ++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 40 insertions(+), 5 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - src/pciinit.c | 45 ++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 40 insertions(+), 5 deletions(-) - -diff --git a/src/pciinit.c b/src/pciinit.c -index 4e5d7d0..fe58f59 100644 ---- a/src/pciinit.c -+++ b/src/pciinit.c -@@ -663,10 +663,42 @@ static int pci_bios_check_devices(struct pci_bus *busses) - ****************************************************************/ - - // Setup region bases (given the regions' size and alignment) --static int pci_bios_init_root_regions(struct pci_bus *bus) --{ -- bus->r[PCI_REGION_TYPE_IO].base = 0xc000; -+static int pci_bios_init_root_regions_io(struct pci_bus *bus) -+{ -+ /* -+ * QEMU I/O address space usage: -+ * 0000 - 0fff legacy isa, pci config, pci root bus, ... -+ * 1000 - 9fff free -+ * a000 - afff hotplug (cpu, pci via acpi, i440fx/piix only) -+ * b000 - bfff power management (PORT_ACPI_PM_BASE) -+ * [ qemu 1.4+ implements pci config registers -+ * properly so guests can place the registers -+ * where they want, on older versions its fixed ] -+ * c000 - ffff free, traditionally used for pci io -+ */ -+ struct pci_region *r_io = &bus->r[PCI_REGION_TYPE_IO]; -+ u64 sum = pci_region_sum(r_io); -+ if (sum < 0x4000) { -+ /* traditional region is big enougth, use it */ -+ r_io->base = 0xc000; -+ } else if (sum < 0x9000) { -+ /* use the larger region at 0x1000 */ -+ r_io->base = 0x1000; -+ } else { -+ /* -+ * Not enougth io address space -> error out. -+ * -+ * TODO: on q35 we can move PORT_ACPI_PM_BASE out of -+ * the way, then use the whole 1000 -> ffff region. -+ */ -+ return -1; -+ } -+ dprintf(1, "PCI: IO: %4llx - %4llx\n", r_io->base, r_io->base + sum - 1); -+ return 0; -+} - -+static int pci_bios_init_root_regions_mem(struct pci_bus *bus) -+{ - struct pci_region *r_end = &bus->r[PCI_REGION_TYPE_PREFMEM]; - struct pci_region *r_start = &bus->r[PCI_REGION_TYPE_MEM]; - -@@ -744,8 +776,11 @@ static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r) - - static void pci_bios_map_devices(struct pci_bus *busses) - { -+ if (pci_bios_init_root_regions_io(busses)) -+ panic("PCI: out of I/O address space\n"); -+ - dprintf(1, "PCI: 32: %016llx - %016llx\n", pcimem_start, pcimem_end); -- if (pci_bios_init_root_regions(busses)) { -+ if (pci_bios_init_root_regions_mem(busses)) { - struct pci_region r64_mem, r64_pref; - r64_mem.list = NULL; - r64_pref.list = NULL; -@@ -754,7 +789,7 @@ static void pci_bios_map_devices(struct pci_bus *busses) - pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_PREFMEM], - &r64_pref); - -- if (pci_bios_init_root_regions(busses)) -+ if (pci_bios_init_root_regions_mem(busses)) - panic("PCI: out of 32bit address space\n"); - - u64 sum_mem = pci_region_sum(&r64_mem); --- -1.8.3.1 - diff --git a/SOURCES/seabios-pci-log-pci-windows.patch b/SOURCES/seabios-pci-log-pci-windows.patch deleted file mode 100644 index 3fa2b47..0000000 --- a/SOURCES/seabios-pci-log-pci-windows.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 231900b6da3959e36c364bb5733446891dfd171e Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 27 Jan 2014 15:31:27 -0500 -Subject: [PATCH 5/6] pci: log pci windows - -Message-id: <1390836688-16749-3-git-send-email-kraxel@redhat.com> -Patchwork-id: 56959 -O-Subject: [RHEL-7 seabios PATCH 2/3] pci: log pci windows -Bugzilla: 1055832 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Michael S. Tsirkin - -Signed-off-by: Gerd Hoffmann -(cherry picked from commit c72370ea3764bd009beb49ab3857a3953ed568de) ---- - src/pciinit.c | 2 ++ - 1 file changed, 2 insertions(+) - -Signed-off-by: Miroslav Rezanina ---- - src/pciinit.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/pciinit.c b/src/pciinit.c -index 15744e7..4e5d7d0 100644 ---- a/src/pciinit.c -+++ b/src/pciinit.c -@@ -744,6 +744,7 @@ static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r) - - static void pci_bios_map_devices(struct pci_bus *busses) - { -+ dprintf(1, "PCI: 32: %016llx - %016llx\n", pcimem_start, pcimem_end); - if (pci_bios_init_root_regions(busses)) { - struct pci_region r64_mem, r64_pref; - r64_mem.list = NULL; -@@ -770,6 +771,7 @@ static void pci_bios_map_devices(struct pci_bus *busses) - pcimem64_start = r64_mem.base; - pcimem64_end = r64_pref.base + sum_pref; - pcimem64_end = ALIGN(pcimem64_end, (1LL<<30)); // 1G hugepage -+ dprintf(1, "PCI: 64: %016llx - %016llx\n", pcimem64_start, pcimem64_end); - - pci_region_map_entries(busses, &r64_mem); - pci_region_map_entries(busses, &r64_pref); --- -1.8.3.1 - diff --git a/SOURCES/seabios-resume-restore-piix-pm-config-registers-after-resume.patch b/SOURCES/seabios-resume-restore-piix-pm-config-registers-after-resume.patch deleted file mode 100644 index f09452b..0000000 --- a/SOURCES/seabios-resume-restore-piix-pm-config-registers-after-resume.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 141d320f8763898865780ef07fe6e242279df6d1 Mon Sep 17 00:00:00 2001 -From: Laszlo Ersek -Date: Fri, 24 Jan 2014 18:50:34 -0500 -Subject: [PATCH 3/6] resume: restore piix pm config registers after resume - -Message-id: <1390589434-13326-2-git-send-email-lersek@redhat.com> -Patchwork-id: 56947 -O-Subject: [RHEL-7.0 seabios PATCH 1/1] resume: restore piix pm config registers after resume -Bugzilla: 1049860 -RH-Acked-by: Michael S. Tsirkin -RH-Acked-by: Gerd Hoffmann -RH-Acked-by: Marcel Apfelbaum - -From: Marcel Apfelbaum - -On resume, the OS queries the power management event that -caused it. In order to complete this task, it executes some -reads to the piix pm io space. This all happens before the -OS has a chance to restore the PCI config space for devices, -so it is bios's responsibility to make sure the pm IO space -is configured correctly. (During suspend, the piix pm -configuration space is lost). - -Note: For 'ordinary' pci devices the config space is -saved by the OS on sleep and restored on resume. - -Signed-off-by: Marcel Apfelbaum -Acked-by: Michael S. Tsirkin -(cherry picked from commit 40d020f56226aee7c75a6c29f471c4b866765732) - -Conflicts (mainly due to not having upstream d83c87b, "Normalize POST -initialization function name suffixes."): - - src/pciinit.c - src/resume.c - src/util.h - -Signed-off-by: Laszlo Ersek ---- - src/util.h | 1 + - src/pciinit.c | 26 ++++++++++++++++++++++---- - src/resume.c | 2 ++ - 3 files changed, 25 insertions(+), 4 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - src/pciinit.c | 26 ++++++++++++++++++++++---- - src/resume.c | 2 ++ - src/util.h | 1 + - 3 files changed, 25 insertions(+), 4 deletions(-) - -diff --git a/src/pciinit.c b/src/pciinit.c -index b3f359f..e501964 100644 ---- a/src/pciinit.c -+++ b/src/pciinit.c -@@ -225,10 +225,8 @@ static void apple_macio_init(struct pci_device *pci, void *arg) - pci_set_io_region_addr(pci, 0, 0x80800000, 0); - } - --/* PIIX4 Power Management device (for ACPI) */ --static void piix4_pm_init(struct pci_device *pci, void *arg) -+static void piix4_pm_config_setup(u16 bdf) - { -- u16 bdf = pci->bdf; - // acpi sci is hardwired to 9 - pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9); - -@@ -236,6 +234,15 @@ static void piix4_pm_init(struct pci_device *pci, void *arg) - pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */ - pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1); - pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */ -+} -+ -+static int PiixPmBDF = -1; -+ -+/* PIIX4 Power Management device (for ACPI) */ -+static void piix4_pm_setup(struct pci_device *pci, void *arg) -+{ -+ PiixPmBDF = pci->bdf; -+ piix4_pm_config_setup(pci->bdf); - - pmtimer_init(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000); - } -@@ -278,7 +285,7 @@ static const struct pci_device_id pci_device_tbl[] = { - - /* PIIX4 Power Management device (for ACPI) */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, -- piix4_pm_init), -+ piix4_pm_setup), - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_SMBUS, - ich9_smbus_init), - -@@ -289,6 +296,17 @@ static const struct pci_device_id pci_device_tbl[] = { - PCI_DEVICE_END, - }; - -+void pci_resume(void) -+{ -+ if (!CONFIG_QEMU) { -+ return; -+ } -+ -+ if (PiixPmBDF >= 0) { -+ piix4_pm_config_setup(PiixPmBDF); -+ } -+} -+ - static void pci_bios_init_device(struct pci_device *pci) - { - u16 bdf = pci->bdf; -diff --git a/src/resume.c b/src/resume.c -index f1a96ac..eed94aa 100644 ---- a/src/resume.c -+++ b/src/resume.c -@@ -111,6 +111,8 @@ s3_resume(void) - pic_setup(); - smm_init(); - -+ pci_resume(); -+ - s3_resume_vga_init(); - - make_bios_readonly(); -diff --git a/src/util.h b/src/util.h -index e46d298..59c0fcf 100644 ---- a/src/util.h -+++ b/src/util.h -@@ -317,6 +317,7 @@ void qemu_prep_reset(void); - // pciinit.c - extern const u8 pci_irqs[4]; - void pci_setup(void); -+void pci_resume(void); - - // smm.c - void smm_init(void); --- -1.8.3.1 - diff --git a/SOURCES/seabios-romfile_loader-utility-to-patch-in-memory-ROM-files.patch b/SOURCES/seabios-romfile_loader-utility-to-patch-in-memory-ROM-files.patch deleted file mode 100644 index 6364be2..0000000 --- a/SOURCES/seabios-romfile_loader-utility-to-patch-in-memory-ROM-files.patch +++ /dev/null @@ -1,319 +0,0 @@ -From b841f263ee4264333fcb571fcc4f7769040df90b Mon Sep 17 00:00:00 2001 -Message-Id: -In-Reply-To: -References: -From: "Michael S. Tsirkin" -Date: Wed, 11 Dec 2013 15:16:35 +0100 -Subject: [PATCH 2/3] romfile_loader: utility to patch in-memory ROM files - -RH-Author: Michael S. Tsirkin -Message-id: <1386774929-25693-3-git-send-email-mst@redhat.com> -Patchwork-id: 56225 -O-Subject: [RHEL7.0 seabios PATCH 2/3] romfile_loader: utility to patch in-memory ROM files -Bugzilla: 1034877 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Gerd Hoffmann -RH-Acked-by: Marcel Apfelbaum - -Add ability for a ROM file to point to -it's image in memory. When file is in memory, -add utility that can patch it, storing -pointers to one file within another file. - -This is not a lot of code: together with the follow-up patch to load -ACPI tables from ROM, it's about 1K extra. - -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Gerd Hoffmann -(cherry-picked from commit 4a02768fbbd33e263122bf5deb54382de56c1cfe) ---- - Makefile | 2 +- - src/romfile_loader.h | 72 +++++++++++++++++++++ - src/romfile_loader.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 246 insertions(+), 1 deletion(-) - create mode 100644 src/romfile_loader.h - create mode 100644 src/romfile_loader.c - -Signed-off-by: Michal Novotny ---- - Makefile | 2 +- - src/romfile_loader.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++ - src/romfile_loader.h | 72 +++++++++++++++++++++ - 3 files changed, 246 insertions(+), 1 deletion(-) - create mode 100644 src/romfile_loader.c - create mode 100644 src/romfile_loader.h - -diff --git a/Makefile b/Makefile -index f28d86c..9125ea0 100644 ---- a/Makefile -+++ b/Makefile -@@ -18,7 +18,7 @@ SRC16=$(SRCBOTH) system.c disk.c font.c - SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \ - acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \ - lzmadecode.c bootsplash.c jpeg.c usb-hub.c paravirt.c \ -- biostables.c xen.c bmp.c romfile.c -+ biostables.c xen.c bmp.c romfile.c romfile_loader.c - SRC32SEG=util.c output.c pci.c pcibios.c apm.c stacks.c - - # Default compiler flags -diff --git a/src/romfile_loader.c b/src/romfile_loader.c -new file mode 100644 -index 0000000..cae3cc3 ---- /dev/null -+++ b/src/romfile_loader.c -@@ -0,0 +1,173 @@ -+#include "romfile_loader.h" -+#include "byteorder.h" // leXX_to_cpu/cpu_to_leXX -+#include "util.h" -+ -+struct romfile_loader_file { -+ struct romfile_s *file; -+ void *data; -+}; -+struct romfile_loader_files { -+ int nfiles; -+ struct romfile_loader_file files[]; -+}; -+ -+static struct romfile_loader_file * -+romfile_loader_find(const char *name, -+ struct romfile_loader_files *files) -+{ -+ int i; -+ if (name[ROMFILE_LOADER_FILESZ - 1]) -+ return NULL; -+ for (i = 0; i < files->nfiles; ++i) -+ if (!strcmp(files->files[i].file->name, name)) -+ return &files->files[i]; -+ return NULL; -+} -+ -+static void romfile_loader_allocate(struct romfile_loader_entry_s *entry, -+ struct romfile_loader_files *files) -+{ -+ struct zone_s *zone; -+ struct romfile_loader_file *file = &files->files[files->nfiles]; -+ void *data; -+ int ret; -+ unsigned alloc_align = le32_to_cpu(entry->alloc_align); -+ -+ if (alloc_align & (alloc_align - 1)) -+ goto err; -+ -+ switch (entry->alloc_zone) { -+ case ROMFILE_LOADER_ALLOC_ZONE_HIGH: -+ zone = &ZoneHigh; -+ break; -+ case ROMFILE_LOADER_ALLOC_ZONE_FSEG: -+ zone = &ZoneFSeg; -+ break; -+ default: -+ goto err; -+ } -+ if (alloc_align < MALLOC_MIN_ALIGN) -+ alloc_align = MALLOC_MIN_ALIGN; -+ if (entry->alloc_file[ROMFILE_LOADER_FILESZ - 1]) -+ goto err; -+ file->file = romfile_find(entry->alloc_file); -+ if (!file->file || !file->file->size) -+ return; -+ data = pmm_malloc(zone, PMM_DEFAULT_HANDLE, file->file->size, alloc_align); -+ if (!data) { -+ warn_noalloc(); -+ return; -+ } -+ ret = file->file->copy(file->file, data, file->file->size); -+ if (ret != file->file->size) -+ goto file_err; -+ file->data = data; -+ files->nfiles++; -+ return; -+ -+file_err: -+ free(data); -+err: -+ warn_internalerror(); -+} -+ -+static void romfile_loader_add_pointer(struct romfile_loader_entry_s *entry, -+ struct romfile_loader_files *files) -+{ -+ struct romfile_loader_file *dest_file; -+ struct romfile_loader_file *src_file; -+ unsigned offset = le32_to_cpu(entry->pointer_offset); -+ u64 pointer = 0; -+ -+ dest_file = romfile_loader_find(entry->pointer_dest_file, files); -+ src_file = romfile_loader_find(entry->pointer_src_file, files); -+ -+ if (!dest_file || !src_file || !dest_file->data || !src_file->data || -+ offset + entry->pointer_size < offset || -+ offset + entry->pointer_size > dest_file->file->size || -+ entry->pointer_size < 1 || entry->pointer_size > 8 || -+ entry->pointer_size & (entry->pointer_size - 1)) -+ goto err; -+ -+ memcpy(&pointer, dest_file->data + offset, entry->pointer_size); -+ pointer = le64_to_cpu(pointer); -+ pointer += (unsigned long)src_file->data; -+ pointer = cpu_to_le64(pointer); -+ memcpy(dest_file->data + offset, &pointer, entry->pointer_size); -+ -+ return; -+err: -+ warn_internalerror(); -+} -+ -+static void romfile_loader_add_checksum(struct romfile_loader_entry_s *entry, -+ struct romfile_loader_files *files) -+{ -+ struct romfile_loader_file *file; -+ unsigned offset = le32_to_cpu(entry->cksum_offset); -+ unsigned start = le32_to_cpu(entry->cksum_start); -+ unsigned len = le32_to_cpu(entry->cksum_length); -+ u8 *data; -+ -+ file = romfile_loader_find(entry->cksum_file, files); -+ -+ if (!file || !file->data || offset >= file->file->size || -+ start + len < start || start + len > file->file->size) -+ goto err; -+ -+ data = file->data + offset; -+ *data -= checksum(file->data + start, len); -+ -+ return; -+err: -+ warn_internalerror(); -+} -+ -+int romfile_loader_execute(const char *name) -+{ -+ struct romfile_loader_entry_s *entry; -+ int size, offset = 0, nfiles; -+ struct romfile_loader_files *files; -+ void *data = romfile_loadfile(name, &size); -+ if (!data) -+ return -1; -+ -+ if (size % sizeof(*entry)) { -+ warn_internalerror(); -+ goto err; -+ } -+ -+ /* (over)estimate the number of files to load. */ -+ nfiles = size / sizeof(*entry); -+ files = malloc_tmp(sizeof(*files) + nfiles * sizeof(files->files[0])); -+ if (!files) { -+ warn_noalloc(); -+ goto err; -+ } -+ files->nfiles = 0; -+ -+ for (offset = 0; offset < size; offset += sizeof(*entry)) { -+ entry = data + offset; -+ switch (le32_to_cpu(entry->command)) { -+ case ROMFILE_LOADER_COMMAND_ALLOCATE: -+ romfile_loader_allocate(entry, files); -+ break; -+ case ROMFILE_LOADER_COMMAND_ADD_POINTER: -+ romfile_loader_add_pointer(entry, files); -+ break; -+ case ROMFILE_LOADER_COMMAND_ADD_CHECKSUM: -+ romfile_loader_add_checksum(entry, files); -+ default: -+ /* Skip commands that we don't recognize. */ -+ break; -+ } -+ } -+ -+ free(files); -+ free(data); -+ return 0; -+ -+err: -+ free(data); -+ return -1; -+} -diff --git a/src/romfile_loader.h b/src/romfile_loader.h -new file mode 100644 -index 0000000..15eab2a ---- /dev/null -+++ b/src/romfile_loader.h -@@ -0,0 +1,72 @@ -+#ifndef __ROMFILE_LOADER_H -+#define __ROMFILE_LOADER_H -+ -+#include "types.h" // u8 -+#include "util.h" // romfile_s -+ -+#define ROMFILE_LOADER_FILESZ 56 -+ -+/* ROM file linker/loader interface. Linker uses little endian format */ -+struct romfile_loader_entry_s { -+ u32 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 alloc_file[ROMFILE_LOADER_FILESZ]; -+ u32 alloc_align; -+ u8 alloc_zone; -+ }; -+ -+ /* -+ * 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 pointer_dest_file[ROMFILE_LOADER_FILESZ]; -+ char pointer_src_file[ROMFILE_LOADER_FILESZ]; -+ u32 pointer_offset; -+ u8 pointer_size; -+ }; -+ -+ /* -+ * 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 cksum_file[ROMFILE_LOADER_FILESZ]; -+ u32 cksum_offset; -+ u32 cksum_start; -+ u32 cksum_length; -+ }; -+ -+ /* padding */ -+ char pad[124]; -+ }; -+}; -+ -+enum { -+ ROMFILE_LOADER_COMMAND_ALLOCATE = 0x1, -+ ROMFILE_LOADER_COMMAND_ADD_POINTER = 0x2, -+ ROMFILE_LOADER_COMMAND_ADD_CHECKSUM = 0x3, -+}; -+ -+enum { -+ ROMFILE_LOADER_ALLOC_ZONE_HIGH = 0x1, -+ ROMFILE_LOADER_ALLOC_ZONE_FSEG = 0x2, -+}; -+ -+int romfile_loader_execute(const char *name); -+ -+#endif --- -1.7.11.7 - diff --git a/SOURCES/seabios-smbios-catch-zero-length-strings.patch b/SOURCES/seabios-smbios-catch-zero-length-strings.patch deleted file mode 100644 index 1913d36..0000000 --- a/SOURCES/seabios-smbios-catch-zero-length-strings.patch +++ /dev/null @@ -1,77 +0,0 @@ -From ba6951c82c8af1c9fd4669d8561517bd7850eeee Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 22 Jan 2014 09:32:53 -0500 -Subject: [PATCH 2/6] smbios: catch zero-length strings - -Message-id: <1390383173-24339-2-git-send-email-kraxel@redhat.com> -Patchwork-id: 56881 -O-Subject: [RHEL-7 seabios PATCH 1/1] smbios: catch zero-length strings -Bugzilla: 1052837 -RH-Acked-by: Markus Armbruster -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Igor Mammedov - -qemu may pass us zero-length strings for smbios fields, when starting -qemu this way ... - - qemu -smbios type=1,version=,serial=test - -... for example. - -Today we don't specifically handle them and simply append them to the -string list. Therefore we get two string-terminating zeros in a row. -Result is that we by accident create a end-of-entry marker in the middle -of the entry. - -Fix this by handling zero-length strings like non-present strings. - -Cc: armbru@redhat.com -Signed-off-by: Gerd Hoffmann -(cherry picked from commit 344496fae4bee9243be7f9719a60b01189c12f00) -Signed-off-by: Miroslav Rezanina - -Conflicts: - src/smbios.c ---- - src/smbios.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) ---- - src/smbios.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/src/smbios.c b/src/smbios.c -index 23713a2..4e6df14 100644 ---- a/src/smbios.c -+++ b/src/smbios.c -@@ -61,13 +61,17 @@ smbios_entry_point_init(u16 max_structure_size, - size = qemu_cfg_smbios_load_field(type, \ - offsetof(struct smbios_type_##type, \ - field), end); \ -- if (size > 0) { \ -+ if (size == 1) { \ -+ /* zero-length string, skip to avoid bogus end marker */ \ -+ p->field = 0; \ -+ } else if (size > 1) { \ - end += size; \ -+ p->field = ++str_index; \ - } else { \ - memcpy(end, def, sizeof(def)); \ - end += sizeof(def); \ -+ p->field = ++str_index; \ - } \ -- p->field = ++str_index; \ - } while (0) - - #define load_str_field_or_skip(type, field) \ -@@ -75,7 +79,7 @@ smbios_entry_point_init(u16 max_structure_size, - size = qemu_cfg_smbios_load_field(type, \ - offsetof(struct smbios_type_##type, \ - field), end); \ -- if (size > 0) { \ -+ if (size > 1) { \ - end += size; \ - p->field = ++str_index; \ - } else { \ --- -1.8.3.1 - diff --git a/SOURCES/seabios-smbios-set-bios-vendor-version-fields-to-Seabios-0.5.patch b/SOURCES/seabios-smbios-set-bios-vendor-version-fields-to-Seabios-0.5.patch index d564f17..f5bf3f0 100644 --- a/SOURCES/seabios-smbios-set-bios-vendor-version-fields-to-Seabios-0.5.patch +++ b/SOURCES/seabios-smbios-set-bios-vendor-version-fields-to-Seabios-0.5.patch @@ -1,12 +1,12 @@ -From e56e4275b3c4e8af573e9beb4b8d45f303e05ecd Mon Sep 17 00:00:00 2001 +From 1141076a607c566707186d5e6e317d79b16b2661 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann -Date: Mon, 28 Jul 2014 12:29:01 +0200 +Date: Mon, 28 Jul 2014 12:14:11 +0200 Subject: [PATCH] smbios: set bios vendor/version fields to Seabios/0.5.1 -Message-id: <1406550541-26947-2-git-send-email-kraxel@redhat.com> -Patchwork-id: 60265 -O-Subject: [RHEL-7.0.z seabios PATCH 1/1] smbios: set bios vendor/version fields to Seabios/0.5.1 -Bugzilla: 1124216 +Message-id: <1406549651-26021-2-git-send-email-kraxel@redhat.com> +Patchwork-id: 60264 +O-Subject: [RHEL-7.1 seabios PATCH 1/1] smbios: set bios vendor/version fields to Seabios/0.5.1 +Bugzilla: 1123299 RH-Acked-by: Miroslav Rezanina RH-Acked-by: Laszlo Ersek RH-Acked-by: Paolo Bonzini @@ -20,25 +20,21 @@ fill in the actual version information instead of the bogous 0.5.1 which we are using here for backward compatibility reasons. Signed-off-by: Gerd Hoffmann ---- - src/smbios.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - Signed-off-by: Miroslav Rezanina --- - src/smbios.c | 4 ++-- + src/fw/smbios.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) -diff --git a/src/smbios.c b/src/smbios.c -index 4e6df14..2ff4d98 100644 ---- a/src/smbios.c -+++ b/src/smbios.c -@@ -110,8 +110,8 @@ smbios_init_type_0(void *start) +diff --git a/src/fw/smbios.c b/src/fw/smbios.c +index dba0541..465b9ee 100644 +--- a/src/fw/smbios.c ++++ b/src/fw/smbios.c +@@ -174,8 +174,8 @@ smbios_init_type_0(void *start) p->header.length = sizeof(struct smbios_type_0); p->header.handle = 0; -- load_str_field_with_default(0, vendor_str, CONFIG_APPNAME); -- load_str_field_with_default(0, bios_version_str, CONFIG_APPNAME); +- load_str_field_with_default(0, vendor_str, BUILD_APPNAME); +- load_str_field_with_default(0, bios_version_str, BUILD_APPNAME); + load_str_field_with_default(0, vendor_str, "Seabios"); + load_str_field_with_default(0, bios_version_str, "0.5.1"); diff --git a/SOURCES/seabios-uas-add-temporary-superspeed-stopgap.patch b/SOURCES/seabios-uas-add-temporary-superspeed-stopgap.patch deleted file mode 100644 index 91eb4c7..0000000 --- a/SOURCES/seabios-uas-add-temporary-superspeed-stopgap.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 50c3f2680f910216492622858884acd5f1eba9d9 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 2 Oct 2013 07:00:16 +0200 -Subject: [PATCH 4/8] uas: add (temporary) superspeed stopgap - -RH-Author: Gerd Hoffmann -Message-id: <1380697219-1860-5-git-send-email-kraxel@redhat.com> -Patchwork-id: 54630 -O-Subject: [RHEL-7 seabios PATCH 4/7] uas: add (temporary) superspeed stopgap -Bugzilla: 947051 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Bandan Das -RH-Acked-by: Miroslav Rezanina - -Signed-off-by: Gerd Hoffmann -(cherry picked from commit ee9b84f61c55a67b477a019e937460be13ccbfa1) ---- - src/usb-uas.c | 4 ++++ - src/usb.h | 1 + - 2 files changed, 5 insertions(+) - -Signed-off-by: Miroslav Rezanina ---- - src/usb-uas.c | 4 ++++ - src/usb.h | 1 + - 2 files changed, 5 insertions(+), 0 deletions(-) - -diff --git a/src/usb-uas.c b/src/usb-uas.c -index be153ed..2133c0e 100644 ---- a/src/usb-uas.c -+++ b/src/usb-uas.c -@@ -220,6 +220,10 @@ usb_uas_init(struct usbdevice_s *usbdev) - case USB_DT_ENDPOINT: - ep = (void*)desc; - break; -+ case USB_DT_ENDPOINT_COMPANION: -+ /* No support (yet) for usb3 streams */ -+ dprintf(1, "Superspeed UAS devices not supported (yet)\n"); -+ goto fail; - case 0x24: - switch (desc[2]) { - case UAS_PIPE_ID_COMMAND: -diff --git a/src/usb.h b/src/usb.h -index a43e829..d9eadd7 100644 ---- a/src/usb.h -+++ b/src/usb.h -@@ -130,6 +130,7 @@ struct usb_ctrlrequest { - #define USB_DT_ENDPOINT 0x05 - #define USB_DT_DEVICE_QUALIFIER 0x06 - #define USB_DT_OTHER_SPEED_CONFIG 0x07 -+#define USB_DT_ENDPOINT_COMPANION 0x30 - - struct usb_device_descriptor { - u8 bLength; --- -1.7.1 - diff --git a/SOURCES/seabios-usb-add-usb_update_pipe.patch b/SOURCES/seabios-usb-add-usb_update_pipe.patch deleted file mode 100644 index 86f26da..0000000 --- a/SOURCES/seabios-usb-add-usb_update_pipe.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0966143d780d669d8208ab2ac77254fb20f779d2 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 2 Oct 2013 07:00:17 +0200 -Subject: [PATCH 5/8] usb: add usb_update_pipe() - -RH-Author: Gerd Hoffmann -Message-id: <1380697219-1860-6-git-send-email-kraxel@redhat.com> -Patchwork-id: 54632 -O-Subject: [RHEL-7 seabios PATCH 5/7] usb: add usb_update_pipe() -Bugzilla: 947051 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Bandan Das -RH-Acked-by: Miroslav Rezanina - -Preparation for better xhci support: allows to notify host controllers -instead of going through a free+alloc cycle. - -Signed-off-by: Gerd Hoffmann -(cherry picked from commit 63cbab1628dc406ed5d765bd85bae3a1a525a2c0) ---- - src/usb.c | 22 +++++++++++++++++----- - 1 file changed, 17 insertions(+), 5 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - src/usb.c | 22 +++++++++++++++++----- - 1 files changed, 17 insertions(+), 5 deletions(-) - -diff --git a/src/usb.c b/src/usb.c -index 421d0b8..3efa367 100644 ---- a/src/usb.c -+++ b/src/usb.c -@@ -40,6 +40,18 @@ usb_alloc_pipe(struct usbdevice_s *usbdev - } - } - -+// Update an pipe (used for control only) -+struct usb_pipe * -+usb_update_pipe(struct usbdevice_s *usbdev, struct usb_pipe *pipe -+ , struct usb_endpoint_descriptor *epdesc) -+{ -+ switch (usbdev->hub->cntl->type) { -+ default: -+ free_pipe(pipe); -+ return usb_alloc_pipe(usbdev, epdesc); -+ } -+} -+ - // Send a message on a control pipe using the default control descriptor. - static int - send_control(struct usb_pipe *pipe, int dir, const void *cmd, int cmdsize -@@ -258,15 +270,16 @@ usb_set_address(struct usbdevice_s *usbdev) - req.wIndex = 0; - req.wLength = 0; - int ret = send_default_control(usbdev->defpipe, &req, NULL); -- free_pipe(usbdev->defpipe); -- if (ret) -+ if (ret) { -+ free_pipe(usbdev->defpipe); - return -1; -+ } - - msleep(USB_TIME_SETADDR_RECOVERY); - - cntl->maxaddr++; - usbdev->devaddr = cntl->maxaddr; -- usbdev->defpipe = usb_alloc_pipe(usbdev, &epdesc); -+ usbdev->defpipe = usb_update_pipe(usbdev, usbdev->defpipe, &epdesc); - if (!usbdev->defpipe) - return -1; - return 0; -@@ -290,12 +303,11 @@ configure_usb_device(struct usbdevice_s *usbdev) - , dinfo.bDeviceProtocol, dinfo.bMaxPacketSize0); - if (dinfo.bMaxPacketSize0 < 8 || dinfo.bMaxPacketSize0 > 64) - return 0; -- free_pipe(usbdev->defpipe); - struct usb_endpoint_descriptor epdesc = { - .wMaxPacketSize = dinfo.bMaxPacketSize0, - .bmAttributes = USB_ENDPOINT_XFER_CONTROL, - }; -- usbdev->defpipe = usb_alloc_pipe(usbdev, &epdesc); -+ usbdev->defpipe = usb_update_pipe(usbdev, usbdev->defpipe, &epdesc); - if (!usbdev->defpipe) - return -1; - --- -1.7.1 - diff --git a/SOURCES/seabios-usb-add-xhci-support.patch b/SOURCES/seabios-usb-add-xhci-support.patch deleted file mode 100644 index d047843..0000000 --- a/SOURCES/seabios-usb-add-xhci-support.patch +++ /dev/null @@ -1,1472 +0,0 @@ -From c1d503b5c244efa1daf29fa297314e7cc82175af Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 2 Oct 2013 07:00:18 +0200 -Subject: [PATCH 6/8] usb: add xhci support - -RH-Author: Gerd Hoffmann -Message-id: <1380697219-1860-7-git-send-email-kraxel@redhat.com> -Patchwork-id: 54633 -O-Subject: [RHEL-7 seabios PATCH 6/7] usb: add xhci support -Bugzilla: 947051 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Bandan Das -RH-Acked-by: Miroslav Rezanina - -$subject says all. Support for usb3 streams is not implemented yet, -otherwise it is fully functional. Tested all usb devices supported -by qemu (keyboard, storage, usb hubs), except for usb attached scsi -in usb3 mode (which needs streams). - -Tested on qemu only, tagged with QEMU_HARDWARE because of that. -Testing with physical hardware to be done. - -Signed-off-by: Gerd Hoffmann -(cherry picked from commit e144bb7af49ca8756b7222a75811f3b85b0bc1f5) - -Conflicts: - Makefile - src/usb.c ---- - Makefile | 2 +- - src/Kconfig | 6 + - src/pci_ids.h | 1 + - src/usb-xhci.c | 1124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/usb-xhci.h | 144 ++++++++ - src/usb.c | 13 + - src/usb.h | 16 +- - 7 files changed, 1298 insertions(+), 8 deletions(-) - create mode 100644 src/usb-xhci.c - create mode 100644 src/usb-xhci.h - -Signed-off-by: Miroslav Rezanina ---- - Makefile | 2 +- - src/Kconfig | 6 + - src/pci_ids.h | 1 + - src/usb-xhci.c | 1124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/usb-xhci.h | 144 ++++++++ - src/usb.c | 13 + - src/usb.h | 16 +- - 7 files changed, 1298 insertions(+), 8 deletions(-) - create mode 100644 src/usb-xhci.c - create mode 100644 src/usb-xhci.h - -diff --git a/Makefile b/Makefile -index 20da6d0..409aefa 100644 ---- a/Makefile -+++ b/Makefile -@@ -11,7 +11,7 @@ OUT=out/ - SRCBOTH=misc.c stacks.c pmm.c output.c util.c block.c floppy.c ata.c mouse.c \ - kbd.c pci.c serial.c clock.c pic.c cdrom.c ps2port.c smp.c resume.c \ - pnpbios.c pirtable.c vgahooks.c ramdisk.c pcibios.c blockcmd.c \ -- usb.c usb-uhci.c usb-ohci.c usb-ehci.c usb-hid.c usb-msc.c \ -+ usb.c usb-uhci.c usb-ohci.c usb-ehci.c usb-xhci.c usb-hid.c usb-msc.c \ - virtio-ring.c virtio-pci.c virtio-blk.c virtio-scsi.c apm.c ahci.c \ - usb-uas.c lsi-scsi.c esp-scsi.c megasas.c - SRC16=$(SRCBOTH) system.c disk.c font.c -diff --git a/src/Kconfig b/src/Kconfig -index 2c9100d..b059a73 100644 ---- a/src/Kconfig -+++ b/src/Kconfig -@@ -184,6 +184,12 @@ menu "Hardware support" - default y - help - Support USB EHCI controllers. -+ config USB_XHCI -+ depends on USB && QEMU_HARDWARE -+ bool "USB XHCI controllers" -+ default y -+ help -+ Support USB XHCI controllers. - config USB_MSC - depends on USB && DRIVES - bool "USB drives" -diff --git a/src/pci_ids.h b/src/pci_ids.h -index 665e945..322d156 100644 ---- a/src/pci_ids.h -+++ b/src/pci_ids.h -@@ -104,6 +104,7 @@ - #define PCI_CLASS_SERIAL_USB_UHCI 0x0c0300 - #define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310 - #define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320 -+#define PCI_CLASS_SERIAL_USB_XHCI 0x0c0330 - #define PCI_CLASS_SERIAL_FIBER 0x0c04 - #define PCI_CLASS_SERIAL_SMBUS 0x0c05 - -diff --git a/src/usb-xhci.c b/src/usb-xhci.c -new file mode 100644 -index 0000000..5be0b25 ---- /dev/null -+++ b/src/usb-xhci.c -@@ -0,0 +1,1124 @@ -+#include "config.h" // CONFIG_* -+#include "util.h" // timer_calc -+#include "pci.h" // pci_bdf_to_bus -+#include "pci_regs.h" // PCI_BASE_ADDRESS_0 -+#include "usb.h" // struct usb_s -+#include "usb-xhci.h" // struct ehci_qh -+#include "biosvar.h" // GET_LOWFLAT -+ -+// -------------------------------------------------------------- -+// configuration -+ -+#define XHCI_RING_ITEMS 16 -+#define XHCI_RING_SIZE (XHCI_RING_ITEMS*sizeof(struct xhci_trb)) -+ -+/* -+ * xhci_ring structs are allocated with XHCI_RING_SIZE alignment, -+ * then we can get it from a trb pointer (provided by evt ring). -+ */ -+#define XHCI_RING(_trb) \ -+ ((struct xhci_ring*)((u32)(_trb) & ~(XHCI_RING_SIZE-1))) -+ -+// -------------------------------------------------------------- -+// bit definitions -+ -+#define XHCI_CMD_RS (1<<0) -+#define XHCI_CMD_HCRST (1<<1) -+#define XHCI_CMD_INTE (1<<2) -+#define XHCI_CMD_HSEE (1<<3) -+#define XHCI_CMD_LHCRST (1<<7) -+#define XHCI_CMD_CSS (1<<8) -+#define XHCI_CMD_CRS (1<<9) -+#define XHCI_CMD_EWE (1<<10) -+#define XHCI_CMD_EU3S (1<<11) -+ -+#define XHCI_STS_HCH (1<<0) -+#define XHCI_STS_HSE (1<<2) -+#define XHCI_STS_EINT (1<<3) -+#define XHCI_STS_PCD (1<<4) -+#define XHCI_STS_SSS (1<<8) -+#define XHCI_STS_RSS (1<<9) -+#define XHCI_STS_SRE (1<<10) -+#define XHCI_STS_CNR (1<<11) -+#define XHCI_STS_HCE (1<<12) -+ -+#define XHCI_PORTSC_CCS (1<<0) -+#define XHCI_PORTSC_PED (1<<1) -+#define XHCI_PORTSC_OCA (1<<3) -+#define XHCI_PORTSC_PR (1<<4) -+#define XHCI_PORTSC_PLS_SHIFT 5 -+#define XHCI_PORTSC_PLS_MASK 0xf -+#define XHCI_PORTSC_PP (1<<9) -+#define XHCI_PORTSC_SPEED_SHIFT 10 -+#define XHCI_PORTSC_SPEED_MASK 0xf -+#define XHCI_PORTSC_SPEED_FULL (1<<10) -+#define XHCI_PORTSC_SPEED_LOW (2<<10) -+#define XHCI_PORTSC_SPEED_HIGH (3<<10) -+#define XHCI_PORTSC_SPEED_SUPER (4<<10) -+#define XHCI_PORTSC_PIC_SHIFT 14 -+#define XHCI_PORTSC_PIC_MASK 0x3 -+#define XHCI_PORTSC_LWS (1<<16) -+#define XHCI_PORTSC_CSC (1<<17) -+#define XHCI_PORTSC_PEC (1<<18) -+#define XHCI_PORTSC_WRC (1<<19) -+#define XHCI_PORTSC_OCC (1<<20) -+#define XHCI_PORTSC_PRC (1<<21) -+#define XHCI_PORTSC_PLC (1<<22) -+#define XHCI_PORTSC_CEC (1<<23) -+#define XHCI_PORTSC_CAS (1<<24) -+#define XHCI_PORTSC_WCE (1<<25) -+#define XHCI_PORTSC_WDE (1<<26) -+#define XHCI_PORTSC_WOE (1<<27) -+#define XHCI_PORTSC_DR (1<<30) -+#define XHCI_PORTSC_WPR (1<<31) -+ -+#define TRB_C (1<<0) -+#define TRB_TYPE_SHIFT 10 -+#define TRB_TYPE_MASK 0x3f -+#define TRB_TYPE(t) (((t) >> TRB_TYPE_SHIFT) & TRB_TYPE_MASK) -+ -+#define TRB_EV_ED (1<<2) -+ -+#define TRB_TR_ENT (1<<1) -+#define TRB_TR_ISP (1<<2) -+#define TRB_TR_NS (1<<3) -+#define TRB_TR_CH (1<<4) -+#define TRB_TR_IOC (1<<5) -+#define TRB_TR_IDT (1<<6) -+#define TRB_TR_TBC_SHIFT 7 -+#define TRB_TR_TBC_MASK 0x3 -+#define TRB_TR_BEI (1<<9) -+#define TRB_TR_TLBPC_SHIFT 16 -+#define TRB_TR_TLBPC_MASK 0xf -+#define TRB_TR_FRAMEID_SHIFT 20 -+#define TRB_TR_FRAMEID_MASK 0x7ff -+#define TRB_TR_SIA (1<<31) -+ -+#define TRB_TR_DIR (1<<16) -+ -+#define TRB_CR_SLOTID_SHIFT 24 -+#define TRB_CR_SLOTID_MASK 0xff -+#define TRB_CR_EPID_SHIFT 16 -+#define TRB_CR_EPID_MASK 0x1f -+ -+#define TRB_CR_BSR (1<<9) -+#define TRB_CR_DC (1<<9) -+ -+#define TRB_LK_TC (1<<1) -+ -+#define TRB_INTR_SHIFT 22 -+#define TRB_INTR_MASK 0x3ff -+#define TRB_INTR(t) (((t).status >> TRB_INTR_SHIFT) & TRB_INTR_MASK) -+ -+typedef enum TRBType { -+ TRB_RESERVED = 0, -+ TR_NORMAL, -+ TR_SETUP, -+ TR_DATA, -+ TR_STATUS, -+ TR_ISOCH, -+ TR_LINK, -+ TR_EVDATA, -+ TR_NOOP, -+ CR_ENABLE_SLOT, -+ CR_DISABLE_SLOT, -+ CR_ADDRESS_DEVICE, -+ CR_CONFIGURE_ENDPOINT, -+ CR_EVALUATE_CONTEXT, -+ CR_RESET_ENDPOINT, -+ CR_STOP_ENDPOINT, -+ CR_SET_TR_DEQUEUE, -+ CR_RESET_DEVICE, -+ CR_FORCE_EVENT, -+ CR_NEGOTIATE_BW, -+ CR_SET_LATENCY_TOLERANCE, -+ CR_GET_PORT_BANDWIDTH, -+ CR_FORCE_HEADER, -+ CR_NOOP, -+ ER_TRANSFER = 32, -+ ER_COMMAND_COMPLETE, -+ ER_PORT_STATUS_CHANGE, -+ ER_BANDWIDTH_REQUEST, -+ ER_DOORBELL, -+ ER_HOST_CONTROLLER, -+ ER_DEVICE_NOTIFICATION, -+ ER_MFINDEX_WRAP, -+} TRBType; -+ -+typedef enum TRBCCode { -+ CC_INVALID = 0, -+ CC_SUCCESS, -+ CC_DATA_BUFFER_ERROR, -+ CC_BABBLE_DETECTED, -+ CC_USB_TRANSACTION_ERROR, -+ CC_TRB_ERROR, -+ CC_STALL_ERROR, -+ CC_RESOURCE_ERROR, -+ CC_BANDWIDTH_ERROR, -+ CC_NO_SLOTS_ERROR, -+ CC_INVALID_STREAM_TYPE_ERROR, -+ CC_SLOT_NOT_ENABLED_ERROR, -+ CC_EP_NOT_ENABLED_ERROR, -+ CC_SHORT_PACKET, -+ CC_RING_UNDERRUN, -+ CC_RING_OVERRUN, -+ CC_VF_ER_FULL, -+ CC_PARAMETER_ERROR, -+ CC_BANDWIDTH_OVERRUN, -+ CC_CONTEXT_STATE_ERROR, -+ CC_NO_PING_RESPONSE_ERROR, -+ CC_EVENT_RING_FULL_ERROR, -+ CC_INCOMPATIBLE_DEVICE_ERROR, -+ CC_MISSED_SERVICE_ERROR, -+ CC_COMMAND_RING_STOPPED, -+ CC_COMMAND_ABORTED, -+ CC_STOPPED, -+ CC_STOPPED_LENGTH_INVALID, -+ CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR = 29, -+ CC_ISOCH_BUFFER_OVERRUN = 31, -+ CC_EVENT_LOST_ERROR, -+ CC_UNDEFINED_ERROR, -+ CC_INVALID_STREAM_ID_ERROR, -+ CC_SECONDARY_BANDWIDTH_ERROR, -+ CC_SPLIT_TRANSACTION_ERROR -+} TRBCCode; -+ -+enum { -+ PLS_U0 = 0, -+ PLS_U1 = 1, -+ PLS_U2 = 2, -+ PLS_U3 = 3, -+ PLS_DISABLED = 4, -+ PLS_RX_DETECT = 5, -+ PLS_INACTIVE = 6, -+ PLS_POLLING = 7, -+ PLS_RECOVERY = 8, -+ PLS_HOT_RESET = 9, -+ PLS_COMPILANCE_MODE = 10, -+ PLS_TEST_MODE = 11, -+ PLS_RESUME = 15, -+}; -+ -+#define xhci_get_field(data, field) \ -+ (((data) >> field##_SHIFT) & field##_MASK) -+ -+// -------------------------------------------------------------- -+// state structs -+ -+struct xhci_ring { -+ struct xhci_trb ring[XHCI_RING_ITEMS]; -+ struct xhci_trb evt; -+ u32 eidx; -+ u32 nidx; -+ u32 cs; -+ struct mutex_s lock; -+}; -+ -+struct usb_xhci_s { -+ struct usb_s usb; -+ struct usbhub_s hub; -+ -+ /* devinfo */ -+ u32 baseaddr; -+ u32 xcap; -+ u32 ports; -+ u32 slots; -+ -+ /* xhci registers */ -+ struct xhci_caps *caps; -+ struct xhci_op *op; -+ struct xhci_pr *pr; -+ struct xhci_ir *ir; -+ struct xhci_db *db; -+ -+ /* xhci data structures */ -+ struct xhci_devlist *devs; -+ struct xhci_ring *cmds; -+ struct xhci_ring *evts; -+ struct xhci_er_seg *eseg; -+ -+ /* usb devices */ -+ struct hlist_head list; -+}; -+ -+struct xhci_device { -+ struct xhci_devctx devctx; -+ struct xhci_inctx inctx; -+ -+ struct usbdevice_s *usbdev; -+ struct usb_xhci_s *xhci; -+ u32 slotid; -+ struct hlist_node next; -+}; -+ -+struct xhci_pipe { -+ struct xhci_ring reqs; -+ -+ struct usb_pipe pipe; -+ struct xhci_device *dev; -+ u32 epid; -+ void *buf; -+ int bufused; -+}; -+ -+// -------------------------------------------------------------- -+// tables -+ -+static const char *speed_name[16] = { -+ [ 0 ] = " - ", -+ [ 1 ] = "Full", -+ [ 2 ] = "Low", -+ [ 3 ] = "High", -+ [ 4 ] = "Super", -+}; -+ -+static const int speed_from_xhci[16] = { -+ [ 0 ... 15 ] = -1, -+ [ 1 ] = USB_FULLSPEED, -+ [ 2 ] = USB_LOWSPEED, -+ [ 3 ] = USB_HIGHSPEED, -+ [ 4 ] = USB_SUPERSPEED, -+}; -+ -+static const int speed_to_xhci[] = { -+ [ USB_FULLSPEED ] = 1, -+ [ USB_LOWSPEED ] = 2, -+ [ USB_HIGHSPEED ] = 3, -+ [ USB_SUPERSPEED ] = 4, -+}; -+ -+static const int speed_to_ctlsize[] = { -+ [ USB_FULLSPEED ] = 8, -+ [ USB_LOWSPEED ] = 8, -+ [ USB_HIGHSPEED ] = 64, -+ [ USB_SUPERSPEED ] = 256, -+}; -+ -+static const int eptype_to_xhci_in[] = { -+ [ USB_ENDPOINT_XFER_CONTROL] = 4, -+ [ USB_ENDPOINT_XFER_ISOC ] = 5, -+ [ USB_ENDPOINT_XFER_BULK ] = 6, -+ [ USB_ENDPOINT_XFER_INT ] = 7, -+}; -+ -+static const int eptype_to_xhci_out[] = { -+ [ USB_ENDPOINT_XFER_CONTROL] = 4, -+ [ USB_ENDPOINT_XFER_ISOC ] = 1, -+ [ USB_ENDPOINT_XFER_BULK ] = 2, -+ [ USB_ENDPOINT_XFER_INT ] = 3, -+}; -+ -+// -------------------------------------------------------------- -+// internal functions, 16bit + 32bit -+ -+static void xhci_doorbell(struct usb_xhci_s *xhci, u32 slotid, u32 value) -+{ -+ struct xhci_db *db = GET_LOWFLAT(xhci->db); -+ u32 addr = (u32)(&db[slotid].doorbell); -+ pci_writel(addr, value); -+} -+ -+static void xhci_process_events(struct usb_xhci_s *xhci) -+{ -+ struct xhci_ring *evts = GET_LOWFLAT(xhci->evts); -+ -+ for (;;) { -+ /* check for event */ -+ u32 nidx = GET_LOWFLAT(evts->nidx); -+ u32 cs = GET_LOWFLAT(evts->cs); -+ struct xhci_trb *etrb = evts->ring + nidx; -+ u32 control = GET_LOWFLAT(etrb->control); -+ if ((control & TRB_C) != (cs ? 1 : 0)) -+ return; -+ -+ /* process event */ -+ u32 evt_type = TRB_TYPE(control); -+ u32 evt_cc = (GET_LOWFLAT(etrb->status) >> 24) & 0xff; -+ switch (evt_type) { -+ case ER_TRANSFER: -+ case ER_COMMAND_COMPLETE: -+ { -+ struct xhci_trb *rtrb = (void*)GET_LOWFLAT(etrb->ptr_low); -+ struct xhci_ring *ring = XHCI_RING(rtrb); -+ struct xhci_trb *evt = &ring->evt; -+ u32 eidx = rtrb - ring->ring + 1; -+ dprintf(5, "%s: ring %p [trb %p, evt %p, type %d, eidx %d, cc %d]\n", -+ __func__, ring, rtrb, evt, evt_type, eidx, evt_cc); -+ memcpy_fl(evt, etrb, sizeof(*etrb)); -+ SET_LOWFLAT(ring->eidx, eidx); -+ break; -+ } -+ case ER_PORT_STATUS_CHANGE: -+ { -+ u32 portid = (GET_LOWFLAT(etrb->ptr_low) >> 24) & 0xff; -+ dprintf(3, "%s: status change port #%d\n", -+ __func__, portid); -+ break; -+ } -+ default: -+ dprintf(1, "%s: unknown event, type %d, cc %d\n", -+ __func__, evt_type, evt_cc); -+ break; -+ } -+ -+ /* move ring index, notify xhci */ -+ nidx++; -+ if (nidx == XHCI_RING_ITEMS) { -+ nidx = 0; -+ cs = cs ? 0 : 1; -+ SET_LOWFLAT(evts->cs, cs); -+ } -+ SET_LOWFLAT(evts->nidx, nidx); -+ struct xhci_ir *ir = GET_LOWFLAT(xhci->ir); -+ u32 addr = (u32)(&ir->erdp_low); -+ u32 erdp = (u32)(evts->ring + nidx); -+ pci_writel(addr, erdp); -+ } -+} -+ -+static int xhci_ring_busy(struct xhci_ring *ring) -+{ -+ u32 eidx = GET_LOWFLAT(ring->eidx); -+ u32 nidx = GET_LOWFLAT(ring->nidx); -+ return (eidx != nidx); -+} -+ -+static int xhci_event_wait(struct usb_xhci_s *xhci, -+ struct xhci_ring *ring, -+ u32 timeout) -+{ -+ u32 end = timer_calc(timeout); -+ -+ for (;;) { -+ xhci_process_events(xhci); -+ if (!xhci_ring_busy(ring)) { -+ u32 status = GET_LOWFLAT(ring->evt.status); -+ return (status >> 24) & 0xff; -+ } -+ if (timer_check(end)) { -+ warn_timeout(); -+ return -1; -+ } -+ yield(); -+ } -+} -+ -+static void xhci_trb_queue(struct xhci_ring *ring, -+ struct xhci_trb *trb) -+{ -+ u32 nidx = GET_LOWFLAT(ring->nidx); -+ u32 cs = GET_LOWFLAT(ring->cs); -+ struct xhci_trb *dst; -+ u32 control; -+ -+ if (nidx == XHCI_RING_ITEMS-1) { -+ dst = ring->ring + nidx; -+ control = (TR_LINK << 10); // trb type -+ control |= TRB_LK_TC; -+ control |= (cs ? TRB_C : 0); -+ SET_LOWFLAT(dst->ptr_low, (u32)&ring[0]); -+ SET_LOWFLAT(dst->ptr_high, 0); -+ SET_LOWFLAT(dst->status, 0); -+ SET_LOWFLAT(dst->control, control); -+ nidx = 0; -+ cs = cs ? 0 : 1; -+ SET_LOWFLAT(ring->nidx, nidx); -+ SET_LOWFLAT(ring->cs, cs); -+ -+ dprintf(5, "%s: ring %p [linked]\n", __func__, ring); -+ } -+ -+ dst = ring->ring + nidx; -+ control = GET_LOWFLAT(trb->control) | (cs ? TRB_C : 0); -+ -+ SET_LOWFLAT(dst->ptr_low, GET_LOWFLAT(trb->ptr_low)); -+ SET_LOWFLAT(dst->ptr_high, GET_LOWFLAT(trb->ptr_high)); -+ SET_LOWFLAT(dst->status, GET_LOWFLAT(trb->status)); -+ SET_LOWFLAT(dst->control, control); -+ nidx++; -+ SET_LOWFLAT(ring->nidx, nidx); -+ -+ dprintf(5, "%s: ring %p [nidx %d, len %d]\n", -+ __func__, ring, nidx, -+ GET_LOWFLAT(trb->status) & 0xffff); -+} -+ -+static void xhci_xfer_queue(struct xhci_pipe *pipe, -+ struct xhci_trb *trb) -+{ -+ xhci_trb_queue(&pipe->reqs, trb); -+} -+ -+static void xhci_xfer_kick(struct xhci_pipe *pipe) -+{ -+ struct xhci_device *dev = GET_LOWFLAT(pipe->dev); -+ struct usb_xhci_s *xhci = GET_LOWFLAT(dev->xhci); -+ u32 slotid = GET_LOWFLAT(dev->slotid); -+ u32 epid = GET_LOWFLAT(pipe->epid); -+ -+ dprintf(5, "%s: ring %p, slotid %d, epid %d\n", -+ __func__, &pipe->reqs, slotid, epid); -+ xhci_doorbell(xhci, slotid, epid); -+} -+ -+static void xhci_xfer_normal(struct xhci_pipe *pipe, -+ void *data, int datalen) -+{ -+ struct xhci_trb trb; -+ -+ memset(&trb, 0, sizeof(trb)); -+ trb.ptr_low = (u32)data; -+ trb.status = datalen; -+ trb.control |= (TR_NORMAL << 10); // trb type -+ trb.control |= TRB_TR_IOC; -+ -+ xhci_xfer_queue(pipe, MAKE_FLATPTR(GET_SEG(SS), &trb)); -+ xhci_xfer_kick(pipe); -+} -+ -+// -------------------------------------------------------------- -+// internal functions, pure 32bit -+ -+static int wait_bit(u32 *reg, u32 mask, int value, u32 timeout) -+{ -+ ASSERT32FLAT(); -+ u32 end = timer_calc(timeout); -+ -+ while ((readl(reg) & mask) != value) { -+ if (timer_check(end)) { -+ warn_timeout(); -+ return -1; -+ } -+ yield(); -+ } -+ return 0; -+} -+ -+static int xhci_cmd_submit(struct usb_xhci_s *xhci, -+ struct xhci_trb *cmd) -+{ -+ ASSERT32FLAT(); -+ int rc; -+ -+ mutex_lock(&xhci->cmds->lock); -+ xhci_trb_queue(xhci->cmds, cmd); -+ xhci_doorbell(xhci, 0, 0); -+ rc = xhci_event_wait(xhci, xhci->cmds, 1000); -+ mutex_unlock(&xhci->cmds->lock); -+ return rc; -+} -+ -+static int xhci_cmd_enable_slot(struct usb_xhci_s *xhci) -+{ -+ ASSERT32FLAT(); -+ struct xhci_trb cmd = { -+ .ptr_low = 0, -+ .ptr_high = 0, -+ .status = 0, -+ .control = (CR_ENABLE_SLOT << 10) -+ }; -+ dprintf(3, "%s:\n", __func__); -+ int cc = xhci_cmd_submit(xhci, &cmd); -+ if (cc != CC_SUCCESS) -+ return -1; -+ return (xhci->cmds->evt.control >> 24) & 0xff; -+} -+ -+static int xhci_cmd_disable_slot(struct xhci_device *dev) -+{ -+ ASSERT32FLAT(); -+ struct xhci_trb cmd = { -+ .ptr_low = 0, -+ .ptr_high = 0, -+ .status = 0, -+ .control = (dev->slotid << 24) | (CR_DISABLE_SLOT << 10) -+ }; -+ dprintf(3, "%s: slotid %d\n", __func__, dev->slotid); -+ return xhci_cmd_submit(dev->xhci, &cmd); -+} -+ -+static int xhci_cmd_address_device(struct xhci_device *dev) -+{ -+ ASSERT32FLAT(); -+ struct xhci_trb cmd = { -+ .ptr_low = (u32)&dev->inctx, -+ .ptr_high = 0, -+ .status = 0, -+ .control = (dev->slotid << 24) | (CR_ADDRESS_DEVICE << 10) -+ }; -+ dprintf(3, "%s: slotid %d\n", __func__, dev->slotid); -+ return xhci_cmd_submit(dev->xhci, &cmd); -+} -+ -+static int xhci_cmd_configure_endpoint(struct xhci_device *dev) -+{ -+ ASSERT32FLAT(); -+ struct xhci_trb cmd = { -+ .ptr_low = (u32)&dev->inctx, -+ .ptr_high = 0, -+ .status = 0, -+ .control = (dev->slotid << 24) | (CR_CONFIGURE_ENDPOINT << 10) -+ }; -+ dprintf(3, "%s: slotid %d, add 0x%x, del 0x%x\n", __func__, -+ dev->slotid, dev->inctx.add, dev->inctx.del); -+ return xhci_cmd_submit(dev->xhci, &cmd); -+} -+ -+static int xhci_cmd_evaluate_context(struct xhci_device *dev) -+{ -+ ASSERT32FLAT(); -+ struct xhci_trb cmd = { -+ .ptr_low = (u32)&dev->inctx, -+ .ptr_high = 0, -+ .status = 0, -+ .control = (dev->slotid << 24) | (CR_EVALUATE_CONTEXT << 10) -+ }; -+ dprintf(3, "%s: slotid %d, add 0x%x, del 0x%x\n", __func__, -+ dev->slotid, dev->inctx.add, dev->inctx.del); -+ return xhci_cmd_submit(dev->xhci, &cmd); -+} -+ -+static void xhci_xfer_setup(struct xhci_pipe *pipe, -+ const struct usb_ctrlrequest *req, -+ int dir, int datalen) -+{ -+ ASSERT32FLAT(); -+ struct xhci_trb trb; -+ -+ memset(&trb, 0, sizeof(trb)); -+ trb.ptr_low |= req->bRequestType; -+ trb.ptr_low |= (req->bRequest) << 8; -+ trb.ptr_low |= (req->wValue) << 16; -+ trb.ptr_high |= req->wIndex; -+ trb.ptr_high |= (req->wLength) << 16; -+ trb.status |= 8; // length -+ trb.control |= (TR_SETUP << 10); // trb type -+ trb.control |= TRB_TR_IDT; -+ if (datalen) -+ trb.control |= (dir ? 3 : 2) << 16; // transfer type -+ xhci_xfer_queue(pipe, &trb); -+} -+ -+static void xhci_xfer_data(struct xhci_pipe *pipe, -+ int dir, void *data, int datalen) -+{ -+ ASSERT32FLAT(); -+ struct xhci_trb trb; -+ -+ memset(&trb, 0, sizeof(trb)); -+ trb.ptr_low = (u32)data; -+ trb.status = datalen; -+ trb.control |= (TR_DATA << 10); // trb type -+ if (dir) -+ trb.control |= (1 << 16); -+ xhci_xfer_queue(pipe, &trb); -+} -+ -+static void xhci_xfer_status(struct xhci_pipe *pipe, int dir) -+{ -+ ASSERT32FLAT(); -+ struct xhci_trb trb; -+ -+ memset(&trb, 0, sizeof(trb)); -+ trb.control |= (TR_STATUS << 10); // trb type -+ trb.control |= TRB_TR_IOC; -+ if (dir) -+ trb.control |= (1 << 16); -+ -+ xhci_xfer_queue(pipe, &trb); -+ xhci_xfer_kick(pipe); -+} -+ -+static struct xhci_device *xhci_find_alloc_device(struct usb_xhci_s *xhci, -+ struct usbdevice_s *usbdev) -+{ -+ ASSERT32FLAT(); -+ struct xhci_device *dev; -+ -+ hlist_for_each_entry(dev, &xhci->list, next) { -+ if (dev->usbdev == usbdev) { -+ return dev; -+ } -+ } -+ -+ dev = memalign_low(64, sizeof(*dev)); -+ if (!dev) { -+ warn_noalloc(); -+ return NULL; -+ } -+ memset(dev, 0, sizeof(*dev)); -+ dev->usbdev = usbdev; -+ dev->xhci = xhci; -+ hlist_add_head(&dev->next, &xhci->list); -+ return dev; -+} -+ -+static void -+configure_xhci(void *data) -+{ -+ ASSERT32FLAT(); -+ struct usb_xhci_s *xhci = data; -+ u32 reg; -+ -+ xhci->devs = memalign_high(64, sizeof(*xhci->devs) * (xhci->slots + 1)); -+ xhci->eseg = memalign_high(64, sizeof(*xhci->eseg)); -+ xhci->cmds = memalign_high(XHCI_RING_SIZE, sizeof(*xhci->cmds)); -+ xhci->evts = memalign_low(XHCI_RING_SIZE, sizeof(*xhci->evts)); -+ if (!xhci->devs || !xhci->cmds || !xhci->evts || !xhci->eseg) { -+ warn_noalloc(); -+ goto fail; -+ } -+ memset(xhci->devs, 0, sizeof(*xhci->devs) * (xhci->slots + 1)); -+ memset(xhci->cmds, 0, sizeof(*xhci->cmds)); -+ memset(xhci->evts, 0, sizeof(*xhci->evts)); -+ memset(xhci->eseg, 0, sizeof(*xhci->eseg)); -+ -+ reg = readl(&xhci->op->usbcmd); -+ if (reg & XHCI_CMD_RS) { -+ reg &= ~XHCI_CMD_RS; -+ writel(&xhci->op->usbcmd, reg); -+ if (wait_bit(&xhci->op->usbsts, XHCI_STS_HCH, XHCI_STS_HCH, 32) != 0) -+ goto fail; -+ } -+ -+ dprintf(3, "%s: resetting\n", __func__); -+ writel(&xhci->op->usbcmd, XHCI_CMD_HCRST); -+ if (wait_bit(&xhci->op->usbcmd, XHCI_CMD_HCRST, 0, 100) != 0) -+ goto fail; -+ if (wait_bit(&xhci->op->usbsts, XHCI_STS_CNR, 0, 100) != 0) -+ goto fail; -+ -+ writel(&xhci->op->config, xhci->slots); -+ writel(&xhci->op->dcbaap_low, (u32)xhci->devs); -+ writel(&xhci->op->dcbaap_high, 0); -+ writel(&xhci->op->crcr_low, (u32)xhci->cmds | 1); -+ writel(&xhci->op->crcr_high, 0); -+ xhci->cmds->cs = 1; -+ -+ xhci->eseg->ptr_low = (u32)xhci->evts; -+ xhci->eseg->ptr_high = 0; -+ xhci->eseg->size = XHCI_RING_ITEMS; -+ writel(&xhci->ir->erstsz, 1); -+ writel(&xhci->ir->erdp_low, (u32)xhci->evts); -+ writel(&xhci->ir->erdp_high, 0); -+ writel(&xhci->ir->erstba_low, (u32)xhci->eseg); -+ writel(&xhci->ir->erstba_high, 0); -+ xhci->evts->cs = 1; -+ -+ reg = readl(&xhci->op->usbcmd); -+ reg |= XHCI_CMD_RS; -+ writel(&xhci->op->usbcmd, reg); -+ -+ // FIXME: try find a more elegant way than a fixed delay -+ mdelay(100); -+ -+ usb_enumerate(&xhci->hub); -+ if (xhci->hub.devcount) -+ return; -+ -+ // No devices found - shutdown and free controller. -+ dprintf(1, "XHCI no devices found\n"); -+ reg = readl(&xhci->op->usbcmd); -+ reg &= ~XHCI_CMD_RS; -+ writel(&xhci->op->usbcmd, reg); -+ wait_bit(&xhci->op->usbsts, XHCI_STS_HCH, XHCI_STS_HCH, 32); -+ -+fail: -+ free(xhci->eseg); -+ free(xhci->evts); -+ free(xhci->cmds); -+ free(xhci->devs); -+ free(xhci); -+} -+ -+// -------------------------------------------------------------- -+// xhci root hub -+ -+// Check if device attached to port -+static void -+xhci_print_port_state(int loglevel, const char *prefix, u32 port, u32 portsc) -+{ -+ ASSERT32FLAT(); -+ u32 pls = xhci_get_field(portsc, XHCI_PORTSC_PLS); -+ u32 speed = xhci_get_field(portsc, XHCI_PORTSC_SPEED); -+ -+ dprintf(loglevel, "%s port #%d: 0x%08x,%s%s pls %d, speed %d [%s]\n", -+ prefix, port + 1, portsc, -+ (portsc & XHCI_PORTSC_PP) ? " powered," : "", -+ (portsc & XHCI_PORTSC_PED) ? " enabled," : "", -+ pls, speed, speed_name[speed]); -+} -+ -+static int -+xhci_hub_detect(struct usbhub_s *hub, u32 port) -+{ -+ ASSERT32FLAT(); -+ struct usb_xhci_s *xhci = container_of(hub->cntl, struct usb_xhci_s, usb); -+ u32 portsc = readl(&xhci->pr[port].portsc); -+ -+ xhci_print_port_state(3, __func__, port, portsc); -+ switch (xhci_get_field(portsc, XHCI_PORTSC_PLS)) { -+ case PLS_U0: -+ case PLS_POLLING: -+ return 0; -+ default: -+ return -1; -+ } -+} -+ -+// Reset device on port -+static int -+xhci_hub_reset(struct usbhub_s *hub, u32 port) -+{ -+ ASSERT32FLAT(); -+ struct usb_xhci_s *xhci = container_of(hub->cntl, struct usb_xhci_s, usb); -+ u32 portsc = readl(&xhci->pr[port].portsc); -+ int rc; -+ -+ switch (xhci_get_field(portsc, XHCI_PORTSC_PLS)) { -+ case PLS_U0: -+ rc = speed_from_xhci[xhci_get_field(portsc, XHCI_PORTSC_SPEED)]; -+ break; -+ case PLS_POLLING: -+ xhci_print_port_state(3, __func__, port, portsc); -+ portsc |= XHCI_PORTSC_PR; -+ writel(&xhci->pr[port].portsc, portsc); -+ if (wait_bit(&xhci->pr[port].portsc, XHCI_PORTSC_PED, XHCI_PORTSC_PED, 100) != 0) -+ return -1; -+ portsc = readl(&xhci->pr[port].portsc); -+ rc = speed_from_xhci[xhci_get_field(portsc, XHCI_PORTSC_SPEED)]; -+ break; -+ default: -+ rc = -1; -+ break; -+ } -+ -+ xhci_print_port_state(1, "XHCI", port, portsc); -+ return rc; -+} -+ -+static void -+xhci_hub_disconnect(struct usbhub_s *hub, u32 port) -+{ -+ ASSERT32FLAT(); -+ struct usb_xhci_s *xhci = container_of(hub->cntl, struct usb_xhci_s, usb); -+ struct xhci_device *dev; -+ -+ hlist_for_each_entry(dev, &xhci->list, next) { -+ if (dev->usbdev->hub == hub && -+ dev->usbdev->port == port && -+ dev->slotid != 0) { -+ xhci_cmd_disable_slot(dev); -+ hlist_del(&dev->next); -+ return; -+ } -+ } -+} -+ -+static struct usbhub_op_s xhci_hub_ops = { -+ .detect = xhci_hub_detect, -+ .reset = xhci_hub_reset, -+ .disconnect = xhci_hub_disconnect, -+}; -+ -+// -------------------------------------------------------------- -+// external interface -+ -+struct usb_pipe * -+xhci_alloc_pipe(struct usbdevice_s *usbdev -+ , struct usb_endpoint_descriptor *epdesc) -+{ -+ ASSERT32FLAT(); -+ if (!CONFIG_USB_XHCI) -+ return NULL; -+ u8 eptype = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; -+ struct usb_xhci_s *xhci = container_of( -+ usbdev->hub->cntl, struct usb_xhci_s, usb); -+ struct xhci_pipe *pipe; -+ u32 epid; -+ -+ if (epdesc->bEndpointAddress == 0) { -+ epid = 1; -+ } else { -+ epid = (epdesc->bEndpointAddress & 0x0f) * 2; -+ epid += (epdesc->bEndpointAddress & USB_DIR_IN) ? 1 : 0; -+ } -+ -+ if (eptype == USB_ENDPOINT_XFER_CONTROL) -+ pipe = memalign_high(XHCI_RING_SIZE, sizeof(*pipe)); -+ else -+ pipe = memalign_low(XHCI_RING_SIZE, sizeof(*pipe)); -+ if (!pipe) { -+ warn_noalloc(); -+ return NULL; -+ } -+ memset(pipe, 0, sizeof(*pipe)); -+ -+ usb_desc2pipe(&pipe->pipe, usbdev, epdesc); -+ pipe->dev = xhci_find_alloc_device(xhci, usbdev); -+ if (!pipe->dev) { -+ free(pipe); -+ return NULL; -+ } -+ pipe->epid = epid; -+ pipe->reqs.cs = 1; -+ if (eptype == USB_ENDPOINT_XFER_INT) -+ pipe->buf = malloc_low(pipe->pipe.maxpacket); -+ -+ dprintf(3, "%s: usbdev %p, ring %p, slotid %d, epid %d\n", __func__, -+ usbdev, &pipe->reqs, pipe->dev->slotid, pipe->epid); -+ if (pipe->epid > 1 && pipe->dev->slotid) { -+ struct xhci_inctx *in = &pipe->dev->inctx; -+ in->add = (1 << pipe->epid) | 1; -+ in->del = 0; -+ -+ in->slot.ctx[0] |= (31 << 27); // context entries -+ -+ int e = pipe->epid-1; -+ in->ep[e].ctx[1] |= (eptype << 3); -+ if (epdesc->bEndpointAddress & USB_DIR_IN) -+ in->ep[e].ctx[1] |= (1 << 5); -+ in->ep[e].ctx[1] |= (pipe->pipe.maxpacket << 16); -+ in->ep[e].deq_low = (u32)&pipe->reqs.ring[0]; -+ in->ep[e].deq_low |= 1; // dcs -+ in->ep[e].deq_high = 0; -+ in->ep[e].length = pipe->pipe.maxpacket; -+ -+ int cc = xhci_cmd_configure_endpoint(pipe->dev); -+ if (cc != CC_SUCCESS) { -+ dprintf(1, "%s: configure endpoint: failed (cc %d)\n", __func__, cc); -+ free(pipe); -+ return NULL; -+ } -+ } -+ -+ return &pipe->pipe; -+} -+ -+struct usb_pipe * -+xhci_update_pipe(struct usbdevice_s *usbdev, struct usb_pipe *upipe -+ , struct usb_endpoint_descriptor *epdesc) -+{ -+ ASSERT32FLAT(); -+ if (!CONFIG_USB_XHCI) -+ return NULL; -+ u8 eptype = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; -+ struct xhci_pipe *pipe = container_of(upipe, struct xhci_pipe, pipe); -+ dprintf(3, "%s: usbdev %p, ring %p, slotid %d, epid %d\n", __func__, -+ usbdev, &pipe->reqs, pipe->dev->slotid, pipe->epid); -+ if (eptype == USB_ENDPOINT_XFER_CONTROL && -+ pipe->pipe.maxpacket != epdesc->wMaxPacketSize) { -+ dprintf(1, "%s: reconf ctl endpoint pkt size: %d -> %d\n", -+ __func__, pipe->pipe.maxpacket, epdesc->wMaxPacketSize); -+ pipe->pipe.maxpacket = epdesc->wMaxPacketSize; -+ struct xhci_inctx *in = &pipe->dev->inctx; -+ in->add = (1 << 1); -+ in->del = 0; -+ in->ep[0].ctx[1] &= 0xffff; -+ in->ep[0].ctx[1] |= (pipe->pipe.maxpacket << 16); -+ int cc = xhci_cmd_evaluate_context(pipe->dev); -+ if (cc != CC_SUCCESS) { -+ dprintf(1, "%s: reconf ctl endpoint: failed (cc %d)\n", -+ __func__, cc); -+ } -+ } -+ return upipe; -+} -+ -+int -+xhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize -+ , void *data, int datalen) -+{ -+ ASSERT32FLAT(); -+ if (!CONFIG_USB_XHCI) -+ return -1; -+ const struct usb_ctrlrequest *req = cmd; -+ struct xhci_pipe *pipe = container_of(p, struct xhci_pipe, pipe); -+ struct usb_xhci_s *xhci = pipe->dev->xhci; -+ int cc; -+ -+ if (req->bRequest == USB_REQ_SET_ADDRESS) { -+ int slotid = xhci_cmd_enable_slot(xhci); -+ if (slotid < 0) { -+ dprintf(1, "%s: enable slot: failed\n", __func__); -+ return -1; -+ } -+ dprintf(3, "%s: enable slot: got slotid %d\n", __func__, slotid); -+ pipe->dev->slotid = slotid; -+ xhci->devs[slotid].ptr_low = (u32)&pipe->dev->devctx; -+ xhci->devs[slotid].ptr_high = 0; -+ -+ struct usbdevice_s *usbdev = pipe->dev->usbdev; -+ u32 route = 0; -+ while (usbdev->hub->usbdev) { -+ route <<= 4; -+ route |= (usbdev->port+1) & 0xf; -+ usbdev = usbdev->hub->usbdev; -+ } -+ dprintf(3, "%s: root port %d, route 0x%x\n", -+ __func__, usbdev->port+1, route); -+ -+ struct xhci_inctx *in = &pipe->dev->inctx; -+ in->add = 0x03; -+ in->slot.ctx[0] |= (1 << 27); // context entries -+ in->slot.ctx[0] |= speed_to_xhci[pipe->dev->usbdev->speed] << 20; -+ in->slot.ctx[0] |= route; -+ in->slot.ctx[1] |= (usbdev->port+1) << 16; -+ /* TODO ctx0: hub bit */ -+ /* TODO ctx1: hub ports */ -+ -+ in->ep[0].ctx[0] |= (3 << 16); // interval: 1ms -+ in->ep[0].ctx[1] |= (4 << 3); // control pipe -+ in->ep[0].ctx[1] |= (speed_to_ctlsize[pipe->dev->usbdev->speed] << 16); -+ -+ in->ep[0].deq_low = (u32)&pipe->reqs.ring[0]; -+ in->ep[0].deq_low |= 1; // dcs -+ in->ep[0].deq_high = 0; -+ in->ep[0].length = 8; -+ -+ cc = xhci_cmd_address_device(pipe->dev); -+ if (cc != CC_SUCCESS) { -+ dprintf(1, "%s: address device: failed (cc %d)\n", __func__, cc); -+ return -1; -+ } -+ return 0; -+ } -+ -+ xhci_xfer_setup(pipe, req, dir, datalen); -+ if (datalen) -+ xhci_xfer_data(pipe, dir, data, datalen); -+ xhci_xfer_status(pipe, dir); -+ -+ cc = xhci_event_wait(xhci, &pipe->reqs, 1000); -+ if (cc != CC_SUCCESS) { -+ dprintf(1, "%s: control xfer failed (cc %d)\n", __func__, cc); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+int -+xhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datalen) -+{ -+ if (!CONFIG_USB_XHCI) -+ return -1; -+ -+ struct xhci_pipe *pipe = container_of(p, struct xhci_pipe, pipe); -+ struct xhci_device *dev = GET_LOWFLAT(pipe->dev); -+ struct usb_xhci_s *xhci = GET_LOWFLAT(dev->xhci); -+ -+ xhci_xfer_normal(pipe, data, datalen); -+ int cc = xhci_event_wait(xhci, &pipe->reqs, 1000); -+ if (cc != CC_SUCCESS) { -+ dprintf(1, "%s: bulk xfer failed (cc %d)\n", __func__, cc); -+ return -1; -+ } -+ return 0; -+} -+ -+int -+xhci_poll_intr(struct usb_pipe *p, void *data) -+{ -+ if (!CONFIG_USB_XHCI) -+ return -1; -+ -+ struct xhci_pipe *pipe = container_of(p, struct xhci_pipe, pipe); -+ struct xhci_device *dev = GET_LOWFLAT(pipe->dev); -+ struct usb_xhci_s *xhci = GET_LOWFLAT(dev->xhci); -+ u32 len = GET_LOWFLAT(pipe->pipe.maxpacket); -+ void *buf = GET_LOWFLAT(pipe->buf); -+ int bufused = GET_LOWFLAT(pipe->bufused); -+ -+ if (!bufused) { -+ xhci_xfer_normal(pipe, buf, len); -+ bufused = 1; -+ SET_LOWFLAT(pipe->bufused, bufused); -+ return -1; -+ } -+ -+ xhci_process_events(xhci); -+ if (xhci_ring_busy(&pipe->reqs)) -+ return -1; -+ dprintf(5, "%s: st %x ct %x [ %p <= %p / %d ]\n", __func__, -+ GET_LOWFLAT(pipe->reqs.evt.status), -+ GET_LOWFLAT(pipe->reqs.evt.control), -+ MAKE_FLATPTR(GET_SEG(SS), data), buf, len); -+ memcpy_fl(MAKE_FLATPTR(GET_SEG(SS), data), buf, len); -+ xhci_xfer_normal(pipe, buf, len); -+ return 0; -+} -+ -+int -+xhci_setup(struct pci_device *pci, int busid) -+{ -+ ASSERT32FLAT(); -+ if (!CONFIG_USB_XHCI) -+ return -1; -+ -+ struct usb_xhci_s *xhci = malloc_low(sizeof(*xhci)); -+ if (!xhci) { -+ warn_noalloc(); -+ return -1; -+ } -+ memset(xhci, 0, sizeof(*xhci)); -+ -+ xhci->baseaddr = pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0) -+ & PCI_BASE_ADDRESS_MEM_MASK; -+ xhci->caps = (void*)(xhci->baseaddr); -+ xhci->op = (void*)(xhci->baseaddr + readb(&xhci->caps->caplength)); -+ xhci->pr = (void*)(xhci->baseaddr + readb(&xhci->caps->caplength) + 0x400); -+ xhci->db = (void*)(xhci->baseaddr + readl(&xhci->caps->dboff)); -+ xhci->ir = (void*)(xhci->baseaddr + readl(&xhci->caps->rtsoff) + 0x20); -+ -+ u32 hcs1 = readl(&xhci->caps->hcsparams1); -+ u32 hcc = readl(&xhci->caps->hccparams); -+ xhci->ports = (hcs1 >> 24) & 0xff; -+ xhci->slots = hcs1 & 0xff; -+ xhci->xcap = ((hcc >> 16) & 0xffff) << 2; -+ -+ xhci->usb.busid = busid; -+ xhci->usb.pci = pci; -+ xhci->usb.type = USB_TYPE_XHCI; -+ xhci->hub.cntl = &xhci->usb; -+ xhci->hub.portcount = xhci->ports; -+ xhci->hub.op = &xhci_hub_ops; -+ -+ dprintf(1, "XHCI init on dev %02x:%02x.%x: regs @ %p, %d ports, %d slots\n" -+ , pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf) -+ , pci_bdf_to_fn(pci->bdf), xhci->caps -+ , xhci->ports, xhci->slots); -+ -+ if (xhci->xcap) { -+ u32 off, addr = xhci->baseaddr + xhci->xcap; -+ do { -+ struct xhci_xcap *xcap = (void*)addr; -+ u32 ports, name, cap = readl(&xcap->cap); -+ switch (cap & 0xff) { -+ case 0x02: -+ name = readl(&xcap->data[0]); -+ ports = readl(&xcap->data[1]); -+ dprintf(1, "XHCI protocol %c%c%c%c %x.%02x, %d ports (offset %d)\n" -+ , (name >> 0) & 0xff -+ , (name >> 8) & 0xff -+ , (name >> 16) & 0xff -+ , (name >> 24) & 0xff -+ , (cap >> 24) & 0xff -+ , (cap >> 16) & 0xff -+ , (ports >> 8) & 0xff -+ , (ports >> 0) & 0xff); -+ break; -+ default: -+ dprintf(1, "XHCI extcap 0x%x @ %x\n", cap & 0xff, addr); -+ break; -+ } -+ off = (cap >> 8) & 0xff; -+ addr += off << 2; -+ } while (off > 0); -+ } -+ -+ pci_config_maskw(pci->bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER); -+ -+ run_thread(configure_xhci, xhci); -+ return 0; -+} -diff --git a/src/usb-xhci.h b/src/usb-xhci.h -new file mode 100644 -index 0000000..64ee82c ---- /dev/null -+++ b/src/usb-xhci.h -@@ -0,0 +1,144 @@ -+#ifndef __USB_XHCI_H -+#define __USB_XHCI_H -+ -+struct usbdevice_s; -+struct usb_endpoint_descriptor; -+struct usb_pipe; -+ -+// -------------------------------------------------------------- -+ -+// usb-xhci.c -+int xhci_setup(struct pci_device *pci, int busid); -+struct usb_pipe *xhci_alloc_pipe(struct usbdevice_s *usbdev -+ , struct usb_endpoint_descriptor *epdesc); -+struct usb_pipe *xhci_update_pipe(struct usbdevice_s *usbdev -+ , struct usb_pipe *pipe -+ , struct usb_endpoint_descriptor *epdesc); -+int xhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize -+ , void *data, int datasize); -+int xhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize); -+int xhci_poll_intr(struct usb_pipe *p, void *data); -+ -+// -------------------------------------------------------------- -+// register interface -+ -+// capabilities -+struct xhci_caps { -+ u8 caplength; -+ u8 reserved_01; -+ u16 hciversion; -+ u32 hcsparams1; -+ u32 hcsparams2; -+ u32 hcsparams3; -+ u32 hccparams; -+ u32 dboff; -+ u32 rtsoff; -+} PACKED; -+ -+// extended capabilities -+struct xhci_xcap { -+ u32 cap; -+ u32 data[]; -+} PACKED; -+ -+// operational registers -+struct xhci_op { -+ u32 usbcmd; -+ u32 usbsts; -+ u32 pagesize; -+ u32 reserved_01[2]; -+ u32 dnctl; -+ u32 crcr_low; -+ u32 crcr_high; -+ u32 reserved_02[4]; -+ u32 dcbaap_low; -+ u32 dcbaap_high; -+ u32 config; -+} PACKED; -+ -+// port registers -+struct xhci_pr { -+ u32 portsc; -+ u32 portpmsc; -+ u32 portli; -+ u32 reserved_01; -+} PACKED; -+ -+// doorbell registers -+struct xhci_db { -+ u32 doorbell; -+} PACKED; -+ -+// runtime registers -+struct xhci_rts { -+ u32 mfindex; -+} PACKED; -+ -+// interrupter registers -+struct xhci_ir { -+ u32 iman; -+ u32 imod; -+ u32 erstsz; -+ u32 reserved_01; -+ u32 erstba_low; -+ u32 erstba_high; -+ u32 erdp_low; -+ u32 erdp_high; -+} PACKED; -+ -+// -------------------------------------------------------------- -+// memory data structs -+ -+// slot context -+struct xhci_slotctx { -+ u32 ctx[4]; -+ u32 reserved_01[4]; -+} PACKED; -+ -+// endpoint context -+struct xhci_epctx { -+ u32 ctx[2]; -+ u32 deq_low; -+ u32 deq_high; -+ u32 length; -+ u32 reserved_01[3]; -+} PACKED; -+ -+// device context -+struct xhci_devctx { -+ struct xhci_slotctx slot; -+ struct xhci_epctx ep[31]; -+} PACKED; -+ -+// device context array element -+struct xhci_devlist { -+ u32 ptr_low; -+ u32 ptr_high; -+} PACKED; -+ -+// input context -+struct xhci_inctx { -+ u32 del; -+ u32 add; -+ u32 reserved_01[6]; -+ struct xhci_slotctx slot; -+ struct xhci_epctx ep[31]; -+} PACKED; -+ -+// transfer block (ring element) -+struct xhci_trb { -+ u32 ptr_low; -+ u32 ptr_high; -+ u32 status; -+ u32 control; -+} PACKED; -+ -+// event ring segment -+struct xhci_er_seg { -+ u32 ptr_low; -+ u32 ptr_high; -+ u32 size; -+ u32 reserved_01; -+} PACKED; -+ -+#endif // usb-xhci.h -diff --git a/src/usb.c b/src/usb.c -index 3efa367..1cdb612 100644 ---- a/src/usb.c -+++ b/src/usb.c -@@ -12,6 +12,7 @@ - #include "usb-uhci.h" // uhci_init - #include "usb-ohci.h" // ohci_init - #include "usb-ehci.h" // ehci_init -+#include "usb-xhci.h" // xhci_setup - #include "usb-hid.h" // usb_keyboard_setup - #include "usb-hub.h" // usb_hub_init - #include "usb-msc.h" // usb_msc_init -@@ -37,6 +38,8 @@ usb_alloc_pipe(struct usbdevice_s *usbdev - return ohci_alloc_pipe(usbdev, epdesc); - case USB_TYPE_EHCI: - return ehci_alloc_pipe(usbdev, epdesc); -+ case USB_TYPE_XHCI: -+ return xhci_alloc_pipe(usbdev, epdesc); - } - } - -@@ -46,6 +49,8 @@ usb_update_pipe(struct usbdevice_s *usbdev, struct usb_pipe *pipe - , struct usb_endpoint_descriptor *epdesc) - { - switch (usbdev->hub->cntl->type) { -+ case USB_TYPE_XHCI: -+ return xhci_update_pipe(usbdev, pipe, epdesc); - default: - free_pipe(pipe); - return usb_alloc_pipe(usbdev, epdesc); -@@ -66,6 +71,8 @@ send_control(struct usb_pipe *pipe, int dir, const void *cmd, int cmdsize - return ohci_control(pipe, dir, cmd, cmdsize, data, datasize); - case USB_TYPE_EHCI: - return ehci_control(pipe, dir, cmd, cmdsize, data, datasize); -+ case USB_TYPE_XHCI: -+ return xhci_control(pipe, dir, cmd, cmdsize, data, datasize); - } - } - -@@ -80,6 +87,8 @@ usb_send_bulk(struct usb_pipe *pipe_fl, int dir, void *data, int datasize) - return ohci_send_bulk(pipe_fl, dir, data, datasize); - case USB_TYPE_EHCI: - return ehci_send_bulk(pipe_fl, dir, data, datasize); -+ case USB_TYPE_XHCI: -+ return xhci_send_bulk(pipe_fl, dir, data, datasize); - } - } - -@@ -94,6 +103,8 @@ usb_poll_intr(struct usb_pipe *pipe_fl, void *data) - return ohci_poll_intr(pipe_fl, data); - case USB_TYPE_EHCI: - return ehci_poll_intr(pipe_fl, data); -+ case USB_TYPE_XHCI: -+ return xhci_poll_intr(pipe_fl, data); - } - } - -@@ -469,5 +480,7 @@ usb_setup(void) - uhci_init(pci, count++); - else if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_OHCI) - ohci_init(pci, count++); -+ else if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_XHCI) -+ xhci_setup(pci, count++); - } - } -diff --git a/src/usb.h b/src/usb.h -index d9eadd7..a034aa6 100644 ---- a/src/usb.h -+++ b/src/usb.h -@@ -60,15 +60,17 @@ struct usbhub_op_s { - void (*disconnect)(struct usbhub_s *hub, u32 port); - }; - --#define USB_TYPE_UHCI 1 --#define USB_TYPE_OHCI 2 --#define USB_TYPE_EHCI 3 -+#define USB_TYPE_UHCI 1 -+#define USB_TYPE_OHCI 2 -+#define USB_TYPE_EHCI 3 -+#define USB_TYPE_XHCI 4 - --#define USB_FULLSPEED 0 --#define USB_LOWSPEED 1 --#define USB_HIGHSPEED 2 -+#define USB_FULLSPEED 0 -+#define USB_LOWSPEED 1 -+#define USB_HIGHSPEED 2 -+#define USB_SUPERSPEED 3 - --#define USB_MAXADDR 127 -+#define USB_MAXADDR 127 - - - /**************************************************************** --- -1.7.1 - diff --git a/SOURCES/seabios-vgabios-Fix-cirrus-memory-clear-on-mode-switch.patch b/SOURCES/seabios-vgabios-Fix-cirrus-memory-clear-on-mode-switch.patch deleted file mode 100644 index f7addfa..0000000 --- a/SOURCES/seabios-vgabios-Fix-cirrus-memory-clear-on-mode-switch.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 52f633e72965e711be4d92928615f63b4cf9f429 Mon Sep 17 00:00:00 2001 -From: Miki Mishael -Date: Tue, 7 Jan 2014 16:10:44 +0100 -Subject: [PATCH] vgabios: Fix cirrus memory clear on mode switch. - -RH-Author: Miki Mishael -Message-id: <1389111044-9237-1-git-send-email-mmishael@redhat.com> -Patchwork-id: 56530 -O-Subject: [RHEL7.0 seabios PATCH] vgabios: Fix cirrus memory clear on mode switch. -Bugzilla: 979898 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Yan Vugenfirer -RH-Acked-by: Gal Hammer - -From: Kevin O'Connor - -The cirrus_clear_vram() code wasn't actually doing anything because of -a u8 overflow. Fix that. - -Fill with 0xff when performing a legacy cirrus mode switch (WinXP has -been observed to incorrectly render dialog boxes if the memory is -filled to 0). This was the behavior of the original LGPL vgabios -code. To support this, add mechanism (MF_LEGACY) to allow vga drivers -to detect if the mode switch is from vesa or int10. - -Signed-off-by: Kevin O'Connor - -BZ: https://bugzilla.redhat.com/show_bug.cgi?id=979898 -Upstream-status: b7b92935df0e309149c042d587e4764548f10608 -Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=6818682 -Signed-off-by: Miki Mishael -Signed-off-by: Dmitry Fleytman ---- - vgasrc/clext.c | 11 ++++++----- - vgasrc/vgabios.c | 2 +- - vgasrc/vgabios.h | 1 + - 3 files changed, 8 insertions(+), 6 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - vgasrc/clext.c | 11 ++++++----- - vgasrc/vgabios.c | 2 +- - vgasrc/vgabios.h | 1 + - 3 files changed, 8 insertions(+), 6 deletions(-) - -diff --git a/vgasrc/clext.c b/vgasrc/clext.c -index fc5459a..30da499 100644 ---- a/vgasrc/clext.c -+++ b/vgasrc/clext.c -@@ -442,14 +442,14 @@ cirrus_enable_16k_granularity(void) - } - - static void --cirrus_clear_vram(void) -+cirrus_clear_vram(u16 fill) - { - cirrus_enable_16k_granularity(); -- u8 count = GET_GLOBAL(VBE_total_memory) / (16 * 1024); -- u8 i; -+ int count = GET_GLOBAL(VBE_total_memory) / (16 * 1024); -+ int i; - for (i=0; ial = 0x30; - -- int flags = GET_BDA(modeset_ctl) & (MF_NOPALETTE|MF_GRAYSUM); -+ int flags = MF_LEGACY | (GET_BDA(modeset_ctl) & (MF_NOPALETTE|MF_GRAYSUM)); - if (regs->al & 0x80) - flags |= MF_NOCLEARMEM; - -diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h -index ff5ec45..5adbf4b 100644 ---- a/vgasrc/vgabios.h -+++ b/vgasrc/vgabios.h -@@ -39,6 +39,7 @@ struct saveBDAstate { - }; - - // Mode flags -+#define MF_LEGACY 0x0001 - #define MF_GRAYSUM 0x0002 - #define MF_NOPALETTE 0x0008 - #define MF_CUSTOMCRTC 0x0800 --- -1.7.1 - diff --git a/SOURCES/seabios-xhci-adaptions-for-old-rhel7-seabios-codebase.patch b/SOURCES/seabios-xhci-adaptions-for-old-rhel7-seabios-codebase.patch deleted file mode 100644 index 879ee68..0000000 --- a/SOURCES/seabios-xhci-adaptions-for-old-rhel7-seabios-codebase.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 9636beca521c90babc3424789dd13317806d36f7 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 2 Oct 2013 07:00:19 +0200 -Subject: [PATCH 7/8] xhci adaptions for old rhel7 seabios codebase - -RH-Author: Gerd Hoffmann -Message-id: <1380697219-1860-8-git-send-email-kraxel@redhat.com> -Patchwork-id: 54631 -O-Subject: [RHEL-7 seabios PATCH 7/7] xhci adaptions for old rhel7 seabios codebase -Bugzilla: 947051 -RH-Acked-by: Laszlo Ersek -RH-Acked-by: Bandan Das -RH-Acked-by: Miroslav Rezanina - -Kept as separate commit to make review easier. -rhel-only patch for obvious reasons. - -Signed-off-by: Gerd Hoffmann ---- - src/Kconfig | 2 +- - src/usb-xhci.c | 9 +++++---- - 2 files changed, 6 insertions(+), 5 deletions(-) - -Signed-off-by: Miroslav Rezanina ---- - src/Kconfig | 2 +- - src/usb-xhci.c | 9 +++++---- - 2 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/src/Kconfig b/src/Kconfig -index b059a73..d00c66c 100644 ---- a/src/Kconfig -+++ b/src/Kconfig -@@ -185,7 +185,7 @@ menu "Hardware support" - help - Support USB EHCI controllers. - config USB_XHCI -- depends on USB && QEMU_HARDWARE -+ depends on USB && QEMU - bool "USB XHCI controllers" - default y - help -diff --git a/src/usb-xhci.c b/src/usb-xhci.c -index 5be0b25..3a4f3e0 100644 ---- a/src/usb-xhci.c -+++ b/src/usb-xhci.c -@@ -1,5 +1,6 @@ - #include "config.h" // CONFIG_* - #include "util.h" // timer_calc -+#include "list.h" // timer_calc - #include "pci.h" // pci_bdf_to_bus - #include "pci_regs.h" // PCI_BASE_ADDRESS_0 - #include "usb.h" // struct usb_s -@@ -387,7 +388,7 @@ static int xhci_event_wait(struct usb_xhci_s *xhci, - struct xhci_ring *ring, - u32 timeout) - { -- u32 end = timer_calc(timeout); -+ u64 end = calc_future_tsc(timeout); - - for (;;) { - xhci_process_events(xhci); -@@ -395,7 +396,7 @@ static int xhci_event_wait(struct usb_xhci_s *xhci, - u32 status = GET_LOWFLAT(ring->evt.status); - return (status >> 24) & 0xff; - } -- if (timer_check(end)) { -+ if (check_tsc(end)) { - warn_timeout(); - return -1; - } -@@ -482,10 +483,10 @@ static void xhci_xfer_normal(struct xhci_pipe *pipe, - static int wait_bit(u32 *reg, u32 mask, int value, u32 timeout) - { - ASSERT32FLAT(); -- u32 end = timer_calc(timeout); -+ u64 end = calc_future_tsc(timeout); - - while ((readl(reg) & mask) != value) { -- if (timer_check(end)) { -+ if (check_tsc(end)) { - warn_timeout(); - return -1; - } --- -1.7.1 - diff --git a/SPECS/seabios.spec b/SPECS/seabios.spec index 973014c..8cde040 100644 --- a/SPECS/seabios.spec +++ b/SPECS/seabios.spec @@ -1,6 +1,6 @@ Name: seabios -Version: 1.7.2.2 -Release: 12%{?dist}.1 +Version: 1.7.5 +Release: 8%{?dist} Summary: Open-source legacy BIOS implementation Group: Applications/Emulators @@ -22,63 +22,18 @@ Source14: config.vga.vmware Source15: config.base Source16: config.base-256k -# Add pvpanic device driver (rhbz 967777) -Patch1: Add-pvpanic-device-driver.patch -# For bz#920140 - qemu-kvm emulation of 2.88M floppy fails -Patch2: seabios-floppy-Introduce-struct-floppy_pio_s-for-floppy-PIO-.patch -# For bz#920140 - qemu-kvm emulation of 2.88M floppy fails -Patch3: seabios-floppy-Cleanup-floppy-irq-wait-handling.patch -# For bz#920140 - qemu-kvm emulation of 2.88M floppy fails -Patch4: seabios-floppy-Implement-media-format-sensing.patch -# For bz#894979 - place rpm version info into version banner -Patch5: seabios-Place-rpm-version-info-into-version-banner.patch -# For bz#1005747 - fail to boot rhel7 guest with >126(21 ahci controller) ahci disks -Patch6: seabios-ahci-add-missing-check-for-allocation-failure.patch -# For bz#947051 - [RFE] implement xhci support in seabios -Patch7: seabios-Introduce-and-convert-pmm-code-to-use-standard-list-.patch -# For bz#947051 - [RFE] implement xhci support in seabios -Patch8: seabios-Fix-error-in-hlist_for_each_entry_safe-macro.patch -# For bz#947051 - [RFE] implement xhci support in seabios -Patch9: seabios-Another-fix-for-hlist_for_each_entry_safe.patch -# For bz#947051 - [RFE] implement xhci support in seabios -Patch10: seabios-uas-add-temporary-superspeed-stopgap.patch -# For bz#947051 - [RFE] implement xhci support in seabios -Patch11: seabios-usb-add-usb_update_pipe.patch -# For bz#947051 - [RFE] implement xhci support in seabios -Patch12: seabios-usb-add-xhci-support.patch -# For bz#947051 - [RFE] implement xhci support in seabios -Patch13: seabios-xhci-adaptions-for-old-rhel7-seabios-codebase.patch -# For bz#1016974 - [HP 7.0 FEAT]: Increase KVM guest supported memory to 4TiB -Patch14: seabios-allow-1TB-of-RAM.patch -# For bz#1038604 - make seabios 256k for rhel7 machine types -Patch15: seabios-build-explicitly-set-ROM-size.patch -# For bz#1034877 - export acpi tables to guests (seabios) -Patch16: seabios-biostables-support-looking-up-RSDP.patch -# For bz#1034877 - export acpi tables to guests (seabios) -Patch17: seabios-romfile_loader-utility-to-patch-in-memory-ROM-files.patch -# For bz#1034877 - export acpi tables to guests (seabios) -Patch18: seabios-acpi-load-and-link-tables-through-romfile-loader.patch -# For bz#979898 - [qemu-kvm]The win2k3-32 guest display is abnormal when using -vga cirrus -Patch19: seabios-vgabios-Fix-cirrus-memory-clear-on-mode-switch.patch -# For bz#1013418 - qemu-kvm with a virtio-scsi controler without devices attached quits after stop/cont in HMP/QMP -Patch20: seabios-init_virtio_scsi-reset-the-HBA-before-freeing-its-vi.patch -# For bz#1052837 - The wrong DMI structures could not be decoded while booting vm with -smbios params -Patch21: seabios-smbios-catch-zero-length-strings.patch -# For bz#1049860 - Guest agent command hang there after restore the guest from the save file -Patch22: seabios-resume-restore-piix-pm-config-registers-after-resume.patch -# For bz#1055832 - can not see seabios GUI when boot with 155 virtio-blk-pci disks via pci-bridge -Patch23: seabios-pci-align-64bit-pci-regions-to-1G.patch -# For bz#1055832 - can not see seabios GUI when boot with 155 virtio-blk-pci disks via pci-bridge -Patch24: seabios-pci-log-pci-windows.patch -# For bz#1055832 - can not see seabios GUI when boot with 155 virtio-blk-pci disks via pci-bridge -Patch25: seabios-pci-improve-io-address-space-allocation.patch + +Patch0002: seabios-Place-rpm-version-info-into-version-banner.patch +Patch0003: seabios-allow-1TB-of-RAM.patch +# For bz#1123299 - smbios table 0 vendor string should be Seabios (for rhel6 compatibility) [7.1+7.0.z] +Patch4: seabios-smbios-set-bios-vendor-version-fields-to-Seabios-0.5.patch # For bz#1050775 - [whql]KVM internal error. Suberror: 1 when win8.1-32 guest run HCK jobs -Patch26: seabios-Workaround-for-a-win8.1-32-S4-resume-bug.patch -# For bz#1124216 - smbios table 0 vendor string should be Seabios (for rhel6 compatibility) [7.1+7.0.z] -Patch27: seabios-smbios-set-bios-vendor-version-fields-to-Seabios-0.5.patch +Patch5: seabios-Workaround-for-a-win8.1-32-S4-resume-bug.patch +# For bz#1096560 - fail to assign correct order for the boot device in seabios as we specified the bootindex in qemu-kvm cli(under the same virtio-scsi-pci) +Patch6: seabios-boot-Fix-boot-order-for-SCSI-target-lun-9.patch BuildRequires: python iasl -ExclusiveArch: x86_64 +ExclusiveArch: x86_64 %{power64} Requires: %{name}-bin = %{version}-%{release} Requires: seavgabios-bin = %{version}-%{release} @@ -104,6 +59,7 @@ that a typical x86 proprietary BIOS implements. %package bin Summary: Seabios for x86 +BuildArch: noarch %description bin SeaBIOS is an open-source legacy BIOS implementation which can be used as @@ -113,6 +69,8 @@ that a typical x86 proprietary BIOS implements. %package -n seavgabios-bin Summary: Seavgabios for x86 +BuildArch: noarch + Obsoletes: vgabios < 0.6c-10 Provides: vgabios = 0.6c-10 @@ -123,64 +81,42 @@ SeaVGABIOS is an open-source VGABIOS implementation. %prep %setup -q -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 + +%patch0002 -p1 +%patch0003 -p1 %patch4 -p1 %patch5 -p1 %patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -%patch20 -p1 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 # Store version to be used echo "%{name}-%{version}-%release" > .version %build +%ifarch x86_64 export CFLAGS="$RPM_OPT_FLAGS" mkdir binaries +build_bios() { + make clean distclean + cp $1 .config + echo "CONFIG_DEBUG_LEVEL=%{debug_level}" >> .config + make oldnoconfig V=1 + + make V=1 $4 + + cp out/$2 binaries/$3 +} + # seabios 128k -cp %{SOURCE15} .config -make oldnoconfig V=1 -sed -i 's,CONFIG_DEBUG_LEVEL=.*,CONFIG_DEBUG_LEVEL=%{debug_level},g' .config -make -cp out/bios.bin binaries +build_bios %{SOURCE15} bios.bin bios.bin # seabios 256k -cp %{SOURCE16} .config -make oldnoconfig V=1 -sed -i 's,CONFIG_DEBUG_LEVEL=.*,CONFIG_DEBUG_LEVEL=%{debug_level},g' .config -make -cp out/bios.bin binaries/bios-256k.bin +build_bios %{SOURCE16} bios.bin bios-256k.bin # seavgabios for config in %{SOURCE10} %{SOURCE11} %{SOURCE12} %{SOURCE13} %{SOURCE14}; do name=${config#*config.vga.} - make clean distclean - cp ${config} .config - echo "CONFIG_DEBUG_LEVEL=%{debug_level}" >> .config - make oldnoconfig - make - cp out/vgabios.bin binaries/vgabios-${name}.bin + build_bios ${config} vgabios.bin vgabios-${name}.bin out/vgabios.bin done @@ -202,18 +138,41 @@ install -m 0644 binaries/vgabios*.bin $RPM_BUILD_ROOT%{_datadir}/seavgabios %files -n seavgabios-bin %dir %{_datadir}/seavgabios/ %{_datadir}/seavgabios/vgabios*.bin - +%endif %changelog -* Wed Aug 13 2014 Miroslav Rezanina - 1.7.2.2-12.el7_0.1 -- seabios-smbios-set-bios-vendor-version-fields-to-Seabios-0.5.patch [bz#1124216] -- Resolves: bz#1124216 - (smbios table 0 vendor string should be Seabios (for rhel6 compatibility) [7.1+7.0.z]) +* Tue Jan 20 2015 Miroslav Rezanina - 1.7.5-8.el7 +- seabios-turn-off-stack-switching-for-vgabios.patch [bz#1182634] +- Resolves: bz#1182634 + (Remove CONFIG_VGA_ALLOCATE_EXTRA_STACK) + +* Wed Jan 14 2015 jblazek@redhat.com - 1.7.5-7 +- rebuilt with rpm-4.11.1-25.el7 +- Resolves: bz#1163924 -* Tue Mar 11 2014 Miroslav Rezanina - 1.7.2.2-12.el7 +* Thu Nov 20 2014 Miroslav Rezanina - 1.7.5-6.el7 +- seabios-Extend-ExclusiveArch-to-power64-architectures.patch [bz#1163924] +- Resolves: bz#1163924 + (seabios is needed for ppc64 and ppc64le but marked ExclusiveArch aarch64) + +* Tue Aug 26 2014 Miroslav Rezanina - 1.7.5-5.el7 - seabios-Workaround-for-a-win8.1-32-S4-resume-bug.patch [bz#1050775] -- Resolves: bz#1050775 - ([whql]KVM internal error. Suberror: 1 when win8.1-32 guest run HCK jobs) +- seabios-boot-Fix-boot-order-for-SCSI-target-lun-9.patch [bz#1096560] +- Resolves: bz#1096560 + (fail to assign correct order for the boot device in seabios as we specified the bootindex in qemu-kvm cli(under the same virtio-scsi-pci)) + +* Wed Aug 13 2014 Miroslav Rezanina - 1.7.5-4.el7 +- seabios-smbios-set-bios-vendor-version-fields-to-Seabios-0.5.patch [bz#1123299] +- Resolves: bz#1123299 + (smbios table 0 vendor string should be Seabios (for rhel6 compatibility) [7.1+7.0.z]) + +* Sat Aug 02 2014 Miroslav Rezanina - 1.7.5-2.el7 +- seabios-Build-seabios-as-noarch.patch [bz#1118380] +- Resolves: bz#1118380 + (Seabios build required for ppc64) + +* Wed May 28 2014 Gerd Hoffmann - 1.7.5-1.el7 +- rebase to seabios 1.7.5 * Wed Feb 05 2014 Miroslav Rezanina - 1.7.2.2-11.el7 - seabios-init_virtio_scsi-reset-the-HBA-before-freeing-its-vi.patch [bz#1013418]