All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/19] kvm-unit-tests/arm: initial drop
@ 2014-06-11 14:01 Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 01/19] remove unused files Andrew Jones
                   ` (20 more replies)
  0 siblings, 21 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

This is a v5 of a series that introduces arm to kvm-unit-tests. First,
it does some tidying up of the repo. Then, it adds support for device
trees (libfdt), and for virtio-testdev[1]. Next, it adds the basic
infrastructure for booting a test case (guest), and adds a first
test case, a self-test to confirm setup was completed successfully.
Finally, it further prepares the framework for more complicated tests
by adding vector support, and extends the self-test to test that too.

This initial drop doesn't require kvmarm. qemu-system-arm is enough,
but it must have mach-virt, and the virtio-testdev patch[1].

These patches (v5) are also available from a git repo here
https://github.com/rhdrjones/kvm-unit-tests/commits/arm/v5-initial-drop

The v4 patches are available for reference here
https://github.com/rhdrjones/kvm-unit-tests/commits/arm/v4-initial-drop

Not too much has changed since v4. There are no new patches nor dropped
patches, and all patches that did get a change have a v5 note. To see
a branch interdiff (created with git-tbdiff[2]) take a look here[3].

Thanks in advance for reviews!

[1] http://lists.nongnu.org/archive/html/qemu-devel/2013-12/msg00690.html
[2] https://github.com/trast/tbdiff
[3] http://fpaste.org/108932/14024949/

Andrew Jones (17):
  remove unused files
  makefile and run_tests tweaks
  clean root dir of all x86-ness
  add distclean target and gitignore more
  add 'make cscope' support
  libfdt: Import libfdt source
  libfdt: get libfdt to build
  add support for Linux device trees
  libcflat: add abort() and assert()
  Introduce asm-generic/*.h files
  add minimal virtio support for devtree virtio-mmio
  Introduce virtio-testdev
  libcflat: clean up libcflat.h and add string.h
  printf: support field padding
  arm: initial drop
  arm: add useful headers from the Linux kernel
  arm: vectors support

Christoffer Dall (2):
  arm: Add spinlock implementation
  arm: Add IO accessors to avoid register-writeback

 .gitignore                   |    6 +
 Makefile                     |   55 +-
 README                       |   59 +-
 arm/cstart.S                 |  209 ++++++
 arm/flat.lds                 |   23 +
 arm/run                      |   35 +
 arm/selftest.c               |  209 ++++++
 arm/unittests.cfg            |   30 +
 config-i386.mak              |   13 -
 config-ia64.mak              |    7 -
 config-powerpc-440.mak       |   15 -
 config-powerpc.mak           |   39 --
 config-x86-common.mak        |  126 ----
 config-x86_64.mak            |   14 -
 config/asm-offsets.mak       |   41 ++
 config/config-arm.mak        |   79 +++
 config/config-i386.mak       |   12 +
 config/config-x86-common.mak |  124 ++++
 config/config-x86_64.mak     |   13 +
 configure                    |   40 +-
 docs/testdev.txt             |   13 +
 flat.lds                     |   21 -
 formats                      |   31 -
 iotable.c                    |   53 --
 iotable.h                    |   40 --
 kvmtrace.c                   |  706 --------------------
 kvmtrace_format              |  532 ---------------
 lib/argv.c                   |    6 +
 lib/arm/.gitignore           |    1 +
 lib/arm/asm-offsets.c        |   39 ++
 lib/arm/asm/asm-offsets.h    |    1 +
 lib/arm/asm/barrier.h        |   18 +
 lib/arm/asm/cp15.h           |   37 ++
 lib/arm/asm/io.h             |   81 +++
 lib/arm/asm/processor.h      |   40 ++
 lib/arm/asm/ptrace.h         |  100 +++
 lib/arm/asm/setup.h          |   63 ++
 lib/arm/asm/spinlock.h       |   11 +
 lib/arm/eabi_compat.c        |   20 +
 lib/arm/io.c                 |   65 ++
 lib/arm/processor.c          |  115 ++++
 lib/arm/setup.c              |  149 +++++
 lib/arm/spinlock.c           |   28 +
 lib/asm-generic/io.h         |  162 +++++
 lib/asm-generic/spinlock.h   |    4 +
 lib/devicetree.c             |  272 ++++++++
 lib/devicetree.h             |  236 +++++++
 lib/fwcfg.c                  |   58 --
 lib/generated/.gitignore     |    1 +
 lib/libcflat.h               |   58 +-
 lib/libfdt/Makefile.libfdt   |   10 +
 lib/libfdt/README            |    4 +
 lib/libfdt/fdt.c             |  250 +++++++
 lib/libfdt/fdt.h             |  111 ++++
 lib/libfdt/fdt_empty_tree.c  |   84 +++
 lib/libfdt/fdt_ro.c          |  573 ++++++++++++++++
 lib/libfdt/fdt_rw.c          |  492 ++++++++++++++
 lib/libfdt/fdt_strerror.c    |   96 +++
 lib/libfdt/fdt_sw.c          |  256 +++++++
 lib/libfdt/fdt_wip.c         |  118 ++++
 lib/libfdt/libfdt.h          | 1514 ++++++++++++++++++++++++++++++++++++++++++
 lib/libfdt/libfdt_env.h      |  111 ++++
 lib/libfdt/libfdt_internal.h |   95 +++
 lib/libfdt/version.lds       |   60 ++
 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                 |   82 ++-
 lib/string.c                 |   54 ++
 lib/string.h                 |   15 +
 lib/virtio-testdev.c         |  137 ++++
 lib/virtio-testdev.h         |   18 +
 lib/virtio.c                 |  165 +++++
 lib/virtio.h                 |   89 +++
 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                 |   22 +-
 testdev.txt                  |   14 -
 x86-run                      |   41 --
 x86/README                   |   59 +-
 x86/flat.lds                 |   21 +
 x86/print.h                  |   19 -
 x86/run                      |   41 ++
 x86/run-kvm-unit-tests       |    6 -
 96 files changed, 6814 insertions(+), 2670 deletions(-)
 create mode 100644 arm/cstart.S
 create mode 100644 arm/flat.lds
 create mode 100755 arm/run
 create mode 100644 arm/selftest.c
 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/asm-offsets.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/.gitignore
 create mode 100644 lib/arm/asm-offsets.c
 create mode 100644 lib/arm/asm/asm-offsets.h
 create mode 100644 lib/arm/asm/barrier.h
 create mode 100644 lib/arm/asm/cp15.h
 create mode 100644 lib/arm/asm/io.h
 create mode 100644 lib/arm/asm/processor.h
 create mode 100644 lib/arm/asm/ptrace.h
 create mode 100644 lib/arm/asm/setup.h
 create mode 100644 lib/arm/asm/spinlock.h
 create mode 100644 lib/arm/eabi_compat.c
 create mode 100644 lib/arm/io.c
 create mode 100644 lib/arm/processor.c
 create mode 100644 lib/arm/setup.c
 create mode 100644 lib/arm/spinlock.c
 create mode 100644 lib/asm-generic/io.h
 create mode 100644 lib/asm-generic/spinlock.h
 create mode 100644 lib/devicetree.c
 create mode 100644 lib/devicetree.h
 delete mode 100644 lib/fwcfg.c
 create mode 100644 lib/generated/.gitignore
 create mode 100644 lib/libfdt/Makefile.libfdt
 create mode 100644 lib/libfdt/README
 create mode 100644 lib/libfdt/fdt.c
 create mode 100644 lib/libfdt/fdt.h
 create mode 100644 lib/libfdt/fdt_empty_tree.c
 create mode 100644 lib/libfdt/fdt_ro.c
 create mode 100644 lib/libfdt/fdt_rw.c
 create mode 100644 lib/libfdt/fdt_strerror.c
 create mode 100644 lib/libfdt/fdt_sw.c
 create mode 100644 lib/libfdt/fdt_wip.c
 create mode 100644 lib/libfdt/libfdt.h
 create mode 100644 lib/libfdt/libfdt_env.h
 create mode 100644 lib/libfdt/libfdt_internal.h
 create mode 100644 lib/libfdt/version.lds
 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/string.h
 create mode 100644 lib/virtio-testdev.c
 create mode 100644 lib/virtio-testdev.h
 create mode 100644 lib/virtio.c
 create mode 100644 lib/virtio.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
 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.9.3


^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH v5 01/19] remove unused files
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 02/19] makefile and run_tests tweaks Andrew Jones
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

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>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 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 f5eccc77047a7..444b6531b8836 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 \
 	lib/report.o
@@ -40,11 +39,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 $@ $^
 
@@ -58,4 +52,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 3dc378856c83d..cb6663d33ef5a 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -41,7 +41,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, &regs);
-	regs.pc = VM_TEST_LOAD_ADDRESS;
-	kvm_set_regs(kvm, n, &regs);
-
-	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.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 02/19] makefile and run_tests tweaks
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 01/19] remove unused files Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 03/19] clean root dir of all x86-ness Andrew Jones
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

- 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>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
v4: no change other than rebase
v3: reword run_tests.sh help text [Christoffer Dall]
---
 Makefile              | 11 ++++++-----
 config-x86-common.mak | 16 +++++++---------
 run_tests.sh          |  6 +++---
 3 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/Makefile b/Makefile
index 444b6531b8836..17307d1dfd760 100644
--- a/Makefile
+++ b/Makefile
@@ -6,16 +6,16 @@ DESTDIR := $(PREFIX)/share/qemu/tests
 .PHONY: arch_clean clean
 
 #make sure env CFLAGS variable is not used
-CFLAGS = -g
+CFLAGS =
 
 libgcc := $(shell $(CC) --print-libgcc-file-name)
 
 libcflat := lib/libcflat.a
 cflatobjs := \
+	lib/argv.o \
 	lib/printf.o \
 	lib/string.o \
 	lib/report.o
-cflatobjs += lib/argv.o
 
 #include architecure specific make rules
 include config-$(ARCH).mak
@@ -26,8 +26,9 @@ 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 += -g
+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.
@@ -52,4 +53,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 93c9fee875085..84cce7065d400 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 \
@@ -109,7 +107,7 @@ $(TEST_DIR)/debug.elf: $(cstart.o) $(TEST_DIR)/debug.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..b077091da18b3 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
@@ -92,8 +92,8 @@ 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-x86_64 to
+specify the appropriate qemu binary for x86-run.
 
 EOF
 }
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 03/19] clean root dir of all x86-ness
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 01/19] remove unused files Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 02/19] makefile and run_tests tweaks Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-12 10:31   ` Paolo Bonzini
  2014-06-11 14:01 ` [PATCH v5 04/19] add distclean target and gitignore more Andrew Jones
                   ` (17 subsequent siblings)
  20 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

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>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
v4: some more doc touch-ups, check for config.mak in run_tests.sh
---
 Makefile                     |   7 ++-
 README                       |  59 ++++++++------------
 config-i386.mak              |  13 -----
 config-x86-common.mak        | 124 -------------------------------------------
 config-x86_64.mak            |  14 -----
 config/config-i386.mak       |  12 +++++
 config/config-x86-common.mak | 124 +++++++++++++++++++++++++++++++++++++++++++
 config/config-x86_64.mak     |  13 +++++
 configure                    |  17 ++++++
 docs/testdev.txt             |  13 +++++
 flat.lds                     |  21 --------
 run_tests.sh                 |  22 ++++----
 testdev.txt                  |  14 -----
 x86-run                      |  41 --------------
 x86/README                   |  59 +++++++++++++++-----
 x86/flat.lds                 |  21 ++++++++
 x86/run                      |  41 ++++++++++++++
 17 files changed, 324 insertions(+), 291 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 17307d1dfd760..566d2bee771e1 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@ cflatobjs := \
 	lib/report.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)
@@ -31,7 +31,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)
 
@@ -46,11 +45,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 0f5d810738de7..e9869d12bfa20 100644
--- a/README
+++ b/README
@@ -1,40 +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
-
-Note that it's not necessary to specify the "-m" option to qemu. The default
-memory size is enough. Actually, the tests infrastructure doesn't support too
-much RAM anyway, so specifying a large amount of RAM may break it.
-
-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 test images do
+  ./configure
+  make
+in this directory. Test 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 variable, 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
-
+.:		configure script, top-level Makefile, and run_tests.sh
+./config:	collection of architecture dependent makefiles
+./docs:		documentation files
+./lib:		general architecture neutral 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 architecture 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 84cce7065d400..0000000000000
--- a/config-x86-common.mak
+++ /dev/null
@@ -1,124 +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 $(TEST_DIR)/smap.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)/svm.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)/smap.elf: $(cstart.o) $(TEST_DIR)/smap.o
-
-$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o $(TEST_DIR)/vmx_tests.o
-
-$(TEST_DIR)/debug.elf: $(cstart.o) $(TEST_DIR)/debug.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 a9a2a9e87c3a6..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 $(TEST_DIR)/debug.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..0b0da85f2a9df
--- /dev/null
+++ b/config/config-x86-common.mak
@@ -0,0 +1,124 @@
+#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 $(TEST_DIR)/smap.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)/svm.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)/smap.elf: $(cstart.o) $(TEST_DIR)/smap.o
+
+$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o $(TEST_DIR)/vmx_tests.o
+
+$(TEST_DIR)/debug.elf: $(cstart.o) $(TEST_DIR)/debug.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..d69252f3d35b1
--- /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 $(TEST_DIR)/debug.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..854fe20d56f66
--- /dev/null
+++ b/docs/testdev.txt
@@ -0,0 +1,13 @@
+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
+			the 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
+
+The test device uses 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 b077091da18b3..4758573183ba7 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -1,8 +1,13 @@
 #!/bin/bash
 
-testroot=x86
-config=$testroot/unittests.cfg
-qemu=${qemu:-qemu-system-x86_64}
+if [ ! -f config.mak ]; then
+    echo "run ./configure && make first. See ./configure -h"
+    exit
+fi
+source config.mak
+
+config=$TEST_DIR/unittests.cfg
+qemu=${QEMU:-qemu-system-$ARCH}
 verbose=0
 
 function run()
@@ -27,7 +32,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 +70,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 +97,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
-specify the appropriate qemu binary for x86-run.
+Set the environment variable QEMU=/path/to/qemu-system-ARCH to
+specify the appropriate qemu binary for ARCH-run.
 
 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..996ed33546d62 100644
--- a/x86/README
+++ b/x86/README
@@ -1,16 +1,47 @@
+
+Tests for the x86 architecture are run as kernel images for qemu that support
+multiboot format. The tests use an infrastructure called from the bios code.
+The infrastructure initialize the system/cpus, switches to long-mode, and
+calls the 'main' function of the individual test. Tests use a qemu virtual
+test device, named testdev, for services like printing, exiting, querying
+memory size, etc. See file docs/testdev.txt for more details.
+
+Examples of a test invocation:
+ These invocations run the msr test case and outputs to stdio.
+
+ Using qemu-kvm:
+
+	qemu-kvm -device testdev,chardev=testlog \
+		 -chardev file,id=testlog,path=msr.out \
+		 -serial stdio -kernel ./x86/msr.flat
+
+ 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
 
-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
+Legacy notes:
+ The exit status of the binary (and the script) is inconsistent: with
+ qemu-system, after the unit-test 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.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 04/19] add distclean target and gitignore more
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (2 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 03/19] clean root dir of all x86-ness Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-12 10:36   ` Paolo Bonzini
  2014-06-11 14:01 ` [PATCH v5 05/19] add 'make cscope' support Andrew Jones
                   ` (16 subsequent siblings)
  20 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

also add a check for config.mak in Makefile

Signed-off-by: Andrew Jones <drjones@redhat.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 .gitignore | 5 +++++
 Makefile   | 9 ++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index d6663ec10caf1..775d0dfd8263e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,8 @@
 patches
 .stgit-*
 cscope.*
+*.swp
+/config.mak
+/*-run
+/test.log
+/msr.out
diff --git a/Makefile b/Makefile
index 566d2bee771e1..7eeece84300df 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,13 @@
 
+ifeq ($(wildcard config.mak),)
+$(error run ./configure first. See ./configure -h)
+endif
+
 include config.mak
 
 DESTDIR := $(PREFIX)/share/qemu/tests
 
-.PHONY: arch_clean clean
+.PHONY: arch_clean clean distclean
 
 #make sure env CFLAGS variable is not used
 CFLAGS =
@@ -53,3 +57,6 @@ install:
 
 clean: arch_clean
 	$(RM) lib/.*.d $(libcflat) $(cflatobjs)
+
+distclean: clean
+	$(RM) config.mak $(TEST_DIR)-run test.log msr.out
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 05/19] add 'make cscope' support
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (3 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 04/19] add distclean target and gitignore more Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 07/19] libfdt: get libfdt to build Andrew Jones
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Add a Makefile target to quickly generate arch-specific cscope
for kvm-unit-tests. Assumes a mostly flat directory structure,
i.e. uses '-maxdepth 1' in the file search.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 Makefile | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 7eeece84300df..32ae9a59db5b0 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ include config.mak
 
 DESTDIR := $(PREFIX)/share/qemu/tests
 
-.PHONY: arch_clean clean distclean
+.PHONY: arch_clean clean distclean cscope
 
 #make sure env CFLAGS variable is not used
 CFLAGS =
@@ -59,4 +59,11 @@ clean: arch_clean
 	$(RM) lib/.*.d $(libcflat) $(cflatobjs)
 
 distclean: clean
-	$(RM) config.mak $(TEST_DIR)-run test.log msr.out
+	$(RM) config.mak $(TEST_DIR)-run test.log msr.out cscope.*
+
+cscope: common_dirs = lib
+cscope:
+	$(RM) ./cscope.*
+	find $(TEST_DIR) lib/$(TEST_DIR) $(common_dirs) -maxdepth 1 \
+		-name '*.[chsS]' -print | sed 's,^\./,,' > ./cscope.files
+	cscope -bk
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 07/19] libfdt: get libfdt to build
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (4 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 05/19] add 'make cscope' support Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 08/19] add support for Linux device trees Andrew Jones
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Add string functions needed for libfdt, and add a make target.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
v4: rewrite strchr w/out use of strlen, drop libfdt_env.h modifications
---
 Makefile       | 21 +++++++++++++++++++--
 lib/libcflat.h |  4 ++++
 lib/string.c   | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 32ae9a59db5b0..fba58e36f272f 100644
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,13 @@ cflatobjs := \
 	lib/string.o \
 	lib/report.o
 
+# libfdt paths
+LIBFDT_objdir = lib/libfdt
+LIBFDT_srcdir = lib/libfdt
+LIBFDT_archive = $(LIBFDT_objdir)/libfdt.a
+LIBFDT_include = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_INCLUDES))
+LIBFDT_version = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_VERSION))
+
 #include architecure specific make rules
 include config/config-$(ARCH).mak
 
@@ -46,6 +53,11 @@ LDFLAGS += -pthread -lrt
 $(libcflat): $(cflatobjs)
 	$(AR) rcs $@ $^
 
+include $(LIBFDT_srcdir)/Makefile.libfdt
+$(LIBFDT_archive): CFLAGS += -ffreestanding -I lib -I lib/libfdt -Wno-sign-compare
+$(LIBFDT_archive): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS))
+	$(AR) rcs $@ $^
+
 %.o: %.S
 	$(CC) $(CFLAGS) -c -nostdlib -o $@ $<
 
@@ -58,10 +70,15 @@ install:
 clean: arch_clean
 	$(RM) lib/.*.d $(libcflat) $(cflatobjs)
 
-distclean: clean
+libfdt_clean:
+	$(RM) $(LIBFDT_archive) \
+	$(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS)) \
+	$(LIBFDT_objdir)/.*.d
+
+distclean: clean libfdt_clean
 	$(RM) config.mak $(TEST_DIR)-run test.log msr.out cscope.*
 
-cscope: common_dirs = lib
+cscope: common_dirs = lib lib/libfdt
 cscope:
 	$(RM) ./cscope.*
 	find $(TEST_DIR) lib/$(TEST_DIR) $(common_dirs) -maxdepth 1 \
diff --git a/lib/libcflat.h b/lib/libcflat.h
index cb6663d33ef5a..42b7a41b5f832 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -45,6 +45,7 @@ extern void exit(int code);
 extern unsigned long strlen(const char *buf);
 extern char *strcat(char *dest, const char *src);
 extern int strcmp(const char *a, const char *b);
+extern char *strchr(const char *s, int c);
 
 extern int printf(const char *fmt, ...);
 extern int snprintf(char *buf, int size, const char *fmt, ...);
@@ -54,6 +55,9 @@ extern void puts(const char *s);
 
 extern void *memset(void *s, int c, size_t n);
 extern void *memcpy(void *dest, const void *src, size_t n);
+extern int memcmp(const void *s1, const void *s2, size_t n);
+extern void *memmove(void *dest, const void *src, size_t n);
+extern void *memchr(const void *s, int c, size_t n);
 
 extern long atol(const char *ptr);
 #define ARRAY_SIZE(_a)  (sizeof(_a)/sizeof((_a)[0]))
diff --git a/lib/string.c b/lib/string.c
index 3a9caf720bf2b..fe90c8b1289f2 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -31,6 +31,14 @@ int strcmp(const char *a, const char *b)
     return *a - *b;
 }
 
+char *strchr(const char *s, int c)
+{
+    while (*s != (char)c)
+	if (*s++ == '\0')
+	    return NULL;
+    return (char *)s;
+}
+
 void *memset(void *s, int c, size_t n)
 {
     size_t i;
@@ -54,6 +62,46 @@ void *memcpy(void *dest, const void *src, size_t n)
     return dest;
 }
 
+int memcmp(const void *s1, const void *s2, size_t n)
+{
+    const unsigned char *a = s1, *b = s2;
+    int ret = 0;
+
+    while (n--) {
+	ret = *a - *b;
+	if (ret)
+	    break;
+	++a, ++b;
+    }
+    return ret;
+}
+
+void *memmove(void *dest, const void *src, size_t n)
+{
+    const unsigned char *s = src;
+    unsigned char *d = dest;
+
+    if (d <= s) {
+	while (n--)
+	    *d++ = *s++;
+    } else {
+	d += n, s += n;
+	while (n--)
+	    *--d = *--s;
+    }
+    return dest;
+}
+
+void *memchr(const void *s, int c, size_t n)
+{
+    const unsigned char *str = s, chr = (unsigned char)c;
+
+    while (n--)
+	if (*str++ == chr)
+	    return (void *)(str - 1);
+    return NULL;
+}
+
 long atol(const char *ptr)
 {
     long acc = 0;
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 08/19] add support for Linux device trees
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (5 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 07/19] libfdt: get libfdt to build Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-12  9:19   ` Christoffer Dall
  2014-06-11 14:01 ` [PATCH v5 09/19] libcflat: add abort() and assert() Andrew Jones
                   ` (13 subsequent siblings)
  20 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Add some device tree functions, built on libfdt, to the arch-neutral
lib code in order to facilitate the extraction of boot info and device
base addresses. These functions should work on device trees conforming
to section III of the kernel doc
Documentation/devicetree/booting-without-of.txt.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
v5:
 - changed *get_baseaddr* helpers to *get_base* helpers
 - a couple minor code changes [Christoffer Dall]
v4: reworked everything, added lots of comments to devicetree.h
---
 lib/devicetree.c | 272 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/devicetree.h | 236 +++++++++++++++++++++++++++++++++++++++++++++++
 lib/libcflat.h   |   2 +
 3 files changed, 510 insertions(+)
 create mode 100644 lib/devicetree.c
 create mode 100644 lib/devicetree.h

