From 0d6b9cc7420dd2d531b48508f0d4083d1c6a632a Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Fri, 27 Jan 2012 19:44:53 +0100 Subject: [PATCH 1/5] signrom: Rewrite as python script Now that we have a hard dependency on python anyway, we can replace the slow shell script to calculate the option ROM checksum with a fast AND portable python version. Tested both with python 2.7 and 3.1. Signed-off-by: Jan Kiszka --- pc-bios/optionrom/Makefile | 2 +- scripts/signrom.py | 40 +++++++++++++++++++++++++++++++++ scripts/signrom.sh | 45 -------------------------------------- 3 files changed, 41 insertions(+), 46 deletions(-) create mode 100644 scripts/signrom.py delete mode 100755 scripts/signrom.sh diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile index f6b402713b..57d8bd0d6c 100644 --- a/pc-bios/optionrom/Makefile +++ b/pc-bios/optionrom/Makefile @@ -26,7 +26,7 @@ build-all: multiboot.bin linuxboot.bin kvmvapic.bin $(call quiet-command,$(OBJCOPY) -O binary -j .text $< $@," Building $(TARGET_DIR)$@") %.bin: %.raw - $(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/signrom.sh $< $@," Signing $(TARGET_DIR)$@") + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/signrom.py $< $@," Signing $(TARGET_DIR)$@") clean: rm -f *.o *.d *.raw *.img *.bin *~ diff --git a/scripts/signrom.py b/scripts/signrom.py new file mode 100644 index 0000000000..f9c35ccfca --- /dev/null +++ b/scripts/signrom.py @@ -0,0 +1,40 @@ +# +# Option ROM signing utility +# +# Authors: +# Jan Kiszka +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + +import sys +import struct + +if len(sys.argv) < 3: + print('usage: signrom.py input output') + sys.exit(1) + +fin = open(sys.argv[1], 'rb') +fout = open(sys.argv[2], 'wb') + +fin.seek(2) +size = ord(fin.read(1)) * 512 - 1 + +fin.seek(0) +data = fin.read(size) +fout.write(data) + +checksum = 0 +for b in data: + # catch Python 2 vs. 3 differences + if isinstance(b, int): + checksum += b + else: + checksum += ord(b) +checksum = (256 - checksum) % 256 + +# Python 3 no longer allows chr(checksum) +fout.write(struct.pack('B', checksum)) + +fin.close() +fout.close() diff --git a/scripts/signrom.sh b/scripts/signrom.sh deleted file mode 100755 index 9dc5c63dde..0000000000 --- a/scripts/signrom.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh - -# Option ROM Signing utility -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# Copyright Novell Inc, 2009 -# Authors: Alexander Graf -# -# Syntax: signrom.sh - -# did we get proper arguments? -test "$1" -a "$2" || exit 1 - -sum=0 - -# find out the file size -x=`dd if="$1" bs=1 count=1 skip=2 2>/dev/null | od -t u1 -A n` -#size=`expr $x \* 512 - 1` -size=$(( $x * 512 - 1 )) - -# now get the checksum -nums=`od -A n -t u1 -v -N $size "$1"` -for i in ${nums}; do - # add each byte's value to sum - sum=`expr \( $sum + $i \) % 256` -done - -sum=$(( (256 - $sum) % 256 )) -sum_octal=$( printf "%o" $sum ) - -# and write the output file -cp "$1" "$2" -printf "\\$sum_octal" | dd of="$2" bs=1 count=1 seek=$size conv=notrunc 2>/dev/null From 6655124ddd6442b19a4b43b27e7d5a3846c4e6a8 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 29 Feb 2012 15:33:48 +0100 Subject: [PATCH 2/5] pcnet: Clear ERR in CSR0 on stop pcnet_stop already clears any reason (BABL, CERR, MISS, MERR) why ERR (bit 15) should be set in CRS0. So we have to clear that bit as well. Signed-off-by: Jan Kiszka --- hw/pcnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/pcnet.c b/hw/pcnet.c index c53f06ef3b..7413409331 100644 --- a/hw/pcnet.c +++ b/hw/pcnet.c @@ -884,7 +884,7 @@ static void pcnet_stop(PCNetState *s) #ifdef PCNET_DEBUG printf("pcnet_stop\n"); #endif - s->csr[0] &= ~0x7feb; + s->csr[0] &= ~0xffeb; s->csr[0] |= 0x0014; s->csr[4] &= ~0x02c2; s->csr[5] &= ~0x0011; From ef45c9147f534531ef5d8a20315089d43ea4ddef Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 29 Feb 2012 15:37:43 +0100 Subject: [PATCH 3/5] pcnet: Properly handle TX requests during Link Fail As long as we have no link and we aren't in internal loopback mode, no packet must be sent. Instead, LCAR needs to be set in any active TX descriptor and also CERR in CSR0. Signed-off-by: Jan Kiszka --- hw/pcnet.c | 11 +++++++++++ hw/pcnet.h | 1 + 2 files changed, 12 insertions(+) diff --git a/hw/pcnet.c b/hw/pcnet.c index 7413409331..d769b08b78 100644 --- a/hw/pcnet.c +++ b/hw/pcnet.c @@ -77,6 +77,7 @@ struct qemu_ether_header { #define CSR_DTX(S) !!(((S)->csr[15])&0x0002) #define CSR_LOOP(S) !!(((S)->csr[15])&0x0004) #define CSR_DXMTFCS(S) !!(((S)->csr[15])&0x0008) +#define CSR_INTL(S) !!(((S)->csr[15])&0x0040) #define CSR_DRCVPA(S) !!(((S)->csr[15])&0x2000) #define CSR_DRCVBC(S) !!(((S)->csr[15])&0x4000) #define CSR_PROM(S) !!(((S)->csr[15])&0x8000) @@ -1234,6 +1235,15 @@ static void pcnet_transmit(PCNetState *s) if (BCR_SWSTYLE(s) != 1) add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS); } + if (s->lnkst == 0 && + (!CSR_LOOP(s) || (!CSR_INTL(s) && !BCR_TMAULOOP(s)))) { + SET_FIELD(&tmd.misc, TMDM, LCAR, 1); + SET_FIELD(&tmd.status, TMDS, ERR, 1); + SET_FIELD(&tmd.status, TMDS, OWN, 0); + s->csr[0] |= 0xa000; /* ERR | CERR */ + s->xmit_pos = -1; + goto txdone; + } if (!GET_FIELD(tmd.status, TMDS, ENP)) { int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), @@ -1262,6 +1272,7 @@ static void pcnet_transmit(PCNetState *s) s->xmit_pos = -1; } + txdone: SET_FIELD(&tmd.status, TMDS, OWN, 0); TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s))); if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT))) diff --git a/hw/pcnet.h b/hw/pcnet.h index edc81c90ac..803a2cc1ec 100644 --- a/hw/pcnet.h +++ b/hw/pcnet.h @@ -20,6 +20,7 @@ #define BCR_SWS 20 #define BCR_PLAT 22 +#define BCR_TMAULOOP(S) !!((S)->bcr[BCR_MC ] & 0x4000) #define BCR_APROMWE(S) !!((S)->bcr[BCR_MC ] & 0x0100) #define BCR_DWIO(S) !!((S)->bcr[BCR_BSBC] & 0x0080) #define BCR_SSIZE32(S) !!((S)->bcr[BCR_SWS ] & 0x0100) From 98c8ee1da81b88252263f9215ca23b2044650696 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Fri, 16 Mar 2012 13:18:00 +0100 Subject: [PATCH 4/5] Kick io-thread on qemu_chr_accept_input Once a chr frontend is able to receive input again, we need to inform the io-thread about this fact. Otherwise, main_loop_wait may continue to select without the related backend file descriptor in its set. This can cause high input latencies if only low-rate events arrive otherwise. Signed-off-by: Jan Kiszka --- qemu-char.c | 1 + 1 file changed, 1 insertion(+) diff --git a/qemu-char.c b/qemu-char.c index bb9e3f50a8..74c60e11a0 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -177,6 +177,7 @@ void qemu_chr_accept_input(CharDriverState *s) { if (s->chr_accept_input) s->chr_accept_input(s); + qemu_notify_event(); } void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) From 9bea6a2956e5d473b8914b2a5483fbf187b33844 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Thu, 29 Mar 2012 14:07:46 +0200 Subject: [PATCH 5/5] vapic: Disable for pre-1.1 machines The kvmvapic was not present in older QEMU versions, thus must be disabled in compat machines. Signed-off-by: Jan Kiszka --- hw/pc_piix.c | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index fadca4c710..44995bfdc1 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -373,6 +373,10 @@ static QEMUMachine pc_machine_v1_0 = { .driver = "isa-fdc", .property = "check_media_rate", .value = "off", + },{ + .driver = "apic", + .property = "vapic", + .value = "off", }, { /* end of list */ } }, @@ -392,6 +396,10 @@ static QEMUMachine pc_machine_v0_15 = { .driver = "isa-fdc", .property = "check_media_rate", .value = "off", + },{ + .driver = "apic", + .property = "vapic", + .value = "off", }, { /* end of list */ } }, @@ -431,11 +439,14 @@ static QEMUMachine pc_machine_v0_14 = { .driver = "isa-fdc", .property = "check_media_rate", .value = "off", - }, - { + },{ .driver = "pc-sysfw", .property = "rom_only", .value = stringify(1), + },{ + .driver = "apic", + .property = "vapic", + .value = "off", }, { /* end of list */ } }, @@ -487,11 +498,14 @@ static QEMUMachine pc_machine_v0_13 = { .driver = "isa-fdc", .property = "check_media_rate", .value = "off", - }, - { + },{ .driver = "pc-sysfw", .property = "rom_only", .value = stringify(1), + },{ + .driver = "apic", + .property = "vapic", + .value = "off", }, { /* end of list */ } }, @@ -547,11 +561,14 @@ static QEMUMachine pc_machine_v0_12 = { .driver = "isa-fdc", .property = "check_media_rate", .value = "off", - }, - { + },{ .driver = "pc-sysfw", .property = "rom_only", .value = stringify(1), + },{ + .driver = "apic", + .property = "vapic", + .value = "off", }, { /* end of list */ } } @@ -615,11 +632,14 @@ static QEMUMachine pc_machine_v0_11 = { .driver = "isa-fdc", .property = "check_media_rate", .value = "off", - }, - { + },{ .driver = "pc-sysfw", .property = "rom_only", .value = stringify(1), + },{ + .driver = "apic", + .property = "vapic", + .value = "off", }, { /* end of list */ } } @@ -695,11 +715,14 @@ static QEMUMachine pc_machine_v0_10 = { .driver = "isa-fdc", .property = "check_media_rate", .value = "off", - }, - { + },{ .driver = "pc-sysfw", .property = "rom_only", .value = stringify(1), + },{ + .driver = "apic", + .property = "vapic", + .value = "off", }, { /* end of list */ } },