diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-02-19 10:50:37 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-02-19 10:50:37 +0000 |
commit | 09125c5e76923aa22a72f43cb34b6e74ae7fe17f (patch) | |
tree | f396e1b2e8c350741b88632c1700658c422bda15 /tests/boot-sector.c | |
parent | dd5e38b19d7cb07d317e1285941d8245c01da540 (diff) | |
parent | a28c393cc261afeb4863b05d7c33c2a5fc55ef38 (diff) | |
download | qemu-09125c5e76923aa22a72f43cb34b6e74ae7fe17f.zip qemu-09125c5e76923aa22a72f43cb34b6e74ae7fe17f.tar.gz qemu-09125c5e76923aa22a72f43cb34b6e74ae7fe17f.tar.bz2 |
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
vhost, virtio, pci, pxe
Fixes all over the place.
New tests for pxe.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
# gpg: Signature made Thu 18 Feb 2016 15:46:39 GMT using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg: aka "Michael S. Tsirkin <mst@redhat.com>"
* remotes/mst/tags/for_upstream:
tests/vhost-user-bridge: add scattering of incoming packets
vhost-user interrupt management fixes
rules: filter out irrelevant files
change type of pci_bridge_initfn() to void
dec: convert to realize()
tests: add pxe e1000 and virtio-pci tests
msix: fix msix_vector_masked
virtio: optimize virtio_access_is_big_endian() for little-endian targets
vhost: simplify vhost_needs_vring_endian()
vhost: move virtio 1.0 check to cross-endian helper
virtio: move cross-endian helper to vhost
vhost-net: revert support of cross-endian vnet headers
virtio-net: use the backend cross-endian capabilities
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests/boot-sector.c')
-rw-r--r-- | tests/boot-sector.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/tests/boot-sector.c b/tests/boot-sector.c new file mode 100644 index 0000000..0b48bb3 --- /dev/null +++ b/tests/boot-sector.c @@ -0,0 +1,119 @@ +/* + * QEMU boot sector testing helpers. + * + * Copyright (c) 2016 Red Hat Inc. + * + * Authors: + * Michael S. Tsirkin <mst@redhat.com> + * Victor Kaplansky <victork@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include "boot-sector.h" +#include <string.h> +#include <stdio.h> +#include "qemu-common.h" +#include "libqtest.h" + +#define LOW(x) ((x) & 0xff) +#define HIGH(x) ((x) >> 8) + +#define SIGNATURE 0xdead +#define SIGNATURE_OFFSET 0x10 +#define BOOT_SECTOR_ADDRESS 0x7c00 + +/* Boot sector code: write SIGNATURE into memory, + * then halt. + * Q35 machine requires a minimum 0x7e000 bytes disk. + * (bug or feature?) + */ +static uint8_t boot_sector[0x7e000] = { + /* The first sector will be placed at RAM address 00007C00, and + * the BIOS transfers control to 00007C00 + */ + + /* Data Segment register should be initialized, since pxe + * boot loader can leave it dirty. + */ + + /* 7c00: move $0000,%ax */ + [0x00] = 0xb8, + [0x01] = 0x00, + [0x02] = 0x00, + /* 7c03: move %ax,%ds */ + [0x03] = 0x8e, + [0x04] = 0xd8, + + /* 7c05: mov $0xdead,%ax */ + [0x05] = 0xb8, + [0x06] = LOW(SIGNATURE), + [0x07] = HIGH(SIGNATURE), + /* 7c08: mov %ax,0x7c10 */ + [0x08] = 0xa3, + [0x09] = LOW(BOOT_SECTOR_ADDRESS + SIGNATURE_OFFSET), + [0x0a] = HIGH(BOOT_SECTOR_ADDRESS + SIGNATURE_OFFSET), + + /* 7c0b cli */ + [0x0b] = 0xfa, + /* 7c0c: hlt */ + [0x0c] = 0xf4, + /* 7c0e: jmp 0x7c07=0x7c0f-3 */ + [0x0d] = 0xeb, + [0x0e] = LOW(-3), + /* We mov 0xdead here: set value to make debugging easier */ + [SIGNATURE_OFFSET] = LOW(0xface), + [SIGNATURE_OFFSET + 1] = HIGH(0xface), + /* End of boot sector marker */ + [0x1FE] = 0x55, + [0x1FF] = 0xAA, +}; + +/* Create boot disk file. */ +int boot_sector_init(const char *fname) +{ + FILE *f = fopen(fname, "w"); + + if (!f) { + fprintf(stderr, "Couldn't open \"%s\": %s", fname, strerror(errno)); + return 1; + } + fwrite(boot_sector, 1, sizeof boot_sector, f); + fclose(f); + return 0; +} + +/* Loop until signature in memory is OK. */ +void boot_sector_test(void) +{ + uint8_t signature_low; + uint8_t signature_high; + uint16_t signature; + int i; + + /* Wait at most 1 minute */ +#define TEST_DELAY (1 * G_USEC_PER_SEC / 10) +#define TEST_CYCLES MAX((60 * G_USEC_PER_SEC / TEST_DELAY), 1) + + /* Poll until code has run and modified memory. Once it has we know BIOS + * initialization is done. TODO: check that IP reached the halt + * instruction. + */ + for (i = 0; i < TEST_CYCLES; ++i) { + signature_low = readb(BOOT_SECTOR_ADDRESS + SIGNATURE_OFFSET); + signature_high = readb(BOOT_SECTOR_ADDRESS + SIGNATURE_OFFSET + 1); + signature = (signature_high << 8) | signature_low; + if (signature == SIGNATURE) { + break; + } + g_usleep(TEST_DELAY); + } + + g_assert_cmphex(signature, ==, SIGNATURE); +} + +/* unlink boot disk file. */ +void boot_sector_cleanup(const char *fname) +{ + unlink(fname); +} |