diff --git a/lib/devicetree.c b/lib/devicetree.c
new file mode 100644
index 0000000000000..57e7408f4c5a9
--- /dev/null
+++ b/lib/devicetree.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "libfdt/libfdt.h"
+#include "devicetree.h"
+
+static const void *fdt;
+static u32 root_nr_address_cells, root_nr_size_cells;
+
+const void *dt_fdt(void)
+{
+	return fdt;
+}
+
+bool dt_available(void)
+{
+	return fdt_check_header(fdt) == 0;
+}
+
+int dt_get_nr_cells(int fdtnode, u32 *nr_address_cells, u32 *nr_size_cells)
+{
+	const struct fdt_property *prop;
+	u32 *nr_cells;
+	int len;
+
+	prop = fdt_get_property(fdt, fdtnode, "#address-cells", &len);
+	if (prop == NULL)
+		return len;
+
+	nr_cells = (u32 *)prop->data;
+	*nr_address_cells = fdt32_to_cpu(*nr_cells);
+
+	prop = fdt_get_property(fdt, fdtnode, "#size-cells", &len);
+	if (prop == NULL)
+		return len;
+
+	nr_cells = (u32 *)prop->data;
+	*nr_size_cells = fdt32_to_cpu(*nr_cells);
+
+	return 0;
+}
+
+void dt_reg_init(struct dt_reg *reg, u32 nr_address_cells, u32 nr_size_cells)
+{
+	memset(reg, 0, sizeof(struct dt_reg));
+	reg->nr_address_cells = nr_address_cells;
+	reg->nr_size_cells = nr_size_cells;
+}
+
+int dt_get_reg(int fdtnode, int regidx, struct dt_reg *reg)
+{
+	const struct fdt_property *prop;
+	u32 *cells, i;
+	unsigned nr_tuple_cells;
+	int len;
+
+	prop = fdt_get_property(fdt, fdtnode, "reg", &len);
+	if (prop == NULL)
+		return len;
+
+	cells = (u32 *)prop->data;
+	nr_tuple_cells = reg->nr_address_cells + reg->nr_size_cells;
+	regidx *= nr_tuple_cells;
+
+	if (regidx + nr_tuple_cells > len/sizeof(u32))
+		return -FDT_ERR_NOTFOUND;
+
+	for (i = 0; i < reg->nr_address_cells; ++i)
+		reg->address_cells[i] = fdt32_to_cpu(cells[regidx + i]);
+
+	regidx += reg->nr_address_cells;
+	for (i = 0; i < reg->nr_size_cells; ++i)
+		reg->size_cells[i] = fdt32_to_cpu(cells[regidx + i]);
+
+	return 0;
+}
+
+int dt_pbus_translate_node(int fdtnode, int regidx,
+			   struct dt_pbus_reg *pbus_reg)
+{
+	struct dt_reg raw_reg;
+	int ret;
+
+	dt_reg_init(&raw_reg, root_nr_address_cells, root_nr_size_cells);
+
+	ret = dt_get_reg(fdtnode, regidx, &raw_reg);
+	if (ret < 0)
+		return ret;
+
+	pbus_reg->addr = dt_pbus_read_cells(raw_reg.nr_address_cells,
+					    raw_reg.address_cells);
+	pbus_reg->size = dt_pbus_read_cells(raw_reg.nr_size_cells,
+					    raw_reg.size_cells);
+
+	return 0;
+}
+
+int dt_pbus_translate(const struct dt_device *dev, int regidx,
+		      void *reg)
+{
+	return dt_pbus_translate_node(dev->fdtnode, regidx, reg);
+}
+
+int dt_bus_match_any(const struct dt_device *dev __unused, int fdtnode)
+{
+	/* matches any device with a valid node */
+	return fdtnode < 0 ? fdtnode : 1;
+}
+
+static const struct dt_bus dt_default_bus = {
+	.match = dt_bus_match_any,
+	.translate = dt_pbus_translate,
+};
+
+void dt_bus_init_defaults(struct dt_bus *bus)
+{
+	memcpy(bus, &dt_default_bus, sizeof(struct dt_bus));
+}
+
+void dt_device_init(struct dt_device *dev, const struct dt_bus *bus,
+		    const void *info)
+{
+	memset(dev, 0, sizeof(struct dt_device));
+	dev->bus = bus;
+	dev->info = (void *)info;
+}
+
+int dt_device_find_compatible(const struct dt_device *dev,
+			      const char *compatible)
+{
+	int node, ret;
+
+	node = fdt_node_offset_by_compatible(fdt, -1, compatible);
+	while (node >= 0) {
+		ret = dev->bus->match(dev, node);
+		if (ret < 0)
+			return ret;
+		else if (ret)
+			break;
+		node = fdt_node_offset_by_compatible(fdt, node, compatible);
+	}
+	return node;
+}
+
+int dt_pbus_get_base_compatible(const char *compatible,
+				struct dt_pbus_reg *base)
+{
+	struct dt_device dev;
+	int node;
+
+	dt_device_init(&dev, &dt_default_bus, NULL);
+
+	node = dt_device_find_compatible(&dev, compatible);
+	if (node < 0)
+		return node;
+
+	dt_device_bind_node(&dev, node);
+
+	return dt_pbus_get_base(&dev, base);
+}
+
+int dt_get_memory_params(struct dt_pbus_reg *regs, int nr_regs)
+{
+	const char *pn = "device_type", *pv = "memory";
+	int node, ret, pl = strlen(pv) + 1, nr = 0;
+	struct dt_pbus_reg reg;
+
+	node = fdt_node_offset_by_prop_value(fdt, -1, pn, pv, pl);
+
+	while (node >= 0) {
+
+		while (nr < nr_regs) {
+			ret = dt_pbus_translate_node(node, nr, &reg);
+			if (ret == -FDT_ERR_NOTFOUND)
+				break;
+			if (ret < 0)
+				return ret;
+			regs[nr].addr = reg.addr;
+			regs[nr].size = reg.size;
+			++nr;
+		}
+
+		node = fdt_node_offset_by_prop_value(fdt, node, pn, pv, pl);
+	}
+
+	return node != -FDT_ERR_NOTFOUND ? node : nr;
+}
+
+int dt_for_each_cpu_node(void (*func)(int fdtnode, u32 regval, void *info),
+			 void *info)
+{
+	const struct fdt_property *prop;
+	int cpus, cpu, ret, len;
+	struct dt_reg raw_reg;
+	u32 nac, nsc;
+
+	cpus = fdt_path_offset(fdt, "/cpus");
+	if (cpus < 0)
+		return cpus;
+
+	ret = dt_get_nr_cells(cpus, &nac, &nsc);
+	if (ret < 0)
+		return ret;
+
+	dt_reg_init(&raw_reg, nac, nsc);
+
+	dt_for_each_subnode(cpus, cpu) {
+
+		prop = fdt_get_property(fdt, cpu, "device_type", &len);
+		if (prop == NULL)
+			return len;
+
+		if (len != 4 || strcmp((char *)prop->data, "cpu"))
+			continue;
+
+		ret = dt_get_reg(cpu, 0, &raw_reg);
+		if (ret < 0)
+			return ret;
+
+		func(cpu, raw_reg.address_cells[0], info);
+	}
+
+	return 0;
+}
+
+int dt_get_bootargs(const char **bootargs)
+{
+	const struct fdt_property *prop;
+	int node, len;
+
+	*bootargs = NULL;
+
+	node = fdt_path_offset(fdt, "/chosen");
+	if (node < 0)
+		return node;
+
+	prop = fdt_get_property(fdt, node, "bootargs", &len);
+	if (prop)
+		*bootargs = (char *)prop->data;
+	else if (len < 0 && len != -FDT_ERR_NOTFOUND)
+		return len;
+
+	return 0;
+}
+
+int dt_init(const void *fdt_ptr)
+{
+	struct dt_bus *defbus = (struct dt_bus *)&dt_default_bus;
+	int root, ret;
+
+	ret = fdt_check_header(fdt_ptr);
+	if (ret < 0)
+		return ret;
+	fdt = fdt_ptr;
+
+	root = fdt_path_offset(fdt, "/");
+	if (root < 0)
+		return root;
+
+	ret = dt_get_nr_cells(root, &root_nr_address_cells,
+				    &root_nr_size_cells);
+	if (ret < 0)
+		return ret;
+
+	defbus->nr_address_cells = root_nr_address_cells;
+	defbus->nr_size_cells = root_nr_size_cells;
+
+	return 0;
+}
diff --git a/lib/devicetree.h b/lib/devicetree.h
new file mode 100644
index 0000000000000..7a1dc3e77eed3
--- /dev/null
+++ b/lib/devicetree.h
@@ -0,0 +1,236 @@
+#ifndef _DEVICETREE_H_
+#define _DEVICETREE_H_
+/*
+ * devicetree builds on libfdt to implement abstractions and accessors
+ * for Linux required device tree content. The accessors provided are
+ * common across architectures. See section III of the kernel doc
+ * Documentation/devicetree/booting-without-of.txt
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "libfdt/libfdt.h"
+
+/**********************************************************************
+ * devicetree init and libfdt helpers
+ **********************************************************************/
+
+/* dt_init initializes devicetree with a pointer to an fdt, @fdt_ptr */
+extern int dt_init(const void *fdt_ptr);
+
+/* get the fdt pointer that devicetree is using */
+extern const void *dt_fdt(void);
+
+/* check for an initialized, valid devicetree */
+extern bool dt_available(void);
+
+/* traverse child nodes */
+#define dt_for_each_subnode(n, s)					\
+	for (s = fdt_first_subnode(dt_fdt(), n);			\
+	     s != -FDT_ERR_NOTFOUND;					\
+	     s = fdt_next_subnode(dt_fdt(), s))
+
+/**********************************************************************
+ * Abstractions for required node types and properties
+ **********************************************************************/
+
+struct dt_device {
+	int fdtnode;
+	const struct dt_bus *bus;
+
+	/*
+	 * info is a pointer to device specific data, which may be
+	 * used by the bus match() and translate() functions
+	 */
+	void *info;
+};
+
+struct dt_bus {
+	/*
+	 * match a device @dev to an fdt node @fdtnode
+	 * returns
+	 *  - a positive value on match
+	 *  - zero on no match
+	 *  - a negative FDT_ERR_* value on failure
+	 */
+	int (*match)(const struct dt_device *dev, int fdtnode);
+
+	/*
+	 * translate the @regidx'th "address size" tuple of
+	 * @dev's fdt node's "reg" property, and store the result
+	 * in @reg, a bus specific structure
+	 * returns
+	 *  - zero on success
+	 *  - a negative FDT_ERR_* value on failure
+	 */
+	int (*translate)(const struct dt_device *dev, int regidx, void *reg);
+
+	/* the bus #address-cells and #size-cells properties */
+	u32 nr_address_cells, nr_size_cells;
+};
+
+/* dt_bus_match_any matches any fdt node, i.e. it always returns true */
+extern int dt_bus_match_any(const struct dt_device *dev, int fdtnode);
+
+/* the processor bus (pbus) address type and register tuple */
+typedef u64 dt_pbus_addr_t;
+struct dt_pbus_reg {
+	dt_pbus_addr_t addr;
+	dt_pbus_addr_t size;
+};
+
+static inline dt_pbus_addr_t dt_pbus_read_cells(u32 nr_cells, u32 *cells)
+{
+	switch (nr_cells) {
+	case 1: return cells[0];
+	case 2: return ((u64)cells[0] << 32) | cells[1];
+	}
+	return (~0ULL);
+}
+
+/*
+ * dt_pbus_translate translates device node regs for the
+ * processor bus using the root node's #address-cells and
+ * #size-cells and dt_pbus_read_cells()
+ * returns
+ *  - zero on success
+ *  - a negative FDT_ERR_* value on failure
+ */
+extern int dt_pbus_translate(const struct dt_device *dev, int regidx,
+			     void *reg);
+
+/*
+ * dt_pbus_translate_node is the same as dt_pbus_translate but
+ * operates on an fdt node instead of a dt_device
+ */
+extern int dt_pbus_translate_node(int fdtnode, int regidx,
+				  struct dt_pbus_reg *reg);
+
+/*
+ * dt_pbus_get_base is an alias for
+ *     dt_pbus_translate(dev, 0, base)
+ * returns
+ *  - zero on success
+ *  - a negative FDT_ERR_* value on failure
+ */
+static inline int dt_pbus_get_base(const struct dt_device *dev,
+				   struct dt_pbus_reg *base)
+{
+	return dt_pbus_translate(dev, 0, base);
+}
+
+/*
+ * dt_bus_init_defaults initializes @bus with
+ *  match		<- dt_bus_match_any
+ *  translate		<- dt_pbus_translate
+ *  nr_address_cells	<- #address-cells of the root node
+ *  nr_size_cells	<- #size-cells of the root node
+ */
+extern void dt_bus_init_defaults(struct dt_bus *bus);
+
+/*
+ * dt_device_init initializes a dt_device with the given parameters
+ */
+extern void dt_device_init(struct dt_device *dev, const struct dt_bus *bus,
+			   const void *info);
+
+static inline void dt_device_bind_node(struct dt_device *dev, int fdtnode)
+{
+	dev->fdtnode = fdtnode;
+}
+
+/*
+ * dt_device_find_compatible finds a @compatible node
+ * returns
+ *  - node (>= 0) on success
+ *  - a negative FDT_ERR_* value on failure
+ */
+extern int dt_device_find_compatible(const struct dt_device *dev,
+				     const char *compatible);
+
+/*
+ * dt_pbus_get_base_compatible simply bundles many functions into one.
+ * It finds the first @compatible fdt node, then translates the 0th reg
+ * tuple (the base) using the processor bus translation, and finally it
+ * stores that result in @base.
+ * returns
+ *  - zero on success
+ *  - a negative FDT_ERR_* value on failure
+ */
+extern int dt_pbus_get_base_compatible(const char *compatible,
+				       struct dt_pbus_reg *base);
+
+/**********************************************************************
+ * Low-level accessors for required node types and properties
+ **********************************************************************/
+
+/*
+ * dt_get_nr_cells sets @nr_address_cells and @nr_size_cells to the
+ * #address-cells and #size-cells properties of @fdtnode
+ * returns
+ *  - zero on success
+ *  - a negative FDT_ERR_* value on failure
+ */
+extern int dt_get_nr_cells(int fdtnode, u32 *nr_address_cells,
+					u32 *nr_size_cells);
+
+/* dt_reg is a structure for "raw" reg tuples */
+#define MAX_ADDRESS_CELLS	4
+#define MAX_SIZE_CELLS		4
+struct dt_reg {
+	u32 nr_address_cells, nr_size_cells;
+	u32 address_cells[MAX_ADDRESS_CELLS];
+	u32 size_cells[MAX_SIZE_CELLS];
+};
+
+/*
+ * dt_reg_init initialize a dt_reg struct to zero and sets
+ * nr_address_cells and nr_size_cells to @nr_address_cells and
+ * @nr_size_cells respectively.
+ */
+extern void dt_reg_init(struct dt_reg *reg, u32 nr_address_cells,
+					    u32 nr_size_cells);
+
+/*
+ * dt_get_reg gets the @regidx'th reg tuple of @fdtnode's reg property
+ * and stores it in @reg. @reg must be initialized.
+ * returns
+ *  - zero on success
+ *  - a negative FDT_ERR_* value on failure
+ */
+extern int dt_get_reg(int fdtnode, int regidx, struct dt_reg *reg);
+
+/**********************************************************************
+ * High-level accessors for required node types and properties
+ **********************************************************************/
+
+/*
+ * dt_get_bootargs gets a pointer to /chosen/bootargs
+ * returns
+ *  - zero on success
+ *  - a negative FDT_ERR_* value on failure
+ */
+extern int dt_get_bootargs(const char **bootargs);
+
+/*
+ * dt_get_memory_params gets the memory parameters from the /memory node(s)
+ * storing each memory region ("address size" tuple) in consecutive entries
+ * of @regs, up to @nr_regs
+ * returns
+ *  - number of memory regions found on success
+ *  - a negative FDT_ERR_* value on failure
+ */
+extern int dt_get_memory_params(struct dt_pbus_reg *regs, int nr_regs);
+
+/*
+ * dt_for_each_cpu_node runs @func on each cpu node in the /cpus node
+ * passing it its fdt node, its reg property value, and @info
+ *  - zero on success
+ *  - a negative FDT_ERR_* value on failure
+ */
+extern int dt_for_each_cpu_node(void (*func)(int fdtnode, u32 regval,
+				void *info), void *info);
+
+#endif /* _DEVICETREE_H_ */
diff --git a/lib/libcflat.h b/lib/libcflat.h
index 42b7a41b5f832..024c834630d63 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -22,6 +22,8 @@
 
 #include <stdarg.h>
 
+#define __unused __attribute__((__unused__))
+
 #define xstr(s) xxstr(s)
 #define xxstr(s) #s
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 09/19] libcflat: add abort() and assert()
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (6 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 08/19] add support for Linux device trees Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-12 10:48   ` Paolo Bonzini
  2014-06-11 14:01 ` [PATCH v5 10/19] Introduce asm-generic/*.h files Andrew Jones
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

The test framework may have external dependencies. assert() provides
the ability to abort when those dependencies aren't met. However,
assert() should only be used for unlikely conditions. We can provide
more informative messages with printf() for the more likely problems.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 lib/libcflat.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/lib/libcflat.h b/lib/libcflat.h
index 024c834630d63..8886885766ddc 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -70,4 +70,13 @@ extern long atol(const char *ptr);
 
 void report(const char *msg_fmt, bool pass, ...);
 int report_summary(void);
+
+#define abort() exit(64)		/* 129 exit status from qemu */
+#define assert(cond)							\
+do {									\
+	if (!(cond))							\
+		printf("%s:%d: assert failed\n", __FILE__, __LINE__),	\
+		abort();						\
+} while (0)
+
 #endif
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 10/19] Introduce asm-generic/*.h files
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (7 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 09/19] libcflat: add abort() and assert() Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 11/19] add minimal virtio support for devtree virtio-mmio Andrew Jones
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Architecture neutral code may need to call low-level io accessors,
or use spinlocks. Create a generic io.h to ensure those accessors
are defined, and a generic spinlock.h that complains when included,
as we can't write a generic spinlock. These files can be overridden
or extended by architecture specific versions placed in
lib/$ARCH/asm/.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
v5: added a trivial ioremap function [Christoffer Dall]
v4: introduce lib/asm symlink to get rid of #ifdef __arm__,
    add spinlock.h too
v3: wrt to io.h (was libio.[ch]) only
    - get rid of CONFIG_64BIT, replace with asserts
    - get rid of {read,write}_len() [libio.c]
    - fix bad *64_to_cpu macros
---
 .gitignore                 |   1 +
 Makefile                   |   6 +-
 configure                  |  11 +++
 lib/asm-generic/io.h       | 162 +++++++++++++++++++++++++++++++++++++++++++++
 lib/asm-generic/spinlock.h |   4 ++
 5 files changed, 181 insertions(+), 3 deletions(-)
 create mode 100644 lib/asm-generic/io.h
 create mode 100644 lib/asm-generic/spinlock.h

diff --git a/.gitignore b/.gitignore
index 775d0dfd8263e..e21939a8771e9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ patches
 .stgit-*
 cscope.*
 *.swp
+/lib/asm
 /config.mak
 /*-run
 /test.log
diff --git a/Makefile b/Makefile
index fba58e36f272f..51cacdac00615 100644
--- a/Makefile
+++ b/Makefile
@@ -76,11 +76,11 @@ libfdt_clean:
 	$(LIBFDT_objdir)/.*.d
 
 distclean: clean libfdt_clean
-	$(RM) config.mak $(TEST_DIR)-run test.log msr.out cscope.*
+	$(RM) lib/asm config.mak $(TEST_DIR)-run test.log msr.out cscope.*
 
-cscope: common_dirs = lib lib/libfdt
+cscope: common_dirs = lib lib/libfdt lib/asm lib/asm-generic
 cscope:
 	$(RM) ./cscope.*
-	find $(TEST_DIR) lib/$(TEST_DIR) $(common_dirs) -maxdepth 1 \
+	find -L $(TEST_DIR) lib/$(TEST_DIR) $(common_dirs) -maxdepth 1 \
 		-name '*.[chsS]' -print | sed 's,^\./,,' > ./cscope.files
 	cscope -bk
diff --git a/configure b/configure
index 6cfc64943f6e6..8a81bf92e27b7 100755
--- a/configure
+++ b/configure
@@ -95,6 +95,17 @@ if [ $exit -eq 0 ]; then
 fi
 rm -f lib_test.c
 
+# link lib/asm for the architecture
+rm -f lib/asm
+asm=asm-generic
+if [ -d lib/$arch/asm ]; then
+	asm=$arch/asm
+elif [ -d lib/$testdir/asm ]; then
+	asm=$testdir/asm
+fi
+ln -s $asm lib/asm
+
+# create the config
 cat <<EOF > config.mak
 PREFIX=$prefix
 KERNELDIR=$(readlink -f $kerneldir)
diff --git a/lib/asm-generic/io.h b/lib/asm-generic/io.h
new file mode 100644
index 0000000000000..f00f4d3e68fe1
--- /dev/null
+++ b/lib/asm-generic/io.h
@@ -0,0 +1,162 @@
+#ifndef _ASM_GENERIC_IO_H_
+#define _ASM_GENERIC_IO_H_
+/*
+ * asm-generic/io.h
+ *  adapted from the Linux kernel's include/asm-generic/io.h
+ *  and arch/arm/include/asm/io.h
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+
+#ifndef __raw_readb
+static inline u8 __raw_readb(const volatile void *addr)
+{
+	return *(const volatile u8 *)addr;
+}
+#endif
+
+#ifndef __raw_readw
+static inline u16 __raw_readw(const volatile void *addr)
+{
+	return *(const volatile u16 *)addr;
+}
+#endif
+
+#ifndef __raw_readl
+static inline u32 __raw_readl(const volatile void *addr)
+{
+	return *(const volatile u32 *)addr;
+}
+#endif
+
+#ifndef __raw_readq
+static inline u64 __raw_readq(const volatile void *addr)
+{
+	assert(sizeof(unsigned long) == sizeof(u64));
+	return *(const volatile u64 *)addr;
+}
+#endif
+
+#ifndef __raw_writeb
+static inline void __raw_writeb(u8 b, volatile void *addr)
+{
+	*(volatile u8 *)addr = b;
+}
+#endif
+
+#ifndef __raw_writew
+static inline void __raw_writew(u16 b, volatile void *addr)
+{
+	*(volatile u16 *)addr = b;
+}
+#endif
+
+#ifndef __raw_writel
+static inline void __raw_writel(u32 b, volatile void *addr)
+{
+	*(volatile u32 *)addr = b;
+}
+#endif
+
+#ifndef __raw_writeq
+static inline void __raw_writeq(u64 b, volatile void *addr)
+{
+	assert(sizeof(unsigned long) == sizeof(u64));
+	*(volatile u64 *)addr = b;
+}
+#endif
+
+#ifndef __bswap16
+static inline u16 __bswap16(u16 x)
+{
+	return ((x >> 8) & 0xff) | ((x & 0xff) << 8);
+}
+#endif
+
+#ifndef __bswap32
+static inline u32 __bswap32(u32 x)
+{
+	return ((x & 0xff000000) >> 24) | ((x & 0x00ff0000) >>  8) |
+	       ((x & 0x0000ff00) <<  8) | ((x & 0x000000ff) << 24);
+}
+#endif
+
+#ifndef __bswap64
+static inline u64 __bswap64(u64 x)
+{
+	return ((x & 0x00000000000000ffULL) << 56) |
+	       ((x & 0x000000000000ff00ULL) << 40) |
+	       ((x & 0x0000000000ff0000ULL) << 24) |
+	       ((x & 0x00000000ff000000ULL) <<  8) |
+	       ((x & 0x000000ff00000000ULL) >>  8) |
+	       ((x & 0x0000ff0000000000ULL) >> 24) |
+	       ((x & 0x00ff000000000000ULL) >> 40) |
+	       ((x & 0xff00000000000000ULL) >> 56);
+}
+#endif
+
+#ifndef __cpu_is_be
+#define __cpu_is_be() (0)
+#endif
+
+#define le16_to_cpu(x) \
+	({ u16 __r = __cpu_is_be() ? __bswap16(x) : (x); __r; })
+#define cpu_to_le16 le16_to_cpu
+
+#define le32_to_cpu(x) \
+	({ u32 __r = __cpu_is_be() ? __bswap32(x) : (x); __r; })
+#define cpu_to_le32 le32_to_cpu
+
+#define le64_to_cpu(x) \
+	({ u64 __r = __cpu_is_be() ? __bswap64(x) : (x); __r; })
+#define cpu_to_le64 le64_to_cpu
+
+#define be16_to_cpu(x) \
+	({ u16 __r = !__cpu_is_be() ? __bswap16(x) : (x); __r; })
+#define cpu_to_be16 be16_to_cpu
+
+#define be32_to_cpu(x) \
+	({ u32 __r = !__cpu_is_be() ? __bswap32(x) : (x); __r; })
+#define cpu_to_be32 be32_to_cpu
+
+#define be64_to_cpu(x) \
+	({ u64 __r = !__cpu_is_be() ? __bswap64(x) : (x); __r; })
+#define cpu_to_be64 be64_to_cpu
+
+#ifndef rmb
+#define rmb() do { } while (0)
+#endif
+#ifndef wmb
+#define wmb() do { } while (0)
+#endif
+
+#define readb(addr) \
+	({ u8 __r = __raw_readb(addr); rmb(); __r; })
+#define readw(addr) \
+	({ u16 __r = le16_to_cpu(__raw_readw(addr)); rmb(); __r; })
+#define readl(addr) \
+	({ u32 __r = le32_to_cpu(__raw_readl(addr)); rmb(); __r; })
+#define readq(addr) \
+	({ u64 __r = le64_to_cpu(__raw_readq(addr)); rmb(); __r; })
+
+#define writeb(b, addr) \
+	({ wmb(); __raw_writeb(b, addr); })
+#define writew(b, addr) \
+	({ wmb(); __raw_writew(cpu_to_le16(b), addr); })
+#define writel(b, addr) \
+	({ wmb(); __raw_writel(cpu_to_le32(b), addr); })
+#define writeq(b, addr) \
+	({ wmb(); __raw_writeq(cpu_to_le64(b), addr); })
+
+#ifndef ioremap
+static inline void *ioremap(u64 phys_addr, size_t size __unused)
+{
+	assert(sizeof(long) == 8 || !(phys_addr >> 32));
+	return (void *)(unsigned long)phys_addr;
+}
+#endif
+
+#endif /* _ASM_GENERIC_IO_H_ */
diff --git a/lib/asm-generic/spinlock.h b/lib/asm-generic/spinlock.h
new file mode 100644
index 0000000000000..31417442e3330
--- /dev/null
+++ b/lib/asm-generic/spinlock.h
@@ -0,0 +1,4 @@
+#ifndef _ASM_GENERIC_SPINLOCK_H_
+#define _ASM_GENERIC_SPINLOCK_H_
+#error need architecture specific asm/spinlock.h
+#endif
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 11/19] add minimal virtio support for devtree virtio-mmio
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (8 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 10/19] Introduce asm-generic/*.h files Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-14 13:30   ` Christoffer Dall
  2014-06-11 14:01 ` [PATCH v5 12/19] Introduce virtio-testdev Andrew Jones
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Support the bare minimum of virtio to enable access to the virtio-mmio
config space of a device. Currently this implementation must use a
device tree to find the device.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
v5:
 - use same virtio struct names as kernel
 - no need to alloc a new virtio_config_ops for each virtio device
 - use ioremap
v4:
 - split from the virtio-testdev patch
 - search a table to "discover" that the device must be DT/virtio-mmio,
   which doesn't change anything, but looks less hacky than comments
   saying the device must be DT/virtio-mmio...
 - manage own pool of virtio-mmio pre-allocated device structures in
   order to avoid needing access to the heap
---
 lib/libcflat.h |   3 ++
 lib/virtio.c   | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/virtio.h   |  89 +++++++++++++++++++++++++++++++
 3 files changed, 257 insertions(+)
 create mode 100644 lib/virtio.c
 create mode 100644 lib/virtio.h

diff --git a/lib/libcflat.h b/lib/libcflat.h
index 8886885766ddc..5939cee54890b 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -65,6 +65,9 @@ extern long atol(const char *ptr);
 #define ARRAY_SIZE(_a)  (sizeof(_a)/sizeof((_a)[0]))
 
 #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+#define container_of(ptr, type, member) ({				\
+	const typeof( ((type *)0)->member ) *__mptr = (ptr);		\
+	(type *)( (char *)__mptr - offsetof(type,member) );})
 
 #define NULL ((void *)0UL)
 
diff --git a/lib/virtio.c b/lib/virtio.c
new file mode 100644
index 0000000000000..4c597e27f4aff
--- /dev/null
+++ b/lib/virtio.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "devicetree.h"
+#include "asm/spinlock.h"
+#include "asm/io.h"
+#include "virtio.h"
+
+enum virtio_hwdesc_type {
+	VIRTIO_HWDESC_TYPE_DT = 0,	/* device tree */
+	NR_VIRTIO_HWDESC_TYPES,
+};
+
+enum virtio_bus_type {
+	VIRTIO_BUS_TYPE_MMIO = 0,	/* virtio-mmio */
+	NR_VIRTIO_BUS_TYPES,
+};
+
+struct virtio_bind_bus {
+	bool (*hwdesc_probe)(void);
+	struct virtio_device *(*device_bind)(u32 devid);
+};
+
+static struct virtio_device *vm_dt_device_bind(u32 devid);
+
+static struct virtio_bind_bus
+virtio_bind_busses[NR_VIRTIO_HWDESC_TYPES][NR_VIRTIO_BUS_TYPES] = {
+
+[VIRTIO_HWDESC_TYPE_DT] = {
+
+	[VIRTIO_BUS_TYPE_MMIO] = {
+		.hwdesc_probe = dt_available,
+		.device_bind = vm_dt_device_bind,
+	},
+},
+};
+
+struct virtio_device *virtio_bind(u32 devid)
+{
+	struct virtio_bind_bus *bus;
+	struct virtio_device *dev;
+	int i, j;
+
+	for (i = 0; i < NR_VIRTIO_HWDESC_TYPES; ++i) {
+		for (j = 0; j < NR_VIRTIO_BUS_TYPES; ++j) {
+
+			bus = &virtio_bind_busses[i][j];
+
+			if (!bus->hwdesc_probe())
+				continue;
+
+			dev = bus->device_bind(devid);
+			if (dev)
+				return dev;
+		}
+	}
+
+	return NULL;
+}
+
+/******************************************************
+ * virtio-mmio support (config space only)
+ ******************************************************/
+
+static void vm_get(struct virtio_device *vdev, unsigned offset,
+		   void *buf, unsigned len)
+{
+	struct virtio_mmio_device *vmdev = to_virtio_mmio_device(vdev);
+	u8 *p = buf;
+	unsigned i;
+
+	for (i = 0; i < len; ++i)
+		p[i] = readb(vmdev->base + VIRTIO_MMIO_CONFIG + offset + i);
+}
+
+static void vm_set(struct virtio_device *vdev, unsigned offset,
+		   const void *buf, unsigned len)
+{
+	struct virtio_mmio_device *vmdev = to_virtio_mmio_device(vdev);
+	const u8 *p = buf;
+	unsigned i;
+
+	for (i = 0; i < len; ++i)
+		writeb(p[i], vmdev->base + VIRTIO_MMIO_CONFIG + offset + i);
+}
+
+static const struct virtio_config_ops vm_config_ops = {
+	.get = vm_get,
+	.set = vm_set,
+};
+
+#define NR_VM_DEVICES 32
+static struct spinlock vm_lock;
+static struct virtio_mmio_device vm_devs[NR_VM_DEVICES];
+static int nr_vm_devs;
+
+static struct virtio_mmio_device *vm_new_device(u32 devid)
+{
+	struct virtio_mmio_device *vmdev;
+
+	if (nr_vm_devs >= NR_VM_DEVICES)
+		return NULL;
+
+	spin_lock(&vm_lock);
+	vmdev = &vm_devs[nr_vm_devs++];
+	spin_unlock(&vm_lock);
+
+	vmdev->vdev.id.device = devid;
+	vmdev->vdev.id.vendor = -1;
+	vmdev->vdev.config = &vm_config_ops;
+
+	return vmdev;
+}
+
+/******************************************************
+ * virtio-mmio device tree support
+ ******************************************************/
+
+struct vm_dt_info {
+	u32 devid;
+	void *base;
+};
+
+static int vm_dt_match(const struct dt_device *dev, int fdtnode)
+{
+	struct vm_dt_info *info = (struct vm_dt_info *)dev->info;
+	struct dt_pbus_reg base;
+
+	dt_device_bind_node((struct dt_device *)dev, fdtnode);
+
+	assert(dt_pbus_get_base(dev, &base) == 0);
+	info->base = ioremap(base.addr, base.size);
+
+	return readl(info->base + VIRTIO_MMIO_DEVICE_ID) == info->devid;
+}
+
+static struct virtio_device *vm_dt_device_bind(u32 devid)
+{
+	struct virtio_mmio_device *vmdev;
+	struct dt_device dt_dev;
+	struct dt_bus dt_bus;
+	struct vm_dt_info info;
+	int node;
+
+	dt_bus_init_defaults(&dt_bus);
+	dt_bus.match = vm_dt_match;
+
+	info.devid = devid;
+
+	dt_device_init(&dt_dev, &dt_bus, &info);
+
+	node = dt_device_find_compatible(&dt_dev, "virtio,mmio");
+	assert(node >= 0 || node == -FDT_ERR_NOTFOUND);
+
+	if (node == -FDT_ERR_NOTFOUND)
+		return NULL;
+
+	vmdev = vm_new_device(devid);
+	vmdev->base = info.base;
+
+	return &vmdev->vdev;
+}
diff --git a/lib/virtio.h b/lib/virtio.h
new file mode 100644
index 0000000000000..16ebe7e0a7e70
--- /dev/null
+++ b/lib/virtio.h
@@ -0,0 +1,89 @@
+#ifndef _VIRTIO_H_
+#define _VIRTIO_H_
+/*
+ * A minimal implementation of virtio for virtio-mmio config space
+ * access.
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+
+struct virtio_device_id {
+	u32 device;
+	u32 vendor;
+};
+
+struct virtio_device {
+	struct virtio_device_id id;
+	const struct virtio_config_ops *config;
+};
+
+struct virtio_config_ops {
+	void (*get)(struct virtio_device *vdev, unsigned offset,
+		    void *buf, unsigned len);
+	void (*set)(struct virtio_device *vdev, unsigned offset,
+		    const void *buf, unsigned len);
+};
+
+extern struct virtio_device *virtio_bind(u32 devid);
+
+static inline u8
+virtio_config_readb(struct virtio_device *vdev, unsigned offset)
+{
+	u8 val;
+	vdev->config->get(vdev, offset, &val, 1);
+	return val;
+}
+
+static inline u16
+virtio_config_readw(struct virtio_device *vdev, unsigned offset)
+{
+	u16 val;
+	vdev->config->get(vdev, offset, &val, 2);
+	return val;
+}
+
+static inline u32
+virtio_config_readl(struct virtio_device *vdev, unsigned offset)
+{
+	u32 val;
+	vdev->config->get(vdev, offset, &val, 4);
+	return val;
+}
+
+static inline void
+virtio_config_writeb(struct virtio_device *vdev, unsigned offset, u8 val)
+{
+	vdev->config->set(vdev, offset, &val, 1);
+}
+
+static inline void
+virtio_config_writew(struct virtio_device *vdev, unsigned offset, u16 val)
+{
+	vdev->config->set(vdev, offset, &val, 2);
+}
+
+static inline void
+virtio_config_writel(struct virtio_device *vdev, unsigned offset, u32 val)
+{
+	vdev->config->set(vdev, offset, &val, 4);
+}
+
+/******************************************************
+ * virtio-mmio
+ ******************************************************/
+
+#define VIRTIO_MMIO_DEVICE_ID	0x008
+#define VIRTIO_MMIO_CONFIG	0x100
+
+#define to_virtio_mmio_device(vdev_ptr) \
+	container_of(vdev_ptr, struct virtio_mmio_device, vdev)
+
+struct virtio_mmio_device {
+	struct virtio_device vdev;
+	void *base;
+};
+
+#endif /* _VIRTIO_H_ */
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 12/19] Introduce virtio-testdev
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (9 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 11/19] add minimal virtio support for devtree virtio-mmio Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-12 10:16   ` Paolo Bonzini
  2014-06-11 14:01 ` [PATCH v5 13/19] libcflat: clean up libcflat.h and add string.h Andrew Jones
                   ` (9 subsequent siblings)
  20 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

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>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
---
v4: couple tweaks (added spinlock), no functional changes
---
 lib/virtio-testdev.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/virtio-testdev.h |  18 +++++++
 2 files changed, 155 insertions(+)
 create mode 100644 lib/virtio-testdev.c
 create mode 100644 lib/virtio-testdev.h

diff --git a/lib/virtio-testdev.c b/lib/virtio-testdev.c
new file mode 100644
index 0000000000000..422e0bf4fc35a
--- /dev/null
+++ b/lib/virtio-testdev.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "asm/spinlock.h"
+#include "virtio.h"
+
+#define TESTDEV_NAME		"virtio-testdev"
+#define VIRTIO_ID_TESTDEV	0xffff
+#define TESTDEV_MAJOR_VER	1
+#define TESTDEV_MINOR_VER	1
+
+#define VIRTIO_CONFIG_SIZE	64
+
+enum {
+	VERSION = 1,
+	CLEAR,
+	EXIT,
+};
+
+#define TOKEN_OFFSET		0x0
+#define NARGS_OFFSET		0x4
+#define NRETS_OFFSET		0x8
+#define ARG_OFFSET(n)		(0xc + (n) * 4)
+#define __RET_OFFSET(nargs, n)	(ARG_OFFSET(nargs) + (n) * 4)
+
+static struct spinlock lock;
+static struct virtio_device *vdev;
+
+static u32 testdev_readl(unsigned offset)
+{
+	assert(offset <= (VIRTIO_CONFIG_SIZE - 4));
+	return virtio_config_readl(vdev, offset);
+}
+
+static void testdev_writel(unsigned offset, u32 val)
+{
+	assert(offset <= (VIRTIO_CONFIG_SIZE - 4));
+	virtio_config_writel(vdev, offset, val);
+}
+
+/*
+ * We have to write all args; nargs, nrets, ... first to avoid executing
+ * the token's operation until all args are in place. Then issue the op,
+ * and then read the return values. Reading the return values (or just
+ * sanity checking by reading token) 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, ...)
+{
+	va_list va;
+	unsigned off;
+	u32 n;
+
+	if (!vdev)
+		return;
+
+	spin_lock(&lock);
+
+	testdev_writel(NARGS_OFFSET, nargs);
+	testdev_writel(NRETS_OFFSET, nrets);
+
+	va_start(va, nrets);
+
+	off = ARG_OFFSET(0);
+	n = nargs;
+	while (n--) {
+		testdev_writel(off, va_arg(va, unsigned));
+		off += 4;
+	}
+
+	/* this runs the op, but then resets token to zero */
+	testdev_writel(TOKEN_OFFSET, token);
+	assert(testdev_readl(TOKEN_OFFSET) == 0);
+
+	off = __RET_OFFSET(nargs, 0);
+	n = nrets;
+	while (n--) {
+		u32 *r = va_arg(va, unsigned *);
+		*r = testdev_readl(off);
+		off += 4;
+	}
+
+	spin_unlock(&lock);
+	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)
+{
+	u16 major, minor;
+	u32 version;
+
+	vdev = virtio_bind(VIRTIO_ID_TESTDEV);
+	if (vdev == NULL) {
+		printf("%s: can't find " TESTDEV_NAME ". "
+		       "Is '-device " TESTDEV_NAME "' "
+		       "on the qemu command line?\n", __func__);
+		abort();
+	}
+
+	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("%s: incompatible version of " TESTDEV_NAME ": "
+		       "major = %d, minor = %d. Update %s\n",
+		       __func__, major, minor, u);
+		abort();
+	}
+
+	if (minor > TESTDEV_MINOR_VER)
+		printf("%s: " TESTDEV_NAME " has new features. "
+		       "An update of kvm-unit-tests may be possible.\n",
+		       __func__);
+}
diff --git a/lib/virtio-testdev.h b/lib/virtio-testdev.h
new file mode 100644
index 0000000000000..bed9eaf4aca4b
--- /dev/null
+++ b/lib/virtio-testdev.h
@@ -0,0 +1,18 @@
+#ifndef _VIRTIO_TESTDEV_H_
+#define _VIRTIO_TESTDEV_H_
+/*
+ * virtio-testdev is a driver for the virtio-testdev qemu device.
+ * The virtio-testdev device exposes a simple control interface to
+ * qemu for kvm-unit-tests through virtio.
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#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.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 13/19] libcflat: clean up libcflat.h and add string.h
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (10 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 12/19] Introduce virtio-testdev Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-12 10:52   ` Paolo Bonzini
  2014-06-11 14:01 ` [PATCH v5 14/19] printf: support field padding Andrew Jones
                   ` (8 subsequent siblings)
  20 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Use libgcc's stddef.h and stdint.h, and then remove the redundant
