* [PATCH 0/9] kvm-unit-tests/arm: initial drop
@ 2013-10-14 16:23 Andrew Jones
2013-10-14 16:23 ` [PATCH 1/9] remove unused files Andrew Jones
` (10 more replies)
0 siblings, 11 replies; 38+ messages in thread
From: Andrew Jones @ 2013-10-14 16:23 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
This series introduces arm to kvm-unit-tests. First, it does some
tidying up of the repo. Then, it adds support for virtio-testdev,
which was just posted to qemu-devel[1]. Next, it adds the basic
infrastructure for booting a test case (guest). Finally, it adds
support for vectors. This is just an initial drop, I'm starting
work on smp support now, and then will bring in support for
arm64. At that point we should be able to start actually adding
tests. To use this you need an arm platform or simulator capable
of running kvmarm and a qemu with the mach-virt patches[2], as
well as the previously mentioned virtio-testdev.
[1] http://lists.nongnu.org/archive/html/qemu-devel/2013-10/msg01815.html
[2] http://lists.nongnu.org/archive/html/qemu-devel/2013-09/msg02142.html
This patches are also available from a git repo here
https://github.com/rhdrjones/kvm-unit-tests/tree/arm-branch/master
Andrew Jones (9):
remove unused files
makefile and run_tests tweaks
clean root dir of all x86-ness
Introduce a simple iomap structure
Add halt() and some error codes
Introduce virtio-testdev
arm: replace arbitrary divisions
arm: initial drop
arm: add vectors support
Makefile | 19 +-
README | 56 ++--
arm/boot.c | 46 +++
arm/cstart.S | 93 ++++++
arm/flat.lds | 18 ++
arm/run | 19 ++
arm/unittests.cfg | 17 +
config-i386.mak | 13 -
config-ia64.mak | 7 -
config-powerpc-440.mak | 15 -
config-powerpc.mak | 39 ---
config-x86-common.mak | 122 --------
config-x86_64.mak | 14 -
config/config-arm.mak | 63 ++++
config/config-i386.mak | 12 +
config/config-x86-common.mak | 120 +++++++
config/config-x86_64.mak | 13 +
configure | 27 +-
docs/testdev.txt | 11 +
flat.lds | 21 --
formats | 31 --
iotable.c | 53 ----
iotable.h | 40 ---
kvmtrace.c | 706 ------------------------------------------
kvmtrace_format | 532 -------------------------------
lib/arm/bootinfo.c | 68 ++++
lib/arm/bootinfo.h | 19 ++
lib/arm/bswap.h | 30 ++
lib/arm/io.c | 26 ++
lib/arm/processor.h | 45 +++
lib/arm/vectors.c | 65 ++++
lib/arm/vectors.h | 37 +++
lib/bswap.h | 11 +
lib/divmod.h | 20 ++
lib/errno.h | 15 +
lib/fwcfg.c | 58 ----
lib/iomaps.c | 12 +
lib/iomaps.h | 12 +
lib/libcflat.h | 16 +-
lib/panic.c | 13 -
lib/powerpc/44x/map.c | 51 ---
lib/powerpc/44x/timebase.S | 28 --
lib/powerpc/44x/timebase.h | 25 --
lib/powerpc/44x/tlbwe.S | 29 --
lib/powerpc/io.c | 35 ---
lib/printf.c | 27 +-
lib/virtio-testdev.c | 126 ++++++++
lib/virtio-testdev.h | 9 +
lib/x86/io.c | 6 +
main-ppc.c | 383 -----------------------
powerpc/44x/tlbsx.S | 33 --
powerpc/44x/tlbwe.S | 27 --
powerpc/44x/tlbwe_16KB.S | 35 ---
powerpc/44x/tlbwe_hole.S | 27 --
powerpc/cstart.S | 38 ---
powerpc/exit.c | 23 --
powerpc/helloworld.c | 27 --
powerpc/io.S | 32 --
powerpc/spin.S | 4 -
powerpc/sprg.S | 7 -
run_tests.sh | 19 +-
scripts/gen-devtree-iomaps.pl | 81 +++++
testdev.txt | 14 -
x86-run | 41 ---
x86/README | 60 +++-
x86/flat.lds | 21 ++
x86/print.h | 19 --
x86/run | 41 +++
x86/run-kvm-unit-tests | 6 -
69 files changed, 1195 insertions(+), 2633 deletions(-)
create mode 100644 arm/boot.c
create mode 100644 arm/cstart.S
create mode 100644 arm/flat.lds
create mode 100755 arm/run
create mode 100644 arm/unittests.cfg
delete mode 100644 config-i386.mak
delete mode 100644 config-ia64.mak
delete mode 100644 config-powerpc-440.mak
delete mode 100644 config-powerpc.mak
delete mode 100644 config-x86-common.mak
delete mode 100644 config-x86_64.mak
create mode 100644 config/config-arm.mak
create mode 100644 config/config-i386.mak
create mode 100644 config/config-x86-common.mak
create mode 100644 config/config-x86_64.mak
create mode 100644 docs/testdev.txt
delete mode 100644 flat.lds
delete mode 100644 formats
delete mode 100644 iotable.c
delete mode 100644 iotable.h
delete mode 100644 kvmtrace.c
delete mode 100755 kvmtrace_format
create mode 100644 lib/arm/bootinfo.c
create mode 100644 lib/arm/bootinfo.h
create mode 100644 lib/arm/bswap.h
create mode 100644 lib/arm/io.c
create mode 100644 lib/arm/processor.h
create mode 100644 lib/arm/vectors.c
create mode 100644 lib/arm/vectors.h
create mode 100644 lib/bswap.h
create mode 100644 lib/divmod.h
create mode 100644 lib/errno.h
delete mode 100644 lib/fwcfg.c
create mode 100644 lib/iomaps.c
create mode 100644 lib/iomaps.h
delete mode 100644 lib/panic.c
delete mode 100644 lib/powerpc/44x/map.c
delete mode 100644 lib/powerpc/44x/timebase.S
delete mode 100644 lib/powerpc/44x/timebase.h
delete mode 100644 lib/powerpc/44x/tlbwe.S
delete mode 100644 lib/powerpc/io.c
create mode 100644 lib/virtio-testdev.c
create mode 100644 lib/virtio-testdev.h
delete mode 100644 main-ppc.c
delete mode 100644 powerpc/44x/tlbsx.S
delete mode 100644 powerpc/44x/tlbwe.S
delete mode 100644 powerpc/44x/tlbwe_16KB.S
delete mode 100644 powerpc/44x/tlbwe_hole.S
delete mode 100644 powerpc/cstart.S
delete mode 100644 powerpc/exit.c
delete mode 100644 powerpc/helloworld.c
delete mode 100644 powerpc/io.S
delete mode 100644 powerpc/spin.S
delete mode 100644 powerpc/sprg.S
create mode 100755 scripts/gen-devtree-iomaps.pl
delete mode 100644 testdev.txt
delete mode 100755 x86-run
create mode 100644 x86/flat.lds
delete mode 100644 x86/print.h
create mode 100755 x86/run
delete mode 100644 x86/run-kvm-unit-tests
--
1.8.1.4
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 1/9] remove unused files
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
@ 2013-10-14 16:23 ` Andrew Jones
2013-10-16 12:52 ` Gleb Natapov
2013-10-14 16:23 ` [PATCH 2/9] makefile and run_tests tweaks Andrew Jones
` (9 subsequent siblings)
10 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-14 16:23 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
There are several unused files, primarily because powerpc is an unused
arch. The exceptions are config-ia64.mak, which is also an unused arch
file, lib/fwcfg.c, lib/panic.c, x86/print.h and x86/run-kvm-unit-tests,
which are just unused. Remove them all in order to tidy things up.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
Makefile | 8 +-
config-ia64.mak | 7 -
config-powerpc-440.mak | 15 -
config-powerpc.mak | 39 ---
formats | 31 --
iotable.c | 53 ----
iotable.h | 40 ---
kvmtrace.c | 706 ---------------------------------------------
kvmtrace_format | 532 ----------------------------------
lib/fwcfg.c | 58 ----
lib/libcflat.h | 1 -
lib/panic.c | 13 -
lib/powerpc/44x/map.c | 51 ----
lib/powerpc/44x/timebase.S | 28 --
lib/powerpc/44x/timebase.h | 25 --
lib/powerpc/44x/tlbwe.S | 29 --
lib/powerpc/io.c | 35 ---
main-ppc.c | 383 ------------------------
powerpc/44x/tlbsx.S | 33 ---
powerpc/44x/tlbwe.S | 27 --
powerpc/44x/tlbwe_16KB.S | 35 ---
powerpc/44x/tlbwe_hole.S | 27 --
powerpc/cstart.S | 38 ---
powerpc/exit.c | 23 --
powerpc/helloworld.c | 27 --
powerpc/io.S | 32 --
powerpc/spin.S | 4 -
powerpc/sprg.S | 7 -
x86/print.h | 19 --
x86/run-kvm-unit-tests | 6 -
30 files changed, 1 insertion(+), 2331 deletions(-)
delete mode 100644 config-ia64.mak
delete mode 100644 config-powerpc-440.mak
delete mode 100644 config-powerpc.mak
delete mode 100644 formats
delete mode 100644 iotable.c
delete mode 100644 iotable.h
delete mode 100644 kvmtrace.c
delete mode 100755 kvmtrace_format
delete mode 100644 lib/fwcfg.c
delete mode 100644 lib/panic.c
delete mode 100644 lib/powerpc/44x/map.c
delete mode 100644 lib/powerpc/44x/timebase.S
delete mode 100644 lib/powerpc/44x/timebase.h
delete mode 100644 lib/powerpc/44x/tlbwe.S
delete mode 100644 lib/powerpc/io.c
delete mode 100644 main-ppc.c
delete mode 100644 powerpc/44x/tlbsx.S
delete mode 100644 powerpc/44x/tlbwe.S
delete mode 100644 powerpc/44x/tlbwe_16KB.S
delete mode 100644 powerpc/44x/tlbwe_hole.S
delete mode 100644 powerpc/cstart.S
delete mode 100644 powerpc/exit.c
delete mode 100644 powerpc/helloworld.c
delete mode 100644 powerpc/io.S
delete mode 100644 powerpc/spin.S
delete mode 100644 powerpc/sprg.S
delete mode 100644 x86/print.h
delete mode 100644 x86/run-kvm-unit-tests
diff --git a/Makefile b/Makefile
index b6e87598721a6..278791dbbef23 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,6 @@ libgcc := $(shell $(CC) --print-libgcc-file-name)
libcflat := lib/libcflat.a
cflatobjs := \
- lib/panic.o \
lib/printf.o \
lib/string.o
cflatobjs += lib/argv.o
@@ -39,11 +38,6 @@ autodepend-flags = -MMD -MF $(dir $*).$(notdir $*).d
LDFLAGS += $(CFLAGS)
LDFLAGS += -pthread -lrt
-kvmtrace_objs= kvmtrace.o
-
-kvmtrace: $(kvmtrace_objs)
- $(CC) $(LDFLAGS) $^ -o $@
-
$(libcflat): $(cflatobjs)
$(AR) rcs $@ $^
@@ -57,4 +51,4 @@ install:
install $(tests_and_config) $(DESTDIR)
clean: arch_clean
- $(RM) kvmtrace *.o *.a .*.d $(libcflat) $(cflatobjs)
+ $(RM) *.o *.a .*.d $(libcflat) $(cflatobjs)
diff --git a/config-ia64.mak b/config-ia64.mak
deleted file mode 100644
index d9350fcc5a9ec..0000000000000
--- a/config-ia64.mak
+++ /dev/null
@@ -1,7 +0,0 @@
-bits = 64
-CFLAGS += -m64
-CFLAGS += -D__ia64__
-CFLAGS += -I../include/ia64
-
-all:
-
diff --git a/config-powerpc-440.mak b/config-powerpc-440.mak
deleted file mode 100644
index bb8597153b30e..0000000000000
--- a/config-powerpc-440.mak
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-# for some reason binutils hates tlbsx unless we say we're 405 :(
-CFLAGS += -Wa,-m405 -I lib/powerpc/44x
-
-cflatobjs += \
- lib/powerpc/44x/map.o \
- lib/powerpc/44x/tlbwe.o \
- lib/powerpc/44x/timebase.o
-
-simpletests += \
- powerpc/44x/tlbsx.bin \
- powerpc/44x/tlbwe_16KB.bin \
- powerpc/44x/tlbwe_hole.bin \
- powerpc/44x/tlbwe.bin
diff --git a/config-powerpc.mak b/config-powerpc.mak
deleted file mode 100644
index d053569b8aa3c..0000000000000
--- a/config-powerpc.mak
+++ /dev/null
@@ -1,39 +0,0 @@
-CFLAGS += -I../include/powerpc
-CFLAGS += -Wa,-mregnames -I lib
-CFLAGS += -ffreestanding
-
-cstart := powerpc/cstart.o
-
-cflatobjs += \
- lib/powerpc/io.o
-
-$(libcflat): LDFLAGS += -nostdlib
-
-# these tests do not use libcflat
-simpletests := \
- powerpc/spin.bin \
- powerpc/io.bin \
- powerpc/sprg.bin
-
-# theses tests use cstart.o, libcflat, and libgcc
-tests := \
- powerpc/exit.bin \
- powerpc/helloworld.bin
-
-include config-powerpc-$(PROCESSOR).mak
-
-
-all: kvmtrace kvmctl $(libcflat) $(simpletests) $(tests)
-
-$(simpletests): %.bin: %.o
- $(CC) -nostdlib $^ -Wl,-T,flat.lds -o $@
-
-$(tests): %.bin: $(cstart) %.o $(libcflat)
- $(CC) -nostdlib $^ $(libgcc) -Wl,-T,flat.lds -o $@
-
-kvmctl_objs = main-ppc.o iotable.o ../libkvm/libkvm.a
-
-arch_clean:
- $(RM) $(simpletests) $(tests) $(cstart)
- $(RM) $(patsubst %.bin, %.elf, $(simpletests) $(tests))
- $(RM) $(patsubst %.bin, %.o, $(simpletests) $(tests))
diff --git a/formats b/formats
deleted file mode 100644
index 7f4ebdbcedaa2..0000000000000
--- a/formats
+++ /dev/null
@@ -1,31 +0,0 @@
-0x00000000 %(ts)d (+%(relts)12d) unknown (0x%(event)016x) vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ 0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x ]
-
-0x00010001 %(ts)d (+%(relts)12d) VMENTRY vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x
-0x00010002 %(ts)d (+%(relts)12d) VMEXIT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ exitcode = 0x%(1)08x, rip = 0x%(3)08x %(2)08x ]
-0x00020001 %(ts)d (+%(relts)12d) PAGE_FAULT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
-0x00020002 %(ts)d (+%(relts)12d) INJ_VIRQ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
-0x00020003 %(ts)d (+%(relts)12d) REDELIVER_EVT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
-0x00020004 %(ts)d (+%(relts)12d) PEND_INTR vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
-0x00020005 %(ts)d (+%(relts)12d) IO_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ]
-0x00020006 %(ts)d (+%(relts)12d) IO_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ]
-0x00020007 %(ts)d (+%(relts)12d) CR_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ]
-0x00020008 %(ts)d (+%(relts)12d) CR_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ]
-0x00020009 %(ts)d (+%(relts)12d) DR_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ]
-0x0002000A %(ts)d (+%(relts)12d) DR_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ]
-0x0002000B %(ts)d (+%(relts)12d) MSR_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ]
-0x0002000C %(ts)d (+%(relts)12d) MSR_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ]
-0x0002000D %(ts)d (+%(relts)12d) CPUID vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ func = 0x%(1)08x, eax = 0x%(2)08x, ebx = 0x%(3)08x, ecx = 0x%(4)08x edx = 0x%(5)08x]
-0x0002000E %(ts)d (+%(relts)12d) INTR vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
-0x0002000F %(ts)d (+%(relts)12d) NMI vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x
-0x00020010 %(ts)d (+%(relts)12d) VMMCALL vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ func = 0x%(1)08x ]
-0x00020011 %(ts)d (+%(relts)12d) HLT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x
-0x00020012 %(ts)d (+%(relts)12d) CLTS vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x
-0x00020013 %(ts)d (+%(relts)12d) LMSW vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ value = 0x%(1)08x ]
-0x00020014 %(ts)d (+%(relts)12d) APIC_ACCESS vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ offset = 0x%(1)08x ]
-0x00020015 %(ts)d (+%(relts)12d) TDP_FAULT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
-# ppc: tlb traces
-0x00020016 GTLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
-0x00020017 STLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
-0x00020018 STLB_INVAL vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
-# ppc: instruction emulation - this type is handled more complex in kvmtrace_format, but listed to show the eventid and transported data
-#0x00020019 %(ts)d (+%(relts)12d) PPC_INSTR vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ instr = 0x%(1)08x, pc = 0x%(2)08x, emul = 0x%(3)08x, nsec = %(4)08d ]
diff --git a/iotable.c b/iotable.c
deleted file mode 100644
index 91a5016c42005..0000000000000
--- a/iotable.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Kernel-based Virtual Machine test driver
- *
- * This test driver provides a simple way of testing kvm, without a full
- * device model.
- *
- * Copyright (C) 2006 Qumranet
- *
- * Authors:
- *
- * Avi Kivity <avi@qumranet.com>
- * Yaniv Kamay <yaniv@qumranet.com>
- *
- * This work is licensed under the GNU LGPL license, version 2.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <errno.h>
-
-#include "iotable.h"
-
-struct io_table_entry *io_table_lookup(struct io_table *io_table, uint64_t addr)
-{
- int i;
-
- for (i = 0; i < io_table->nr_entries; i++) {
- if (io_table->entries[i].start <= addr &&
- addr < io_table->entries[i].end)
- return &io_table->entries[i];
- }
-
- return NULL;
-}
-
-int io_table_register(struct io_table *io_table, uint64_t start, uint64_t size,
- io_table_handler_t *handler, void *opaque)
-{
- struct io_table_entry *entry;
-
- if (io_table->nr_entries == MAX_IO_TABLE)
- return -ENOSPC;
-
- entry = &io_table->entries[io_table->nr_entries];
- io_table->nr_entries++;
-
- entry->start = start;
- entry->end = start + size;
- entry->handler = handler;
- entry->opaque = opaque;
-
- return 0;
-}
diff --git a/iotable.h b/iotable.h
deleted file mode 100644
index cb18f23789be1..0000000000000
--- a/iotable.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Kernel-based Virtual Machine test driver
- *
- * This test driver provides a simple way of testing kvm, without a full
- * device model.
- *
- * Copyright (C) 2006 Qumranet
- *
- * Authors:
- *
- * Avi Kivity <avi@qumranet.com>
- * Yaniv Kamay <yaniv@qumranet.com>
- *
- * This work is licensed under the GNU LGPL license, version 2.
- */
-
-#include <stdint.h>
-
-#define MAX_IO_TABLE 50
-
-typedef int (io_table_handler_t)(void *, int, int, uint64_t, uint64_t *);
-
-struct io_table_entry
-{
- uint64_t start;
- uint64_t end;
- io_table_handler_t *handler;
- void *opaque;
-};
-
-struct io_table
-{
- int nr_entries;
- struct io_table_entry entries[MAX_IO_TABLE];
-};
-
-struct io_table_entry *io_table_lookup(struct io_table *io_table,
- uint64_t addr);
-int io_table_register(struct io_table *io_table, uint64_t start, uint64_t size,
- io_table_handler_t *handler, void *opaque);
diff --git a/kvmtrace.c b/kvmtrace.c
deleted file mode 100644
index de3c1897f4660..0000000000000
--- a/kvmtrace.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * kvm tracing application
- *
- * This tool is used for collecting trace buffer data
- * for kvm trace.
- *
- * Based on blktrace 0.99.3
- *
- * Copyright (C) 2005 Jens Axboe <axboe@suse.de>
- * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
- * Copyright (C) 2008 Eric Liu <eric.e.liu@intel.com>
- *
- * This work is licensed under the GNU LGPL license, version 2.
- */
-
-#define _GNU_SOURCE
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/statfs.h>
-#include <sys/poll.h>
-#include <sys/mman.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <getopt.h>
-#include <errno.h>
-#include <sched.h>
-
-#ifndef __user
-#define __user
-#endif
-#include <linux/kvm.h>
-
-static char kvmtrace_version[] = "0.1";
-
-/*
- * You may want to increase this even more, if you are logging at a high
- * rate and see skipped/missed events
- */
-#define BUF_SIZE (512 * 1024)
-#define BUF_NR (8)
-
-#define OFILE_BUF (128 * 1024)
-
-#define DEBUGFS_TYPE 0x64626720
-
-#define max(a, b) ((a) > (b) ? (a) : (b))
-
-#define S_OPTS "r:o:w:?Vb:n:D:"
-static struct option l_opts[] = {
- {
- .name = "relay",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'r'
- },
- {
- .name = "output",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'o'
- },
- {
- .name = "stopwatch",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'w'
- },
- {
- .name = "version",
- .has_arg = no_argument,
- .flag = NULL,
- .val = 'V'
- },
- {
- .name = "buffer-size",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'b'
- },
- {
- .name = "num-sub-buffers",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'n'
- },
- {
- .name = "output-dir",
- .has_arg = required_argument,
- .flag = NULL,
- .val = 'D'
- },
- {
- .name = NULL,
- }
-};
-
-struct thread_information {
- int cpu;
- pthread_t thread;
-
- int fd;
- char fn[MAXPATHLEN + 64];
-
- FILE *ofile;
- char *ofile_buffer;
-
- int (*get_subbuf)(struct thread_information *, unsigned int);
- int (*read_data)(struct thread_information *, void *, unsigned int);
-
- unsigned long long data_read;
-
- struct kvm_trace_information *trace_info;
-
- int exited;
-
- /*
- * mmap controlled output files
- */
- unsigned long long fs_size;
- unsigned long long fs_max_size;
- unsigned long fs_off;
- void *fs_buf;
- unsigned long fs_buf_len;
-
-};
-
-struct kvm_trace_information {
- int fd;
- volatile int trace_started;
- unsigned long lost_records;
- struct thread_information *threads;
- unsigned long buf_size;
- unsigned long buf_nr;
-};
-
-static struct kvm_trace_information trace_information;
-
-static int ncpus;
-static char default_debugfs_path[] = "/sys/kernel/debug";
-
-/* command line option globals */
-static char *debugfs_path;
-static char *output_name;
-static char *output_dir;
-static int stop_watch;
-static unsigned long buf_size = BUF_SIZE;
-static unsigned long buf_nr = BUF_NR;
-static unsigned int page_size;
-
-#define for_each_cpu_online(cpu) \
- for (cpu = 0; cpu < ncpus; cpu++)
-#define for_each_tip(tip, i) \
- for (i = 0, tip = trace_information.threads; i < ncpus; i++, tip++)
-
-#define is_done() (*(volatile int *)(&done))
-static volatile int done;
-
-#define is_trace_stopped() (*(volatile int *)(&trace_stopped))
-static volatile int trace_stopped;
-
-static void exit_trace(int status);
-
-static void handle_sigint(__attribute__((__unused__)) int sig)
-{
- ioctl(trace_information.fd, KVM_TRACE_PAUSE);
- done = 1;
-}
-
-static int get_lost_records()
-{
- int fd;
- char tmp[MAXPATHLEN + 64];
-
- snprintf(tmp, sizeof(tmp), "%s/kvm/lost_records", debugfs_path);
- fd = open(tmp, O_RDONLY);
- if (fd < 0) {
- /*
- * this may be ok, if the kernel doesn't support dropped counts
- */
- if (errno == ENOENT)
- return 0;
-
- fprintf(stderr, "Couldn't open dropped file %s\n", tmp);
- return -1;
- }
-
- if (read(fd, tmp, sizeof(tmp)) < 0) {
- perror(tmp);
- close(fd);
- return -1;
- }
- close(fd);
-
- return atoi(tmp);
-}
-
-static void wait_for_data(struct thread_information *tip, int timeout)
-{
- struct pollfd pfd = { .fd = tip->fd, .events = POLLIN };
-
- while (!is_done()) {
- if (poll(&pfd, 1, timeout) < 0) {
- perror("poll");
- break;
- }
- if (pfd.revents & POLLIN)
- break;
- }
-}
-
-static int read_data(struct thread_information *tip, void *buf,
- unsigned int len)
-{
- int ret = 0;
-
- do {
- wait_for_data(tip, 100);
-
- ret = read(tip->fd, buf, len);
-
- if (!ret)
- continue;
- else if (ret > 0)
- return ret;
- else {
- if (errno != EAGAIN) {
- perror(tip->fn);
- fprintf(stderr, "Thread %d failed read of %s\n",
- tip->cpu, tip->fn);
- break;
- }
- continue;
- }
- } while (!is_done());
-
- return ret;
-
-}
-
-/*
- * For file output, truncate and mmap the file appropriately
- */
-static int mmap_subbuf(struct thread_information *tip, unsigned int maxlen)
-{
- int ofd = fileno(tip->ofile);
- int ret;
- unsigned long nr;
- unsigned long size;
-
- /*
- * extend file, if we have to. use chunks of 16 subbuffers.
- */
- if (tip->fs_off + maxlen > tip->fs_buf_len) {
- if (tip->fs_buf) {
- munlock(tip->fs_buf, tip->fs_buf_len);
- munmap(tip->fs_buf, tip->fs_buf_len);
- tip->fs_buf = NULL;
- }
-
- tip->fs_off = tip->fs_size & (page_size - 1);
- nr = max(16, tip->trace_info->buf_nr);
- size = tip->trace_info->buf_size;
- tip->fs_buf_len = (nr * size) - tip->fs_off;
- tip->fs_max_size += tip->fs_buf_len;
-
- if (ftruncate(ofd, tip->fs_max_size) < 0) {
- perror("ftruncate");
- return -1;
- }
-
- tip->fs_buf = mmap(NULL, tip->fs_buf_len, PROT_WRITE,
- MAP_SHARED, ofd, tip->fs_size - tip->fs_off);
- if (tip->fs_buf == MAP_FAILED) {
- perror("mmap");
- return -1;
- }
- mlock(tip->fs_buf, tip->fs_buf_len);
- }
-
- ret = tip->read_data(tip, tip->fs_buf + tip->fs_off, maxlen);
- if (ret >= 0) {
- tip->data_read += ret;
- tip->fs_size += ret;
- tip->fs_off += ret;
- return 0;
- }
-
- return -1;
-}
-
-static void tip_ftrunc_final(struct thread_information *tip)
-{
- /*
- * truncate to right size and cleanup mmap
- */
- if (tip->ofile) {
- int ofd = fileno(tip->ofile);
-
- if (tip->fs_buf)
- munmap(tip->fs_buf, tip->fs_buf_len);
-
- ftruncate(ofd, tip->fs_size);
- }
-}
-
-static void *thread_main(void *arg)
-{
- struct thread_information *tip = arg;
- pid_t pid = getpid();
- cpu_set_t cpu_mask;
-
- CPU_ZERO(&cpu_mask);
- CPU_SET((tip->cpu), &cpu_mask);
-
- if (sched_setaffinity(pid, sizeof(cpu_mask), &cpu_mask) == -1) {
- perror("sched_setaffinity");
- exit_trace(1);
- }
-
- snprintf(tip->fn, sizeof(tip->fn), "%s/kvm/trace%d",
- debugfs_path, tip->cpu);
- tip->fd = open(tip->fn, O_RDONLY);
- if (tip->fd < 0) {
- perror(tip->fn);
- fprintf(stderr, "Thread %d failed open of %s\n", tip->cpu,
- tip->fn);
- exit_trace(1);
- }
- while (!is_done()) {
- if (tip->get_subbuf(tip, tip->trace_info->buf_size) < 0)
- break;
- }
-
- /*
- * trace is stopped, pull data until we get a short read
- */
- while (tip->get_subbuf(tip, tip->trace_info->buf_size) > 0)
- ;
-
- tip_ftrunc_final(tip);
- tip->exited = 1;
- return NULL;
-}
-
-static int fill_ofname(struct thread_information *tip, char *dst)
-{
- struct stat sb;
- int len = 0;
-
- if (output_dir)
- len = sprintf(dst, "%s/", output_dir);
- else
- len = sprintf(dst, "./");
-
- if (stat(dst, &sb) < 0) {
- if (errno != ENOENT) {
- perror("stat");
- return 1;
- }
- if (mkdir(dst, 0755) < 0) {
- perror(dst);
- fprintf(stderr, "Can't make output dir\n");
- return 1;
- }
- }
-
- sprintf(dst + len, "%s.kvmtrace.%d", output_name, tip->cpu);
-
- return 0;
-}
-
-static void fill_ops(struct thread_information *tip)
-{
- tip->get_subbuf = mmap_subbuf;
- tip->read_data = read_data;
-}
-
-static void close_thread(struct thread_information *tip)
-{
- if (tip->fd != -1)
- close(tip->fd);
- if (tip->ofile)
- fclose(tip->ofile);
- if (tip->ofile_buffer)
- free(tip->ofile_buffer);
-
- tip->fd = -1;
- tip->ofile = NULL;
- tip->ofile_buffer = NULL;
-}
-
-static int tip_open_output(struct thread_information *tip)
-{
- int mode, vbuf_size;
- char op[NAME_MAX];
-
- if (fill_ofname(tip, op))
- return 1;
-
- tip->ofile = fopen(op, "w+");
- mode = _IOFBF;
- vbuf_size = OFILE_BUF;
-
- if (tip->ofile == NULL) {
- perror(op);
- return 1;
- }
-
- tip->ofile_buffer = malloc(vbuf_size);
- if (setvbuf(tip->ofile, tip->ofile_buffer, mode, vbuf_size)) {
- perror("setvbuf");
- close_thread(tip);
- return 1;
- }
-
- fill_ops(tip);
- return 0;
-}
-
-static int start_threads(int cpu)
-{
- struct thread_information *tip;
-
- tip = trace_information.threads + cpu;
- tip->cpu = cpu;
- tip->trace_info = &trace_information;
- tip->fd = -1;
-
- if (tip_open_output(tip))
- return 1;
-
- if (pthread_create(&tip->thread, NULL, thread_main, tip)) {
- perror("pthread_create");
- close_thread(tip);
- return 1;
- }
-
- return 0;
-}
-
-static void stop_threads()
-{
- struct thread_information *tip;
- unsigned long ret;
- int i;
-
- for_each_tip(tip, i) {
- if (tip->thread)
- (void) pthread_join(tip->thread, (void *) &ret);
- close_thread(tip);
- }
-}
-
-static int start_trace(void)
-{
- int fd;
- struct kvm_user_trace_setup kuts;
-
- fd = trace_information.fd = open("/dev/kvm", O_RDWR);
- if (fd == -1) {
- perror("/dev/kvm");
- return 1;
- }
-
- memset(&kuts, 0, sizeof(kuts));
- kuts.buf_size = trace_information.buf_size = buf_size;
- kuts.buf_nr = trace_information.buf_nr = buf_nr;
-
- if (ioctl(trace_information.fd , KVM_TRACE_ENABLE, &kuts) < 0) {
- perror("KVM_TRACE_ENABLE");
- close(fd);
- return 1;
- }
- trace_information.trace_started = 1;
-
- return 0;
-}
-
-static void cleanup_trace(void)
-{
- if (trace_information.fd == -1)
- return;
-
- trace_information.lost_records = get_lost_records();
-
- if (trace_information.trace_started) {
- trace_information.trace_started = 0;
- if (ioctl(trace_information.fd, KVM_TRACE_DISABLE) < 0)
- perror("KVM_TRACE_DISABLE");
- }
-
- close(trace_information.fd);
- trace_information.fd = -1;
-}
-
-static void stop_all_traces(void)
-{
- if (!is_trace_stopped()) {
- trace_stopped = 1;
- stop_threads();
- cleanup_trace();
- }
-}
-
-static void exit_trace(int status)
-{
- stop_all_traces();
- exit(status);
-}
-
-static int start_kvm_trace(void)
-{
- int i, size;
- struct thread_information *tip;
-
- size = ncpus * sizeof(struct thread_information);
- tip = malloc(size);
- if (!tip) {
- fprintf(stderr, "Out of memory, threads (%d)\n", size);
- return 1;
- }
- memset(tip, 0, size);
- trace_information.threads = tip;
-
- if (start_trace())
- return 1;
-
- for_each_cpu_online(i) {
- if (start_threads(i)) {
- fprintf(stderr, "Failed to start worker threads\n");
- break;
- }
- }
-
- if (i != ncpus) {
- stop_threads();
- cleanup_trace();
- return 1;
- }
-
- return 0;
-}
-
-static void wait_for_threads(void)
-{
- struct thread_information *tip;
- int i, tips_running;
-
- do {
- tips_running = 0;
- usleep(100000);
-
- for_each_tip(tip, i)
- tips_running += !tip->exited;
-
- } while (tips_running);
-}
-
-static void show_stats(void)
-{
- struct thread_information *tip;
- unsigned long long data_read;
- int i;
-
- data_read = 0;
- for_each_tip(tip, i) {
- printf(" CPU%3d: %8llu KiB data\n",
- tip->cpu, (tip->data_read + 1023) >> 10);
- data_read += tip->data_read;
- }
-
- printf(" Total: lost %lu, %8llu KiB data\n",
- trace_information.lost_records, (data_read + 1023) >> 10);
-
- if (trace_information.lost_records)
- fprintf(stderr, "You have lost records, "
- "consider using a larger buffer size (-b)\n");
-}
-
-static char usage_str[] = \
- "[ -r debugfs path ] [ -D output dir ] [ -b buffer size ]\n" \
- "[ -n number of buffers] [ -o <output file> ] [ -w time ] [ -V ]\n\n" \
- "\t-r Path to mounted debugfs, defaults to /sys/kernel/debug\n" \
- "\t-o File(s) to send output to\n" \
- "\t-D Directory to prepend to output file names\n" \
- "\t-w Stop after defined time, in seconds\n" \
- "\t-b Sub buffer size in KiB\n" \
- "\t-n Number of sub buffers\n" \
- "\t-V Print program version info\n\n";
-
-static void show_usage(char *prog)
-{
- fprintf(stderr, "Usage: %s %s %s", prog, kvmtrace_version, usage_str);
- exit(EXIT_FAILURE);
-}
-
-void parse_args(int argc, char **argv)
-{
- int c;
-
- while ((c = getopt_long(argc, argv, S_OPTS, l_opts, NULL)) >= 0) {
- switch (c) {
- case 'r':
- debugfs_path = optarg;
- break;
- case 'o':
- output_name = optarg;
- break;
- case 'w':
- stop_watch = atoi(optarg);
- if (stop_watch <= 0) {
- fprintf(stderr,
- "Invalid stopwatch value (%d secs)\n",
- stop_watch);
- exit(EXIT_FAILURE);
- }
- break;
- case 'V':
- printf("%s version %s\n", argv[0], kvmtrace_version);
- exit(EXIT_SUCCESS);
- case 'b':
- buf_size = strtoul(optarg, NULL, 10);
- if (buf_size <= 0 || buf_size > 16*1024) {
- fprintf(stderr,
- "Invalid buffer size (%lu)\n",
- buf_size);
- exit(EXIT_FAILURE);
- }
- buf_size <<= 10;
- break;
- case 'n':
- buf_nr = strtoul(optarg, NULL, 10);
- if (buf_nr <= 0) {
- fprintf(stderr,
- "Invalid buffer nr (%lu)\n", buf_nr);
- exit(EXIT_FAILURE);
- }
- break;
- case 'D':
- output_dir = optarg;
- break;
- default:
- show_usage(argv[0]);
- }
- }
-
- if (optind < argc || output_name == NULL)
- show_usage(argv[0]);
-}
-
-int main(int argc, char *argv[])
-{
- struct statfs st;
-
- parse_args(argc, argv);
-
- if (!debugfs_path)
- debugfs_path = default_debugfs_path;
-
- if (statfs(debugfs_path, &st) < 0) {
- perror("statfs");
- fprintf(stderr, "%s does not appear to be a valid path\n",
- debugfs_path);
- return 1;
- } else if (st.f_type != (long) DEBUGFS_TYPE) {
- fprintf(stderr, "%s does not appear to be a debug filesystem,"
- " please mount debugfs.\n",
- debugfs_path);
- return 1;
- }
-
- page_size = getpagesize();
-
- ncpus = sysconf(_SC_NPROCESSORS_ONLN);
- if (ncpus < 0) {
- fprintf(stderr, "sysconf(_SC_NPROCESSORS_ONLN) failed\n");
- return 1;
- }
-
- signal(SIGINT, handle_sigint);
- signal(SIGHUP, handle_sigint);
- signal(SIGTERM, handle_sigint);
- signal(SIGALRM, handle_sigint);
- signal(SIGPIPE, SIG_IGN);
-
- if (start_kvm_trace() != 0)
- return 1;
-
- if (stop_watch)
- alarm(stop_watch);
-
- wait_for_threads();
- stop_all_traces();
- show_stats();
-
- return 0;
-}
diff --git a/kvmtrace_format b/kvmtrace_format
deleted file mode 100755
index 6556475f726c4..0000000000000
--- a/kvmtrace_format
+++ /dev/null
@@ -1,532 +0,0 @@
-#!/usr/bin/env python
-
-# by Mark Williamson, (C) 2004 Intel Research Cambridge
-
-# Program for reformatting trace buffer output according to user-supplied rules
-
-import re, sys, string, signal, struct, os, getopt, operator
-
-PREFIX = '/usr'
-DATADIR = os.path.join(PREFIX, 'share')
-KVMDIR = os.path.join(DATADIR, 'kvm')
-FORMATS_FILE = os.path.join(KVMDIR, 'formats')
-
-def usage():
- print >> sys.stderr, \
- "Usage: " + sys.argv[0] + """ defs-file
- Parses trace data in binary format, as output by kvmtrace and
- reformats it according to the rules in a file of definitions. The
- rules in this file should have the format ({ and } show grouping
- and are not part of the syntax):
-
- {event_id}{whitespace}{text format string}
-
- The textual format string may include format specifiers, such as:
- %(ts)d, %(event)d, %(pid)d %(vcpu)d %(1)d, %(2)d,
- %(3)d, %(4)d, %(5)d
- [ the 'd' format specifier outputs in decimal, alternatively 'x'
- will output in hexadecimal and 'o' will output in octal ]
-
- Which correspond to the event ID, timestamp counter, pid
- , vcpu and the 5 data fields from the trace record. There should be
- one such rule for each type of event.
- Depending on your system and the volume of trace buffer data,
- this script may not be able to keep up with the output of kvmtrace
- if it is piped directly. In these circumstances you should have
- kvmtrace output to a file for processing off-line.
-
- kvmtrace_format has the following additional switches
- -s - if this switch is set additional trace statistics are
- created and printed at the end of the output
- """
- sys.exit(1)
-
-def read_defs(defs_file):
- defs = {}
-
- fd = open(defs_file)
-
- reg = re.compile('(\S+)\s+(\S.*)')
-
- while True:
- line = fd.readline()
- if not line:
- break
-
- if line[0] == '#' or line[0] == '\n':
- continue
-
- m = reg.match(line)
-
- if not m: print >> sys.stderr, "Bad format file" ; sys.exit(1)
-
- defs[str(eval(m.group(1)))] = m.group(2)
-
- return defs
-
-def sighand(x,y):
- global interrupted
- interrupted = 1
-
-# ppc instruction decoding for event type 0x00020019 (PPC_INSTR)
-# some globals for statistic summaries
-stat_ppc_instr_mnemonic = {};
-stat_ppc_instr_spr = {};
-stat_ppc_instr_dcr = {};
-stat_ppc_instr_tlb = {};
-
-def ppc_instr_print_summary(sortedlist, colname):
- print "\n\n%14s + %10s" % (colname, "count")
- print "%s" % (15*"-"+"+"+11*"-")
- sum = 0
- for value, key in sortedlist:
- sum += key
- print "%14s | %10d" % (value, key)
- print "%14s = %10d" % ("sum", sum)
-
-
-def ppc_instr_summary():
- # don't print empty statistics
- if stat_ppc_instr_mnemonic:
- ppc_instr_print_summary(sorted(stat_ppc_instr_mnemonic.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic")
- if stat_ppc_instr_spr:
- ppc_instr_print_summary(sorted(stat_ppc_instr_spr.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-spr")
- if stat_ppc_instr_dcr:
- ppc_instr_print_summary(sorted(stat_ppc_instr_dcr.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-dcr")
- if stat_ppc_instr_tlb:
- ppc_instr_print_summary(sorted(stat_ppc_instr_tlb.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-tlb")
-
-def get_op(instr):
- return (instr >> 26);
-
-def get_xop(instr):
- return (instr >> 1) & 0x3ff;
-
-def get_sprn(instr):
- return ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0)
-
-def get_dcrn(instr):
- return ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
-
-def get_tlbwe_type(instr):
- ws = (instr >> 11) & 0x1f;
- if ws == 0:
- return "PAGEID"
- elif ws == 1:
- return "XLAT"
- elif ws == 2:
- return "ATTRIB"
- else:
- return "UNKNOWN"
-
-def get_name(instr):
- if get_op(instr)==3:
- return "trap"
- elif get_op(instr)==19:
- if get_xop(instr) == 50:
- return "rfi"
- else:
- return "unknown"
- elif get_op(instr)==31:
- if get_xop(instr) == 83:
- return "mfmsr"
-
- elif get_xop(instr) == 87:
- return "lbzx"
-
- elif get_xop(instr) == 131:
- return "wrtee"
-
- elif get_xop(instr) == 146:
- return "mtmsr"
-
- elif get_xop(instr) == 163:
- return "wrteei"
-
- elif get_xop(instr) == 215:
- return "stbx"
-
- elif get_xop(instr) == 247:
- return "stbux"
-
- elif get_xop(instr) == 279:
- return "lhzx"
-
- elif get_xop(instr) == 311:
- return "lhzux"
-
- elif get_xop(instr) == 323:
- return "mfdcr"
-
- elif get_xop(instr) == 339:
- return "mfspr"
-
- elif get_xop(instr) == 407:
- return "sthx"
-
- elif get_xop(instr) == 439:
- return "sthux"
-
- elif get_xop(instr) == 451:
- return "mtdcr"
-
- elif get_xop(instr) == 467:
- return "mtspr"
-
- elif get_xop(instr) == 470:
- return "dcbi"
-
- elif get_xop(instr) == 534:
- return "lwbrx"
-
- elif get_xop(instr) == 566:
- return "tlbsync"
-
- elif get_xop(instr) == 662:
- return "stwbrx"
-
- elif get_xop(instr) == 978:
- return "tlbwe"
-
- elif get_xop(instr) == 914:
- return "tlbsx"
-
- elif get_xop(instr) == 790:
- return "lhbrx"
-
- elif get_xop(instr) == 918:
- return "sthbrx"
-
- elif get_xop(instr) == 966:
- return "iccci"
-
- else:
- return "unknown"
-
- elif get_op(instr) == 32:
- return "lwz"
-
- elif get_op(instr) == 33:
- return "lwzu"
-
- elif get_op(instr) == 34:
- return "lbz"
-
- elif get_op(instr) == 35:
- return "lbzu"
-
- elif get_op(instr) == 36:
- return "stw"
-
- elif get_op(instr) == 37:
- return "stwu"
-
- elif get_op(instr) == 38:
- return "stb"
-
- elif get_op(instr) == 39:
- return "stbu"
-
- elif get_op(instr) == 40:
- return "lhz"
-
- elif get_op(instr) == 41:
- return "lhzu"
-
- elif get_op(instr) == 44:
- return "sth"
-
- elif get_op(instr) == 45:
- return "sthu"
-
- else:
- return "unknown"
-
-def get_sprn_name(sprn):
- if sprn == 0x01a:
- return "SRR0"
- elif sprn == 0x01b:
- return "SRR1"
- elif sprn == 0x3b2:
- return "MMUCR"
- elif sprn == 0x030:
- return "PID"
- elif sprn == 0x03f:
- return "IVPR"
- elif sprn == 0x3b3:
- return "CCR0"
- elif sprn == 0x378:
- return "CCR1"
- elif sprn == 0x11f:
- return "PVR"
- elif sprn == 0x03d:
- return "DEAR"
- elif sprn == 0x03e:
- return "ESR"
- elif sprn == 0x134:
- return "DBCR0"
- elif sprn == 0x135:
- return "DBCR1"
- elif sprn == 0x11c:
- return "TBWL"
- elif sprn == 0x11d:
- return "TBWU"
- elif sprn == 0x016:
- return "DEC"
- elif sprn == 0x150:
- return "TSR"
- elif sprn == 0x154:
- return "TCR"
- elif sprn == 0x110:
- return "SPRG0"
- elif sprn == 0x111:
- return "SPRG1"
- elif sprn == 0x112:
- return "SPRG2"
- elif sprn == 0x113:
- return "SPRG3"
- elif sprn == 0x114:
- return "SPRG4"
- elif sprn == 0x115:
- return "SPRG5"
- elif sprn == 0x116:
- return "SPRG6"
- elif sprn == 0x117:
- return "SPRG7"
- elif sprn == 0x190:
- return "IVOR0"
- elif sprn == 0x191:
- return "IVOR1"
- elif sprn == 0x192:
- return "IVOR2"
- elif sprn == 0x193:
- return "IVOR3"
- elif sprn == 0x194:
- return "IVOR4"
- elif sprn == 0x195:
- return "IVOR5"
- elif sprn == 0x196:
- return "IVOR6"
- elif sprn == 0x197:
- return "IVOR7"
- elif sprn == 0x198:
- return "IVOR8"
- elif sprn == 0x199:
- return "IVOR9"
- elif sprn == 0x19a:
- return "IVOR10"
- elif sprn == 0x19b:
- return "IVOR11"
- elif sprn == 0x19c:
- return "IVOR12"
- elif sprn == 0x19d:
- return "IVOR13"
- elif sprn == 0x19e:
- return "IVOR14"
- elif sprn == 0x19f:
- return "IVOR15"
- else:
- return "UNKNOWN"
-
-def get_special(instr):
- name = get_name(instr);
- if stat_ppc_instr_mnemonic.has_key(name):
- stat_ppc_instr_mnemonic[name] += 1
- else:
- stat_ppc_instr_mnemonic[name] = 1
-
- if get_op(instr) == 31:
- if (get_xop(instr) == 339) or (get_xop(instr) == 467):
- sprn = get_sprn(instr);
- sprn_name = get_sprn_name(sprn);
- stat_idx = name+"-"+sprn_name
- if stat_ppc_instr_spr.has_key(stat_idx):
- stat_ppc_instr_spr[stat_idx] += 1
- else:
- stat_ppc_instr_spr[stat_idx] = 1
- return ("- sprn 0x%03x %8s" % (sprn, sprn_name))
- elif (get_xop(instr) == 323 ) or (get_xop(instr) == 451):
- dcrn = get_dcrn(instr);
- stat_idx = name+"-"+("%04X"%dcrn)
- if stat_ppc_instr_dcr.has_key(stat_idx):
- stat_ppc_instr_dcr[stat_idx] += 1
- else:
- stat_ppc_instr_dcr[stat_idx] = 1
- return ("- dcrn 0x%03x" % dcrn)
- elif (get_xop(instr) == 978 ) or (get_xop(instr) == 451):
- tlbwe_type = get_tlbwe_type(instr)
- stat_idx = name+"-"+tlbwe_type
- if stat_ppc_instr_tlb.has_key(stat_idx):
- stat_ppc_instr_tlb[stat_idx] += 1
- else:
- stat_ppc_instr_tlb[stat_idx] = 1
- return ("- ws -> %8s" % tlbwe_type)
- return ""
-
-##### Main code
-
-summary = False
-
-try:
- opts, arg = getopt.getopt(sys.argv[1:], "sc:" )
- for opt in opts:
- if opt[0] == '-s' : summary = True
-
-except getopt.GetoptError:
- usage()
-
-signal.signal(signal.SIGTERM, sighand)
-signal.signal(signal.SIGHUP, sighand)
-signal.signal(signal.SIGINT, sighand)
-
-interrupted = 0
-
-if len(arg) > 0:
- defs = read_defs(arg[0])
-else:
- defs = read_defs(FORMATS_FILE)
-
-# structure of trace record (as output by kvmtrace):
-# HDR(I) {TSC(Q)} D1(I) D2(I) D3(I) D4(I) D5(I)
-#
-# HDR consists of EVENT:28:, n_data:3:, ts_in:1:
-# pid:32, vcpu_id:32
-# EVENT means Event ID
-# n_data means number of data (like D1, D2, ...)
-# ts_in means Timestamp data exists(1) or not(0).
-# if ts_in == 0, TSC(Q) does not exists.
-#
-HDRREC = "<III"
-TSCREC = "<Q"
-D1REC = "<I"
-D2REC = "<II"
-D3REC = "<III"
-D4REC = "<IIII"
-D5REC = "<IIIII"
-KMAGIC = "<I"
-
-last_ts = 0
-
-i=0
-
-while not interrupted:
- try:
- i=i+1
-
- if i == 1:
- line = sys.stdin.read(struct.calcsize(KMAGIC))
- if not line:
- break
- kmgc = struct.unpack(KMAGIC, line)[0]
-
- #firstly try to parse data file as little endian
- # if "kvmtrace-metadata".kmagic != kmagic
- # then data file must be big endian"
- if kmgc != 0x12345678:
- if kmgc != 0x78563412:
- print >> sys.stderr, "Bad data file: magic number error."
- break;
- else:
- HDRREC = ">III"
- TSCREC = ">Q"
- D1REC = ">I"
- D2REC = ">II"
- D3REC = ">III"
- D4REC = ">IIII"
- D5REC = ">IIIII"
- continue
-
- line = sys.stdin.read(struct.calcsize(HDRREC))
- if not line:
- break
- (event, pid, vcpu_id) = struct.unpack(HDRREC, line)
-
- n_data = event >> 28 & 0x7
- ts_in = event >> 31
-
- d1 = 0
- d2 = 0
- d3 = 0
- d4 = 0
- d5 = 0
-
- ts = 0
-
- if ts_in == 1:
- line = sys.stdin.read(struct.calcsize(TSCREC))
- if not line:
- break
- ts = struct.unpack(TSCREC, line)[0]
- if n_data == 1:
- line = sys.stdin.read(struct.calcsize(D1REC))
- if not line:
- break
- d1 = struct.unpack(D1REC, line)[0]
- if n_data == 2:
- line = sys.stdin.read(struct.calcsize(D2REC))
- if not line:
- break
- (d1, d2) = struct.unpack(D2REC, line)
- if n_data == 3:
- line = sys.stdin.read(struct.calcsize(D3REC))
- if not line:
- break
- (d1, d2, d3) = struct.unpack(D3REC, line)
- if n_data == 4:
- line = sys.stdin.read(struct.calcsize(D4REC))
- if not line:
- break
- (d1, d2, d3, d4) = struct.unpack(D4REC, line)
- if n_data == 5:
- line = sys.stdin.read(struct.calcsize(D5REC))
- if not line:
- break
- (d1, d2, d3, d4, d5) = struct.unpack(D5REC, line)
-
- event &= 0x0fffffff
-
- # provide relative TSC
-
- if last_ts > 0 and ts_in == 1:
- relts = ts - last_ts
- else:
- relts = 0
-
- if ts_in == 1:
- last_ts = ts
-
- args = {'ts' : ts,
- 'event' : event,
- 'relts': relts,
- 'pid' : pid,
- 'vcpu' : vcpu_id,
- '1' : d1,
- '2' : d2,
- '3' : d3,
- '4' : d4,
- '5' : d5 }
-
- # some event types need more than just formats mapping they are if/elif
- # chained here and the last default else is the mapping via formats
- if event == 0x00020019:
- pdata = (ts, relts, vcpu_id, pid, d1, d2, d3, get_name(d1), get_special(d1))
- print "%d (+%12d) PPC_INSTR vcpu = 0x%08x pid = 0x%08x [ instr = 0x%08x, pc = 0x%08x, emul = %01d, mnemonic = %8s %s" % pdata
- else:
- try:
- if defs.has_key(str(event)):
- print defs[str(event)] % args
- else:
- if defs.has_key(str(0)): print defs[str(0)] % args
- except TypeError:
- if defs.has_key(str(event)):
- print defs[str(event)]
- print args
- else:
- if defs.has_key(str(0)):
- print defs[str(0)]
- print args
-
- except IOError, struct.error: sys.exit()
-
-if summary:
- ppc_instr_summary()
diff --git a/lib/fwcfg.c b/lib/fwcfg.c
deleted file mode 100644
index dc34d299df766..0000000000000
--- a/lib/fwcfg.c
+++ /dev/null
@@ -1,58 +0,0 @@
-
-void qemu_cfg_select(int f)
-{
- outw(QEMU_CFG_CTL_PORT, f);
-}
-
-int qemu_cfg_port_probe()
-{
- char *sig = "QEMU";
- int i;
-
- qemu_cfg_select(QEMU_CFG_SIGNATURE);
-
- for (i = 0; i < 4; i++)
- if (inb(QEMU_CFG_DATA_PORT) != sig[i])
- return 0;
-
- return 1;
-}
-
-void qemu_cfg_read(uint8_t *buf, int len)
-{
- while (len--)
- *(buf++) = inb(QEMU_CFG_DATA_PORT);
-}
-
-uint8_t qemu_cfg_get8(void)
-{
- uint8_t ret;
-
- qemu_cfg_read(&ret, 1);
- return ret;
-}
-
-uint16_t qemu_cfg_get16(void)
-{
- uint16_t ret;
-
- qemu_cfg_read((uint8_t*)&ret, 2);
- return le16_to_cpu(ret);
-}
-
-uint64_t qemu_cfg_get32(void)
-{
- uint32_t ret;
-
- qemu_cfg_read((uint8_t*)&ret, 4);
- return le32_to_cpu(ret);
-}
-
-uint64_t qemu_cfg_get64(void)
-{
- uint64_t ret;
-
- qemu_cfg_read((uint8_t*)&ret, 8);
- return le64_to_cpu(ret);
-}
-
diff --git a/lib/libcflat.h b/lib/libcflat.h
index fadc33d30f85b..140c172e77d54 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -38,7 +38,6 @@ typedef _Bool bool;
#define false 0
extern void exit(int code);
-extern void panic(char *fmt, ...);
extern unsigned long strlen(const char *buf);
extern char *strcat(char *dest, const char *src);
diff --git a/lib/panic.c b/lib/panic.c
deleted file mode 100644
index 6e0b29ebed503..0000000000000
--- a/lib/panic.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "libcflat.h"
-
-void panic(char *fmt, ...)
-{
- va_list va;
- char buf[2000];
-
- va_start(va, fmt);
- vsnprintf(buf, sizeof(buf), fmt, va);
- va_end(va);
- puts(buf);
- exit(-1);
-}
diff --git a/lib/powerpc/44x/map.c b/lib/powerpc/44x/map.c
deleted file mode 100644
index 113434d2f1b4d..0000000000000
--- a/lib/powerpc/44x/map.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * 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, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright IBM Corp. 2008
- *
- * Authors: Hollis Blanchard <hollisb@us.ibm.com>
- */
-
-#include "libcflat.h"
-
-#define TLB_SIZE 64
-
-extern void tlbwe(unsigned int index,
- unsigned char tid,
- unsigned int word0,
- unsigned int word1,
- unsigned int word2);
-
-unsigned int next_free_index;
-
-#define PAGE_SHIFT 12
-#define PAGE_MASK (~((1<<PAGE_SHIFT)-1))
-
-#define V (1<<9)
-
-void map(unsigned long vaddr, unsigned long paddr)
-{
- unsigned int w0, w1, w2;
-
- /* We don't install exception handlers, so we can't handle TLB misses,
- * so we can't loop around and overwrite entry 0. */
- if (next_free_index++ >= TLB_SIZE)
- panic("TLB overflow");
-
- w0 = (vaddr & PAGE_MASK) | V;
- w1 = paddr & PAGE_MASK;
- w2 = 0x3;
-
- tlbwe(next_free_index, 0, w0, w1, w2);
-}
diff --git a/lib/powerpc/44x/timebase.S b/lib/powerpc/44x/timebase.S
deleted file mode 100644
index 385904da3c161..0000000000000
--- a/lib/powerpc/44x/timebase.S
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * 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, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright IBM Corp. 2008
- *
- * Authors: Hollis Blanchard <hollisb@us.ibm.com>
- */
-
-/* unsigned long long mftb(void); */
-.global mftb
-mftb:
- mftbu r5
- mftbl r4
- mftbu r3
- cmpw r3, r5
- bne mftb
- blr
diff --git a/lib/powerpc/44x/timebase.h b/lib/powerpc/44x/timebase.h
deleted file mode 100644
index ce85347bd17c5..0000000000000
--- a/lib/powerpc/44x/timebase.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * 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, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright IBM Corp. 2008
- *
- * Authors: Hollis Blanchard <hollisb@us.ibm.com>
- */
-
-#ifndef __TIMEBASE_H__
-#define __TIMEBASE_H__
-
-unsigned long long mftb(void);
-
-#endif /* __TIMEBASE_H__ */
diff --git a/lib/powerpc/44x/tlbwe.S b/lib/powerpc/44x/tlbwe.S
deleted file mode 100644
index 3790374eb5c61..0000000000000
--- a/lib/powerpc/44x/tlbwe.S
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * 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, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright IBM Corp. 2008
- *
- * Authors: Hollis Blanchard <hollisb@us.ibm.com>
- */
-
-#define SPRN_MMUCR 0x3b2
-
-/* tlbwe(uint index, uint8_t tid, uint word0, uint word1, uint word2) */
-.global tlbwe
-tlbwe:
- mtspr SPRN_MMUCR, r4
- tlbwe r5, r3, 0
- tlbwe r6, r3, 1
- tlbwe r7, r3, 2
- blr
diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
deleted file mode 100644
index 8bd239521f25f..0000000000000
--- a/lib/powerpc/io.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * 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, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright IBM Corp. 2008
- *
- * Authors: Hollis Blanchard <hollisb@us.ibm.com>
- */
-
-#include "libcflat.h"
-
-#define BASE 0xf0000000
-#define _putc ((volatile char *)(BASE))
-#define _exit ((volatile char *)(BASE+1))
-
-void puts(const char *s)
-{
- while (*s != '\0')
- *_putc = *s++;
-}
-
-void exit(int code)
-{
- *_exit = code;
-}
diff --git a/main-ppc.c b/main-ppc.c
deleted file mode 100644
index 5af59f846ef07..0000000000000
--- a/main-ppc.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Kernel-based Virtual Machine test driver
- *
- * This test driver provides a simple way of testing kvm, without a full
- * device model.
- *
- * Copyright (C) 2006 Qumranet
- * Copyright IBM Corp. 2008
- *
- * Authors:
- *
- * Avi Kivity <avi@qumranet.com>
- * Yaniv Kamay <yaniv@qumranet.com>
- * Hollis Blanchard <hollisb@us.ibm.com>
- *
- * This work is licensed under the GNU LGPL license, version 2.
- */
-
-#define _GNU_SOURCE
-
-#include <libkvm.h>
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <semaphore.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-#include <pthread.h>
-#include <sys/syscall.h>
-#include <linux/unistd.h>
-#include <getopt.h>
-#include <stdbool.h>
-#include <inttypes.h>
-
-#include "iotable.h"
-
-static int gettid(void)
-{
- return syscall(__NR_gettid);
-}
-
-kvm_context_t kvm;
-
-#define IPI_SIGNAL (SIGRTMIN + 4)
-
-struct io_table mmio_table;
-
-static int ncpus = 1;
-static sem_t exited_sem;
-static __thread int vcpu;
-static sigset_t kernel_sigmask;
-static sigset_t ipi_sigmask;
-static uint64_t memory_size = 128 * 1024 * 1024;
-
-struct vcpu_info {
- pid_t tid;
-};
-
-struct vcpu_info *vcpus;
-
-/* Must match flat.lds linker script */
-#define VM_TEST_LOAD_ADDRESS 0x100000
-
-static int test_debug(void *opaque, void *vcpu)
-{
- printf("test_debug\n");
- return 0;
-}
-
-static int test_halt(void *opaque, int vcpu)
-{
- int n;
-
- sigwait(&ipi_sigmask, &n);
- return 0;
-}
-
-static int test_io_window(void *opaque)
-{
- return 0;
-}
-
-static int test_try_push_interrupts(void *opaque)
-{
- return 0;
-}
-
-static void test_post_kvm_run(void *opaque, void *vcpu)
-{
-}
-
-static int test_pre_kvm_run(void *opaque, void *vcpu)
-{
- return 0;
-}
-
-static int mmio_handler(void *opaque, int len, int is_write, uint64_t offset,
- uint64_t *data)
-{
- int r = 0;
-
- switch (offset) {
- case 0: /* putc */
- putc(*(char *)data, stdout);
- fflush(stdout);
- break;
- case 1: /* exit */
- r = *(char *)data;
- break;
- default:
- printf("%s: offset %"PRIx64" len %d data %"PRIx64"\n",
- __func__, offset, len, *(uint64_t *)data);
- r = -EINVAL;
- }
-
- return r;
-}
-
-static int test_mem_read(void *opaque, uint64_t addr, uint8_t *data, int len)
-{
- struct io_table_entry *iodev;
-
-#if 0
- printf("%s: addr %"PRIx64" len %d\n", __func__, addr, len);
-#endif
-
- iodev = io_table_lookup(&mmio_table, addr);
- if (!iodev) {
- printf("couldn't find device\n");
- return -ENODEV;
- }
-
- return iodev->handler(iodev->opaque, len, 0, addr - iodev->start,
- (uint64_t *)data);
-}
-
-static int test_mem_write(void *opaque, uint64_t addr, uint8_t *data, int len)
-{
- struct io_table_entry *iodev;
-
-#if 0
- printf("%s: addr %"PRIx64" len %d data %"PRIx64"\n",
- __func__, addr, len, *(uint64_t *)data);
-#endif
-
- iodev = io_table_lookup(&mmio_table, addr);
- if (!iodev) {
- printf("couldn't find device\n");
- return -ENODEV;
- }
-
- return iodev->handler(iodev->opaque, len, 1, addr - iodev->start,
- (uint64_t *)data);
-}
-
-static int test_dcr_read(int vcpu, uint32_t dcrn, uint32_t *data)
-{
- printf("%s: dcrn %04X\n", __func__, dcrn);
- *data = 0;
- return 0;
-}
-
-static int test_dcr_write(int vcpu, uint32_t dcrn, uint32_t data)
-{
- printf("%s: dcrn %04X data %04X\n", __func__, dcrn, data);
- return 0;
-}
-
-static struct kvm_callbacks test_callbacks = {
- .mmio_read = test_mem_read,
- .mmio_write = test_mem_write,
- .debug = test_debug,
- .halt = test_halt,
- .io_window = test_io_window,
- .try_push_interrupts = test_try_push_interrupts,
- .post_kvm_run = test_post_kvm_run,
- .pre_kvm_run = test_pre_kvm_run,
- .powerpc_dcr_read = test_dcr_read,
- .powerpc_dcr_write = test_dcr_write,
-};
-
-static unsigned long load_file(void *mem, const char *fname, int inval_icache)
-{
- ssize_t r;
- int fd;
- unsigned long bytes = 0;
-
- fd = open(fname, O_RDONLY);
- if (fd == -1) {
- perror("open");
- exit(1);
- }
-
- while ((r = read(fd, mem, 4096)) != -1 && r != 0) {
- mem += r;
- bytes += r;
- }
-
- if (r == -1) {
- perror("read");
- printf("read %d bytes\n", bytes);
- exit(1);
- }
-
- return bytes;
-}
-
-#define ICACHE_LINE_SIZE 32
-
-void sync_caches(void *mem, unsigned long len)
-{
- unsigned long i;
-
- for (i = 0; i < len; i += ICACHE_LINE_SIZE)
- asm volatile ("dcbst %0, %1" : : "g"(mem), "r"(i));
- asm volatile ("sync");
- for (i = 0; i < len; i += ICACHE_LINE_SIZE)
- asm volatile ("icbi %0, %1" : : "g"(mem), "r"(i));
- asm volatile ("sync; isync");
-}
-
-static void init_vcpu(int n)
-{
- sigemptyset(&ipi_sigmask);
- sigaddset(&ipi_sigmask, IPI_SIGNAL);
- sigprocmask(SIG_UNBLOCK, &ipi_sigmask, NULL);
- sigprocmask(SIG_BLOCK, &ipi_sigmask, &kernel_sigmask);
- vcpus[n].tid = gettid();
- vcpu = n;
- kvm_set_signal_mask(kvm, n, &kernel_sigmask);
-}
-
-static void *do_create_vcpu(void *_n)
-{
- struct kvm_regs regs;
- int n = (long)_n;
-
- kvm_create_vcpu(kvm, n);
- init_vcpu(n);
-
- kvm_get_regs(kvm, n, ®s);
- regs.pc = VM_TEST_LOAD_ADDRESS;
- kvm_set_regs(kvm, n, ®s);
-
- kvm_run(kvm, n, &vcpus[n]);
- sem_post(&exited_sem);
- return NULL;
-}
-
-static void start_vcpu(int n)
-{
- pthread_t thread;
-
- pthread_create(&thread, NULL, do_create_vcpu, (void *)(long)n);
-}
-
-static void usage(const char *progname)
-{
- fprintf(stderr,
-"Usage: %s [OPTIONS] [bootstrap] flatfile\n"
-"KVM test harness.\n"
-"\n"
-" -s, --smp=NUM create a VM with NUM virtual CPUs\n"
-" -m, --memory=NUM[GMKB] allocate NUM memory for virtual machine. A suffix\n"
-" can be used to change the unit (default: `M')\n"
-" -h, --help display this help screen and exit\n"
-"\n"
-"Report bugs to <kvm-ppc@vger.kernel.org>.\n"
- , progname);
-}
-
-static void sig_ignore(int sig)
-{
- write(1, "boo\n", 4);
-}
-
-int main(int argc, char **argv)
-{
- void *vm_mem;
- unsigned long len;
- int i;
- const char *sopts = "s:phm:";
- struct option lopts[] = {
- { "smp", 1, 0, 's' },
- { "memory", 1, 0, 'm' },
- { "help", 0, 0, 'h' },
- { 0 },
- };
- int opt_ind, ch;
- int nb_args;
- char *endptr;
-
- while ((ch = getopt_long(argc, argv, sopts, lopts, &opt_ind)) != -1) {
- switch (ch) {
- case 's':
- ncpus = atoi(optarg);
- break;
- case 'm':
- memory_size = strtoull(optarg, &endptr, 0);
- switch (*endptr) {
- case 'G': case 'g':
- memory_size <<= 30;
- break;
- case '\0':
- case 'M': case 'm':
- memory_size <<= 20;
- break;
- case 'K': case 'k':
- memory_size <<= 10;
- break;
- default:
- fprintf(stderr,
- "Unrecongized memory suffix: %c\n",
- *endptr);
- exit(1);
- }
- if (memory_size == 0) {
- fprintf(stderr,
- "Invalid memory size: 0\n");
- exit(1);
- }
- break;
- case 'h':
- usage(argv[0]);
- exit(0);
- case '?':
- default:
- fprintf(stderr,
- "Try `%s --help' for more information.\n",
- argv[0]);
- exit(1);
- }
- }
-
- nb_args = argc - optind;
- if (nb_args < 1 || nb_args > 2) {
- fprintf(stderr,
- "Incorrect number of arguments.\n"
- "Try `%s --help' for more information.\n",
- argv[0]);
- exit(1);
- }
-
- signal(IPI_SIGNAL, sig_ignore);
-
- vcpus = calloc(ncpus, sizeof *vcpus);
- if (!vcpus) {
- fprintf(stderr, "calloc failed\n");
- return 1;
- }
-
- kvm = kvm_init(&test_callbacks, 0);
- if (!kvm) {
- fprintf(stderr, "kvm_init failed\n");
- return 1;
- }
- if (kvm_create(kvm, memory_size, &vm_mem) < 0) {
- kvm_finalize(kvm);
- fprintf(stderr, "kvm_create failed\n");
- return 1;
- }
-
- vm_mem = kvm_create_phys_mem(kvm, 0, memory_size, 0, 1);
-
- len = load_file(vm_mem + VM_TEST_LOAD_ADDRESS, argv[optind], 1);
- sync_caches(vm_mem + VM_TEST_LOAD_ADDRESS, len);
-
- io_table_register(&mmio_table, 0xf0000000, 64, mmio_handler, NULL);
-
- sem_init(&exited_sem, 0, 0);
- for (i = 0; i < ncpus; ++i)
- start_vcpu(i);
- /* Wait for all vcpus to exit. */
- for (i = 0; i < ncpus; ++i)
- sem_wait(&exited_sem);
-
- return 0;
-}
diff --git a/powerpc/44x/tlbsx.S b/powerpc/44x/tlbsx.S
deleted file mode 100644
index b15874b18b74c..0000000000000
--- a/powerpc/44x/tlbsx.S
+++ /dev/null
@@ -1,33 +0,0 @@
-#define SPRN_MMUCR 0x3b2
-
-#define TLBWORD0 0x10000210
-#define TLBWORD1 0x10000000
-#define TLBWORD2 0x00000003
-
-.global _start
-_start:
- li r4, 0
- mtspr SPRN_MMUCR, r4
-
- li r3, 23
-
- lis r4, TLBWORD0@h
- ori r4, r4, TLBWORD0@l
- tlbwe r4, r3, 0
-
- lis r4, TLBWORD1@h
- ori r4, r4, TLBWORD1@l
- tlbwe r4, r3, 1
-
- lis r4, TLBWORD2@h
- ori r4, r4, TLBWORD2@l
- tlbwe r4, r3, 2
-
- lis r4, 0x1000
- tlbsx r5, r4, r0
- cmpwi r5, 23
- beq good
- trap
-
-good:
- b .
diff --git a/powerpc/44x/tlbwe.S b/powerpc/44x/tlbwe.S
deleted file mode 100644
index ec6ef5c57fc47..0000000000000
--- a/powerpc/44x/tlbwe.S
+++ /dev/null
@@ -1,27 +0,0 @@
-#define SPRN_MMUCR 0x3b2
-
-/* Create a mapping at 4MB */
-#define TLBWORD0 0x00400210
-#define TLBWORD1 0x00400000
-#define TLBWORD2 0x00000003
-
-.global _start
-_start:
- li r4, 0
- mtspr SPRN_MMUCR, r4
-
- li r3, 23
-
- lis r4, TLBWORD0@h
- ori r4, r4, TLBWORD0@l
- tlbwe r4, r3, 0
-
- lis r4, TLBWORD1@h
- ori r4, r4, TLBWORD1@l
- tlbwe r4, r3, 1
-
- lis r4, TLBWORD2@h
- ori r4, r4, TLBWORD2@l
- tlbwe r4, r3, 2
-
- b .
diff --git a/powerpc/44x/tlbwe_16KB.S b/powerpc/44x/tlbwe_16KB.S
deleted file mode 100644
index 1bd10bf17a187..0000000000000
--- a/powerpc/44x/tlbwe_16KB.S
+++ /dev/null
@@ -1,35 +0,0 @@
-#define SPRN_MMUCR 0x3b2
-
-/* 16KB mapping at 4MB */
-#define TLBWORD0 0x00400220
-#define TLBWORD1 0x00400000
-#define TLBWORD2 0x00000003
-
-.global _start
-_start:
- li r4, 0
- mtspr SPRN_MMUCR, r4
-
- li r3, 5
-
- lis r4, TLBWORD0@h
- ori r4, r4, TLBWORD0@l
- tlbwe r4, r3, 0
-
- lis r4, TLBWORD1@h
- ori r4, r4, TLBWORD1@l
- tlbwe r4, r3, 1
-
- lis r4, TLBWORD2@h
- ori r4, r4, TLBWORD2@l
- tlbwe r4, r3, 2
-
- /* load from 4MB */
- lis r3, 0x0040
- lwz r4, 0(r3)
-
- /* load from 4MB+8KB */
- ori r3, r3, 0x2000
- lwz r4, 0(r3)
-
- b .
diff --git a/powerpc/44x/tlbwe_hole.S b/powerpc/44x/tlbwe_hole.S
deleted file mode 100644
index 5efd30357daa9..0000000000000
--- a/powerpc/44x/tlbwe_hole.S
+++ /dev/null
@@ -1,27 +0,0 @@
-#define SPRN_MMUCR 0x3b2
-
-/* Try to map real address 1GB. */
-#define TLBWORD0 0x40000210
-#define TLBWORD1 0x40000000
-#define TLBWORD2 0x00000003
-
-.global _start
-_start:
- li r4, 0
- mtspr SPRN_MMUCR, r4
-
- li r3, 23
-
- lis r4, TLBWORD0@h
- ori r4, r4, TLBWORD0@l
- tlbwe r4, r3, 0
-
- lis r4, TLBWORD1@h
- ori r4, r4, TLBWORD1@l
- tlbwe r4, r3, 1
-
- lis r4, TLBWORD2@h
- ori r4, r4, TLBWORD2@l
- tlbwe r4, r3, 2
-
- b .
diff --git a/powerpc/cstart.S b/powerpc/cstart.S
deleted file mode 100644
index 70a0e9fcd47c9..0000000000000
--- a/powerpc/cstart.S
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation;
- *
- * 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, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright IBM Corp. 2008
- *
- * Authors: Hollis Blanchard <hollisb@us.ibm.com>
- */
-
-#define OUTPUT_VADDR 0xf0000000
-#define OUTPUT_PADDR 0xf0000000
-
-.globl _start
-_start:
- /* In the future we might need to assign a stack and zero BSS here. */
-
- /* Map the debug page 1:1. */
- lis r3, OUTPUT_VADDR@h
- ori r3, r3, OUTPUT_VADDR@l
- lis r4, OUTPUT_PADDR@h
- ori r4, r4, OUTPUT_PADDR@l
- bl map
-
- /* Call main() and pass return code to exit(). */
- bl main
- bl exit
-
- b .
diff --git a/powerpc/exit.c b/powerpc/exit.c
deleted file mode 100644
index 804ee04d9f88e..0000000000000
--- a/powerpc/exit.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation;
- *
- * 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, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright IBM Corp. 2008
- *
- * Authors: Hollis Blanchard <hollisb@us.ibm.com>
- */
-
-int main(void)
-{
- return 1;
-}
diff --git a/powerpc/helloworld.c b/powerpc/helloworld.c
deleted file mode 100644
index f8630f7c5381f..0000000000000
--- a/powerpc/helloworld.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation;
- *
- * 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, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright IBM Corp. 2008
- *
- * Authors: Deepa Srinivasan <deepas@us.ibm.com>
- */
-
-#include "libcflat.h"
-
-int main()
-{
- printf("Hello World\n");
-
- return 1;
-}
diff --git a/powerpc/io.S b/powerpc/io.S
deleted file mode 100644
index 97567cb6c73f2..0000000000000
--- a/powerpc/io.S
+++ /dev/null
@@ -1,32 +0,0 @@
-#define SPRN_MMUCR 0x3b2
-
-#define TLBWORD0 0xf0000210
-#define TLBWORD1 0xf0000000
-#define TLBWORD2 0x00000003
-
-.global _start
-_start:
- li r4, 0
- mtspr SPRN_MMUCR, r4
-
- li r3, 2
-
- lis r4, TLBWORD0@h
- ori r4, r4, TLBWORD0@l
- tlbwe r4, r3, 0
-
- lis r4, TLBWORD1@h
- ori r4, r4, TLBWORD1@l
- tlbwe r4, r3, 1
-
- lis r4, TLBWORD2@h
- ori r4, r4, TLBWORD2@l
- tlbwe r4, r3, 2
-
- lis r3, 0xf000
- lis r4, 0x1234
- ori r4, r4, 0x5678
- stb r4, 0(r3)
- lbz r5, 0(r3)
-
- b .
diff --git a/powerpc/spin.S b/powerpc/spin.S
deleted file mode 100644
index 4406641c2711c..0000000000000
--- a/powerpc/spin.S
+++ /dev/null
@@ -1,4 +0,0 @@
-
-.global _start
-_start:
- b .
diff --git a/powerpc/sprg.S b/powerpc/sprg.S
deleted file mode 100644
index d0414a480342a..0000000000000
--- a/powerpc/sprg.S
+++ /dev/null
@@ -1,7 +0,0 @@
-
-.global _start
-_start:
- li r3, 42
- mtsprg 0, r3
- mfsprg r4, 0
- b .
diff --git a/x86/print.h b/x86/print.h
deleted file mode 100644
index d5bd2f9978dc4..0000000000000
--- a/x86/print.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef PRINT_H
-#define PRINT_H
-
-.macro PRINT text
-
-.data
-
-333: .asciz "\text\n"
-
-.previous
-
- push %rdi
- lea 333b, %rdi
- call print
- pop %rdi
-
-.endm
-
-#endif
diff --git a/x86/run-kvm-unit-tests b/x86/run-kvm-unit-tests
deleted file mode 100644
index fed925a3d70fe..0000000000000
--- a/x86/run-kvm-unit-tests
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/python
-
-import sys, os, os.path
-
-prog = sys.argv[0]
-dir = os.path.dirname(prog)
--
1.8.1.4
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 2/9] makefile and run_tests tweaks
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
2013-10-14 16:23 ` [PATCH 1/9] remove unused files Andrew Jones
@ 2013-10-14 16:23 ` Andrew Jones
2013-10-14 16:23 ` [PATCH 3/9] clean root dir of all x86-ness Andrew Jones
` (8 subsequent siblings)
10 siblings, 0 replies; 38+ messages in thread
From: Andrew Jones @ 2013-10-14 16:23 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
- remove a redundant '-display none'
- remove a redundant -g from CFLAGS
- remove a useless -I../include/x86 from CFLAGS
- remove lib autodep files on make clean
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
Makefile | 8 ++++----
config-x86-common.mak | 16 +++++++---------
run_tests.sh | 2 +-
3 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/Makefile b/Makefile
index 278791dbbef23..697fc2a766966 100644
--- a/Makefile
+++ b/Makefile
@@ -12,9 +12,9 @@ libgcc := $(shell $(CC) --print-libgcc-file-name)
libcflat := lib/libcflat.a
cflatobjs := \
+ lib/argv.o \
lib/printf.o \
lib/string.o
-cflatobjs += lib/argv.o
#include architecure specific make rules
include config-$(ARCH).mak
@@ -25,8 +25,8 @@ include config-$(ARCH).mak
cc-option = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
-CFLAGS += -O1
-CFLAGS += $(autodepend-flags) -g -fomit-frame-pointer -Wall
+CFLAGS += $(autodepend-flags) -Wall
+CFLAGS += $(call cc-option, -fomit-frame-pointer, "")
CFLAGS += $(call cc-option, -fno-stack-protector, "")
CFLAGS += $(call cc-option, -fno-stack-protector-all, "")
CFLAGS += -I.
@@ -51,4 +51,4 @@ install:
install $(tests_and_config) $(DESTDIR)
clean: arch_clean
- $(RM) *.o *.a .*.d $(libcflat) $(cflatobjs)
+ $(RM) *.o *.a .*.d lib/.*.d $(libcflat) $(cflatobjs)
diff --git a/config-x86-common.mak b/config-x86-common.mak
index bf88c672de472..7e481192a0737 100644
--- a/config-x86-common.mak
+++ b/config-x86-common.mak
@@ -1,13 +1,9 @@
#This is a make file with common rules for both x86 & x86-64
-CFLAGS += -I../include/x86
-
all: test_cases
-cflatobjs += \
- lib/x86/io.o \
- lib/x86/smp.o
-
+cflatobjs += lib/x86/io.o
+cflatobjs += lib/x86/smp.o
cflatobjs += lib/x86/vm.o
cflatobjs += lib/x86/fwcfg.o
cflatobjs += lib/x86/apic.o
@@ -20,15 +16,17 @@ $(libcflat): LDFLAGS += -nostdlib
$(libcflat): CFLAGS += -ffreestanding -I lib
CFLAGS += -m$(bits)
+CFLAGS += -O1
libgcc := $(shell $(CC) -m$(bits) --print-libgcc-file-name)
FLATLIBS = lib/libcflat.a $(libgcc)
%.elf: %.o $(FLATLIBS) flat.lds
- $(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-T,flat.lds $(filter %.o, $^) $(FLATLIBS)
+ $(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-T,flat.lds \
+ $(filter %.o, $^) $(FLATLIBS)
%.flat: %.elf
- objcopy -O elf32-i386 $^ $@
+ $(OBJCOPY) -O elf32-i386 $^ $@
tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
$(TEST_DIR)/smptest.flat $(TEST_DIR)/port80.flat \
@@ -105,7 +103,7 @@ $(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o $(TEST_DIR)/vmx_tests.o
arch_clean:
$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
- $(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o
+ $(TEST_DIR)/.*.d lib/x86/.*.d
api/%.o: CFLAGS += -m32
diff --git a/run_tests.sh b/run_tests.sh
index 55ecac5bed3a4..f373c533b75b2 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -27,7 +27,7 @@ function run()
return
fi
- cmdline="./x86-run $kernel -smp $smp -display none $opts"
+ cmdline="./x86-run $kernel -smp $smp $opts"
if [ $verbose != 0 ]; then
echo $cmdline
fi
--
1.8.1.4
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 3/9] clean root dir of all x86-ness
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
2013-10-14 16:23 ` [PATCH 1/9] remove unused files Andrew Jones
2013-10-14 16:23 ` [PATCH 2/9] makefile and run_tests tweaks Andrew Jones
@ 2013-10-14 16:23 ` Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 4/9] Introduce a simple iomap structure Andrew Jones
` (7 subsequent siblings)
10 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-14 16:23 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
Remove all references to x86 from the root dir (except from in
configure). Also remove references from the root dir README
by moving that documentation to the x86/README, and touch up
the READMEs at the same time.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
Makefile | 7 ++-
README | 55 +++++++++-----------
config-i386.mak | 13 -----
config-x86-common.mak | 120 -------------------------------------------
config-x86_64.mak | 14 -----
config/config-i386.mak | 12 +++++
config/config-x86-common.mak | 120 +++++++++++++++++++++++++++++++++++++++++++
config/config-x86_64.mak | 13 +++++
configure | 17 ++++++
docs/testdev.txt | 11 ++++
flat.lds | 21 --------
run_tests.sh | 19 ++++---
testdev.txt | 14 -----
x86-run | 41 ---------------
x86/README | 60 +++++++++++++++++-----
x86/flat.lds | 21 ++++++++
x86/run | 41 +++++++++++++++
17 files changed, 316 insertions(+), 283 deletions(-)
delete mode 100644 config-i386.mak
delete mode 100644 config-x86-common.mak
delete mode 100644 config-x86_64.mak
create mode 100644 config/config-i386.mak
create mode 100644 config/config-x86-common.mak
create mode 100644 config/config-x86_64.mak
create mode 100644 docs/testdev.txt
delete mode 100644 flat.lds
delete mode 100644 testdev.txt
delete mode 100755 x86-run
create mode 100644 x86/flat.lds
create mode 100755 x86/run
diff --git a/Makefile b/Makefile
index 697fc2a766966..7a5ec8e6348bf 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ cflatobjs := \
lib/string.o
#include architecure specific make rules
-include config-$(ARCH).mak
+include config/config-$(ARCH).mak
# cc-option
# Usage: OP_CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
@@ -29,7 +29,6 @@ CFLAGS += $(autodepend-flags) -Wall
CFLAGS += $(call cc-option, -fomit-frame-pointer, "")
CFLAGS += $(call cc-option, -fno-stack-protector, "")
CFLAGS += $(call cc-option, -fno-stack-protector-all, "")
-CFLAGS += -I.
CXXFLAGS += $(CFLAGS)
@@ -44,11 +43,11 @@ $(libcflat): $(cflatobjs)
%.o: %.S
$(CC) $(CFLAGS) -c -nostdlib -o $@ $<
--include .*.d */.*.d */*/.*.d
+-include */.*.d */*/.*.d
install:
mkdir -p $(DESTDIR)
install $(tests_and_config) $(DESTDIR)
clean: arch_clean
- $(RM) *.o *.a .*.d lib/.*.d $(libcflat) $(cflatobjs)
+ $(RM) lib/.*.d $(libcflat) $(cflatobjs)
diff --git a/README b/README
index db525e3bbb79d..49468b94bc7fc 100644
--- a/README
+++ b/README
@@ -1,36 +1,27 @@
This directory contains sources for a kvm test suite.
-Tests for x86 architecture are run as kernel images for qemu that supports multiboot format.
-Tests uses an infrastructure called from the bios code. The infrastructure initialize the system/cpu's,
-switch to long-mode and calls the 'main' function of the individual test.
-Tests uses a qemu's virtual test device, named testdev, for services like printing, exiting, query memory size etc.
-See file testdev.txt for more details.
-
-To create the tests' images just type 'make' in this directory.
-Tests' images created in ./<ARCH>/*.flat
-
-An example of a test invocation:
-Using qemu-kvm:
-
-qemu-kvm -device testdev,chardev=testlog -chardev file,id=testlog,path=msr.out -serial stdio -kernel ./x86/msr.flat
-This invocation runs the msr test case. The test outputs to stdio.
-
-Using qemu (supported since qemu 1.3):
-qemu-system-x86_64 -enable-kvm -device pc-testdev -serial stdio -device isa-debug-exit,iobase=0xf4,iosize=0x4 -kernel ./x86/msr.flat
-
-Or use a runner script to detect the correct invocation:
-./x86-run ./x86/msr.flat
-To select a specific qemu binary, specify the QEMU=<path> environment:
-QEMU=/tmp/qemu/x86_64-softmmu/qemu-system-x86_64 ./x86-run ./x86/msr.flat
-
-The exit status of the binary (and the script) is inconsistent: with
-qemu-system, after the unittest is done, the exit status of qemu is 1,
-different from the 'old style' qemu-kvm, whose exit status in successful
-completion is 0.
+To create the tests' images do
+ ./configure
+ make
+in this directory. Tests' images are created in ./<ARCH>/*.flat
+
+Then use the runner script to detect the correct invocation and
+invoke the test, e.g.
+ ./x86-run ./x86/msr.flat
+or
+ ./run_tests.sh
+to run them all.
+
+To select a specific qemu binary, specify the QEMU=<path>
+environment, e.g.
+ QEMU=/tmp/qemu/x86_64-softmmu/qemu-system-x86_64 ./x86-run ./x86/msr.flat
Directory structure:
-.: Makefile and config files for the tests
-./lib: general services for the tests
-./lib/<ARCH>: architecture dependent services for the tests
-./<ARCH>: the sources of the tests and the created objects/images
-
+.: Makefile and config files for the tests
+./config: config files for the tests
+./docs: documentation files
+./lib: general services for the tests
+./lib/<ARCH>: architecture dependent services for the tests
+./<ARCH>: the sources of the tests and the created objects/images
+
+See <ARCH>/README for arch specific documentation.
diff --git a/config-i386.mak b/config-i386.mak
deleted file mode 100644
index de52f3d53cff8..0000000000000
--- a/config-i386.mak
+++ /dev/null
@@ -1,13 +0,0 @@
-TEST_DIR=x86
-cstart.o = $(TEST_DIR)/cstart.o
-bits = 32
-ldarch = elf32-i386
-CFLAGS += -D__i386__
-CFLAGS += -I $(KERNELDIR)/include
-
-tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat
-
-include config-x86-common.mak
-
-$(TEST_DIR)/taskswitch.elf: $(cstart.o) $(TEST_DIR)/taskswitch.o
-$(TEST_DIR)/taskswitch2.elf: $(cstart.o) $(TEST_DIR)/taskswitch2.o
diff --git a/config-x86-common.mak b/config-x86-common.mak
deleted file mode 100644
index 7e481192a0737..0000000000000
--- a/config-x86-common.mak
+++ /dev/null
@@ -1,120 +0,0 @@
-#This is a make file with common rules for both x86 & x86-64
-
-all: test_cases
-
-cflatobjs += lib/x86/io.o
-cflatobjs += lib/x86/smp.o
-cflatobjs += lib/x86/vm.o
-cflatobjs += lib/x86/fwcfg.o
-cflatobjs += lib/x86/apic.o
-cflatobjs += lib/x86/atomic.o
-cflatobjs += lib/x86/desc.o
-cflatobjs += lib/x86/isr.o
-cflatobjs += lib/x86/pci.o
-
-$(libcflat): LDFLAGS += -nostdlib
-$(libcflat): CFLAGS += -ffreestanding -I lib
-
-CFLAGS += -m$(bits)
-CFLAGS += -O1
-
-libgcc := $(shell $(CC) -m$(bits) --print-libgcc-file-name)
-
-FLATLIBS = lib/libcflat.a $(libgcc)
-%.elf: %.o $(FLATLIBS) flat.lds
- $(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-T,flat.lds \
- $(filter %.o, $^) $(FLATLIBS)
-
-%.flat: %.elf
- $(OBJCOPY) -O elf32-i386 $^ $@
-
-tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
- $(TEST_DIR)/smptest.flat $(TEST_DIR)/port80.flat \
- $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat \
- $(TEST_DIR)/hypercall.flat $(TEST_DIR)/sieve.flat \
- $(TEST_DIR)/kvmclock_test.flat $(TEST_DIR)/eventinj.flat \
- $(TEST_DIR)/s3.flat $(TEST_DIR)/pmu.flat \
- $(TEST_DIR)/tsc_adjust.flat $(TEST_DIR)/asyncpf.flat \
- $(TEST_DIR)/init.flat
-
-ifdef API
-tests-common += api/api-sample
-tests-common += api/dirty-log
-tests-common += api/dirty-log-perf
-endif
-
-tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
-
-test_cases: $(tests-common) $(tests)
-
-$(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I lib -I lib/x86
-
-$(TEST_DIR)/access.elf: $(cstart.o) $(TEST_DIR)/access.o
-
-$(TEST_DIR)/hypercall.elf: $(cstart.o) $(TEST_DIR)/hypercall.o
-
-$(TEST_DIR)/sieve.elf: $(cstart.o) $(TEST_DIR)/sieve.o
-
-$(TEST_DIR)/vmexit.elf: $(cstart.o) $(TEST_DIR)/vmexit.o
-
-$(TEST_DIR)/smptest.elf: $(cstart.o) $(TEST_DIR)/smptest.o
-
-$(TEST_DIR)/emulator.elf: $(cstart.o) $(TEST_DIR)/emulator.o
-
-$(TEST_DIR)/port80.elf: $(cstart.o) $(TEST_DIR)/port80.o
-
-$(TEST_DIR)/tsc.elf: $(cstart.o) $(TEST_DIR)/tsc.o
-
-$(TEST_DIR)/tsc_adjust.elf: $(cstart.o) $(TEST_DIR)/tsc_adjust.o
-
-$(TEST_DIR)/apic.elf: $(cstart.o) $(TEST_DIR)/apic.o
-
-$(TEST_DIR)/init.elf: $(cstart.o) $(TEST_DIR)/init.o
-
-$(TEST_DIR)/realmode.elf: $(TEST_DIR)/realmode.o
- $(CC) -m32 -nostdlib -o $@ -Wl,-T,$(TEST_DIR)/realmode.lds $^
-
-$(TEST_DIR)/realmode.o: bits = 32
-
-$(TEST_DIR)/msr.elf: $(cstart.o) $(TEST_DIR)/msr.o
-
-$(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt_test.o
-
-$(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/xsave.o
-
-$(TEST_DIR)/rmap_chain.elf: $(cstart.o) $(TEST_DIR)/rmap_chain.o
-
-$(TEST_DIR)/svm.elf: $(cstart.o)
-
-$(TEST_DIR)/kvmclock_test.elf: $(cstart.o) $(TEST_DIR)/kvmclock.o \
- $(TEST_DIR)/kvmclock_test.o
-
-$(TEST_DIR)/eventinj.elf: $(cstart.o) $(TEST_DIR)/eventinj.o
-
-$(TEST_DIR)/s3.elf: $(cstart.o) $(TEST_DIR)/s3.o
-
-$(TEST_DIR)/pmu.elf: $(cstart.o) $(TEST_DIR)/pmu.o
-
-$(TEST_DIR)/asyncpf.elf: $(cstart.o) $(TEST_DIR)/asyncpf.o
-
-$(TEST_DIR)/pcid.elf: $(cstart.o) $(TEST_DIR)/pcid.o
-
-$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o $(TEST_DIR)/vmx_tests.o
-
-arch_clean:
- $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
- $(TEST_DIR)/.*.d lib/x86/.*.d
-
-api/%.o: CFLAGS += -m32
-
-api/%: LDLIBS += -lstdc++ -lboost_thread-mt -lpthread -lrt
-api/%: LDFLAGS += -m32
-
-api/libapi.a: api/kvmxx.o api/identity.o api/exception.o api/memmap.o
- $(AR) rcs $@ $^
-
-api/api-sample: api/api-sample.o api/libapi.a
-
-api/dirty-log: api/dirty-log.o api/libapi.a
-
-api/dirty-log-perf: api/dirty-log-perf.o api/libapi.a
diff --git a/config-x86_64.mak b/config-x86_64.mak
deleted file mode 100644
index bb8ee89713abd..0000000000000
--- a/config-x86_64.mak
+++ /dev/null
@@ -1,14 +0,0 @@
-TEST_DIR=x86
-cstart.o = $(TEST_DIR)/cstart64.o
-bits = 64
-ldarch = elf64-x86-64
-CFLAGS += -D__x86_64__
-
-tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \
- $(TEST_DIR)/emulator.flat $(TEST_DIR)/idt_test.flat \
- $(TEST_DIR)/xsave.flat $(TEST_DIR)/rmap_chain.flat \
- $(TEST_DIR)/pcid.flat
-tests += $(TEST_DIR)/svm.flat
-tests += $(TEST_DIR)/vmx.flat
-
-include config-x86-common.mak
diff --git a/config/config-i386.mak b/config/config-i386.mak
new file mode 100644
index 0000000000000..82fed0f5a48b0
--- /dev/null
+++ b/config/config-i386.mak
@@ -0,0 +1,12 @@
+cstart.o = $(TEST_DIR)/cstart.o
+bits = 32
+ldarch = elf32-i386
+CFLAGS += -D__i386__
+CFLAGS += -I $(KERNELDIR)/include
+
+tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat
+
+include config/config-x86-common.mak
+
+$(TEST_DIR)/taskswitch.elf: $(cstart.o) $(TEST_DIR)/taskswitch.o
+$(TEST_DIR)/taskswitch2.elf: $(cstart.o) $(TEST_DIR)/taskswitch2.o
diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
new file mode 100644
index 0000000000000..917cbbf801a65
--- /dev/null
+++ b/config/config-x86-common.mak
@@ -0,0 +1,120 @@
+#This is a make file with common rules for both x86 & x86-64
+
+all: test_cases
+
+cflatobjs += lib/x86/io.o
+cflatobjs += lib/x86/smp.o
+cflatobjs += lib/x86/vm.o
+cflatobjs += lib/x86/fwcfg.o
+cflatobjs += lib/x86/apic.o
+cflatobjs += lib/x86/atomic.o
+cflatobjs += lib/x86/desc.o
+cflatobjs += lib/x86/isr.o
+cflatobjs += lib/x86/pci.o
+
+$(libcflat): LDFLAGS += -nostdlib
+$(libcflat): CFLAGS += -ffreestanding -I lib
+
+CFLAGS += -m$(bits)
+CFLAGS += -O1
+
+libgcc := $(shell $(CC) -m$(bits) --print-libgcc-file-name)
+
+FLATLIBS = lib/libcflat.a $(libgcc)
+%.elf: %.o $(FLATLIBS) x86/flat.lds
+ $(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-T,x86/flat.lds \
+ $(filter %.o, $^) $(FLATLIBS)
+
+%.flat: %.elf
+ $(OBJCOPY) -O elf32-i386 $^ $@
+
+tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
+ $(TEST_DIR)/smptest.flat $(TEST_DIR)/port80.flat \
+ $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat \
+ $(TEST_DIR)/hypercall.flat $(TEST_DIR)/sieve.flat \
+ $(TEST_DIR)/kvmclock_test.flat $(TEST_DIR)/eventinj.flat \
+ $(TEST_DIR)/s3.flat $(TEST_DIR)/pmu.flat \
+ $(TEST_DIR)/tsc_adjust.flat $(TEST_DIR)/asyncpf.flat \
+ $(TEST_DIR)/init.flat
+
+ifdef API
+tests-common += api/api-sample
+tests-common += api/dirty-log
+tests-common += api/dirty-log-perf
+endif
+
+tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
+
+test_cases: $(tests-common) $(tests)
+
+$(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I lib -I lib/x86
+
+$(TEST_DIR)/access.elf: $(cstart.o) $(TEST_DIR)/access.o
+
+$(TEST_DIR)/hypercall.elf: $(cstart.o) $(TEST_DIR)/hypercall.o
+
+$(TEST_DIR)/sieve.elf: $(cstart.o) $(TEST_DIR)/sieve.o
+
+$(TEST_DIR)/vmexit.elf: $(cstart.o) $(TEST_DIR)/vmexit.o
+
+$(TEST_DIR)/smptest.elf: $(cstart.o) $(TEST_DIR)/smptest.o
+
+$(TEST_DIR)/emulator.elf: $(cstart.o) $(TEST_DIR)/emulator.o
+
+$(TEST_DIR)/port80.elf: $(cstart.o) $(TEST_DIR)/port80.o
+
+$(TEST_DIR)/tsc.elf: $(cstart.o) $(TEST_DIR)/tsc.o
+
+$(TEST_DIR)/tsc_adjust.elf: $(cstart.o) $(TEST_DIR)/tsc_adjust.o
+
+$(TEST_DIR)/apic.elf: $(cstart.o) $(TEST_DIR)/apic.o
+
+$(TEST_DIR)/init.elf: $(cstart.o) $(TEST_DIR)/init.o
+
+$(TEST_DIR)/realmode.elf: $(TEST_DIR)/realmode.o
+ $(CC) -m32 -nostdlib -o $@ -Wl,-T,$(TEST_DIR)/realmode.lds $^
+
+$(TEST_DIR)/realmode.o: bits = 32
+
+$(TEST_DIR)/msr.elf: $(cstart.o) $(TEST_DIR)/msr.o
+
+$(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt_test.o
+
+$(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/xsave.o
+
+$(TEST_DIR)/rmap_chain.elf: $(cstart.o) $(TEST_DIR)/rmap_chain.o
+
+$(TEST_DIR)/svm.elf: $(cstart.o)
+
+$(TEST_DIR)/kvmclock_test.elf: $(cstart.o) $(TEST_DIR)/kvmclock.o \
+ $(TEST_DIR)/kvmclock_test.o
+
+$(TEST_DIR)/eventinj.elf: $(cstart.o) $(TEST_DIR)/eventinj.o
+
+$(TEST_DIR)/s3.elf: $(cstart.o) $(TEST_DIR)/s3.o
+
+$(TEST_DIR)/pmu.elf: $(cstart.o) $(TEST_DIR)/pmu.o
+
+$(TEST_DIR)/asyncpf.elf: $(cstart.o) $(TEST_DIR)/asyncpf.o
+
+$(TEST_DIR)/pcid.elf: $(cstart.o) $(TEST_DIR)/pcid.o
+
+$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o $(TEST_DIR)/vmx_tests.o
+
+arch_clean:
+ $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
+ $(TEST_DIR)/.*.d lib/x86/.*.d
+
+api/%.o: CFLAGS += -m32
+
+api/%: LDLIBS += -lstdc++ -lboost_thread-mt -lpthread -lrt
+api/%: LDFLAGS += -m32
+
+api/libapi.a: api/kvmxx.o api/identity.o api/exception.o api/memmap.o
+ $(AR) rcs $@ $^
+
+api/api-sample: api/api-sample.o api/libapi.a
+
+api/dirty-log: api/dirty-log.o api/libapi.a
+
+api/dirty-log-perf: api/dirty-log-perf.o api/libapi.a
diff --git a/config/config-x86_64.mak b/config/config-x86_64.mak
new file mode 100644
index 0000000000000..f089b05a178c3
--- /dev/null
+++ b/config/config-x86_64.mak
@@ -0,0 +1,13 @@
+cstart.o = $(TEST_DIR)/cstart64.o
+bits = 64
+ldarch = elf64-x86-64
+CFLAGS += -D__x86_64__
+
+tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \
+ $(TEST_DIR)/emulator.flat $(TEST_DIR)/idt_test.flat \
+ $(TEST_DIR)/xsave.flat $(TEST_DIR)/rmap_chain.flat \
+ $(TEST_DIR)/pcid.flat
+tests += $(TEST_DIR)/svm.flat
+tests += $(TEST_DIR)/vmx.flat
+
+include config/config-x86-common.mak
diff --git a/configure b/configure
index d0c62e24dd1d2..6cfc64943f6e6 100755
--- a/configure
+++ b/configure
@@ -15,6 +15,7 @@ usage() {
Usage: $0 [options]
Options include:
+ --test-dir=DIR the main directory for tests ($arch)
--arch=ARCH architecture to compile for ($arch)
--cross-prefix=PREFIX cross compiler prefix
--cc=CC c compiler to use ($cc)
@@ -33,6 +34,9 @@ while [[ "$1" = -* ]]; do
opt="${opt%%=*}"
fi
case "$opt" in
+ --test-dir)
+ testdir="$arg"
+ ;;
--prefix)
prefix="$arg"
;;
@@ -62,6 +66,18 @@ while [[ "$1" = -* ]]; do
;;
esac
done
+if [ -z "$testdir" -a \( "$arch" = "i386" -o "$arch" = "x86_64" \) ]; then
+ testdir=x86
+elif [ -z "$testdir" ]; then
+ testdir=$arch
+fi
+if [ ! -d $testdir ]; then
+ echo "$testdir does not exist!"
+ exit 1
+fi
+if [ -f $testdir/run ]; then
+ ln -fs $testdir/run $testdir-run
+fi
# check for dependent 32 bit libraries
cat << EOF > lib_test.c
@@ -89,4 +105,5 @@ LD=$cross_prefix$ld
OBJCOPY=$cross_prefix$objcopy
AR=$cross_prefix$ar
API=$api
+TEST_DIR=$testdir
EOF
diff --git a/docs/testdev.txt b/docs/testdev.txt
new file mode 100644
index 0000000000000..854b5c774b60c
--- /dev/null
+++ b/docs/testdev.txt
@@ -0,0 +1,11 @@
+This file describes the virtual device of qemu for supporting this test suite.
+
+Services supplied by the testdev device:
+
+serial output: write only, on io port 0xf1
+exit process: write only, on io port 0xf4, value used as exit code
+ram size: read-only, on io port 0xd1, 4 bytes' size
+irq line setting: write only, on io ports 0x2000 - 0x2018, value to set/clear
+simple io: read/write, on io port 0xe0, 1/2/4 bytes
+
+Test device used a char device for actual output
diff --git a/flat.lds b/flat.lds
deleted file mode 100644
index a278b56c9a4e3..0000000000000
--- a/flat.lds
+++ /dev/null
@@ -1,21 +0,0 @@
-SECTIONS
-{
- . = 4M + SIZEOF_HEADERS;
- stext = .;
- .text : { *(.init) *(.text) *(.text.*) }
- . = ALIGN(4K);
- .data : {
- *(.data)
- exception_table_start = .;
- *(.data.ex)
- exception_table_end = .;
- }
- . = ALIGN(16);
- .rodata : { *(.rodata) }
- . = ALIGN(16);
- .bss : { *(.bss) }
- . = ALIGN(4K);
- edata = .;
-}
-
-ENTRY(start)
diff --git a/run_tests.sh b/run_tests.sh
index f373c533b75b2..400c62458ae18 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -1,8 +1,10 @@
#!/bin/bash
-testroot=x86
-config=$testroot/unittests.cfg
-qemu=${qemu:-qemu-system-x86_64}
+# As it happens, config.mak is valid shell script code, too :-)
+source config.mak
+
+config=$TEST_DIR/unittests.cfg
+qemu=${QEMU:-qemu-system-$ARCH}
verbose=0
function run()
@@ -27,7 +29,7 @@ function run()
return
fi
- cmdline="./x86-run $kernel -smp $smp $opts"
+ cmdline="./$TEST_DIR-run $kernel -smp $smp $opts"
if [ $verbose != 0 ]; then
echo $cmdline
fi
@@ -65,7 +67,7 @@ function run_all()
groups=""
arch=""
elif [[ $line =~ ^file\ *=\ *(.*)$ ]]; then
- kernel=$testroot/${BASH_REMATCH[1]}
+ kernel=$TEST_DIR/${BASH_REMATCH[1]}
elif [[ $line =~ ^smp\ *=\ *(.*)$ ]]; then
smp=${BASH_REMATCH[1]}
elif [[ $line =~ ^extra_params\ *=\ *(.*)$ ]]; then
@@ -92,15 +94,12 @@ Usage: $0 [-g group] [-h] [-v]
-h: Output this help text
-v: Enables verbose mode
-Set the environment variable QEMU=/path/to/qemu-system-x86_64 to allow the
-internally used x86-run to pick up the right qemu binary.
+Set the environment variable QEMU=/path/to/qemu-system-ARCH to allow the
+internally used ARCH-run to pick up the right qemu binary.
EOF
}
-# As it happens, config.mak is valid shell script code, too :-)
-source config.mak
-
echo > test.log
while getopts "g:hv" opt; do
case $opt in
diff --git a/testdev.txt b/testdev.txt
deleted file mode 100644
index ac436efadb633..0000000000000
--- a/testdev.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This file describes the virtual device of qemu for supporting this test suite.
-
-Services supplied by the testdev device:
-
-serial output: write only, on io port 0xf1
-exit process: write only, on io port 0xf4, value used as exit code
-ram size: read-only, on io port 0xd1, 4 bytes' size
-irq line setting: write only, on io ports 0x2000 - 0x2018, value to set/clear
-simple io: read/write, on io port 0xe0, 1/2/4 bytes
-
-Test device used a char device for actual output
-
-
-
diff --git a/x86-run b/x86-run
deleted file mode 100755
index 646c5770ed03f..0000000000000
--- a/x86-run
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-
-qemukvm="${QEMU:-qemu-kvm}"
-qemusystem="${QEMU:-qemu-system-x86_64}"
-if
- ${qemukvm} -device '?' 2>&1 | grep -F -e \"testdev\" -e \"pc-testdev\" > /dev/null;
-then
- qemu="${qemukvm}"
-else
- if
- ${qemusystem} -device '?' 2>&1 | grep -F -e \"testdev\" -e \"pc-testdev\" > /dev/null;
- then
- qemu="${qemusystem}"
- else
- echo QEMU binary ${QEMU} has no support for test device. Exiting.
- exit 2
- fi
-fi
-
-if
- ${qemu} -device '?' 2>&1 | grep -F "pci-testdev" > /dev/null;
-then
- pci_testdev="-device pci-testdev"
-else
- pci_testdev=""
-fi
-
-if
- ${qemu} -device '?' 2>&1 | grep -F "pc-testdev" > /dev/null;
-then
- pc_testdev="-device pc-testdev -device isa-debug-exit,iobase=0xf4,iosize=0x4"
-else
- pc_testdev="-device testdev,chardev=testlog -chardev file,id=testlog,path=msr.out"
-fi
-
-command="${qemu} -enable-kvm $pc_testdev -display none -serial stdio $pci_testdev -kernel"
-echo ${command} "$@"
-${command} "$@"
-ret=$?
-echo Return value from qemu: $ret
-exit $ret
diff --git a/x86/README b/x86/README
index d644abdf31708..2f4baa46c6ed1 100644
--- a/x86/README
+++ b/x86/README
@@ -1,16 +1,48 @@
+
+Tests for x86 architecture are run as kernel images for qemu that supports
+multiboot format. Tests uses an infrastructure called from the bios code.
+The infrastructure initialize the system/cpu's, switch to long-mode and calls
+the 'main' function of the individual test. Tests uses a qemu's virtual test
+device, named testdev, for services like printing, exiting, query memory
+size etc. See file docs/testdev.txt for more details.
+
+An example of a test invocation:
+Using qemu-kvm:
+
+qemu-kvm -device testdev,chardev=testlog \
+ -chardev file,id=testlog,path=msr.out \
+ -serial stdio -kernel ./x86/msr.flat
+This invocation runs the msr test case. The test outputs to stdio.
+
+Using qemu (supported since qemu 1.3):
+qemu-system-x86_64 -enable-kvm -device pc-testdev -serial stdio \
+ -device isa-debug-exit,iobase=0xf4,iosize=0x4 \
+ -kernel ./x86/msr.flat
+
Tests in this directory and what they do:
-access: lots of page table related access (pte/pde) (read/write)
-apic: enable x2apic, self ipi, ioapic intr, ioapic simultaneous
-emulator: move to/from regs, cmps, push, pop, to/from cr8, smsw and lmsw
-hypercall: intel and amd hypercall insn
-msr: write to msr (only KERNEL_GS_BASE for now)
-port80: lots of out to port 80
-realmode: goes back to realmode, shld, push/pop, mov immediate, cmp immediate, add immediate,
- io, eflags instructions (clc, cli, etc.), jcc short, jcc near, call, long jmp, xchg
-sieve: heavy memory access with no paging and with paging static and with paging vmalloc'ed
-smptest: run smp_id() on every cpu and compares return value to number
-tsc: write to tsc(0) and write to tsc(100000000000) and read it back
-vmexit: long loops for each: cpuid, vmcall, mov_from_cr8, mov_to_cr8, inl_pmtimer, ipi, ipi+halt
-kvmclock_test: test of wallclock, monotonic cycle and performance of kvmclock
-pcid: basic functionality test of PCID/INVPCID feature
\ No newline at end of file
+ access: lots of page table related access (pte/pde) (read/write)
+ apic: enable x2apic, self ipi, ioapic intr, ioapic simultaneous
+ emulator: move to/from regs, cmps, push, pop, to/from cr8, smsw and lmsw
+ hypercall: intel and amd hypercall insn
+ msr: write to msr (only KERNEL_GS_BASE for now)
+ port80: lots of out to port 80
+ realmode: goes back to realmode, shld, push/pop, mov immediate,
+ cmp immediate, add immediate, io, eflags instructions
+ (clc, cli, etc.), jcc short, jcc near, call, long jmp, xchg
+ sieve: heavy memory access with no paging and with paging static and
+ with paging vmalloc'ed
+ smptest: run smp_id() on every cpu and compares return value to number
+ tsc: write to tsc(0) and write to tsc(100000000000) and read it back
+ vmexit: long loops for each: cpuid, vmcall, mov_from_cr8, mov_to_cr8,
+ inl_pmtimer, ipi, ipi+halt
+ kvmclock_test: test of wallclock, monotonic cycle and performance of kvmclock
+ pcid: basic functionality test of PCID/INVPCID featureThis directory
+ contains sources for a kvm test suite.
+
+Legacy notes:
+
+ The exit status of the binary (and the script) is inconsistent: with
+ qemu-system, after the unittest is done, the exit status of qemu is 1,
+ different from the 'old style' qemu-kvm, whose exit status in successful
+ completion is 0.
diff --git a/x86/flat.lds b/x86/flat.lds
new file mode 100644
index 0000000000000..a278b56c9a4e3
--- /dev/null
+++ b/x86/flat.lds
@@ -0,0 +1,21 @@
+SECTIONS
+{
+ . = 4M + SIZEOF_HEADERS;
+ stext = .;
+ .text : { *(.init) *(.text) *(.text.*) }
+ . = ALIGN(4K);
+ .data : {
+ *(.data)
+ exception_table_start = .;
+ *(.data.ex)
+ exception_table_end = .;
+ }
+ . = ALIGN(16);
+ .rodata : { *(.rodata) }
+ . = ALIGN(16);
+ .bss : { *(.bss) }
+ . = ALIGN(4K);
+ edata = .;
+}
+
+ENTRY(start)
diff --git a/x86/run b/x86/run
new file mode 100755
index 0000000000000..646c5770ed03f
--- /dev/null
+++ b/x86/run
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+qemukvm="${QEMU:-qemu-kvm}"
+qemusystem="${QEMU:-qemu-system-x86_64}"
+if
+ ${qemukvm} -device '?' 2>&1 | grep -F -e \"testdev\" -e \"pc-testdev\" > /dev/null;
+then
+ qemu="${qemukvm}"
+else
+ if
+ ${qemusystem} -device '?' 2>&1 | grep -F -e \"testdev\" -e \"pc-testdev\" > /dev/null;
+ then
+ qemu="${qemusystem}"
+ else
+ echo QEMU binary ${QEMU} has no support for test device. Exiting.
+ exit 2
+ fi
+fi
+
+if
+ ${qemu} -device '?' 2>&1 | grep -F "pci-testdev" > /dev/null;
+then
+ pci_testdev="-device pci-testdev"
+else
+ pci_testdev=""
+fi
+
+if
+ ${qemu} -device '?' 2>&1 | grep -F "pc-testdev" > /dev/null;
+then
+ pc_testdev="-device pc-testdev -device isa-debug-exit,iobase=0xf4,iosize=0x4"
+else
+ pc_testdev="-device testdev,chardev=testlog -chardev file,id=testlog,path=msr.out"
+fi
+
+command="${qemu} -enable-kvm $pc_testdev -display none -serial stdio $pci_testdev -kernel"
+echo ${command} "$@"
+${command} "$@"
+ret=$?
+echo Return value from qemu: $ret
+exit $ret
--
1.8.1.4
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 4/9] Introduce a simple iomap structure
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
` (2 preceding siblings ...)
2013-10-14 16:23 ` [PATCH 3/9] clean root dir of all x86-ness Andrew Jones
@ 2013-10-14 16:23 ` Andrew Jones
2013-10-14 16:23 ` [PATCH 5/9] Add halt() and some error codes Andrew Jones
` (6 subsequent siblings)
10 siblings, 0 replies; 38+ messages in thread
From: Andrew Jones @ 2013-10-14 16:23 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
Add a simple structure and search function to the common code that
can be used for looking up a set of addresses by type. The user
must supply the iomaps[] table, e.g.
struct iomap iomaps[] = {
{
.type = "virtio_mmio",
.nr = 4,
.addrs = { 0x2000000, 0x2000200, 0x2000400, 0x2000600, },
},
{
.type = NULL,
},
};
Also add a script scripts/gen-devtree-iomaps.pl that can generate
the iomaps table from an fdt, e.g.
fdtdump dtb | scripts/gen-devtree-iomaps.pl - virtio_mmio
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
README | 1 +
lib/iomaps.c | 12 +++++++
lib/iomaps.h | 12 +++++++
scripts/gen-devtree-iomaps.pl | 81 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 106 insertions(+)
create mode 100644 lib/iomaps.c
create mode 100644 lib/iomaps.h
create mode 100755 scripts/gen-devtree-iomaps.pl
diff --git a/README b/README
index 49468b94bc7fc..1e58fd2e3ca00 100644
--- a/README
+++ b/README
@@ -20,6 +20,7 @@ Directory structure:
.: Makefile and config files for the tests
./config: config files for the tests
./docs: documentation files
+./scripts: misc helper scripts
./lib: general services for the tests
./lib/<ARCH>: architecture dependent services for the tests
./<ARCH>: the sources of the tests and the created objects/images
diff --git a/lib/iomaps.c b/lib/iomaps.c
new file mode 100644
index 0000000000000..6169bcf2e43d2
--- /dev/null
+++ b/lib/iomaps.c
@@ -0,0 +1,12 @@
+#include "libcflat.h"
+#include "iomaps.h"
+
+extern struct iomap iomaps[];
+
+struct iomap *iomaps_find(const char *type)
+{
+ struct iomap *m = &iomaps[0];
+ for (; m->type && strcmp(m->type, type); ++m)
+ ;
+ return m->type ? m : NULL;
+}
diff --git a/lib/iomaps.h b/lib/iomaps.h
new file mode 100644
index 0000000000000..4581eee0e5337
--- /dev/null
+++ b/lib/iomaps.h
@@ -0,0 +1,12 @@
+#ifndef _IOMAPS_H_
+#define _IOMAPS_H_
+#include "libcflat.h"
+
+struct iomap {
+ const char *type;
+ u32 nr;
+ u32 addrs[64];
+};
+
+struct iomap *iomaps_find(const char *type);
+#endif
diff --git a/scripts/gen-devtree-iomaps.pl b/scripts/gen-devtree-iomaps.pl
new file mode 100755
index 0000000000000..91fa83d521839
--- /dev/null
+++ b/scripts/gen-devtree-iomaps.pl
@@ -0,0 +1,81 @@
+#!/usr/bin/perl -w
+use strict;
+
+my $fdt = shift @ARGV;
+my @types = @ARGV;
+my $max_nr = 64;
+
+if (!defined $fdt || $#types < 0) {
+ print STDERR "Usage: gen-devtree-iomaps ".
+ "<fdt-file|-> <addr-type> [addr-types...]\n";
+ exit 1;
+}
+
+my @dtb;
+if ($fdt eq '-') {
+ @dtb = <STDIN>;
+} else {
+ open F, "<$fdt" or die "can't read $fdt: $!";
+ @dtb = <F>;
+ close F;
+}
+
+my $g = (join '@|', @types) . '@';
+@dtb = grep { /$g/ } @dtb;
+foreach (@dtb) {
+ chomp($_);
+ s/^\s*//, s/\s*{$//;
+}
+
+my %iomaps;
+foreach (@dtb) {
+ my ($type, $addr) = split /@/, $_;
+ if (!exists $iomaps{$type}) {
+ $iomaps{$type} = [$addr];
+ } else {
+ push $iomaps{$type}, $addr;
+ }
+}
+
+print <<EOF;
+/*
+ * Generated file. See gen-devtree-iomaps.pl
+ */
+#include "iomaps.h"
+EOF
+print "\nstruct iomap iomaps[] = {\n";
+foreach my $type (keys %iomaps) {
+ @{ $iomaps{$type} } = sort @{ $iomaps{$type} };
+ my $nr = $#{ $iomaps{$type} } + 1;
+ if ($nr > $max_nr) {
+ print STDERR "$type has $nr addrs, but iomaps can only ".
+ "support up to $max_nr.\n";
+ $nr = $max_nr;
+ splice @{ $iomaps{$type} }, $nr;
+ }
+ print "{\n";
+ print " .type = \"$type\",\n";
+ print " .nr = $nr,\n";
+ print " .addrs = {";
+ if ($nr < 5) {
+ my $line = join ', 0x', @{ $iomaps{$type} };
+ print " 0x$line, },\n";
+ print "},\n";
+ next;
+ }
+ print "\n";
+ for (my $i = 0; $i < $nr; $i += 5) {
+ print "\t";
+ my $j = $i;
+ while ($j < $i + 4 && $j < $nr - 1) {
+ print "0x$iomaps{$type}[$j], ";
+ ++$j;
+ }
+ print "0x$iomaps{$type}[$j],\n";
+ }
+ print " },\n";
+ print "},\n";
+}
+print "{\n .type = NULL,\n},\n";
+print "};\n";
+exit 0;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 5/9] Add halt() and some error codes
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
` (3 preceding siblings ...)
2013-10-14 16:23 ` [PATCH 4/9] Introduce a simple iomap structure Andrew Jones
@ 2013-10-14 16:23 ` Andrew Jones
2013-10-14 16:23 ` [PATCH 6/9] Introduce virtio-testdev Andrew Jones
` (5 subsequent siblings)
10 siblings, 0 replies; 38+ messages in thread
From: Andrew Jones @ 2013-10-14 16:23 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
Add a halt function that can be used by the test infrastructure on error
paths before exit() works. Also add some error codes that can be passed
to halt() in case the serial isn't working either. Then, on register
inspection of the halted guest we may be able to quickly determine the
problem without having to find the halt() call-site using its return
address.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
lib/errno.h | 15 +++++++++++++++
lib/libcflat.h | 2 ++
lib/x86/io.c | 6 ++++++
3 files changed, 23 insertions(+)
create mode 100644 lib/errno.h
diff --git a/lib/errno.h b/lib/errno.h
new file mode 100644
index 0000000000000..4c7478229baf3
--- /dev/null
+++ b/lib/errno.h
@@ -0,0 +1,15 @@
+#ifndef _ERRNO_H_
+#define _ERRNO_H_
+/*
+ * Define some error codes for the test infrastructure's use.
+ * (Ab)use the standard E* names for syntax highlighting...
+ */
+#define MAXERR 127 /* exit(-1) */
+#define EINTR (MAXERR - 1) /* unhandled exception */
+#define EIO (MAXERR - 2) /* I/O error */
+#define ENXIO (MAXERR - 3) /* no serial */
+#define ENOEXEC (MAXERR - 4) /* bad test file format */
+#define ENOMEM (MAXERR - 5) /* Out of memory */
+#define ENODEV (MAXERR - 6) /* no testdev device */
+#define EINVAL (MAXERR - 7) /* Invalid argument */
+#endif
diff --git a/lib/libcflat.h b/lib/libcflat.h
index 140c172e77d54..a1be635ab4ee9 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -37,6 +37,7 @@ typedef _Bool bool;
#define true 1
#define false 0
+extern void halt(int code);
extern void exit(int code);
extern unsigned long strlen(const char *buf);
@@ -57,4 +58,5 @@ extern long atol(const char *ptr);
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define NULL ((void *)0UL)
+#include "errno.h"
#endif
diff --git a/lib/x86/io.c b/lib/x86/io.c
index d3b971ef67b0e..7a36c9ca0c951 100644
--- a/lib/x86/io.c
+++ b/lib/x86/io.c
@@ -1,4 +1,5 @@
#include "libcflat.h"
+#include "processor.h"
#include "smp.h"
#include "io.h"
#ifndef USE_SERIAL
@@ -81,3 +82,8 @@ void exit(int code)
asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4));
#endif
}
+
+void halt(int code)
+{
+ safe_halt();
+}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 6/9] Introduce virtio-testdev
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
` (4 preceding siblings ...)
2013-10-14 16:23 ` [PATCH 5/9] Add halt() and some error codes Andrew Jones
@ 2013-10-14 16:23 ` Andrew Jones
2013-10-15 8:39 ` Andrew Jones
` (2 more replies)
2013-10-14 16:23 ` [PATCH 7/9] arm: replace arbitrary divisions Andrew Jones
` (4 subsequent siblings)
10 siblings, 3 replies; 38+ messages in thread
From: Andrew Jones @ 2013-10-14 16:23 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
virtio-testdev is a communication channel to qemu through virtio that
can be used by test code to send commands. The only command currently
implemented is EXIT, which allows the test code to exit with a given
status code.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
lib/bswap.h | 7 +++
lib/libcflat.h | 10 ++++
lib/virtio-testdev.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
lib/virtio-testdev.h | 9 ++++
4 files changed, 152 insertions(+)
create mode 100644 lib/bswap.h
create mode 100644 lib/virtio-testdev.c
create mode 100644 lib/virtio-testdev.h
diff --git a/lib/bswap.h b/lib/bswap.h
new file mode 100644
index 0000000000000..e63c4d37a8b9a
--- /dev/null
+++ b/lib/bswap.h
@@ -0,0 +1,7 @@
+#ifndef _BSWAP_H_
+#define _BSWAP_H_
+#define le32_to_cpu(x) (x)
+#define cpu_to_le32(x) (x)
+#define le16_to_cpu(x) (x)
+#define cpu_to_le16(x) (x)
+#endif
diff --git a/lib/libcflat.h b/lib/libcflat.h
index a1be635ab4ee9..41791194657d0 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -37,6 +37,16 @@ typedef _Bool bool;
#define true 1
#define false 0
+typedef u32 compat_ptr_t;
+static inline void *compat_ptr(compat_ptr_t ptr)
+{
+ return (void *)(unsigned long)ptr;
+}
+static inline compat_ptr_t ptr_to_compat(void *ptr)
+{
+ return (u32)(unsigned long)ptr;
+}
+
extern void halt(int code);
extern void exit(int code);
diff --git a/lib/virtio-testdev.c b/lib/virtio-testdev.c
new file mode 100644
index 0000000000000..900921302c344
--- /dev/null
+++ b/lib/virtio-testdev.c
@@ -0,0 +1,126 @@
+#include "libcflat.h"
+#include "iomaps.h"
+#include "bswap.h"
+
+#define TESTDEV_MAJOR_VER 1
+#define TESTDEV_MINOR_VER 1
+
+#define VIRTIO_MMIO_DEVICEID 0x8
+#define VIRTIO_ID_TESTDEV 0xffff
+#define DEV_CONFIG_BASE 0x100
+#define DEV_CONFIG_SIZE 0x100
+
+enum { VERSION = 1, CLEAR, EXIT, };
+enum { TOKEN, NARGS, NRETS, ARG1, ARG2, ARG3, ARG4, };
+
+#define RET1(nargs) (ARG1 + (nargs) + 0)
+#define RET2(nargs) (ARG1 + (nargs) + 1)
+#define RET3(nargs) (ARG1 + (nargs) + 2)
+#define RET4(nargs) (ARG1 + (nargs) + 3)
+
+static u32 *testdev_base;
+
+/*
+ * We have to write all args; nargs, nrets, ... first to
+ * avoid executing token's operation until all args are in
+ * place. Then issue the op, and then read the rets. Reading
+ * the rets (or just sanity checking by reading base[0]) will
+ * read a zero into qemu's copy of the token, which allows us
+ * to prepare additional ops without re-executing the last one.
+ */
+void virtio_testdev(u32 token, u32 nargs, u32 nrets, ...)
+{
+ volatile u32 *base = testdev_base;
+ volatile u32 *tdp = base + 1;
+ va_list va;
+
+ if (!testdev_base)
+ return;
+
+ *tdp++ = cpu_to_le32(nargs);
+ *tdp++ = cpu_to_le32(nrets);
+
+ va_start(va, nrets);
+
+ while (nargs--)
+ *tdp++ = cpu_to_le32(va_arg(va, unsigned));
+
+ /* this runs the op, but then resets base[0] to zero */
+ base[0] = cpu_to_le32(token);
+
+ /* sanity check */
+ if (base[0] != 0) {
+ printf("virtio-testdev base[0] should always be zero!\n");
+ halt(EIO);
+ }
+
+ while (nrets--) {
+ u32 *r = va_arg(va, unsigned *);
+ *r = le32_to_cpu(*tdp++);
+ }
+
+ va_end(va);
+}
+
+void virtio_testdev_version(u32 *version)
+{
+ virtio_testdev(VERSION, 0, 1, version);
+}
+
+void virtio_testdev_clear(void)
+{
+ virtio_testdev(CLEAR, 0, 0);
+}
+
+void virtio_testdev_exit(int code)
+{
+ virtio_testdev(EXIT, 1, 0, code);
+}
+
+void virtio_testdev_init(void)
+{
+ struct iomap *m;
+ u32 version, i;
+ u16 major, minor;
+
+ m = iomaps_find("virtio_mmio");
+ if (!m) {
+ printf("No virtio-mmio transports for virtio-testdev found!\n");
+ halt(ENODEV);
+ }
+
+ for (i = 0; i < m->nr; ++i) {
+ volatile u32 *base = (u32 *)compat_ptr(m->addrs[i]);
+ u32 devid32 = base[VIRTIO_MMIO_DEVICEID / 4];
+ u16 devid = devid32 & 0xffff;
+ devid = le16_to_cpu(devid);
+ if (devid == VIRTIO_ID_TESTDEV) {
+ testdev_base = (u32 *)compat_ptr(m->addrs[i] + DEV_CONFIG_BASE);
+ break;
+ }
+ }
+
+ if (!testdev_base) {
+ printf("Can't find virtio-testdev. Is '-device virtio-testdev' "
+ "on the qemu command line?\n");
+ halt(ENODEV);
+ }
+
+ virtio_testdev_version(&version);
+ major = version >> 16;
+ minor = version & 0xffff;
+
+ if (major != TESTDEV_MAJOR_VER || minor < TESTDEV_MINOR_VER) {
+ char *u = "qemu";
+ if (major > TESTDEV_MAJOR_VER)
+ u = "kvm-unit-tests";
+ printf("Refusing to run with virtio-testdev major = %d, minor = %d\n",
+ major, minor);
+ printf("Update %s.\n", u);
+ exit(ENODEV);
+ }
+
+ if (minor > TESTDEV_MINOR_VER)
+ printf("testdev has new features. "
+ "An update of kvm-unit-tests may be possible.\n");
+}
diff --git a/lib/virtio-testdev.h b/lib/virtio-testdev.h
new file mode 100644
index 0000000000000..c10bbfb591d0b
--- /dev/null
+++ b/lib/virtio-testdev.h
@@ -0,0 +1,9 @@
+#ifndef _VIRTIO_TESTDEV_H_
+#define _VIRTIO_TESTDEV_H_
+#include "libcflat.h"
+
+extern void virtio_testdev_init(void);
+extern void virtio_testdev_version(u32 *version);
+extern void virtio_testdev_clear(void);
+extern void virtio_testdev_exit(int code);
+#endif
--
1.8.1.4
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 7/9] arm: replace arbitrary divisions
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
` (5 preceding siblings ...)
2013-10-14 16:23 ` [PATCH 6/9] Introduce virtio-testdev Andrew Jones
@ 2013-10-14 16:23 ` Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 8/9] arm: initial drop Andrew Jones
` (3 subsequent siblings)
10 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-14 16:23 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
arm can't do arbitrary divisions without software support. Usually
libgcc would jump in here, but depending on the toolchain used that may
or may not work. Luckily, we only care about two types of divisions.
Divide by 10 and divide by 16. Divide by 16 is already covered by gcc
since it's a power of two. Divide by 10 can be hacked up using a
multiplication and shift.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
lib/divmod.h | 20 ++++++++++++++++++++
lib/printf.c | 27 ++++++++++++++-------------
2 files changed, 34 insertions(+), 13 deletions(-)
create mode 100644 lib/divmod.h
diff --git a/lib/divmod.h b/lib/divmod.h
new file mode 100644
index 0000000000000..c0f04d7d8386d
--- /dev/null
+++ b/lib/divmod.h
@@ -0,0 +1,20 @@
+#ifndef _DIVMOD_H_
+#define _DIVMOD_H_
+#ifdef __arm__
+static inline long long div10(long long n)
+{
+ /*
+ * multiply n by 2^32/10 and the result of n/10
+ * will be in the upper word
+ */
+ return (n * 0x1999999aU) >> 32;
+}
+static inline int mod10(long long n)
+{
+ return n - div10(n) * 10;
+}
+#else
+#define div10(n) ((n) / 10)
+#define mod10(n) ((n) % 10)
+#endif
+#endif
diff --git a/lib/printf.c b/lib/printf.c
index 867eb1926f742..9fb8133868c7a 100644
--- a/lib/printf.c
+++ b/lib/printf.c
@@ -1,4 +1,5 @@
#include "libcflat.h"
+#include "divmod.h"
typedef struct pstream {
char *buffer;
@@ -23,7 +24,7 @@ void print_str(pstream_t *p, const char *s)
static char digits[16] = "0123456789abcdef";
-void print_int(pstream_t *ps, long long n, int base)
+void print_int(pstream_t *ps, long long n)
{
char buf[sizeof(long) * 3 + 2], *p = buf;
int s = 0, i;
@@ -34,8 +35,8 @@ void print_int(pstream_t *ps, long long n, int base)
}
while (n) {
- *p++ = digits[n % base];
- n /= base;
+ *p++ = digits[mod10(n)];
+ n = div10(n);
}
if (s)
@@ -57,14 +58,14 @@ void print_int(pstream_t *ps, long long n, int base)
print_str(ps, buf);
}
-void print_unsigned(pstream_t *ps, unsigned long long n, int base)
+void print_unsigned(pstream_t *ps, unsigned long long n)
{
char buf[sizeof(long) * 3 + 1], *p = buf;
int i;
while (n) {
- *p++ = digits[n % base];
- n /= base;
+ *p++ = digits[n % 16];
+ n /= 16;
}
if (p == buf)
@@ -116,32 +117,32 @@ int vsnprintf(char *buf, int size, const char *fmt, va_list va)
case 'd':
switch (nlong) {
case 0:
- print_int(&s, va_arg(va, int), 10);
+ print_int(&s, va_arg(va, int));
break;
case 1:
- print_int(&s, va_arg(va, long), 10);
+ print_int(&s, va_arg(va, long));
break;
default:
- print_int(&s, va_arg(va, long long), 10);
+ print_int(&s, va_arg(va, long long));
break;
}
break;
case 'x':
switch (nlong) {
case 0:
- print_unsigned(&s, va_arg(va, unsigned), 16);
+ print_unsigned(&s, va_arg(va, unsigned));
break;
case 1:
- print_unsigned(&s, va_arg(va, unsigned long), 16);
+ print_unsigned(&s, va_arg(va, unsigned long));
break;
default:
- print_unsigned(&s, va_arg(va, unsigned long long), 16);
+ print_unsigned(&s, va_arg(va, unsigned long long));
break;
}
break;
case 'p':
print_str(&s, "0x");
- print_unsigned(&s, (unsigned long)va_arg(va, void *), 16);
+ print_unsigned(&s, (unsigned long)va_arg(va, void *));
break;
case 's':
print_str(&s, va_arg(va, const char *));
--
1.8.1.4
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 8/9] arm: initial drop
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
` (6 preceding siblings ...)
2013-10-14 16:23 ` [PATCH 7/9] arm: replace arbitrary divisions Andrew Jones
@ 2013-10-14 16:23 ` Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 9/9] arm: add vectors support Andrew Jones
` (2 subsequent siblings)
10 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-14 16:23 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
This is the initial arm test infrastructure and a first test that
simply checks some bootinfo. kvm isn't needed to run this test. This
patch also adds a common build environment variable, $QEMU_BIN, which
allows makefiles to call on qemu when needed.
Try it out with
yum install gcc-arm-linux-gnu dtc
export QEMU=[qemu with mach-virt and virtio-testdev]
./configure --cross-prefix=arm-linux-gnu- --arch=arm
make
./run_tests.sh
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
arm/boot.c | 27 ++++++++++++++++++++
arm/cstart.S | 47 ++++++++++++++++++++++++++++++++++
arm/flat.lds | 18 +++++++++++++
arm/run | 19 ++++++++++++++
arm/unittests.cfg | 11 ++++++++
config/config-arm.mak | 62 +++++++++++++++++++++++++++++++++++++++++++++
configure | 10 ++++++--
lib/arm/bootinfo.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++
lib/arm/bootinfo.h | 19 ++++++++++++++
lib/arm/bswap.h | 30 ++++++++++++++++++++++
lib/arm/io.c | 26 +++++++++++++++++++
lib/bswap.h | 4 +++
lib/libcflat.h | 1 +
13 files changed, 342 insertions(+), 2 deletions(-)
create mode 100644 arm/boot.c
create mode 100644 arm/cstart.S
create mode 100644 arm/flat.lds
create mode 100755 arm/run
create mode 100644 arm/unittests.cfg
create mode 100644 config/config-arm.mak
create mode 100644 lib/arm/bootinfo.c
create mode 100644 lib/arm/bootinfo.h
create mode 100644 lib/arm/bswap.h
create mode 100644 lib/arm/io.c
diff --git a/arm/boot.c b/arm/boot.c
new file mode 100644
index 0000000000000..375e8708a7c54
--- /dev/null
+++ b/arm/boot.c
@@ -0,0 +1,27 @@
+#include "libcflat.h"
+#include "arm/bootinfo.h"
+
+static bool info_check(u32 var, char *expected)
+{
+ char var_str[9];
+ snprintf(var_str, 9, "%x", var);
+ while (*expected == '0' || *expected == 'x')
+ ++expected;
+ return !strcmp(var_str, expected);
+}
+
+int main(int argc, char **argv)
+{
+ int ret = 0;
+
+ if (argc < 3) {
+ printf("Not enough arguments. Can't test\n");
+ return 1;
+ }
+
+ if (!strcmp(argv[0], "info"))
+ ret = !info_check(mem32.size, argv[1])
+ || !info_check(core.pagesize, argv[2]);
+
+ return ret;
+}
diff --git a/arm/cstart.S b/arm/cstart.S
new file mode 100644
index 0000000000000..a65809824d4f1
--- /dev/null
+++ b/arm/cstart.S
@@ -0,0 +1,47 @@
+
+#define CR_B (1 << 7)
+
+.arm
+
+.section .init
+
+.globl start
+start:
+ /* bootloader params are in r0-r2 */
+ ldr sp, =stacktop
+ push { r0-r3 } @push r3 too for 8-byte alignment
+
+ mrc p15, 0, r8, c1, c0, 0 @r8 = sctrl
+ bl get_endianness
+ bl io_init
+
+ pop { r0-r3 }
+ bl read_bootinfo
+ bl __setup_args
+ ldr r0, =__argc
+ ldr r0, [r0]
+ ldr r1, =__argv
+ bl main
+ bl exit
+ b halt
+
+get_endianness:
+ and r0, r8, #CR_B
+ cmp r0, #0
+ beq 1f
+ ldr r1, =cpu_is_be
+ mov r0, #1
+ str r0, [r1]
+1: mov pc, lr
+
+.text
+
+.globl halt
+halt:
+1: wfi
+ b 1b
+
+.data
+
+.globl cpu_is_be
+cpu_is_be: .word 0
diff --git a/arm/flat.lds b/arm/flat.lds
new file mode 100644
index 0000000000000..3e5d72e24989b
--- /dev/null
+++ b/arm/flat.lds
@@ -0,0 +1,18 @@
+
+SECTIONS
+{
+ .text : { *(.init) *(.text) *(.text.*) }
+ . = ALIGN(4K);
+ .data : { *(.data) }
+ . = ALIGN(16);
+ .rodata : { *(.rodata) }
+ . = ALIGN(16);
+ .bss : { *(.bss) }
+ . = ALIGN(4K);
+ edata = .;
+ . += 8K;
+ . = ALIGN(4K);
+ stacktop = .;
+}
+
+ENTRY(start)
diff --git a/arm/run b/arm/run
new file mode 100755
index 0000000000000..64446e8907564
--- /dev/null
+++ b/arm/run
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+qemu="${QEMU:-qemu-system-arm}"
+testdev='virtio-testdev'
+
+if ! $qemu -device '?' 2>&1 | grep $testdev > /dev/null; then
+ echo \"$qemu\" has no support for the virtio test device. Exiting.
+ exit 2
+fi
+
+command="$qemu -device $testdev -display none -serial stdio "
+command+="-M virt -cpu cortex-a15 "
+#command+="-enable-kvm "
+command+="-kernel"
+echo $command "$@"
+$command "$@"
+ret=$?
+echo Return value from qemu: $ret
+exit $ret
diff --git a/arm/unittests.cfg b/arm/unittests.cfg
new file mode 100644
index 0000000000000..fb78cd906839a
--- /dev/null
+++ b/arm/unittests.cfg
@@ -0,0 +1,11 @@
+# Define your new unittest following the convention:
+# [unittest_name]
+# file = foo.flat # Name of the flat file to be used
+# smp = 2 # Number of processors the VM will use during this test
+# extra_params = -append <params...> # Additional parameters used
+# arch = arm/arm64 # Only if the test case works only on one of them
+# groups = group1 group2 # Used to identify test cases with run_tests -g ...
+
+[boot_info]
+file = boot.flat
+extra_params = -m 256 -append 'info 0x10000000 0x1000'
diff --git a/config/config-arm.mak b/config/config-arm.mak
new file mode 100644
index 0000000000000..066b1f725c5b3
--- /dev/null
+++ b/config/config-arm.mak
@@ -0,0 +1,62 @@
+mach = mach-virt
+iodevs = pl011 virtio_mmio
+phys_base = 0x8000000
+
+cstart.o = $(TEST_DIR)/cstart.o
+bits = 32
+ldarch = elf32-littlearm
+kernel_offset = 0x10000
+CFLAGS += -D__arm__
+
+all: test_cases
+
+cflatobjs += \
+ lib/$(TEST_DIR)/iomaps.gen.o \
+ lib/iomaps.o \
+ lib/virtio-testdev.o \
+ lib/arm/io.o \
+ lib/arm/bootinfo.o
+
+$(libcflat): LDFLAGS += -nostdlib
+$(libcflat): CFLAGS += -ffreestanding -I lib
+
+CFLAGS += -Wextra
+CFLAGS += -marm
+#CFLAGS += -mcpu=$(PROCESSOR)
+CFLAGS += -mcpu=cortex-a15
+CFLAGS += -O2
+
+libgcc := $(shell $(CC) -m$(ARCH) --print-libgcc-file-name)
+start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
+
+FLATLIBS = lib/libcflat.a $(libgcc)
+%.elf: %.o $(FLATLIBS) arm/flat.lds
+ $(CC) $(CFLAGS) -nostdlib -o $@ \
+ -Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
+ $(filter %.o, $^) $(FLATLIBS)
+
+%.flat: %.elf
+ $(OBJCOPY) -O binary $^ $@
+
+tests-common = $(TEST_DIR)/boot.flat
+
+tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
+
+test_cases: $(tests-common) $(tests)
+
+$(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I lib
+
+$(TEST_DIR)/boot.elf: $(cstart.o) $(TEST_DIR)/boot.o
+
+lib/$(TEST_DIR)/iomaps.gen.c: lib/$(TEST_DIR)/$(mach).dts
+ scripts/gen-devtree-iomaps.pl $^ $(iodevs) > $@
+
+lib/$(TEST_DIR)/mach-virt.dts: dtb = $(subst .dts,.dtb,$@)
+lib/$(TEST_DIR)/mach-virt.dts:
+ $(QEMU_BIN) -kernel /dev/null -M virt -machine dumpdtb=$(dtb)
+ fdtdump $(dtb) > $@
+
+arch_clean:
+ $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
+ $(TEST_DIR)/.*.d lib/arm/.*.d \
+ lib/$(TEST_DIR)/iomaps.gen.c lib/$(TEST_DIR)/mach-virt.*
diff --git a/configure b/configure
index 6cfc64943f6e6..296c70182ea1d 100755
--- a/configure
+++ b/configure
@@ -6,8 +6,7 @@ cc=gcc
ld=ld
objcopy=objcopy
ar=ar
-arch=`uname -m | sed -e s/i.86/i386/`
-processor="$arch"
+arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'`
cross_prefix=
usage() {
@@ -17,6 +16,7 @@ usage() {
Options include:
--test-dir=DIR the main directory for tests ($arch)
--arch=ARCH architecture to compile for ($arch)
+ --processor=PROCESSOR processor to compile for ($arch)
--cross-prefix=PREFIX cross compiler prefix
--cc=CC c compiler to use ($cc)
--ld=LD ld linker to use ($ld)
@@ -66,6 +66,9 @@ while [[ "$1" = -* ]]; do
;;
esac
done
+[ -z "$processor" ] && processor="$arch"
+qemu="${QEMU:-qemu-system-$arch}"
+
if [ -z "$testdir" -a \( "$arch" = "i386" -o "$arch" = "x86_64" \) ]; then
testdir=x86
elif [ -z "$testdir" ]; then
@@ -80,6 +83,7 @@ if [ -f $testdir/run ]; then
fi
# check for dependent 32 bit libraries
+if [ "$arch" = "i386" -o "$arch" = "x86_64" ]; then
cat << EOF > lib_test.c
#include <stdc++.h>
#include <boost_thread-mt.h>
@@ -94,6 +98,7 @@ if [ $exit -eq 0 ]; then
api=true
fi
rm -f lib_test.c
+fi
cat <<EOF > config.mak
PREFIX=$prefix
@@ -106,4 +111,5 @@ OBJCOPY=$cross_prefix$objcopy
AR=$cross_prefix$ar
API=$api
TEST_DIR=$testdir
+QEMU_BIN=$qemu
EOF
diff --git a/lib/arm/bootinfo.c b/lib/arm/bootinfo.c
new file mode 100644
index 0000000000000..c362064f661d9
--- /dev/null
+++ b/lib/arm/bootinfo.c
@@ -0,0 +1,70 @@
+#include "libcflat.h"
+#include "arm/bootinfo.h"
+#include "arm/bswap.h"
+
+#define FDT_SIG 0xd00dfeed
+
+#define KERNEL_OFFSET 0x00010000
+#define ATAG_OFFSET 0x00000100
+
+#define ATAG_CORE 0x54410001
+#define ATAG_MEM 0x54410002
+#define ATAG_CMDLINE 0x54410009
+
+extern void start(void);
+extern char *__args;
+
+u32 mach_type_id;
+struct tag_core core;
+struct tag_mem32 mem32;
+
+static void read_atags(u32 id, u32 *info)
+{
+ u32 *p = info;
+
+ if (!p) {
+ printf("Can't find bootinfo. mach-type = %x\n", id);
+ exit(ENOEXEC);
+ }
+
+ /*
+ * p[0] count of words for the tag
+ * p[1] tag id
+ * p[2..] tag data
+ */
+ for (; p[0] != 0; p += p[0])
+ switch (p[1]) {
+ case ATAG_CORE:
+ core.flags = p[2];
+ core.pagesize = p[3];
+ core.rootdev = p[4];
+ break;
+ case ATAG_MEM:
+ mem32.size = p[2];
+ mem32.start = p[3];
+ break;
+ case ATAG_CMDLINE:
+ __args = (char *)&p[2];
+ break;
+ }
+}
+
+#define __unused __attribute__((__unused__))
+
+void read_bootinfo(u32 arg __unused, u32 id, u32 *info)
+{
+ u32 *atags = NULL;
+
+ mach_type_id = id;
+
+ if (info[0] == be32_to_cpu(FDT_SIG)) {
+ /*
+ * fdt reading is not [yet?] implemented. So calculate
+ * the ATAGS addr to read that instead.
+ */
+ atags = (u32 *)((u32)start - KERNEL_OFFSET + ATAG_OFFSET);
+ } else if (info[1] == ATAG_CORE)
+ atags = info;
+
+ read_atags(id, atags);
+}
diff --git a/lib/arm/bootinfo.h b/lib/arm/bootinfo.h
new file mode 100644
index 0000000000000..9cf547e4cebeb
--- /dev/null
+++ b/lib/arm/bootinfo.h
@@ -0,0 +1,19 @@
+#ifndef _BOOTINFO_H_
+#define _BOOTINFO_H_
+#include "libcflat.h"
+
+struct tag_core {
+ u32 flags; /* bit 0 = read-only */
+ u32 pagesize;
+ u32 rootdev;
+};
+
+struct tag_mem32 {
+ u32 size;
+ u32 start; /* physical start address */
+};
+
+extern u32 mach_type_id;
+extern struct tag_core core;
+extern struct tag_mem32 mem32;
+#endif
diff --git a/lib/arm/bswap.h b/lib/arm/bswap.h
new file mode 100644
index 0000000000000..9bd16e789fcc5
--- /dev/null
+++ b/lib/arm/bswap.h
@@ -0,0 +1,30 @@
+#ifndef _ARM_BSWAP_H_
+#define _ARM_BSWAP_H_
+#include "libcflat.h"
+
+extern bool cpu_is_be;
+
+static inline u32 bswap32(u32 val)
+{
+ u32 ret;
+ asm volatile("rev %0, %1" : "=r" (ret) : "r" (val));
+ return ret;
+}
+
+static inline u16 bswap16(u16 val)
+{
+ u16 ret;
+ asm volatile("rev16 %0, %1" : "=r" (ret) : "r" (val));
+ return ret;
+}
+
+#define be32_to_cpu(x) (cpu_is_be ? x : bswap32(x))
+#define cpu_to_be32(x) (cpu_is_be ? x : bswap32(x))
+#define be16_to_cpu(x) (cpu_is_be ? x : bswap16(x))
+#define cpu_to_be16(x) (cpu_is_be ? x : bswap16(x))
+
+#define le32_to_cpu(x) (cpu_is_be ? bswap32(x) : x)
+#define cpu_to_le32(x) (cpu_is_be ? bswap32(x) : x)
+#define le16_to_cpu(x) (cpu_is_be ? bswap16(x) : x)
+#define cpu_to_le16(x) (cpu_is_be ? bswap16(x) : x)
+#endif
diff --git a/lib/arm/io.c b/lib/arm/io.c
new file mode 100644
index 0000000000000..951af60551a4c
--- /dev/null
+++ b/lib/arm/io.c
@@ -0,0 +1,26 @@
+#include "libcflat.h"
+#include "iomaps.h"
+#include "virtio-testdev.h"
+
+static volatile u8 *uart0_base;
+
+void puts(const char *s)
+{
+ while (*s)
+ *uart0_base = *s++;
+}
+
+void exit(int code)
+{
+ virtio_testdev_exit(code);
+ halt(code);
+}
+
+void io_init(void)
+{
+ struct iomap *m = iomaps_find("pl011");
+ if (!m)
+ halt(ENXIO);
+ uart0_base = (u8 *)compat_ptr(m->addrs[0]);
+ virtio_testdev_init();
+}
diff --git a/lib/bswap.h b/lib/bswap.h
index e63c4d37a8b9a..a428ed6c646dd 100644
--- a/lib/bswap.h
+++ b/lib/bswap.h
@@ -1,7 +1,11 @@
#ifndef _BSWAP_H_
#define _BSWAP_H_
+#ifdef __arm__
+#include "arm/bswap.h"
+#else
#define le32_to_cpu(x) (x)
#define cpu_to_le32(x) (x)
#define le16_to_cpu(x) (x)
#define cpu_to_le16(x) (x)
#endif
+#endif
diff --git a/lib/libcflat.h b/lib/libcflat.h
index 41791194657d0..dce9a0f516e7e 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -55,6 +55,7 @@ extern char *strcat(char *dest, const char *src);
extern int strcmp(const char *a, const char *b);
extern int printf(const char *fmt, ...);
+extern int snprintf(char *buf, int size, const char *fmt, ...);
extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
extern void puts(const char *s);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 9/9] arm: add vectors support
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
` (7 preceding siblings ...)
2013-10-14 16:23 ` [PATCH 8/9] arm: initial drop Andrew Jones
@ 2013-10-14 16:23 ` Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-11-20 23:06 ` [PATCH 0/9] kvm-unit-tests/arm: initial drop María Soler Heredia
2013-12-29 9:24 ` Christoffer Dall
10 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-14 16:23 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
Add support for tests to manage exception handlers. Now we need kvm.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
arm/boot.c | 29 +++++++++++++++++++----
arm/cstart.S | 46 ++++++++++++++++++++++++++++++++++++
arm/run | 2 +-
arm/unittests.cfg | 6 +++++
config/config-arm.mak | 1 +
lib/arm/bootinfo.c | 2 --
lib/arm/processor.h | 45 +++++++++++++++++++++++++++++++++++
lib/arm/vectors.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++
lib/arm/vectors.h | 37 +++++++++++++++++++++++++++++
lib/libcflat.h | 2 ++
10 files changed, 227 insertions(+), 8 deletions(-)
create mode 100644 lib/arm/processor.h
create mode 100644 lib/arm/vectors.c
create mode 100644 lib/arm/vectors.h
diff --git a/arm/boot.c b/arm/boot.c
index 375e8708a7c54..5103499b83155 100644
--- a/arm/boot.c
+++ b/arm/boot.c
@@ -1,5 +1,10 @@
#include "libcflat.h"
#include "arm/bootinfo.h"
+#include "arm/vectors.h"
+
+#define die(msg...) printf(msg), exit(1)
+
+static bool svc_works;
static bool info_check(u32 var, char *expected)
{
@@ -10,18 +15,32 @@ static bool info_check(u32 var, char *expected)
return !strcmp(var_str, expected);
}
+static void svc_check(struct ex_regs *regs __unused)
+{
+ svc_works = true;
+}
+
+static bool vectors_check(void)
+{
+ handle_exception(V_SVC, svc_check);
+ asm volatile("svc #123");
+ return svc_works;
+}
+
int main(int argc, char **argv)
{
int ret = 0;
- if (argc < 3) {
- printf("Not enough arguments. Can't test\n");
- return 1;
- }
+ if (argc < 1)
+ die("boot: No test name appended to qemu command line\n");
- if (!strcmp(argv[0], "info"))
+ if (!strcmp(argv[0], "info")) {
+ if (argc < 3)
+ die("boot info: Not enough arguments for test\n");
ret = !info_check(mem32.size, argv[1])
|| !info_check(core.pagesize, argv[2]);
+ } else if (!strcmp(argv[0], "vectors"))
+ ret = !vectors_check();
return ret;
}
diff --git a/arm/cstart.S b/arm/cstart.S
index a65809824d4f1..0907c620bd83f 100644
--- a/arm/cstart.S
+++ b/arm/cstart.S
@@ -1,5 +1,6 @@
#define CR_B (1 << 7)
+#define CR_V (1 << 13)
.arm
@@ -12,6 +13,13 @@ start:
push { r0-r3 } @push r3 too for 8-byte alignment
mrc p15, 0, r8, c1, c0, 0 @r8 = sctrl
+
+ /* set up vector table */
+ bic r8, #CR_V @sctrl.V = 0
+ mcr p15, 0, r8, c1, c0, 0
+ ldr r0, =vector_table @vbar = vector_table
+ mcr p15, 0, r0, c12, c0, 0
+
bl get_endianness
bl io_init
@@ -41,6 +49,44 @@ halt:
1: wfi
b 1b
+vector_common:
+ add r2, sp, #(14 * 4)
+ mrs r3, spsr
+ push { r0-r3 } @push r0 too for padding
+ add r0, sp, #4 @skip pad
+ bl do_handle_exception
+ pop { r0-r3 }
+ msr spsr_fsxc, r3
+ ldm sp!, { r0-r12,pc }^
+
+.macro m_vector, v
+ push { r0-r12,lr }
+ mov r1, \v
+ b vector_common
+.endm
+
+reset: m_vector #0
+undef: m_vector #1
+svc: m_vector #2
+prefetch: m_vector #3
+data: m_vector #4
+impossible: m_vector #5
+irq: m_vector #6
+fiq: m_vector #7
+
+.section .text.ex
+.align 5
+
+vector_table:
+ b reset
+ b undef
+ b svc
+ b prefetch
+ b data
+ b impossible
+ b irq
+ b fiq
+
.data
.globl cpu_is_be
diff --git a/arm/run b/arm/run
index 64446e8907564..b512880e28cb7 100755
--- a/arm/run
+++ b/arm/run
@@ -10,7 +10,7 @@ fi
command="$qemu -device $testdev -display none -serial stdio "
command+="-M virt -cpu cortex-a15 "
-#command+="-enable-kvm "
+command+="-enable-kvm "
command+="-kernel"
echo $command "$@"
$command "$@"
diff --git a/arm/unittests.cfg b/arm/unittests.cfg
index fb78cd906839a..9c4faa600e9c5 100644
--- a/arm/unittests.cfg
+++ b/arm/unittests.cfg
@@ -9,3 +9,9 @@
[boot_info]
file = boot.flat
extra_params = -m 256 -append 'info 0x10000000 0x1000'
+groups = boot
+
+[boot_vectors]
+file = boot.flat
+extra_params = -append 'vectors'
+groups = boot
diff --git a/config/config-arm.mak b/config/config-arm.mak
index 066b1f725c5b3..87d61872ab16a 100644
--- a/config/config-arm.mak
+++ b/config/config-arm.mak
@@ -15,6 +15,7 @@ cflatobjs += \
lib/iomaps.o \
lib/virtio-testdev.o \
lib/arm/io.o \
+ lib/arm/vectors.o \
lib/arm/bootinfo.o
$(libcflat): LDFLAGS += -nostdlib
diff --git a/lib/arm/bootinfo.c b/lib/arm/bootinfo.c
index c362064f661d9..fd74fac2c5a2f 100644
--- a/lib/arm/bootinfo.c
+++ b/lib/arm/bootinfo.c
@@ -49,8 +49,6 @@ static void read_atags(u32 id, u32 *info)
}
}
-#define __unused __attribute__((__unused__))
-
void read_bootinfo(u32 arg __unused, u32 id, u32 *info)
{
u32 *atags = NULL;
diff --git a/lib/arm/processor.h b/lib/arm/processor.h
new file mode 100644
index 0000000000000..32e1778477be2
--- /dev/null
+++ b/lib/arm/processor.h
@@ -0,0 +1,45 @@
+#ifndef _PROCESSOR_H_
+#define _PROCESSOR_H_
+#include "libcflat.h"
+
+#define __stringify_1(x...) #x
+#define __stringify(x...) __stringify_1(x)
+
+#undef __regfn
+#define __regfn(reg) \
+static inline u32 read_##reg(void) \
+{ \
+ u32 val; \
+ asm volatile("mov %0, " __stringify(reg) : "=r" (val)); \
+ return val; \
+}
+__regfn(lr)
+
+#undef __regfn
+#define __regfn(reg) \
+static inline void write_##reg(u32 val) \
+{ \
+ asm volatile("mov " __stringify(reg) ", %0" :: "r" (val)); \
+}
+__regfn(lr)
+
+#undef __regfn
+#define __regfn(reg) \
+static inline u32 read_##reg(void) \
+{ \
+ u32 val; \
+ asm volatile("mrs %0, " __stringify(reg) : "=r" (val)); \
+ return val; \
+}
+__regfn(cpsr)
+
+#undef __regfn
+#define __regfn(reg) \
+static inline void write_##reg(u32 val) \
+{ \
+ asm volatile("msr " __stringify(reg) ", %0" :: "r" (val)); \
+}
+__regfn(cpsr)
+
+#undef __regfn
+#endif
diff --git a/lib/arm/vectors.c b/lib/arm/vectors.c
new file mode 100644
index 0000000000000..c1e2dea519e56
--- /dev/null
+++ b/lib/arm/vectors.c
@@ -0,0 +1,65 @@
+#include "libcflat.h"
+#include "arm/processor.h"
+#include "arm/vectors.h"
+
+#define abort(msg...) \
+ printf(msg), dump_ex_regs(regs), exit(EINTR)
+
+const char *mode_names[] = {
+ "usr", "fiq", "irq", "svc", NULL, NULL, NULL,
+ "abt", NULL, NULL, NULL, "und",
+};
+
+const char *vector_names[] = {
+ "Reset", "Undefined", "SVC", "Prefetch abort", "Data abort",
+ "Impossible vector 0x14", "IRQ", "FIQ",
+};
+
+void dump_ex_regs(struct ex_regs *regs)
+{
+ u32 cpsr = read_cpsr();
+ u8 mode, smode;
+
+ mode = cpsr & MODE_MASK;
+ smode = ex_reg(regs, R_SPSR) & MODE_MASK;
+
+ printf("vector = %s\n", vector_name(ex_vector(regs)));
+ printf("mode %s to %s\n", mode_name(smode), mode_name(mode));
+ printf("cpsr=%x\n", cpsr);
+ printf(
+ "r0=%x\n" "r1=%x\n" "r2=%x\n" "r3=%x\n"
+ "r4=%x\n" "r5=%x\n" "r6=%x\n" "r7=%x\n"
+ "r8=%x\n" "r9=%x\n" "r10=%x\n" "r11=%x\n"
+ "ip=%x\n" "sp_%s=%x\n" "lr_%s=%x\n" "cpsr_%s=%x\n",
+ ex_reg(regs,0), ex_reg(regs,1), ex_reg(regs,2), ex_reg(regs,3),
+ ex_reg(regs,4), ex_reg(regs,5), ex_reg(regs,6), ex_reg(regs,7),
+ ex_reg(regs,8), ex_reg(regs,9), ex_reg(regs,10), ex_reg(regs,11),
+ ex_reg(regs, R_IP),
+ mode_name(mode), ex_reg(regs, R_SP),
+ mode_name(mode), ex_reg(regs, R_LR),
+ mode_name(mode), ex_reg(regs, R_SPSR)
+ );
+}
+
+static void (*exception_handlers[8])(struct ex_regs *regs);
+
+void handle_exception(u8 v, void (*func)(struct ex_regs *regs))
+{
+ if (v < 8)
+ exception_handlers[v] = func;
+}
+
+void do_handle_exception(struct ex_regs *regs)
+{
+ u8 v;
+
+ if ((v = ex_vector(regs)) > 7)
+ abort("%s called with vector=%d\n", __func__, v);
+
+ if (exception_handlers[v]) {
+ exception_handlers[v](regs);
+ return;
+ }
+
+ abort("Exception %s\n", vector_name(v));
+}
diff --git a/lib/arm/vectors.h b/lib/arm/vectors.h
new file mode 100644
index 0000000000000..ca074aab674a3
--- /dev/null
+++ b/lib/arm/vectors.h
@@ -0,0 +1,37 @@
+#ifndef _VECTORS_H_
+#define _VECTORS_H_
+
+/* modes */
+enum {
+ M_USR = 0x10, M_FIQ = 0x11, M_IRQ = 0x12, M_SVC = 0x13,
+ M_ABT = 0x17, M_UND = 0x1b,
+};
+#define MODE_MASK 0x1f
+extern const char *mode_names[];
+#define mode_name(m) mode_names[(m) - 0x10]
+
+/* vectors */
+enum {
+ V_RESET, V_UNDEF, V_SVC, V_PREFETCH_ABT, V_DATA_ABT,
+ V_IMPOSSIBLE, V_IRQ, V_FIQ,
+};
+extern const char *vector_names[];
+#define vector_name(v) vector_names[v]
+
+#define R_IP 12
+#define R_SP 13
+#define R_LR 14
+#define R_SPSR 16
+#define __ex_reg(n) \
+ ((n) == R_SP ? 1 : (n) == R_LR ? 16 : (n) == R_SPSR ? 2 : ((n)+3))
+#define ex_reg(regs, n) ((regs)->words[__ex_reg(n)])
+#define ex_vector(regs) ((regs)->words[0])
+
+struct ex_regs {
+ /* see cstart.S for the register push order */
+ unsigned long words[18];
+};
+
+void handle_exception(u8 v, void (*func)(struct ex_regs *regs));
+
+#endif
diff --git a/lib/libcflat.h b/lib/libcflat.h
index dce9a0f516e7e..6ebd903a27f46 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -68,6 +68,8 @@ extern long atol(const char *ptr);
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+#define __unused __attribute__((__unused__))
+
#define NULL ((void *)0UL)
#include "errno.h"
#endif
--
1.8.1.4
^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 6/9] Introduce virtio-testdev
2013-10-14 16:23 ` [PATCH 6/9] Introduce virtio-testdev Andrew Jones
@ 2013-10-15 8:39 ` Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-17 1:06 ` Christoffer Dall
2 siblings, 0 replies; 38+ messages in thread
From: Andrew Jones @ 2013-10-15 8:39 UTC (permalink / raw)
To: kvm; +Cc: kvmarm, gleb, christoffer.dall
On Mon, Oct 14, 2013 at 06:23:32PM +0200, Andrew Jones wrote:
> virtio-testdev is a communication channel to qemu through virtio that
> can be used by test code to send commands. The only command currently
> implemented is EXIT, which allows the test code to exit with a given
> status code.
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> lib/bswap.h | 7 +++
> lib/libcflat.h | 10 ++++
> lib/virtio-testdev.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
> lib/virtio-testdev.h | 9 ++++
> 4 files changed, 152 insertions(+)
> create mode 100644 lib/bswap.h
> create mode 100644 lib/virtio-testdev.c
> create mode 100644 lib/virtio-testdev.h
>
> diff --git a/lib/bswap.h b/lib/bswap.h
> new file mode 100644
> index 0000000000000..e63c4d37a8b9a
> --- /dev/null
> +++ b/lib/bswap.h
> @@ -0,0 +1,7 @@
> +#ifndef _BSWAP_H_
> +#define _BSWAP_H_
> +#define le32_to_cpu(x) (x)
> +#define cpu_to_le32(x) (x)
> +#define le16_to_cpu(x) (x)
> +#define cpu_to_le16(x) (x)
> +#endif
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index a1be635ab4ee9..41791194657d0 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -37,6 +37,16 @@ typedef _Bool bool;
> #define true 1
> #define false 0
>
> +typedef u32 compat_ptr_t;
> +static inline void *compat_ptr(compat_ptr_t ptr)
> +{
> + return (void *)(unsigned long)ptr;
> +}
> +static inline compat_ptr_t ptr_to_compat(void *ptr)
> +{
> + return (u32)(unsigned long)ptr;
> +}
> +
> extern void halt(int code);
> extern void exit(int code);
>
> diff --git a/lib/virtio-testdev.c b/lib/virtio-testdev.c
> new file mode 100644
> index 0000000000000..900921302c344
> --- /dev/null
> +++ b/lib/virtio-testdev.c
> @@ -0,0 +1,126 @@
> +#include "libcflat.h"
> +#include "iomaps.h"
> +#include "bswap.h"
> +
> +#define TESTDEV_MAJOR_VER 1
> +#define TESTDEV_MINOR_VER 1
> +
> +#define VIRTIO_MMIO_DEVICEID 0x8
> +#define VIRTIO_ID_TESTDEV 0xffff
> +#define DEV_CONFIG_BASE 0x100
> +#define DEV_CONFIG_SIZE 0x100
> +
> +enum { VERSION = 1, CLEAR, EXIT, };
> +enum { TOKEN, NARGS, NRETS, ARG1, ARG2, ARG3, ARG4, };
> +
> +#define RET1(nargs) (ARG1 + (nargs) + 0)
> +#define RET2(nargs) (ARG1 + (nargs) + 1)
> +#define RET3(nargs) (ARG1 + (nargs) + 2)
> +#define RET4(nargs) (ARG1 + (nargs) + 3)
> +
> +static u32 *testdev_base;
> +
> +/*
> + * We have to write all args; nargs, nrets, ... first to
> + * avoid executing token's operation until all args are in
> + * place. Then issue the op, and then read the rets. Reading
> + * the rets (or just sanity checking by reading base[0]) will
> + * read a zero into qemu's copy of the token, which allows us
> + * to prepare additional ops without re-executing the last one.
> + */
> +void virtio_testdev(u32 token, u32 nargs, u32 nrets, ...)
> +{
> + volatile u32 *base = testdev_base;
> + volatile u32 *tdp = base + 1;
> + va_list va;
> +
> + if (!testdev_base)
> + return;
> +
> + *tdp++ = cpu_to_le32(nargs);
> + *tdp++ = cpu_to_le32(nrets);
> +
> + va_start(va, nrets);
> +
> + while (nargs--)
> + *tdp++ = cpu_to_le32(va_arg(va, unsigned));
> +
> + /* this runs the op, but then resets base[0] to zero */
> + base[0] = cpu_to_le32(token);
> +
> + /* sanity check */
> + if (base[0] != 0) {
> + printf("virtio-testdev base[0] should always be zero!\n");
> + halt(EIO);
> + }
> +
> + while (nrets--) {
> + u32 *r = va_arg(va, unsigned *);
> + *r = le32_to_cpu(*tdp++);
> + }
> +
> + va_end(va);
> +}
> +
> +void virtio_testdev_version(u32 *version)
> +{
> + virtio_testdev(VERSION, 0, 1, version);
> +}
> +
> +void virtio_testdev_clear(void)
> +{
> + virtio_testdev(CLEAR, 0, 0);
> +}
> +
> +void virtio_testdev_exit(int code)
> +{
> + virtio_testdev(EXIT, 1, 0, code);
> +}
> +
> +void virtio_testdev_init(void)
> +{
> + struct iomap *m;
> + u32 version, i;
> + u16 major, minor;
> +
> + m = iomaps_find("virtio_mmio");
> + if (!m) {
> + printf("No virtio-mmio transports for virtio-testdev found!\n");
> + halt(ENODEV);
> + }
> +
> + for (i = 0; i < m->nr; ++i) {
> + volatile u32 *base = (u32 *)compat_ptr(m->addrs[i]);
> + u32 devid32 = base[VIRTIO_MMIO_DEVICEID / 4];
> + u16 devid = devid32 & 0xffff;
> + devid = le16_to_cpu(devid);
> + if (devid == VIRTIO_ID_TESTDEV) {
Argh, I was just looking back over this file, and now see that I screwed
up here. It should of course be
u32 devid32 = le32_to_cpu(base[VIRTIO_MMIO_DEVICEID / 4]);
u16 devid = devid32 & 0xffff;
I'll need to send a v2 for this, but I'll wait a bit for other comments
to roll in before doing so.
drew
> + testdev_base = (u32 *)compat_ptr(m->addrs[i] + DEV_CONFIG_BASE);
> + break;
> + }
> + }
> +
> + if (!testdev_base) {
> + printf("Can't find virtio-testdev. Is '-device virtio-testdev' "
> + "on the qemu command line?\n");
> + halt(ENODEV);
> + }
> +
> + virtio_testdev_version(&version);
> + major = version >> 16;
> + minor = version & 0xffff;
> +
> + if (major != TESTDEV_MAJOR_VER || minor < TESTDEV_MINOR_VER) {
> + char *u = "qemu";
> + if (major > TESTDEV_MAJOR_VER)
> + u = "kvm-unit-tests";
> + printf("Refusing to run with virtio-testdev major = %d, minor = %d\n",
> + major, minor);
> + printf("Update %s.\n", u);
> + exit(ENODEV);
> + }
> +
> + if (minor > TESTDEV_MINOR_VER)
> + printf("testdev has new features. "
> + "An update of kvm-unit-tests may be possible.\n");
> +}
> diff --git a/lib/virtio-testdev.h b/lib/virtio-testdev.h
> new file mode 100644
> index 0000000000000..c10bbfb591d0b
> --- /dev/null
> +++ b/lib/virtio-testdev.h
> @@ -0,0 +1,9 @@
> +#ifndef _VIRTIO_TESTDEV_H_
> +#define _VIRTIO_TESTDEV_H_
> +#include "libcflat.h"
> +
> +extern void virtio_testdev_init(void);
> +extern void virtio_testdev_version(u32 *version);
> +extern void virtio_testdev_clear(void);
> +extern void virtio_testdev_exit(int code);
> +#endif
> --
> 1.8.1.4
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 1/9] remove unused files
2013-10-14 16:23 ` [PATCH 1/9] remove unused files Andrew Jones
@ 2013-10-16 12:52 ` Gleb Natapov
2013-10-16 13:13 ` Alexander Graf
2013-10-16 13:18 ` Andrew Jones
0 siblings, 2 replies; 38+ messages in thread
From: Gleb Natapov @ 2013-10-16 12:52 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, christoffer.dall, Alexander Graf
Copying Alex in case he has an opinion about removing powerpc.
On Mon, Oct 14, 2013 at 06:23:27PM +0200, Andrew Jones wrote:
> There are several unused files, primarily because powerpc is an unused
> arch. The exceptions are config-ia64.mak, which is also an unused arch
> file, lib/fwcfg.c, lib/panic.c, x86/print.h and x86/run-kvm-unit-tests,
> which are just unused. Remove them all in order to tidy things up.
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> Makefile | 8 +-
> config-ia64.mak | 7 -
> config-powerpc-440.mak | 15 -
> config-powerpc.mak | 39 ---
> formats | 31 --
> iotable.c | 53 ----
> iotable.h | 40 ---
> kvmtrace.c | 706 ---------------------------------------------
> kvmtrace_format | 532 ----------------------------------
> lib/fwcfg.c | 58 ----
> lib/libcflat.h | 1 -
> lib/panic.c | 13 -
> lib/powerpc/44x/map.c | 51 ----
> lib/powerpc/44x/timebase.S | 28 --
> lib/powerpc/44x/timebase.h | 25 --
> lib/powerpc/44x/tlbwe.S | 29 --
> lib/powerpc/io.c | 35 ---
> main-ppc.c | 383 ------------------------
> powerpc/44x/tlbsx.S | 33 ---
> powerpc/44x/tlbwe.S | 27 --
> powerpc/44x/tlbwe_16KB.S | 35 ---
> powerpc/44x/tlbwe_hole.S | 27 --
> powerpc/cstart.S | 38 ---
> powerpc/exit.c | 23 --
> powerpc/helloworld.c | 27 --
> powerpc/io.S | 32 --
> powerpc/spin.S | 4 -
> powerpc/sprg.S | 7 -
> x86/print.h | 19 --
> x86/run-kvm-unit-tests | 6 -
> 30 files changed, 1 insertion(+), 2331 deletions(-)
> delete mode 100644 config-ia64.mak
> delete mode 100644 config-powerpc-440.mak
> delete mode 100644 config-powerpc.mak
> delete mode 100644 formats
> delete mode 100644 iotable.c
> delete mode 100644 iotable.h
> delete mode 100644 kvmtrace.c
> delete mode 100755 kvmtrace_format
> delete mode 100644 lib/fwcfg.c
> delete mode 100644 lib/panic.c
> delete mode 100644 lib/powerpc/44x/map.c
> delete mode 100644 lib/powerpc/44x/timebase.S
> delete mode 100644 lib/powerpc/44x/timebase.h
> delete mode 100644 lib/powerpc/44x/tlbwe.S
> delete mode 100644 lib/powerpc/io.c
> delete mode 100644 main-ppc.c
> delete mode 100644 powerpc/44x/tlbsx.S
> delete mode 100644 powerpc/44x/tlbwe.S
> delete mode 100644 powerpc/44x/tlbwe_16KB.S
> delete mode 100644 powerpc/44x/tlbwe_hole.S
> delete mode 100644 powerpc/cstart.S
> delete mode 100644 powerpc/exit.c
> delete mode 100644 powerpc/helloworld.c
> delete mode 100644 powerpc/io.S
> delete mode 100644 powerpc/spin.S
> delete mode 100644 powerpc/sprg.S
> delete mode 100644 x86/print.h
> delete mode 100644 x86/run-kvm-unit-tests
>
> diff --git a/Makefile b/Makefile
> index b6e87598721a6..278791dbbef23 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -12,7 +12,6 @@ libgcc := $(shell $(CC) --print-libgcc-file-name)
>
> libcflat := lib/libcflat.a
> cflatobjs := \
> - lib/panic.o \
> lib/printf.o \
> lib/string.o
> cflatobjs += lib/argv.o
> @@ -39,11 +38,6 @@ autodepend-flags = -MMD -MF $(dir $*).$(notdir $*).d
> LDFLAGS += $(CFLAGS)
> LDFLAGS += -pthread -lrt
>
> -kvmtrace_objs= kvmtrace.o
> -
> -kvmtrace: $(kvmtrace_objs)
> - $(CC) $(LDFLAGS) $^ -o $@
> -
> $(libcflat): $(cflatobjs)
> $(AR) rcs $@ $^
>
> @@ -57,4 +51,4 @@ install:
> install $(tests_and_config) $(DESTDIR)
>
> clean: arch_clean
> - $(RM) kvmtrace *.o *.a .*.d $(libcflat) $(cflatobjs)
> + $(RM) *.o *.a .*.d $(libcflat) $(cflatobjs)
> diff --git a/config-ia64.mak b/config-ia64.mak
> deleted file mode 100644
> index d9350fcc5a9ec..0000000000000
> --- a/config-ia64.mak
> +++ /dev/null
> @@ -1,7 +0,0 @@
> -bits = 64
> -CFLAGS += -m64
> -CFLAGS += -D__ia64__
> -CFLAGS += -I../include/ia64
> -
> -all:
> -
> diff --git a/config-powerpc-440.mak b/config-powerpc-440.mak
> deleted file mode 100644
> index bb8597153b30e..0000000000000
> --- a/config-powerpc-440.mak
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -
> -
> -# for some reason binutils hates tlbsx unless we say we're 405 :(
> -CFLAGS += -Wa,-m405 -I lib/powerpc/44x
> -
> -cflatobjs += \
> - lib/powerpc/44x/map.o \
> - lib/powerpc/44x/tlbwe.o \
> - lib/powerpc/44x/timebase.o
> -
> -simpletests += \
> - powerpc/44x/tlbsx.bin \
> - powerpc/44x/tlbwe_16KB.bin \
> - powerpc/44x/tlbwe_hole.bin \
> - powerpc/44x/tlbwe.bin
> diff --git a/config-powerpc.mak b/config-powerpc.mak
> deleted file mode 100644
> index d053569b8aa3c..0000000000000
> --- a/config-powerpc.mak
> +++ /dev/null
> @@ -1,39 +0,0 @@
> -CFLAGS += -I../include/powerpc
> -CFLAGS += -Wa,-mregnames -I lib
> -CFLAGS += -ffreestanding
> -
> -cstart := powerpc/cstart.o
> -
> -cflatobjs += \
> - lib/powerpc/io.o
> -
> -$(libcflat): LDFLAGS += -nostdlib
> -
> -# these tests do not use libcflat
> -simpletests := \
> - powerpc/spin.bin \
> - powerpc/io.bin \
> - powerpc/sprg.bin
> -
> -# theses tests use cstart.o, libcflat, and libgcc
> -tests := \
> - powerpc/exit.bin \
> - powerpc/helloworld.bin
> -
> -include config-powerpc-$(PROCESSOR).mak
> -
> -
> -all: kvmtrace kvmctl $(libcflat) $(simpletests) $(tests)
> -
> -$(simpletests): %.bin: %.o
> - $(CC) -nostdlib $^ -Wl,-T,flat.lds -o $@
> -
> -$(tests): %.bin: $(cstart) %.o $(libcflat)
> - $(CC) -nostdlib $^ $(libgcc) -Wl,-T,flat.lds -o $@
> -
> -kvmctl_objs = main-ppc.o iotable.o ../libkvm/libkvm.a
> -
> -arch_clean:
> - $(RM) $(simpletests) $(tests) $(cstart)
> - $(RM) $(patsubst %.bin, %.elf, $(simpletests) $(tests))
> - $(RM) $(patsubst %.bin, %.o, $(simpletests) $(tests))
> diff --git a/formats b/formats
> deleted file mode 100644
> index 7f4ebdbcedaa2..0000000000000
> --- a/formats
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -0x00000000 %(ts)d (+%(relts)12d) unknown (0x%(event)016x) vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ 0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x ]
> -
> -0x00010001 %(ts)d (+%(relts)12d) VMENTRY vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x
> -0x00010002 %(ts)d (+%(relts)12d) VMEXIT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ exitcode = 0x%(1)08x, rip = 0x%(3)08x %(2)08x ]
> -0x00020001 %(ts)d (+%(relts)12d) PAGE_FAULT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
> -0x00020002 %(ts)d (+%(relts)12d) INJ_VIRQ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
> -0x00020003 %(ts)d (+%(relts)12d) REDELIVER_EVT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
> -0x00020004 %(ts)d (+%(relts)12d) PEND_INTR vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
> -0x00020005 %(ts)d (+%(relts)12d) IO_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ]
> -0x00020006 %(ts)d (+%(relts)12d) IO_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ]
> -0x00020007 %(ts)d (+%(relts)12d) CR_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ]
> -0x00020008 %(ts)d (+%(relts)12d) CR_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ]
> -0x00020009 %(ts)d (+%(relts)12d) DR_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ]
> -0x0002000A %(ts)d (+%(relts)12d) DR_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ]
> -0x0002000B %(ts)d (+%(relts)12d) MSR_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ]
> -0x0002000C %(ts)d (+%(relts)12d) MSR_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ]
> -0x0002000D %(ts)d (+%(relts)12d) CPUID vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ func = 0x%(1)08x, eax = 0x%(2)08x, ebx = 0x%(3)08x, ecx = 0x%(4)08x edx = 0x%(5)08x]
> -0x0002000E %(ts)d (+%(relts)12d) INTR vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
> -0x0002000F %(ts)d (+%(relts)12d) NMI vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x
> -0x00020010 %(ts)d (+%(relts)12d) VMMCALL vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ func = 0x%(1)08x ]
> -0x00020011 %(ts)d (+%(relts)12d) HLT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x
> -0x00020012 %(ts)d (+%(relts)12d) CLTS vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x
> -0x00020013 %(ts)d (+%(relts)12d) LMSW vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ value = 0x%(1)08x ]
> -0x00020014 %(ts)d (+%(relts)12d) APIC_ACCESS vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ offset = 0x%(1)08x ]
> -0x00020015 %(ts)d (+%(relts)12d) TDP_FAULT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
> -# ppc: tlb traces
> -0x00020016 GTLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
> -0x00020017 STLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
> -0x00020018 STLB_INVAL vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
> -# ppc: instruction emulation - this type is handled more complex in kvmtrace_format, but listed to show the eventid and transported data
> -#0x00020019 %(ts)d (+%(relts)12d) PPC_INSTR vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ instr = 0x%(1)08x, pc = 0x%(2)08x, emul = 0x%(3)08x, nsec = %(4)08d ]
> diff --git a/iotable.c b/iotable.c
> deleted file mode 100644
> index 91a5016c42005..0000000000000
> --- a/iotable.c
> +++ /dev/null
> @@ -1,53 +0,0 @@
> -/*
> - * Kernel-based Virtual Machine test driver
> - *
> - * This test driver provides a simple way of testing kvm, without a full
> - * device model.
> - *
> - * Copyright (C) 2006 Qumranet
> - *
> - * Authors:
> - *
> - * Avi Kivity <avi@qumranet.com>
> - * Yaniv Kamay <yaniv@qumranet.com>
> - *
> - * This work is licensed under the GNU LGPL license, version 2.
> - */
> -
> -#include <stdlib.h>
> -#include <stdint.h>
> -#include <errno.h>
> -
> -#include "iotable.h"
> -
> -struct io_table_entry *io_table_lookup(struct io_table *io_table, uint64_t addr)
> -{
> - int i;
> -
> - for (i = 0; i < io_table->nr_entries; i++) {
> - if (io_table->entries[i].start <= addr &&
> - addr < io_table->entries[i].end)
> - return &io_table->entries[i];
> - }
> -
> - return NULL;
> -}
> -
> -int io_table_register(struct io_table *io_table, uint64_t start, uint64_t size,
> - io_table_handler_t *handler, void *opaque)
> -{
> - struct io_table_entry *entry;
> -
> - if (io_table->nr_entries == MAX_IO_TABLE)
> - return -ENOSPC;
> -
> - entry = &io_table->entries[io_table->nr_entries];
> - io_table->nr_entries++;
> -
> - entry->start = start;
> - entry->end = start + size;
> - entry->handler = handler;
> - entry->opaque = opaque;
> -
> - return 0;
> -}
> diff --git a/iotable.h b/iotable.h
> deleted file mode 100644
> index cb18f23789be1..0000000000000
> --- a/iotable.h
> +++ /dev/null
> @@ -1,40 +0,0 @@
> -/*
> - * Kernel-based Virtual Machine test driver
> - *
> - * This test driver provides a simple way of testing kvm, without a full
> - * device model.
> - *
> - * Copyright (C) 2006 Qumranet
> - *
> - * Authors:
> - *
> - * Avi Kivity <avi@qumranet.com>
> - * Yaniv Kamay <yaniv@qumranet.com>
> - *
> - * This work is licensed under the GNU LGPL license, version 2.
> - */
> -
> -#include <stdint.h>
> -
> -#define MAX_IO_TABLE 50
> -
> -typedef int (io_table_handler_t)(void *, int, int, uint64_t, uint64_t *);
> -
> -struct io_table_entry
> -{
> - uint64_t start;
> - uint64_t end;
> - io_table_handler_t *handler;
> - void *opaque;
> -};
> -
> -struct io_table
> -{
> - int nr_entries;
> - struct io_table_entry entries[MAX_IO_TABLE];
> -};
> -
> -struct io_table_entry *io_table_lookup(struct io_table *io_table,
> - uint64_t addr);
> -int io_table_register(struct io_table *io_table, uint64_t start, uint64_t size,
> - io_table_handler_t *handler, void *opaque);
> diff --git a/kvmtrace.c b/kvmtrace.c
> deleted file mode 100644
> index de3c1897f4660..0000000000000
> --- a/kvmtrace.c
> +++ /dev/null
> @@ -1,706 +0,0 @@
> -/*
> - * kvm tracing application
> - *
> - * This tool is used for collecting trace buffer data
> - * for kvm trace.
> - *
> - * Based on blktrace 0.99.3
> - *
> - * Copyright (C) 2005 Jens Axboe <axboe@suse.de>
> - * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
> - * Copyright (C) 2008 Eric Liu <eric.e.liu@intel.com>
> - *
> - * This work is licensed under the GNU LGPL license, version 2.
> - */
> -
> -#define _GNU_SOURCE
> -
> -#include <pthread.h>
> -#include <sys/types.h>
> -#include <sys/stat.h>
> -#include <unistd.h>
> -#include <signal.h>
> -#include <fcntl.h>
> -#include <string.h>
> -#include <sys/ioctl.h>
> -#include <sys/param.h>
> -#include <sys/statfs.h>
> -#include <sys/poll.h>
> -#include <sys/mman.h>
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <ctype.h>
> -#include <getopt.h>
> -#include <errno.h>
> -#include <sched.h>
> -
> -#ifndef __user
> -#define __user
> -#endif
> -#include <linux/kvm.h>
> -
> -static char kvmtrace_version[] = "0.1";
> -
> -/*
> - * You may want to increase this even more, if you are logging at a high
> - * rate and see skipped/missed events
> - */
> -#define BUF_SIZE (512 * 1024)
> -#define BUF_NR (8)
> -
> -#define OFILE_BUF (128 * 1024)
> -
> -#define DEBUGFS_TYPE 0x64626720
> -
> -#define max(a, b) ((a) > (b) ? (a) : (b))
> -
> -#define S_OPTS "r:o:w:?Vb:n:D:"
> -static struct option l_opts[] = {
> - {
> - .name = "relay",
> - .has_arg = required_argument,
> - .flag = NULL,
> - .val = 'r'
> - },
> - {
> - .name = "output",
> - .has_arg = required_argument,
> - .flag = NULL,
> - .val = 'o'
> - },
> - {
> - .name = "stopwatch",
> - .has_arg = required_argument,
> - .flag = NULL,
> - .val = 'w'
> - },
> - {
> - .name = "version",
> - .has_arg = no_argument,
> - .flag = NULL,
> - .val = 'V'
> - },
> - {
> - .name = "buffer-size",
> - .has_arg = required_argument,
> - .flag = NULL,
> - .val = 'b'
> - },
> - {
> - .name = "num-sub-buffers",
> - .has_arg = required_argument,
> - .flag = NULL,
> - .val = 'n'
> - },
> - {
> - .name = "output-dir",
> - .has_arg = required_argument,
> - .flag = NULL,
> - .val = 'D'
> - },
> - {
> - .name = NULL,
> - }
> -};
> -
> -struct thread_information {
> - int cpu;
> - pthread_t thread;
> -
> - int fd;
> - char fn[MAXPATHLEN + 64];
> -
> - FILE *ofile;
> - char *ofile_buffer;
> -
> - int (*get_subbuf)(struct thread_information *, unsigned int);
> - int (*read_data)(struct thread_information *, void *, unsigned int);
> -
> - unsigned long long data_read;
> -
> - struct kvm_trace_information *trace_info;
> -
> - int exited;
> -
> - /*
> - * mmap controlled output files
> - */
> - unsigned long long fs_size;
> - unsigned long long fs_max_size;
> - unsigned long fs_off;
> - void *fs_buf;
> - unsigned long fs_buf_len;
> -
> -};
> -
> -struct kvm_trace_information {
> - int fd;
> - volatile int trace_started;
> - unsigned long lost_records;
> - struct thread_information *threads;
> - unsigned long buf_size;
> - unsigned long buf_nr;
> -};
> -
> -static struct kvm_trace_information trace_information;
> -
> -static int ncpus;
> -static char default_debugfs_path[] = "/sys/kernel/debug";
> -
> -/* command line option globals */
> -static char *debugfs_path;
> -static char *output_name;
> -static char *output_dir;
> -static int stop_watch;
> -static unsigned long buf_size = BUF_SIZE;
> -static unsigned long buf_nr = BUF_NR;
> -static unsigned int page_size;
> -
> -#define for_each_cpu_online(cpu) \
> - for (cpu = 0; cpu < ncpus; cpu++)
> -#define for_each_tip(tip, i) \
> - for (i = 0, tip = trace_information.threads; i < ncpus; i++, tip++)
> -
> -#define is_done() (*(volatile int *)(&done))
> -static volatile int done;
> -
> -#define is_trace_stopped() (*(volatile int *)(&trace_stopped))
> -static volatile int trace_stopped;
> -
> -static void exit_trace(int status);
> -
> -static void handle_sigint(__attribute__((__unused__)) int sig)
> -{
> - ioctl(trace_information.fd, KVM_TRACE_PAUSE);
> - done = 1;
> -}
> -
> -static int get_lost_records()
> -{
> - int fd;
> - char tmp[MAXPATHLEN + 64];
> -
> - snprintf(tmp, sizeof(tmp), "%s/kvm/lost_records", debugfs_path);
> - fd = open(tmp, O_RDONLY);
> - if (fd < 0) {
> - /*
> - * this may be ok, if the kernel doesn't support dropped counts
> - */
> - if (errno == ENOENT)
> - return 0;
> -
> - fprintf(stderr, "Couldn't open dropped file %s\n", tmp);
> - return -1;
> - }
> -
> - if (read(fd, tmp, sizeof(tmp)) < 0) {
> - perror(tmp);
> - close(fd);
> - return -1;
> - }
> - close(fd);
> -
> - return atoi(tmp);
> -}
> -
> -static void wait_for_data(struct thread_information *tip, int timeout)
> -{
> - struct pollfd pfd = { .fd = tip->fd, .events = POLLIN };
> -
> - while (!is_done()) {
> - if (poll(&pfd, 1, timeout) < 0) {
> - perror("poll");
> - break;
> - }
> - if (pfd.revents & POLLIN)
> - break;
> - }
> -}
> -
> -static int read_data(struct thread_information *tip, void *buf,
> - unsigned int len)
> -{
> - int ret = 0;
> -
> - do {
> - wait_for_data(tip, 100);
> -
> - ret = read(tip->fd, buf, len);
> -
> - if (!ret)
> - continue;
> - else if (ret > 0)
> - return ret;
> - else {
> - if (errno != EAGAIN) {
> - perror(tip->fn);
> - fprintf(stderr, "Thread %d failed read of %s\n",
> - tip->cpu, tip->fn);
> - break;
> - }
> - continue;
> - }
> - } while (!is_done());
> -
> - return ret;
> -
> -}
> -
> -/*
> - * For file output, truncate and mmap the file appropriately
> - */
> -static int mmap_subbuf(struct thread_information *tip, unsigned int maxlen)
> -{
> - int ofd = fileno(tip->ofile);
> - int ret;
> - unsigned long nr;
> - unsigned long size;
> -
> - /*
> - * extend file, if we have to. use chunks of 16 subbuffers.
> - */
> - if (tip->fs_off + maxlen > tip->fs_buf_len) {
> - if (tip->fs_buf) {
> - munlock(tip->fs_buf, tip->fs_buf_len);
> - munmap(tip->fs_buf, tip->fs_buf_len);
> - tip->fs_buf = NULL;
> - }
> -
> - tip->fs_off = tip->fs_size & (page_size - 1);
> - nr = max(16, tip->trace_info->buf_nr);
> - size = tip->trace_info->buf_size;
> - tip->fs_buf_len = (nr * size) - tip->fs_off;
> - tip->fs_max_size += tip->fs_buf_len;
> -
> - if (ftruncate(ofd, tip->fs_max_size) < 0) {
> - perror("ftruncate");
> - return -1;
> - }
> -
> - tip->fs_buf = mmap(NULL, tip->fs_buf_len, PROT_WRITE,
> - MAP_SHARED, ofd, tip->fs_size - tip->fs_off);
> - if (tip->fs_buf == MAP_FAILED) {
> - perror("mmap");
> - return -1;
> - }
> - mlock(tip->fs_buf, tip->fs_buf_len);
> - }
> -
> - ret = tip->read_data(tip, tip->fs_buf + tip->fs_off, maxlen);
> - if (ret >= 0) {
> - tip->data_read += ret;
> - tip->fs_size += ret;
> - tip->fs_off += ret;
> - return 0;
> - }
> -
> - return -1;
> -}
> -
> -static void tip_ftrunc_final(struct thread_information *tip)
> -{
> - /*
> - * truncate to right size and cleanup mmap
> - */
> - if (tip->ofile) {
> - int ofd = fileno(tip->ofile);
> -
> - if (tip->fs_buf)
> - munmap(tip->fs_buf, tip->fs_buf_len);
> -
> - ftruncate(ofd, tip->fs_size);
> - }
> -}
> -
> -static void *thread_main(void *arg)
> -{
> - struct thread_information *tip = arg;
> - pid_t pid = getpid();
> - cpu_set_t cpu_mask;
> -
> - CPU_ZERO(&cpu_mask);
> - CPU_SET((tip->cpu), &cpu_mask);
> -
> - if (sched_setaffinity(pid, sizeof(cpu_mask), &cpu_mask) == -1) {
> - perror("sched_setaffinity");
> - exit_trace(1);
> - }
> -
> - snprintf(tip->fn, sizeof(tip->fn), "%s/kvm/trace%d",
> - debugfs_path, tip->cpu);
> - tip->fd = open(tip->fn, O_RDONLY);
> - if (tip->fd < 0) {
> - perror(tip->fn);
> - fprintf(stderr, "Thread %d failed open of %s\n", tip->cpu,
> - tip->fn);
> - exit_trace(1);
> - }
> - while (!is_done()) {
> - if (tip->get_subbuf(tip, tip->trace_info->buf_size) < 0)
> - break;
> - }
> -
> - /*
> - * trace is stopped, pull data until we get a short read
> - */
> - while (tip->get_subbuf(tip, tip->trace_info->buf_size) > 0)
> - ;
> -
> - tip_ftrunc_final(tip);
> - tip->exited = 1;
> - return NULL;
> -}
> -
> -static int fill_ofname(struct thread_information *tip, char *dst)
> -{
> - struct stat sb;
> - int len = 0;
> -
> - if (output_dir)
> - len = sprintf(dst, "%s/", output_dir);
> - else
> - len = sprintf(dst, "./");
> -
> - if (stat(dst, &sb) < 0) {
> - if (errno != ENOENT) {
> - perror("stat");
> - return 1;
> - }
> - if (mkdir(dst, 0755) < 0) {
> - perror(dst);
> - fprintf(stderr, "Can't make output dir\n");
> - return 1;
> - }
> - }
> -
> - sprintf(dst + len, "%s.kvmtrace.%d", output_name, tip->cpu);
> -
> - return 0;
> -}
> -
> -static void fill_ops(struct thread_information *tip)
> -{
> - tip->get_subbuf = mmap_subbuf;
> - tip->read_data = read_data;
> -}
> -
> -static void close_thread(struct thread_information *tip)
> -{
> - if (tip->fd != -1)
> - close(tip->fd);
> - if (tip->ofile)
> - fclose(tip->ofile);
> - if (tip->ofile_buffer)
> - free(tip->ofile_buffer);
> -
> - tip->fd = -1;
> - tip->ofile = NULL;
> - tip->ofile_buffer = NULL;
> -}
> -
> -static int tip_open_output(struct thread_information *tip)
> -{
> - int mode, vbuf_size;
> - char op[NAME_MAX];
> -
> - if (fill_ofname(tip, op))
> - return 1;
> -
> - tip->ofile = fopen(op, "w+");
> - mode = _IOFBF;
> - vbuf_size = OFILE_BUF;
> -
> - if (tip->ofile == NULL) {
> - perror(op);
> - return 1;
> - }
> -
> - tip->ofile_buffer = malloc(vbuf_size);
> - if (setvbuf(tip->ofile, tip->ofile_buffer, mode, vbuf_size)) {
> - perror("setvbuf");
> - close_thread(tip);
> - return 1;
> - }
> -
> - fill_ops(tip);
> - return 0;
> -}
> -
> -static int start_threads(int cpu)
> -{
> - struct thread_information *tip;
> -
> - tip = trace_information.threads + cpu;
> - tip->cpu = cpu;
> - tip->trace_info = &trace_information;
> - tip->fd = -1;
> -
> - if (tip_open_output(tip))
> - return 1;
> -
> - if (pthread_create(&tip->thread, NULL, thread_main, tip)) {
> - perror("pthread_create");
> - close_thread(tip);
> - return 1;
> - }
> -
> - return 0;
> -}
> -
> -static void stop_threads()
> -{
> - struct thread_information *tip;
> - unsigned long ret;
> - int i;
> -
> - for_each_tip(tip, i) {
> - if (tip->thread)
> - (void) pthread_join(tip->thread, (void *) &ret);
> - close_thread(tip);
> - }
> -}
> -
> -static int start_trace(void)
> -{
> - int fd;
> - struct kvm_user_trace_setup kuts;
> -
> - fd = trace_information.fd = open("/dev/kvm", O_RDWR);
> - if (fd == -1) {
> - perror("/dev/kvm");
> - return 1;
> - }
> -
> - memset(&kuts, 0, sizeof(kuts));
> - kuts.buf_size = trace_information.buf_size = buf_size;
> - kuts.buf_nr = trace_information.buf_nr = buf_nr;
> -
> - if (ioctl(trace_information.fd , KVM_TRACE_ENABLE, &kuts) < 0) {
> - perror("KVM_TRACE_ENABLE");
> - close(fd);
> - return 1;
> - }
> - trace_information.trace_started = 1;
> -
> - return 0;
> -}
> -
> -static void cleanup_trace(void)
> -{
> - if (trace_information.fd == -1)
> - return;
> -
> - trace_information.lost_records = get_lost_records();
> -
> - if (trace_information.trace_started) {
> - trace_information.trace_started = 0;
> - if (ioctl(trace_information.fd, KVM_TRACE_DISABLE) < 0)
> - perror("KVM_TRACE_DISABLE");
> - }
> -
> - close(trace_information.fd);
> - trace_information.fd = -1;
> -}
> -
> -static void stop_all_traces(void)
> -{
> - if (!is_trace_stopped()) {
> - trace_stopped = 1;
> - stop_threads();
> - cleanup_trace();
> - }
> -}
> -
> -static void exit_trace(int status)
> -{
> - stop_all_traces();
> - exit(status);
> -}
> -
> -static int start_kvm_trace(void)
> -{
> - int i, size;
> - struct thread_information *tip;
> -
> - size = ncpus * sizeof(struct thread_information);
> - tip = malloc(size);
> - if (!tip) {
> - fprintf(stderr, "Out of memory, threads (%d)\n", size);
> - return 1;
> - }
> - memset(tip, 0, size);
> - trace_information.threads = tip;
> -
> - if (start_trace())
> - return 1;
> -
> - for_each_cpu_online(i) {
> - if (start_threads(i)) {
> - fprintf(stderr, "Failed to start worker threads\n");
> - break;
> - }
> - }
> -
> - if (i != ncpus) {
> - stop_threads();
> - cleanup_trace();
> - return 1;
> - }
> -
> - return 0;
> -}
> -
> -static void wait_for_threads(void)
> -{
> - struct thread_information *tip;
> - int i, tips_running;
> -
> - do {
> - tips_running = 0;
> - usleep(100000);
> -
> - for_each_tip(tip, i)
> - tips_running += !tip->exited;
> -
> - } while (tips_running);
> -}
> -
> -static void show_stats(void)
> -{
> - struct thread_information *tip;
> - unsigned long long data_read;
> - int i;
> -
> - data_read = 0;
> - for_each_tip(tip, i) {
> - printf(" CPU%3d: %8llu KiB data\n",
> - tip->cpu, (tip->data_read + 1023) >> 10);
> - data_read += tip->data_read;
> - }
> -
> - printf(" Total: lost %lu, %8llu KiB data\n",
> - trace_information.lost_records, (data_read + 1023) >> 10);
> -
> - if (trace_information.lost_records)
> - fprintf(stderr, "You have lost records, "
> - "consider using a larger buffer size (-b)\n");
> -}
> -
> -static char usage_str[] = \
> - "[ -r debugfs path ] [ -D output dir ] [ -b buffer size ]\n" \
> - "[ -n number of buffers] [ -o <output file> ] [ -w time ] [ -V ]\n\n" \
> - "\t-r Path to mounted debugfs, defaults to /sys/kernel/debug\n" \
> - "\t-o File(s) to send output to\n" \
> - "\t-D Directory to prepend to output file names\n" \
> - "\t-w Stop after defined time, in seconds\n" \
> - "\t-b Sub buffer size in KiB\n" \
> - "\t-n Number of sub buffers\n" \
> - "\t-V Print program version info\n\n";
> -
> -static void show_usage(char *prog)
> -{
> - fprintf(stderr, "Usage: %s %s %s", prog, kvmtrace_version, usage_str);
> - exit(EXIT_FAILURE);
> -}
> -
> -void parse_args(int argc, char **argv)
> -{
> - int c;
> -
> - while ((c = getopt_long(argc, argv, S_OPTS, l_opts, NULL)) >= 0) {
> - switch (c) {
> - case 'r':
> - debugfs_path = optarg;
> - break;
> - case 'o':
> - output_name = optarg;
> - break;
> - case 'w':
> - stop_watch = atoi(optarg);
> - if (stop_watch <= 0) {
> - fprintf(stderr,
> - "Invalid stopwatch value (%d secs)\n",
> - stop_watch);
> - exit(EXIT_FAILURE);
> - }
> - break;
> - case 'V':
> - printf("%s version %s\n", argv[0], kvmtrace_version);
> - exit(EXIT_SUCCESS);
> - case 'b':
> - buf_size = strtoul(optarg, NULL, 10);
> - if (buf_size <= 0 || buf_size > 16*1024) {
> - fprintf(stderr,
> - "Invalid buffer size (%lu)\n",
> - buf_size);
> - exit(EXIT_FAILURE);
> - }
> - buf_size <<= 10;
> - break;
> - case 'n':
> - buf_nr = strtoul(optarg, NULL, 10);
> - if (buf_nr <= 0) {
> - fprintf(stderr,
> - "Invalid buffer nr (%lu)\n", buf_nr);
> - exit(EXIT_FAILURE);
> - }
> - break;
> - case 'D':
> - output_dir = optarg;
> - break;
> - default:
> - show_usage(argv[0]);
> - }
> - }
> -
> - if (optind < argc || output_name == NULL)
> - show_usage(argv[0]);
> -}
> -
> -int main(int argc, char *argv[])
> -{
> - struct statfs st;
> -
> - parse_args(argc, argv);
> -
> - if (!debugfs_path)
> - debugfs_path = default_debugfs_path;
> -
> - if (statfs(debugfs_path, &st) < 0) {
> - perror("statfs");
> - fprintf(stderr, "%s does not appear to be a valid path\n",
> - debugfs_path);
> - return 1;
> - } else if (st.f_type != (long) DEBUGFS_TYPE) {
> - fprintf(stderr, "%s does not appear to be a debug filesystem,"
> - " please mount debugfs.\n",
> - debugfs_path);
> - return 1;
> - }
> -
> - page_size = getpagesize();
> -
> - ncpus = sysconf(_SC_NPROCESSORS_ONLN);
> - if (ncpus < 0) {
> - fprintf(stderr, "sysconf(_SC_NPROCESSORS_ONLN) failed\n");
> - return 1;
> - }
> -
> - signal(SIGINT, handle_sigint);
> - signal(SIGHUP, handle_sigint);
> - signal(SIGTERM, handle_sigint);
> - signal(SIGALRM, handle_sigint);
> - signal(SIGPIPE, SIG_IGN);
> -
> - if (start_kvm_trace() != 0)
> - return 1;
> -
> - if (stop_watch)
> - alarm(stop_watch);
> -
> - wait_for_threads();
> - stop_all_traces();
> - show_stats();
> -
> - return 0;
> -}
> diff --git a/kvmtrace_format b/kvmtrace_format
> deleted file mode 100755
> index 6556475f726c4..0000000000000
> --- a/kvmtrace_format
> +++ /dev/null
> @@ -1,532 +0,0 @@
> -#!/usr/bin/env python
> -
> -# by Mark Williamson, (C) 2004 Intel Research Cambridge
> -
> -# Program for reformatting trace buffer output according to user-supplied rules
> -
> -import re, sys, string, signal, struct, os, getopt, operator
> -
> -PREFIX = '/usr'
> -DATADIR = os.path.join(PREFIX, 'share')
> -KVMDIR = os.path.join(DATADIR, 'kvm')
> -FORMATS_FILE = os.path.join(KVMDIR, 'formats')
> -
> -def usage():
> - print >> sys.stderr, \
> - "Usage: " + sys.argv[0] + """ defs-file
> - Parses trace data in binary format, as output by kvmtrace and
> - reformats it according to the rules in a file of definitions. The
> - rules in this file should have the format ({ and } show grouping
> - and are not part of the syntax):
> -
> - {event_id}{whitespace}{text format string}
> -
> - The textual format string may include format specifiers, such as:
> - %(ts)d, %(event)d, %(pid)d %(vcpu)d %(1)d, %(2)d,
> - %(3)d, %(4)d, %(5)d
> - [ the 'd' format specifier outputs in decimal, alternatively 'x'
> - will output in hexadecimal and 'o' will output in octal ]
> -
> - Which correspond to the event ID, timestamp counter, pid
> - , vcpu and the 5 data fields from the trace record. There should be
> - one such rule for each type of event.
> - Depending on your system and the volume of trace buffer data,
> - this script may not be able to keep up with the output of kvmtrace
> - if it is piped directly. In these circumstances you should have
> - kvmtrace output to a file for processing off-line.
> -
> - kvmtrace_format has the following additional switches
> - -s - if this switch is set additional trace statistics are
> - created and printed at the end of the output
> - """
> - sys.exit(1)
> -
> -def read_defs(defs_file):
> - defs = {}
> -
> - fd = open(defs_file)
> -
> - reg = re.compile('(\S+)\s+(\S.*)')
> -
> - while True:
> - line = fd.readline()
> - if not line:
> - break
> -
> - if line[0] == '#' or line[0] == '\n':
> - continue
> -
> - m = reg.match(line)
> -
> - if not m: print >> sys.stderr, "Bad format file" ; sys.exit(1)
> -
> - defs[str(eval(m.group(1)))] = m.group(2)
> -
> - return defs
> -
> -def sighand(x,y):
> - global interrupted
> - interrupted = 1
> -
> -# ppc instruction decoding for event type 0x00020019 (PPC_INSTR)
> -# some globals for statistic summaries
> -stat_ppc_instr_mnemonic = {};
> -stat_ppc_instr_spr = {};
> -stat_ppc_instr_dcr = {};
> -stat_ppc_instr_tlb = {};
> -
> -def ppc_instr_print_summary(sortedlist, colname):
> - print "\n\n%14s + %10s" % (colname, "count")
> - print "%s" % (15*"-"+"+"+11*"-")
> - sum = 0
> - for value, key in sortedlist:
> - sum += key
> - print "%14s | %10d" % (value, key)
> - print "%14s = %10d" % ("sum", sum)
> -
> -
> -def ppc_instr_summary():
> - # don't print empty statistics
> - if stat_ppc_instr_mnemonic:
> - ppc_instr_print_summary(sorted(stat_ppc_instr_mnemonic.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic")
> - if stat_ppc_instr_spr:
> - ppc_instr_print_summary(sorted(stat_ppc_instr_spr.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-spr")
> - if stat_ppc_instr_dcr:
> - ppc_instr_print_summary(sorted(stat_ppc_instr_dcr.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-dcr")
> - if stat_ppc_instr_tlb:
> - ppc_instr_print_summary(sorted(stat_ppc_instr_tlb.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-tlb")
> -
> -def get_op(instr):
> - return (instr >> 26);
> -
> -def get_xop(instr):
> - return (instr >> 1) & 0x3ff;
> -
> -def get_sprn(instr):
> - return ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0)
> -
> -def get_dcrn(instr):
> - return ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
> -
> -def get_tlbwe_type(instr):
> - ws = (instr >> 11) & 0x1f;
> - if ws == 0:
> - return "PAGEID"
> - elif ws == 1:
> - return "XLAT"
> - elif ws == 2:
> - return "ATTRIB"
> - else:
> - return "UNKNOWN"
> -
> -def get_name(instr):
> - if get_op(instr)==3:
> - return "trap"
> - elif get_op(instr)==19:
> - if get_xop(instr) == 50:
> - return "rfi"
> - else:
> - return "unknown"
> - elif get_op(instr)==31:
> - if get_xop(instr) == 83:
> - return "mfmsr"
> -
> - elif get_xop(instr) == 87:
> - return "lbzx"
> -
> - elif get_xop(instr) == 131:
> - return "wrtee"
> -
> - elif get_xop(instr) == 146:
> - return "mtmsr"
> -
> - elif get_xop(instr) == 163:
> - return "wrteei"
> -
> - elif get_xop(instr) == 215:
> - return "stbx"
> -
> - elif get_xop(instr) == 247:
> - return "stbux"
> -
> - elif get_xop(instr) == 279:
> - return "lhzx"
> -
> - elif get_xop(instr) == 311:
> - return "lhzux"
> -
> - elif get_xop(instr) == 323:
> - return "mfdcr"
> -
> - elif get_xop(instr) == 339:
> - return "mfspr"
> -
> - elif get_xop(instr) == 407:
> - return "sthx"
> -
> - elif get_xop(instr) == 439:
> - return "sthux"
> -
> - elif get_xop(instr) == 451:
> - return "mtdcr"
> -
> - elif get_xop(instr) == 467:
> - return "mtspr"
> -
> - elif get_xop(instr) == 470:
> - return "dcbi"
> -
> - elif get_xop(instr) == 534:
> - return "lwbrx"
> -
> - elif get_xop(instr) == 566:
> - return "tlbsync"
> -
> - elif get_xop(instr) == 662:
> - return "stwbrx"
> -
> - elif get_xop(instr) == 978:
> - return "tlbwe"
> -
> - elif get_xop(instr) == 914:
> - return "tlbsx"
> -
> - elif get_xop(instr) == 790:
> - return "lhbrx"
> -
> - elif get_xop(instr) == 918:
> - return "sthbrx"
> -
> - elif get_xop(instr) == 966:
> - return "iccci"
> -
> - else:
> - return "unknown"
> -
> - elif get_op(instr) == 32:
> - return "lwz"
> -
> - elif get_op(instr) == 33:
> - return "lwzu"
> -
> - elif get_op(instr) == 34:
> - return "lbz"
> -
> - elif get_op(instr) == 35:
> - return "lbzu"
> -
> - elif get_op(instr) == 36:
> - return "stw"
> -
> - elif get_op(instr) == 37:
> - return "stwu"
> -
> - elif get_op(instr) == 38:
> - return "stb"
> -
> - elif get_op(instr) == 39:
> - return "stbu"
> -
> - elif get_op(instr) == 40:
> - return "lhz"
> -
> - elif get_op(instr) == 41:
> - return "lhzu"
> -
> - elif get_op(instr) == 44:
> - return "sth"
> -
> - elif get_op(instr) == 45:
> - return "sthu"
> -
> - else:
> - return "unknown"
> -
> -def get_sprn_name(sprn):
> - if sprn == 0x01a:
> - return "SRR0"
> - elif sprn == 0x01b:
> - return "SRR1"
> - elif sprn == 0x3b2:
> - return "MMUCR"
> - elif sprn == 0x030:
> - return "PID"
> - elif sprn == 0x03f:
> - return "IVPR"
> - elif sprn == 0x3b3:
> - return "CCR0"
> - elif sprn == 0x378:
> - return "CCR1"
> - elif sprn == 0x11f:
> - return "PVR"
> - elif sprn == 0x03d:
> - return "DEAR"
> - elif sprn == 0x03e:
> - return "ESR"
> - elif sprn == 0x134:
> - return "DBCR0"
> - elif sprn == 0x135:
> - return "DBCR1"
> - elif sprn == 0x11c:
> - return "TBWL"
> - elif sprn == 0x11d:
> - return "TBWU"
> - elif sprn == 0x016:
> - return "DEC"
> - elif sprn == 0x150:
> - return "TSR"
> - elif sprn == 0x154:
> - return "TCR"
> - elif sprn == 0x110:
> - return "SPRG0"
> - elif sprn == 0x111:
> - return "SPRG1"
> - elif sprn == 0x112:
> - return "SPRG2"
> - elif sprn == 0x113:
> - return "SPRG3"
> - elif sprn == 0x114:
> - return "SPRG4"
> - elif sprn == 0x115:
> - return "SPRG5"
> - elif sprn == 0x116:
> - return "SPRG6"
> - elif sprn == 0x117:
> - return "SPRG7"
> - elif sprn == 0x190:
> - return "IVOR0"
> - elif sprn == 0x191:
> - return "IVOR1"
> - elif sprn == 0x192:
> - return "IVOR2"
> - elif sprn == 0x193:
> - return "IVOR3"
> - elif sprn == 0x194:
> - return "IVOR4"
> - elif sprn == 0x195:
> - return "IVOR5"
> - elif sprn == 0x196:
> - return "IVOR6"
> - elif sprn == 0x197:
> - return "IVOR7"
> - elif sprn == 0x198:
> - return "IVOR8"
> - elif sprn == 0x199:
> - return "IVOR9"
> - elif sprn == 0x19a:
> - return "IVOR10"
> - elif sprn == 0x19b:
> - return "IVOR11"
> - elif sprn == 0x19c:
> - return "IVOR12"
> - elif sprn == 0x19d:
> - return "IVOR13"
> - elif sprn == 0x19e:
> - return "IVOR14"
> - elif sprn == 0x19f:
> - return "IVOR15"
> - else:
> - return "UNKNOWN"
> -
> -def get_special(instr):
> - name = get_name(instr);
> - if stat_ppc_instr_mnemonic.has_key(name):
> - stat_ppc_instr_mnemonic[name] += 1
> - else:
> - stat_ppc_instr_mnemonic[name] = 1
> -
> - if get_op(instr) == 31:
> - if (get_xop(instr) == 339) or (get_xop(instr) == 467):
> - sprn = get_sprn(instr);
> - sprn_name = get_sprn_name(sprn);
> - stat_idx = name+"-"+sprn_name
> - if stat_ppc_instr_spr.has_key(stat_idx):
> - stat_ppc_instr_spr[stat_idx] += 1
> - else:
> - stat_ppc_instr_spr[stat_idx] = 1
> - return ("- sprn 0x%03x %8s" % (sprn, sprn_name))
> - elif (get_xop(instr) == 323 ) or (get_xop(instr) == 451):
> - dcrn = get_dcrn(instr);
> - stat_idx = name+"-"+("%04X"%dcrn)
> - if stat_ppc_instr_dcr.has_key(stat_idx):
> - stat_ppc_instr_dcr[stat_idx] += 1
> - else:
> - stat_ppc_instr_dcr[stat_idx] = 1
> - return ("- dcrn 0x%03x" % dcrn)
> - elif (get_xop(instr) == 978 ) or (get_xop(instr) == 451):
> - tlbwe_type = get_tlbwe_type(instr)
> - stat_idx = name+"-"+tlbwe_type
> - if stat_ppc_instr_tlb.has_key(stat_idx):
> - stat_ppc_instr_tlb[stat_idx] += 1
> - else:
> - stat_ppc_instr_tlb[stat_idx] = 1
> - return ("- ws -> %8s" % tlbwe_type)
> - return ""
> -
> -##### Main code
> -
> -summary = False
> -
> -try:
> - opts, arg = getopt.getopt(sys.argv[1:], "sc:" )
> - for opt in opts:
> - if opt[0] == '-s' : summary = True
> -
> -except getopt.GetoptError:
> - usage()
> -
> -signal.signal(signal.SIGTERM, sighand)
> -signal.signal(signal.SIGHUP, sighand)
> -signal.signal(signal.SIGINT, sighand)
> -
> -interrupted = 0
> -
> -if len(arg) > 0:
> - defs = read_defs(arg[0])
> -else:
> - defs = read_defs(FORMATS_FILE)
> -
> -# structure of trace record (as output by kvmtrace):
> -# HDR(I) {TSC(Q)} D1(I) D2(I) D3(I) D4(I) D5(I)
> -#
> -# HDR consists of EVENT:28:, n_data:3:, ts_in:1:
> -# pid:32, vcpu_id:32
> -# EVENT means Event ID
> -# n_data means number of data (like D1, D2, ...)
> -# ts_in means Timestamp data exists(1) or not(0).
> -# if ts_in == 0, TSC(Q) does not exists.
> -#
> -HDRREC = "<III"
> -TSCREC = "<Q"
> -D1REC = "<I"
> -D2REC = "<II"
> -D3REC = "<III"
> -D4REC = "<IIII"
> -D5REC = "<IIIII"
> -KMAGIC = "<I"
> -
> -last_ts = 0
> -
> -i=0
> -
> -while not interrupted:
> - try:
> - i=i+1
> -
> - if i == 1:
> - line = sys.stdin.read(struct.calcsize(KMAGIC))
> - if not line:
> - break
> - kmgc = struct.unpack(KMAGIC, line)[0]
> -
> - #firstly try to parse data file as little endian
> - # if "kvmtrace-metadata".kmagic != kmagic
> - # then data file must be big endian"
> - if kmgc != 0x12345678:
> - if kmgc != 0x78563412:
> - print >> sys.stderr, "Bad data file: magic number error."
> - break;
> - else:
> - HDRREC = ">III"
> - TSCREC = ">Q"
> - D1REC = ">I"
> - D2REC = ">II"
> - D3REC = ">III"
> - D4REC = ">IIII"
> - D5REC = ">IIIII"
> - continue
> -
> - line = sys.stdin.read(struct.calcsize(HDRREC))
> - if not line:
> - break
> - (event, pid, vcpu_id) = struct.unpack(HDRREC, line)
> -
> - n_data = event >> 28 & 0x7
> - ts_in = event >> 31
> -
> - d1 = 0
> - d2 = 0
> - d3 = 0
> - d4 = 0
> - d5 = 0
> -
> - ts = 0
> -
> - if ts_in == 1:
> - line = sys.stdin.read(struct.calcsize(TSCREC))
> - if not line:
> - break
> - ts = struct.unpack(TSCREC, line)[0]
> - if n_data == 1:
> - line = sys.stdin.read(struct.calcsize(D1REC))
> - if not line:
> - break
> - d1 = struct.unpack(D1REC, line)[0]
> - if n_data == 2:
> - line = sys.stdin.read(struct.calcsize(D2REC))
> - if not line:
> - break
> - (d1, d2) = struct.unpack(D2REC, line)
> - if n_data == 3:
> - line = sys.stdin.read(struct.calcsize(D3REC))
> - if not line:
> - break
> - (d1, d2, d3) = struct.unpack(D3REC, line)
> - if n_data == 4:
> - line = sys.stdin.read(struct.calcsize(D4REC))
> - if not line:
> - break
> - (d1, d2, d3, d4) = struct.unpack(D4REC, line)
> - if n_data == 5:
> - line = sys.stdin.read(struct.calcsize(D5REC))
> - if not line:
> - break
> - (d1, d2, d3, d4, d5) = struct.unpack(D5REC, line)
> -
> - event &= 0x0fffffff
> -
> - # provide relative TSC
> -
> - if last_ts > 0 and ts_in == 1:
> - relts = ts - last_ts
> - else:
> - relts = 0
> -
> - if ts_in == 1:
> - last_ts = ts
> -
> - args = {'ts' : ts,
> - 'event' : event,
> - 'relts': relts,
> - 'pid' : pid,
> - 'vcpu' : vcpu_id,
> - '1' : d1,
> - '2' : d2,
> - '3' : d3,
> - '4' : d4,
> - '5' : d5 }
> -
> - # some event types need more than just formats mapping they are if/elif
> - # chained here and the last default else is the mapping via formats
> - if event == 0x00020019:
> - pdata = (ts, relts, vcpu_id, pid, d1, d2, d3, get_name(d1), get_special(d1))
> - print "%d (+%12d) PPC_INSTR vcpu = 0x%08x pid = 0x%08x [ instr = 0x%08x, pc = 0x%08x, emul = %01d, mnemonic = %8s %s" % pdata
> - else:
> - try:
> - if defs.has_key(str(event)):
> - print defs[str(event)] % args
> - else:
> - if defs.has_key(str(0)): print defs[str(0)] % args
> - except TypeError:
> - if defs.has_key(str(event)):
> - print defs[str(event)]
> - print args
> - else:
> - if defs.has_key(str(0)):
> - print defs[str(0)]
> - print args
> -
> - except IOError, struct.error: sys.exit()
> -
> -if summary:
> - ppc_instr_summary()
> diff --git a/lib/fwcfg.c b/lib/fwcfg.c
> deleted file mode 100644
> index dc34d299df766..0000000000000
> --- a/lib/fwcfg.c
> +++ /dev/null
> @@ -1,58 +0,0 @@
> -
> -void qemu_cfg_select(int f)
> -{
> - outw(QEMU_CFG_CTL_PORT, f);
> -}
> -
> -int qemu_cfg_port_probe()
> -{
> - char *sig = "QEMU";
> - int i;
> -
> - qemu_cfg_select(QEMU_CFG_SIGNATURE);
> -
> - for (i = 0; i < 4; i++)
> - if (inb(QEMU_CFG_DATA_PORT) != sig[i])
> - return 0;
> -
> - return 1;
> -}
> -
> -void qemu_cfg_read(uint8_t *buf, int len)
> -{
> - while (len--)
> - *(buf++) = inb(QEMU_CFG_DATA_PORT);
> -}
> -
> -uint8_t qemu_cfg_get8(void)
> -{
> - uint8_t ret;
> -
> - qemu_cfg_read(&ret, 1);
> - return ret;
> -}
> -
> -uint16_t qemu_cfg_get16(void)
> -{
> - uint16_t ret;
> -
> - qemu_cfg_read((uint8_t*)&ret, 2);
> - return le16_to_cpu(ret);
> -}
> -
> -uint64_t qemu_cfg_get32(void)
> -{
> - uint32_t ret;
> -
> - qemu_cfg_read((uint8_t*)&ret, 4);
> - return le32_to_cpu(ret);
> -}
> -
> -uint64_t qemu_cfg_get64(void)
> -{
> - uint64_t ret;
> -
> - qemu_cfg_read((uint8_t*)&ret, 8);
> - return le64_to_cpu(ret);
> -}
> -
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index fadc33d30f85b..140c172e77d54 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -38,7 +38,6 @@ typedef _Bool bool;
> #define false 0
>
> extern void exit(int code);
> -extern void panic(char *fmt, ...);
>
> extern unsigned long strlen(const char *buf);
> extern char *strcat(char *dest, const char *src);
> diff --git a/lib/panic.c b/lib/panic.c
> deleted file mode 100644
> index 6e0b29ebed503..0000000000000
> --- a/lib/panic.c
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -#include "libcflat.h"
> -
> -void panic(char *fmt, ...)
> -{
> - va_list va;
> - char buf[2000];
> -
> - va_start(va, fmt);
> - vsnprintf(buf, sizeof(buf), fmt, va);
> - va_end(va);
> - puts(buf);
> - exit(-1);
> -}
> diff --git a/lib/powerpc/44x/map.c b/lib/powerpc/44x/map.c
> deleted file mode 100644
> index 113434d2f1b4d..0000000000000
> --- a/lib/powerpc/44x/map.c
> +++ /dev/null
> @@ -1,51 +0,0 @@
> -/*
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License, version 2, as
> - * published by the Free Software Foundation.
> - *
> - * 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, write to the Free Software
> - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> - *
> - * Copyright IBM Corp. 2008
> - *
> - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
> - */
> -
> -#include "libcflat.h"
> -
> -#define TLB_SIZE 64
> -
> -extern void tlbwe(unsigned int index,
> - unsigned char tid,
> - unsigned int word0,
> - unsigned int word1,
> - unsigned int word2);
> -
> -unsigned int next_free_index;
> -
> -#define PAGE_SHIFT 12
> -#define PAGE_MASK (~((1<<PAGE_SHIFT)-1))
> -
> -#define V (1<<9)
> -
> -void map(unsigned long vaddr, unsigned long paddr)
> -{
> - unsigned int w0, w1, w2;
> -
> - /* We don't install exception handlers, so we can't handle TLB misses,
> - * so we can't loop around and overwrite entry 0. */
> - if (next_free_index++ >= TLB_SIZE)
> - panic("TLB overflow");
> -
> - w0 = (vaddr & PAGE_MASK) | V;
> - w1 = paddr & PAGE_MASK;
> - w2 = 0x3;
> -
> - tlbwe(next_free_index, 0, w0, w1, w2);
> -}
> diff --git a/lib/powerpc/44x/timebase.S b/lib/powerpc/44x/timebase.S
> deleted file mode 100644
> index 385904da3c161..0000000000000
> --- a/lib/powerpc/44x/timebase.S
> +++ /dev/null
> @@ -1,28 +0,0 @@
> -/*
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License, version 2, as
> - * published by the Free Software Foundation.
> - *
> - * 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, write to the Free Software
> - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> - *
> - * Copyright IBM Corp. 2008
> - *
> - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
> - */
> -
> -/* unsigned long long mftb(void); */
> -.global mftb
> -mftb:
> - mftbu r5
> - mftbl r4
> - mftbu r3
> - cmpw r3, r5
> - bne mftb
> - blr
> diff --git a/lib/powerpc/44x/timebase.h b/lib/powerpc/44x/timebase.h
> deleted file mode 100644
> index ce85347bd17c5..0000000000000
> --- a/lib/powerpc/44x/timebase.h
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -/*
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License, version 2, as
> - * published by the Free Software Foundation.
> - *
> - * 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, write to the Free Software
> - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> - *
> - * Copyright IBM Corp. 2008
> - *
> - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
> - */
> -
> -#ifndef __TIMEBASE_H__
> -#define __TIMEBASE_H__
> -
> -unsigned long long mftb(void);
> -
> -#endif /* __TIMEBASE_H__ */
> diff --git a/lib/powerpc/44x/tlbwe.S b/lib/powerpc/44x/tlbwe.S
> deleted file mode 100644
> index 3790374eb5c61..0000000000000
> --- a/lib/powerpc/44x/tlbwe.S
> +++ /dev/null
> @@ -1,29 +0,0 @@
> -/*
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License, version 2, as
> - * published by the Free Software Foundation.
> - *
> - * 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, write to the Free Software
> - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> - *
> - * Copyright IBM Corp. 2008
> - *
> - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
> - */
> -
> -#define SPRN_MMUCR 0x3b2
> -
> -/* tlbwe(uint index, uint8_t tid, uint word0, uint word1, uint word2) */
> -.global tlbwe
> -tlbwe:
> - mtspr SPRN_MMUCR, r4
> - tlbwe r5, r3, 0
> - tlbwe r6, r3, 1
> - tlbwe r7, r3, 2
> - blr
> diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c
> deleted file mode 100644
> index 8bd239521f25f..0000000000000
> --- a/lib/powerpc/io.c
> +++ /dev/null
> @@ -1,35 +0,0 @@
> -/*
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License, version 2, as
> - * published by the Free Software Foundation.
> - *
> - * 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, write to the Free Software
> - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> - *
> - * Copyright IBM Corp. 2008
> - *
> - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
> - */
> -
> -#include "libcflat.h"
> -
> -#define BASE 0xf0000000
> -#define _putc ((volatile char *)(BASE))
> -#define _exit ((volatile char *)(BASE+1))
> -
> -void puts(const char *s)
> -{
> - while (*s != '\0')
> - *_putc = *s++;
> -}
> -
> -void exit(int code)
> -{
> - *_exit = code;
> -}
> diff --git a/main-ppc.c b/main-ppc.c
> deleted file mode 100644
> index 5af59f846ef07..0000000000000
> --- a/main-ppc.c
> +++ /dev/null
> @@ -1,383 +0,0 @@
> -/*
> - * Kernel-based Virtual Machine test driver
> - *
> - * This test driver provides a simple way of testing kvm, without a full
> - * device model.
> - *
> - * Copyright (C) 2006 Qumranet
> - * Copyright IBM Corp. 2008
> - *
> - * Authors:
> - *
> - * Avi Kivity <avi@qumranet.com>
> - * Yaniv Kamay <yaniv@qumranet.com>
> - * Hollis Blanchard <hollisb@us.ibm.com>
> - *
> - * This work is licensed under the GNU LGPL license, version 2.
> - */
> -
> -#define _GNU_SOURCE
> -
> -#include <libkvm.h>
> -
> -#include <stdio.h>
> -#include <unistd.h>
> -#include <fcntl.h>
> -#include <stdlib.h>
> -#include <string.h>
> -#include <semaphore.h>
> -#include <sys/types.h>
> -#include <errno.h>
> -#include <pthread.h>
> -#include <signal.h>
> -#include <pthread.h>
> -#include <sys/syscall.h>
> -#include <linux/unistd.h>
> -#include <getopt.h>
> -#include <stdbool.h>
> -#include <inttypes.h>
> -
> -#include "iotable.h"
> -
> -static int gettid(void)
> -{
> - return syscall(__NR_gettid);
> -}
> -
> -kvm_context_t kvm;
> -
> -#define IPI_SIGNAL (SIGRTMIN + 4)
> -
> -struct io_table mmio_table;
> -
> -static int ncpus = 1;
> -static sem_t exited_sem;
> -static __thread int vcpu;
> -static sigset_t kernel_sigmask;
> -static sigset_t ipi_sigmask;
> -static uint64_t memory_size = 128 * 1024 * 1024;
> -
> -struct vcpu_info {
> - pid_t tid;
> -};
> -
> -struct vcpu_info *vcpus;
> -
> -/* Must match flat.lds linker script */
> -#define VM_TEST_LOAD_ADDRESS 0x100000
> -
> -static int test_debug(void *opaque, void *vcpu)
> -{
> - printf("test_debug\n");
> - return 0;
> -}
> -
> -static int test_halt(void *opaque, int vcpu)
> -{
> - int n;
> -
> - sigwait(&ipi_sigmask, &n);
> - return 0;
> -}
> -
> -static int test_io_window(void *opaque)
> -{
> - return 0;
> -}
> -
> -static int test_try_push_interrupts(void *opaque)
> -{
> - return 0;
> -}
> -
> -static void test_post_kvm_run(void *opaque, void *vcpu)
> -{
> -}
> -
> -static int test_pre_kvm_run(void *opaque, void *vcpu)
> -{
> - return 0;
> -}
> -
> -static int mmio_handler(void *opaque, int len, int is_write, uint64_t offset,
> - uint64_t *data)
> -{
> - int r = 0;
> -
> - switch (offset) {
> - case 0: /* putc */
> - putc(*(char *)data, stdout);
> - fflush(stdout);
> - break;
> - case 1: /* exit */
> - r = *(char *)data;
> - break;
> - default:
> - printf("%s: offset %"PRIx64" len %d data %"PRIx64"\n",
> - __func__, offset, len, *(uint64_t *)data);
> - r = -EINVAL;
> - }
> -
> - return r;
> -}
> -
> -static int test_mem_read(void *opaque, uint64_t addr, uint8_t *data, int len)
> -{
> - struct io_table_entry *iodev;
> -
> -#if 0
> - printf("%s: addr %"PRIx64" len %d\n", __func__, addr, len);
> -#endif
> -
> - iodev = io_table_lookup(&mmio_table, addr);
> - if (!iodev) {
> - printf("couldn't find device\n");
> - return -ENODEV;
> - }
> -
> - return iodev->handler(iodev->opaque, len, 0, addr - iodev->start,
> - (uint64_t *)data);
> -}
> -
> -static int test_mem_write(void *opaque, uint64_t addr, uint8_t *data, int len)
> -{
> - struct io_table_entry *iodev;
> -
> -#if 0
> - printf("%s: addr %"PRIx64" len %d data %"PRIx64"\n",
> - __func__, addr, len, *(uint64_t *)data);
> -#endif
> -
> - iodev = io_table_lookup(&mmio_table, addr);
> - if (!iodev) {
> - printf("couldn't find device\n");
> - return -ENODEV;
> - }
> -
> - return iodev->handler(iodev->opaque, len, 1, addr - iodev->start,
> - (uint64_t *)data);
> -}
> -
> -static int test_dcr_read(int vcpu, uint32_t dcrn, uint32_t *data)
> -{
> - printf("%s: dcrn %04X\n", __func__, dcrn);
> - *data = 0;
> - return 0;
> -}
> -
> -static int test_dcr_write(int vcpu, uint32_t dcrn, uint32_t data)
> -{
> - printf("%s: dcrn %04X data %04X\n", __func__, dcrn, data);
> - return 0;
> -}
> -
> -static struct kvm_callbacks test_callbacks = {
> - .mmio_read = test_mem_read,
> - .mmio_write = test_mem_write,
> - .debug = test_debug,
> - .halt = test_halt,
> - .io_window = test_io_window,
> - .try_push_interrupts = test_try_push_interrupts,
> - .post_kvm_run = test_post_kvm_run,
> - .pre_kvm_run = test_pre_kvm_run,
> - .powerpc_dcr_read = test_dcr_read,
> - .powerpc_dcr_write = test_dcr_write,
> -};
> -
> -static unsigned long load_file(void *mem, const char *fname, int inval_icache)
> -{
> - ssize_t r;
> - int fd;
> - unsigned long bytes = 0;
> -
> - fd = open(fname, O_RDONLY);
> - if (fd == -1) {
> - perror("open");
> - exit(1);
> - }
> -
> - while ((r = read(fd, mem, 4096)) != -1 && r != 0) {
> - mem += r;
> - bytes += r;
> - }
> -
> - if (r == -1) {
> - perror("read");
> - printf("read %d bytes\n", bytes);
> - exit(1);
> - }
> -
> - return bytes;
> -}
> -
> -#define ICACHE_LINE_SIZE 32
> -
> -void sync_caches(void *mem, unsigned long len)
> -{
> - unsigned long i;
> -
> - for (i = 0; i < len; i += ICACHE_LINE_SIZE)
> - asm volatile ("dcbst %0, %1" : : "g"(mem), "r"(i));
> - asm volatile ("sync");
> - for (i = 0; i < len; i += ICACHE_LINE_SIZE)
> - asm volatile ("icbi %0, %1" : : "g"(mem), "r"(i));
> - asm volatile ("sync; isync");
> -}
> -
> -static void init_vcpu(int n)
> -{
> - sigemptyset(&ipi_sigmask);
> - sigaddset(&ipi_sigmask, IPI_SIGNAL);
> - sigprocmask(SIG_UNBLOCK, &ipi_sigmask, NULL);
> - sigprocmask(SIG_BLOCK, &ipi_sigmask, &kernel_sigmask);
> - vcpus[n].tid = gettid();
> - vcpu = n;
> - kvm_set_signal_mask(kvm, n, &kernel_sigmask);
> -}
> -
> -static void *do_create_vcpu(void *_n)
> -{
> - struct kvm_regs regs;
> - int n = (long)_n;
> -
> - kvm_create_vcpu(kvm, n);
> - init_vcpu(n);
> -
> - kvm_get_regs(kvm, n, ®s);
> - regs.pc = VM_TEST_LOAD_ADDRESS;
> - kvm_set_regs(kvm, n, ®s);
> -
> - kvm_run(kvm, n, &vcpus[n]);
> - sem_post(&exited_sem);
> - return NULL;
> -}
> -
> -static void start_vcpu(int n)
> -{
> - pthread_t thread;
> -
> - pthread_create(&thread, NULL, do_create_vcpu, (void *)(long)n);
> -}
> -
> -static void usage(const char *progname)
> -{
> - fprintf(stderr,
> -"Usage: %s [OPTIONS] [bootstrap] flatfile\n"
> -"KVM test harness.\n"
> -"\n"
> -" -s, --smp=NUM create a VM with NUM virtual CPUs\n"
> -" -m, --memory=NUM[GMKB] allocate NUM memory for virtual machine. A suffix\n"
> -" can be used to change the unit (default: `M')\n"
> -" -h, --help display this help screen and exit\n"
> -"\n"
> -"Report bugs to <kvm-ppc@vger.kernel.org>.\n"
> - , progname);
> -}
> -
> -static void sig_ignore(int sig)
> -{
> - write(1, "boo\n", 4);
> -}
> -
> -int main(int argc, char **argv)
> -{
> - void *vm_mem;
> - unsigned long len;
> - int i;
> - const char *sopts = "s:phm:";
> - struct option lopts[] = {
> - { "smp", 1, 0, 's' },
> - { "memory", 1, 0, 'm' },
> - { "help", 0, 0, 'h' },
> - { 0 },
> - };
> - int opt_ind, ch;
> - int nb_args;
> - char *endptr;
> -
> - while ((ch = getopt_long(argc, argv, sopts, lopts, &opt_ind)) != -1) {
> - switch (ch) {
> - case 's':
> - ncpus = atoi(optarg);
> - break;
> - case 'm':
> - memory_size = strtoull(optarg, &endptr, 0);
> - switch (*endptr) {
> - case 'G': case 'g':
> - memory_size <<= 30;
> - break;
> - case '\0':
> - case 'M': case 'm':
> - memory_size <<= 20;
> - break;
> - case 'K': case 'k':
> - memory_size <<= 10;
> - break;
> - default:
> - fprintf(stderr,
> - "Unrecongized memory suffix: %c\n",
> - *endptr);
> - exit(1);
> - }
> - if (memory_size == 0) {
> - fprintf(stderr,
> - "Invalid memory size: 0\n");
> - exit(1);
> - }
> - break;
> - case 'h':
> - usage(argv[0]);
> - exit(0);
> - case '?':
> - default:
> - fprintf(stderr,
> - "Try `%s --help' for more information.\n",
> - argv[0]);
> - exit(1);
> - }
> - }
> -
> - nb_args = argc - optind;
> - if (nb_args < 1 || nb_args > 2) {
> - fprintf(stderr,
> - "Incorrect number of arguments.\n"
> - "Try `%s --help' for more information.\n",
> - argv[0]);
> - exit(1);
> - }
> -
> - signal(IPI_SIGNAL, sig_ignore);
> -
> - vcpus = calloc(ncpus, sizeof *vcpus);
> - if (!vcpus) {
> - fprintf(stderr, "calloc failed\n");
> - return 1;
> - }
> -
> - kvm = kvm_init(&test_callbacks, 0);
> - if (!kvm) {
> - fprintf(stderr, "kvm_init failed\n");
> - return 1;
> - }
> - if (kvm_create(kvm, memory_size, &vm_mem) < 0) {
> - kvm_finalize(kvm);
> - fprintf(stderr, "kvm_create failed\n");
> - return 1;
> - }
> -
> - vm_mem = kvm_create_phys_mem(kvm, 0, memory_size, 0, 1);
> -
> - len = load_file(vm_mem + VM_TEST_LOAD_ADDRESS, argv[optind], 1);
> - sync_caches(vm_mem + VM_TEST_LOAD_ADDRESS, len);
> -
> - io_table_register(&mmio_table, 0xf0000000, 64, mmio_handler, NULL);
> -
> - sem_init(&exited_sem, 0, 0);
> - for (i = 0; i < ncpus; ++i)
> - start_vcpu(i);
> - /* Wait for all vcpus to exit. */
> - for (i = 0; i < ncpus; ++i)
> - sem_wait(&exited_sem);
> -
> - return 0;
> -}
> diff --git a/powerpc/44x/tlbsx.S b/powerpc/44x/tlbsx.S
> deleted file mode 100644
> index b15874b18b74c..0000000000000
> --- a/powerpc/44x/tlbsx.S
> +++ /dev/null
> @@ -1,33 +0,0 @@
> -#define SPRN_MMUCR 0x3b2
> -
> -#define TLBWORD0 0x10000210
> -#define TLBWORD1 0x10000000
> -#define TLBWORD2 0x00000003
> -
> -.global _start
> -_start:
> - li r4, 0
> - mtspr SPRN_MMUCR, r4
> -
> - li r3, 23
> -
> - lis r4, TLBWORD0@h
> - ori r4, r4, TLBWORD0@l
> - tlbwe r4, r3, 0
> -
> - lis r4, TLBWORD1@h
> - ori r4, r4, TLBWORD1@l
> - tlbwe r4, r3, 1
> -
> - lis r4, TLBWORD2@h
> - ori r4, r4, TLBWORD2@l
> - tlbwe r4, r3, 2
> -
> - lis r4, 0x1000
> - tlbsx r5, r4, r0
> - cmpwi r5, 23
> - beq good
> - trap
> -
> -good:
> - b .
> diff --git a/powerpc/44x/tlbwe.S b/powerpc/44x/tlbwe.S
> deleted file mode 100644
> index ec6ef5c57fc47..0000000000000
> --- a/powerpc/44x/tlbwe.S
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -#define SPRN_MMUCR 0x3b2
> -
> -/* Create a mapping at 4MB */
> -#define TLBWORD0 0x00400210
> -#define TLBWORD1 0x00400000
> -#define TLBWORD2 0x00000003
> -
> -.global _start
> -_start:
> - li r4, 0
> - mtspr SPRN_MMUCR, r4
> -
> - li r3, 23
> -
> - lis r4, TLBWORD0@h
> - ori r4, r4, TLBWORD0@l
> - tlbwe r4, r3, 0
> -
> - lis r4, TLBWORD1@h
> - ori r4, r4, TLBWORD1@l
> - tlbwe r4, r3, 1
> -
> - lis r4, TLBWORD2@h
> - ori r4, r4, TLBWORD2@l
> - tlbwe r4, r3, 2
> -
> - b .
> diff --git a/powerpc/44x/tlbwe_16KB.S b/powerpc/44x/tlbwe_16KB.S
> deleted file mode 100644
> index 1bd10bf17a187..0000000000000
> --- a/powerpc/44x/tlbwe_16KB.S
> +++ /dev/null
> @@ -1,35 +0,0 @@
> -#define SPRN_MMUCR 0x3b2
> -
> -/* 16KB mapping at 4MB */
> -#define TLBWORD0 0x00400220
> -#define TLBWORD1 0x00400000
> -#define TLBWORD2 0x00000003
> -
> -.global _start
> -_start:
> - li r4, 0
> - mtspr SPRN_MMUCR, r4
> -
> - li r3, 5
> -
> - lis r4, TLBWORD0@h
> - ori r4, r4, TLBWORD0@l
> - tlbwe r4, r3, 0
> -
> - lis r4, TLBWORD1@h
> - ori r4, r4, TLBWORD1@l
> - tlbwe r4, r3, 1
> -
> - lis r4, TLBWORD2@h
> - ori r4, r4, TLBWORD2@l
> - tlbwe r4, r3, 2
> -
> - /* load from 4MB */
> - lis r3, 0x0040
> - lwz r4, 0(r3)
> -
> - /* load from 4MB+8KB */
> - ori r3, r3, 0x2000
> - lwz r4, 0(r3)
> -
> - b .
> diff --git a/powerpc/44x/tlbwe_hole.S b/powerpc/44x/tlbwe_hole.S
> deleted file mode 100644
> index 5efd30357daa9..0000000000000
> --- a/powerpc/44x/tlbwe_hole.S
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -#define SPRN_MMUCR 0x3b2
> -
> -/* Try to map real address 1GB. */
> -#define TLBWORD0 0x40000210
> -#define TLBWORD1 0x40000000
> -#define TLBWORD2 0x00000003
> -
> -.global _start
> -_start:
> - li r4, 0
> - mtspr SPRN_MMUCR, r4
> -
> - li r3, 23
> -
> - lis r4, TLBWORD0@h
> - ori r4, r4, TLBWORD0@l
> - tlbwe r4, r3, 0
> -
> - lis r4, TLBWORD1@h
> - ori r4, r4, TLBWORD1@l
> - tlbwe r4, r3, 1
> -
> - lis r4, TLBWORD2@h
> - ori r4, r4, TLBWORD2@l
> - tlbwe r4, r3, 2
> -
> - b .
> diff --git a/powerpc/cstart.S b/powerpc/cstart.S
> deleted file mode 100644
> index 70a0e9fcd47c9..0000000000000
> --- a/powerpc/cstart.S
> +++ /dev/null
> @@ -1,38 +0,0 @@
> -/*
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License, version 2, as
> - * published by the Free Software Foundation;
> - *
> - * 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, write to the Free Software
> - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> - *
> - * Copyright IBM Corp. 2008
> - *
> - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
> - */
> -
> -#define OUTPUT_VADDR 0xf0000000
> -#define OUTPUT_PADDR 0xf0000000
> -
> -.globl _start
> -_start:
> - /* In the future we might need to assign a stack and zero BSS here. */
> -
> - /* Map the debug page 1:1. */
> - lis r3, OUTPUT_VADDR@h
> - ori r3, r3, OUTPUT_VADDR@l
> - lis r4, OUTPUT_PADDR@h
> - ori r4, r4, OUTPUT_PADDR@l
> - bl map
> -
> - /* Call main() and pass return code to exit(). */
> - bl main
> - bl exit
> -
> - b .
> diff --git a/powerpc/exit.c b/powerpc/exit.c
> deleted file mode 100644
> index 804ee04d9f88e..0000000000000
> --- a/powerpc/exit.c
> +++ /dev/null
> @@ -1,23 +0,0 @@
> -/*
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License, version 2, as
> - * published by the Free Software Foundation;
> - *
> - * 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, write to the Free Software
> - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> - *
> - * Copyright IBM Corp. 2008
> - *
> - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
> - */
> -
> -int main(void)
> -{
> - return 1;
> -}
> diff --git a/powerpc/helloworld.c b/powerpc/helloworld.c
> deleted file mode 100644
> index f8630f7c5381f..0000000000000
> --- a/powerpc/helloworld.c
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/*
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License, version 2, as
> - * published by the Free Software Foundation;
> - *
> - * 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, write to the Free Software
> - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> - *
> - * Copyright IBM Corp. 2008
> - *
> - * Authors: Deepa Srinivasan <deepas@us.ibm.com>
> - */
> -
> -#include "libcflat.h"
> -
> -int main()
> -{
> - printf("Hello World\n");
> -
> - return 1;
> -}
> diff --git a/powerpc/io.S b/powerpc/io.S
> deleted file mode 100644
> index 97567cb6c73f2..0000000000000
> --- a/powerpc/io.S
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -#define SPRN_MMUCR 0x3b2
> -
> -#define TLBWORD0 0xf0000210
> -#define TLBWORD1 0xf0000000
> -#define TLBWORD2 0x00000003
> -
> -.global _start
> -_start:
> - li r4, 0
> - mtspr SPRN_MMUCR, r4
> -
> - li r3, 2
> -
> - lis r4, TLBWORD0@h
> - ori r4, r4, TLBWORD0@l
> - tlbwe r4, r3, 0
> -
> - lis r4, TLBWORD1@h
> - ori r4, r4, TLBWORD1@l
> - tlbwe r4, r3, 1
> -
> - lis r4, TLBWORD2@h
> - ori r4, r4, TLBWORD2@l
> - tlbwe r4, r3, 2
> -
> - lis r3, 0xf000
> - lis r4, 0x1234
> - ori r4, r4, 0x5678
> - stb r4, 0(r3)
> - lbz r5, 0(r3)
> -
> - b .
> diff --git a/powerpc/spin.S b/powerpc/spin.S
> deleted file mode 100644
> index 4406641c2711c..0000000000000
> --- a/powerpc/spin.S
> +++ /dev/null
> @@ -1,4 +0,0 @@
> -
> -.global _start
> -_start:
> - b .
> diff --git a/powerpc/sprg.S b/powerpc/sprg.S
> deleted file mode 100644
> index d0414a480342a..0000000000000
> --- a/powerpc/sprg.S
> +++ /dev/null
> @@ -1,7 +0,0 @@
> -
> -.global _start
> -_start:
> - li r3, 42
> - mtsprg 0, r3
> - mfsprg r4, 0
> - b .
> diff --git a/x86/print.h b/x86/print.h
> deleted file mode 100644
> index d5bd2f9978dc4..0000000000000
> --- a/x86/print.h
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -#ifndef PRINT_H
> -#define PRINT_H
> -
> -.macro PRINT text
> -
> -.data
> -
> -333: .asciz "\text\n"
> -
> -.previous
> -
> - push %rdi
> - lea 333b, %rdi
> - call print
> - pop %rdi
> -
> -.endm
> -
> -#endif
> diff --git a/x86/run-kvm-unit-tests b/x86/run-kvm-unit-tests
> deleted file mode 100644
> index fed925a3d70fe..0000000000000
> --- a/x86/run-kvm-unit-tests
> +++ /dev/null
> @@ -1,6 +0,0 @@
> -#!/usr/bin/python
> -
> -import sys, os, os.path
> -
> -prog = sys.argv[0]
> -dir = os.path.dirname(prog)
> --
> 1.8.1.4
--
Gleb.
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 1/9] remove unused files
2013-10-16 12:52 ` Gleb Natapov
@ 2013-10-16 13:13 ` Alexander Graf
2013-10-16 13:18 ` Andrew Jones
1 sibling, 0 replies; 38+ messages in thread
From: Alexander Graf @ 2013-10-16 13:13 UTC (permalink / raw)
To: Gleb Natapov; +Cc: Andrew Jones, kvm, kvmarm, christoffer.dall, kvm-ppc
On 10/16/2013 02:52 PM, Gleb Natapov wrote:
> Copying Alex in case he has an opinion about removing powerpc.
I would prefer to see it fixed and actually get unit tests, but the code
that's there is trivial enough to not really make an impact on that. So
no real complaints from my side.
Alex
>
> On Mon, Oct 14, 2013 at 06:23:27PM +0200, Andrew Jones wrote:
>> There are several unused files, primarily because powerpc is an unused
>> arch. The exceptions are config-ia64.mak, which is also an unused arch
>> file, lib/fwcfg.c, lib/panic.c, x86/print.h and x86/run-kvm-unit-tests,
>> which are just unused. Remove them all in order to tidy things up.
>>
>> Signed-off-by: Andrew Jones <drjones@redhat.com>
>> ---
>> Makefile | 8 +-
>> config-ia64.mak | 7 -
>> config-powerpc-440.mak | 15 -
>> config-powerpc.mak | 39 ---
>> formats | 31 --
>> iotable.c | 53 ----
>> iotable.h | 40 ---
>> kvmtrace.c | 706 ---------------------------------------------
>> kvmtrace_format | 532 ----------------------------------
>> lib/fwcfg.c | 58 ----
>> lib/libcflat.h | 1 -
>> lib/panic.c | 13 -
>> lib/powerpc/44x/map.c | 51 ----
>> lib/powerpc/44x/timebase.S | 28 --
>> lib/powerpc/44x/timebase.h | 25 --
>> lib/powerpc/44x/tlbwe.S | 29 --
>> lib/powerpc/io.c | 35 ---
>> main-ppc.c | 383 ------------------------
>> powerpc/44x/tlbsx.S | 33 ---
>> powerpc/44x/tlbwe.S | 27 --
>> powerpc/44x/tlbwe_16KB.S | 35 ---
>> powerpc/44x/tlbwe_hole.S | 27 --
>> powerpc/cstart.S | 38 ---
>> powerpc/exit.c | 23 --
>> powerpc/helloworld.c | 27 --
>> powerpc/io.S | 32 --
>> powerpc/spin.S | 4 -
>> powerpc/sprg.S | 7 -
>> x86/print.h | 19 --
>> x86/run-kvm-unit-tests | 6 -
>> 30 files changed, 1 insertion(+), 2331 deletions(-)
>> delete mode 100644 config-ia64.mak
>> delete mode 100644 config-powerpc-440.mak
>> delete mode 100644 config-powerpc.mak
>> delete mode 100644 formats
>> delete mode 100644 iotable.c
>> delete mode 100644 iotable.h
>> delete mode 100644 kvmtrace.c
>> delete mode 100755 kvmtrace_format
>> delete mode 100644 lib/fwcfg.c
>> delete mode 100644 lib/panic.c
>> delete mode 100644 lib/powerpc/44x/map.c
>> delete mode 100644 lib/powerpc/44x/timebase.S
>> delete mode 100644 lib/powerpc/44x/timebase.h
>> delete mode 100644 lib/powerpc/44x/tlbwe.S
>> delete mode 100644 lib/powerpc/io.c
>> delete mode 100644 main-ppc.c
>> delete mode 100644 powerpc/44x/tlbsx.S
>> delete mode 100644 powerpc/44x/tlbwe.S
>> delete mode 100644 powerpc/44x/tlbwe_16KB.S
>> delete mode 100644 powerpc/44x/tlbwe_hole.S
>> delete mode 100644 powerpc/cstart.S
>> delete mode 100644 powerpc/exit.c
>> delete mode 100644 powerpc/helloworld.c
>> delete mode 100644 powerpc/io.S
>> delete mode 100644 powerpc/spin.S
>> delete mode 100644 powerpc/sprg.S
>> delete mode 100644 x86/print.h
>> delete mode 100644 x86/run-kvm-unit-tests
>>
[...]
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 1/9] remove unused files
2013-10-16 12:52 ` Gleb Natapov
2013-10-16 13:13 ` Alexander Graf
@ 2013-10-16 13:18 ` Andrew Jones
1 sibling, 0 replies; 38+ messages in thread
From: Andrew Jones @ 2013-10-16 13:18 UTC (permalink / raw)
To: Gleb Natapov; +Cc: kvm, kvmarm, christoffer.dall, Alexander Graf
On Wed, Oct 16, 2013 at 03:52:43PM +0300, Gleb Natapov wrote:
> Copying Alex in case he has an opinion about removing powerpc.
>
We had discussed it earlier[1], and I got the go-ahead to toss
out the current code.
drew
[1] http://comments.gmane.org/gmane.comp.emulators.kvm.powerpc.devel/7747
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 3/9] clean root dir of all x86-ness
2013-10-14 16:23 ` [PATCH 3/9] clean root dir of all x86-ness Andrew Jones
@ 2013-10-17 1:06 ` Christoffer Dall
2013-10-17 9:35 ` Andrew Jones
0 siblings, 1 reply; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 1:06 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Mon, Oct 14, 2013 at 06:23:29PM +0200, Andrew Jones wrote:
> Remove all references to x86 from the root dir (except from in
> configure). Also remove references from the root dir README
> by moving that documentation to the x86/README, and touch up
> the READMEs at the same time.
Just giving this a cursory pass...
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> Makefile | 7 ++-
> README | 55 +++++++++-----------
> config-i386.mak | 13 -----
> config-x86-common.mak | 120 -------------------------------------------
> config-x86_64.mak | 14 -----
> config/config-i386.mak | 12 +++++
> config/config-x86-common.mak | 120 +++++++++++++++++++++++++++++++++++++++++++
> config/config-x86_64.mak | 13 +++++
> configure | 17 ++++++
> docs/testdev.txt | 11 ++++
> flat.lds | 21 --------
> run_tests.sh | 19 ++++---
> testdev.txt | 14 -----
> x86-run | 41 ---------------
> x86/README | 60 +++++++++++++++++-----
> x86/flat.lds | 21 ++++++++
> x86/run | 41 +++++++++++++++
> 17 files changed, 316 insertions(+), 283 deletions(-)
> delete mode 100644 config-i386.mak
> delete mode 100644 config-x86-common.mak
> delete mode 100644 config-x86_64.mak
> create mode 100644 config/config-i386.mak
> create mode 100644 config/config-x86-common.mak
> create mode 100644 config/config-x86_64.mak
> create mode 100644 docs/testdev.txt
> delete mode 100644 flat.lds
> delete mode 100644 testdev.txt
> delete mode 100755 x86-run
> create mode 100644 x86/flat.lds
> create mode 100755 x86/run
>
> diff --git a/Makefile b/Makefile
> index 697fc2a766966..7a5ec8e6348bf 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -17,7 +17,7 @@ cflatobjs := \
> lib/string.o
>
> #include architecure specific make rules
> -include config-$(ARCH).mak
> +include config/config-$(ARCH).mak
>
> # cc-option
> # Usage: OP_CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
> @@ -29,7 +29,6 @@ CFLAGS += $(autodepend-flags) -Wall
> CFLAGS += $(call cc-option, -fomit-frame-pointer, "")
> CFLAGS += $(call cc-option, -fno-stack-protector, "")
> CFLAGS += $(call cc-option, -fno-stack-protector-all, "")
> -CFLAGS += -I.
>
> CXXFLAGS += $(CFLAGS)
>
> @@ -44,11 +43,11 @@ $(libcflat): $(cflatobjs)
> %.o: %.S
> $(CC) $(CFLAGS) -c -nostdlib -o $@ $<
>
> --include .*.d */.*.d */*/.*.d
> +-include */.*.d */*/.*.d
>
> install:
> mkdir -p $(DESTDIR)
> install $(tests_and_config) $(DESTDIR)
>
> clean: arch_clean
> - $(RM) *.o *.a .*.d lib/.*.d $(libcflat) $(cflatobjs)
> + $(RM) lib/.*.d $(libcflat) $(cflatobjs)
> diff --git a/README b/README
> index db525e3bbb79d..49468b94bc7fc 100644
> --- a/README
> +++ b/README
> @@ -1,36 +1,27 @@
> This directory contains sources for a kvm test suite.
>
> -Tests for x86 architecture are run as kernel images for qemu that supports multiboot format.
> -Tests uses an infrastructure called from the bios code. The infrastructure initialize the system/cpu's,
> -switch to long-mode and calls the 'main' function of the individual test.
> -Tests uses a qemu's virtual test device, named testdev, for services like printing, exiting, query memory size etc.
> -See file testdev.txt for more details.
> -
> -To create the tests' images just type 'make' in this directory.
> -Tests' images created in ./<ARCH>/*.flat
> -
> -An example of a test invocation:
> -Using qemu-kvm:
> -
> -qemu-kvm -device testdev,chardev=testlog -chardev file,id=testlog,path=msr.out -serial stdio -kernel ./x86/msr.flat
> -This invocation runs the msr test case. The test outputs to stdio.
> -
> -Using qemu (supported since qemu 1.3):
> -qemu-system-x86_64 -enable-kvm -device pc-testdev -serial stdio -device isa-debug-exit,iobase=0xf4,iosize=0x4 -kernel ./x86/msr.flat
> -
> -Or use a runner script to detect the correct invocation:
> -./x86-run ./x86/msr.flat
> -To select a specific qemu binary, specify the QEMU=<path> environment:
> -QEMU=/tmp/qemu/x86_64-softmmu/qemu-system-x86_64 ./x86-run ./x86/msr.flat
> -
> -The exit status of the binary (and the script) is inconsistent: with
> -qemu-system, after the unittest is done, the exit status of qemu is 1,
> -different from the 'old style' qemu-kvm, whose exit status in successful
> -completion is 0.
> +To create the tests' images do
tests' images doesn't read very nice, can we just say test images?
> + ./configure
> + make
> +in this directory. Tests' images are created in ./<ARCH>/*.flat
> +
> +Then use the runner script to detect the correct invocation and
> +invoke the test, e.g.
> + ./x86-run ./x86/msr.flat
> +or
> + ./run_tests.sh
> +to run them all.
While you're at it, it would be great to provide a little more context
in the README file.
For example, we start talking abouter 'runner scripts', we refer to
something called '.flat', and we refer to QEMU without explaining how
this whole thing works, what the components are, what is required of
QEMU etc.
I think that would be useful for the wider adoption of kvm-unit-tests to
developers writing ad-hoc patches for KVM.
A reference to docs/testdev.txt from somewhere approrpriate in such text
would probably also be useful...
I know much of this is arch-specific, but there must be something
generic or common across the architecture, and that would in essense be
capturing what 'kvm-unit-tests' give you, which I think is very useful
to have in the readme.
> +
> +To select a specific qemu binary, specify the QEMU=<path>
> +environment, e.g.
> + QEMU=/tmp/qemu/x86_64-softmmu/qemu-system-x86_64 ./x86-run ./x86/msr.flat
>
> Directory structure:
> -.: Makefile and config files for the tests
> -./lib: general services for the tests
> -./lib/<ARCH>: architecture dependent services for the tests
> -./<ARCH>: the sources of the tests and the created objects/images
> -
> +.: Makefile and config files for the tests
> +./config: config files for the tests
> +./docs: documentation files
> +./lib: general services for the tests
> +./lib/<ARCH>: architecture dependent services for the tests
> +./<ARCH>: the sources of the tests and the created objects/images
> +
> +See <ARCH>/README for arch specific documentation.
> diff --git a/config-i386.mak b/config-i386.mak
> deleted file mode 100644
> index de52f3d53cff8..0000000000000
> --- a/config-i386.mak
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -TEST_DIR=x86
> -cstart.o = $(TEST_DIR)/cstart.o
> -bits = 32
> -ldarch = elf32-i386
> -CFLAGS += -D__i386__
> -CFLAGS += -I $(KERNELDIR)/include
> -
> -tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat
> -
> -include config-x86-common.mak
> -
> -$(TEST_DIR)/taskswitch.elf: $(cstart.o) $(TEST_DIR)/taskswitch.o
> -$(TEST_DIR)/taskswitch2.elf: $(cstart.o) $(TEST_DIR)/taskswitch2.o
> diff --git a/config-x86-common.mak b/config-x86-common.mak
> deleted file mode 100644
> index 7e481192a0737..0000000000000
> --- a/config-x86-common.mak
> +++ /dev/null
> @@ -1,120 +0,0 @@
> -#This is a make file with common rules for both x86 & x86-64
> -
> -all: test_cases
> -
> -cflatobjs += lib/x86/io.o
> -cflatobjs += lib/x86/smp.o
> -cflatobjs += lib/x86/vm.o
> -cflatobjs += lib/x86/fwcfg.o
> -cflatobjs += lib/x86/apic.o
> -cflatobjs += lib/x86/atomic.o
> -cflatobjs += lib/x86/desc.o
> -cflatobjs += lib/x86/isr.o
> -cflatobjs += lib/x86/pci.o
> -
> -$(libcflat): LDFLAGS += -nostdlib
> -$(libcflat): CFLAGS += -ffreestanding -I lib
> -
> -CFLAGS += -m$(bits)
> -CFLAGS += -O1
> -
> -libgcc := $(shell $(CC) -m$(bits) --print-libgcc-file-name)
> -
> -FLATLIBS = lib/libcflat.a $(libgcc)
> -%.elf: %.o $(FLATLIBS) flat.lds
> - $(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-T,flat.lds \
> - $(filter %.o, $^) $(FLATLIBS)
> -
> -%.flat: %.elf
> - $(OBJCOPY) -O elf32-i386 $^ $@
> -
> -tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
> - $(TEST_DIR)/smptest.flat $(TEST_DIR)/port80.flat \
> - $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat \
> - $(TEST_DIR)/hypercall.flat $(TEST_DIR)/sieve.flat \
> - $(TEST_DIR)/kvmclock_test.flat $(TEST_DIR)/eventinj.flat \
> - $(TEST_DIR)/s3.flat $(TEST_DIR)/pmu.flat \
> - $(TEST_DIR)/tsc_adjust.flat $(TEST_DIR)/asyncpf.flat \
> - $(TEST_DIR)/init.flat
> -
> -ifdef API
> -tests-common += api/api-sample
> -tests-common += api/dirty-log
> -tests-common += api/dirty-log-perf
> -endif
> -
> -tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
> -
> -test_cases: $(tests-common) $(tests)
> -
> -$(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I lib -I lib/x86
> -
> -$(TEST_DIR)/access.elf: $(cstart.o) $(TEST_DIR)/access.o
> -
> -$(TEST_DIR)/hypercall.elf: $(cstart.o) $(TEST_DIR)/hypercall.o
> -
> -$(TEST_DIR)/sieve.elf: $(cstart.o) $(TEST_DIR)/sieve.o
> -
> -$(TEST_DIR)/vmexit.elf: $(cstart.o) $(TEST_DIR)/vmexit.o
> -
> -$(TEST_DIR)/smptest.elf: $(cstart.o) $(TEST_DIR)/smptest.o
> -
> -$(TEST_DIR)/emulator.elf: $(cstart.o) $(TEST_DIR)/emulator.o
> -
> -$(TEST_DIR)/port80.elf: $(cstart.o) $(TEST_DIR)/port80.o
> -
> -$(TEST_DIR)/tsc.elf: $(cstart.o) $(TEST_DIR)/tsc.o
> -
> -$(TEST_DIR)/tsc_adjust.elf: $(cstart.o) $(TEST_DIR)/tsc_adjust.o
> -
> -$(TEST_DIR)/apic.elf: $(cstart.o) $(TEST_DIR)/apic.o
> -
> -$(TEST_DIR)/init.elf: $(cstart.o) $(TEST_DIR)/init.o
> -
> -$(TEST_DIR)/realmode.elf: $(TEST_DIR)/realmode.o
> - $(CC) -m32 -nostdlib -o $@ -Wl,-T,$(TEST_DIR)/realmode.lds $^
> -
> -$(TEST_DIR)/realmode.o: bits = 32
> -
> -$(TEST_DIR)/msr.elf: $(cstart.o) $(TEST_DIR)/msr.o
> -
> -$(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt_test.o
> -
> -$(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/xsave.o
> -
> -$(TEST_DIR)/rmap_chain.elf: $(cstart.o) $(TEST_DIR)/rmap_chain.o
> -
> -$(TEST_DIR)/svm.elf: $(cstart.o)
> -
> -$(TEST_DIR)/kvmclock_test.elf: $(cstart.o) $(TEST_DIR)/kvmclock.o \
> - $(TEST_DIR)/kvmclock_test.o
> -
> -$(TEST_DIR)/eventinj.elf: $(cstart.o) $(TEST_DIR)/eventinj.o
> -
> -$(TEST_DIR)/s3.elf: $(cstart.o) $(TEST_DIR)/s3.o
> -
> -$(TEST_DIR)/pmu.elf: $(cstart.o) $(TEST_DIR)/pmu.o
> -
> -$(TEST_DIR)/asyncpf.elf: $(cstart.o) $(TEST_DIR)/asyncpf.o
> -
> -$(TEST_DIR)/pcid.elf: $(cstart.o) $(TEST_DIR)/pcid.o
> -
> -$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o $(TEST_DIR)/vmx_tests.o
> -
> -arch_clean:
> - $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
> - $(TEST_DIR)/.*.d lib/x86/.*.d
> -
> -api/%.o: CFLAGS += -m32
> -
> -api/%: LDLIBS += -lstdc++ -lboost_thread-mt -lpthread -lrt
> -api/%: LDFLAGS += -m32
> -
> -api/libapi.a: api/kvmxx.o api/identity.o api/exception.o api/memmap.o
> - $(AR) rcs $@ $^
> -
> -api/api-sample: api/api-sample.o api/libapi.a
> -
> -api/dirty-log: api/dirty-log.o api/libapi.a
> -
> -api/dirty-log-perf: api/dirty-log-perf.o api/libapi.a
> diff --git a/config-x86_64.mak b/config-x86_64.mak
> deleted file mode 100644
> index bb8ee89713abd..0000000000000
> --- a/config-x86_64.mak
> +++ /dev/null
> @@ -1,14 +0,0 @@
> -TEST_DIR=x86
> -cstart.o = $(TEST_DIR)/cstart64.o
> -bits = 64
> -ldarch = elf64-x86-64
> -CFLAGS += -D__x86_64__
> -
> -tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \
> - $(TEST_DIR)/emulator.flat $(TEST_DIR)/idt_test.flat \
> - $(TEST_DIR)/xsave.flat $(TEST_DIR)/rmap_chain.flat \
> - $(TEST_DIR)/pcid.flat
> -tests += $(TEST_DIR)/svm.flat
> -tests += $(TEST_DIR)/vmx.flat
> -
> -include config-x86-common.mak
> diff --git a/config/config-i386.mak b/config/config-i386.mak
> new file mode 100644
> index 0000000000000..82fed0f5a48b0
> --- /dev/null
> +++ b/config/config-i386.mak
> @@ -0,0 +1,12 @@
> +cstart.o = $(TEST_DIR)/cstart.o
> +bits = 32
> +ldarch = elf32-i386
> +CFLAGS += -D__i386__
> +CFLAGS += -I $(KERNELDIR)/include
> +
> +tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat
> +
> +include config/config-x86-common.mak
> +
> +$(TEST_DIR)/taskswitch.elf: $(cstart.o) $(TEST_DIR)/taskswitch.o
> +$(TEST_DIR)/taskswitch2.elf: $(cstart.o) $(TEST_DIR)/taskswitch2.o
> diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
> new file mode 100644
> index 0000000000000..917cbbf801a65
> --- /dev/null
> +++ b/config/config-x86-common.mak
> @@ -0,0 +1,120 @@
> +#This is a make file with common rules for both x86 & x86-64
> +
> +all: test_cases
> +
> +cflatobjs += lib/x86/io.o
> +cflatobjs += lib/x86/smp.o
> +cflatobjs += lib/x86/vm.o
> +cflatobjs += lib/x86/fwcfg.o
> +cflatobjs += lib/x86/apic.o
> +cflatobjs += lib/x86/atomic.o
> +cflatobjs += lib/x86/desc.o
> +cflatobjs += lib/x86/isr.o
> +cflatobjs += lib/x86/pci.o
> +
> +$(libcflat): LDFLAGS += -nostdlib
> +$(libcflat): CFLAGS += -ffreestanding -I lib
> +
> +CFLAGS += -m$(bits)
> +CFLAGS += -O1
> +
> +libgcc := $(shell $(CC) -m$(bits) --print-libgcc-file-name)
> +
> +FLATLIBS = lib/libcflat.a $(libgcc)
> +%.elf: %.o $(FLATLIBS) x86/flat.lds
> + $(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-T,x86/flat.lds \
> + $(filter %.o, $^) $(FLATLIBS)
> +
> +%.flat: %.elf
> + $(OBJCOPY) -O elf32-i386 $^ $@
> +
> +tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
> + $(TEST_DIR)/smptest.flat $(TEST_DIR)/port80.flat \
> + $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat \
> + $(TEST_DIR)/hypercall.flat $(TEST_DIR)/sieve.flat \
> + $(TEST_DIR)/kvmclock_test.flat $(TEST_DIR)/eventinj.flat \
> + $(TEST_DIR)/s3.flat $(TEST_DIR)/pmu.flat \
> + $(TEST_DIR)/tsc_adjust.flat $(TEST_DIR)/asyncpf.flat \
> + $(TEST_DIR)/init.flat
> +
> +ifdef API
> +tests-common += api/api-sample
> +tests-common += api/dirty-log
> +tests-common += api/dirty-log-perf
> +endif
> +
> +tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
> +
> +test_cases: $(tests-common) $(tests)
> +
> +$(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I lib -I lib/x86
> +
> +$(TEST_DIR)/access.elf: $(cstart.o) $(TEST_DIR)/access.o
> +
> +$(TEST_DIR)/hypercall.elf: $(cstart.o) $(TEST_DIR)/hypercall.o
> +
> +$(TEST_DIR)/sieve.elf: $(cstart.o) $(TEST_DIR)/sieve.o
> +
> +$(TEST_DIR)/vmexit.elf: $(cstart.o) $(TEST_DIR)/vmexit.o
> +
> +$(TEST_DIR)/smptest.elf: $(cstart.o) $(TEST_DIR)/smptest.o
> +
> +$(TEST_DIR)/emulator.elf: $(cstart.o) $(TEST_DIR)/emulator.o
> +
> +$(TEST_DIR)/port80.elf: $(cstart.o) $(TEST_DIR)/port80.o
> +
> +$(TEST_DIR)/tsc.elf: $(cstart.o) $(TEST_DIR)/tsc.o
> +
> +$(TEST_DIR)/tsc_adjust.elf: $(cstart.o) $(TEST_DIR)/tsc_adjust.o
> +
> +$(TEST_DIR)/apic.elf: $(cstart.o) $(TEST_DIR)/apic.o
> +
> +$(TEST_DIR)/init.elf: $(cstart.o) $(TEST_DIR)/init.o
> +
> +$(TEST_DIR)/realmode.elf: $(TEST_DIR)/realmode.o
> + $(CC) -m32 -nostdlib -o $@ -Wl,-T,$(TEST_DIR)/realmode.lds $^
> +
> +$(TEST_DIR)/realmode.o: bits = 32
> +
> +$(TEST_DIR)/msr.elf: $(cstart.o) $(TEST_DIR)/msr.o
> +
> +$(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt_test.o
> +
> +$(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/xsave.o
> +
> +$(TEST_DIR)/rmap_chain.elf: $(cstart.o) $(TEST_DIR)/rmap_chain.o
> +
> +$(TEST_DIR)/svm.elf: $(cstart.o)
> +
> +$(TEST_DIR)/kvmclock_test.elf: $(cstart.o) $(TEST_DIR)/kvmclock.o \
> + $(TEST_DIR)/kvmclock_test.o
> +
> +$(TEST_DIR)/eventinj.elf: $(cstart.o) $(TEST_DIR)/eventinj.o
> +
> +$(TEST_DIR)/s3.elf: $(cstart.o) $(TEST_DIR)/s3.o
> +
> +$(TEST_DIR)/pmu.elf: $(cstart.o) $(TEST_DIR)/pmu.o
> +
> +$(TEST_DIR)/asyncpf.elf: $(cstart.o) $(TEST_DIR)/asyncpf.o
> +
> +$(TEST_DIR)/pcid.elf: $(cstart.o) $(TEST_DIR)/pcid.o
> +
> +$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o $(TEST_DIR)/vmx_tests.o
> +
> +arch_clean:
> + $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
> + $(TEST_DIR)/.*.d lib/x86/.*.d
> +
> +api/%.o: CFLAGS += -m32
> +
> +api/%: LDLIBS += -lstdc++ -lboost_thread-mt -lpthread -lrt
> +api/%: LDFLAGS += -m32
> +
> +api/libapi.a: api/kvmxx.o api/identity.o api/exception.o api/memmap.o
> + $(AR) rcs $@ $^
> +
> +api/api-sample: api/api-sample.o api/libapi.a
> +
> +api/dirty-log: api/dirty-log.o api/libapi.a
> +
> +api/dirty-log-perf: api/dirty-log-perf.o api/libapi.a
> diff --git a/config/config-x86_64.mak b/config/config-x86_64.mak
> new file mode 100644
> index 0000000000000..f089b05a178c3
> --- /dev/null
> +++ b/config/config-x86_64.mak
> @@ -0,0 +1,13 @@
> +cstart.o = $(TEST_DIR)/cstart64.o
> +bits = 64
> +ldarch = elf64-x86-64
> +CFLAGS += -D__x86_64__
> +
> +tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \
> + $(TEST_DIR)/emulator.flat $(TEST_DIR)/idt_test.flat \
> + $(TEST_DIR)/xsave.flat $(TEST_DIR)/rmap_chain.flat \
> + $(TEST_DIR)/pcid.flat
> +tests += $(TEST_DIR)/svm.flat
> +tests += $(TEST_DIR)/vmx.flat
> +
> +include config/config-x86-common.mak
> diff --git a/configure b/configure
> index d0c62e24dd1d2..6cfc64943f6e6 100755
> --- a/configure
> +++ b/configure
> @@ -15,6 +15,7 @@ usage() {
> Usage: $0 [options]
>
> Options include:
> + --test-dir=DIR the main directory for tests ($arch)
> --arch=ARCH architecture to compile for ($arch)
> --cross-prefix=PREFIX cross compiler prefix
> --cc=CC c compiler to use ($cc)
> @@ -33,6 +34,9 @@ while [[ "$1" = -* ]]; do
> opt="${opt%%=*}"
> fi
> case "$opt" in
> + --test-dir)
> + testdir="$arg"
> + ;;
> --prefix)
> prefix="$arg"
> ;;
> @@ -62,6 +66,18 @@ while [[ "$1" = -* ]]; do
> ;;
> esac
> done
> +if [ -z "$testdir" -a \( "$arch" = "i386" -o "$arch" = "x86_64" \) ]; then
> + testdir=x86
> +elif [ -z "$testdir" ]; then
> + testdir=$arch
> +fi
> +if [ ! -d $testdir ]; then
> + echo "$testdir does not exist!"
> + exit 1
> +fi
> +if [ -f $testdir/run ]; then
> + ln -fs $testdir/run $testdir-run
> +fi
>
> # check for dependent 32 bit libraries
> cat << EOF > lib_test.c
> @@ -89,4 +105,5 @@ LD=$cross_prefix$ld
> OBJCOPY=$cross_prefix$objcopy
> AR=$cross_prefix$ar
> API=$api
> +TEST_DIR=$testdir
> EOF
> diff --git a/docs/testdev.txt b/docs/testdev.txt
> new file mode 100644
> index 0000000000000..854b5c774b60c
> --- /dev/null
> +++ b/docs/testdev.txt
> @@ -0,0 +1,11 @@
> +This file describes the virtual device of qemu for supporting this test suite.
> +
> +Services supplied by the testdev device:
> +
> +serial output: write only, on io port 0xf1
> +exit process: write only, on io port 0xf4, value used as exit code
> +ram size: read-only, on io port 0xd1, 4 bytes' size
> +irq line setting: write only, on io ports 0x2000 - 0x2018, value to set/clear
> +simple io: read/write, on io port 0xe0, 1/2/4 bytes
> +
> +Test device used a char device for actual output
> diff --git a/flat.lds b/flat.lds
> deleted file mode 100644
> index a278b56c9a4e3..0000000000000
> --- a/flat.lds
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -SECTIONS
> -{
> - . = 4M + SIZEOF_HEADERS;
> - stext = .;
> - .text : { *(.init) *(.text) *(.text.*) }
> - . = ALIGN(4K);
> - .data : {
> - *(.data)
> - exception_table_start = .;
> - *(.data.ex)
> - exception_table_end = .;
> - }
> - . = ALIGN(16);
> - .rodata : { *(.rodata) }
> - . = ALIGN(16);
> - .bss : { *(.bss) }
> - . = ALIGN(4K);
> - edata = .;
> -}
> -
> -ENTRY(start)
> diff --git a/run_tests.sh b/run_tests.sh
> index f373c533b75b2..400c62458ae18 100755
> --- a/run_tests.sh
> +++ b/run_tests.sh
> @@ -1,8 +1,10 @@
> #!/bin/bash
>
> -testroot=x86
> -config=$testroot/unittests.cfg
> -qemu=${qemu:-qemu-system-x86_64}
> +# As it happens, config.mak is valid shell script code, too :-)
> +source config.mak
> +
> +config=$TEST_DIR/unittests.cfg
> +qemu=${QEMU:-qemu-system-$ARCH}
> verbose=0
>
> function run()
> @@ -27,7 +29,7 @@ function run()
> return
> fi
>
> - cmdline="./x86-run $kernel -smp $smp $opts"
> + cmdline="./$TEST_DIR-run $kernel -smp $smp $opts"
> if [ $verbose != 0 ]; then
> echo $cmdline
> fi
> @@ -65,7 +67,7 @@ function run_all()
> groups=""
> arch=""
> elif [[ $line =~ ^file\ *=\ *(.*)$ ]]; then
> - kernel=$testroot/${BASH_REMATCH[1]}
> + kernel=$TEST_DIR/${BASH_REMATCH[1]}
> elif [[ $line =~ ^smp\ *=\ *(.*)$ ]]; then
> smp=${BASH_REMATCH[1]}
> elif [[ $line =~ ^extra_params\ *=\ *(.*)$ ]]; then
> @@ -92,15 +94,12 @@ Usage: $0 [-g group] [-h] [-v]
> -h: Output this help text
> -v: Enables verbose mode
>
> -Set the environment variable QEMU=/path/to/qemu-system-x86_64 to allow the
> -internally used x86-run to pick up the right qemu binary.
> +Set the environment variable QEMU=/path/to/qemu-system-ARCH to allow the
> +internally used ARCH-run to pick up the right qemu binary.
>
> EOF
> }
>
> -# As it happens, config.mak is valid shell script code, too :-)
> -source config.mak
> -
> echo > test.log
> while getopts "g:hv" opt; do
> case $opt in
> diff --git a/testdev.txt b/testdev.txt
> deleted file mode 100644
> index ac436efadb633..0000000000000
> --- a/testdev.txt
> +++ /dev/null
> @@ -1,14 +0,0 @@
> -This file describes the virtual device of qemu for supporting this test suite.
> -
> -Services supplied by the testdev device:
> -
> -serial output: write only, on io port 0xf1
> -exit process: write only, on io port 0xf4, value used as exit code
> -ram size: read-only, on io port 0xd1, 4 bytes' size
> -irq line setting: write only, on io ports 0x2000 - 0x2018, value to set/clear
> -simple io: read/write, on io port 0xe0, 1/2/4 bytes
> -
> -Test device used a char device for actual output
> -
> -
> -
> diff --git a/x86-run b/x86-run
> deleted file mode 100755
> index 646c5770ed03f..0000000000000
> --- a/x86-run
> +++ /dev/null
> @@ -1,41 +0,0 @@
> -#!/bin/bash
> -
> -qemukvm="${QEMU:-qemu-kvm}"
> -qemusystem="${QEMU:-qemu-system-x86_64}"
> -if
> - ${qemukvm} -device '?' 2>&1 | grep -F -e \"testdev\" -e \"pc-testdev\" > /dev/null;
> -then
> - qemu="${qemukvm}"
> -else
> - if
> - ${qemusystem} -device '?' 2>&1 | grep -F -e \"testdev\" -e \"pc-testdev\" > /dev/null;
> - then
> - qemu="${qemusystem}"
> - else
> - echo QEMU binary ${QEMU} has no support for test device. Exiting.
> - exit 2
> - fi
> -fi
> -
> -if
> - ${qemu} -device '?' 2>&1 | grep -F "pci-testdev" > /dev/null;
> -then
> - pci_testdev="-device pci-testdev"
> -else
> - pci_testdev=""
> -fi
> -
> -if
> - ${qemu} -device '?' 2>&1 | grep -F "pc-testdev" > /dev/null;
> -then
> - pc_testdev="-device pc-testdev -device isa-debug-exit,iobase=0xf4,iosize=0x4"
> -else
> - pc_testdev="-device testdev,chardev=testlog -chardev file,id=testlog,path=msr.out"
> -fi
> -
> -command="${qemu} -enable-kvm $pc_testdev -display none -serial stdio $pci_testdev -kernel"
> -echo ${command} "$@"
> -${command} "$@"
> -ret=$?
> -echo Return value from qemu: $ret
> -exit $ret
> diff --git a/x86/README b/x86/README
> index d644abdf31708..2f4baa46c6ed1 100644
> --- a/x86/README
> +++ b/x86/README
> @@ -1,16 +1,48 @@
> +
> +Tests for x86 architecture are run as kernel images for qemu that supports
> +multiboot format. Tests uses an infrastructure called from the bios code.
> +The infrastructure initialize the system/cpu's, switch to long-mode and calls
> +the 'main' function of the individual test. Tests uses a qemu's virtual test
> +device, named testdev, for services like printing, exiting, query memory
> +size etc. See file docs/testdev.txt for more details.
> +
> +An example of a test invocation:
> +Using qemu-kvm:
> +
> +qemu-kvm -device testdev,chardev=testlog \
> + -chardev file,id=testlog,path=msr.out \
> + -serial stdio -kernel ./x86/msr.flat
> +This invocation runs the msr test case. The test outputs to stdio.
> +
> +Using qemu (supported since qemu 1.3):
> +qemu-system-x86_64 -enable-kvm -device pc-testdev -serial stdio \
> + -device isa-debug-exit,iobase=0xf4,iosize=0x4 \
> + -kernel ./x86/msr.flat
> +
> Tests in this directory and what they do:
>
> -access: lots of page table related access (pte/pde) (read/write)
> -apic: enable x2apic, self ipi, ioapic intr, ioapic simultaneous
> -emulator: move to/from regs, cmps, push, pop, to/from cr8, smsw and lmsw
> -hypercall: intel and amd hypercall insn
> -msr: write to msr (only KERNEL_GS_BASE for now)
> -port80: lots of out to port 80
> -realmode: goes back to realmode, shld, push/pop, mov immediate, cmp immediate, add immediate,
> - io, eflags instructions (clc, cli, etc.), jcc short, jcc near, call, long jmp, xchg
> -sieve: heavy memory access with no paging and with paging static and with paging vmalloc'ed
> -smptest: run smp_id() on every cpu and compares return value to number
> -tsc: write to tsc(0) and write to tsc(100000000000) and read it back
> -vmexit: long loops for each: cpuid, vmcall, mov_from_cr8, mov_to_cr8, inl_pmtimer, ipi, ipi+halt
> -kvmclock_test: test of wallclock, monotonic cycle and performance of kvmclock
> -pcid: basic functionality test of PCID/INVPCID feature
> \ No newline at end of file
> + access: lots of page table related access (pte/pde) (read/write)
> + apic: enable x2apic, self ipi, ioapic intr, ioapic simultaneous
> + emulator: move to/from regs, cmps, push, pop, to/from cr8, smsw and lmsw
> + hypercall: intel and amd hypercall insn
> + msr: write to msr (only KERNEL_GS_BASE for now)
> + port80: lots of out to port 80
> + realmode: goes back to realmode, shld, push/pop, mov immediate,
> + cmp immediate, add immediate, io, eflags instructions
> + (clc, cli, etc.), jcc short, jcc near, call, long jmp, xchg
> + sieve: heavy memory access with no paging and with paging static and
> + with paging vmalloc'ed
> + smptest: run smp_id() on every cpu and compares return value to number
> + tsc: write to tsc(0) and write to tsc(100000000000) and read it back
> + vmexit: long loops for each: cpuid, vmcall, mov_from_cr8, mov_to_cr8,
> + inl_pmtimer, ipi, ipi+halt
> + kvmclock_test: test of wallclock, monotonic cycle and performance of kvmclock
> + pcid: basic functionality test of PCID/INVPCID featureThis directory
> + contains sources for a kvm test suite.
> +
> +Legacy notes:
> +
> + The exit status of the binary (and the script) is inconsistent: with
> + qemu-system, after the unittest is done, the exit status of qemu is 1,
> + different from the 'old style' qemu-kvm, whose exit status in successful
> + completion is 0.
> diff --git a/x86/flat.lds b/x86/flat.lds
> new file mode 100644
> index 0000000000000..a278b56c9a4e3
> --- /dev/null
> +++ b/x86/flat.lds
> @@ -0,0 +1,21 @@
> +SECTIONS
> +{
> + . = 4M + SIZEOF_HEADERS;
> + stext = .;
> + .text : { *(.init) *(.text) *(.text.*) }
> + . = ALIGN(4K);
> + .data : {
> + *(.data)
> + exception_table_start = .;
> + *(.data.ex)
> + exception_table_end = .;
> + }
> + . = ALIGN(16);
> + .rodata : { *(.rodata) }
> + . = ALIGN(16);
> + .bss : { *(.bss) }
> + . = ALIGN(4K);
> + edata = .;
> +}
> +
> +ENTRY(start)
> diff --git a/x86/run b/x86/run
> new file mode 100755
> index 0000000000000..646c5770ed03f
> --- /dev/null
> +++ b/x86/run
> @@ -0,0 +1,41 @@
> +#!/bin/bash
> +
> +qemukvm="${QEMU:-qemu-kvm}"
> +qemusystem="${QEMU:-qemu-system-x86_64}"
> +if
> + ${qemukvm} -device '?' 2>&1 | grep -F -e \"testdev\" -e \"pc-testdev\" > /dev/null;
> +then
> + qemu="${qemukvm}"
> +else
> + if
> + ${qemusystem} -device '?' 2>&1 | grep -F -e \"testdev\" -e \"pc-testdev\" > /dev/null;
> + then
> + qemu="${qemusystem}"
> + else
> + echo QEMU binary ${QEMU} has no support for test device. Exiting.
> + exit 2
> + fi
> +fi
> +
> +if
> + ${qemu} -device '?' 2>&1 | grep -F "pci-testdev" > /dev/null;
> +then
> + pci_testdev="-device pci-testdev"
> +else
> + pci_testdev=""
> +fi
> +
> +if
> + ${qemu} -device '?' 2>&1 | grep -F "pc-testdev" > /dev/null;
> +then
> + pc_testdev="-device pc-testdev -device isa-debug-exit,iobase=0xf4,iosize=0x4"
> +else
> + pc_testdev="-device testdev,chardev=testlog -chardev file,id=testlog,path=msr.out"
> +fi
> +
> +command="${qemu} -enable-kvm $pc_testdev -display none -serial stdio $pci_testdev -kernel"
> +echo ${command} "$@"
> +${command} "$@"
> +ret=$?
> +echo Return value from qemu: $ret
> +exit $ret
> --
> 1.8.1.4
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 6/9] Introduce virtio-testdev
2013-10-14 16:23 ` [PATCH 6/9] Introduce virtio-testdev Andrew Jones
2013-10-15 8:39 ` Andrew Jones
@ 2013-10-17 1:06 ` Christoffer Dall
2013-10-17 9:51 ` Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2 siblings, 1 reply; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 1:06 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Mon, Oct 14, 2013 at 06:23:32PM +0200, Andrew Jones wrote:
> virtio-testdev is a communication channel to qemu through virtio that
> can be used by test code to send commands. The only command currently
> implemented is EXIT, which allows the test code to exit with a given
> status code.
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> lib/bswap.h | 7 +++
> lib/libcflat.h | 10 ++++
> lib/virtio-testdev.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
> lib/virtio-testdev.h | 9 ++++
> 4 files changed, 152 insertions(+)
> create mode 100644 lib/bswap.h
> create mode 100644 lib/virtio-testdev.c
> create mode 100644 lib/virtio-testdev.h
>
> diff --git a/lib/bswap.h b/lib/bswap.h
> new file mode 100644
> index 0000000000000..e63c4d37a8b9a
> --- /dev/null
> +++ b/lib/bswap.h
> @@ -0,0 +1,7 @@
> +#ifndef _BSWAP_H_
> +#define _BSWAP_H_
> +#define le32_to_cpu(x) (x)
> +#define cpu_to_le32(x) (x)
> +#define le16_to_cpu(x) (x)
> +#define cpu_to_le16(x) (x)
> +#endif
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index a1be635ab4ee9..41791194657d0 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -37,6 +37,16 @@ typedef _Bool bool;
> #define true 1
> #define false 0
>
> +typedef u32 compat_ptr_t;
> +static inline void *compat_ptr(compat_ptr_t ptr)
> +{
> + return (void *)(unsigned long)ptr;
> +}
> +static inline compat_ptr_t ptr_to_compat(void *ptr)
> +{
> + return (u32)(unsigned long)ptr;
> +}
> +
> extern void halt(int code);
> extern void exit(int code);
>
> diff --git a/lib/virtio-testdev.c b/lib/virtio-testdev.c
> new file mode 100644
> index 0000000000000..900921302c344
> --- /dev/null
> +++ b/lib/virtio-testdev.c
There's an interesting mix of space and tab indentations in this file...
I assume using the kernel coding style would be approprate here...
Actually, that could be added to the readme too. (Or whichever format we
choose).
Could you fix?
> @@ -0,0 +1,126 @@
> +#include "libcflat.h"
> +#include "iomaps.h"
> +#include "bswap.h"
> +
> +#define TESTDEV_MAJOR_VER 1
> +#define TESTDEV_MINOR_VER 1
> +
> +#define VIRTIO_MMIO_DEVICEID 0x8
> +#define VIRTIO_ID_TESTDEV 0xffff
> +#define DEV_CONFIG_BASE 0x100
> +#define DEV_CONFIG_SIZE 0x100
> +
> +enum { VERSION = 1, CLEAR, EXIT, };
> +enum { TOKEN, NARGS, NRETS, ARG1, ARG2, ARG3, ARG4, };
> +
> +#define RET1(nargs) (ARG1 + (nargs) + 0)
> +#define RET2(nargs) (ARG1 + (nargs) + 1)
> +#define RET3(nargs) (ARG1 + (nargs) + 2)
> +#define RET4(nargs) (ARG1 + (nargs) + 3)
> +
> +static u32 *testdev_base;
> +
> +/*
> + * We have to write all args; nargs, nrets, ... first to
> + * avoid executing token's operation until all args are in
> + * place. Then issue the op, and then read the rets. Reading
> + * the rets (or just sanity checking by reading base[0]) will
> + * read a zero into qemu's copy of the token, which allows us
> + * to prepare additional ops without re-executing the last one.
> + */
> +void virtio_testdev(u32 token, u32 nargs, u32 nrets, ...)
> +{
> + volatile u32 *base = testdev_base;
> + volatile u32 *tdp = base + 1;
> + va_list va;
> +
> + if (!testdev_base)
> + return;
> +
> + *tdp++ = cpu_to_le32(nargs);
> + *tdp++ = cpu_to_le32(nrets);
> +
> + va_start(va, nrets);
> +
> + while (nargs--)
> + *tdp++ = cpu_to_le32(va_arg(va, unsigned));
> +
> + /* this runs the op, but then resets base[0] to zero */
> + base[0] = cpu_to_le32(token);
> +
> + /* sanity check */
> + if (base[0] != 0) {
> + printf("virtio-testdev base[0] should always be zero!\n");
> + halt(EIO);
> + }
> +
> + while (nrets--) {
> + u32 *r = va_arg(va, unsigned *);
> + *r = le32_to_cpu(*tdp++);
> + }
> +
> + va_end(va);
> +}
> +
> +void virtio_testdev_version(u32 *version)
> +{
> + virtio_testdev(VERSION, 0, 1, version);
> +}
> +
> +void virtio_testdev_clear(void)
> +{
> + virtio_testdev(CLEAR, 0, 0);
> +}
> +
> +void virtio_testdev_exit(int code)
> +{
> + virtio_testdev(EXIT, 1, 0, code);
> +}
> +
> +void virtio_testdev_init(void)
> +{
> + struct iomap *m;
> + u32 version, i;
> + u16 major, minor;
> +
> + m = iomaps_find("virtio_mmio");
> + if (!m) {
> + printf("No virtio-mmio transports for virtio-testdev found!\n");
> + halt(ENODEV);
> + }
> +
> + for (i = 0; i < m->nr; ++i) {
> + volatile u32 *base = (u32 *)compat_ptr(m->addrs[i]);
> + u32 devid32 = base[VIRTIO_MMIO_DEVICEID / 4];
do we have readl/writel in this framework? If not, maybe we should to
indicate IO read/writes and ensure the compiler doesn't reorder things
and that we have the necessary memory barriers etc...?
That would apply to virtio_testdev above as well.
> + u16 devid = devid32 & 0xffff;
> + devid = le16_to_cpu(devid);
> + if (devid == VIRTIO_ID_TESTDEV) {
> + testdev_base = (u32 *)compat_ptr(m->addrs[i] + DEV_CONFIG_BASE);
> + break;
> + }
> + }
> +
> + if (!testdev_base) {
> + printf("Can't find virtio-testdev. Is '-device virtio-testdev' "
> + "on the qemu command line?\n");
> + halt(ENODEV);
> + }
> +
> + virtio_testdev_version(&version);
> + major = version >> 16;
> + minor = version & 0xffff;
> +
> + if (major != TESTDEV_MAJOR_VER || minor < TESTDEV_MINOR_VER) {
> + char *u = "qemu";
> + if (major > TESTDEV_MAJOR_VER)
> + u = "kvm-unit-tests";
> + printf("Refusing to run with virtio-testdev major = %d, minor = %d\n",
> + major, minor);
"Refusing to run"?
How about "incompatible version of virtio-testdev"?
> + printf("Update %s.\n", u);
> + exit(ENODEV);
> + }
> +
> + if (minor > TESTDEV_MINOR_VER)
> + printf("testdev has new features. "
> + "An update of kvm-unit-tests may be possible.\n");
> +}
> diff --git a/lib/virtio-testdev.h b/lib/virtio-testdev.h
> new file mode 100644
> index 0000000000000..c10bbfb591d0b
> --- /dev/null
> +++ b/lib/virtio-testdev.h
> @@ -0,0 +1,9 @@
> +#ifndef _VIRTIO_TESTDEV_H_
> +#define _VIRTIO_TESTDEV_H_
> +#include "libcflat.h"
> +
> +extern void virtio_testdev_init(void);
> +extern void virtio_testdev_version(u32 *version);
> +extern void virtio_testdev_clear(void);
> +extern void virtio_testdev_exit(int code);
> +#endif
> --
> 1.8.1.4
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 6/9] Introduce virtio-testdev
2013-10-14 16:23 ` [PATCH 6/9] Introduce virtio-testdev Andrew Jones
2013-10-15 8:39 ` Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
@ 2013-10-17 1:06 ` Christoffer Dall
2 siblings, 0 replies; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 1:06 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Mon, Oct 14, 2013 at 06:23:32PM +0200, Andrew Jones wrote:
> virtio-testdev is a communication channel to qemu through virtio that
> can be used by test code to send commands. The only command currently
> implemented is EXIT, which allows the test code to exit with a given
> status code.
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> lib/bswap.h | 7 +++
> lib/libcflat.h | 10 ++++
> lib/virtio-testdev.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
> lib/virtio-testdev.h | 9 ++++
> 4 files changed, 152 insertions(+)
> create mode 100644 lib/bswap.h
> create mode 100644 lib/virtio-testdev.c
> create mode 100644 lib/virtio-testdev.h
>
> diff --git a/lib/bswap.h b/lib/bswap.h
> new file mode 100644
> index 0000000000000..e63c4d37a8b9a
> --- /dev/null
> +++ b/lib/bswap.h
> @@ -0,0 +1,7 @@
> +#ifndef _BSWAP_H_
> +#define _BSWAP_H_
> +#define le32_to_cpu(x) (x)
> +#define cpu_to_le32(x) (x)
> +#define le16_to_cpu(x) (x)
> +#define cpu_to_le16(x) (x)
> +#endif
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index a1be635ab4ee9..41791194657d0 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -37,6 +37,16 @@ typedef _Bool bool;
> #define true 1
> #define false 0
>
> +typedef u32 compat_ptr_t;
> +static inline void *compat_ptr(compat_ptr_t ptr)
> +{
> + return (void *)(unsigned long)ptr;
> +}
> +static inline compat_ptr_t ptr_to_compat(void *ptr)
> +{
> + return (u32)(unsigned long)ptr;
> +}
> +
> extern void halt(int code);
> extern void exit(int code);
>
> diff --git a/lib/virtio-testdev.c b/lib/virtio-testdev.c
> new file mode 100644
> index 0000000000000..900921302c344
> --- /dev/null
> +++ b/lib/virtio-testdev.c
There's an interesting mix of space and tab indentations in this file...
I assume using the kernel coding style would be approprate here...
Actually, that could be added to the readme too. (Or whichever format we
choose).
Could you fix?
> @@ -0,0 +1,126 @@
> +#include "libcflat.h"
> +#include "iomaps.h"
> +#include "bswap.h"
> +
> +#define TESTDEV_MAJOR_VER 1
> +#define TESTDEV_MINOR_VER 1
> +
> +#define VIRTIO_MMIO_DEVICEID 0x8
> +#define VIRTIO_ID_TESTDEV 0xffff
> +#define DEV_CONFIG_BASE 0x100
> +#define DEV_CONFIG_SIZE 0x100
> +
> +enum { VERSION = 1, CLEAR, EXIT, };
> +enum { TOKEN, NARGS, NRETS, ARG1, ARG2, ARG3, ARG4, };
> +
> +#define RET1(nargs) (ARG1 + (nargs) + 0)
> +#define RET2(nargs) (ARG1 + (nargs) + 1)
> +#define RET3(nargs) (ARG1 + (nargs) + 2)
> +#define RET4(nargs) (ARG1 + (nargs) + 3)
> +
> +static u32 *testdev_base;
> +
> +/*
> + * We have to write all args; nargs, nrets, ... first to
> + * avoid executing token's operation until all args are in
> + * place. Then issue the op, and then read the rets. Reading
> + * the rets (or just sanity checking by reading base[0]) will
> + * read a zero into qemu's copy of the token, which allows us
> + * to prepare additional ops without re-executing the last one.
> + */
> +void virtio_testdev(u32 token, u32 nargs, u32 nrets, ...)
> +{
> + volatile u32 *base = testdev_base;
> + volatile u32 *tdp = base + 1;
> + va_list va;
> +
> + if (!testdev_base)
> + return;
> +
> + *tdp++ = cpu_to_le32(nargs);
> + *tdp++ = cpu_to_le32(nrets);
> +
> + va_start(va, nrets);
> +
> + while (nargs--)
> + *tdp++ = cpu_to_le32(va_arg(va, unsigned));
> +
> + /* this runs the op, but then resets base[0] to zero */
> + base[0] = cpu_to_le32(token);
> +
> + /* sanity check */
> + if (base[0] != 0) {
> + printf("virtio-testdev base[0] should always be zero!\n");
> + halt(EIO);
> + }
> +
> + while (nrets--) {
> + u32 *r = va_arg(va, unsigned *);
> + *r = le32_to_cpu(*tdp++);
> + }
> +
> + va_end(va);
> +}
> +
> +void virtio_testdev_version(u32 *version)
> +{
> + virtio_testdev(VERSION, 0, 1, version);
> +}
> +
> +void virtio_testdev_clear(void)
> +{
> + virtio_testdev(CLEAR, 0, 0);
> +}
> +
> +void virtio_testdev_exit(int code)
> +{
> + virtio_testdev(EXIT, 1, 0, code);
> +}
> +
> +void virtio_testdev_init(void)
> +{
> + struct iomap *m;
> + u32 version, i;
> + u16 major, minor;
> +
> + m = iomaps_find("virtio_mmio");
> + if (!m) {
> + printf("No virtio-mmio transports for virtio-testdev found!\n");
> + halt(ENODEV);
> + }
> +
> + for (i = 0; i < m->nr; ++i) {
> + volatile u32 *base = (u32 *)compat_ptr(m->addrs[i]);
> + u32 devid32 = base[VIRTIO_MMIO_DEVICEID / 4];
do we have readl/writel in this framework? If not, maybe we should to
indicate IO read/writes and ensure the compiler doesn't reorder things
and that we have the necessary memory barriers etc...?
That would apply to virtio_testdev above as well.
> + u16 devid = devid32 & 0xffff;
> + devid = le16_to_cpu(devid);
> + if (devid == VIRTIO_ID_TESTDEV) {
> + testdev_base = (u32 *)compat_ptr(m->addrs[i] + DEV_CONFIG_BASE);
> + break;
> + }
> + }
> +
> + if (!testdev_base) {
> + printf("Can't find virtio-testdev. Is '-device virtio-testdev' "
> + "on the qemu command line?\n");
> + halt(ENODEV);
> + }
> +
> + virtio_testdev_version(&version);
> + major = version >> 16;
> + minor = version & 0xffff;
> +
> + if (major != TESTDEV_MAJOR_VER || minor < TESTDEV_MINOR_VER) {
> + char *u = "qemu";
> + if (major > TESTDEV_MAJOR_VER)
> + u = "kvm-unit-tests";
> + printf("Refusing to run with virtio-testdev major = %d, minor = %d\n",
> + major, minor);
"Refusing to run"?
How about "incompatible version of virtio-testdev"?
> + printf("Update %s.\n", u);
> + exit(ENODEV);
> + }
> +
> + if (minor > TESTDEV_MINOR_VER)
> + printf("testdev has new features. "
> + "An update of kvm-unit-tests may be possible.\n");
> +}
> diff --git a/lib/virtio-testdev.h b/lib/virtio-testdev.h
> new file mode 100644
> index 0000000000000..c10bbfb591d0b
> --- /dev/null
> +++ b/lib/virtio-testdev.h
> @@ -0,0 +1,9 @@
> +#ifndef _VIRTIO_TESTDEV_H_
> +#define _VIRTIO_TESTDEV_H_
> +#include "libcflat.h"
> +
> +extern void virtio_testdev_init(void);
> +extern void virtio_testdev_version(u32 *version);
> +extern void virtio_testdev_clear(void);
> +extern void virtio_testdev_exit(int code);
> +#endif
> --
> 1.8.1.4
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 7/9] arm: replace arbitrary divisions
2013-10-14 16:23 ` [PATCH 7/9] arm: replace arbitrary divisions Andrew Jones
@ 2013-10-17 1:06 ` Christoffer Dall
2013-10-17 10:03 ` Andrew Jones
0 siblings, 1 reply; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 1:06 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Mon, Oct 14, 2013 at 06:23:33PM +0200, Andrew Jones wrote:
> arm can't do arbitrary divisions without software support. Usually
> libgcc would jump in here, but depending on the toolchain used that may
> or may not work. Luckily, we only care about two types of divisions.
> Divide by 10 and divide by 16. Divide by 16 is already covered by gcc
> since it's a power of two. Divide by 10 can be hacked up using a
> multiplication and shift.
Isn't this just a matter of supplying a few libc implementations to
handle div_by_0 and that sort? I'm pretty sure we had that working in
the kvm-selftest for ARM thingy that allowed you to use the standard '/'
operator in C code.... I suspect there will be more users of this
eventually.
Or wait, do you mean 'long long' operations by arbitrary? In that case,
I'm less sure... A library implementation to support the operator would
still be preferred IMHO.
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> lib/divmod.h | 20 ++++++++++++++++++++
> lib/printf.c | 27 ++++++++++++++-------------
> 2 files changed, 34 insertions(+), 13 deletions(-)
> create mode 100644 lib/divmod.h
>
> diff --git a/lib/divmod.h b/lib/divmod.h
> new file mode 100644
> index 0000000000000..c0f04d7d8386d
> --- /dev/null
> +++ b/lib/divmod.h
> @@ -0,0 +1,20 @@
> +#ifndef _DIVMOD_H_
> +#define _DIVMOD_H_
> +#ifdef __arm__
> +static inline long long div10(long long n)
> +{
> + /*
> + * multiply n by 2^32/10 and the result of n/10
> + * will be in the upper word
> + */
> + return (n * 0x1999999aU) >> 32;
> +}
> +static inline int mod10(long long n)
> +{
> + return n - div10(n) * 10;
> +}
> +#else
> +#define div10(n) ((n) / 10)
> +#define mod10(n) ((n) % 10)
> +#endif
> +#endif
> diff --git a/lib/printf.c b/lib/printf.c
> index 867eb1926f742..9fb8133868c7a 100644
> --- a/lib/printf.c
> +++ b/lib/printf.c
> @@ -1,4 +1,5 @@
> #include "libcflat.h"
> +#include "divmod.h"
>
> typedef struct pstream {
> char *buffer;
> @@ -23,7 +24,7 @@ void print_str(pstream_t *p, const char *s)
>
> static char digits[16] = "0123456789abcdef";
>
> -void print_int(pstream_t *ps, long long n, int base)
> +void print_int(pstream_t *ps, long long n)
> {
> char buf[sizeof(long) * 3 + 2], *p = buf;
> int s = 0, i;
> @@ -34,8 +35,8 @@ void print_int(pstream_t *ps, long long n, int base)
> }
>
> while (n) {
> - *p++ = digits[n % base];
> - n /= base;
> + *p++ = digits[mod10(n)];
> + n = div10(n);
> }
>
> if (s)
> @@ -57,14 +58,14 @@ void print_int(pstream_t *ps, long long n, int base)
> print_str(ps, buf);
> }
>
> -void print_unsigned(pstream_t *ps, unsigned long long n, int base)
> +void print_unsigned(pstream_t *ps, unsigned long long n)
> {
> char buf[sizeof(long) * 3 + 1], *p = buf;
> int i;
>
> while (n) {
> - *p++ = digits[n % base];
> - n /= base;
> + *p++ = digits[n % 16];
> + n /= 16;
> }
>
> if (p == buf)
> @@ -116,32 +117,32 @@ int vsnprintf(char *buf, int size, const char *fmt, va_list va)
> case 'd':
> switch (nlong) {
> case 0:
> - print_int(&s, va_arg(va, int), 10);
> + print_int(&s, va_arg(va, int));
> break;
> case 1:
> - print_int(&s, va_arg(va, long), 10);
> + print_int(&s, va_arg(va, long));
> break;
> default:
> - print_int(&s, va_arg(va, long long), 10);
> + print_int(&s, va_arg(va, long long));
> break;
> }
> break;
> case 'x':
> switch (nlong) {
> case 0:
> - print_unsigned(&s, va_arg(va, unsigned), 16);
> + print_unsigned(&s, va_arg(va, unsigned));
> break;
> case 1:
> - print_unsigned(&s, va_arg(va, unsigned long), 16);
> + print_unsigned(&s, va_arg(va, unsigned long));
> break;
> default:
> - print_unsigned(&s, va_arg(va, unsigned long long), 16);
> + print_unsigned(&s, va_arg(va, unsigned long long));
> break;
> }
> break;
> case 'p':
> print_str(&s, "0x");
> - print_unsigned(&s, (unsigned long)va_arg(va, void *), 16);
> + print_unsigned(&s, (unsigned long)va_arg(va, void *));
> break;
> case 's':
> print_str(&s, va_arg(va, const char *));
> --
> 1.8.1.4
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 8/9] arm: initial drop
2013-10-14 16:23 ` [PATCH 8/9] arm: initial drop Andrew Jones
@ 2013-10-17 1:06 ` Christoffer Dall
2013-10-17 10:16 ` Andrew Jones
0 siblings, 1 reply; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 1:06 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Mon, Oct 14, 2013 at 06:23:34PM +0200, Andrew Jones wrote:
> This is the initial arm test infrastructure and a first test that
> simply checks some bootinfo. kvm isn't needed to run this test. This
> patch also adds a common build environment variable, $QEMU_BIN, which
> allows makefiles to call on qemu when needed.
>
> Try it out with
> yum install gcc-arm-linux-gnu dtc
> export QEMU=[qemu with mach-virt and virtio-testdev]
> ./configure --cross-prefix=arm-linux-gnu- --arch=arm
> make
> ./run_tests.sh
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> arm/boot.c | 27 ++++++++++++++++++++
> arm/cstart.S | 47 ++++++++++++++++++++++++++++++++++
> arm/flat.lds | 18 +++++++++++++
> arm/run | 19 ++++++++++++++
> arm/unittests.cfg | 11 ++++++++
> config/config-arm.mak | 62 +++++++++++++++++++++++++++++++++++++++++++++
> configure | 10 ++++++--
> lib/arm/bootinfo.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++
> lib/arm/bootinfo.h | 19 ++++++++++++++
> lib/arm/bswap.h | 30 ++++++++++++++++++++++
> lib/arm/io.c | 26 +++++++++++++++++++
> lib/bswap.h | 4 +++
> lib/libcflat.h | 1 +
> 13 files changed, 342 insertions(+), 2 deletions(-)
> create mode 100644 arm/boot.c
> create mode 100644 arm/cstart.S
> create mode 100644 arm/flat.lds
> create mode 100755 arm/run
> create mode 100644 arm/unittests.cfg
> create mode 100644 config/config-arm.mak
> create mode 100644 lib/arm/bootinfo.c
> create mode 100644 lib/arm/bootinfo.h
> create mode 100644 lib/arm/bswap.h
> create mode 100644 lib/arm/io.c
>
> diff --git a/arm/boot.c b/arm/boot.c
> new file mode 100644
> index 0000000000000..375e8708a7c54
this file's indentation is also funny, you should really check your
editor configuration :)
> --- /dev/null
> +++ b/arm/boot.c
> @@ -0,0 +1,27 @@
> +#include "libcflat.h"
> +#include "arm/bootinfo.h"
> +
> +static bool info_check(u32 var, char *expected)
> +{
> + char var_str[9];
> + snprintf(var_str, 9, "%x", var);
> + while (*expected == '0' || *expected == 'x')
> + ++expected;
> + return !strcmp(var_str, expected);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + int ret = 0;
> +
> + if (argc < 3) {
> + printf("Not enough arguments. Can't test\n");
> + return 1;
> + }
> +
> + if (!strcmp(argv[0], "info"))
> + ret = !info_check(mem32.size, argv[1])
> + || !info_check(core.pagesize, argv[2]);
> +
> + return ret;
> +}
I'm actually a little confused, when does this main get invoked and by
whom and what are we testing for here?
> diff --git a/arm/cstart.S b/arm/cstart.S
> new file mode 100644
> index 0000000000000..a65809824d4f1
> --- /dev/null
> +++ b/arm/cstart.S
> @@ -0,0 +1,47 @@
> +
> +#define CR_B (1 << 7)
> +
> +.arm
> +
> +.section .init
> +
> +.globl start
> +start:
> + /* bootloader params are in r0-r2 */
> + ldr sp, =stacktop
> + push { r0-r3 } @push r3 too for 8-byte alignment
> +
> + mrc p15, 0, r8, c1, c0, 0 @r8 = sctrl
> + bl get_endianness
> + bl io_init
> +
> + pop { r0-r3 }
> + bl read_bootinfo
> + bl __setup_args
> + ldr r0, =__argc
> + ldr r0, [r0]
> + ldr r1, =__argv
> + bl main
> + bl exit
> + b halt
> +
> +get_endianness:
> + and r0, r8, #CR_B
> + cmp r0, #0
> + beq 1f
> + ldr r1, =cpu_is_be
> + mov r0, #1
> + str r0, [r1]
> +1: mov pc, lr
> +
> +.text
> +
> +.globl halt
> +halt:
> +1: wfi
> + b 1b
> +
> +.data
> +
> +.globl cpu_is_be
> +cpu_is_be: .word 0
> diff --git a/arm/flat.lds b/arm/flat.lds
> new file mode 100644
> index 0000000000000..3e5d72e24989b
> --- /dev/null
> +++ b/arm/flat.lds
> @@ -0,0 +1,18 @@
> +
> +SECTIONS
> +{
> + .text : { *(.init) *(.text) *(.text.*) }
> + . = ALIGN(4K);
> + .data : { *(.data) }
> + . = ALIGN(16);
> + .rodata : { *(.rodata) }
> + . = ALIGN(16);
> + .bss : { *(.bss) }
> + . = ALIGN(4K);
> + edata = .;
> + . += 8K;
> + . = ALIGN(4K);
> + stacktop = .;
> +}
> +
> +ENTRY(start)
> diff --git a/arm/run b/arm/run
> new file mode 100755
> index 0000000000000..64446e8907564
> --- /dev/null
> +++ b/arm/run
> @@ -0,0 +1,19 @@
> +#!/bin/bash
> +
> +qemu="${QEMU:-qemu-system-arm}"
> +testdev='virtio-testdev'
> +
> +if ! $qemu -device '?' 2>&1 | grep $testdev > /dev/null; then
> + echo \"$qemu\" has no support for the virtio test device. Exiting.
> + exit 2
> +fi
> +
> +command="$qemu -device $testdev -display none -serial stdio "
> +command+="-M virt -cpu cortex-a15 "
> +#command+="-enable-kvm "
> +command+="-kernel"
> +echo $command "$@"
> +$command "$@"
> +ret=$?
> +echo Return value from qemu: $ret
> +exit $ret
> diff --git a/arm/unittests.cfg b/arm/unittests.cfg
> new file mode 100644
> index 0000000000000..fb78cd906839a
> --- /dev/null
> +++ b/arm/unittests.cfg
> @@ -0,0 +1,11 @@
> +# Define your new unittest following the convention:
> +# [unittest_name]
> +# file = foo.flat # Name of the flat file to be used
> +# smp = 2 # Number of processors the VM will use during this test
> +# extra_params = -append <params...> # Additional parameters used
> +# arch = arm/arm64 # Only if the test case works only on one of them
> +# groups = group1 group2 # Used to identify test cases with run_tests -g ...
> +
> +[boot_info]
> +file = boot.flat
> +extra_params = -m 256 -append 'info 0x10000000 0x1000'
> diff --git a/config/config-arm.mak b/config/config-arm.mak
> new file mode 100644
> index 0000000000000..066b1f725c5b3
> --- /dev/null
> +++ b/config/config-arm.mak
> @@ -0,0 +1,62 @@
> +mach = mach-virt
> +iodevs = pl011 virtio_mmio
> +phys_base = 0x8000000
> +
> +cstart.o = $(TEST_DIR)/cstart.o
> +bits = 32
> +ldarch = elf32-littlearm
> +kernel_offset = 0x10000
> +CFLAGS += -D__arm__
> +
> +all: test_cases
> +
> +cflatobjs += \
> + lib/$(TEST_DIR)/iomaps.gen.o \
> + lib/iomaps.o \
> + lib/virtio-testdev.o \
> + lib/arm/io.o \
> + lib/arm/bootinfo.o
> +
> +$(libcflat): LDFLAGS += -nostdlib
> +$(libcflat): CFLAGS += -ffreestanding -I lib
> +
> +CFLAGS += -Wextra
> +CFLAGS += -marm
> +#CFLAGS += -mcpu=$(PROCESSOR)
> +CFLAGS += -mcpu=cortex-a15
> +CFLAGS += -O2
> +
> +libgcc := $(shell $(CC) -m$(ARCH) --print-libgcc-file-name)
> +start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> +
> +FLATLIBS = lib/libcflat.a $(libgcc)
> +%.elf: %.o $(FLATLIBS) arm/flat.lds
> + $(CC) $(CFLAGS) -nostdlib -o $@ \
> + -Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
> + $(filter %.o, $^) $(FLATLIBS)
> +
> +%.flat: %.elf
> + $(OBJCOPY) -O binary $^ $@
> +
> +tests-common = $(TEST_DIR)/boot.flat
> +
> +tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
> +
> +test_cases: $(tests-common) $(tests)
> +
> +$(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I lib
> +
> +$(TEST_DIR)/boot.elf: $(cstart.o) $(TEST_DIR)/boot.o
> +
> +lib/$(TEST_DIR)/iomaps.gen.c: lib/$(TEST_DIR)/$(mach).dts
> + scripts/gen-devtree-iomaps.pl $^ $(iodevs) > $@
> +
> +lib/$(TEST_DIR)/mach-virt.dts: dtb = $(subst .dts,.dtb,$@)
> +lib/$(TEST_DIR)/mach-virt.dts:
> + $(QEMU_BIN) -kernel /dev/null -M virt -machine dumpdtb=$(dtb)
> + fdtdump $(dtb) > $@
> +
> +arch_clean:
> + $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
> + $(TEST_DIR)/.*.d lib/arm/.*.d \
> + lib/$(TEST_DIR)/iomaps.gen.c lib/$(TEST_DIR)/mach-virt.*
> diff --git a/configure b/configure
> index 6cfc64943f6e6..296c70182ea1d 100755
> --- a/configure
> +++ b/configure
> @@ -6,8 +6,7 @@ cc=gcc
> ld=ld
> objcopy=objcopy
> ar=ar
> -arch=`uname -m | sed -e s/i.86/i386/`
> -processor="$arch"
> +arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'`
> cross_prefix=
>
> usage() {
> @@ -17,6 +16,7 @@ usage() {
> Options include:
> --test-dir=DIR the main directory for tests ($arch)
> --arch=ARCH architecture to compile for ($arch)
> + --processor=PROCESSOR processor to compile for ($arch)
> --cross-prefix=PREFIX cross compiler prefix
> --cc=CC c compiler to use ($cc)
> --ld=LD ld linker to use ($ld)
> @@ -66,6 +66,9 @@ while [[ "$1" = -* ]]; do
> ;;
> esac
> done
> +[ -z "$processor" ] && processor="$arch"
> +qemu="${QEMU:-qemu-system-$arch}"
> +
> if [ -z "$testdir" -a \( "$arch" = "i386" -o "$arch" = "x86_64" \) ]; then
> testdir=x86
> elif [ -z "$testdir" ]; then
> @@ -80,6 +83,7 @@ if [ -f $testdir/run ]; then
> fi
>
> # check for dependent 32 bit libraries
> +if [ "$arch" = "i386" -o "$arch" = "x86_64" ]; then
> cat << EOF > lib_test.c
> #include <stdc++.h>
> #include <boost_thread-mt.h>
> @@ -94,6 +98,7 @@ if [ $exit -eq 0 ]; then
> api=true
> fi
> rm -f lib_test.c
> +fi
>
> cat <<EOF > config.mak
> PREFIX=$prefix
> @@ -106,4 +111,5 @@ OBJCOPY=$cross_prefix$objcopy
> AR=$cross_prefix$ar
> API=$api
> TEST_DIR=$testdir
> +QEMU_BIN=$qemu
> EOF
> diff --git a/lib/arm/bootinfo.c b/lib/arm/bootinfo.c
> new file mode 100644
> index 0000000000000..c362064f661d9
> --- /dev/null
> +++ b/lib/arm/bootinfo.c
> @@ -0,0 +1,70 @@
> +#include "libcflat.h"
> +#include "arm/bootinfo.h"
> +#include "arm/bswap.h"
> +
> +#define FDT_SIG 0xd00dfeed
> +
> +#define KERNEL_OFFSET 0x00010000
> +#define ATAG_OFFSET 0x00000100
> +
> +#define ATAG_CORE 0x54410001
> +#define ATAG_MEM 0x54410002
> +#define ATAG_CMDLINE 0x54410009
> +
> +extern void start(void);
> +extern char *__args;
> +
> +u32 mach_type_id;
> +struct tag_core core;
> +struct tag_mem32 mem32;
> +
> +static void read_atags(u32 id, u32 *info)
> +{
> + u32 *p = info;
> +
> + if (!p) {
> + printf("Can't find bootinfo. mach-type = %x\n", id);
> + exit(ENOEXEC);
> + }
> +
> + /*
> + * p[0] count of words for the tag
> + * p[1] tag id
> + * p[2..] tag data
> + */
> + for (; p[0] != 0; p += p[0])
> + switch (p[1]) {
> + case ATAG_CORE:
> + core.flags = p[2];
> + core.pagesize = p[3];
> + core.rootdev = p[4];
> + break;
> + case ATAG_MEM:
> + mem32.size = p[2];
> + mem32.start = p[3];
> + break;
> + case ATAG_CMDLINE:
> + __args = (char *)&p[2];
> + break;
> + }
> +}
> +
> +#define __unused __attribute__((__unused__))
> +
> +void read_bootinfo(u32 arg __unused, u32 id, u32 *info)
> +{
> + u32 *atags = NULL;
> +
> + mach_type_id = id;
> +
> + if (info[0] == be32_to_cpu(FDT_SIG)) {
> + /*
> + * fdt reading is not [yet?] implemented. So calculate
> + * the ATAGS addr to read that instead.
> + */
> + atags = (u32 *)((u32)start - KERNEL_OFFSET + ATAG_OFFSET);
> + } else if (info[1] == ATAG_CORE)
> + atags = info;
> +
> + read_atags(id, atags);
> +}
> diff --git a/lib/arm/bootinfo.h b/lib/arm/bootinfo.h
> new file mode 100644
> index 0000000000000..9cf547e4cebeb
> --- /dev/null
> +++ b/lib/arm/bootinfo.h
> @@ -0,0 +1,19 @@
> +#ifndef _BOOTINFO_H_
> +#define _BOOTINFO_H_
> +#include "libcflat.h"
> +
> +struct tag_core {
> + u32 flags; /* bit 0 = read-only */
> + u32 pagesize;
> + u32 rootdev;
> +};
> +
> +struct tag_mem32 {
> + u32 size;
> + u32 start; /* physical start address */
> +};
> +
> +extern u32 mach_type_id;
> +extern struct tag_core core;
> +extern struct tag_mem32 mem32;
> +#endif
> diff --git a/lib/arm/bswap.h b/lib/arm/bswap.h
> new file mode 100644
> index 0000000000000..9bd16e789fcc5
> --- /dev/null
> +++ b/lib/arm/bswap.h
> @@ -0,0 +1,30 @@
> +#ifndef _ARM_BSWAP_H_
> +#define _ARM_BSWAP_H_
> +#include "libcflat.h"
> +
> +extern bool cpu_is_be;
> +
> +static inline u32 bswap32(u32 val)
> +{
> + u32 ret;
> + asm volatile("rev %0, %1" : "=r" (ret) : "r" (val));
> + return ret;
> +}
> +
> +static inline u16 bswap16(u16 val)
> +{
> + u16 ret;
> + asm volatile("rev16 %0, %1" : "=r" (ret) : "r" (val));
> + return ret;
> +}
> +
> +#define be32_to_cpu(x) (cpu_is_be ? x : bswap32(x))
> +#define cpu_to_be32(x) (cpu_is_be ? x : bswap32(x))
> +#define be16_to_cpu(x) (cpu_is_be ? x : bswap16(x))
> +#define cpu_to_be16(x) (cpu_is_be ? x : bswap16(x))
> +
> +#define le32_to_cpu(x) (cpu_is_be ? bswap32(x) : x)
> +#define cpu_to_le32(x) (cpu_is_be ? bswap32(x) : x)
> +#define le16_to_cpu(x) (cpu_is_be ? bswap16(x) : x)
> +#define cpu_to_le16(x) (cpu_is_be ? bswap16(x) : x)
> +#endif
> diff --git a/lib/arm/io.c b/lib/arm/io.c
> new file mode 100644
> index 0000000000000..951af60551a4c
> --- /dev/null
> +++ b/lib/arm/io.c
> @@ -0,0 +1,26 @@
> +#include "libcflat.h"
> +#include "iomaps.h"
> +#include "virtio-testdev.h"
> +
> +static volatile u8 *uart0_base;
> +
> +void puts(const char *s)
> +{
> + while (*s)
> + *uart0_base = *s++;
> +}
> +
> +void exit(int code)
> +{
> + virtio_testdev_exit(code);
> + halt(code);
> +}
> +
> +void io_init(void)
> +{
> + struct iomap *m = iomaps_find("pl011");
> + if (!m)
> + halt(ENXIO);
> + uart0_base = (u8 *)compat_ptr(m->addrs[0]);
> + virtio_testdev_init();
> +}
> diff --git a/lib/bswap.h b/lib/bswap.h
> index e63c4d37a8b9a..a428ed6c646dd 100644
> --- a/lib/bswap.h
> +++ b/lib/bswap.h
> @@ -1,7 +1,11 @@
> #ifndef _BSWAP_H_
> #define _BSWAP_H_
> +#ifdef __arm__
> +#include "arm/bswap.h"
> +#else
> #define le32_to_cpu(x) (x)
> #define cpu_to_le32(x) (x)
> #define le16_to_cpu(x) (x)
> #define cpu_to_le16(x) (x)
> #endif
> +#endif
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index 41791194657d0..dce9a0f516e7e 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -55,6 +55,7 @@ extern char *strcat(char *dest, const char *src);
> extern int strcmp(const char *a, const char *b);
>
> extern int printf(const char *fmt, ...);
> +extern int snprintf(char *buf, int size, const char *fmt, ...);
> extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
>
> extern void puts(const char *s);
> --
> 1.8.1.4
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 9/9] arm: add vectors support
2013-10-14 16:23 ` [PATCH 9/9] arm: add vectors support Andrew Jones
@ 2013-10-17 1:06 ` Christoffer Dall
2013-10-17 10:38 ` Andrew Jones
0 siblings, 1 reply; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 1:06 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Mon, Oct 14, 2013 at 06:23:35PM +0200, Andrew Jones wrote:
> Add support for tests to manage exception handlers. Now we need kvm.
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> arm/boot.c | 29 +++++++++++++++++++----
> arm/cstart.S | 46 ++++++++++++++++++++++++++++++++++++
> arm/run | 2 +-
> arm/unittests.cfg | 6 +++++
> config/config-arm.mak | 1 +
> lib/arm/bootinfo.c | 2 --
> lib/arm/processor.h | 45 +++++++++++++++++++++++++++++++++++
> lib/arm/vectors.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++
> lib/arm/vectors.h | 37 +++++++++++++++++++++++++++++
> lib/libcflat.h | 2 ++
> 10 files changed, 227 insertions(+), 8 deletions(-)
> create mode 100644 lib/arm/processor.h
> create mode 100644 lib/arm/vectors.c
> create mode 100644 lib/arm/vectors.h
>
> diff --git a/arm/boot.c b/arm/boot.c
> index 375e8708a7c54..5103499b83155 100644
> --- a/arm/boot.c
> +++ b/arm/boot.c
> @@ -1,5 +1,10 @@
> #include "libcflat.h"
> #include "arm/bootinfo.h"
> +#include "arm/vectors.h"
> +
> +#define die(msg...) printf(msg), exit(1)
> +
> +static bool svc_works;
>
> static bool info_check(u32 var, char *expected)
> {
> @@ -10,18 +15,32 @@ static bool info_check(u32 var, char *expected)
> return !strcmp(var_str, expected);
> }
>
> +static void svc_check(struct ex_regs *regs __unused)
> +{
> + svc_works = true;
> +}
> +
> +static bool vectors_check(void)
> +{
> + handle_exception(V_SVC, svc_check);
> + asm volatile("svc #123");
> + return svc_works;
> +}
> +
> int main(int argc, char **argv)
> {
> int ret = 0;
>
> - if (argc < 3) {
> - printf("Not enough arguments. Can't test\n");
> - return 1;
> - }
> + if (argc < 1)
> + die("boot: No test name appended to qemu command line\n");
>
> - if (!strcmp(argv[0], "info"))
> + if (!strcmp(argv[0], "info")) {
> + if (argc < 3)
> + die("boot info: Not enough arguments for test\n");
> ret = !info_check(mem32.size, argv[1])
> || !info_check(core.pagesize, argv[2]);
> + } else if (!strcmp(argv[0], "vectors"))
> + ret = !vectors_check();
>
> return ret;
> }
> diff --git a/arm/cstart.S b/arm/cstart.S
> index a65809824d4f1..0907c620bd83f 100644
> --- a/arm/cstart.S
> +++ b/arm/cstart.S
> @@ -1,5 +1,6 @@
>
> #define CR_B (1 << 7)
> +#define CR_V (1 << 13)
>
> .arm
>
> @@ -12,6 +13,13 @@ start:
> push { r0-r3 } @push r3 too for 8-byte alignment
>
> mrc p15, 0, r8, c1, c0, 0 @r8 = sctrl
> +
> + /* set up vector table */
> + bic r8, #CR_V @sctrl.V = 0
> + mcr p15, 0, r8, c1, c0, 0
> + ldr r0, =vector_table @vbar = vector_table
> + mcr p15, 0, r0, c12, c0, 0
> +
> bl get_endianness
> bl io_init
>
> @@ -41,6 +49,44 @@ halt:
> 1: wfi
> b 1b
>
> +vector_common:
> + add r2, sp, #(14 * 4)
this looks weird, what are you pointing to here?
> + mrs r3, spsr
> + push { r0-r3 } @push r0 too for padding
> + add r0, sp, #4 @skip pad
so you're embedding the exception number into the regs structure?
That's weird too... Why not have regs be regs at the time of calling
the exception and then pass that little bit of extra information here?
If not, could we at least call the regs structure something like
ex_info and have named fields on there?
> + bl do_handle_exception
> + pop { r0-r3 }
> + msr spsr_fsxc, r3
> + ldm sp!, { r0-r12,pc }^
> +
> +.macro m_vector, v
> + push { r0-r12,lr }
> + mov r1, \v
> + b vector_common
> +.endm
> +
> +reset: m_vector #0
> +undef: m_vector #1
> +svc: m_vector #2
> +prefetch: m_vector #3
> +data: m_vector #4
> +impossible: m_vector #5
> +irq: m_vector #6
> +fiq: m_vector #7
> +
> +.section .text.ex
> +.align 5
> +
> +vector_table:
> + b reset
> + b undef
> + b svc
> + b prefetch
> + b data
> + b impossible
> + b irq
> + b fiq
> +
> .data
>
> .globl cpu_is_be
> diff --git a/arm/run b/arm/run
> index 64446e8907564..b512880e28cb7 100755
> --- a/arm/run
> +++ b/arm/run
> @@ -10,7 +10,7 @@ fi
>
> command="$qemu -device $testdev -display none -serial stdio "
> command+="-M virt -cpu cortex-a15 "
> -#command+="-enable-kvm "
> +command+="-enable-kvm "
> command+="-kernel"
> echo $command "$@"
> $command "$@"
> diff --git a/arm/unittests.cfg b/arm/unittests.cfg
> index fb78cd906839a..9c4faa600e9c5 100644
> --- a/arm/unittests.cfg
> +++ b/arm/unittests.cfg
> @@ -9,3 +9,9 @@
> [boot_info]
> file = boot.flat
> extra_params = -m 256 -append 'info 0x10000000 0x1000'
> +groups = boot
> +
> +[boot_vectors]
> +file = boot.flat
> +extra_params = -append 'vectors'
> +groups = boot
> diff --git a/config/config-arm.mak b/config/config-arm.mak
> index 066b1f725c5b3..87d61872ab16a 100644
> --- a/config/config-arm.mak
> +++ b/config/config-arm.mak
> @@ -15,6 +15,7 @@ cflatobjs += \
> lib/iomaps.o \
> lib/virtio-testdev.o \
> lib/arm/io.o \
> + lib/arm/vectors.o \
> lib/arm/bootinfo.o
>
> $(libcflat): LDFLAGS += -nostdlib
> diff --git a/lib/arm/bootinfo.c b/lib/arm/bootinfo.c
> index c362064f661d9..fd74fac2c5a2f 100644
> --- a/lib/arm/bootinfo.c
> +++ b/lib/arm/bootinfo.c
> @@ -49,8 +49,6 @@ static void read_atags(u32 id, u32 *info)
> }
> }
>
> -#define __unused __attribute__((__unused__))
> -
> void read_bootinfo(u32 arg __unused, u32 id, u32 *info)
> {
> u32 *atags = NULL;
> diff --git a/lib/arm/processor.h b/lib/arm/processor.h
> new file mode 100644
> index 0000000000000..32e1778477be2
> --- /dev/null
> +++ b/lib/arm/processor.h
> @@ -0,0 +1,45 @@
> +#ifndef _PROCESSOR_H_
> +#define _PROCESSOR_H_
> +#include "libcflat.h"
> +
> +#define __stringify_1(x...) #x
> +#define __stringify(x...) __stringify_1(x)
> +
> +#undef __regfn
> +#define __regfn(reg) \
> +static inline u32 read_##reg(void) \
> +{ \
> + u32 val; \
> + asm volatile("mov %0, " __stringify(reg) : "=r" (val)); \
> + return val; \
> +}
> +__regfn(lr)
> +
> +#undef __regfn
> +#define __regfn(reg) \
> +static inline void write_##reg(u32 val) \
> +{ \
> + asm volatile("mov " __stringify(reg) ", %0" :: "r" (val)); \
> +}
> +__regfn(lr)
> +
> +#undef __regfn
> +#define __regfn(reg) \
> +static inline u32 read_##reg(void) \
> +{ \
> + u32 val; \
> + asm volatile("mrs %0, " __stringify(reg) : "=r" (val)); \
> + return val; \
> +}
> +__regfn(cpsr)
> +
> +#undef __regfn
> +#define __regfn(reg) \
> +static inline void write_##reg(u32 val) \
> +{ \
> + asm volatile("msr " __stringify(reg) ", %0" :: "r" (val)); \
> +}
> +__regfn(cpsr)
> +
> +#undef __regfn
> +#endif
> diff --git a/lib/arm/vectors.c b/lib/arm/vectors.c
> new file mode 100644
> index 0000000000000..c1e2dea519e56
> --- /dev/null
> +++ b/lib/arm/vectors.c
> @@ -0,0 +1,65 @@
> +#include "libcflat.h"
> +#include "arm/processor.h"
> +#include "arm/vectors.h"
> +
> +#define abort(msg...) \
> + printf(msg), dump_ex_regs(regs), exit(EINTR)
> +
> +const char *mode_names[] = {
> + "usr", "fiq", "irq", "svc", NULL, NULL, NULL,
> + "abt", NULL, NULL, NULL, "und",
> +};
> +
> +const char *vector_names[] = {
> + "Reset", "Undefined", "SVC", "Prefetch abort", "Data abort",
> + "Impossible vector 0x14", "IRQ", "FIQ",
> +};
> +
> +void dump_ex_regs(struct ex_regs *regs)
> +{
> + u32 cpsr = read_cpsr();
> + u8 mode, smode;
> +
> + mode = cpsr & MODE_MASK;
> + smode = ex_reg(regs, R_SPSR) & MODE_MASK;
> +
> + printf("vector = %s\n", vector_name(ex_vector(regs)));
> + printf("mode %s to %s\n", mode_name(smode), mode_name(mode));
> + printf("cpsr=%x\n", cpsr);
> + printf(
> + "r0=%x\n" "r1=%x\n" "r2=%x\n" "r3=%x\n"
> + "r4=%x\n" "r5=%x\n" "r6=%x\n" "r7=%x\n"
> + "r8=%x\n" "r9=%x\n" "r10=%x\n" "r11=%x\n"
> + "ip=%x\n" "sp_%s=%x\n" "lr_%s=%x\n" "cpsr_%s=%x\n",
> + ex_reg(regs,0), ex_reg(regs,1), ex_reg(regs,2), ex_reg(regs,3),
> + ex_reg(regs,4), ex_reg(regs,5), ex_reg(regs,6), ex_reg(regs,7),
> + ex_reg(regs,8), ex_reg(regs,9), ex_reg(regs,10), ex_reg(regs,11),
> + ex_reg(regs, R_IP),
> + mode_name(mode), ex_reg(regs, R_SP),
> + mode_name(mode), ex_reg(regs, R_LR),
> + mode_name(mode), ex_reg(regs, R_SPSR)
> + );
> +}
> +
> +static void (*exception_handlers[8])(struct ex_regs *regs);
> +
> +void handle_exception(u8 v, void (*func)(struct ex_regs *regs))
> +{
> + if (v < 8)
> + exception_handlers[v] = func;
> +}
> +
> +void do_handle_exception(struct ex_regs *regs)
> +{
> + u8 v;
> +
> + if ((v = ex_vector(regs)) > 7)
> + abort("%s called with vector=%d\n", __func__, v);
> +
> + if (exception_handlers[v]) {
> + exception_handlers[v](regs);
> + return;
> + }
> +
> + abort("Exception %s\n", vector_name(v));
> +}
> diff --git a/lib/arm/vectors.h b/lib/arm/vectors.h
> new file mode 100644
> index 0000000000000..ca074aab674a3
> --- /dev/null
> +++ b/lib/arm/vectors.h
> @@ -0,0 +1,37 @@
> +#ifndef _VECTORS_H_
> +#define _VECTORS_H_
> +
> +/* modes */
> +enum {
> + M_USR = 0x10, M_FIQ = 0x11, M_IRQ = 0x12, M_SVC = 0x13,
> + M_ABT = 0x17, M_UND = 0x1b,
> +};
> +#define MODE_MASK 0x1f
> +extern const char *mode_names[];
> +#define mode_name(m) mode_names[(m) - 0x10]
> +
> +/* vectors */
> +enum {
> + V_RESET, V_UNDEF, V_SVC, V_PREFETCH_ABT, V_DATA_ABT,
> + V_IMPOSSIBLE, V_IRQ, V_FIQ,
> +};
> +extern const char *vector_names[];
> +#define vector_name(v) vector_names[v]
> +
> +#define R_IP 12
> +#define R_SP 13
> +#define R_LR 14
> +#define R_SPSR 16
> +#define __ex_reg(n) \
> + ((n) == R_SP ? 1 : (n) == R_LR ? 16 : (n) == R_SPSR ? 2 : ((n)+3))
> +#define ex_reg(regs, n) ((regs)->words[__ex_reg(n)])
> +#define ex_vector(regs) ((regs)->words[0])
> +
> +struct ex_regs {
> + /* see cstart.S for the register push order */
> + unsigned long words[18];
> +};
referring to an assembly file to understand a data structure is not
super user-friendly. You could also consider being inspired by ptrace.h
from the kernel here to use a well-known format for this data.
> +
> +void handle_exception(u8 v, void (*func)(struct ex_regs *regs));
> +
> +#endif
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index dce9a0f516e7e..6ebd903a27f46 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -68,6 +68,8 @@ extern long atol(const char *ptr);
>
> #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
>
> +#define __unused __attribute__((__unused__))
> +
> #define NULL ((void *)0UL)
> #include "errno.h"
> #endif
> --
> 1.8.1.4
>
Looks roughly ok as a first drop, but I would like to reuse a bit more
familiar names from the kernel for mode definitions etc., and possibly
copy in the kernel header file for the data structure.
I'll review the implementation in more depth for v2 when the
indentations are fixed.
Thanks a lot for working on this and doing the initial legwork here.
-Christoffer
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 3/9] clean root dir of all x86-ness
2013-10-17 1:06 ` Christoffer Dall
@ 2013-10-17 9:35 ` Andrew Jones
2013-10-17 19:01 ` Christoffer Dall
0 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-17 9:35 UTC (permalink / raw)
To: Christoffer Dall; +Cc: kvm, kvmarm, gleb
On Wed, Oct 16, 2013 at 06:06:06PM -0700, Christoffer Dall wrote:
> > -The exit status of the binary (and the script) is inconsistent: with
> > -qemu-system, after the unittest is done, the exit status of qemu is 1,
> > -different from the 'old style' qemu-kvm, whose exit status in successful
> > -completion is 0.
> > +To create the tests' images do
>
> tests' images doesn't read very nice, can we just say test images?
OK
>
> > + ./configure
> > + make
> > +in this directory. Tests' images are created in ./<ARCH>/*.flat
> > +
> > +Then use the runner script to detect the correct invocation and
> > +invoke the test, e.g.
> > + ./x86-run ./x86/msr.flat
> > +or
> > + ./run_tests.sh
> > +to run them all.
>
> While you're at it, it would be great to provide a little more context
> in the README file.
>
> For example, we start talking abouter 'runner scripts', we refer to
> something called '.flat', and we refer to QEMU without explaining how
> this whole thing works, what the components are, what is required of
> QEMU etc.
>
> I think that would be useful for the wider adoption of kvm-unit-tests to
> developers writing ad-hoc patches for KVM.
>
> A reference to docs/testdev.txt from somewhere approrpriate in such text
> would probably also be useful...
>
> I know much of this is arch-specific, but there must be something
> generic or common across the architecture, and that would in essense be
> capturing what 'kvm-unit-tests' give you, which I think is very useful
> to have in the readme.
>
Agreed. I'll see what I can do with the overall documentation. And I need
to create an arm/README for arm specific documentation as well.
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 6/9] Introduce virtio-testdev
2013-10-17 1:06 ` Christoffer Dall
@ 2013-10-17 9:51 ` Andrew Jones
2013-10-17 19:01 ` Christoffer Dall
0 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-17 9:51 UTC (permalink / raw)
To: Christoffer Dall; +Cc: kvm, kvmarm, gleb
On Wed, Oct 16, 2013 at 06:06:14PM -0700, Christoffer Dall wrote:
> There's an interesting mix of space and tab indentations in this file...
>
> I assume using the kernel coding style would be approprate here...
> Actually, that could be added to the readme too. (Or whichever format we
> choose).
>
> Could you fix?
I was attempting to adopt the style from the common code lib/*, see
lib/string.c, lib/printf.c, lib/argv,c. The style used there is
1. 'four spaces'
2. 'tab'
3. 'tab + four spaces'
4. 'tab + tab'
...
However, I'd actually prefer to use the kernel style as well, and I see
that not even those three common files are consistent. argv.c only uses
spaces. Other x86 files also have a variety of styles (kernel style
being one of them). So probably the best choice is to go with kernel
style, and to add another cleanup patch that changes lib/* files as
well.
> > + for (i = 0; i < m->nr; ++i) {
> > + volatile u32 *base = (u32 *)compat_ptr(m->addrs[i]);
> > + u32 devid32 = base[VIRTIO_MMIO_DEVICEID / 4];
>
> do we have readl/writel in this framework? If not, maybe we should to
> indicate IO read/writes and ensure the compiler doesn't reorder things
> and that we have the necessary memory barriers etc...?
>
> That would apply to virtio_testdev above as well.
OK, I agree it makes sense to add readl and writel in. I'll do that, and
then rework my mmio reads to use them.
> + printf("Refusing to run with virtio-testdev major = %d, minor = %d\n",
> + major, minor);
> "Refusing to run"?
> How about "incompatible version of virtio-testdev"?
Sure. OK.
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 7/9] arm: replace arbitrary divisions
2013-10-17 1:06 ` Christoffer Dall
@ 2013-10-17 10:03 ` Andrew Jones
2013-10-17 18:59 ` Christoffer Dall
0 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-17 10:03 UTC (permalink / raw)
To: Christoffer Dall; +Cc: kvm, kvmarm, gleb
On Wed, Oct 16, 2013 at 06:06:29PM -0700, Christoffer Dall wrote:
> On Mon, Oct 14, 2013 at 06:23:33PM +0200, Andrew Jones wrote:
> > arm can't do arbitrary divisions without software support. Usually
> > libgcc would jump in here, but depending on the toolchain used that may
> > or may not work. Luckily, we only care about two types of divisions.
> > Divide by 10 and divide by 16. Divide by 16 is already covered by gcc
> > since it's a power of two. Divide by 10 can be hacked up using a
> > multiplication and shift.
>
> Isn't this just a matter of supplying a few libc implementations to
> handle div_by_0 and that sort? I'm pretty sure we had that working in
> the kvm-selftest for ARM thingy that allowed you to use the standard '/'
> operator in C code.... I suspect there will be more users of this
> eventually.
>
> Or wait, do you mean 'long long' operations by arbitrary? In that case,
> I'm less sure... A library implementation to support the operator would
> still be preferred IMHO.
No, that's not what I meant, nor can I pretend that's what I meant now :-)
I saw that you had brought lib1funcs.S into kvm-selftest, but I'm not sure
why I rejected doing the same thing... Probably because my reflex was to
not adopt a bunch of assembler that I didn't want to maintain. But I guess
there's nothing to maintain there. It works, and will always work. I'll
switch to using it.
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 8/9] arm: initial drop
2013-10-17 1:06 ` Christoffer Dall
@ 2013-10-17 10:16 ` Andrew Jones
2013-10-17 13:28 ` Andrew Jones
0 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-17 10:16 UTC (permalink / raw)
To: Christoffer Dall; +Cc: kvm, kvmarm, gleb
On Wed, Oct 16, 2013 at 06:06:35PM -0700, Christoffer Dall wrote:
> > diff --git a/arm/boot.c b/arm/boot.c
> > new file mode 100644
> > index 0000000000000..375e8708a7c54
>
> this file's indentation is also funny, you should really check your
> editor configuration :)
Actually the editor prefers kernel style, I had to keep trying to
force the other style on it, and now see below that I wasn't always
successful. '++expected' should have had just a tab, not a
tab+4spaces...
> > --- /dev/null
> > +++ b/arm/boot.c
> > @@ -0,0 +1,27 @@
> > +#include "libcflat.h"
> > +#include "arm/bootinfo.h"
> > +
> > +static bool info_check(u32 var, char *expected)
> > +{
> > + char var_str[9];
> > + snprintf(var_str, 9, "%x", var);
> > + while (*expected == '0' || *expected == 'x')
> > + ++expected;
> > + return !strcmp(var_str, expected);
> > +}
> > +
> > +int main(int argc, char **argv)
> > +{
> > + int ret = 0;
> > +
> > + if (argc < 3) {
> > + printf("Not enough arguments. Can't test\n");
> > + return 1;
> > + }
> > +
> > + if (!strcmp(argv[0], "info"))
> > + ret = !info_check(mem32.size, argv[1])
> > + || !info_check(core.pagesize, argv[2]);
> > +
> > + return ret;
> > +}
>
> I'm actually a little confused, when does this main get invoked and by
> whom and what are we testing for here?
See cstart.S:start 'bl main' below for the who invokes. And
arm/unittests.cfg, also below, for the (poorly documented) test case
definition. You'll see we config the test to have 256G memory, and then
here we confirm that we read the bootinfo correctly, i.e. it says 256G.
There's also a check for pagesize, which isn't really necessary, but as
that info comes from a different ATAG, it (sort of) checks something
else.
>
> > diff --git a/arm/cstart.S b/arm/cstart.S
> > new file mode 100644
> > index 0000000000000..a65809824d4f1
> > --- /dev/null
> > +++ b/arm/cstart.S
> > @@ -0,0 +1,47 @@
> > +
> > +#define CR_B (1 << 7)
> > +
> > +.arm
> > +
> > +.section .init
> > +
> > +.globl start
> > +start:
> > + /* bootloader params are in r0-r2 */
> > + ldr sp, =stacktop
> > + push { r0-r3 } @push r3 too for 8-byte alignment
> > +
> > + mrc p15, 0, r8, c1, c0, 0 @r8 = sctrl
> > + bl get_endianness
> > + bl io_init
> > +
> > + pop { r0-r3 }
> > + bl read_bootinfo
> > + bl __setup_args
> > + ldr r0, =__argc
> > + ldr r0, [r0]
> > + ldr r1, =__argv
> > + bl main
> > + bl exit
> > + b halt
> > +
> > +get_endianness:
> > + and r0, r8, #CR_B
> > + cmp r0, #0
> > + beq 1f
> > + ldr r1, =cpu_is_be
> > + mov r0, #1
> > + str r0, [r1]
> > +1: mov pc, lr
> > +
> > +.text
> > +
> > +.globl halt
> > +halt:
> > +1: wfi
> > + b 1b
> > +
> > +.data
> > +
> > +.globl cpu_is_be
> > +cpu_is_be: .word 0
[snip]
> > diff --git a/arm/unittests.cfg b/arm/unittests.cfg
> > new file mode 100644
> > index 0000000000000..fb78cd906839a
> > --- /dev/null
> > +++ b/arm/unittests.cfg
> > @@ -0,0 +1,11 @@
> > +# Define your new unittest following the convention:
> > +# [unittest_name]
> > +# file = foo.flat # Name of the flat file to be used
> > +# smp = 2 # Number of processors the VM will use during this test
> > +# extra_params = -append <params...> # Additional parameters used
> > +# arch = arm/arm64 # Only if the test case works only on one of them
> > +# groups = group1 group2 # Used to identify test cases with run_tests -g ...
> > +
> > +[boot_info]
> > +file = boot.flat
> > +extra_params = -m 256 -append 'info 0x10000000 0x1000'
> > diff --git a/config/config-arm.mak b/config/config-arm.mak
[snip]
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 9/9] arm: add vectors support
2013-10-17 1:06 ` Christoffer Dall
@ 2013-10-17 10:38 ` Andrew Jones
2013-10-17 18:58 ` Christoffer Dall
0 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-17 10:38 UTC (permalink / raw)
To: Christoffer Dall; +Cc: kvm, kvmarm, gleb
On Wed, Oct 16, 2013 at 06:06:42PM -0700, Christoffer Dall wrote:
> > +++ b/arm/cstart.S
> > @@ -1,5 +1,6 @@
> >
> > #define CR_B (1 << 7)
> > +#define CR_V (1 << 13)
> >
> > .arm
> >
> > @@ -12,6 +13,13 @@ start:
> > push { r0-r3 } @push r3 too for 8-byte alignment
> >
> > mrc p15, 0, r8, c1, c0, 0 @r8 = sctrl
> > +
> > + /* set up vector table */
> > + bic r8, #CR_V @sctrl.V = 0
> > + mcr p15, 0, r8, c1, c0, 0
> > + ldr r0, =vector_table @vbar = vector_table
> > + mcr p15, 0, r0, c12, c0, 0
> > +
> > bl get_endianness
> > bl io_init
> >
> > @@ -41,6 +49,44 @@ halt:
> > 1: wfi
> > b 1b
> >
> > +vector_common:
> > + add r2, sp, #(14 * 4)
>
> this looks weird, what are you pointing to here?
What sp was at the time of exception. So if you look at ex_regs->sp,
then you'll see what sp was when the exception occurred, not that plus
what we're pushing on now for the handler.
>
> > + mrs r3, spsr
> > + push { r0-r3 } @push r0 too for padding
> > + add r0, sp, #4 @skip pad
>
> so you're embedding the exception number into the regs structure?
> That's weird too... Why not have regs be regs at the time of calling
> the exception and then pass that little bit of extra information here?
Just to be somewhat consistent with the way x86 does it. See
lib/x86/desc.h. I imagine there will be developers working on both
arches, and so I want to try to keep some interfaces consistent.
>
> If not, could we at least call the regs structure something like
> ex_info and have named fields on there?
I should have used named fields. I'll switch to that, but I guess
if I want to maintain my consistent naming with x86, then I can't
rename to ex_info...
> > +#define R_IP 12
> > +#define R_SP 13
> > +#define R_LR 14
> > +#define R_SPSR 16
> > +#define __ex_reg(n) \
> > + ((n) == R_SP ? 1 : (n) == R_LR ? 16 : (n) == R_SPSR ? 2 : ((n)+3))
> > +#define ex_reg(regs, n) ((regs)->words[__ex_reg(n)])
> > +#define ex_vector(regs) ((regs)->words[0])
> > +
> > +struct ex_regs {
> > + /* see cstart.S for the register push order */
> > + unsigned long words[18];
> > +};
>
> referring to an assembly file to understand a data structure is not
> super user-friendly. You could also consider being inspired by ptrace.h
> from the kernel here to use a well-known format for this data.
OK, I'm inspired. Actually, inspired enough that I'll just include
ptrace.h I'll use struct pt_regs and forget about consistency with x86.
That means vector will be passed as a separate argument as well.
>
> > +
> > +void handle_exception(u8 v, void (*func)(struct ex_regs *regs));
> > +
> > +#endif
> > diff --git a/lib/libcflat.h b/lib/libcflat.h
> > index dce9a0f516e7e..6ebd903a27f46 100644
> > --- a/lib/libcflat.h
> > +++ b/lib/libcflat.h
> > @@ -68,6 +68,8 @@ extern long atol(const char *ptr);
> >
> > #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
> >
> > +#define __unused __attribute__((__unused__))
> > +
> > #define NULL ((void *)0UL)
> > #include "errno.h"
> > #endif
> > --
> > 1.8.1.4
> >
>
> Looks roughly ok as a first drop, but I would like to reuse a bit more
> familiar names from the kernel for mode definitions etc., and possibly
> copy in the kernel header file for the data structure.
Agreed. ptrace.h will come over.
>
> I'll review the implementation in more depth for v2 when the
> indentations are fixed.
>
> Thanks a lot for working on this and doing the initial legwork here.
Thanks for reviewing.
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 8/9] arm: initial drop
2013-10-17 10:16 ` Andrew Jones
@ 2013-10-17 13:28 ` Andrew Jones
2013-10-17 18:39 ` Christoffer Dall
0 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-17 13:28 UTC (permalink / raw)
To: Christoffer Dall; +Cc: kvm, kvmarm, gleb
On Thu, Oct 17, 2013 at 12:16:18PM +0200, Andrew Jones wrote:
> On Wed, Oct 16, 2013 at 06:06:35PM -0700, Christoffer Dall wrote:
> > > diff --git a/arm/boot.c b/arm/boot.c
> > > new file mode 100644
> > > index 0000000000000..375e8708a7c54
> >
> > this file's indentation is also funny, you should really check your
> > editor configuration :)
>
> Actually the editor prefers kernel style, I had to keep trying to
> force the other style on it, and now see below that I wasn't always
> successful. '++expected' should have had just a tab, not a
> tab+4spaces...
>
> > > --- /dev/null
> > > +++ b/arm/boot.c
> > > @@ -0,0 +1,27 @@
> > > +#include "libcflat.h"
> > > +#include "arm/bootinfo.h"
> > > +
> > > +static bool info_check(u32 var, char *expected)
> > > +{
> > > + char var_str[9];
> > > + snprintf(var_str, 9, "%x", var);
> > > + while (*expected == '0' || *expected == 'x')
> > > + ++expected;
> > > + return !strcmp(var_str, expected);
> > > +}
> > > +
> > > +int main(int argc, char **argv)
> > > +{
> > > + int ret = 0;
> > > +
> > > + if (argc < 3) {
> > > + printf("Not enough arguments. Can't test\n");
> > > + return 1;
> > > + }
> > > +
> > > + if (!strcmp(argv[0], "info"))
> > > + ret = !info_check(mem32.size, argv[1])
> > > + || !info_check(core.pagesize, argv[2]);
> > > +
> > > + return ret;
> > > +}
> >
> > I'm actually a little confused, when does this main get invoked and by
> > whom and what are we testing for here?
>
> See cstart.S:start 'bl main' below for the who invokes. And
> arm/unittests.cfg, also below, for the (poorly documented) test case
> definition. You'll see we config the test to have 256G memory, and then
> here we confirm that we read the bootinfo correctly, i.e. it says 256G.
The above 'G's are of course 'M's. Who remapped my keyboard?
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 8/9] arm: initial drop
2013-10-17 13:28 ` Andrew Jones
@ 2013-10-17 18:39 ` Christoffer Dall
0 siblings, 0 replies; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 18:39 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Thu, Oct 17, 2013 at 03:28:15PM +0200, Andrew Jones wrote:
> On Thu, Oct 17, 2013 at 12:16:18PM +0200, Andrew Jones wrote:
> > On Wed, Oct 16, 2013 at 06:06:35PM -0700, Christoffer Dall wrote:
> > > > diff --git a/arm/boot.c b/arm/boot.c
> > > > new file mode 100644
> > > > index 0000000000000..375e8708a7c54
> > >
> > > this file's indentation is also funny, you should really check your
> > > editor configuration :)
> >
> > Actually the editor prefers kernel style, I had to keep trying to
> > force the other style on it, and now see below that I wasn't always
> > successful. '++expected' should have had just a tab, not a
> > tab+4spaces...
> >
> > > > --- /dev/null
> > > > +++ b/arm/boot.c
> > > > @@ -0,0 +1,27 @@
> > > > +#include "libcflat.h"
> > > > +#include "arm/bootinfo.h"
> > > > +
> > > > +static bool info_check(u32 var, char *expected)
> > > > +{
> > > > + char var_str[9];
> > > > + snprintf(var_str, 9, "%x", var);
> > > > + while (*expected == '0' || *expected == 'x')
> > > > + ++expected;
> > > > + return !strcmp(var_str, expected);
> > > > +}
> > > > +
> > > > +int main(int argc, char **argv)
> > > > +{
> > > > + int ret = 0;
> > > > +
> > > > + if (argc < 3) {
> > > > + printf("Not enough arguments. Can't test\n");
> > > > + return 1;
> > > > + }
> > > > +
> > > > + if (!strcmp(argv[0], "info"))
> > > > + ret = !info_check(mem32.size, argv[1])
> > > > + || !info_check(core.pagesize, argv[2]);
> > > > +
> > > > + return ret;
> > > > +}
> > >
> > > I'm actually a little confused, when does this main get invoked and by
> > > whom and what are we testing for here?
> >
> > See cstart.S:start 'bl main' below for the who invokes. And
> > arm/unittests.cfg, also below, for the (poorly documented) test case
> > definition. You'll see we config the test to have 256G memory, and then
> > here we confirm that we read the bootinfo correctly, i.e. it says 256G.
Thanks.
>
> The above 'G's are of course 'M's. Who remapped my keyboard?
>
That would be one swanky ARM board.
-Chrsitoffer
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 9/9] arm: add vectors support
2013-10-17 10:38 ` Andrew Jones
@ 2013-10-17 18:58 ` Christoffer Dall
2013-10-20 16:35 ` Andrew Jones
0 siblings, 1 reply; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 18:58 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Thu, Oct 17, 2013 at 12:38:59PM +0200, Andrew Jones wrote:
> On Wed, Oct 16, 2013 at 06:06:42PM -0700, Christoffer Dall wrote:
> > > +++ b/arm/cstart.S
> > > @@ -1,5 +1,6 @@
> > >
> > > #define CR_B (1 << 7)
> > > +#define CR_V (1 << 13)
> > >
> > > .arm
> > >
> > > @@ -12,6 +13,13 @@ start:
> > > push { r0-r3 } @push r3 too for 8-byte alignment
> > >
> > > mrc p15, 0, r8, c1, c0, 0 @r8 = sctrl
> > > +
> > > + /* set up vector table */
> > > + bic r8, #CR_V @sctrl.V = 0
> > > + mcr p15, 0, r8, c1, c0, 0
> > > + ldr r0, =vector_table @vbar = vector_table
> > > + mcr p15, 0, r0, c12, c0, 0
> > > +
> > > bl get_endianness
> > > bl io_init
> > >
> > > @@ -41,6 +49,44 @@ halt:
> > > 1: wfi
> > > b 1b
> > >
> > > +vector_common:
> > > + add r2, sp, #(14 * 4)
> >
> > this looks weird, what are you pointing to here?
>
> What sp was at the time of exception. So if you look at ex_regs->sp,
> then you'll see what sp was when the exception occurred, not that plus
> what we're pushing on now for the handler.
>
Hmmm, so you're assuming that all exceptions will be taken from SVC
mode? I assume we will run tests in more than SVC mode, no?
Also note that the lr you're pushing here is not the lr at the time the
exception occurs, but the return address from the exception. If the SVC
instruction is executed from SVC mode, the original lr is lost iirc, and
the caller needs to save it. If you're from user mode, something like
stm sp, {r0-lr}^
will take care of this for you, and if you're from svc
mode, you may want consider doing something like
push {sp, lr}
push {r0-r12}
instead (assuming this is only ever compiled in ARM mode, not Thumb2, in
which case the whole thing gets more complicated.
> >
> > > + mrs r3, spsr
> > > + push { r0-r3 } @push r0 too for padding
> > > + add r0, sp, #4 @skip pad
> >
> > so you're embedding the exception number into the regs structure?
> > That's weird too... Why not have regs be regs at the time of calling
> > the exception and then pass that little bit of extra information here?
>
> Just to be somewhat consistent with the way x86 does it. See
> lib/x86/desc.h. I imagine there will be developers working on both
> arches, and so I want to try to keep some interfaces consistent.
>
I imagine more that ARM guys will be working on this, and x86 guys will
be working on x86, but I guess the future will tell, but it seems you
are leaning to the conclusion as well below...
> >
> > If not, could we at least call the regs structure something like
> > ex_info and have named fields on there?
>
> I should have used named fields. I'll switch to that, but I guess
> if I want to maintain my consistent naming with x86, then I can't
> rename to ex_info...
>
> > > +#define R_IP 12
> > > +#define R_SP 13
> > > +#define R_LR 14
> > > +#define R_SPSR 16
> > > +#define __ex_reg(n) \
> > > + ((n) == R_SP ? 1 : (n) == R_LR ? 16 : (n) == R_SPSR ? 2 : ((n)+3))
> > > +#define ex_reg(regs, n) ((regs)->words[__ex_reg(n)])
> > > +#define ex_vector(regs) ((regs)->words[0])
> > > +
> > > +struct ex_regs {
> > > + /* see cstart.S for the register push order */
> > > + unsigned long words[18];
> > > +};
> >
> > referring to an assembly file to understand a data structure is not
> > super user-friendly. You could also consider being inspired by ptrace.h
> > from the kernel here to use a well-known format for this data.
>
> OK, I'm inspired. Actually, inspired enough that I'll just include
> ptrace.h I'll use struct pt_regs and forget about consistency with x86.
> That means vector will be passed as a separate argument as well.
>
nice! :)
> >
> > > +
> > > +void handle_exception(u8 v, void (*func)(struct ex_regs *regs));
> > > +
> > > +#endif
> > > diff --git a/lib/libcflat.h b/lib/libcflat.h
> > > index dce9a0f516e7e..6ebd903a27f46 100644
> > > --- a/lib/libcflat.h
> > > +++ b/lib/libcflat.h
> > > @@ -68,6 +68,8 @@ extern long atol(const char *ptr);
> > >
> > > #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
> > >
> > > +#define __unused __attribute__((__unused__))
> > > +
> > > #define NULL ((void *)0UL)
> > > #include "errno.h"
> > > #endif
> > > --
> > > 1.8.1.4
> > >
> >
> > Looks roughly ok as a first drop, but I would like to reuse a bit more
> > familiar names from the kernel for mode definitions etc., and possibly
> > copy in the kernel header file for the data structure.
>
> Agreed. ptrace.h will come over.
>
> >
> > I'll review the implementation in more depth for v2 when the
> > indentations are fixed.
> >
> > Thanks a lot for working on this and doing the initial legwork here.
>
> Thanks for reviewing.
>
> drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 7/9] arm: replace arbitrary divisions
2013-10-17 10:03 ` Andrew Jones
@ 2013-10-17 18:59 ` Christoffer Dall
0 siblings, 0 replies; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 18:59 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Thu, Oct 17, 2013 at 12:03:23PM +0200, Andrew Jones wrote:
> On Wed, Oct 16, 2013 at 06:06:29PM -0700, Christoffer Dall wrote:
> > On Mon, Oct 14, 2013 at 06:23:33PM +0200, Andrew Jones wrote:
> > > arm can't do arbitrary divisions without software support. Usually
> > > libgcc would jump in here, but depending on the toolchain used that may
> > > or may not work. Luckily, we only care about two types of divisions.
> > > Divide by 10 and divide by 16. Divide by 16 is already covered by gcc
> > > since it's a power of two. Divide by 10 can be hacked up using a
> > > multiplication and shift.
> >
> > Isn't this just a matter of supplying a few libc implementations to
> > handle div_by_0 and that sort? I'm pretty sure we had that working in
> > the kvm-selftest for ARM thingy that allowed you to use the standard '/'
> > operator in C code.... I suspect there will be more users of this
> > eventually.
> >
> > Or wait, do you mean 'long long' operations by arbitrary? In that case,
> > I'm less sure... A library implementation to support the operator would
> > still be preferred IMHO.
>
> No, that's not what I meant, nor can I pretend that's what I meant now :-)
> I saw that you had brought lib1funcs.S into kvm-selftest, but I'm not sure
> why I rejected doing the same thing... Probably because my reflex was to
> not adopt a bunch of assembler that I didn't want to maintain. But I guess
> there's nothing to maintain there. It works, and will always work. I'll
> switch to using it.
>
I think so, and I'll gladly help you maintain those bits.
-Christoffer
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 6/9] Introduce virtio-testdev
2013-10-17 9:51 ` Andrew Jones
@ 2013-10-17 19:01 ` Christoffer Dall
0 siblings, 0 replies; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 19:01 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Thu, Oct 17, 2013 at 11:51:26AM +0200, Andrew Jones wrote:
> On Wed, Oct 16, 2013 at 06:06:14PM -0700, Christoffer Dall wrote:
> > There's an interesting mix of space and tab indentations in this file...
> >
> > I assume using the kernel coding style would be approprate here...
> > Actually, that could be added to the readme too. (Or whichever format we
> > choose).
> >
> > Could you fix?
>
> I was attempting to adopt the style from the common code lib/*, see
> lib/string.c, lib/printf.c, lib/argv,c. The style used there is
>
> 1. 'four spaces'
> 2. 'tab'
> 3. 'tab + four spaces'
> 4. 'tab + tab'
> ...
that sounds like the most horrible broken coding style I have ever heard
of. At least it reads like sh*t in mutt.
>
> However, I'd actually prefer to use the kernel style as well, and I see
> that not even those three common files are consistent. argv.c only uses
> spaces. Other x86 files also have a variety of styles (kernel style
> being one of them). So probably the best choice is to go with kernel
> style, and to add another cleanup patch that changes lib/* files as
> well.
>
> > > + for (i = 0; i < m->nr; ++i) {
> > > + volatile u32 *base = (u32 *)compat_ptr(m->addrs[i]);
> > > + u32 devid32 = base[VIRTIO_MMIO_DEVICEID / 4];
Yeah, I think it's is by far the easiest and most convenient for
everyone.
> >
> > do we have readl/writel in this framework? If not, maybe we should to
> > indicate IO read/writes and ensure the compiler doesn't reorder things
> > and that we have the necessary memory barriers etc...?
> >
> > That would apply to virtio_testdev above as well.
>
> OK, I agree it makes sense to add readl and writel in. I'll do that, and
> then rework my mmio reads to use them.
>
> > + printf("Refusing to run with virtio-testdev major = %d, minor = %d\n",
> > + major, minor);
>
> > "Refusing to run"?
> > How about "incompatible version of virtio-testdev"?
>
> Sure. OK.
>
> drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 3/9] clean root dir of all x86-ness
2013-10-17 9:35 ` Andrew Jones
@ 2013-10-17 19:01 ` Christoffer Dall
2013-10-20 16:37 ` Andrew Jones
0 siblings, 1 reply; 38+ messages in thread
From: Christoffer Dall @ 2013-10-17 19:01 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Thu, Oct 17, 2013 at 11:35:09AM +0200, Andrew Jones wrote:
> On Wed, Oct 16, 2013 at 06:06:06PM -0700, Christoffer Dall wrote:
> > > -The exit status of the binary (and the script) is inconsistent: with
> > > -qemu-system, after the unittest is done, the exit status of qemu is 1,
> > > -different from the 'old style' qemu-kvm, whose exit status in successful
> > > -completion is 0.
> > > +To create the tests' images do
> >
> > tests' images doesn't read very nice, can we just say test images?
>
> OK
>
> >
> > > + ./configure
> > > + make
> > > +in this directory. Tests' images are created in ./<ARCH>/*.flat
> > > +
> > > +Then use the runner script to detect the correct invocation and
> > > +invoke the test, e.g.
> > > + ./x86-run ./x86/msr.flat
> > > +or
> > > + ./run_tests.sh
> > > +to run them all.
> >
> > While you're at it, it would be great to provide a little more context
> > in the README file.
> >
> > For example, we start talking abouter 'runner scripts', we refer to
> > something called '.flat', and we refer to QEMU without explaining how
> > this whole thing works, what the components are, what is required of
> > QEMU etc.
> >
> > I think that would be useful for the wider adoption of kvm-unit-tests to
> > developers writing ad-hoc patches for KVM.
> >
> > A reference to docs/testdev.txt from somewhere approrpriate in such text
> > would probably also be useful...
> >
> > I know much of this is arch-specific, but there must be something
> > generic or common across the architecture, and that would in essense be
> > capturing what 'kvm-unit-tests' give you, which I think is very useful
> > to have in the readme.
> >
>
> Agreed. I'll see what I can do with the overall documentation. And I need
> to create an arm/README for arm specific documentation as well.
>
We can work on this a bit together as well if you want, I need to get a
slightly broader understanding of this framework first though. Are you
going to be at KVM forum?
-Christoffer
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 9/9] arm: add vectors support
2013-10-17 18:58 ` Christoffer Dall
@ 2013-10-20 16:35 ` Andrew Jones
2013-10-21 9:59 ` Christoffer Dall
0 siblings, 1 reply; 38+ messages in thread
From: Andrew Jones @ 2013-10-20 16:35 UTC (permalink / raw)
To: Christoffer Dall; +Cc: kvm, kvmarm, gleb
On Thu, Oct 17, 2013 at 11:58:43AM -0700, Christoffer Dall wrote:
> On Thu, Oct 17, 2013 at 12:38:59PM +0200, Andrew Jones wrote:
> > On Wed, Oct 16, 2013 at 06:06:42PM -0700, Christoffer Dall wrote:
> > > > +++ b/arm/cstart.S
> > > > @@ -1,5 +1,6 @@
> > > >
> > > > #define CR_B (1 << 7)
> > > > +#define CR_V (1 << 13)
> > > >
> > > > .arm
> > > >
> > > > @@ -12,6 +13,13 @@ start:
> > > > push { r0-r3 } @push r3 too for 8-byte alignment
> > > >
> > > > mrc p15, 0, r8, c1, c0, 0 @r8 = sctrl
> > > > +
> > > > + /* set up vector table */
> > > > + bic r8, #CR_V @sctrl.V = 0
> > > > + mcr p15, 0, r8, c1, c0, 0
> > > > + ldr r0, =vector_table @vbar = vector_table
> > > > + mcr p15, 0, r0, c12, c0, 0
> > > > +
> > > > bl get_endianness
> > > > bl io_init
> > > >
> > > > @@ -41,6 +49,44 @@ halt:
> > > > 1: wfi
> > > > b 1b
> > > >
> > > > +vector_common:
> > > > + add r2, sp, #(14 * 4)
> > >
> > > this looks weird, what are you pointing to here?
> >
> > What sp was at the time of exception. So if you look at ex_regs->sp,
> > then you'll see what sp was when the exception occurred, not that plus
> > what we're pushing on now for the handler.
> >
>
> Hmmm, so you're assuming that all exceptions will be taken from SVC
> mode? I assume we will run tests in more than SVC mode, no?
>
> Also note that the lr you're pushing here is not the lr at the time the
> exception occurs, but the return address from the exception. If the SVC
> instruction is executed from SVC mode, the original lr is lost iirc, and
> the caller needs to save it. If you're from user mode, something like
>
> stm sp, {r0-lr}^
>
> will take care of this for you, and if you're from svc
> mode, you may want consider doing something like
>
> push {sp, lr}
> push {r0-r12}
>
> instead (assuming this is only ever compiled in ARM mode, not Thumb2, in
> which case the whole thing gets more complicated.
I think the lr pushing should be ok. That part is done in the macro that
all vectors start with. It got snipped from this mail, so here it is
.macro m_vector, v
push { r0-r12,lr }
mov r1, \v
b vector_common
.endm
I realize it may still not be correct, just as the calculated sp
may not be correct, depending on which mode,vector combo is used,
but I was expecting to have different paths in the C code for
fixing it up. Although that said, I haven't thought about it a
bunch yet, so maybe it won't work that way...
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 3/9] clean root dir of all x86-ness
2013-10-17 19:01 ` Christoffer Dall
@ 2013-10-20 16:37 ` Andrew Jones
0 siblings, 0 replies; 38+ messages in thread
From: Andrew Jones @ 2013-10-20 16:37 UTC (permalink / raw)
To: Christoffer Dall; +Cc: kvm, kvmarm, gleb
On Thu, Oct 17, 2013 at 12:01:52PM -0700, Christoffer Dall wrote:
> On Thu, Oct 17, 2013 at 11:35:09AM +0200, Andrew Jones wrote:
> > On Wed, Oct 16, 2013 at 06:06:06PM -0700, Christoffer Dall wrote:
> > > > -The exit status of the binary (and the script) is inconsistent: with
> > > > -qemu-system, after the unittest is done, the exit status of qemu is 1,
> > > > -different from the 'old style' qemu-kvm, whose exit status in successful
> > > > -completion is 0.
> > > > +To create the tests' images do
> > >
> > > tests' images doesn't read very nice, can we just say test images?
> >
> > OK
> >
> > >
> > > > + ./configure
> > > > + make
> > > > +in this directory. Tests' images are created in ./<ARCH>/*.flat
> > > > +
> > > > +Then use the runner script to detect the correct invocation and
> > > > +invoke the test, e.g.
> > > > + ./x86-run ./x86/msr.flat
> > > > +or
> > > > + ./run_tests.sh
> > > > +to run them all.
> > >
> > > While you're at it, it would be great to provide a little more context
> > > in the README file.
> > >
> > > For example, we start talking abouter 'runner scripts', we refer to
> > > something called '.flat', and we refer to QEMU without explaining how
> > > this whole thing works, what the components are, what is required of
> > > QEMU etc.
> > >
> > > I think that would be useful for the wider adoption of kvm-unit-tests to
> > > developers writing ad-hoc patches for KVM.
> > >
> > > A reference to docs/testdev.txt from somewhere approrpriate in such text
> > > would probably also be useful...
> > >
> > > I know much of this is arch-specific, but there must be something
> > > generic or common across the architecture, and that would in essense be
> > > capturing what 'kvm-unit-tests' give you, which I think is very useful
> > > to have in the readme.
> > >
> >
> > Agreed. I'll see what I can do with the overall documentation. And I need
> > to create an arm/README for arm specific documentation as well.
> >
> We can work on this a bit together as well if you want, I need to get a
> slightly broader understanding of this framework first though. Are you
> going to be at KVM forum?
>
Yup. Already here :-)
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 9/9] arm: add vectors support
2013-10-20 16:35 ` Andrew Jones
@ 2013-10-21 9:59 ` Christoffer Dall
0 siblings, 0 replies; 38+ messages in thread
From: Christoffer Dall @ 2013-10-21 9:59 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Sun, Oct 20, 2013 at 06:35:34PM +0200, Andrew Jones wrote:
> On Thu, Oct 17, 2013 at 11:58:43AM -0700, Christoffer Dall wrote:
> > On Thu, Oct 17, 2013 at 12:38:59PM +0200, Andrew Jones wrote:
> > > On Wed, Oct 16, 2013 at 06:06:42PM -0700, Christoffer Dall wrote:
> > > > > +++ b/arm/cstart.S
> > > > > @@ -1,5 +1,6 @@
> > > > >
> > > > > #define CR_B (1 << 7)
> > > > > +#define CR_V (1 << 13)
> > > > >
> > > > > .arm
> > > > >
> > > > > @@ -12,6 +13,13 @@ start:
> > > > > push { r0-r3 } @push r3 too for 8-byte alignment
> > > > >
> > > > > mrc p15, 0, r8, c1, c0, 0 @r8 = sctrl
> > > > > +
> > > > > + /* set up vector table */
> > > > > + bic r8, #CR_V @sctrl.V = 0
> > > > > + mcr p15, 0, r8, c1, c0, 0
> > > > > + ldr r0, =vector_table @vbar = vector_table
> > > > > + mcr p15, 0, r0, c12, c0, 0
> > > > > +
> > > > > bl get_endianness
> > > > > bl io_init
> > > > >
> > > > > @@ -41,6 +49,44 @@ halt:
> > > > > 1: wfi
> > > > > b 1b
> > > > >
> > > > > +vector_common:
> > > > > + add r2, sp, #(14 * 4)
> > > >
> > > > this looks weird, what are you pointing to here?
> > >
> > > What sp was at the time of exception. So if you look at ex_regs->sp,
> > > then you'll see what sp was when the exception occurred, not that plus
> > > what we're pushing on now for the handler.
> > >
> >
> > Hmmm, so you're assuming that all exceptions will be taken from SVC
> > mode? I assume we will run tests in more than SVC mode, no?
> >
> > Also note that the lr you're pushing here is not the lr at the time the
> > exception occurs, but the return address from the exception. If the SVC
> > instruction is executed from SVC mode, the original lr is lost iirc, and
> > the caller needs to save it. If you're from user mode, something like
> >
> > stm sp, {r0-lr}^
> >
> > will take care of this for you, and if you're from svc
> > mode, you may want consider doing something like
> >
> > push {sp, lr}
> > push {r0-r12}
> >
> > instead (assuming this is only ever compiled in ARM mode, not Thumb2, in
> > which case the whole thing gets more complicated.
>
> I think the lr pushing should be ok. That part is done in the macro that
> all vectors start with. It got snipped from this mail, so here it is
>
> .macro m_vector, v
> push { r0-r12,lr }
> mov r1, \v
> b vector_common
> .endm
You push this lr after taking the exception, so the lr will point to the
instruction following the trap instruction itself; if your convention is
that the regs struct is the lr as it was when the trap was generated,
well then, things don't match. If the exception is taken from SVC mode,
I'm not sure there's a proper way to get this information though, so it
really depends on how you imagine this to be used...
>
> I realize it may still not be correct, just as the calculated sp
> may not be correct, depending on which mode,vector combo is used,
> but I was expecting to have different paths in the C code for
> fixing it up. Although that said, I haven't thought about it a
> bunch yet, so maybe it won't work that way...
>
I think it may be worth taking an extra look at how the kernel handles
all this and somewhat replicate some of what we're doing, but again, it
depends on what the goal here is.
The SP calculation is probably correct, but it's error-prone and bound
to confuse people IMHO, but it's up to you at this point.
-Christoffer
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 0/9] kvm-unit-tests/arm: initial drop
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
` (8 preceding siblings ...)
2013-10-14 16:23 ` [PATCH 9/9] arm: add vectors support Andrew Jones
@ 2013-11-20 23:06 ` María Soler Heredia
2013-11-26 17:23 ` Andrew Jones
2013-12-29 9:24 ` Christoffer Dall
10 siblings, 1 reply; 38+ messages in thread
From: María Soler Heredia @ 2013-11-20 23:06 UTC (permalink / raw)
To: kvm
Andrew Jones <drjones <at> redhat.com> writes:
> This series introduces arm to kvm-unit-tests.
> To use this you need an arm platform or simulator capable
> of running kvmarm and a qemu with the mach-virt patches[2], as
> well as the previously mentioned virtio-testdev.
Hello,
I have been playing with your tests for a while and I cannot seem to get
them to work all right. When I run them disabling kvm on the arm-run script,
they do work, but when I run them with kvm enabled they fail.
This is my output:
./arm-run arm/boot.flat -smp 1 -m 256 -append 'info 0x10000000 0x1000'
qemu-system-arm -device virtio-testdev -display none -serial stdio -M virt
-cpu cortex-a15 -enable-kvm -kernel arm/boot.flat -smp 1 -m 256 -append info
0x10000000 0x1000
kvm [1252]: load/store instruction decoding not implemented
error: kvm run failed Function not implemented
./arm-run: line 16: 1251 Aborted $command "$@"
Return value from qemu: 134
FAIL boot_info
./arm-run arm/boot.flat -smp 1 -append 'vectors'
qemu-system-arm -device virtio-testdev -display none -serial stdio -M virt
-cpu cortex-a15 -enable-kvm -kernel arm/boot.flat -smp 1 -append vectors
kvm [1257]: load/store instruction decoding not implemented
error: kvm run failed Function not implemented
./arm-run: line 16: 1256 Aborted $command "$@"
Return value from qemu: 134
FAIL boot_vectors
I am using FastModels Model Debugger version 8.2.028, with a model of this
characteristics:
Model:
------
Model name: ARM_Cortex-A15
Instance: cluster.cpu0
Using CADI 2.0 interface revision 0.
Version: 8.2.72
Generated by Core Generator: No
Needs SimGen License: No
running the latest stable linux release and qemu-devel's latest qemu with
the patches indicated here
https://lists.gnu.org/archive/html/qemu-devel/2013-10/msg02428.html plus
> [1] http://lists.nongnu.org/archive/html/qemu-devel/2013-10/msg01815.html
I tested the instalation by running a linux with the same setup using this call:
qemu-system-arm \
-display none \
-enable-kvm \
-kernel zImage\
-m 128 -M virt -cpu cortex-a15 \
-drive if=none,file=linux.img,id=fs \
-device virtio-blk-device,drive=fs
As I said, the tests pass if the kvm is not enabled and fail otherwise. I
have added a few printfs for debugging and I can tell that the code in
boot.c runs ok, but then when virtio_testdev is called (from
virtio_testdev_exit) the execution throws an exception (more specifically
the line *tdp++ = cpu_to_le32(va_arg(va, unsigned)); inside the first while.
I am not used to sending emails to this kind of list, so I don't know if I
am being too specific, too little or maybe not even giving the right
information. Please tell me what else you need and if you can help me solve
this problem.
Thank you very much,
María.
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 0/9] kvm-unit-tests/arm: initial drop
2013-11-20 23:06 ` [PATCH 0/9] kvm-unit-tests/arm: initial drop María Soler Heredia
@ 2013-11-26 17:23 ` Andrew Jones
0 siblings, 0 replies; 38+ messages in thread
From: Andrew Jones @ 2013-11-26 17:23 UTC (permalink / raw)
To: María Soler Heredia; +Cc: kvm, kvmarm
Sorry, just noticed this - you dropped me and the kvmarm list
from your reply.
On Wed, Nov 20, 2013 at 11:06:11PM +0000, María Soler Heredia wrote:
> Andrew Jones <drjones <at> redhat.com> writes:
>
>
> > This series introduces arm to kvm-unit-tests.
>
> > To use this you need an arm platform or simulator capable
> > of running kvmarm and a qemu with the mach-virt patches[2], as
> > well as the previously mentioned virtio-testdev.
>
> Hello,
>
> I have been playing with your tests for a while and I cannot seem to get
> them to work all right. When I run them disabling kvm on the arm-run script,
> they do work, but when I run them with kvm enabled they fail.
>
> This is my output:
>
> ./arm-run arm/boot.flat -smp 1 -m 256 -append 'info 0x10000000 0x1000'
> qemu-system-arm -device virtio-testdev -display none -serial stdio -M virt
> -cpu cortex-a15 -enable-kvm -kernel arm/boot.flat -smp 1 -m 256 -append info
> 0x10000000 0x1000
> kvm [1252]: load/store instruction decoding not implemented
> error: kvm run failed Function not implemented
The above errors come from the kernel and qemu. It's easy to see under
what condition you would hit them, but it's not clear to me why that
condition is present for you.
> ./arm-run: line 16: 1251 Aborted $command "$@"
> Return value from qemu: 134
> FAIL boot_info
> ./arm-run arm/boot.flat -smp 1 -append 'vectors'
> qemu-system-arm -device virtio-testdev -display none -serial stdio -M virt
> -cpu cortex-a15 -enable-kvm -kernel arm/boot.flat -smp 1 -append vectors
> kvm [1257]: load/store instruction decoding not implemented
> error: kvm run failed Function not implemented
> ./arm-run: line 16: 1256 Aborted $command "$@"
> Return value from qemu: 134
> FAIL boot_vectors
>
> I am using FastModels Model Debugger version 8.2.028, with a model of this
> characteristics:
>
> Model:
> ------
> Model name: ARM_Cortex-A15
> Instance: cluster.cpu0
> Using CADI 2.0 interface revision 0.
> Version: 8.2.72
> Generated by Core Generator: No
> Needs SimGen License: No
So far I've only tested on real hardware. So this could be the difference.
>
> running the latest stable linux release and qemu-devel's latest qemu with
> the patches indicated here
> https://lists.gnu.org/archive/html/qemu-devel/2013-10/msg02428.html plus
> > [1] http://lists.nongnu.org/archive/html/qemu-devel/2013-10/msg01815.html
>
> I tested the instalation by running a linux with the same setup using this call:
> qemu-system-arm \
> -display none \
> -enable-kvm \
> -kernel zImage\
> -m 128 -M virt -cpu cortex-a15 \
> -drive if=none,file=linux.img,id=fs \
> -device virtio-blk-device,drive=fs
>
> As I said, the tests pass if the kvm is not enabled and fail otherwise. I
> have added a few printfs for debugging and I can tell that the code in
> boot.c runs ok, but then when virtio_testdev is called (from
> virtio_testdev_exit) the execution throws an exception (more specifically
> the line *tdp++ = cpu_to_le32(va_arg(va, unsigned)); inside the first while.
Hmm, even more confusing, as this isn't the first mmio access.
>
> I am not used to sending emails to this kind of list, so I don't know if I
> am being too specific, too little or maybe not even giving the right
> information. Please tell me what else you need and if you can help me solve
> this problem.
Your details are good, but instead of just stating 'latest' for your
kernel and qemu versions, please give the exact version numbers.
I've been busy with other things lately, but I'm due to post a v2 of
this series. I should be able to finish that off this week. When I do,
I'll see if I can test it over FastModel as well this time.
Thanks for starting to poke at this!
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 0/9] kvm-unit-tests/arm: initial drop
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
` (9 preceding siblings ...)
2013-11-20 23:06 ` [PATCH 0/9] kvm-unit-tests/arm: initial drop María Soler Heredia
@ 2013-12-29 9:24 ` Christoffer Dall
2014-01-02 18:56 ` Andrew Jones
10 siblings, 1 reply; 38+ messages in thread
From: Christoffer Dall @ 2013-12-29 9:24 UTC (permalink / raw)
To: Andrew Jones; +Cc: kvm, kvmarm, gleb
On Mon, Oct 14, 2013 at 06:23:26PM +0200, Andrew Jones wrote:
Hi Drew,
> This series introduces arm to kvm-unit-tests. First, it does some
> tidying up of the repo. Then, it adds support for virtio-testdev,
> which was just posted to qemu-devel[1]. Next, it adds the basic
> infrastructure for booting a test case (guest). Finally, it adds
> support for vectors. This is just an initial drop, I'm starting
> work on smp support now, and then will bring in support for
> arm64. At that point we should be able to start actually adding
> tests. To use this you need an arm platform or simulator capable
> of running kvmarm and a qemu with the mach-virt patches[2], as
> well as the previously mentioned virtio-testdev.
>
> [1] http://lists.nongnu.org/archive/html/qemu-devel/2013-10/msg01815.html
> [2] http://lists.nongnu.org/archive/html/qemu-devel/2013-09/msg02142.html
>
> This patches are also available from a git repo here
> https://github.com/rhdrjones/kvm-unit-tests/tree/arm-branch/master
>
I'm playing around with this, thanks again for working on it. It's long
overdue that we're getting something real done in this area.
I have run into some problems trying to run this thing on real hardware.
The biggest problem is the known cache coherency issue where we need to
flush the data cache to make things coherent when the guest runs with
the MMU disabled. It shows up quite frequently if you just try to run
the small flat binaries with KVM, and I suspec the only reason we are
not seeing this with real kernels is that they are large enough that we
end up writing the necessary data all the way to main memory.
I'm working on a vmexit test to measure stuff, and I noticed that we:
- really need to find a way to let a guest read the cycle counter
- need a way to let a call a dummy HVC to KVM to measure round-trip
times
- ...
This is probably something we should try to discuss on one of the next
kvm/arm sync-up calls. I remember something about you not being able to
make those, but we can arrange a different time for one of them some
time.
For now, I can work around the cache issue by enabling the DC bits and
by adding a terrible hack for the cycle counter and dummy HVC. You can
follow my hackings here:
Kernel:
https://git.linaro.org/people/christoffer.dall/linux-kvm-arm.git/shortlog/refs/heads/kvm-arm-next-measure
unit-tests:
https://github.com/columbia/kvm-unit-tests/tree/arm-support
-Christoffer
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 0/9] kvm-unit-tests/arm: initial drop
2013-12-29 9:24 ` Christoffer Dall
@ 2014-01-02 18:56 ` Andrew Jones
0 siblings, 0 replies; 38+ messages in thread
From: Andrew Jones @ 2014-01-02 18:56 UTC (permalink / raw)
To: Christoffer Dall; +Cc: kvm, kvmarm, gleb
On Sun, Dec 29, 2013 at 01:24:11AM -0800, Christoffer Dall wrote:
> On Mon, Oct 14, 2013 at 06:23:26PM +0200, Andrew Jones wrote:
>
> Hi Drew,
>
> > This series introduces arm to kvm-unit-tests. First, it does some
> > tidying up of the repo. Then, it adds support for virtio-testdev,
> > which was just posted to qemu-devel[1]. Next, it adds the basic
> > infrastructure for booting a test case (guest). Finally, it adds
> > support for vectors. This is just an initial drop, I'm starting
> > work on smp support now, and then will bring in support for
> > arm64. At that point we should be able to start actually adding
> > tests. To use this you need an arm platform or simulator capable
> > of running kvmarm and a qemu with the mach-virt patches[2], as
> > well as the previously mentioned virtio-testdev.
> >
> > [1] http://lists.nongnu.org/archive/html/qemu-devel/2013-10/msg01815.html
> > [2] http://lists.nongnu.org/archive/html/qemu-devel/2013-09/msg02142.html
> >
> > This patches are also available from a git repo here
> > https://github.com/rhdrjones/kvm-unit-tests/tree/arm-branch/master
> >
>
> I'm playing around with this, thanks again for working on it. It's long
> overdue that we're getting something real done in this area.
>
> I have run into some problems trying to run this thing on real hardware.
> The biggest problem is the known cache coherency issue where we need to
> flush the data cache to make things coherent when the guest runs with
> the MMU disabled. It shows up quite frequently if you just try to run
> the small flat binaries with KVM, and I suspec the only reason we are
> not seeing this with real kernels is that they are large enough that we
> end up writing the necessary data all the way to main memory.
>
> I'm working on a vmexit test to measure stuff, and I noticed that we:
> - really need to find a way to let a guest read the cycle counter
> - need a way to let a call a dummy HVC to KVM to measure round-trip
> times
> - ...
>
> This is probably something we should try to discuss on one of the next
> kvm/arm sync-up calls. I remember something about you not being able to
> make those, but we can arrange a different time for one of them some
> time.
>
> For now, I can work around the cache issue by enabling the DC bits and
> by adding a terrible hack for the cycle counter and dummy HVC. You can
> follow my hackings here:
>
> Kernel:
> https://git.linaro.org/people/christoffer.dall/linux-kvm-arm.git/shortlog/refs/heads/kvm-arm-next-measure
>
> unit-tests:
> https://github.com/columbia/kvm-unit-tests/tree/arm-support
>
> -Christoffer
Thanks Christoffer! I'll look at these branches tomorrow. I'm glad we're
getting some momentum on kvm-unit-tests/arm!
drew
^ permalink raw reply [flat|nested] 38+ messages in thread
end of thread, other threads:[~2014-01-02 18:56 UTC | newest]
Thread overview: 38+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
2013-10-14 16:23 ` [PATCH 1/9] remove unused files Andrew Jones
2013-10-16 12:52 ` Gleb Natapov
2013-10-16 13:13 ` Alexander Graf
2013-10-16 13:18 ` Andrew Jones
2013-10-14 16:23 ` [PATCH 2/9] makefile and run_tests tweaks Andrew Jones
2013-10-14 16:23 ` [PATCH 3/9] clean root dir of all x86-ness Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-17 9:35 ` Andrew Jones
2013-10-17 19:01 ` Christoffer Dall
2013-10-20 16:37 ` Andrew Jones
2013-10-14 16:23 ` [PATCH 4/9] Introduce a simple iomap structure Andrew Jones
2013-10-14 16:23 ` [PATCH 5/9] Add halt() and some error codes Andrew Jones
2013-10-14 16:23 ` [PATCH 6/9] Introduce virtio-testdev Andrew Jones
2013-10-15 8:39 ` Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-17 9:51 ` Andrew Jones
2013-10-17 19:01 ` Christoffer Dall
2013-10-17 1:06 ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 7/9] arm: replace arbitrary divisions Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-17 10:03 ` Andrew Jones
2013-10-17 18:59 ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 8/9] arm: initial drop Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-17 10:16 ` Andrew Jones
2013-10-17 13:28 ` Andrew Jones
2013-10-17 18:39 ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 9/9] arm: add vectors support Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-17 10:38 ` Andrew Jones
2013-10-17 18:58 ` Christoffer Dall
2013-10-20 16:35 ` Andrew Jones
2013-10-21 9:59 ` Christoffer Dall
2013-11-20 23:06 ` [PATCH 0/9] kvm-unit-tests/arm: initial drop María Soler Heredia
2013-11-26 17:23 ` Andrew Jones
2013-12-29 9:24 ` Christoffer Dall
2014-01-02 18:56 ` Andrew Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).