defines from libcflat.h. Also separate out the string function
declarations into a new file string.h. These changes have no affect
on code including libcflat.h, but are needed in order to compile an
unmodified libfdt for kvm-unit-tests using an arm cross-compiler.
While at it, add strcpy.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 lib/libcflat.h | 55 +++++++++++++++++++++----------------------------------
 lib/string.c   |  6 ++++++
 lib/string.h   | 15 +++++++++++++++
 3 files changed, 42 insertions(+), 34 deletions(-)
 create mode 100644 lib/string.h

diff --git a/lib/libcflat.h b/lib/libcflat.h
index 5939cee54890b..404560cd103e5 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -21,60 +21,47 @@
 #define __LIBCFLAT_H
 
 #include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include "string.h"
 
 #define __unused __attribute__((__unused__))
 
 #define xstr(s) xxstr(s)
 #define xxstr(s) #s
 
-typedef unsigned char u8;
-typedef signed char s8;
-typedef unsigned short u16;
-typedef signed short s16;
-typedef unsigned u32;
-typedef signed s32;
-typedef unsigned long ulong;
-typedef unsigned long long u64;
-typedef signed long long s64;
-typedef unsigned long size_t;
-typedef _Bool bool;
-
-#define true 1
+typedef uint8_t		u8;
+typedef int8_t		s8;
+typedef uint16_t	u16;
+typedef int16_t		s16;
+typedef uint32_t	u32;
+typedef int32_t		s32;
+typedef uint64_t	u64;
+typedef int64_t		s64;
+typedef unsigned long	ulong;
+
+typedef _Bool		bool;
 #define false 0
+#define true  1
 
+extern void puts(const char *s);
 extern void exit(int code);
 
-extern unsigned long strlen(const char *buf);
-extern char *strcat(char *dest, const char *src);
-extern int strcmp(const char *a, const char *b);
-extern char *strchr(const char *s, int c);
-
 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 long atol(const char *ptr);
 
-extern void puts(const char *s);
-
-extern void *memset(void *s, int c, size_t n);
-extern void *memcpy(void *dest, const void *src, size_t n);
-extern int memcmp(const void *s1, const void *s2, size_t n);
-extern void *memmove(void *dest, const void *src, size_t n);
-extern void *memchr(const void *s, int c, size_t n);
+void report(const char *msg_fmt, bool pass, ...);
+int report_summary(void);
 
-extern long atol(const char *ptr);
-#define ARRAY_SIZE(_a)  (sizeof(_a)/sizeof((_a)[0]))
+#define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
 
-#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
 #define container_of(ptr, type, member) ({				\
 	const typeof( ((type *)0)->member ) *__mptr = (ptr);		\
 	(type *)( (char *)__mptr - offsetof(type,member) );})
 
-#define NULL ((void *)0UL)
-
-void report(const char *msg_fmt, bool pass, ...);
-int report_summary(void);
-
-#define abort() exit(64)		/* 129 exit status from qemu */
+#define abort() exit(64) /* 129 exit status from qemu */
 #define assert(cond)							\
 do {									\
 	if (!(cond))							\
diff --git a/lib/string.c b/lib/string.c
index fe90c8b1289f2..026f50252287c 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -20,6 +20,12 @@ char *strcat(char *dest, const char *src)
     return dest;
 }
 
+char *strcpy(char *dest, const char *src)
+{
+    *dest = 0;
+    return strcat(dest, src);
+}
+
 int strcmp(const char *a, const char *b)
 {
     while (*a == *b) {
diff --git a/lib/string.h b/lib/string.h
new file mode 100644
index 0000000000000..dbab368b1b9e4
--- /dev/null
+++ b/lib/string.h
@@ -0,0 +1,15 @@
+#ifndef __STRING_H
+#define __STRING_H
+
+extern unsigned long strlen(const char *buf);
+extern char *strcat(char *dest, const char *src);
+extern char *strcpy(char *dest, const char *src);
+extern int strcmp(const char *a, const char *b);
+extern char *strchr(const char *s, int c);
+extern void *memset(void *s, int c, size_t n);
+extern void *memcpy(void *dest, const void *src, size_t n);
+extern int memcmp(const void *s1, const void *s2, size_t n);
+extern void *memmove(void *dest, const void *src, size_t n);
+extern void *memchr(const void *s, int c, size_t n);
+
+#endif /* _STRING_H */
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 14/19] printf: support field padding
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (11 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 13/19] libcflat: clean up libcflat.h and add string.h Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 15/19] arm: initial drop Andrew Jones
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Support format flags for field padding, such as "%08x", allowing
register dumps to be easier on the eyes.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 lib/printf.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 68 insertions(+), 14 deletions(-)

diff --git a/lib/printf.c b/lib/printf.c
index 867eb1926f742..89308fb26b7d2 100644
--- a/lib/printf.c
+++ b/lib/printf.c
@@ -6,6 +6,11 @@ typedef struct pstream {
     int added;
 } pstream_t;
 
+typedef struct strprops {
+    char pad;
+    int npad;
+} strprops_t;
+
 static void addchar(pstream_t *p, char c)
 {
     if (p->remain) {
@@ -15,15 +20,35 @@ static void addchar(pstream_t *p, char c)
     ++p->added;
 }
 
-void print_str(pstream_t *p, const char *s)
+void print_str(pstream_t *p, const char *s, strprops_t props)
 {
+    const char *s_orig = s;
+    int npad = props.npad;
+
+    if (npad > 0) {
+	npad -= strlen(s_orig);
+	while (npad > 0) {
+	    addchar(p, props.pad);
+	    --npad;
+	}
+    }
+
     while (*s)
 	addchar(p, *s++);
+
+    if (npad < 0) {
+	props.pad = ' '; /* ignore '0' flag with '-' flag */
+	npad += strlen(s_orig);
+	while (npad < 0) {
+	    addchar(p, props.pad);
+	    ++npad;
+	}
+    }
 }
 
 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, int base, strprops_t props)
 {
     char buf[sizeof(long) * 3 + 2], *p = buf;
     int s = 0, i;
@@ -54,10 +79,11 @@ void print_int(pstream_t *ps, long long n, int base)
 
     *p = 0;
 
-    print_str(ps, buf);
+    print_str(ps, buf, props);
 }
 
-void print_unsigned(pstream_t *ps, unsigned long long n, int base)
+void print_unsigned(pstream_t *ps, unsigned long long n, int base,
+		    strprops_t props)
 {
     char buf[sizeof(long) * 3 + 1], *p = buf;
     int i;
@@ -80,7 +106,23 @@ void print_unsigned(pstream_t *ps, unsigned long long n, int base)
 
     *p = 0;
 
-    print_str(ps, buf);
+    print_str(ps, buf, props);
+}
+
+static int fmtnum(const char **fmt)
+{
+    const char *f = *fmt;
+    int len = 0, num;
+
+    if (*f == '-')
+	++f, ++len;
+
+    while (*f >= '0' && *f <= '9')
+	++f, ++len;
+
+    num = atol(*fmt);
+    *fmt += len;
+    return num;
 }
 
 int vsnprintf(char *buf, int size, const char *fmt, va_list va)
@@ -93,6 +135,9 @@ int vsnprintf(char *buf, int size, const char *fmt, va_list va)
     while (*fmt) {
 	char f = *fmt++;
 	int nlong = 0;
+	strprops_t props;
+	memset(&props, 0, sizeof(props));
+	props.pad = ' ';
 
 	if (f != '%') {
 	    addchar(&s, f);
@@ -110,41 +155,50 @@ int vsnprintf(char *buf, int size, const char *fmt, va_list va)
 	case '\0':
 	    --fmt;
 	    break;
+	case '0':
+	    props.pad = '0';
+	    ++fmt;
+	    /* fall through */
+	case '1'...'9':
+	case '-':
+	    --fmt;
+	    props.npad = fmtnum(&fmt);
+	    goto morefmt;
 	case 'l':
 	    ++nlong;
 	    goto morefmt;
 	case 'd':
 	    switch (nlong) {
 	    case 0:
-		print_int(&s, va_arg(va, int), 10);
+		print_int(&s, va_arg(va, int), 10, props);
 		break;
 	    case 1:
-		print_int(&s, va_arg(va, long), 10);
+		print_int(&s, va_arg(va, long), 10, props);
 		break;
 	    default:
-		print_int(&s, va_arg(va, long long), 10);
+		print_int(&s, va_arg(va, long long), 10, props);
 		break;
 	    }
 	    break;
 	case 'x':
 	    switch (nlong) {
 	    case 0:
-		print_unsigned(&s, va_arg(va, unsigned), 16);
+		print_unsigned(&s, va_arg(va, unsigned), 16, props);
 		break;
 	    case 1:
-		print_unsigned(&s, va_arg(va, unsigned long), 16);
+		print_unsigned(&s, va_arg(va, unsigned long), 16, props);
 		break;
 	    default:
-		print_unsigned(&s, va_arg(va, unsigned long long), 16);
+		print_unsigned(&s, va_arg(va, unsigned long long), 16, props);
 		break;
 	    }
 	    break;
 	case 'p':
-	    print_str(&s, "0x");
-	    print_unsigned(&s, (unsigned long)va_arg(va, void *), 16);
+	    print_str(&s, "0x", props);
+	    print_unsigned(&s, (unsigned long)va_arg(va, void *), 16, props);
 	    break;
 	case 's':
-	    print_str(&s, va_arg(va, const char *));
+	    print_str(&s, va_arg(va, const char *), props);
 	    break;
 	default:
 	    addchar(&s, f);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 15/19] arm: initial drop
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (12 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 14/19] printf: support field padding Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-14 14:16   ` Christoffer Dall
  2014-06-11 14:01 ` [PATCH v5 16/19] arm: Add spinlock implementation Andrew Jones
                   ` (6 subsequent siblings)
  20 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

This is the initial drop of the arm test framework and a first test
that just checks that setup completed (a selftest). kvm isn't needed
to run this test unless testing with smp > 1.

Try it out with
  yum install gcc-arm-linux-gnu
  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>
---
v5:
  - memregions: check freemem_start is in bounds and document
  - selftest: rename testnam => testname and properly init it
  - io.c: use writeb instead of writel in puts() and use ioremap
  - arm/run script update for new qemu ('-device ?' now requires -machine)
  - couple other minor changes to setup.c and io.c [Christoffer Dall]
v4:
  - moved fdt to just after stacktop (it was in the middle of free memory)
  - switched from using heap to memregions
  - get nr_cpus and added smp=<num> test
  - added barrier.h
  - use new report()/report_summary()
  - config/config-arm.mak cleanup
---
 arm/cstart.S           |  35 ++++++++++++
 arm/flat.lds           |  18 ++++++
 arm/run                |  35 ++++++++++++
 arm/selftest.c         |  89 +++++++++++++++++++++++++++++
 arm/unittests.cfg      |  18 ++++++
 config/config-arm.mak  |  72 ++++++++++++++++++++++++
 configure              |  12 +++-
 lib/argv.c             |   6 ++
 lib/arm/asm/barrier.h  |  18 ++++++
 lib/arm/asm/io.h       |  24 ++++++++
 lib/arm/asm/setup.h    |  63 +++++++++++++++++++++
 lib/arm/asm/spinlock.h |  16 ++++++
 lib/arm/eabi_compat.c  |  20 +++++++
 lib/arm/io.c           |  65 +++++++++++++++++++++
 lib/arm/setup.c        | 149 +++++++++++++++++++++++++++++++++++++++++++++++++
 15 files changed, 638 insertions(+), 2 deletions(-)
 create mode 100644 arm/cstart.S
 create mode 100644 arm/flat.lds
 create mode 100755 arm/run
 create mode 100644 arm/selftest.c
 create mode 100644 arm/unittests.cfg
 create mode 100644 config/config-arm.mak
 create mode 100644 lib/arm/asm/barrier.h
 create mode 100644 lib/arm/asm/io.h
 create mode 100644 lib/arm/asm/setup.h
 create mode 100644 lib/arm/asm/spinlock.h
 create mode 100644 lib/arm/eabi_compat.c
 create mode 100644 lib/arm/io.c
 create mode 100644 lib/arm/setup.c

diff --git a/arm/cstart.S b/arm/cstart.S
new file mode 100644
index 0000000000000..e28251db2950d
--- /dev/null
+++ b/arm/cstart.S
@@ -0,0 +1,35 @@
+/*
+ * Boot entry point and assembler functions for armv7 tests.
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+
+.arm
+
+.section .init
+
+.globl start
+start:
+	/*
+	 * bootloader params are in r0-r2
+	 * See the kernel doc Documentation/arm/Booting
+	 */
+	ldr	sp, =stacktop
+	bl	setup
+
+	/* run the test */
+	ldr	r0, =__argc
+	ldr	r0, [r0]
+	ldr	r1, =__argv
+	bl	main
+	bl	exit
+	b	halt
+
+.text
+
+.globl halt
+halt:
+1:	wfi
+	b	1b
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..627123b7bc9b6
--- /dev/null
+++ b/arm/run
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+if [ ! -f config.mak ]; then
+	echo run ./configure first. See ./configure -h
+	exit 2
+fi
+source config.mak
+
+qemu="${QEMU:-qemu-system-arm}"
+qpath=$(which $qemu 2>/dev/null)
+testdev=virtio-testdev
+
+if [ -z "$qpath" ]; then
+	echo $qemu not found.
+	exit 2
+fi
+
+if ! $qemu -machine '?' 2>&1 | grep 'ARM Virtual Machine' > /dev/null; then
+	echo "$qpath doesn't support mach-virt ('-machine virt'). Exiting."
+	exit 2
+fi
+
+if ! $qemu -machine virt -device '?' 2>&1 | grep $testdev > /dev/null; then
+	echo "$qpath doesn't support $testdev. Exiting."
+	exit 2
+fi
+
+command="$qemu -machine virt,accel=kvm:tcg -device $testdev -cpu $PROCESSOR"
+command+=" -display none -serial stdio -kernel"
+
+echo $command "$@"
+$command "$@"
+ret=$?
+echo Return value from qemu: $ret
+exit $ret
diff --git a/arm/selftest.c b/arm/selftest.c
new file mode 100644
index 0000000000000..bcaecfae17fcd
--- /dev/null
+++ b/arm/selftest.c
@@ -0,0 +1,89 @@
+/*
+ * Test the framework itself. These tests confirm that setup works.
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "asm/setup.h"
+
+#define TESTGRP "selftest"
+
+static char testname[64];
+
+static void testname_set(const char *subtest)
+{
+	strcpy(testname, TESTGRP);
+	if (subtest) {
+		strcat(testname, "::");
+		strcat(testname, subtest);
+	}
+}
+
+static void assert_args(int num_args, int needed_args)
+{
+	if (num_args < needed_args) {
+		printf("%s: not enough arguments\n", testname);
+		abort();
+	}
+}
+
+static char *split_var(char *s, long *val)
+{
+	char *p;
+
+	p = strchr(s, '=');
+	if (!p)
+		return NULL;
+
+	*val = atol(p+1);
+	*p = '\0';
+
+	return s;
+}
+
+static void check_setup(int argc, char **argv)
+{
+	int nr_tests = 0, i;
+	char *var;
+	long val;
+
+	for (i = 0; i < argc; ++i) {
+
+		var = split_var(argv[i], &val);
+		if (!var)
+			continue;
+
+		if (strcmp(argv[i], "mem") == 0) {
+
+			phys_addr_t memsize =
+					memregions[nr_memregions-1].addr
+					+ memregions[nr_memregions-1].size
+					- PHYS_OFFSET;
+			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
+
+			report("%s[%s]", memsize == expected, testname, "mem");
+			++nr_tests;
+
+		} else if (strcmp(argv[i], "smp") == 0) {
+
+			report("%s[%s]", nr_cpus == (int)val, testname, "smp");
+			++nr_tests;
+		}
+	}
+
+	assert_args(nr_tests, 2);
+}
+
+int main(int argc, char **argv)
+{
+	testname_set(NULL);
+	assert_args(argc, 1);
+	testname_set(argv[0]);
+
+	if (strcmp(argv[0], "setup") == 0)
+		check_setup(argc-1, &argv[1]);
+
+	return report_summary();
+}
diff --git a/arm/unittests.cfg b/arm/unittests.cfg
new file mode 100644
index 0000000000000..da9dfd7b1f118
--- /dev/null
+++ b/arm/unittests.cfg
@@ -0,0 +1,18 @@
+# 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 test case is specific to one
+# groups = group1 group2 # Used to identify test cases with run_tests -g ...
+
+#
+# Test that the configured number of processors (smp = <num>), and
+# that the configured amount of memory (-m <MB>) are correctly setup
+# by the framework.
+#
+[selftest::setup]
+file = selftest.flat
+smp  = 1
+extra_params = -m 256 -append 'setup smp=1 mem=256'
+groups = selftest
diff --git a/config/config-arm.mak b/config/config-arm.mak
new file mode 100644
index 0000000000000..915b1cc318d79
--- /dev/null
+++ b/config/config-arm.mak
@@ -0,0 +1,72 @@
+#
+# arm makefile
+#
+# Authors: Andrew Jones <drjones@redhat.com>
+#
+
+tests-common = \
+	$(TEST_DIR)/selftest.flat
+
+tests =
+
+all: test_cases
+
+##################################################################
+bits = 32
+ldarch = elf32-littlearm
+
+ifeq ($(LOADADDR),)
+	LOADADDR = 0x40000000
+endif
+phys_base = $(LOADADDR)
+kernel_offset = 0x10000
+
+CFLAGS += -D__arm__
+CFLAGS += -marm
+CFLAGS += -mcpu=$(PROCESSOR)
+CFLAGS += -std=gnu99
+CFLAGS += -ffreestanding
+CFLAGS += -Wextra
+CFLAGS += -O2
+CFLAGS += -I lib -I lib/libfdt
+
+cflatobjs += \
+	lib/devicetree.o \
+	lib/virtio.o \
+	lib/virtio-testdev.o \
+	lib/arm/io.o \
+	lib/arm/setup.o
+
+libeabi = lib/arm/libeabi.a
+eabiobjs = lib/arm/eabi_compat.o
+
+libgcc := $(shell $(CC) -m$(ARCH) --print-libgcc-file-name)
+start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
+
+FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
+%.elf: LDFLAGS = $(CFLAGS) -nostdlib
+%.elf: %.o $(FLATLIBS) arm/flat.lds
+	$(CC) $(LDFLAGS) -o $@ \
+		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
+		$(filter %.o, $^) $(FLATLIBS)
+
+%.flat: %.elf
+	$(OBJCOPY) -O binary $^ $@
+
+$(libeabi): $(eabiobjs)
+	$(AR) rcs $@ $^
+
+arch_clean: libfdt_clean
+	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
+	      $(TEST_DIR)/.*.d lib/arm/.*.d
+
+##################################################################
+
+tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
+
+cstart.o = $(TEST_DIR)/cstart.o
+
+test_cases: $(tests-common) $(tests)
+
+$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
+
diff --git a/configure b/configure
index 8a81bf92e27b7..f92f585724bb1 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,12 @@ while [[ "$1" = -* ]]; do
 	    ;;
     esac
 done
+[ -z "$processor" ] && processor="$arch"
+
+if [ "$processor" = "arm" ]; then
+    processor="cortex-a15"
+fi
+
 if [ -z "$testdir" -a \( "$arch" = "i386" -o "$arch" = "x86_64" \) ]; then
     testdir=x86
 elif [ -z "$testdir" ]; then
@@ -80,6 +86,7 @@ if [ -f $testdir/run ]; then
 fi
 
 # check for dependent 32 bit libraries
+if [ "$arch" != "arm" ]; then
 cat << EOF > lib_test.c
 #include <stdc++.h>
 #include <boost_thread-mt.h>
@@ -94,6 +101,7 @@ if [ $exit -eq 0 ]; then
     api=true
 fi
 rm -f lib_test.c
+fi
 
 # link lib/asm for the architecture
 rm -f lib/asm
diff --git a/lib/argv.c b/lib/argv.c
index 4ee54a6eeac3e..078a05faffebf 100644
--- a/lib/argv.c
+++ b/lib/argv.c
@@ -31,3 +31,9 @@ void __setup_args(void)
     }
     __argc = argv - __argv;
 }
+
+void setup_args(char *args)
+{
+    __args = args;
+    __setup_args();
+}
diff --git a/lib/arm/asm/barrier.h b/lib/arm/asm/barrier.h
new file mode 100644
index 0000000000000..acaeab5123431
--- /dev/null
+++ b/lib/arm/asm/barrier.h
@@ -0,0 +1,18 @@
+#ifndef _ASMARM_BARRIER_H_
+#define _ASMARM_BARRIER_H_
+/*
+ * Adapted form arch/arm/include/asm/barrier.h
+ */
+
+#define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory")
+#define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
+#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
+
+#define mb()		dsb()
+#define rmb()		dsb()
+#define wmb()		dsb(st)
+#define smp_mb()	dmb(ish)
+#define smp_rmb()	smp_mb()
+#define smp_wmb()	dmb(ishst)
+
+#endif /* _ASMARM_BARRIER_H_ */
diff --git a/lib/arm/asm/io.h b/lib/arm/asm/io.h
new file mode 100644
index 0000000000000..51ec6e9aa2e99
--- /dev/null
+++ b/lib/arm/asm/io.h
@@ -0,0 +1,24 @@
+#ifndef _ASMARM_IO_H_
+#define _ASMARM_IO_H_
+#include "libcflat.h"
+#include "asm/barrier.h"
+
+#define __bswap16 bswap16
+static inline u16 bswap16(u16 val)
+{
+	u16 ret;
+	asm volatile("rev16 %0, %1" : "=r" (ret) :  "r" (val));
+	return ret;
+}
+
+#define __bswap32 bswap32
+static inline u32 bswap32(u32 val)
+{
+	u32 ret;
+	asm volatile("rev %0, %1" : "=r" (ret) :  "r" (val));
+	return ret;
+}
+
+#include "asm-generic/io.h"
+
+#endif /* _ASMARM_IO_H_ */
diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
new file mode 100644
index 0000000000000..8aedf6e672541
--- /dev/null
+++ b/lib/arm/asm/setup.h
@@ -0,0 +1,63 @@
+#ifndef _ASMARM_SETUP_H_
+#define _ASMARM_SETUP_H_
+/*
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+
+#define NR_CPUS			8
+extern u32 cpus[NR_CPUS];
+extern int nr_cpus;
+
+typedef u64 phys_addr_t;
+
+/*
+ * memregions implement a very simple allocator which allows physical
+ * memory to be partitioned into regions until all memory is allocated.
+ * Also, as long as not all memory has been allocated, one region (the
+ * highest indexable region) is used to represent the start and size of
+ * the remaining free memory. This means that there will always be a
+ * minimum of two regions: one for the unit test code, initially loaded
+ * at the base of physical memory (PHYS_OFFSET), and another for the
+ * remaining free memory.
+ *
+ * Note: This is such a simple allocator that there is no way to free
+ * a memregion. For more complicated memory management a single region
+ * can be allocated, but then have its memory managed by a more
+ * sophisticated allocator, e.g. a page allocator.
+ */
+#define NR_MEMREGIONS		16
+struct memregion {
+	phys_addr_t addr;
+	phys_addr_t size;
+	bool free;
+};
+
+extern struct memregion memregions[NR_MEMREGIONS];
+extern int nr_memregions;
+
+/*
+ * memregion_new returns a new memregion of size @size, or NULL if
+ * there isn't enough free memory to satisfy the request.
+ */
+extern struct memregion *memregion_new(phys_addr_t size);
+
+/*
+ * memregions_show outputs all memregions with the following format
+ *   <start_addr>-<end_addr> [<USED|FREE>]
+ */
+extern void memregions_show(void);
+
+#define PHYS_OFFSET		({ memregions[0].addr; })
+#define PHYS_SHIFT		40
+#define PHYS_SIZE		(1ULL << PHYS_SHIFT)
+#define PHYS_MASK		(PHYS_SIZE - 1ULL)
+
+#define PAGE_SHIFT		12
+#define PAGE_SIZE		(1UL << PAGE_SHIFT)
+#define PAGE_MASK		(~(PAGE_SIZE - 1UL))
+#define PAGE_ALIGN(addr)	(((addr) + (PAGE_SIZE-1UL)) & PAGE_MASK)
+
+#endif /* _ASMARM_SETUP_H_ */
diff --git a/lib/arm/asm/spinlock.h b/lib/arm/asm/spinlock.h
new file mode 100644
index 0000000000000..04f5a1a5538e2
--- /dev/null
+++ b/lib/arm/asm/spinlock.h
@@ -0,0 +1,16 @@
+#ifndef _ASMARM_SPINLOCK_H_
+#define _ASMARM_SPINLOCK_H_
+
+struct spinlock {
+	int v;
+};
+
+//TODO
+static inline void spin_lock(struct spinlock *lock __unused)
+{
+}
+static inline void spin_unlock(struct spinlock *lock __unused)
+{
+}
+
+#endif /* _ASMARM_SPINLOCK_H_ */
diff --git a/lib/arm/eabi_compat.c b/lib/arm/eabi_compat.c
new file mode 100644
index 0000000000000..59d624dcd9277
--- /dev/null
+++ b/lib/arm/eabi_compat.c
@@ -0,0 +1,20 @@
+/*
+ * Adapted from u-boot's arch/arm/lib/eabi_compat.c
+ */
+#include "libcflat.h"
+
+int raise(int signum __unused)
+{
+	printf("Divide by zero!\n");
+	abort();
+	return 0;
+}
+
+/* Dummy functions to avoid linker complaints */
+void __aeabi_unwind_cpp_pr0(void)
+{
+}
+
+void __aeabi_unwind_cpp_pr1(void)
+{
+}
diff --git a/lib/arm/io.c b/lib/arm/io.c
new file mode 100644
index 0000000000000..114d6517a959e
--- /dev/null
+++ b/lib/arm/io.c
@@ -0,0 +1,65 @@
+/*
+ * Each architecture must implement puts() and exit() with the I/O
+ * devices exposed from QEMU, e.g. pl011 and virtio-testdev. That's
+ * what's done here, along with initialization functions for those
+ * devices.
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "devicetree.h"
+#include "virtio-testdev.h"
+#include "asm/spinlock.h"
+#include "asm/io.h"
+
+extern void halt(int code);
+
+/*
+ * Use this guess for the pl011 base in order to make an attempt at
+ * having earlier printf support. We'll overwrite it with the real
+ * base address that we read from the device tree later.
+ */
+#define QEMU_MACH_VIRT_PL011_BASE 0x09000000UL
+
+static struct spinlock uart_lock;
+static volatile u8 *uart0_base = (u8 *)QEMU_MACH_VIRT_PL011_BASE;
+
+static void uart0_init(void)
+{
+	const char *compatible = "arm,pl011";
+	struct dt_pbus_reg base;
+	int ret;
+
+	ret = dt_pbus_get_base_compatible(compatible, &base);
+	assert(ret == 0 || ret == -FDT_ERR_NOTFOUND);
+
+	if (ret) {
+		printf("%s: %s not found in the device tree, aborting...\n",
+			__func__, compatible);
+		abort();
+	}
+
+	uart0_base = ioremap(base.addr, base.size);
+}
+
+void io_init(void)
+{
+	uart0_init();
+	virtio_testdev_init();
+}
+
+void puts(const char *s)
+{
+	spin_lock(&uart_lock);
+	while (*s)
+		writeb(*s++, uart0_base);
+	spin_unlock(&uart_lock);
+}
+
+void exit(int code)
+{
+	virtio_testdev_exit(code);
+	halt(code);
+}
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
new file mode 100644
index 0000000000000..68a244aef56b8
--- /dev/null
+++ b/lib/arm/setup.c
@@ -0,0 +1,149 @@
+/*
+ * Initialize machine setup information and I/O.
+ *
+ * After running setup() unit tests may query how many cpus they have
+ * (nr_cpus), how much free memory it has, and at what physical
+ * address that free memory starts (memregions[1].{addr,size}),
+ * printf() and exit() will both work, and (argc, argv) are ready
+ * to be passed to main().
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "libfdt/libfdt.h"
+#include "devicetree.h"
+#include "asm/spinlock.h"
+#include "asm/setup.h"
+
+extern unsigned long stacktop;
+extern void io_init(void);
+extern void setup_args(const char *args);
+
+u32 cpus[NR_CPUS] = { [0 ... NR_CPUS-1] = (~0UL) };
+int nr_cpus;
+
+static struct spinlock memregion_lock;
+struct memregion memregions[NR_MEMREGIONS];
+int nr_memregions;
+
+static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
+{
+	assert(nr_cpus < NR_CPUS);
+	cpus[nr_cpus++] = regval;
+}
+
+static void cpu_init(void)
+{
+	nr_cpus = 0;
+	assert(dt_for_each_cpu_node(cpu_set, NULL) == 0);
+}
+
+static void memregions_init(phys_addr_t freemem_start)
+{
+	/* we only expect one membank to be defined in the DT */
+	struct dt_pbus_reg regs[1];
+	phys_addr_t addr, size, mem_end;
+
+	nr_memregions = dt_get_memory_params(regs, 1);
+
+	assert(nr_memregions > 0);
+
+	addr = regs[0].addr;
+	size = regs[0].size;
+	mem_end = addr + size;
+
+	assert(!(addr & ~PHYS_MASK) && !((mem_end-1) & ~PHYS_MASK));
+
+	memregions[0].addr = PAGE_ALIGN(addr); /* PHYS_OFFSET */
+
+	freemem_start = PAGE_ALIGN(freemem_start);
+	assert(freemem_start >= PHYS_OFFSET && freemem_start < mem_end);
+
+	memregions[0].size = freemem_start - PHYS_OFFSET;
+	memregions[1].addr = freemem_start;
+	memregions[1].size = mem_end - freemem_start;
+	memregions[1].free = true;
+	nr_memregions = 2;
+
+#ifdef __arm__
+	/*
+	 * make sure 32-bit unit tests don't have any surprises when
+	 * running without virtual memory, by ensuring the initial
+	 * memory region uses 32-bit addresses. Other memory regions
+	 * may have > 32-bit addresses though, and the unit tests are
+	 * free to do as they wish with that.
+	 */
+	assert(!(memregions[0].addr >> 32));
+	assert(!((memregions[0].addr + memregions[0].size - 1) >> 32));
+#endif
+}
+
+struct memregion *memregion_new(phys_addr_t size)
+{
+	phys_addr_t freemem_start, mem_end;
+	struct memregion *mr;
+
+	spin_lock(&memregion_lock);
+
+	mr = &memregions[nr_memregions-1];
+
+	if (!mr->free || mr->size < size) {
+		printf("%s: requested=0x%llx, free=0x%llx.\n", size,
+				mr->free ? mr->size : 0ULL);
+		return NULL;
+	}
+
+	mem_end = mr->addr + mr->size;
+
+	mr->size = size;
+	mr->free = false;
+
+	freemem_start = PAGE_ALIGN(mr->addr + size);
+
+	if (freemem_start < mem_end && nr_memregions < NR_MEMREGIONS) {
+		mr->size = freemem_start - mr->addr;
+		memregions[nr_memregions].addr = freemem_start;
+		memregions[nr_memregions].size = mem_end - freemem_start;
+		memregions[nr_memregions].free = true;
+		++nr_memregions;
+	}
+
+	spin_unlock(&memregion_lock);
+
+	return mr;
+}
+
+void memregions_show(void)
+{
+	int i;
+	for (i = 0; i < nr_memregions; ++i)
+		printf("%016llx-%016llx [%s]\n",
+			memregions[i].addr,
+			memregions[i].addr + memregions[i].size - 1,
+			memregions[i].free ? "FREE" : "USED");
+}
+
+void setup(unsigned long arg __unused, unsigned long id __unused,
+	   const void *fdt)
+{
+	const char *bootargs;
+	u32 fdt_size;
+
+	/*
+	 * Move the fdt to just above the stack. The free memory
+	 * then starts just after the fdt.
+	 */
+	fdt_size = fdt_totalsize(fdt);
+	assert(fdt_move(fdt, &stacktop, fdt_size) == 0);
+	assert(dt_init(&stacktop) == 0);
+
+	memregions_init((unsigned long)&stacktop + fdt_size);
+
+	io_init();
+	cpu_init();
+
+	assert(dt_get_bootargs(&bootargs) == 0);
+	setup_args(bootargs);
+}
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 16/19] arm: Add spinlock implementation
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (13 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 15/19] arm: initial drop Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 17/19] arm: Add IO accessors to avoid register-writeback Andrew Jones
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

From: Christoffer Dall <christoffer.dall@linaro.org>

Add simple busy-wait spinlock implementation for ARM.

Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 config/config-arm.mak  |  3 ++-
 lib/arm/asm/spinlock.h |  9 ++-------
 lib/arm/spinlock.c     | 28 ++++++++++++++++++++++++++++
 3 files changed, 32 insertions(+), 8 deletions(-)
 create mode 100644 lib/arm/spinlock.c

diff --git a/config/config-arm.mak b/config/config-arm.mak
index 915b1cc318d79..d150807ec6fe4 100644
--- a/config/config-arm.mak
+++ b/config/config-arm.mak
@@ -35,7 +35,8 @@ cflatobjs += \
 	lib/virtio.o \
 	lib/virtio-testdev.o \
 	lib/arm/io.o \
-	lib/arm/setup.o
+	lib/arm/setup.o \
+	lib/arm/spinlock.o
 
 libeabi = lib/arm/libeabi.a
 eabiobjs = lib/arm/eabi_compat.o
diff --git a/lib/arm/asm/spinlock.h b/lib/arm/asm/spinlock.h
index 04f5a1a5538e2..2118a4b3751e0 100644
--- a/lib/arm/asm/spinlock.h
+++ b/lib/arm/asm/spinlock.h
@@ -5,12 +5,7 @@ struct spinlock {
 	int v;
 };
 
-//TODO
-static inline void spin_lock(struct spinlock *lock __unused)
-{
-}
-static inline void spin_unlock(struct spinlock *lock __unused)
-{
-}
+extern void spin_lock(struct spinlock *lock);
+extern void spin_unlock(struct spinlock *lock);
 
 #endif /* _ASMARM_SPINLOCK_H_ */
diff --git a/lib/arm/spinlock.c b/lib/arm/spinlock.c
new file mode 100644
index 0000000000000..d8a6d4c3383d6
--- /dev/null
+++ b/lib/arm/spinlock.c
@@ -0,0 +1,28 @@
+#include "libcflat.h"
+#include "asm/spinlock.h"
+#include "asm/barrier.h"
+
+void spin_lock(struct spinlock *lock)
+{
+	u32 val, fail;
+
+	dmb();
+	do {
+		asm volatile(
+		"1:	ldrex	%0, [%2]\n"
+		"	teq	%0, #0\n"
+		"	bne	1b\n"
+		"	mov	%0, #1\n"
+		"	strex	%1, %0, [%2]\n"
+		: "=&r" (val), "=&r" (fail)
+		: "r" (&lock->v)
+		: "cc" );
+	} while (fail);
+	dmb();
+}
+
+void spin_unlock(struct spinlock *lock)
+{
+	lock->v = 0;
+	dmb();
+}
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 17/19] arm: Add IO accessors to avoid register-writeback
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (14 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 16/19] arm: Add spinlock implementation Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 18/19] arm: add useful headers from the Linux kernel Andrew Jones
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

From: Christoffer Dall <christoffer.dall@linaro.org>

Add IO accessor functions to the arm library functions to avoid
register-writeback IO accessors that are not yet supported by the
kernel.

Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 lib/arm/asm/io.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/lib/arm/asm/io.h b/lib/arm/asm/io.h
index 51ec6e9aa2e99..1d0abb7d9f405 100644
--- a/lib/arm/asm/io.h
+++ b/lib/arm/asm/io.h
@@ -3,6 +3,9 @@
 #include "libcflat.h"
 #include "asm/barrier.h"
 
+#define __iomem
+#define __force
+
 #define __bswap16 bswap16
 static inline u16 bswap16(u16 val)
 {
@@ -19,6 +22,60 @@ static inline u32 bswap32(u32 val)
 	return ret;
 }
 
+#define __raw_readb __raw_readb
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+	u8 val;
+	asm volatile("ldrb %1, %0"
+		     : "+Qo" (*(volatile u8 __force *)addr),
+		       "=r" (val));
+	return val;
+}
+
+#define __raw_readw __raw_readw
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+	u16 val;
+	asm volatile("ldrh %1, %0"
+		     : "+Q" (*(volatile u16 __force *)addr),
+		       "=r" (val));
+	return val;
+}
+
+#define __raw_readl __raw_readl
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+	u32 val;
+	asm volatile("ldr %1, %0"
+		     : "+Qo" (*(volatile u32 __force *)addr),
+		       "=r" (val));
+	return val;
+}
+
+#define __raw_writeb __raw_writeb
+static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
+{
+	asm volatile("strb %1, %0"
+		     : "+Qo" (*(volatile u8 __force *)addr)
+		     : "r" (val));
+}
+
+#define __raw_writew __raw_writew
+static inline void __raw_writew(u16 val, volatile void __iomem *addr)
+{
+	asm volatile("strh %1, %0"
+		     : "+Q" (*(volatile u16 __force *)addr)
+		     : "r" (val));
+}
+
+#define __raw_writel __raw_writel
+static inline void __raw_writel(u32 val, volatile void __iomem *addr)
+{
+	asm volatile("str %1, %0"
+		     : "+Qo" (*(volatile u32 __force *)addr)
+		     : "r" (val));
+}
+
 #include "asm-generic/io.h"
 
 #endif /* _ASMARM_IO_H_ */
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 18/19] arm: add useful headers from the Linux kernel
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (15 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 17/19] arm: Add IO accessors to avoid register-writeback Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-11 14:01 ` [PATCH v5 19/19] arm: vectors support Andrew Jones
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

We're going to need PSR bit defines and pt_regs. We'll also need
pt_regs offsets in assembly code. This patch adapts the Linux
kernel's ptrace.h and generated/asm-offsets.h to this framework.
It also adapts cp15.h from the kernel, since we'll need bit defines
from there too.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
v4: much improved asm-offsets.h generation based on Kbuild
---
 config/asm-offsets.mak    |  41 +++++++++++++++++++
 config/config-arm.mak     |   9 ++++-
 lib/arm/.gitignore        |   1 +
 lib/arm/asm-offsets.c     |  39 ++++++++++++++++++
 lib/arm/asm/asm-offsets.h |   1 +
 lib/arm/asm/cp15.h        |  37 +++++++++++++++++
 lib/arm/asm/ptrace.h      | 100 ++++++++++++++++++++++++++++++++++++++++++++++
 lib/generated/.gitignore  |   1 +
 8 files changed, 227 insertions(+), 2 deletions(-)
 create mode 100644 config/asm-offsets.mak
 create mode 100644 lib/arm/.gitignore
 create mode 100644 lib/arm/asm-offsets.c
 create mode 100644 lib/arm/asm/asm-offsets.h
 create mode 100644 lib/arm/asm/cp15.h
 create mode 100644 lib/arm/asm/ptrace.h
 create mode 100644 lib/generated/.gitignore

diff --git a/config/asm-offsets.mak b/config/asm-offsets.mak
new file mode 100644
index 0000000000000..b2578a6692f33
--- /dev/null
+++ b/config/asm-offsets.mak
@@ -0,0 +1,41 @@
+#
+# asm-offsets adapted from the kernel, see
+#   Kbuild
+#   scripts/Kbuild.include
+#   scripts/Makefile.build
+#
+#   Authors: Andrew Jones <drjones@redhat.com>
+#
+
+define sed-y
+	"/^->/{s:->#\(.*\):/* \1 */:; \
+	s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
+	s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
+	s:->::; p;}"
+endef
+
+define make_asm_offsets
+	(set -e; \
+	 echo "#ifndef __ASM_OFFSETS_H__"; \
+	 echo "#define __ASM_OFFSETS_H__"; \
+	 echo "/*"; \
+	 echo " * Generated file. DO NOT MODIFY."; \
+	 echo " *"; \
+	 echo " */"; \
+	 echo ""; \
+	 sed -ne $(sed-y) $<; \
+	 echo ""; \
+	 echo "#endif" ) > $@
+endef
+
+$(asm-offsets:.h=.s): $(asm-offsets:.h=.c)
+	$(CC) $(CFLAGS) -fverbose-asm -S -o $@ $<
+
+$(asm-offsets): $(asm-offsets:.h=.s)
+	$(call make_asm_offsets)
+	cp -f $(asm-offsets) lib/generated
+
+asm_offsets_clean:
+	$(RM) $(asm-offsets) $(asm-offsets:.h=.s) \
+	      $(addprefix lib/generated/,$(notdir $(asm-offsets)))
+
diff --git a/config/config-arm.mak b/config/config-arm.mak
index d150807ec6fe4..ead191f4954f4 100644
--- a/config/config-arm.mak
+++ b/config/config-arm.mak
@@ -30,6 +30,9 @@ CFLAGS += -Wextra
 CFLAGS += -O2
 CFLAGS += -I lib -I lib/libfdt
 
+asm-offsets = lib/arm/asm-offsets.h
+include config/asm-offsets.mak
+
 cflatobjs += \
 	lib/devicetree.o \
 	lib/virtio.o \
@@ -57,7 +60,7 @@ FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
 $(libeabi): $(eabiobjs)
 	$(AR) rcs $@ $^
 
-arch_clean: libfdt_clean
+arch_clean: libfdt_clean asm_offsets_clean
 	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
 	      $(TEST_DIR)/.*.d lib/arm/.*.d
 
@@ -67,7 +70,9 @@ tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
 
 cstart.o = $(TEST_DIR)/cstart.o
 
-test_cases: $(tests-common) $(tests)
+generated_files = $(asm-offsets)
+
+test_cases: $(generated_files) $(tests-common) $(tests)
 
 $(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
 
diff --git a/lib/arm/.gitignore b/lib/arm/.gitignore
new file mode 100644
index 0000000000000..84872bf197c67
--- /dev/null
+++ b/lib/arm/.gitignore
@@ -0,0 +1 @@
+asm-offsets.[hs]
diff --git a/lib/arm/asm-offsets.c b/lib/arm/asm-offsets.c
new file mode 100644
index 0000000000000..a9c349d2d427c
--- /dev/null
+++ b/lib/arm/asm-offsets.c
@@ -0,0 +1,39 @@
+/*
+ * Adapted from arch/arm/kernel/asm-offsets.c
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "asm/ptrace.h"
+
+#define DEFINE(sym, val) \
+	asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+#define OFFSET(sym, str, mem)	DEFINE(sym, offsetof(struct str, mem))
+#define COMMENT(x)		asm volatile("\n->#" x)
+#define BLANK()			asm volatile("\n->" : : )
+
+int main(void)
+{
+	OFFSET(S_R0, pt_regs, ARM_r0);
+	OFFSET(S_R1, pt_regs, ARM_r1);
+	OFFSET(S_R2, pt_regs, ARM_r2);
+	OFFSET(S_R3, pt_regs, ARM_r3);
+	OFFSET(S_R4, pt_regs, ARM_r4);
+	OFFSET(S_R5, pt_regs, ARM_r5);
+	OFFSET(S_R6, pt_regs, ARM_r6);
+	OFFSET(S_R7, pt_regs, ARM_r7);
+	OFFSET(S_R8, pt_regs, ARM_r8);
+	OFFSET(S_R9, pt_regs, ARM_r9);
+	OFFSET(S_R10, pt_regs, ARM_r10);
+	OFFSET(S_FP, pt_regs, ARM_fp);
+	OFFSET(S_IP, pt_regs, ARM_ip);
+	OFFSET(S_SP, pt_regs, ARM_sp);
+	OFFSET(S_LR, pt_regs, ARM_lr);
+	OFFSET(S_PC, pt_regs, ARM_pc);
+	OFFSET(S_PSR, pt_regs, ARM_cpsr);
+	OFFSET(S_OLD_R0, pt_regs, ARM_ORIG_r0);
+	DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
+	return 0;
+}
diff --git a/lib/arm/asm/asm-offsets.h b/lib/arm/asm/asm-offsets.h
new file mode 100644
index 0000000000000..c2ff2ba6ec417
--- /dev/null
+++ b/lib/arm/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include "generated/asm-offsets.h"
diff --git a/lib/arm/asm/cp15.h b/lib/arm/asm/cp15.h
new file mode 100644
index 0000000000000..7690a48f17f1f
--- /dev/null
+++ b/lib/arm/asm/cp15.h
@@ -0,0 +1,37 @@
+#ifndef _ASMARM_CP15_H_
+#define _ASMARM_CP15_H_
+/*
+ * From the Linux kernel arch/arm/include/asm/cp15.h
+ *
+ * CR1 bits (CP#15 CR1)
+ */
+#define CR_M	(1 << 0)	/* MMU enable				*/
+#define CR_A	(1 << 1)	/* Alignment abort enable		*/
+#define CR_C	(1 << 2)	/* Dcache enable			*/
+#define CR_W	(1 << 3)	/* Write buffer enable			*/
+#define CR_P	(1 << 4)	/* 32-bit exception handler		*/
+#define CR_D	(1 << 5)	/* 32-bit data address range		*/
+#define CR_L	(1 << 6)	/* Implementation defined		*/
+#define CR_B	(1 << 7)	/* Big endian				*/
+#define CR_S	(1 << 8)	/* System MMU protection		*/
+#define CR_R	(1 << 9)	/* ROM MMU protection			*/
+#define CR_F	(1 << 10)	/* Implementation defined		*/
+#define CR_Z	(1 << 11)	/* Implementation defined		*/
+#define CR_I	(1 << 12)	/* Icache enable			*/
+#define CR_V	(1 << 13)	/* Vectors relocated to 0xffff0000	*/
+#define CR_RR	(1 << 14)	/* Round Robin cache replacement	*/
+#define CR_L4	(1 << 15)	/* LDR pc can set T bit			*/
+#define CR_DT	(1 << 16)
+#define CR_HA	(1 << 17)	/* Hardware management of Access Flag	*/
+#define CR_IT	(1 << 18)
+#define CR_ST	(1 << 19)
+#define CR_FI	(1 << 21)	/* Fast interrupt (lower latency mode)	*/
+#define CR_U	(1 << 22)	/* Unaligned access operation		*/
+#define CR_XP	(1 << 23)	/* Extended page tables			*/
+#define CR_VE	(1 << 24)	/* Vectored interrupts			*/
+#define CR_EE	(1 << 25)	/* Exception (Big) Endian		*/
+#define CR_TRE	(1 << 28)	/* TEX remap enable			*/
+#define CR_AFE	(1 << 29)	/* Access flag enable			*/
+#define CR_TE	(1 << 30)	/* Thumb exception enable		*/
+
+#endif /* _ASMARM_CP15_H_ */
diff --git a/lib/arm/asm/ptrace.h b/lib/arm/asm/ptrace.h
new file mode 100644
index 0000000000000..3a4c7532258f6
--- /dev/null
+++ b/lib/arm/asm/ptrace.h
@@ -0,0 +1,100 @@
+#ifndef _ASMARM_PTRACE_H_
+#define _ASMARM_PTRACE_H_
+/*
+ * Adapted from Linux kernel headers
+ *   arch/arm/include/asm/ptrace.h
+ *   arch/arm/include/uapi/asm/ptrace.h
+ */
+
+/*
+ * PSR bits
+ */
+#define USR_MODE	0x00000010
+#define SVC_MODE	0x00000013
+#define FIQ_MODE	0x00000011
+#define IRQ_MODE	0x00000012
+#define ABT_MODE	0x00000017
+#define HYP_MODE	0x0000001a
+#define UND_MODE	0x0000001b
+#define SYSTEM_MODE	0x0000001f
+#define MODE32_BIT	0x00000010
+#define MODE_MASK	0x0000001f
+
+#define PSR_T_BIT	0x00000020	/* >= V4T, but not V7M */
+#define PSR_F_BIT	0x00000040	/* >= V4, but not V7M */
+#define PSR_I_BIT	0x00000080	/* >= V4, but not V7M */
+#define PSR_A_BIT	0x00000100	/* >= V6, but not V7M */
+#define PSR_E_BIT	0x00000200	/* >= V6, but not V7M */
+#define PSR_J_BIT	0x01000000	/* >= V5J, but not V7M */
+#define PSR_Q_BIT	0x08000000	/* >= V5E, including V7M */
+#define PSR_V_BIT	0x10000000
+#define PSR_C_BIT	0x20000000
+#define PSR_Z_BIT	0x40000000
+#define PSR_N_BIT	0x80000000
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f		0xff000000	/* Flags                */
+#define PSR_s		0x00ff0000	/* Status               */
+#define PSR_x		0x0000ff00	/* Extension            */
+#define PSR_c		0x000000ff	/* Control              */
+
+/*
+ * ARMv7 groups of PSR bits
+ */
+#define APSR_MASK	0xf80f0000	/* N, Z, C, V, Q and GE flags */
+#define PSR_ISET_MASK	0x01000010	/* ISA state (J, T) mask */
+#define PSR_IT_MASK	0x0600fc00	/* If-Then execution state mask */
+#define PSR_ENDIAN_MASK	0x00000200	/* Endianness state mask */
+
+#ifndef __ASSEMBLY__
+#include "libcflat.h"
+
+struct pt_regs {
+	unsigned long uregs[18];
+};
+
+#define ARM_cpsr	uregs[16]
+#define ARM_pc		uregs[15]
+#define ARM_lr		uregs[14]
+#define ARM_sp		uregs[13]
+#define ARM_ip		uregs[12]
+#define ARM_fp		uregs[11]
+#define ARM_r10		uregs[10]
+#define ARM_r9		uregs[9]
+#define ARM_r8		uregs[8]
+#define ARM_r7		uregs[7]
+#define ARM_r6		uregs[6]
+#define ARM_r5		uregs[5]
+#define ARM_r4		uregs[4]
+#define ARM_r3		uregs[3]
+#define ARM_r2		uregs[2]
+#define ARM_r1		uregs[1]
+#define ARM_r0		uregs[0]
+#define ARM_ORIG_r0	uregs[17]
+
+#define user_mode(regs) \
+	(((regs)->ARM_cpsr & 0xf) == 0)
+
+#define processor_mode(regs) \
+	((regs)->ARM_cpsr & MODE_MASK)
+
+#define interrupts_enabled(regs) \
+	(!((regs)->ARM_cpsr & PSR_I_BIT))
+
+#define fast_interrupts_enabled(regs) \
+	(!((regs)->ARM_cpsr & PSR_F_BIT))
+
+#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0))
+
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+					      unsigned int offset)
+{
+	if (offset > MAX_REG_OFFSET)
+		return 0;
+	return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASMARM_PTRACE_H_ */
diff --git a/lib/generated/.gitignore b/lib/generated/.gitignore
new file mode 100644
index 0000000000000..72e8ffc0db8aa
--- /dev/null
+++ b/lib/generated/.gitignore
@@ -0,0 +1 @@
+*
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v5 19/19] arm: vectors support
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (16 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 18/19] arm: add useful headers from the Linux kernel Andrew Jones
@ 2014-06-11 14:01 ` Andrew Jones
  2014-06-12 10:54 ` [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Paolo Bonzini
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-11 14:01 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Add support for tests to use exception handlers using
install_exception_handler(). This patch also adds phys_start_usr(),
which can be used to start a function in USR mode, using a stack
set up in a new memregion. phys_start_usr() is used by new selftest
tests that check the new vector support.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
---
v5: rebase change: replace __stringify with libcflat's new xstr
    macro
v4: a couple tweaks to fit changes in the other patches,
    vectors-usr test now has an 8K usr stack
v3:
  - squashed in 'arm: Simplify exceptions_init in cstart.S'
    [Christoffer Dall]
  - suggested function name changes and comment additions
    [Christoffer Dall]
  - fix a bug with stack restore from usr mode exceptions that
    Christoffer pointed out. Add a get_sp() accessor too.
---
 arm/cstart.S            | 174 ++++++++++++++++++++++++++++++++++++++++++++++++
 arm/flat.lds            |   7 +-
 arm/selftest.c          | 122 ++++++++++++++++++++++++++++++++-
 arm/unittests.cfg       |  12 ++++
 config/config-arm.mak   |   3 +-
 lib/arm/asm/processor.h |  40 +++++++++++
 lib/arm/processor.c     | 115 ++++++++++++++++++++++++++++++++
 7 files changed, 470 insertions(+), 3 deletions(-)
 create mode 100644 lib/arm/asm/processor.h
 create mode 100644 lib/arm/processor.c

diff --git a/arm/cstart.S b/arm/cstart.S
index e28251db2950d..cc87ece4b6b40 100644
--- a/arm/cstart.S
+++ b/arm/cstart.S
@@ -5,6 +5,10 @@
  *
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
+#define __ASSEMBLY__
+#include "asm/asm-offsets.h"
+#include "asm/ptrace.h"
+#include "asm/cp15.h"
 
 .arm
 
@@ -17,6 +21,13 @@ start:
 	 * See the kernel doc Documentation/arm/Booting
 	 */
 	ldr	sp, =stacktop
+	push	{r0-r3}
+
+	/* set up vector table and mode stacks */
+	bl	exceptions_init
+
+	/* complete setup */
+	pop	{r0-r3}
 	bl	setup
 
 	/* run the test */
@@ -27,9 +38,172 @@ start:
 	bl	exit
 	b	halt
 
+
+.macro set_mode_stack mode, stack
+	add	\stack, #S_FRAME_SIZE
+	msr	cpsr_c, #(\mode | PSR_I_BIT | PSR_F_BIT)
+	mov	sp, \stack
+.endm
+
+exceptions_init:
+	mrc	p15, 0, r2, c1, c0, 0	@ read SCTLR
+	bic	r2, #CR_V		@ SCTLR.V := 0
+	mcr	p15, 0, r2, c1, c0, 0	@ write SCTLR
+	ldr	r2, =vector_table
+	mcr	p15, 0, r2, c12, c0, 0	@ write VBAR
+
+	mrs	r2, cpsr
+	ldr	r1, =exception_stacks
+
+	/* first frame reserved for svc mode */
+	set_mode_stack	UND_MODE, r1
+	set_mode_stack	ABT_MODE, r1
+	set_mode_stack	IRQ_MODE, r1
+	set_mode_stack	FIQ_MODE, r1
+
+	msr	cpsr_cxsf, r2		@ back to svc mode
+	mov	pc, lr
+
 .text
 
 .globl halt
 halt:
 1:	wfi
 	b	1b
+
+/*
+ * Vector stubs
+ * Simplified version of the Linux kernel implementation
+ *   arch/arm/kernel/entry-armv.S
+ *
+ * Each mode has an S_FRAME_SIZE sized stack initialized
+ * in exceptions_init
+ */
+.macro vector_stub, name, vec, mode, correction=0
+.align 5
+vector_\name:
+.if \correction
+	sub	lr, lr, #\correction
+.endif
+	/*
+	 * Save r0, r1, lr_<exception> (parent PC)
+	 * and spsr_<exception> (parent CPSR)
+	 */
+	str	r0, [sp, #S_R0]
+	str	r1, [sp, #S_R1]
+	str	lr, [sp, #S_PC]
+	mrs	r0, spsr
+	str	r0, [sp, #S_PSR]
+
+	/* Prepare for SVC32 mode. */
+	mrs	r0, cpsr
+	bic	r0, #MODE_MASK
+	orr	r0, #SVC_MODE
+	msr	spsr_cxsf, r0
+
+	/* Branch to handler in SVC mode */
+	mov	r0, #\vec
+	mov	r1, sp
+	ldr	lr, =vector_common
+	movs	pc, lr
+.endm
+
+vector_stub 	rst,	0, UND_MODE
+vector_stub	und,	1, UND_MODE
+vector_stub	pabt,	3, ABT_MODE, 4
+vector_stub	dabt,	4, ABT_MODE, 8
+vector_stub	irq,	6, IRQ_MODE, 4
+vector_stub	fiq,	7, FIQ_MODE, 4
+
+.align 5
+vector_svc:
+	/*
+	 * Save r0, r1, lr_<exception> (parent PC)
+	 * and spsr_<exception> (parent CPSR)
+	 */
+	push	{ r1 }
+	ldr	r1, =exception_stacks
+	str	r0, [r1, #S_R0]
+	pop	{ r0 }
+	str	r0, [r1, #S_R1]
+	str	lr, [r1, #S_PC]
+	mrs	r0, spsr
+	str	r0, [r1, #S_PSR]
+
+	/*
+	 * Branch to handler, still in SVC mode.
+	 * r0 := 2 is the svc vector number.
+	 */
+	mov	r0, #2
+	ldr	lr, =vector_common
+	mov	pc, lr
+
+vector_common:
+	/* make room for pt_regs */
+	sub	sp, #S_FRAME_SIZE
+	tst	sp, #4			@ check stack alignment
+	subne	sp, #4
+
+	/* store registers r0-r12 */
+	stmia	sp, { r0-r12 }		@ stored wrong r0 and r1, fix later
+
+	/* get registers saved in the stub */
+	ldr	r2, [r1, #S_R0]		@ r0
+	ldr	r3, [r1, #S_R1]		@ r1
+	ldr	r4, [r1, #S_PC] 	@ lr_<exception> (parent PC)
+	ldr	r5, [r1, #S_PSR]	@ spsr_<exception> (parent CPSR)
+
+	/* fix r0 and r1 */
+	str	r2, [sp, #S_R0]
+	str	r3, [sp, #S_R1]
+
+	/* store sp_svc, if we were in usr mode we'll fix this later */
+	add	r6, sp, #S_FRAME_SIZE
+	addne	r6, #4			@ stack wasn't aligned
+	str	r6, [sp, #S_SP]
+
+	str	lr, [sp, #S_LR]		@ store lr_svc, fix later for usr mode
+	str	r4, [sp, #S_PC]		@ store lr_<exception>
+	str	r5, [sp, #S_PSR]	@ store spsr_<exception>
+
+	/* set ORIG_r0 */
+	mov	r2, #-1
+	str	r2, [sp, #S_OLD_R0]
+
+	/* if we were in usr mode then we need sp_usr and lr_usr instead */
+	and	r1, r5, #MODE_MASK
+	cmp	r1, #USR_MODE
+	bne	1f
+	add	r1, sp, #S_SP
+	stmia	r1, { sp,lr }^
+
+	/* Call the handler. r0 is the vector number, r1 := pt_regs */
+1:	mov	r1, sp
+	bl	do_handle_exception
+
+	/*
+	 * make sure we restore sp_svc on mode change. No need to
+	 * worry about lr_svc though, as that gets clobbered on
+	 * exception entry anyway.
+	 */
+	str	r6, [sp, #S_SP]
+
+	/* return from exception */
+	msr	spsr_cxsf, r5
+	ldmia	sp, { r0-pc }^
+
+.align 5
+vector_addrexcptn:
+	b	vector_addrexcptn
+
+.section .text.ex
+.align 5
+vector_table:
+	b	vector_rst
+	b	vector_und
+	b	vector_svc
+	b	vector_pabt
+	b	vector_dabt
+	b	vector_addrexcptn	@ should never happen
+	b	vector_irq
+	b	vector_fiq
diff --git a/arm/flat.lds b/arm/flat.lds
index 3e5d72e24989b..ee9fc0ab79abc 100644
--- a/arm/flat.lds
+++ b/arm/flat.lds
@@ -3,7 +3,12 @@ SECTIONS
 {
     .text : { *(.init) *(.text) *(.text.*) }
     . = ALIGN(4K);
-    .data : { *(.data) }
+    .data : {
+        exception_stacks = .;
+        . += 4K;
+        exception_stacks_end = .;
+        *(.data)
+    }
     . = ALIGN(16);
     .rodata : { *(.rodata) }
     . = ALIGN(16);
diff --git a/arm/selftest.c b/arm/selftest.c
index bcaecfae17fcd..0bc1f8fcb33a2 100644
--- a/arm/selftest.c
+++ b/arm/selftest.c
@@ -7,6 +7,9 @@
  */
 #include "libcflat.h"
 #include "asm/setup.h"
+#include "asm/ptrace.h"
+#include "asm/asm-offsets.h"
+#include "asm/processor.h"
 
 #define TESTGRP "selftest"
 
@@ -76,14 +79,131 @@ static void check_setup(int argc, char **argv)
 	assert_args(nr_tests, 2);
 }
 
+static struct pt_regs expected_regs;
+/*
+ * Capture the current register state and execute an instruction
+ * that causes an exception. The test handler will check that its
+ * capture of the current register state matches the capture done
+ * here.
+ *
+ * NOTE: update clobber list if passed insns needs more than r0,r1
+ */
+#define test_exception(pre_insns, excptn_insn, post_insns)	\
+	asm volatile(						\
+		pre_insns "\n"					\
+		"mov	r0, %0\n"				\
+		"stmia	r0, { r0-lr }\n"			\
+		"mrs	r1, cpsr\n"				\
+		"str	r1, [r0, #" xstr(S_PSR) "]\n"		\
+		"mov	r1, #-1\n"				\
+		"str	r1, [r0, #" xstr(S_OLD_R0) "]\n"	\
+		"add	r1, pc, #8\n"				\
+		"str	r1, [r0, #" xstr(S_R1) "]\n"		\
+		"str	r1, [r0, #" xstr(S_PC) "]\n"		\
+		excptn_insn "\n"				\
+		post_insns "\n"					\
+	:: "r" (&expected_regs) : "r0", "r1")
+
+static bool check_regs(struct pt_regs *regs)
+{
+	unsigned i;
+
+	/* exception handlers should always run in svc mode */
+	if (current_mode() != SVC_MODE)
+		return false;
+
+	for (i = 0; i < ARRAY_SIZE(regs->uregs); ++i) {
+		if (regs->uregs[i] != expected_regs.uregs[i])
+			return false;
+	}
+
+	return true;
+}
+
+static bool und_works;
+static void und_handler(struct pt_regs *regs)
+{
+	und_works = check_regs(regs);
+}
+
+static bool check_und(void)
+{
+	install_exception_handler(EXCPTN_UND, und_handler);
+
+	/* issue an instruction to a coprocessor we don't have */
+	test_exception("", "mcr p2, 0, r0, c0, c0", "");
+
+	install_exception_handler(EXCPTN_UND, NULL);
+
+	return und_works;
+}
+
+static bool svc_works;
+static void svc_handler(struct pt_regs *regs)
+{
+	u32 svc = *(u32 *)(regs->ARM_pc - 4) & 0xffffff;
+
+	if (processor_mode(regs) == SVC_MODE) {
+		/*
+		 * When issuing an svc from supervisor mode lr_svc will
+		 * get corrupted. So before issuing the svc, callers must
+		 * always push it on the stack. We pushed it to offset 4.
+		 */
+		regs->ARM_lr = *(unsigned long *)(regs->ARM_sp + 4);
+	}
+
+	svc_works = check_regs(regs) && svc == 123;
+}
+
+static bool check_svc(void)
+{
+	install_exception_handler(EXCPTN_SVC, svc_handler);
+
+	if (current_mode() == SVC_MODE) {
+		/*
+		 * An svc from supervisor mode will corrupt lr_svc and
+		 * spsr_svc. We need to save/restore them separately.
+		 */
+		test_exception(
+			"mrs	r0, spsr\n"
+			"push	{ r0,lr }\n",
+			"svc	#123\n",
+			"pop	{ r0,lr }\n"
+			"msr	spsr_cxsf, r0\n"
+		);
+	} else {
+		test_exception("", "svc #123", "");
+	}
+
+	install_exception_handler(EXCPTN_SVC, NULL);
+
+	return svc_works;
+}
+
+static void check_vectors(void *arg __unused)
+{
+	report("%s", check_und() && check_svc(), testname);
+	exit(report_summary());
+}
+
 int main(int argc, char **argv)
 {
 	testname_set(NULL);
 	assert_args(argc, 1);
 	testname_set(argv[0]);
 
-	if (strcmp(argv[0], "setup") == 0)
+	if (strcmp(argv[0], "setup") == 0) {
+
 		check_setup(argc-1, &argv[1]);
 
+	} else if (strcmp(argv[0], "vectors-svc") == 0) {
+
+		check_vectors(NULL);
+
+	} else if (strcmp(argv[0], "vectors-usr") == 0) {
+
+		phys_start_usr(2*PAGE_SIZE, check_vectors, NULL);
+	}
+
 	return report_summary();
 }
diff --git a/arm/unittests.cfg b/arm/unittests.cfg
index da9dfd7b1f118..57f5f90f3e808 100644
--- a/arm/unittests.cfg
+++ b/arm/unittests.cfg
@@ -16,3 +16,15 @@ file = selftest.flat
 smp  = 1
 extra_params = -m 256 -append 'setup smp=1 mem=256'
 groups = selftest
+
+# Test vector setup and exception handling (svc mode).
+[selftest::vectors-svc]
+file = selftest.flat
+extra_params = -append 'vectors-svc'
+groups = selftest
+
+# Test vector setup and exception handling (usr mode).
+[selftest::vectors-usr]
+file = selftest.flat
+extra_params = -append 'vectors-usr'
+groups = selftest
diff --git a/config/config-arm.mak b/config/config-arm.mak
index ead191f4954f4..2a62b5847e230 100644
--- a/config/config-arm.mak
+++ b/config/config-arm.mak
@@ -39,7 +39,8 @@ cflatobjs += \
 	lib/virtio-testdev.o \
 	lib/arm/io.o \
 	lib/arm/setup.o \
-	lib/arm/spinlock.o
+	lib/arm/spinlock.o \
+	lib/arm/processor.o
 
 libeabi = lib/arm/libeabi.a
 eabiobjs = lib/arm/eabi_compat.o
diff --git a/lib/arm/asm/processor.h b/lib/arm/asm/processor.h
new file mode 100644
index 0000000000000..b7d3be00135fd
--- /dev/null
+++ b/lib/arm/asm/processor.h
@@ -0,0 +1,40 @@
+#ifndef _ASMARM_PROCESSOR_H_
+#define _ASMARM_PROCESSOR_H_
+/*
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "ptrace.h"
+
+enum vector {
+	EXCPTN_RST,
+	EXCPTN_UND,
+	EXCPTN_SVC,
+	EXCPTN_PABT,
+	EXCPTN_DABT,
+	EXCPTN_ADDREXCPTN,
+	EXCPTN_IRQ,
+	EXCPTN_FIQ,
+	EXCPTN_MAX,
+};
+
+typedef void (*exception_fn)(struct pt_regs *);
+extern void install_exception_handler(enum vector v, exception_fn fn);
+
+extern void show_regs(struct pt_regs *regs);
+extern void *get_sp(void);
+
+static inline unsigned long current_cpsr(void)
+{
+	unsigned long cpsr;
+	asm volatile("mrs %0, cpsr" : "=r" (cpsr));
+	return cpsr;
+}
+
+#define current_mode() (current_cpsr() & MODE_MASK)
+
+extern void
+phys_start_usr(size_t stacksize, void (*func)(void *arg), void *arg);
+
+#endif /* _ASMARM_PROCESSOR_H_ */
diff --git a/lib/arm/processor.c b/lib/arm/processor.c
new file mode 100644
index 0000000000000..47e290b467912
--- /dev/null
+++ b/lib/arm/processor.c
@@ -0,0 +1,115 @@
+/*
+ * processor control and status functions
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "asm/setup.h"
+#include "asm/ptrace.h"
+#include "asm/processor.h"
+
+static const char *processor_modes[] = {
+	"USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" ,
+	"UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
+	"UK8_26" , "UK9_26" , "UK10_26", "UK11_26",
+	"UK12_26", "UK13_26", "UK14_26", "UK15_26",
+	"USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" ,
+	"UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
+	"UK8_32" , "UK9_32" , "UK10_32", "UND_32" ,
+	"UK12_32", "UK13_32", "UK14_32", "SYS_32"
+};
+
+static char *vector_names[] = {
+	"rst", "und", "svc", "pabt", "dabt", "addrexcptn", "irq", "fiq"
+};
+
+void show_regs(struct pt_regs *regs)
+{
+	unsigned long flags;
+	char buf[64];
+
+	printf("pc : [<%08lx>]    lr : [<%08lx>]    psr: %08lx\n"
+	       "sp : %08lx  ip : %08lx  fp : %08lx\n",
+		regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
+		regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+	printf("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
+		regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
+	printf("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
+		regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+	printf("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
+		regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+
+	flags = regs->ARM_cpsr;
+	buf[0] = flags & PSR_N_BIT ? 'N' : 'n';
+	buf[1] = flags & PSR_Z_BIT ? 'Z' : 'z';
+	buf[2] = flags & PSR_C_BIT ? 'C' : 'c';
+	buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
+	buf[4] = '\0';
+
+	printf("Flags: %s  IRQs o%s  FIQs o%s  Mode %s\n",
+		buf, interrupts_enabled(regs) ? "n" : "ff",
+		fast_interrupts_enabled(regs) ? "n" : "ff",
+		processor_modes[processor_mode(regs)]);
+
+	if (!user_mode(regs)) {
+		unsigned int ctrl, transbase, dac;
+		asm volatile(
+			"mrc p15, 0, %0, c1, c0\n"
+			"mrc p15, 0, %1, c2, c0\n"
+			"mrc p15, 0, %2, c3, c0\n"
+		: "=r" (ctrl), "=r" (transbase), "=r" (dac));
+		printf("Control: %08x  Table: %08x  DAC: %08x\n",
+			ctrl, transbase, dac);
+	}
+}
+
+void *get_sp(void)
+{
+	register unsigned long sp asm("sp");
+	return (void *)sp;
+}
+
+static exception_fn exception_handlers[EXCPTN_MAX];
+
+void install_exception_handler(enum vector v, exception_fn fn)
+{
+	if (v < EXCPTN_MAX)
+		exception_handlers[v] = fn;
+}
+
+void do_handle_exception(enum vector v, struct pt_regs *regs)
+{
+	if (v < EXCPTN_MAX && exception_handlers[v]) {
+		exception_handlers[v](regs);
+		return;
+	}
+
+	if (v < EXCPTN_MAX)
+		printf("Unhandled exception %d (%s)\n", v, vector_names[v]);
+	else
+		printf("%s called with vector=%d\n", __func__, v);
+
+	printf("Exception frame registers:\n");
+	show_regs(regs);
+	abort();
+}
+
+void phys_start_usr(size_t stacksize, void (*func)(void *arg), void *arg)
+{
+	struct memregion *m = memregion_new(stacksize);
+	unsigned long sp_usr = (unsigned long)(m->addr + m->size);
+
+	sp_usr &= (~7UL); /* stack ptr needs 8-byte alignment */
+
+	asm volatile(
+		"mrs	r0, cpsr\n"
+		"bic	r0, #" xstr(MODE_MASK) "\n"
+		"orr	r0, #" xstr(USR_MODE) "\n"
+		"msr	cpsr_c, r0\n"
+		"mov	r0, %0\n"
+		"mov	sp, %1\n"
+		"mov	pc, %2\n"
+	:: "r" (arg), "r" (sp_usr), "r" (func) : "r0");
+}
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 08/19] add support for Linux device trees
  2014-06-11 14:01 ` [PATCH v5 08/19] add support for Linux device trees Andrew Jones
@ 2014-06-12  9:19   ` Christoffer Dall
  0 siblings, 0 replies; 45+ messages in thread
From: Christoffer Dall @ 2014-06-12  9:19 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvmarm, kvm, pbonzini

On Wed, Jun 11, 2014 at 04:01:23PM +0200, Andrew Jones wrote:
> Add some device tree functions, built on libfdt, to the arch-neutral
> lib code in order to facilitate the extraction of boot info and device
> base addresses. These functions should work on device trees conforming
> to section III of the kernel doc
> Documentation/devicetree/booting-without-of.txt.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> v5:
>  - changed *get_baseaddr* helpers to *get_base* helpers
>  - a couple minor code changes [Christoffer Dall]
> v4: reworked everything, added lots of comments to devicetree.h
> ---

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 12/19] Introduce virtio-testdev
  2014-06-11 14:01 ` [PATCH v5 12/19] Introduce virtio-testdev Andrew Jones
@ 2014-06-12 10:16   ` Paolo Bonzini
  2014-06-12 11:30     ` Andrew Jones
  0 siblings, 1 reply; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 10:16 UTC (permalink / raw)
  To: Andrew Jones, kvmarm, kvm; +Cc: christoffer.dall

[-- Attachment #1: Type: text/plain, Size: 1814 bytes --]

Il 11/06/2014 16:01, Andrew Jones ha scritto:
> 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>
> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

Hi Drew,

quite a few months ago I had promised to help with an alternative
implementation that does not require a new virtio device (which would
in turn need registration of the device ID and so on.

Since the return values are hardly used in your test device, I removed
them and made a simple write-only backend for virtio-serial.  With this
simplification, virtio-serial is almost as simple as your test device,
you just use the transmit queue (queue 1).  Receiving data would be a
bit more complicated, basically you would first put a buffer in queue
0, then issue the command, then wait for an interrupt on queue 0.

There is a single command implemented, "q".  It takes a (prefix)
argument for the exit code, so an error exit is implemented by writing
"1q" to the virtio-serial port.

Right now I'm using ASCII (because I tested it from a Linux guest with
just "echo 1q > /dev/vport0p1"), but of course you could just as well
encode arguments in binary format.

The QEMU implementation follows, it can be used as:

    qemu-system-arm ... \
      -chardev testdev,id=ctl \
      -device virtio-serial -device virtserialport,chardev=ctl ...

If you are okay with it, feel free to pick it up and send it to 
qemu-devel, and just send v6 of this one patch.  Unfortunately I cannot 
merge kvm-unit-tests until there is QEMU support for either 
virtio-testdev or chardev-testdev, but it should not take much time.

Paolo

[-- Attachment #2: char-testdev.patch --]
[-- Type: text/x-patch, Size: 6082 bytes --]

diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 591ddcf..5820608 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -1,7 +1,7 @@
 common-obj-y += rng.o rng-egd.o
 common-obj-$(CONFIG_POSIX) += rng-random.o
 
-common-obj-y += msmouse.o
+common-obj-y += msmouse.o testdev.o
 common-obj-$(CONFIG_BRLAPI) += baum.o
 baum.o-cflags := $(SDL_CFLAGS)
 
diff --git a/backends/testdev.c b/backends/testdev.c
new file mode 100644
index 0000000..8e93266
--- /dev/null
+++ b/backends/testdev.c
@@ -0,0 +1,131 @@
+/*
+ * QEMU Char Device for testsuite control
+ *
+ * Copyright (c) 2014 Red Hat, Inc.
+ *
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu-common.h"
+#include "sysemu/char.h"
+
+#define BUF_SIZE 32
+
+typedef struct {
+    CharDriverState *chr;
+    uint8_t in_buf[32];
+    int in_buf_used;
+} TestdevCharState;
+
+/* Try to interpret a whole incoming packet */
+static int testdev_eat_packet(TestdevCharState *testdev)
+{
+    const uint8_t *cur = testdev->in_buf;
+    int len = testdev->in_buf_used;
+    uint8_t c;
+    int arg;
+
+#define EAT(c) do { \
+    if (!len--) {   \
+        return 0;   \
+    }               \
+    c = *cur++;     \
+} while (0)
+
+    EAT(c);
+
+    while (isspace(c)) {
+        EAT(c);
+    }
+
+    arg = 0;
+    while (isdigit(c)) {
+        arg = arg * 10 + c - '0';
+        EAT(c);
+    }
+
+    while (isspace(c)) {
+        EAT(c);
+    }
+
+    switch (c) {
+    case 'q':
+        exit((arg << 1) | 1);
+        break;
+    default:
+        break;
+    }
+    return cur - testdev->in_buf;
+}
+
+/* The other end is writing some data.  Store it and try to interpret */
+static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    TestdevCharState *testdev = chr->opaque;
+    int tocopy, eaten, orig_len = len;
+
+    while (len) {
+        /* Complete our buffer as much as possible */
+        tocopy = MIN(len, BUF_SIZE - testdev->in_buf_used);
+
+        memcpy(testdev->in_buf + testdev->in_buf_used, buf, tocopy);
+        testdev->in_buf_used += tocopy;
+        buf += tocopy;
+        len -= tocopy;
+
+        /* Interpret it as much as possible */
+        while (testdev->in_buf_used > 0 &&
+               (eaten = testdev_eat_packet(testdev)) > 0) {
+            memmove(testdev->in_buf, testdev->in_buf + eaten,
+                    testdev->in_buf_used - eaten);
+            testdev->in_buf_used -= eaten;
+        }
+    }
+    return orig_len;
+}
+
+static void testdev_close(struct CharDriverState *chr)
+{
+    TestdevCharState *testdev = chr->opaque;
+
+    g_free(testdev);
+}
+
+CharDriverState *chr_testdev_init(void)
+{
+    TestdevCharState *testdev;
+    CharDriverState *chr;
+
+    testdev = g_malloc0(sizeof(TestdevCharState));
+    testdev->chr = chr = g_malloc0(sizeof(CharDriverState));
+
+    chr->opaque = testdev;
+    chr->chr_write = testdev_write;
+    chr->chr_close = testdev_close;
+
+    return chr;
+}
+
+static void register_types(void)
+{
+    register_char_driver_qapi("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL);
+}
+
+type_init(register_types);
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index b81a6ff..fbb356e 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -306,6 +306,9 @@ CharDriverState *qemu_char_get_next_serial(void);
 /* msmouse */
 CharDriverState *qemu_chr_open_msmouse(void);
 
+/* testdev.c */
+CharDriverState *chr_testdev_init(void);
+
 /* baum.c */
 CharDriverState *chr_baum_init(void);
 
diff --git a/qapi-schema.json b/qapi-schema.json
index 14b498b..f9e5bbd 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2617,6 +2617,7 @@
                                        'mux'    : 'ChardevMux',
                                        'msmouse': 'ChardevDummy',
                                        'braille': 'ChardevDummy',
+                                       'testdev': 'ChardevDummy',
                                        'stdio'  : 'ChardevStdio',
                                        'console': 'ChardevDummy',
                                        'spicevmc' : 'ChardevSpiceChannel',
diff --git a/qemu-char.c b/qemu-char.c
index 17b476e..a64dec5 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2974,6 +2974,7 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
         strcmp(filename, "pty")     == 0 ||
         strcmp(filename, "msmouse") == 0 ||
         strcmp(filename, "braille") == 0 ||
+        strcmp(filename, "testdev") == 0 ||
         strcmp(filename, "stdio")   == 0) {
         qemu_opt_set(opts, "backend", filename);
         return opts;
@@ -3770,6 +3771,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
         chr = chr_baum_init();
         break;
 #endif
+    case CHARDEV_BACKEND_KIND_TESTDEV:
+        chr = chr_testdev_init();
+        break;
     case CHARDEV_BACKEND_KIND_STDIO:
         chr = qemu_chr_open_stdio(backend->stdio);
         break;

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 03/19] clean root dir of all x86-ness
  2014-06-11 14:01 ` [PATCH v5 03/19] clean root dir of all x86-ness Andrew Jones
@ 2014-06-12 10:31   ` Paolo Bonzini
  2014-06-12 10:40     ` Andrew Jones
  0 siblings, 1 reply; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 10:31 UTC (permalink / raw)
  To: Andrew Jones, kvmarm, kvm; +Cc: christoffer.dall

Il 11/06/2014 16:01, Andrew Jones ha scritto:
> 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

Why is --test-dir useful?  Can you just use --arch instead?

> diff --git a/docs/testdev.txt b/docs/testdev.txt
> new file mode 100644
> index 0000000000000..854fe20d56f66
> --- /dev/null
> +++ b/docs/testdev.txt
> @@ -0,0 +1,13 @@
> +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
> +			the 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
> +
> +The test device uses a char device for actual output.

I'm removing this file altogether and adding it to QEMU instead.  Most 
of the content is obsolete too.

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 04/19] add distclean target and gitignore more
  2014-06-11 14:01 ` [PATCH v5 04/19] add distclean target and gitignore more Andrew Jones
@ 2014-06-12 10:36   ` Paolo Bonzini
  2014-06-14 13:17     ` Christoffer Dall
  0 siblings, 1 reply; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 10:36 UTC (permalink / raw)
  To: Andrew Jones, kvmarm, kvm; +Cc: christoffer.dall

Il 11/06/2014 16:01, Andrew Jones ha scritto:
>  patches
>  .stgit-*
>  cscope.*
> +*.swp
> +/config.mak
> +/*-run
> +/test.log
> +/msr.out

I'd place swp, cscope, stgit and patches file in a global gitignore file 
("git config --global core.excludesfile /path/to/file") rather than 
polluting each repository.  But since you're adding to something that 
already exist (and since I also use vi :)), I'll apply this patch and 
content myself with sharing the git trick I have just learnt.

Paolo

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 03/19] clean root dir of all x86-ness
  2014-06-12 10:31   ` Paolo Bonzini
@ 2014-06-12 10:40     ` Andrew Jones
  2014-06-12 10:42       ` Paolo Bonzini
  0 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-12 10:40 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvmarm, kvm, christoffer.dall

On Thu, Jun 12, 2014 at 12:31:54PM +0200, Paolo Bonzini wrote:
> Il 11/06/2014 16:01, Andrew Jones ha scritto:
> >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
> 
> Why is --test-dir useful?  Can you just use --arch instead?

testdir is not always the same as arch, e.g. arch=x86_64, testdir=x86,
and setting --arch x86 would lose useful information. We wouldn't know
if arch is supposed to be i386 or x86_64. The same argument will apply
to arch=arm vs. arch=aarch64.

> 
> >diff --git a/docs/testdev.txt b/docs/testdev.txt
> >new file mode 100644
> >index 0000000000000..854fe20d56f66
> >--- /dev/null
> >+++ b/docs/testdev.txt
> >@@ -0,0 +1,13 @@
> >+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
> >+			the 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
> >+
> >+The test device uses a char device for actual output.
> 
> I'm removing this file altogether and adding it to QEMU instead.  Most of
> the content is obsolete too.

Sounds good to me.

drew

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 03/19] clean root dir of all x86-ness
  2014-06-12 10:40     ` Andrew Jones
@ 2014-06-12 10:42       ` Paolo Bonzini
  2014-06-12 10:54         ` Andrew Jones
  0 siblings, 1 reply; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 10:42 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvmarm, kvm, christoffer.dall

Il 12/06/2014 12:40, Andrew Jones ha scritto:
>>> > >+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
>> >
>> > Why is --test-dir useful?  Can you just use --arch instead?
> testdir is not always the same as arch, e.g. arch=x86_64, testdir=x86,
> and setting --arch x86 would lose useful information. We wouldn't know
> if arch is supposed to be i386 or x86_64. The same argument will apply
> to arch=arm vs. arch=aarch64.
>

Yes, testdir is useful indeed.  But what is the usecase for --test-dir?

Paolo

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 06/19] libfdt: Import libfdt source
       [not found] ` <1402495294-30737-7-git-send-email-drjones@redhat.com>
@ 2014-06-12 10:44   ` Paolo Bonzini
  2014-06-12 10:59     ` Andrew Jones
  2014-06-12 11:09   ` Paolo Bonzini
  1 sibling, 1 reply; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 10:44 UTC (permalink / raw)
  To: Andrew Jones, kvmarm, kvm; +Cc: christoffer.dall

Il 11/06/2014 16:01, Andrew Jones ha scritto:
> This adds the applicable libfdt source files (unmodified) and a
> README to explain where the source came from. The README says
>
>   The code in this directory is originally imported from the libfdt
>   directory of git://git.jdl.com/software/dtc.git - version 1.4.0.
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

Would it make sense to use a submodule instead?

Paolo

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 09/19] libcflat: add abort() and assert()
  2014-06-11 14:01 ` [PATCH v5 09/19] libcflat: add abort() and assert() Andrew Jones
@ 2014-06-12 10:48   ` Paolo Bonzini
  2014-06-12 11:07     ` Andrew Jones
  0 siblings, 1 reply; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 10:48 UTC (permalink / raw)
  To: Andrew Jones, kvmarm, kvm; +Cc: christoffer.dall

Il 11/06/2014 16:01, Andrew Jones ha scritto:
> The test framework may have external dependencies. assert() provides
> the ability to abort when those dependencies aren't met. However,
> assert() should only be used for unlikely conditions. We can provide
> more informative messages with printf() for the more likely problems.
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
> ---
>  lib/libcflat.h | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index 024c834630d63..8886885766ddc 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -70,4 +70,13 @@ extern long atol(const char *ptr);
>
>  void report(const char *msg_fmt, bool pass, ...);
>  int report_summary(void);
> +
> +#define abort() exit(64)		/* 129 exit status from qemu */

This can be confused with a SIGHUP.  We can change it to exit(44) aka 99 
exit status.

Also, please make it a function rather than a macro.

> +#define assert(cond)							\
> +do {									\
> +	if (!(cond))							\
> +		printf("%s:%d: assert failed\n", __FILE__, __LINE__),	\
> +		abort();						\
> +} while (0)

Here you could also put the printf/abort into a function; as you prefer.

Paolo

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 13/19] libcflat: clean up libcflat.h and add string.h
  2014-06-11 14:01 ` [PATCH v5 13/19] libcflat: clean up libcflat.h and add string.h Andrew Jones
@ 2014-06-12 10:52   ` Paolo Bonzini
  2014-06-12 11:12     ` Andrew Jones
  0 siblings, 1 reply; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 10:52 UTC (permalink / raw)
  To: Andrew Jones, kvmarm, kvm; +Cc: christoffer.dall

Il 11/06/2014 16:01, Andrew Jones ha scritto:
> Use libgcc's stddef.h and stdint.h, and then remove the redundant
> defines from libcflat.h. Also separate out the string function
> declarations into a new file string.h. These changes have no affect
> on code including libcflat.h, but are needed in order to compile an
> unmodified libfdt for kvm-unit-tests using an arm cross-compiler.
> While at it, add strcpy.
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
> ---
>  lib/libcflat.h | 55 +++++++++++++++++++++----------------------------------
>  lib/string.c   |  6 ++++++
>  lib/string.h   | 15 +++++++++++++++
>  3 files changed, 42 insertions(+), 34 deletions(-)
>  create mode 100644 lib/string.h
>
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index 5939cee54890b..404560cd103e5 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -21,60 +21,47 @@
>  #define __LIBCFLAT_H
>
>  #include <stdarg.h>
> +#include <stddef.h>
> +#include <stdint.h>
> +#include "string.h"

No need to use quotes here.

>
>  #define __unused __attribute__((__unused__))
>
>  #define xstr(s) xxstr(s)
>  #define xxstr(s) #s
>
> -typedef unsigned char u8;
> -typedef signed char s8;
> -typedef unsigned short u16;
> -typedef signed short s16;
> -typedef unsigned u32;
> -typedef signed s32;
> -typedef unsigned long ulong;
> -typedef unsigned long long u64;
> -typedef signed long long s64;
> -typedef unsigned long size_t;
> -typedef _Bool bool;
> -
> -#define true 1
> +typedef uint8_t		u8;
> +typedef int8_t		s8;
> +typedef uint16_t	u16;
> +typedef int16_t		s16;
> +typedef uint32_t	u32;
> +typedef int32_t		s32;
> +typedef uint64_t	u64;
> +typedef int64_t		s64;
> +typedef unsigned long	ulong;
> +
> +typedef _Bool		bool;
>  #define false 0
> +#define true  1
>
> +extern void puts(const char *s);
>  extern void exit(int code);
>
> -extern unsigned long strlen(const char *buf);
> -extern char *strcat(char *dest, const char *src);
> -extern int strcmp(const char *a, const char *b);
> -extern char *strchr(const char *s, int c);
> -
>  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 long atol(const char *ptr);
>
> -extern void puts(const char *s);
> -
> -extern void *memset(void *s, int c, size_t n);
> -extern void *memcpy(void *dest, const void *src, size_t n);
> -extern int memcmp(const void *s1, const void *s2, size_t n);
> -extern void *memmove(void *dest, const void *src, size_t n);
> -extern void *memchr(const void *s, int c, size_t n);
> +void report(const char *msg_fmt, bool pass, ...);
> +int report_summary(void);
>
> -extern long atol(const char *ptr);
> -#define ARRAY_SIZE(_a)  (sizeof(_a)/sizeof((_a)[0]))
> +#define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
>
> -#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
>  #define container_of(ptr, type, member) ({				\
>  	const typeof( ((type *)0)->member ) *__mptr = (ptr);		\
>  	(type *)( (char *)__mptr - offsetof(type,member) );})
>
> -#define NULL ((void *)0UL)
> -
> -void report(const char *msg_fmt, bool pass, ...);
> -int report_summary(void);
> -
> -#define abort() exit(64)		/* 129 exit status from qemu */
> +#define abort() exit(64) /* 129 exit status from qemu */
>  #define assert(cond)							\
>  do {									\
>  	if (!(cond))							\
> diff --git a/lib/string.c b/lib/string.c
> index fe90c8b1289f2..026f50252287c 100644
> --- a/lib/string.c
> +++ b/lib/string.c
> @@ -20,6 +20,12 @@ char *strcat(char *dest, const char *src)
>      return dest;
>  }
>
> +char *strcpy(char *dest, const char *src)
> +{
> +    *dest = 0;
> +    return strcat(dest, src);
> +}
> +
>  int strcmp(const char *a, const char *b)
>  {
>      while (*a == *b) {
> diff --git a/lib/string.h b/lib/string.h
> new file mode 100644
> index 0000000000000..dbab368b1b9e4
> --- /dev/null
> +++ b/lib/string.h
> @@ -0,0 +1,15 @@
> +#ifndef __STRING_H
> +#define __STRING_H
> +
> +extern unsigned long strlen(const char *buf);
> +extern char *strcat(char *dest, const char *src);
> +extern char *strcpy(char *dest, const char *src);
> +extern int strcmp(const char *a, const char *b);
> +extern char *strchr(const char *s, int c);
> +extern void *memset(void *s, int c, size_t n);
> +extern void *memcpy(void *dest, const void *src, size_t n);
> +extern int memcmp(const void *s1, const void *s2, size_t n);
> +extern void *memmove(void *dest, const void *src, size_t n);
> +extern void *memchr(const void *s, int c, size_t n);
> +
> +#endif /* _STRING_H */
>

Please separate the string.h parts and squash them into patch 7.

Otherwise looks good!

Paolo

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 00/19] kvm-unit-tests/arm: initial drop
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (17 preceding siblings ...)
  2014-06-11 14:01 ` [PATCH v5 19/19] arm: vectors support Andrew Jones
@ 2014-06-12 10:54 ` Paolo Bonzini
       [not found] ` <1402495294-30737-7-git-send-email-drjones@redhat.com>
  2014-06-14 14:44 ` [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Christoffer Dall
  20 siblings, 0 replies; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 10:54 UTC (permalink / raw)
  To: Andrew Jones, kvmarm, kvm; +Cc: christoffer.dall

Il 11/06/2014 16:01, Andrew Jones ha scritto:
> This is a v5 of a series that introduces arm to kvm-unit-tests. First,
> it does some tidying up of the repo. Then, it adds support for device
> trees (libfdt), and for virtio-testdev[1]. Next, it adds the basic
> infrastructure for booting a test case (guest), and adds a first
> test case, a self-test to confirm setup was completed successfully.
> Finally, it further prepares the framework for more complicated tests
> by adding vector support, and extends the self-test to test that too.
>
> This initial drop doesn't require kvmarm. qemu-system-arm is enough,
> but it must have mach-virt, and the virtio-testdev patch[1].
>
> These patches (v5) are also available from a git repo here
> https://github.com/rhdrjones/kvm-unit-tests/commits/arm/v5-initial-drop
>
> The v4 patches are available for reference here
> https://github.com/rhdrjones/kvm-unit-tests/commits/arm/v4-initial-drop
>
> Not too much has changed since v4. There are no new patches nor dropped
> patches, and all patches that did get a change have a v5 note. To see
> a branch interdiff (created with git-tbdiff[2]) take a look here[3].
>
> Thanks in advance for reviews!

I'm applying patches 1-5 and 14.

Thanks!

Paolo

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 03/19] clean root dir of all x86-ness
  2014-06-12 10:42       ` Paolo Bonzini
@ 2014-06-12 10:54         ` Andrew Jones
  0 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-12 10:54 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvmarm, kvm, christoffer.dall

On Thu, Jun 12, 2014 at 12:42:51PM +0200, Paolo Bonzini wrote:
> Il 12/06/2014 12:40, Andrew Jones ha scritto:
> >>>> >+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
> >>>
> >>> Why is --test-dir useful?  Can you just use --arch instead?
> >testdir is not always the same as arch, e.g. arch=x86_64, testdir=x86,
> >and setting --arch x86 would lose useful information. We wouldn't know
> >if arch is supposed to be i386 or x86_64. The same argument will apply
> >to arch=arm vs. arch=aarch64.
> >
> 
> Yes, testdir is useful indeed.  But what is the usecase for --test-dir?
>

Ah, I misunderstood your question. Why the command line parameter? No
good reason. I was just creating the parameter to be consistent with the
other configuration options. I don't see any harm in keeping it, but I
also don't care if you'd prefer it go.

drew

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 06/19] libfdt: Import libfdt source
  2014-06-12 10:44   ` [PATCH v5 06/19] libfdt: Import libfdt source Paolo Bonzini
@ 2014-06-12 10:59     ` Andrew Jones
  2014-06-12 14:39       ` Paolo Bonzini
  0 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-12 10:59 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvmarm, kvm, christoffer.dall

On Thu, Jun 12, 2014 at 12:44:30PM +0200, Paolo Bonzini wrote:
> Il 11/06/2014 16:01, Andrew Jones ha scritto:
> >This adds the applicable libfdt source files (unmodified) and a
> >README to explain where the source came from. The README says
> >
> >  The code in this directory is originally imported from the libfdt
> >  directory of git://git.jdl.com/software/dtc.git - version 1.4.0.
> >
> >Signed-off-by: Andrew Jones <drjones@redhat.com>
> >Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
> 
> Would it make sense to use a submodule instead?

I considered that, but since we'll probably never need to update
libfdt, it seemed like it'd just be an additional step for
kvm-unit-test developers and users. I have no strong preference
though. If you'd rather we submodule it, then I can spin up those
patches for a v6.

drew

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 09/19] libcflat: add abort() and assert()
  2014-06-12 10:48   ` Paolo Bonzini
@ 2014-06-12 11:07     ` Andrew Jones
  2014-06-12 11:09       ` Paolo Bonzini
  0 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-12 11:07 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvmarm, kvm, christoffer.dall

On Thu, Jun 12, 2014 at 12:48:16PM +0200, Paolo Bonzini wrote:
> Il 11/06/2014 16:01, Andrew Jones ha scritto:
> >The test framework may have external dependencies. assert() provides
> >the ability to abort when those dependencies aren't met. However,
> >assert() should only be used for unlikely conditions. We can provide
> >more informative messages with printf() for the more likely problems.
> >
> >Signed-off-by: Andrew Jones <drjones@redhat.com>
> >Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
> >---
> > lib/libcflat.h | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> >diff --git a/lib/libcflat.h b/lib/libcflat.h
> >index 024c834630d63..8886885766ddc 100644
> >--- a/lib/libcflat.h
> >+++ b/lib/libcflat.h
> >@@ -70,4 +70,13 @@ extern long atol(const char *ptr);
> >
> > void report(const char *msg_fmt, bool pass, ...);
> > int report_summary(void);
> >+
> >+#define abort() exit(64)		/* 129 exit status from qemu */
> 
> This can be confused with a SIGHUP.  We can change it to exit(44) aka 99
> exit status.
> 
> Also, please make it a function rather than a macro.

OK

> 
> >+#define assert(cond)							\
> >+do {									\
> >+	if (!(cond))							\
> >+		printf("%s:%d: assert failed\n", __FILE__, __LINE__),	\
> >+		abort();						\
> >+} while (0)
> 
> Here you could also put the printf/abort into a function; as you prefer.
>

Might as well. If I'm moving abort() into a general lib function, then
I'll need to find a home for it. I can use the same home for assert().
The best existing home is probably lib/report.c, or I should create a
new .c file.

drew

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 06/19] libfdt: Import libfdt source
       [not found] ` <1402495294-30737-7-git-send-email-drjones@redhat.com>
  2014-06-12 10:44   ` [PATCH v5 06/19] libfdt: Import libfdt source Paolo Bonzini
@ 2014-06-12 11:09   ` Paolo Bonzini
  1 sibling, 0 replies; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 11:09 UTC (permalink / raw)
  To: Andrew Jones, kvmarm, kvm; +Cc: christoffer.dall

Il 11/06/2014 16:01, Andrew Jones ha scritto:
> This adds the applicable libfdt source files (unmodified) and a
> README to explain where the source came from. The README says
>
>   The code in this directory is originally imported from the libfdt
>   directory of git://git.jdl.com/software/dtc.git - version 1.4.0.
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

Would it make sense to use a submodule instead?

Paolo

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 09/19] libcflat: add abort() and assert()
  2014-06-12 11:07     ` Andrew Jones
@ 2014-06-12 11:09       ` Paolo Bonzini
  0 siblings, 0 replies; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 11:09 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvmarm, kvm, christoffer.dall

Il 12/06/2014 13:07, Andrew Jones ha scritto:
> On Thu, Jun 12, 2014 at 12:48:16PM +0200, Paolo Bonzini wrote:
>> Il 11/06/2014 16:01, Andrew Jones ha scritto:
>>> The test framework may have external dependencies. assert() provides
>>> the ability to abort when those dependencies aren't met. However,
>>> assert() should only be used for unlikely conditions. We can provide
>>> more informative messages with printf() for the more likely problems.
>>>
>>> Signed-off-by: Andrew Jones <drjones@redhat.com>
>>> Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
>>> ---
>>> lib/libcflat.h | 9 +++++++++
>>> 1 file changed, 9 insertions(+)
>>>
>>> diff --git a/lib/libcflat.h b/lib/libcflat.h
>>> index 024c834630d63..8886885766ddc 100644
>>> --- a/lib/libcflat.h
>>> +++ b/lib/libcflat.h
>>> @@ -70,4 +70,13 @@ extern long atol(const char *ptr);
>>>
>>> void report(const char *msg_fmt, bool pass, ...);
>>> int report_summary(void);
>>> +
>>> +#define abort() exit(64)		/* 129 exit status from qemu */
>>
>> This can be confused with a SIGHUP.  We can change it to exit(44) aka 99
>> exit status.
>>
>> Also, please make it a function rather than a macro.
>
> OK
>
>>
>>> +#define assert(cond)							\
>>> +do {									\
>>> +	if (!(cond))							\
>>> +		printf("%s:%d: assert failed\n", __FILE__, __LINE__),	\
>>> +		abort();						\
>>> +} while (0)
>>
>> Here you could also put the printf/abort into a function; as you prefer.
>>
>
> Might as well. If I'm moving abort() into a general lib function, then
> I'll need to find a home for it. I can use the same home for assert().
> The best existing home is probably lib/report.c, or I should create a
> new .c file.

A new lib/abort.c file sounds better.

Paolo

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 13/19] libcflat: clean up libcflat.h and add string.h
  2014-06-12 10:52   ` Paolo Bonzini
@ 2014-06-12 11:12     ` Andrew Jones
  0 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-12 11:12 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvmarm, kvm, christoffer.dall

On Thu, Jun 12, 2014 at 12:52:18PM +0200, Paolo Bonzini wrote:
> Il 11/06/2014 16:01, Andrew Jones ha scritto:
> >Use libgcc's stddef.h and stdint.h, and then remove the redundant
> >defines from libcflat.h. Also separate out the string function
> >declarations into a new file string.h. These changes have no affect
> >on code including libcflat.h, but are needed in order to compile an
> >unmodified libfdt for kvm-unit-tests using an arm cross-compiler.
> >While at it, add strcpy.
> >
> >Signed-off-by: Andrew Jones <drjones@redhat.com>
> >Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
> >---
> > lib/libcflat.h | 55 +++++++++++++++++++++----------------------------------
> > lib/string.c   |  6 ++++++
> > lib/string.h   | 15 +++++++++++++++
> > 3 files changed, 42 insertions(+), 34 deletions(-)
> > create mode 100644 lib/string.h
> >
> >diff --git a/lib/libcflat.h b/lib/libcflat.h
> >index 5939cee54890b..404560cd103e5 100644
> >--- a/lib/libcflat.h
> >+++ b/lib/libcflat.h
> >@@ -21,60 +21,47 @@
> > #define __LIBCFLAT_H
> >
> > #include <stdarg.h>
> >+#include <stddef.h>
> >+#include <stdint.h>
> >+#include "string.h"
> 
> No need to use quotes here.

OK

> 
> >
> > #define __unused __attribute__((__unused__))
> >
> > #define xstr(s) xxstr(s)
> > #define xxstr(s) #s
> >
> >-typedef unsigned char u8;
> >-typedef signed char s8;
> >-typedef unsigned short u16;
> >-typedef signed short s16;
> >-typedef unsigned u32;
> >-typedef signed s32;
> >-typedef unsigned long ulong;
> >-typedef unsigned long long u64;
> >-typedef signed long long s64;
> >-typedef unsigned long size_t;
> >-typedef _Bool bool;
> >-
> >-#define true 1
> >+typedef uint8_t		u8;
> >+typedef int8_t		s8;
> >+typedef uint16_t	u16;
> >+typedef int16_t		s16;
> >+typedef uint32_t	u32;
> >+typedef int32_t		s32;
> >+typedef uint64_t	u64;
> >+typedef int64_t		s64;
> >+typedef unsigned long	ulong;
> >+
> >+typedef _Bool		bool;
> > #define false 0
> >+#define true  1
> >
> >+extern void puts(const char *s);
> > extern void exit(int code);
> >
> >-extern unsigned long strlen(const char *buf);
> >-extern char *strcat(char *dest, const char *src);
> >-extern int strcmp(const char *a, const char *b);
> >-extern char *strchr(const char *s, int c);
> >-
> > 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 long atol(const char *ptr);
> >
> >-extern void puts(const char *s);
> >-
> >-extern void *memset(void *s, int c, size_t n);
> >-extern void *memcpy(void *dest, const void *src, size_t n);
> >-extern int memcmp(const void *s1, const void *s2, size_t n);
> >-extern void *memmove(void *dest, const void *src, size_t n);
> >-extern void *memchr(const void *s, int c, size_t n);
> >+void report(const char *msg_fmt, bool pass, ...);
> >+int report_summary(void);
> >
> >-extern long atol(const char *ptr);
> >-#define ARRAY_SIZE(_a)  (sizeof(_a)/sizeof((_a)[0]))
> >+#define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
> >
> >-#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
> > #define container_of(ptr, type, member) ({				\
> > 	const typeof( ((type *)0)->member ) *__mptr = (ptr);		\
> > 	(type *)( (char *)__mptr - offsetof(type,member) );})
> >
> >-#define NULL ((void *)0UL)
> >-
> >-void report(const char *msg_fmt, bool pass, ...);
> >-int report_summary(void);
> >-
> >-#define abort() exit(64)		/* 129 exit status from qemu */
> >+#define abort() exit(64) /* 129 exit status from qemu */
> > #define assert(cond)							\
> > do {									\
> > 	if (!(cond))							\
> >diff --git a/lib/string.c b/lib/string.c
> >index fe90c8b1289f2..026f50252287c 100644
> >--- a/lib/string.c
> >+++ b/lib/string.c
> >@@ -20,6 +20,12 @@ char *strcat(char *dest, const char *src)
> >     return dest;
> > }
> >
> >+char *strcpy(char *dest, const char *src)
> >+{
> >+    *dest = 0;
> >+    return strcat(dest, src);
> >+}
> >+
> > int strcmp(const char *a, const char *b)
> > {
> >     while (*a == *b) {
> >diff --git a/lib/string.h b/lib/string.h
> >new file mode 100644
> >index 0000000000000..dbab368b1b9e4
> >--- /dev/null
> >+++ b/lib/string.h
> >@@ -0,0 +1,15 @@
> >+#ifndef __STRING_H
> >+#define __STRING_H
> >+
> >+extern unsigned long strlen(const char *buf);
> >+extern char *strcat(char *dest, const char *src);
> >+extern char *strcpy(char *dest, const char *src);
> >+extern int strcmp(const char *a, const char *b);
> >+extern char *strchr(const char *s, int c);
> >+extern void *memset(void *s, int c, size_t n);
> >+extern void *memcpy(void *dest, const void *src, size_t n);
> >+extern int memcmp(const void *s1, const void *s2, size_t n);
> >+extern void *memmove(void *dest, const void *src, size_t n);
> >+extern void *memchr(const void *s, int c, size_t n);
> >+
> >+#endif /* _STRING_H */
> >
> 
> Please separate the string.h parts and squash them into patch 7.
> 
> Otherwise looks good!
> 
> Paolo

OK

drew

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 12/19] Introduce virtio-testdev
  2014-06-12 10:16   ` Paolo Bonzini
@ 2014-06-12 11:30     ` Andrew Jones
  2014-06-12 11:56       ` Paolo Bonzini
  0 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-12 11:30 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvmarm, kvm, christoffer.dall

On Thu, Jun 12, 2014 at 12:16:18PM +0200, Paolo Bonzini wrote:
> Il 11/06/2014 16:01, Andrew Jones ha scritto:
> >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>
> >Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
> 
> Hi Drew,
> 
> quite a few months ago I had promised to help with an alternative
> implementation that does not require a new virtio device (which would
> in turn need registration of the device ID and so on.

Does it? I assumed we'd be fine just using 0xffff (which I understood
from the spec to be reserved for development purposes). I guess a
potential problem would be if this device is also used at the same
time as an experimental device that is also making that assumption,
but that'd be easily fixed by the developer who's doing the
experimenting.

> 
> Since the return values are hardly used in your test device, I removed
> them and made a simple write-only backend for virtio-serial.  With this
> simplification, virtio-serial is almost as simple as your test device,
> you just use the transmit queue (queue 1).  Receiving data would be a
> bit more complicated, basically you would first put a buffer in queue
> 0, then issue the command, then wait for an interrupt on queue 0.
> 
> There is a single command implemented, "q".  It takes a (prefix)
> argument for the exit code, so an error exit is implemented by writing
> "1q" to the virtio-serial port.
> 
> Right now I'm using ASCII (because I tested it from a Linux guest with
> just "echo 1q > /dev/vport0p1"), but of course you could just as well
> encode arguments in binary format.
> 
> The QEMU implementation follows, it can be used as:
> 
>    qemu-system-arm ... \
>      -chardev testdev,id=ctl \
>      -device virtio-serial -device virtserialport,chardev=ctl ...
> 
> If you are okay with it, feel free to pick it up and send it to qemu-devel,
> and just send v6 of this one patch.  Unfortunately I cannot merge
> kvm-unit-tests until there is QEMU support for either virtio-testdev or
> chardev-testdev, but it should not take much time.

Thanks for this! I'll experiment with it, and let you know how it goes.

drew

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 12/19] Introduce virtio-testdev
  2014-06-12 11:30     ` Andrew Jones
@ 2014-06-12 11:56       ` Paolo Bonzini
  0 siblings, 0 replies; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 11:56 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvmarm, kvm, christoffer.dall

Il 12/06/2014 13:30, Andrew Jones ha scritto:
>> >
>> > Hi Drew,
>> >
>> > quite a few months ago I had promised to help with an alternative
>> > implementation that does not require a new virtio device (which would
>> > in turn need registration of the device ID and so on.
> Does it? I assumed we'd be fine just using 0xffff (which I understood
> from the spec to be reserved for development purposes).

That actually means "use 65535 until you've requested a unique id".

I'd rather use 0xf2d6 (a random high number) than 65535, even though 
that's out-of-spec.

Paolo

> I guess a
> potential problem would be if this device is also used at the same
> time as an experimental device that is also making that assumption,
> but that'd be easily fixed by the developer who's doing the
> experimenting.
>


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 06/19] libfdt: Import libfdt source
  2014-06-12 10:59     ` Andrew Jones
@ 2014-06-12 14:39       ` Paolo Bonzini
  0 siblings, 0 replies; 45+ messages in thread
From: Paolo Bonzini @ 2014-06-12 14:39 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvmarm, kvm, christoffer.dall

Il 12/06/2014 12:59, Andrew Jones ha scritto:
>> >
>> > Would it make sense to use a submodule instead?
> I considered that, but since we'll probably never need to update
> libfdt, it seemed like it'd just be an additional step for
> kvm-unit-test developers and users. I have no strong preference
> though. If you'd rather we submodule it, then I can spin up those
> patches for a v6.

A submodule improves the tracking of patches on top of upstream...   I 
guess it's not a big deal though, it's unlikely that we will update it 
as you said.

Paolo

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 04/19] add distclean target and gitignore more
  2014-06-12 10:36   ` Paolo Bonzini
@ 2014-06-14 13:17     ` Christoffer Dall
  0 siblings, 0 replies; 45+ messages in thread
From: Christoffer Dall @ 2014-06-14 13:17 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Andrew Jones, kvmarm, kvm

On Thu, Jun 12, 2014 at 12:36:00PM +0200, Paolo Bonzini wrote:
> Il 11/06/2014 16:01, Andrew Jones ha scritto:
> > patches
> > .stgit-*
> > cscope.*
> >+*.swp
> >+/config.mak
> >+/*-run
> >+/test.log
> >+/msr.out
> 
> I'd place swp, cscope, stgit and patches file in a global gitignore
> file ("git config --global core.excludesfile /path/to/file") rather
> than polluting each repository.  But since you're adding to
> something that already exist (and since I also use vi :)), I'll
> apply this patch and content myself with sharing the git trick I
> have just learnt.
> 

You can also add

set directory=~/.vim/swap

to your ~/.vimrc and not have to worry about this in any of your
directories ;)

-Christoffer

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 11/19] add minimal virtio support for devtree virtio-mmio
  2014-06-11 14:01 ` [PATCH v5 11/19] add minimal virtio support for devtree virtio-mmio Andrew Jones
@ 2014-06-14 13:30   ` Christoffer Dall
  0 siblings, 0 replies; 45+ messages in thread
From: Christoffer Dall @ 2014-06-14 13:30 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvmarm, kvm, pbonzini

On Wed, Jun 11, 2014 at 04:01:26PM +0200, Andrew Jones wrote:
> Support the bare minimum of virtio to enable access to the virtio-mmio
> config space of a device. Currently this implementation must use a
> device tree to find the device.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> v5:
>  - use same virtio struct names as kernel
>  - no need to alloc a new virtio_config_ops for each virtio device
>  - use ioremap
> v4:
>  - split from the virtio-testdev patch
>  - search a table to "discover" that the device must be DT/virtio-mmio,
>    which doesn't change anything, but looks less hacky than comments
>    saying the device must be DT/virtio-mmio...
>  - manage own pool of virtio-mmio pre-allocated device structures in
>    order to avoid needing access to the heap
> ---

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 15/19] arm: initial drop
  2014-06-11 14:01 ` [PATCH v5 15/19] arm: initial drop Andrew Jones
@ 2014-06-14 14:16   ` Christoffer Dall
  2014-06-16  7:36     ` Andrew Jones
  0 siblings, 1 reply; 45+ messages in thread
From: Christoffer Dall @ 2014-06-14 14:16 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvmarm, kvm, pbonzini

On Wed, Jun 11, 2014 at 04:01:30PM +0200, Andrew Jones wrote:
> This is the initial drop of the arm test framework and a first test
> that just checks that setup completed (a selftest). kvm isn't needed
> to run this test unless testing with smp > 1.
> 
> Try it out with
>   yum install gcc-arm-linux-gnu
>   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>
> ---
> v5:
>   - memregions: check freemem_start is in bounds and document
>   - selftest: rename testnam => testname and properly init it
>   - io.c: use writeb instead of writel in puts() and use ioremap
>   - arm/run script update for new qemu ('-device ?' now requires -machine)
>   - couple other minor changes to setup.c and io.c [Christoffer Dall]
> v4:
>   - moved fdt to just after stacktop (it was in the middle of free memory)
>   - switched from using heap to memregions
>   - get nr_cpus and added smp=<num> test
>   - added barrier.h
>   - use new report()/report_summary()
>   - config/config-arm.mak cleanup
> ---
>  arm/cstart.S           |  35 ++++++++++++
>  arm/flat.lds           |  18 ++++++
>  arm/run                |  35 ++++++++++++
>  arm/selftest.c         |  89 +++++++++++++++++++++++++++++
>  arm/unittests.cfg      |  18 ++++++
>  config/config-arm.mak  |  72 ++++++++++++++++++++++++
>  configure              |  12 +++-
>  lib/argv.c             |   6 ++
>  lib/arm/asm/barrier.h  |  18 ++++++
>  lib/arm/asm/io.h       |  24 ++++++++
>  lib/arm/asm/setup.h    |  63 +++++++++++++++++++++
>  lib/arm/asm/spinlock.h |  16 ++++++
>  lib/arm/eabi_compat.c  |  20 +++++++
>  lib/arm/io.c           |  65 +++++++++++++++++++++
>  lib/arm/setup.c        | 149 +++++++++++++++++++++++++++++++++++++++++++++++++
>  15 files changed, 638 insertions(+), 2 deletions(-)
>  create mode 100644 arm/cstart.S
>  create mode 100644 arm/flat.lds
>  create mode 100755 arm/run
>  create mode 100644 arm/selftest.c
>  create mode 100644 arm/unittests.cfg
>  create mode 100644 config/config-arm.mak
>  create mode 100644 lib/arm/asm/barrier.h
>  create mode 100644 lib/arm/asm/io.h
>  create mode 100644 lib/arm/asm/setup.h
>  create mode 100644 lib/arm/asm/spinlock.h
>  create mode 100644 lib/arm/eabi_compat.c
>  create mode 100644 lib/arm/io.c
>  create mode 100644 lib/arm/setup.c
> 
> diff --git a/arm/cstart.S b/arm/cstart.S
> new file mode 100644
> index 0000000000000..e28251db2950d
> --- /dev/null
> +++ b/arm/cstart.S
> @@ -0,0 +1,35 @@
> +/*
> + * Boot entry point and assembler functions for armv7 tests.
> + *
> + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +
> +.arm
> +
> +.section .init
> +
> +.globl start
> +start:
> +	/*
> +	 * bootloader params are in r0-r2
> +	 * See the kernel doc Documentation/arm/Booting
> +	 */
> +	ldr	sp, =stacktop
> +	bl	setup
> +
> +	/* run the test */
> +	ldr	r0, =__argc
> +	ldr	r0, [r0]
> +	ldr	r1, =__argv
> +	bl	main
> +	bl	exit
> +	b	halt
> +
> +.text
> +
> +.globl halt
> +halt:
> +1:	wfi
> +	b	1b
> 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..627123b7bc9b6
> --- /dev/null
> +++ b/arm/run
> @@ -0,0 +1,35 @@
> +#!/bin/bash
> +
> +if [ ! -f config.mak ]; then
> +	echo run ./configure first. See ./configure -h
> +	exit 2
> +fi
> +source config.mak
> +
> +qemu="${QEMU:-qemu-system-arm}"
> +qpath=$(which $qemu 2>/dev/null)
> +testdev=virtio-testdev
> +
> +if [ -z "$qpath" ]; then
> +	echo $qemu not found.
> +	exit 2
> +fi
> +
> +if ! $qemu -machine '?' 2>&1 | grep 'ARM Virtual Machine' > /dev/null; then
> +	echo "$qpath doesn't support mach-virt ('-machine virt'). Exiting."
> +	exit 2
> +fi
> +
> +if ! $qemu -machine virt -device '?' 2>&1 | grep $testdev > /dev/null; then
> +	echo "$qpath doesn't support $testdev. Exiting."
> +	exit 2
> +fi
> +
> +command="$qemu -machine virt,accel=kvm:tcg -device $testdev -cpu $PROCESSOR"
> +command+=" -display none -serial stdio -kernel"
> +
> +echo $command "$@"
> +$command "$@"
> +ret=$?
> +echo Return value from qemu: $ret
> +exit $ret
> diff --git a/arm/selftest.c b/arm/selftest.c
> new file mode 100644
> index 0000000000000..bcaecfae17fcd
> --- /dev/null
> +++ b/arm/selftest.c
> @@ -0,0 +1,89 @@
> +/*
> + * Test the framework itself. These tests confirm that setup works.
> + *
> + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#include "libcflat.h"
> +#include "asm/setup.h"
> +
> +#define TESTGRP "selftest"
> +
> +static char testname[64];
> +
> +static void testname_set(const char *subtest)
> +{
> +	strcpy(testname, TESTGRP);
> +	if (subtest) {
> +		strcat(testname, "::");
> +		strcat(testname, subtest);
> +	}
> +}
> +
> +static void assert_args(int num_args, int needed_args)
> +{
> +	if (num_args < needed_args) {
> +		printf("%s: not enough arguments\n", testname);
> +		abort();
> +	}
> +}
> +
> +static char *split_var(char *s, long *val)
> +{
> +	char *p;
> +
> +	p = strchr(s, '=');
> +	if (!p)
> +		return NULL;
> +
> +	*val = atol(p+1);
> +	*p = '\0';
> +
> +	return s;
> +}
> +
> +static void check_setup(int argc, char **argv)
> +{
> +	int nr_tests = 0, i;
> +	char *var;
> +	long val;
> +
> +	for (i = 0; i < argc; ++i) {
> +
> +		var = split_var(argv[i], &val);
> +		if (!var)
> +			continue;
> +
> +		if (strcmp(argv[i], "mem") == 0) {
> +
> +			phys_addr_t memsize =
> +					memregions[nr_memregions-1].addr
> +					+ memregions[nr_memregions-1].size
> +					- PHYS_OFFSET;
> +			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
> +
> +			report("%s[%s]", memsize == expected, testname, "mem");
> +			++nr_tests;
> +
> +		} else if (strcmp(argv[i], "smp") == 0) {
> +
> +			report("%s[%s]", nr_cpus == (int)val, testname, "smp");
> +			++nr_tests;
> +		}
> +	}
> +
> +	assert_args(nr_tests, 2);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +	testname_set(NULL);
> +	assert_args(argc, 1);
> +	testname_set(argv[0]);
> +
> +	if (strcmp(argv[0], "setup") == 0)
> +		check_setup(argc-1, &argv[1]);
> +
> +	return report_summary();
> +}
> diff --git a/arm/unittests.cfg b/arm/unittests.cfg
> new file mode 100644
> index 0000000000000..da9dfd7b1f118
> --- /dev/null
> +++ b/arm/unittests.cfg
> @@ -0,0 +1,18 @@
> +# 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 test case is specific to one
> +# groups = group1 group2 # Used to identify test cases with run_tests -g ...
> +
> +#
> +# Test that the configured number of processors (smp = <num>), and
> +# that the configured amount of memory (-m <MB>) are correctly setup
> +# by the framework.
> +#
> +[selftest::setup]
> +file = selftest.flat
> +smp  = 1
> +extra_params = -m 256 -append 'setup smp=1 mem=256'
> +groups = selftest
> diff --git a/config/config-arm.mak b/config/config-arm.mak
> new file mode 100644
> index 0000000000000..915b1cc318d79
> --- /dev/null
> +++ b/config/config-arm.mak
> @@ -0,0 +1,72 @@
> +#
> +# arm makefile
> +#
> +# Authors: Andrew Jones <drjones@redhat.com>
> +#
> +
> +tests-common = \
> +	$(TEST_DIR)/selftest.flat
> +
> +tests =
> +
> +all: test_cases
> +
> +##################################################################
> +bits = 32
> +ldarch = elf32-littlearm
> +
> +ifeq ($(LOADADDR),)
> +	LOADADDR = 0x40000000
> +endif
> +phys_base = $(LOADADDR)
> +kernel_offset = 0x10000
> +
> +CFLAGS += -D__arm__
> +CFLAGS += -marm
> +CFLAGS += -mcpu=$(PROCESSOR)
> +CFLAGS += -std=gnu99
> +CFLAGS += -ffreestanding
> +CFLAGS += -Wextra
> +CFLAGS += -O2
> +CFLAGS += -I lib -I lib/libfdt
> +
> +cflatobjs += \
> +	lib/devicetree.o \
> +	lib/virtio.o \
> +	lib/virtio-testdev.o \
> +	lib/arm/io.o \
> +	lib/arm/setup.o
> +
> +libeabi = lib/arm/libeabi.a
> +eabiobjs = lib/arm/eabi_compat.o
> +
> +libgcc := $(shell $(CC) -m$(ARCH) --print-libgcc-file-name)
> +start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> +
> +FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
> +%.elf: LDFLAGS = $(CFLAGS) -nostdlib
> +%.elf: %.o $(FLATLIBS) arm/flat.lds
> +	$(CC) $(LDFLAGS) -o $@ \
> +		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
> +		$(filter %.o, $^) $(FLATLIBS)
> +
> +%.flat: %.elf
> +	$(OBJCOPY) -O binary $^ $@
> +
> +$(libeabi): $(eabiobjs)
> +	$(AR) rcs $@ $^
> +
> +arch_clean: libfdt_clean
> +	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
> +	      $(TEST_DIR)/.*.d lib/arm/.*.d
> +
> +##################################################################
> +
> +tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
> +
> +cstart.o = $(TEST_DIR)/cstart.o
> +
> +test_cases: $(tests-common) $(tests)
> +
> +$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
> +
> diff --git a/configure b/configure
> index 8a81bf92e27b7..f92f585724bb1 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,12 @@ while [[ "$1" = -* ]]; do
>  	    ;;
>      esac
>  done
> +[ -z "$processor" ] && processor="$arch"
> +
> +if [ "$processor" = "arm" ]; then
> +    processor="cortex-a15"
> +fi
> +
>  if [ -z "$testdir" -a \( "$arch" = "i386" -o "$arch" = "x86_64" \) ]; then
>      testdir=x86
>  elif [ -z "$testdir" ]; then
> @@ -80,6 +86,7 @@ if [ -f $testdir/run ]; then
>  fi
>  
>  # check for dependent 32 bit libraries
> +if [ "$arch" != "arm" ]; then
>  cat << EOF > lib_test.c
>  #include <stdc++.h>
>  #include <boost_thread-mt.h>
> @@ -94,6 +101,7 @@ if [ $exit -eq 0 ]; then
>      api=true
>  fi
>  rm -f lib_test.c
> +fi
>  
>  # link lib/asm for the architecture
>  rm -f lib/asm
> diff --git a/lib/argv.c b/lib/argv.c
> index 4ee54a6eeac3e..078a05faffebf 100644
> --- a/lib/argv.c
> +++ b/lib/argv.c
> @@ -31,3 +31,9 @@ void __setup_args(void)
>      }
>      __argc = argv - __argv;
>  }
> +
> +void setup_args(char *args)
> +{
> +    __args = args;
> +    __setup_args();
> +}
> diff --git a/lib/arm/asm/barrier.h b/lib/arm/asm/barrier.h
> new file mode 100644
> index 0000000000000..acaeab5123431
> --- /dev/null
> +++ b/lib/arm/asm/barrier.h
> @@ -0,0 +1,18 @@
> +#ifndef _ASMARM_BARRIER_H_
> +#define _ASMARM_BARRIER_H_
> +/*
> + * Adapted form arch/arm/include/asm/barrier.h
> + */
> +
> +#define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory")
> +#define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
> +#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
> +
> +#define mb()		dsb()
> +#define rmb()		dsb()
> +#define wmb()		dsb(st)
> +#define smp_mb()	dmb(ish)
> +#define smp_rmb()	smp_mb()
> +#define smp_wmb()	dmb(ishst)
> +
> +#endif /* _ASMARM_BARRIER_H_ */
> diff --git a/lib/arm/asm/io.h b/lib/arm/asm/io.h
> new file mode 100644
> index 0000000000000..51ec6e9aa2e99
> --- /dev/null
> +++ b/lib/arm/asm/io.h
> @@ -0,0 +1,24 @@
> +#ifndef _ASMARM_IO_H_
> +#define _ASMARM_IO_H_
> +#include "libcflat.h"
> +#include "asm/barrier.h"
> +
> +#define __bswap16 bswap16
> +static inline u16 bswap16(u16 val)
> +{
> +	u16 ret;
> +	asm volatile("rev16 %0, %1" : "=r" (ret) :  "r" (val));
> +	return ret;
> +}
> +
> +#define __bswap32 bswap32
> +static inline u32 bswap32(u32 val)
> +{
> +	u32 ret;
> +	asm volatile("rev %0, %1" : "=r" (ret) :  "r" (val));
> +	return ret;
> +}
> +
> +#include "asm-generic/io.h"
> +
> +#endif /* _ASMARM_IO_H_ */
> diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
> new file mode 100644
> index 0000000000000..8aedf6e672541
> --- /dev/null
> +++ b/lib/arm/asm/setup.h
> @@ -0,0 +1,63 @@
> +#ifndef _ASMARM_SETUP_H_
> +#define _ASMARM_SETUP_H_
> +/*
> + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#include "libcflat.h"
> +
> +#define NR_CPUS			8
> +extern u32 cpus[NR_CPUS];
> +extern int nr_cpus;
> +
> +typedef u64 phys_addr_t;
> +
> +/*
> + * memregions implement a very simple allocator which allows physical
> + * memory to be partitioned into regions until all memory is allocated.
> + * Also, as long as not all memory has been allocated, one region (the
> + * highest indexable region) is used to represent the start and size of
> + * the remaining free memory. This means that there will always be a
> + * minimum of two regions: one for the unit test code, initially loaded
> + * at the base of physical memory (PHYS_OFFSET), and another for the
> + * remaining free memory.
> + *
> + * Note: This is such a simple allocator that there is no way to free
> + * a memregion. For more complicated memory management a single region
> + * can be allocated, but then have its memory managed by a more
> + * sophisticated allocator, e.g. a page allocator.
> + */
> +#define NR_MEMREGIONS		16
> +struct memregion {
> +	phys_addr_t addr;
> +	phys_addr_t size;
> +	bool free;
> +};
> +
> +extern struct memregion memregions[NR_MEMREGIONS];
> +extern int nr_memregions;
> +
> +/*
> + * memregion_new returns a new memregion of size @size, or NULL if
> + * there isn't enough free memory to satisfy the request.
> + */
> +extern struct memregion *memregion_new(phys_addr_t size);
> +
> +/*
> + * memregions_show outputs all memregions with the following format
> + *   <start_addr>-<end_addr> [<USED|FREE>]
> + */
> +extern void memregions_show(void);
> +
> +#define PHYS_OFFSET		({ memregions[0].addr; })
> +#define PHYS_SHIFT		40
> +#define PHYS_SIZE		(1ULL << PHYS_SHIFT)
> +#define PHYS_MASK		(PHYS_SIZE - 1ULL)
> +
> +#define PAGE_SHIFT		12
> +#define PAGE_SIZE		(1UL << PAGE_SHIFT)
> +#define PAGE_MASK		(~(PAGE_SIZE - 1UL))
> +#define PAGE_ALIGN(addr)	(((addr) + (PAGE_SIZE-1UL)) & PAGE_MASK)
> +
> +#endif /* _ASMARM_SETUP_H_ */
> diff --git a/lib/arm/asm/spinlock.h b/lib/arm/asm/spinlock.h
> new file mode 100644
> index 0000000000000..04f5a1a5538e2
> --- /dev/null
> +++ b/lib/arm/asm/spinlock.h
> @@ -0,0 +1,16 @@
> +#ifndef _ASMARM_SPINLOCK_H_
> +#define _ASMARM_SPINLOCK_H_
> +
> +struct spinlock {
> +	int v;
> +};
> +
> +//TODO
> +static inline void spin_lock(struct spinlock *lock __unused)
> +{
> +}
> +static inline void spin_unlock(struct spinlock *lock __unused)
> +{
> +}
> +
> +#endif /* _ASMARM_SPINLOCK_H_ */
> diff --git a/lib/arm/eabi_compat.c b/lib/arm/eabi_compat.c
> new file mode 100644
> index 0000000000000..59d624dcd9277
> --- /dev/null
> +++ b/lib/arm/eabi_compat.c
> @@ -0,0 +1,20 @@
> +/*
> + * Adapted from u-boot's arch/arm/lib/eabi_compat.c
> + */
> +#include "libcflat.h"
> +
> +int raise(int signum __unused)
> +{
> +	printf("Divide by zero!\n");
> +	abort();
> +	return 0;
> +}
> +
> +/* Dummy functions to avoid linker complaints */
> +void __aeabi_unwind_cpp_pr0(void)
> +{
> +}
> +
> +void __aeabi_unwind_cpp_pr1(void)
> +{
> +}
> diff --git a/lib/arm/io.c b/lib/arm/io.c
> new file mode 100644
> index 0000000000000..114d6517a959e
> --- /dev/null
> +++ b/lib/arm/io.c
> @@ -0,0 +1,65 @@
> +/*
> + * Each architecture must implement puts() and exit() with the I/O
> + * devices exposed from QEMU, e.g. pl011 and virtio-testdev. That's
> + * what's done here, along with initialization functions for those
> + * devices.
> + *
> + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#include "libcflat.h"
> +#include "devicetree.h"
> +#include "virtio-testdev.h"
> +#include "asm/spinlock.h"
> +#include "asm/io.h"
> +
> +extern void halt(int code);
> +
> +/*
> + * Use this guess for the pl011 base in order to make an attempt at
> + * having earlier printf support. We'll overwrite it with the real
> + * base address that we read from the device tree later.
> + */
> +#define QEMU_MACH_VIRT_PL011_BASE 0x09000000UL
> +
> +static struct spinlock uart_lock;
> +static volatile u8 *uart0_base = (u8 *)QEMU_MACH_VIRT_PL011_BASE;
> +
> +static void uart0_init(void)
> +{
> +	const char *compatible = "arm,pl011";
> +	struct dt_pbus_reg base;
> +	int ret;
> +
> +	ret = dt_pbus_get_base_compatible(compatible, &base);
> +	assert(ret == 0 || ret == -FDT_ERR_NOTFOUND);
> +
> +	if (ret) {
> +		printf("%s: %s not found in the device tree, aborting...\n",
> +			__func__, compatible);
> +		abort();
> +	}
> +
> +	uart0_base = ioremap(base.addr, base.size);
> +}
> +
> +void io_init(void)
> +{
> +	uart0_init();
> +	virtio_testdev_init();
> +}
> +
> +void puts(const char *s)
> +{
> +	spin_lock(&uart_lock);
> +	while (*s)
> +		writeb(*s++, uart0_base);
> +	spin_unlock(&uart_lock);
> +}
> +
> +void exit(int code)
> +{
> +	virtio_testdev_exit(code);
> +	halt(code);
> +}
> diff --git a/lib/arm/setup.c b/lib/arm/setup.c
> new file mode 100644
> index 0000000000000..dafjsdfl86a244aef56b8
> --- /dev/null
> +++ b/lib/arm/setup.c
> @@ -0,0 +1,149 @@
> +/*
> + * Initialize machine setup information and I/O.
> + *
> + * After running setup() unit tests may query how many cpus they have
> + * (nr_cpus), how much free memory it has, and at what physical

nit: you seem to be changing between singular and plural here, it's
confusing.

> + * address that free memory starts (memregions[1].{addr,size}),
> + * printf() and exit() will both work, and (argc, argv) are ready
> + * to be passed to main().
> + *
> + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.
> + */
> +#include "libcflat.h"
> +#include "libfdt/libfdt.h"
> +#include "devicetree.h"
> +#include "asm/spinlock.h"
> +#include "asm/setup.h"
> +
> +extern unsigned long stacktop;
> +extern void io_init(void);
> +extern void setup_args(const char *args);
> +
> +u32 cpus[NR_CPUS] = { [0 ... NR_CPUS-1] = (~0UL) };
> +int nr_cpus;
> +
> +static struct spinlock memregion_lock;
> +struct memregion memregions[NR_MEMREGIONS];
> +int nr_memregions;
> +
> +static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
> +{
> +	assert(nr_cpus < NR_CPUS);
> +	cpus[nr_cpus++] = regval;
> +}
> +
> +static void cpu_init(void)
> +{
> +	nr_cpus = 0;
> +	assert(dt_for_each_cpu_node(cpu_set, NULL) == 0);
> +}
> +
> +static void memregions_init(phys_addr_t freemem_start)
> +{
> +	/* we only expect one membank to be defined in the DT */
> +	struct dt_pbus_reg regs[1];
> +	phys_addr_t addr, size, mem_end;
> +
> +	nr_memregions = dt_get_memory_params(regs, 1);
> +
> +	assert(nr_memregions > 0);
> +
> +	addr = regs[0].addr;
> +	size = regs[0].size;
> +	mem_end = addr + size;
> +
> +	assert(!(addr & ~PHYS_MASK) && !((mem_end-1) & ~PHYS_MASK));
> +
> +	memregions[0].addr = PAGE_ALIGN(addr); /* PHYS_OFFSET */
> +
> +	freemem_start = PAGE_ALIGN(freemem_start);
> +	assert(freemem_start >= PHYS_OFFSET && freemem_start < mem_end);
> +
> +	memregions[0].size = freemem_start - PHYS_OFFSET;
> +	memregions[1].addr = freemem_start;
> +	memregions[1].size = mem_end - freemem_start;
> +	memregions[1].free = true;
> +	nr_memregions = 2;
> +
> +#ifdef __arm__
> +	/*
> +	 * make sure 32-bit unit tests don't have any surprises when
> +	 * running without virtual memory, by ensuring the initial
> +	 * memory region uses 32-bit addresses. Other memory regions
> +	 * may have > 32-bit addresses though, and the unit tests are
> +	 * free to do as they wish with that.
> +	 */
> +	assert(!(memregions[0].addr >> 32));
> +	assert(!((memregions[0].addr + memregions[0].size - 1) >> 32));
> +#endif
> +}
> +
> +struct memregion *memregion_new(phys_addr_t size)
> +{
> +	phys_addr_t freemem_start, mem_end;
> +	struct memregion *mr;
> +
> +	spin_lock(&memregion_lock);
> +
> +	mr = &memregions[nr_memregions-1];
> +
> +	if (!mr->free || mr->size < size) {
> +		printf("%s: requested=0x%llx, free=0x%llx.\n", size,
> +				mr->free ? mr->size : 0ULL);
> +		return NULL;
> +	}
> +
> +	mem_end = mr->addr + mr->size;
> +
> +	mr->size = size;
> +	mr->free = false;
> +
> +	freemem_start = PAGE_ALIGN(mr->addr + size);
> +
> +	if (freemem_start < mem_end && nr_memregions < NR_MEMREGIONS) {
> +		mr->size = freemem_start - mr->addr;
> +		memregions[nr_memregions].addr = freemem_start;
> +		memregions[nr_memregions].size = mem_end - freemem_start;
> +		memregions[nr_memregions].free = true;
> +		++nr_memregions;
> +	}
> +
> +	spin_unlock(&memregion_lock);
> +
> +	return mr;
> +}
> +
> +void memregions_show(void)
> +{
> +	int i;
> +	for (i = 0; i < nr_memregions; ++i)
> +		printf("%016llx-%016llx [%s]\n",
> +			memregions[i].addr,
> +			memregions[i].addr + memregions[i].size - 1,
> +			memregions[i].free ? "FREE" : "USED");
> +}
> +
> +void setup(unsigned long arg __unused, unsigned long id __unused,
> +	   const void *fdt)
> +{
> +	const char *bootargs;
> +	u32 fdt_size;
> +
> +	/*
> +	 * Move the fdt to just above the stack. The free memory
> +	 * then starts just after the fdt.
> +	 */
> +	fdt_size = fdt_totalsize(fdt);
> +	assert(fdt_move(fdt, &stacktop, fdt_size) == 0);
> +	assert(dt_init(&stacktop) == 0);
> +
> +	memregions_init((unsigned long)&stacktop + fdt_size);
> +
> +	io_init();
> +	cpu_init();
> +
> +	assert(dt_get_bootargs(&bootargs) == 0);
> +	setup_args(bootargs);
> +}
> -- 
> 1.9.3
> 

looks good otherwise:

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 00/19] kvm-unit-tests/arm: initial drop
  2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
                   ` (19 preceding siblings ...)
       [not found] ` <1402495294-30737-7-git-send-email-drjones@redhat.com>
@ 2014-06-14 14:44 ` Christoffer Dall
  2014-06-16  7:46   ` Andrew Jones
  20 siblings, 1 reply; 45+ messages in thread
From: Christoffer Dall @ 2014-06-14 14:44 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvmarm, kvm, pbonzini

On Wed, Jun 11, 2014 at 04:01:15PM +0200, Andrew Jones wrote:
> This is a v5 of a series that introduces arm to kvm-unit-tests. First,
> it does some tidying up of the repo. Then, it adds support for device
> trees (libfdt), and for virtio-testdev[1]. Next, it adds the basic
> infrastructure for booting a test case (guest), and adds a first
> test case, a self-test to confirm setup was completed successfully.
> Finally, it further prepares the framework for more complicated tests
> by adding vector support, and extends the self-test to test that too.
> 
> This initial drop doesn't require kvmarm. qemu-system-arm is enough,
> but it must have mach-virt, and the virtio-testdev patch[1].
> 
> These patches (v5) are also available from a git repo here
> https://github.com/rhdrjones/kvm-unit-tests/commits/arm/v5-initial-drop
> 
> The v4 patches are available for reference here
> https://github.com/rhdrjones/kvm-unit-tests/commits/arm/v4-initial-drop
> 
> Not too much has changed since v4. There are no new patches nor dropped
> patches, and all patches that did get a change have a v5 note. To see
> a branch interdiff (created with git-tbdiff[2]) take a look here[3].
> 
> Thanks in advance for reviews!
> 
This now looks pretty good overall.  Feels to me like if you address
Paolo's comments then this could be merged, and we can start adding more
complicated tests to it.

When you send out the next (last?) version, I can give it a spin on
hardware with KVM as well.

-Christoffer

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 15/19] arm: initial drop
  2014-06-14 14:16   ` Christoffer Dall
@ 2014-06-16  7:36     ` Andrew Jones
  0 siblings, 0 replies; 45+ messages in thread
From: Andrew Jones @ 2014-06-16  7:36 UTC (permalink / raw)
  To: Christoffer Dall; +Cc: kvmarm, kvm, pbonzini

On Sat, Jun 14, 2014 at 04:16:53PM +0200, Christoffer Dall wrote:
> On Wed, Jun 11, 2014 at 04:01:30PM +0200, Andrew Jones wrote:
> > This is the initial drop of the arm test framework and a first test
> > that just checks that setup completed (a selftest). kvm isn't needed
> > to run this test unless testing with smp > 1.
> > 
> > Try it out with
> >   yum install gcc-arm-linux-gnu
> >   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>
> > ---
> > v5:
> >   - memregions: check freemem_start is in bounds and document
> >   - selftest: rename testnam => testname and properly init it
> >   - io.c: use writeb instead of writel in puts() and use ioremap
> >   - arm/run script update for new qemu ('-device ?' now requires -machine)
> >   - couple other minor changes to setup.c and io.c [Christoffer Dall]
> > v4:
> >   - moved fdt to just after stacktop (it was in the middle of free memory)
> >   - switched from using heap to memregions
> >   - get nr_cpus and added smp=<num> test
> >   - added barrier.h
> >   - use new report()/report_summary()
> >   - config/config-arm.mak cleanup
> > ---
> >  arm/cstart.S           |  35 ++++++++++++
> >  arm/flat.lds           |  18 ++++++
> >  arm/run                |  35 ++++++++++++
> >  arm/selftest.c         |  89 +++++++++++++++++++++++++++++
> >  arm/unittests.cfg      |  18 ++++++
> >  config/config-arm.mak  |  72 ++++++++++++++++++++++++
> >  configure              |  12 +++-
> >  lib/argv.c             |   6 ++
> >  lib/arm/asm/barrier.h  |  18 ++++++
> >  lib/arm/asm/io.h       |  24 ++++++++
> >  lib/arm/asm/setup.h    |  63 +++++++++++++++++++++
> >  lib/arm/asm/spinlock.h |  16 ++++++
> >  lib/arm/eabi_compat.c  |  20 +++++++
> >  lib/arm/io.c           |  65 +++++++++++++++++++++
> >  lib/arm/setup.c        | 149 +++++++++++++++++++++++++++++++++++++++++++++++++
> >  15 files changed, 638 insertions(+), 2 deletions(-)
> >  create mode 100644 arm/cstart.S
> >  create mode 100644 arm/flat.lds
> >  create mode 100755 arm/run
> >  create mode 100644 arm/selftest.c
> >  create mode 100644 arm/unittests.cfg
> >  create mode 100644 config/config-arm.mak
> >  create mode 100644 lib/arm/asm/barrier.h
> >  create mode 100644 lib/arm/asm/io.h
> >  create mode 100644 lib/arm/asm/setup.h
> >  create mode 100644 lib/arm/asm/spinlock.h
> >  create mode 100644 lib/arm/eabi_compat.c
> >  create mode 100644 lib/arm/io.c
> >  create mode 100644 lib/arm/setup.c
> > 
> > diff --git a/arm/cstart.S b/arm/cstart.S
> > new file mode 100644
> > index 0000000000000..e28251db2950d
> > --- /dev/null
> > +++ b/arm/cstart.S
> > @@ -0,0 +1,35 @@
> > +/*
> > + * Boot entry point and assembler functions for armv7 tests.
> > + *
> > + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > + */
> > +
> > +.arm
> > +
> > +.section .init
> > +
> > +.globl start
> > +start:
> > +	/*
> > +	 * bootloader params are in r0-r2
> > +	 * See the kernel doc Documentation/arm/Booting
> > +	 */
> > +	ldr	sp, =stacktop
> > +	bl	setup
> > +
> > +	/* run the test */
> > +	ldr	r0, =__argc
> > +	ldr	r0, [r0]
> > +	ldr	r1, =__argv
> > +	bl	main
> > +	bl	exit
> > +	b	halt
> > +
> > +.text
> > +
> > +.globl halt
> > +halt:
> > +1:	wfi
> > +	b	1b
> > 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..627123b7bc9b6
> > --- /dev/null
> > +++ b/arm/run
> > @@ -0,0 +1,35 @@
> > +#!/bin/bash
> > +
> > +if [ ! -f config.mak ]; then
> > +	echo run ./configure first. See ./configure -h
> > +	exit 2
> > +fi
> > +source config.mak
> > +
> > +qemu="${QEMU:-qemu-system-arm}"
> > +qpath=$(which $qemu 2>/dev/null)
> > +testdev=virtio-testdev
> > +
> > +if [ -z "$qpath" ]; then
> > +	echo $qemu not found.
> > +	exit 2
> > +fi
> > +
> > +if ! $qemu -machine '?' 2>&1 | grep 'ARM Virtual Machine' > /dev/null; then
> > +	echo "$qpath doesn't support mach-virt ('-machine virt'). Exiting."
> > +	exit 2
> > +fi
> > +
> > +if ! $qemu -machine virt -device '?' 2>&1 | grep $testdev > /dev/null; then
> > +	echo "$qpath doesn't support $testdev. Exiting."
> > +	exit 2
> > +fi
> > +
> > +command="$qemu -machine virt,accel=kvm:tcg -device $testdev -cpu $PROCESSOR"
> > +command+=" -display none -serial stdio -kernel"
> > +
> > +echo $command "$@"
> > +$command "$@"
> > +ret=$?
> > +echo Return value from qemu: $ret
> > +exit $ret
> > diff --git a/arm/selftest.c b/arm/selftest.c
> > new file mode 100644
> > index 0000000000000..bcaecfae17fcd
> > --- /dev/null
> > +++ b/arm/selftest.c
> > @@ -0,0 +1,89 @@
> > +/*
> > + * Test the framework itself. These tests confirm that setup works.
> > + *
> > + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > + */
> > +#include "libcflat.h"
> > +#include "asm/setup.h"
> > +
> > +#define TESTGRP "selftest"
> > +
> > +static char testname[64];
> > +
> > +static void testname_set(const char *subtest)
> > +{
> > +	strcpy(testname, TESTGRP);
> > +	if (subtest) {
> > +		strcat(testname, "::");
> > +		strcat(testname, subtest);
> > +	}
> > +}
> > +
> > +static void assert_args(int num_args, int needed_args)
> > +{
> > +	if (num_args < needed_args) {
> > +		printf("%s: not enough arguments\n", testname);
> > +		abort();
> > +	}
> > +}
> > +
> > +static char *split_var(char *s, long *val)
> > +{
> > +	char *p;
> > +
> > +	p = strchr(s, '=');
> > +	if (!p)
> > +		return NULL;
> > +
> > +	*val = atol(p+1);
> > +	*p = '\0';
> > +
> > +	return s;
> > +}
> > +
> > +static void check_setup(int argc, char **argv)
> > +{
> > +	int nr_tests = 0, i;
> > +	char *var;
> > +	long val;
> > +
> > +	for (i = 0; i < argc; ++i) {
> > +
> > +		var = split_var(argv[i], &val);
> > +		if (!var)
> > +			continue;
> > +
> > +		if (strcmp(argv[i], "mem") == 0) {
> > +
> > +			phys_addr_t memsize =
> > +					memregions[nr_memregions-1].addr
> > +					+ memregions[nr_memregions-1].size
> > +					- PHYS_OFFSET;
> > +			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
> > +
> > +			report("%s[%s]", memsize == expected, testname, "mem");
> > +			++nr_tests;
> > +
> > +		} else if (strcmp(argv[i], "smp") == 0) {
> > +
> > +			report("%s[%s]", nr_cpus == (int)val, testname, "smp");
> > +			++nr_tests;
> > +		}
> > +	}
> > +
> > +	assert_args(nr_tests, 2);
> > +}
> > +
> > +int main(int argc, char **argv)
> > +{
> > +	testname_set(NULL);
> > +	assert_args(argc, 1);
> > +	testname_set(argv[0]);
> > +
> > +	if (strcmp(argv[0], "setup") == 0)
> > +		check_setup(argc-1, &argv[1]);
> > +
> > +	return report_summary();
> > +}
> > diff --git a/arm/unittests.cfg b/arm/unittests.cfg
> > new file mode 100644
> > index 0000000000000..da9dfd7b1f118
> > --- /dev/null
> > +++ b/arm/unittests.cfg
> > @@ -0,0 +1,18 @@
> > +# 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 test case is specific to one
> > +# groups = group1 group2 # Used to identify test cases with run_tests -g ...
> > +
> > +#
> > +# Test that the configured number of processors (smp = <num>), and
> > +# that the configured amount of memory (-m <MB>) are correctly setup
> > +# by the framework.
> > +#
> > +[selftest::setup]
> > +file = selftest.flat
> > +smp  = 1
> > +extra_params = -m 256 -append 'setup smp=1 mem=256'
> > +groups = selftest
> > diff --git a/config/config-arm.mak b/config/config-arm.mak
> > new file mode 100644
> > index 0000000000000..915b1cc318d79
> > --- /dev/null
> > +++ b/config/config-arm.mak
> > @@ -0,0 +1,72 @@
> > +#
> > +# arm makefile
> > +#
> > +# Authors: Andrew Jones <drjones@redhat.com>
> > +#
> > +
> > +tests-common = \
> > +	$(TEST_DIR)/selftest.flat
> > +
> > +tests =
> > +
> > +all: test_cases
> > +
> > +##################################################################
> > +bits = 32
> > +ldarch = elf32-littlearm
> > +
> > +ifeq ($(LOADADDR),)
> > +	LOADADDR = 0x40000000
> > +endif
> > +phys_base = $(LOADADDR)
> > +kernel_offset = 0x10000
> > +
> > +CFLAGS += -D__arm__
> > +CFLAGS += -marm
> > +CFLAGS += -mcpu=$(PROCESSOR)
> > +CFLAGS += -std=gnu99
> > +CFLAGS += -ffreestanding
> > +CFLAGS += -Wextra
> > +CFLAGS += -O2
> > +CFLAGS += -I lib -I lib/libfdt
> > +
> > +cflatobjs += \
> > +	lib/devicetree.o \
> > +	lib/virtio.o \
> > +	lib/virtio-testdev.o \
> > +	lib/arm/io.o \
> > +	lib/arm/setup.o
> > +
> > +libeabi = lib/arm/libeabi.a
> > +eabiobjs = lib/arm/eabi_compat.o
> > +
> > +libgcc := $(shell $(CC) -m$(ARCH) --print-libgcc-file-name)
> > +start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> > +
> > +FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi)
> > +%.elf: LDFLAGS = $(CFLAGS) -nostdlib
> > +%.elf: %.o $(FLATLIBS) arm/flat.lds
> > +	$(CC) $(LDFLAGS) -o $@ \
> > +		-Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
> > +		$(filter %.o, $^) $(FLATLIBS)
> > +
> > +%.flat: %.elf
> > +	$(OBJCOPY) -O binary $^ $@
> > +
> > +$(libeabi): $(eabiobjs)
> > +	$(AR) rcs $@ $^
> > +
> > +arch_clean: libfdt_clean
> > +	$(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \
> > +	      $(TEST_DIR)/.*.d lib/arm/.*.d
> > +
> > +##################################################################
> > +
> > +tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
> > +
> > +cstart.o = $(TEST_DIR)/cstart.o
> > +
> > +test_cases: $(tests-common) $(tests)
> > +
> > +$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o
> > +
> > diff --git a/configure b/configure
> > index 8a81bf92e27b7..f92f585724bb1 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,12 @@ while [[ "$1" = -* ]]; do
> >  	    ;;
> >      esac
> >  done
> > +[ -z "$processor" ] && processor="$arch"
> > +
> > +if [ "$processor" = "arm" ]; then
> > +    processor="cortex-a15"
> > +fi
> > +
> >  if [ -z "$testdir" -a \( "$arch" = "i386" -o "$arch" = "x86_64" \) ]; then
> >      testdir=x86
> >  elif [ -z "$testdir" ]; then
> > @@ -80,6 +86,7 @@ if [ -f $testdir/run ]; then
> >  fi
> >  
> >  # check for dependent 32 bit libraries
> > +if [ "$arch" != "arm" ]; then
> >  cat << EOF > lib_test.c
> >  #include <stdc++.h>
> >  #include <boost_thread-mt.h>
> > @@ -94,6 +101,7 @@ if [ $exit -eq 0 ]; then
> >      api=true
> >  fi
> >  rm -f lib_test.c
> > +fi
> >  
> >  # link lib/asm for the architecture
> >  rm -f lib/asm
> > diff --git a/lib/argv.c b/lib/argv.c
> > index 4ee54a6eeac3e..078a05faffebf 100644
> > --- a/lib/argv.c
> > +++ b/lib/argv.c
> > @@ -31,3 +31,9 @@ void __setup_args(void)
> >      }
> >      __argc = argv - __argv;
> >  }
> > +
> > +void setup_args(char *args)
> > +{
> > +    __args = args;
> > +    __setup_args();
> > +}
> > diff --git a/lib/arm/asm/barrier.h b/lib/arm/asm/barrier.h
> > new file mode 100644
> > index 0000000000000..acaeab5123431
> > --- /dev/null
> > +++ b/lib/arm/asm/barrier.h
> > @@ -0,0 +1,18 @@
> > +#ifndef _ASMARM_BARRIER_H_
> > +#define _ASMARM_BARRIER_H_
> > +/*
> > + * Adapted form arch/arm/include/asm/barrier.h
> > + */
> > +
> > +#define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory")
> > +#define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
> > +#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
> > +
> > +#define mb()		dsb()
> > +#define rmb()		dsb()
> > +#define wmb()		dsb(st)
> > +#define smp_mb()	dmb(ish)
> > +#define smp_rmb()	smp_mb()
> > +#define smp_wmb()	dmb(ishst)
> > +
> > +#endif /* _ASMARM_BARRIER_H_ */
> > diff --git a/lib/arm/asm/io.h b/lib/arm/asm/io.h
> > new file mode 100644
> > index 0000000000000..51ec6e9aa2e99
> > --- /dev/null
> > +++ b/lib/arm/asm/io.h
> > @@ -0,0 +1,24 @@
> > +#ifndef _ASMARM_IO_H_
> > +#define _ASMARM_IO_H_
> > +#include "libcflat.h"
> > +#include "asm/barrier.h"
> > +
> > +#define __bswap16 bswap16
> > +static inline u16 bswap16(u16 val)
> > +{
> > +	u16 ret;
> > +	asm volatile("rev16 %0, %1" : "=r" (ret) :  "r" (val));
> > +	return ret;
> > +}
> > +
> > +#define __bswap32 bswap32
> > +static inline u32 bswap32(u32 val)
> > +{
> > +	u32 ret;
> > +	asm volatile("rev %0, %1" : "=r" (ret) :  "r" (val));
> > +	return ret;
> > +}
> > +
> > +#include "asm-generic/io.h"
> > +
> > +#endif /* _ASMARM_IO_H_ */
> > diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
> > new file mode 100644
> > index 0000000000000..8aedf6e672541
> > --- /dev/null
> > +++ b/lib/arm/asm/setup.h
> > @@ -0,0 +1,63 @@
> > +#ifndef _ASMARM_SETUP_H_
> > +#define _ASMARM_SETUP_H_
> > +/*
> > + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > + */
> > +#include "libcflat.h"
> > +
> > +#define NR_CPUS			8
> > +extern u32 cpus[NR_CPUS];
> > +extern int nr_cpus;
> > +
> > +typedef u64 phys_addr_t;
> > +
> > +/*
> > + * memregions implement a very simple allocator which allows physical
> > + * memory to be partitioned into regions until all memory is allocated.
> > + * Also, as long as not all memory has been allocated, one region (the
> > + * highest indexable region) is used to represent the start and size of
> > + * the remaining free memory. This means that there will always be a
> > + * minimum of two regions: one for the unit test code, initially loaded
> > + * at the base of physical memory (PHYS_OFFSET), and another for the
> > + * remaining free memory.
> > + *
> > + * Note: This is such a simple allocator that there is no way to free
> > + * a memregion. For more complicated memory management a single region
> > + * can be allocated, but then have its memory managed by a more
> > + * sophisticated allocator, e.g. a page allocator.
> > + */
> > +#define NR_MEMREGIONS		16
> > +struct memregion {
> > +	phys_addr_t addr;
> > +	phys_addr_t size;
> > +	bool free;
> > +};
> > +
> > +extern struct memregion memregions[NR_MEMREGIONS];
> > +extern int nr_memregions;
> > +
> > +/*
> > + * memregion_new returns a new memregion of size @size, or NULL if
> > + * there isn't enough free memory to satisfy the request.
> > + */
> > +extern struct memregion *memregion_new(phys_addr_t size);
> > +
> > +/*
> > + * memregions_show outputs all memregions with the following format
> > + *   <start_addr>-<end_addr> [<USED|FREE>]
> > + */
> > +extern void memregions_show(void);
> > +
> > +#define PHYS_OFFSET		({ memregions[0].addr; })
> > +#define PHYS_SHIFT		40
> > +#define PHYS_SIZE		(1ULL << PHYS_SHIFT)
> > +#define PHYS_MASK		(PHYS_SIZE - 1ULL)
> > +
> > +#define PAGE_SHIFT		12
> > +#define PAGE_SIZE		(1UL << PAGE_SHIFT)
> > +#define PAGE_MASK		(~(PAGE_SIZE - 1UL))
> > +#define PAGE_ALIGN(addr)	(((addr) + (PAGE_SIZE-1UL)) & PAGE_MASK)
> > +
> > +#endif /* _ASMARM_SETUP_H_ */
> > diff --git a/lib/arm/asm/spinlock.h b/lib/arm/asm/spinlock.h
> > new file mode 100644
> > index 0000000000000..04f5a1a5538e2
> > --- /dev/null
> > +++ b/lib/arm/asm/spinlock.h
> > @@ -0,0 +1,16 @@
> > +#ifndef _ASMARM_SPINLOCK_H_
> > +#define _ASMARM_SPINLOCK_H_
> > +
> > +struct spinlock {
> > +	int v;
> > +};
> > +
> > +//TODO
> > +static inline void spin_lock(struct spinlock *lock __unused)
> > +{
> > +}
> > +static inline void spin_unlock(struct spinlock *lock __unused)
> > +{
> > +}
> > +
> > +#endif /* _ASMARM_SPINLOCK_H_ */
> > diff --git a/lib/arm/eabi_compat.c b/lib/arm/eabi_compat.c
> > new file mode 100644
> > index 0000000000000..59d624dcd9277
> > --- /dev/null
> > +++ b/lib/arm/eabi_compat.c
> > @@ -0,0 +1,20 @@
> > +/*
> > + * Adapted from u-boot's arch/arm/lib/eabi_compat.c
> > + */
> > +#include "libcflat.h"
> > +
> > +int raise(int signum __unused)
> > +{
> > +	printf("Divide by zero!\n");
> > +	abort();
> > +	return 0;
> > +}
> > +
> > +/* Dummy functions to avoid linker complaints */
> > +void __aeabi_unwind_cpp_pr0(void)
> > +{
> > +}
> > +
> > +void __aeabi_unwind_cpp_pr1(void)
> > +{
> > +}
> > diff --git a/lib/arm/io.c b/lib/arm/io.c
> > new file mode 100644
> > index 0000000000000..114d6517a959e
> > --- /dev/null
> > +++ b/lib/arm/io.c
> > @@ -0,0 +1,65 @@
> > +/*
> > + * Each architecture must implement puts() and exit() with the I/O
> > + * devices exposed from QEMU, e.g. pl011 and virtio-testdev. That's
> > + * what's done here, along with initialization functions for those
> > + * devices.
> > + *
> > + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > + */
> > +#include "libcflat.h"
> > +#include "devicetree.h"
> > +#include "virtio-testdev.h"
> > +#include "asm/spinlock.h"
> > +#include "asm/io.h"
> > +
> > +extern void halt(int code);
> > +
> > +/*
> > + * Use this guess for the pl011 base in order to make an attempt at
> > + * having earlier printf support. We'll overwrite it with the real
> > + * base address that we read from the device tree later.
> > + */
> > +#define QEMU_MACH_VIRT_PL011_BASE 0x09000000UL
> > +
> > +static struct spinlock uart_lock;
> > +static volatile u8 *uart0_base = (u8 *)QEMU_MACH_VIRT_PL011_BASE;
> > +
> > +static void uart0_init(void)
> > +{
> > +	const char *compatible = "arm,pl011";
> > +	struct dt_pbus_reg base;
> > +	int ret;
> > +
> > +	ret = dt_pbus_get_base_compatible(compatible, &base);
> > +	assert(ret == 0 || ret == -FDT_ERR_NOTFOUND);
> > +
> > +	if (ret) {
> > +		printf("%s: %s not found in the device tree, aborting...\n",
> > +			__func__, compatible);
> > +		abort();
> > +	}
> > +
> > +	uart0_base = ioremap(base.addr, base.size);
> > +}
> > +
> > +void io_init(void)
> > +{
> > +	uart0_init();
> > +	virtio_testdev_init();
> > +}
> > +
> > +void puts(const char *s)
> > +{
> > +	spin_lock(&uart_lock);
> > +	while (*s)
> > +		writeb(*s++, uart0_base);
> > +	spin_unlock(&uart_lock);
> > +}
> > +
> > +void exit(int code)
> > +{
> > +	virtio_testdev_exit(code);
> > +	halt(code);
> > +}
> > diff --git a/lib/arm/setup.c b/lib/arm/setup.c
> > new file mode 100644
> > index 0000000000000..dafjsdfl86a244aef56b8
> > --- /dev/null
> > +++ b/lib/arm/setup.c
> > @@ -0,0 +1,149 @@
> > +/*
> > + * Initialize machine setup information and I/O.
> > + *
> > + * After running setup() unit tests may query how many cpus they have
> > + * (nr_cpus), how much free memory it has, and at what physical
> 
> nit: you seem to be changing between singular and plural here, it's
> confusing.

Fixed for v6.

> 
> > + * address that free memory starts (memregions[1].{addr,size}),
> > + * printf() and exit() will both work, and (argc, argv) are ready
> > + * to be passed to main().
> > + *
> > + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > + */
> > +#include "libcflat.h"
> > +#include "libfdt/libfdt.h"
> > +#include "devicetree.h"
> > +#include "asm/spinlock.h"
> > +#include "asm/setup.h"
> > +
> > +extern unsigned long stacktop;
> > +extern void io_init(void);
> > +extern void setup_args(const char *args);
> > +
> > +u32 cpus[NR_CPUS] = { [0 ... NR_CPUS-1] = (~0UL) };
> > +int nr_cpus;
> > +
> > +static struct spinlock memregion_lock;
> > +struct memregion memregions[NR_MEMREGIONS];
> > +int nr_memregions;
> > +
> > +static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
> > +{
> > +	assert(nr_cpus < NR_CPUS);
> > +	cpus[nr_cpus++] = regval;
> > +}
> > +
> > +static void cpu_init(void)
> > +{
> > +	nr_cpus = 0;
> > +	assert(dt_for_each_cpu_node(cpu_set, NULL) == 0);
> > +}
> > +
> > +static void memregions_init(phys_addr_t freemem_start)
> > +{
> > +	/* we only expect one membank to be defined in the DT */
> > +	struct dt_pbus_reg regs[1];
> > +	phys_addr_t addr, size, mem_end;
> > +
> > +	nr_memregions = dt_get_memory_params(regs, 1);
> > +
> > +	assert(nr_memregions > 0);
> > +
> > +	addr = regs[0].addr;
> > +	size = regs[0].size;
> > +	mem_end = addr + size;
> > +
> > +	assert(!(addr & ~PHYS_MASK) && !((mem_end-1) & ~PHYS_MASK));
> > +
> > +	memregions[0].addr = PAGE_ALIGN(addr); /* PHYS_OFFSET */
> > +
> > +	freemem_start = PAGE_ALIGN(freemem_start);
> > +	assert(freemem_start >= PHYS_OFFSET && freemem_start < mem_end);
> > +
> > +	memregions[0].size = freemem_start - PHYS_OFFSET;
> > +	memregions[1].addr = freemem_start;
> > +	memregions[1].size = mem_end - freemem_start;
> > +	memregions[1].free = true;
> > +	nr_memregions = 2;
> > +
> > +#ifdef __arm__
> > +	/*
> > +	 * make sure 32-bit unit tests don't have any surprises when
> > +	 * running without virtual memory, by ensuring the initial
> > +	 * memory region uses 32-bit addresses. Other memory regions
> > +	 * may have > 32-bit addresses though, and the unit tests are
> > +	 * free to do as they wish with that.
> > +	 */
> > +	assert(!(memregions[0].addr >> 32));
> > +	assert(!((memregions[0].addr + memregions[0].size - 1) >> 32));
> > +#endif
> > +}
> > +
> > +struct memregion *memregion_new(phys_addr_t size)
> > +{
> > +	phys_addr_t freemem_start, mem_end;
> > +	struct memregion *mr;
> > +
> > +	spin_lock(&memregion_lock);
> > +
> > +	mr = &memregions[nr_memregions-1];
> > +
> > +	if (!mr->free || mr->size < size) {
> > +		printf("%s: requested=0x%llx, free=0x%llx.\n", size,
> > +				mr->free ? mr->size : 0ULL);
> > +		return NULL;
> > +	}
> > +
> > +	mem_end = mr->addr + mr->size;
> > +
> > +	mr->size = size;
> > +	mr->free = false;
> > +
> > +	freemem_start = PAGE_ALIGN(mr->addr + size);
> > +
> > +	if (freemem_start < mem_end && nr_memregions < NR_MEMREGIONS) {
> > +		mr->size = freemem_start - mr->addr;
> > +		memregions[nr_memregions].addr = freemem_start;
> > +		memregions[nr_memregions].size = mem_end - freemem_start;
> > +		memregions[nr_memregions].free = true;
> > +		++nr_memregions;
> > +	}
> > +
> > +	spin_unlock(&memregion_lock);
> > +
> > +	return mr;
> > +}
> > +
> > +void memregions_show(void)
> > +{
> > +	int i;
> > +	for (i = 0; i < nr_memregions; ++i)
> > +		printf("%016llx-%016llx [%s]\n",
> > +			memregions[i].addr,
> > +			memregions[i].addr + memregions[i].size - 1,
> > +			memregions[i].free ? "FREE" : "USED");
> > +}
> > +
> > +void setup(unsigned long arg __unused, unsigned long id __unused,
> > +	   const void *fdt)
> > +{
> > +	const char *bootargs;
> > +	u32 fdt_size;
> > +
> > +	/*
> > +	 * Move the fdt to just above the stack. The free memory
> > +	 * then starts just after the fdt.
> > +	 */
> > +	fdt_size = fdt_totalsize(fdt);
> > +	assert(fdt_move(fdt, &stacktop, fdt_size) == 0);
> > +	assert(dt_init(&stacktop) == 0);
> > +
> > +	memregions_init((unsigned long)&stacktop + fdt_size);
> > +
> > +	io_init();
> > +	cpu_init();
> > +
> > +	assert(dt_get_bootargs(&bootargs) == 0);
> > +	setup_args(bootargs);
> > +}
> > -- 
> > 1.9.3
> > 
> 
> looks good otherwise:
> 
> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 00/19] kvm-unit-tests/arm: initial drop
  2014-06-14 14:44 ` [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Christoffer Dall
@ 2014-06-16  7:46   ` Andrew Jones
  2014-06-16  7:56     ` Christoffer Dall
  0 siblings, 1 reply; 45+ messages in thread
From: Andrew Jones @ 2014-06-16  7:46 UTC (permalink / raw)
  To: Christoffer Dall; +Cc: kvmarm, kvm, pbonzini

On Sat, Jun 14, 2014 at 04:44:47PM +0200, Christoffer Dall wrote:
> On Wed, Jun 11, 2014 at 04:01:15PM +0200, Andrew Jones wrote:
> > This is a v5 of a series that introduces arm to kvm-unit-tests. First,
> > it does some tidying up of the repo. Then, it adds support for device
> > trees (libfdt), and for virtio-testdev[1]. Next, it adds the basic
> > infrastructure for booting a test case (guest), and adds a first
> > test case, a self-test to confirm setup was completed successfully.
> > Finally, it further prepares the framework for more complicated tests
> > by adding vector support, and extends the self-test to test that too.
> > 
> > This initial drop doesn't require kvmarm. qemu-system-arm is enough,
> > but it must have mach-virt, and the virtio-testdev patch[1].
> > 
> > These patches (v5) are also available from a git repo here
> > https://github.com/rhdrjones/kvm-unit-tests/commits/arm/v5-initial-drop
> > 
> > The v4 patches are available for reference here
> > https://github.com/rhdrjones/kvm-unit-tests/commits/arm/v4-initial-drop
> > 
> > Not too much has changed since v4. There are no new patches nor dropped
> > patches, and all patches that did get a change have a v5 note. To see
> > a branch interdiff (created with git-tbdiff[2]) take a look here[3].
> > 
> > Thanks in advance for reviews!
> > 
> This now looks pretty good overall.  Feels to me like if you address
> Paolo's comments then this could be merged, and we can start adding more
> complicated tests to it.
> 
> When you send out the next (last?) version, I can give it a spin on
> hardware with KVM as well.
> 
> -Christoffer

Thanks! It sounds like Paolo would like to see the qemu support merged
first. Although, IMO, which goes first could go either way (either
the qemu side waits on kvm-unit-tests, or kvm-unit-tests waits on qemu),
one must go first.

drew

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v5 00/19] kvm-unit-tests/arm: initial drop
  2014-06-16  7:46   ` Andrew Jones
@ 2014-06-16  7:56     ` Christoffer Dall
  0 siblings, 0 replies; 45+ messages in thread
From: Christoffer Dall @ 2014-06-16  7:56 UTC (permalink / raw)
  To: Andrew Jones; +Cc: kvmarm, kvm, pbonzini

On Mon, Jun 16, 2014 at 09:46:02AM +0200, Andrew Jones wrote:
> On Sat, Jun 14, 2014 at 04:44:47PM +0200, Christoffer Dall wrote:
> > On Wed, Jun 11, 2014 at 04:01:15PM +0200, Andrew Jones wrote:
> > > This is a v5 of a series that introduces arm to kvm-unit-tests. First,
> > > it does some tidying up of the repo. Then, it adds support for device
> > > trees (libfdt), and for virtio-testdev[1]. Next, it adds the basic
> > > infrastructure for booting a test case (guest), and adds a first
> > > test case, a self-test to confirm setup was completed successfully.
> > > Finally, it further prepares the framework for more complicated tests
> > > by adding vector support, and extends the self-test to test that too.
> > > 
> > > This initial drop doesn't require kvmarm. qemu-system-arm is enough,
> > > but it must have mach-virt, and the virtio-testdev patch[1].
> > > 
> > > These patches (v5) are also available from a git repo here
> > > https://github.com/rhdrjones/kvm-unit-tests/commits/arm/v5-initial-drop
> > > 
> > > The v4 patches are available for reference here
> > > https://github.com/rhdrjones/kvm-unit-tests/commits/arm/v4-initial-drop
> > > 
> > > Not too much has changed since v4. There are no new patches nor dropped
> > > patches, and all patches that did get a change have a v5 note. To see
> > > a branch interdiff (created with git-tbdiff[2]) take a look here[3].
> > > 
> > > Thanks in advance for reviews!
> > > 
> > This now looks pretty good overall.  Feels to me like if you address
> > Paolo's comments then this could be merged, and we can start adding more
> > complicated tests to it.
> > 
> > When you send out the next (last?) version, I can give it a spin on
> > hardware with KVM as well.
> > 
> > -Christoffer
> 
> Thanks! It sounds like Paolo would like to see the qemu support merged
> first. Although, IMO, which goes first could go either way (either
> the qemu side waits on kvm-unit-tests, or kvm-unit-tests waits on qemu),
> one must go first.
> 
Yeah, but probably makes sense to have the QEMU side go upstream first
as it is the passive agent, and the one that may require a little
discussion etc. to get in place.

-Christoffer

^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2014-06-16  7:57 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-11 14:01 [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Andrew Jones
2014-06-11 14:01 ` [PATCH v5 01/19] remove unused files Andrew Jones
2014-06-11 14:01 ` [PATCH v5 02/19] makefile and run_tests tweaks Andrew Jones
2014-06-11 14:01 ` [PATCH v5 03/19] clean root dir of all x86-ness Andrew Jones
2014-06-12 10:31   ` Paolo Bonzini
2014-06-12 10:40     ` Andrew Jones
2014-06-12 10:42       ` Paolo Bonzini
2014-06-12 10:54         ` Andrew Jones
2014-06-11 14:01 ` [PATCH v5 04/19] add distclean target and gitignore more Andrew Jones
2014-06-12 10:36   ` Paolo Bonzini
2014-06-14 13:17     ` Christoffer Dall
2014-06-11 14:01 ` [PATCH v5 05/19] add 'make cscope' support Andrew Jones
2014-06-11 14:01 ` [PATCH v5 07/19] libfdt: get libfdt to build Andrew Jones
2014-06-11 14:01 ` [PATCH v5 08/19] add support for Linux device trees Andrew Jones
2014-06-12  9:19   ` Christoffer Dall
2014-06-11 14:01 ` [PATCH v5 09/19] libcflat: add abort() and assert() Andrew Jones
2014-06-12 10:48   ` Paolo Bonzini
2014-06-12 11:07     ` Andrew Jones
2014-06-12 11:09       ` Paolo Bonzini
2014-06-11 14:01 ` [PATCH v5 10/19] Introduce asm-generic/*.h files Andrew Jones
2014-06-11 14:01 ` [PATCH v5 11/19] add minimal virtio support for devtree virtio-mmio Andrew Jones
2014-06-14 13:30   ` Christoffer Dall
2014-06-11 14:01 ` [PATCH v5 12/19] Introduce virtio-testdev Andrew Jones
2014-06-12 10:16   ` Paolo Bonzini
2014-06-12 11:30     ` Andrew Jones
2014-06-12 11:56       ` Paolo Bonzini
2014-06-11 14:01 ` [PATCH v5 13/19] libcflat: clean up libcflat.h and add string.h Andrew Jones
2014-06-12 10:52   ` Paolo Bonzini
2014-06-12 11:12     ` Andrew Jones
2014-06-11 14:01 ` [PATCH v5 14/19] printf: support field padding Andrew Jones
2014-06-11 14:01 ` [PATCH v5 15/19] arm: initial drop Andrew Jones
2014-06-14 14:16   ` Christoffer Dall
2014-06-16  7:36     ` Andrew Jones
2014-06-11 14:01 ` [PATCH v5 16/19] arm: Add spinlock implementation Andrew Jones
2014-06-11 14:01 ` [PATCH v5 17/19] arm: Add IO accessors to avoid register-writeback Andrew Jones
2014-06-11 14:01 ` [PATCH v5 18/19] arm: add useful headers from the Linux kernel Andrew Jones
2014-06-11 14:01 ` [PATCH v5 19/19] arm: vectors support Andrew Jones
2014-06-12 10:54 ` [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Paolo Bonzini
     [not found] ` <1402495294-30737-7-git-send-email-drjones@redhat.com>
2014-06-12 10:44   ` [PATCH v5 06/19] libfdt: Import libfdt source Paolo Bonzini
2014-06-12 10:59     ` Andrew Jones
2014-06-12 14:39       ` Paolo Bonzini
2014-06-12 11:09   ` Paolo Bonzini
2014-06-14 14:44 ` [PATCH v5 00/19] kvm-unit-tests/arm: initial drop Christoffer Dall
2014-06-16  7:46   ` Andrew Jones
2014-06-16  7:56     ` Christoffer Dall

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.