From: Christoffer Dall <christoffer.dall@linaro.org>
To: Andrew Jones <drjones@redhat.com>
Cc: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, gleb@redhat.com
Subject: Re: [PATCH 8/9] arm: initial drop
Date: Wed, 16 Oct 2013 18:06:35 -0700 [thread overview]
Message-ID: <20131017010635.GK24837@cbox> (raw)
In-Reply-To: <1381767815-12510-9-git-send-email-drjones@redhat.com>
On Mon, Oct 14, 2013 at 06:23:34PM +0200, Andrew Jones wrote:
> This is the initial arm test infrastructure and a first test that
> simply checks some bootinfo. kvm isn't needed to run this test. This
> patch also adds a common build environment variable, $QEMU_BIN, which
> allows makefiles to call on qemu when needed.
>
> Try it out with
> yum install gcc-arm-linux-gnu dtc
> export QEMU=[qemu with mach-virt and virtio-testdev]
> ./configure --cross-prefix=arm-linux-gnu- --arch=arm
> make
> ./run_tests.sh
>
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
> arm/boot.c | 27 ++++++++++++++++++++
> arm/cstart.S | 47 ++++++++++++++++++++++++++++++++++
> arm/flat.lds | 18 +++++++++++++
> arm/run | 19 ++++++++++++++
> arm/unittests.cfg | 11 ++++++++
> config/config-arm.mak | 62 +++++++++++++++++++++++++++++++++++++++++++++
> configure | 10 ++++++--
> lib/arm/bootinfo.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++
> lib/arm/bootinfo.h | 19 ++++++++++++++
> lib/arm/bswap.h | 30 ++++++++++++++++++++++
> lib/arm/io.c | 26 +++++++++++++++++++
> lib/bswap.h | 4 +++
> lib/libcflat.h | 1 +
> 13 files changed, 342 insertions(+), 2 deletions(-)
> create mode 100644 arm/boot.c
> create mode 100644 arm/cstart.S
> create mode 100644 arm/flat.lds
> create mode 100755 arm/run
> create mode 100644 arm/unittests.cfg
> create mode 100644 config/config-arm.mak
> create mode 100644 lib/arm/bootinfo.c
> create mode 100644 lib/arm/bootinfo.h
> create mode 100644 lib/arm/bswap.h
> create mode 100644 lib/arm/io.c
>
> diff --git a/arm/boot.c b/arm/boot.c
> new file mode 100644
> index 0000000000000..375e8708a7c54
this file's indentation is also funny, you should really check your
editor configuration :)
> --- /dev/null
> +++ b/arm/boot.c
> @@ -0,0 +1,27 @@
> +#include "libcflat.h"
> +#include "arm/bootinfo.h"
> +
> +static bool info_check(u32 var, char *expected)
> +{
> + char var_str[9];
> + snprintf(var_str, 9, "%x", var);
> + while (*expected == '0' || *expected == 'x')
> + ++expected;
> + return !strcmp(var_str, expected);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + int ret = 0;
> +
> + if (argc < 3) {
> + printf("Not enough arguments. Can't test\n");
> + return 1;
> + }
> +
> + if (!strcmp(argv[0], "info"))
> + ret = !info_check(mem32.size, argv[1])
> + || !info_check(core.pagesize, argv[2]);
> +
> + return ret;
> +}
I'm actually a little confused, when does this main get invoked and by
whom and what are we testing for here?
> diff --git a/arm/cstart.S b/arm/cstart.S
> new file mode 100644
> index 0000000000000..a65809824d4f1
> --- /dev/null
> +++ b/arm/cstart.S
> @@ -0,0 +1,47 @@
> +
> +#define CR_B (1 << 7)
> +
> +.arm
> +
> +.section .init
> +
> +.globl start
> +start:
> + /* bootloader params are in r0-r2 */
> + ldr sp, =stacktop
> + push { r0-r3 } @push r3 too for 8-byte alignment
> +
> + mrc p15, 0, r8, c1, c0, 0 @r8 = sctrl
> + bl get_endianness
> + bl io_init
> +
> + pop { r0-r3 }
> + bl read_bootinfo
> + bl __setup_args
> + ldr r0, =__argc
> + ldr r0, [r0]
> + ldr r1, =__argv
> + bl main
> + bl exit
> + b halt
> +
> +get_endianness:
> + and r0, r8, #CR_B
> + cmp r0, #0
> + beq 1f
> + ldr r1, =cpu_is_be
> + mov r0, #1
> + str r0, [r1]
> +1: mov pc, lr
> +
> +.text
> +
> +.globl halt
> +halt:
> +1: wfi
> + b 1b
> +
> +.data
> +
> +.globl cpu_is_be
> +cpu_is_be: .word 0
> diff --git a/arm/flat.lds b/arm/flat.lds
> new file mode 100644
> index 0000000000000..3e5d72e24989b
> --- /dev/null
> +++ b/arm/flat.lds
> @@ -0,0 +1,18 @@
> +
> +SECTIONS
> +{
> + .text : { *(.init) *(.text) *(.text.*) }
> + . = ALIGN(4K);
> + .data : { *(.data) }
> + . = ALIGN(16);
> + .rodata : { *(.rodata) }
> + . = ALIGN(16);
> + .bss : { *(.bss) }
> + . = ALIGN(4K);
> + edata = .;
> + . += 8K;
> + . = ALIGN(4K);
> + stacktop = .;
> +}
> +
> +ENTRY(start)
> diff --git a/arm/run b/arm/run
> new file mode 100755
> index 0000000000000..64446e8907564
> --- /dev/null
> +++ b/arm/run
> @@ -0,0 +1,19 @@
> +#!/bin/bash
> +
> +qemu="${QEMU:-qemu-system-arm}"
> +testdev='virtio-testdev'
> +
> +if ! $qemu -device '?' 2>&1 | grep $testdev > /dev/null; then
> + echo \"$qemu\" has no support for the virtio test device. Exiting.
> + exit 2
> +fi
> +
> +command="$qemu -device $testdev -display none -serial stdio "
> +command+="-M virt -cpu cortex-a15 "
> +#command+="-enable-kvm "
> +command+="-kernel"
> +echo $command "$@"
> +$command "$@"
> +ret=$?
> +echo Return value from qemu: $ret
> +exit $ret
> diff --git a/arm/unittests.cfg b/arm/unittests.cfg
> new file mode 100644
> index 0000000000000..fb78cd906839a
> --- /dev/null
> +++ b/arm/unittests.cfg
> @@ -0,0 +1,11 @@
> +# Define your new unittest following the convention:
> +# [unittest_name]
> +# file = foo.flat # Name of the flat file to be used
> +# smp = 2 # Number of processors the VM will use during this test
> +# extra_params = -append <params...> # Additional parameters used
> +# arch = arm/arm64 # Only if the test case works only on one of them
> +# groups = group1 group2 # Used to identify test cases with run_tests -g ...
> +
> +[boot_info]
> +file = boot.flat
> +extra_params = -m 256 -append 'info 0x10000000 0x1000'
> diff --git a/config/config-arm.mak b/config/config-arm.mak
> new file mode 100644
> index 0000000000000..066b1f725c5b3
> --- /dev/null
> +++ b/config/config-arm.mak
> @@ -0,0 +1,62 @@
> +mach = mach-virt
> +iodevs = pl011 virtio_mmio
> +phys_base = 0x8000000
> +
> +cstart.o = $(TEST_DIR)/cstart.o
> +bits = 32
> +ldarch = elf32-littlearm
> +kernel_offset = 0x10000
> +CFLAGS += -D__arm__
> +
> +all: test_cases
> +
> +cflatobjs += \
> + lib/$(TEST_DIR)/iomaps.gen.o \
> + lib/iomaps.o \
> + lib/virtio-testdev.o \
> + lib/arm/io.o \
> + lib/arm/bootinfo.o
> +
> +$(libcflat): LDFLAGS += -nostdlib
> +$(libcflat): CFLAGS += -ffreestanding -I lib
> +
> +CFLAGS += -Wextra
> +CFLAGS += -marm
> +#CFLAGS += -mcpu=$(PROCESSOR)
> +CFLAGS += -mcpu=cortex-a15
> +CFLAGS += -O2
> +
> +libgcc := $(shell $(CC) -m$(ARCH) --print-libgcc-file-name)
> +start_addr := $(shell printf "%x\n" $$(( $(phys_base) + $(kernel_offset) )))
> +
> +FLATLIBS = lib/libcflat.a $(libgcc)
> +%.elf: %.o $(FLATLIBS) arm/flat.lds
> + $(CC) $(CFLAGS) -nostdlib -o $@ \
> + -Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \
> + $(filter %.o, $^) $(FLATLIBS)
> +
> +%.flat: %.elf
> + $(OBJCOPY) -O binary $^ $@
> +
> +tests-common = $(TEST_DIR)/boot.flat
> +
> +tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg
> +
> +test_cases: $(tests-common) $(tests)
> +
> +$(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I lib
> +
> +$(TEST_DIR)/boot.elf: $(cstart.o) $(TEST_DIR)/boot.o
> +
> +lib/$(TEST_DIR)/iomaps.gen.c: lib/$(TEST_DIR)/$(mach).dts
> + scripts/gen-devtree-iomaps.pl $^ $(iodevs) > $@
> +
> +lib/$(TEST_DIR)/mach-virt.dts: dtb = $(subst .dts,.dtb,$@)
> +lib/$(TEST_DIR)/mach-virt.dts:
> + $(QEMU_BIN) -kernel /dev/null -M virt -machine dumpdtb=$(dtb)
> + fdtdump $(dtb) > $@
> +
> +arch_clean:
> + $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
> + $(TEST_DIR)/.*.d lib/arm/.*.d \
> + lib/$(TEST_DIR)/iomaps.gen.c lib/$(TEST_DIR)/mach-virt.*
> diff --git a/configure b/configure
> index 6cfc64943f6e6..296c70182ea1d 100755
> --- a/configure
> +++ b/configure
> @@ -6,8 +6,7 @@ cc=gcc
> ld=ld
> objcopy=objcopy
> ar=ar
> -arch=`uname -m | sed -e s/i.86/i386/`
> -processor="$arch"
> +arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'`
> cross_prefix=
>
> usage() {
> @@ -17,6 +16,7 @@ usage() {
> Options include:
> --test-dir=DIR the main directory for tests ($arch)
> --arch=ARCH architecture to compile for ($arch)
> + --processor=PROCESSOR processor to compile for ($arch)
> --cross-prefix=PREFIX cross compiler prefix
> --cc=CC c compiler to use ($cc)
> --ld=LD ld linker to use ($ld)
> @@ -66,6 +66,9 @@ while [[ "$1" = -* ]]; do
> ;;
> esac
> done
> +[ -z "$processor" ] && processor="$arch"
> +qemu="${QEMU:-qemu-system-$arch}"
> +
> if [ -z "$testdir" -a \( "$arch" = "i386" -o "$arch" = "x86_64" \) ]; then
> testdir=x86
> elif [ -z "$testdir" ]; then
> @@ -80,6 +83,7 @@ if [ -f $testdir/run ]; then
> fi
>
> # check for dependent 32 bit libraries
> +if [ "$arch" = "i386" -o "$arch" = "x86_64" ]; then
> cat << EOF > lib_test.c
> #include <stdc++.h>
> #include <boost_thread-mt.h>
> @@ -94,6 +98,7 @@ if [ $exit -eq 0 ]; then
> api=true
> fi
> rm -f lib_test.c
> +fi
>
> cat <<EOF > config.mak
> PREFIX=$prefix
> @@ -106,4 +111,5 @@ OBJCOPY=$cross_prefix$objcopy
> AR=$cross_prefix$ar
> API=$api
> TEST_DIR=$testdir
> +QEMU_BIN=$qemu
> EOF
> diff --git a/lib/arm/bootinfo.c b/lib/arm/bootinfo.c
> new file mode 100644
> index 0000000000000..c362064f661d9
> --- /dev/null
> +++ b/lib/arm/bootinfo.c
> @@ -0,0 +1,70 @@
> +#include "libcflat.h"
> +#include "arm/bootinfo.h"
> +#include "arm/bswap.h"
> +
> +#define FDT_SIG 0xd00dfeed
> +
> +#define KERNEL_OFFSET 0x00010000
> +#define ATAG_OFFSET 0x00000100
> +
> +#define ATAG_CORE 0x54410001
> +#define ATAG_MEM 0x54410002
> +#define ATAG_CMDLINE 0x54410009
> +
> +extern void start(void);
> +extern char *__args;
> +
> +u32 mach_type_id;
> +struct tag_core core;
> +struct tag_mem32 mem32;
> +
> +static void read_atags(u32 id, u32 *info)
> +{
> + u32 *p = info;
> +
> + if (!p) {
> + printf("Can't find bootinfo. mach-type = %x\n", id);
> + exit(ENOEXEC);
> + }
> +
> + /*
> + * p[0] count of words for the tag
> + * p[1] tag id
> + * p[2..] tag data
> + */
> + for (; p[0] != 0; p += p[0])
> + switch (p[1]) {
> + case ATAG_CORE:
> + core.flags = p[2];
> + core.pagesize = p[3];
> + core.rootdev = p[4];
> + break;
> + case ATAG_MEM:
> + mem32.size = p[2];
> + mem32.start = p[3];
> + break;
> + case ATAG_CMDLINE:
> + __args = (char *)&p[2];
> + break;
> + }
> +}
> +
> +#define __unused __attribute__((__unused__))
> +
> +void read_bootinfo(u32 arg __unused, u32 id, u32 *info)
> +{
> + u32 *atags = NULL;
> +
> + mach_type_id = id;
> +
> + if (info[0] == be32_to_cpu(FDT_SIG)) {
> + /*
> + * fdt reading is not [yet?] implemented. So calculate
> + * the ATAGS addr to read that instead.
> + */
> + atags = (u32 *)((u32)start - KERNEL_OFFSET + ATAG_OFFSET);
> + } else if (info[1] == ATAG_CORE)
> + atags = info;
> +
> + read_atags(id, atags);
> +}
> diff --git a/lib/arm/bootinfo.h b/lib/arm/bootinfo.h
> new file mode 100644
> index 0000000000000..9cf547e4cebeb
> --- /dev/null
> +++ b/lib/arm/bootinfo.h
> @@ -0,0 +1,19 @@
> +#ifndef _BOOTINFO_H_
> +#define _BOOTINFO_H_
> +#include "libcflat.h"
> +
> +struct tag_core {
> + u32 flags; /* bit 0 = read-only */
> + u32 pagesize;
> + u32 rootdev;
> +};
> +
> +struct tag_mem32 {
> + u32 size;
> + u32 start; /* physical start address */
> +};
> +
> +extern u32 mach_type_id;
> +extern struct tag_core core;
> +extern struct tag_mem32 mem32;
> +#endif
> diff --git a/lib/arm/bswap.h b/lib/arm/bswap.h
> new file mode 100644
> index 0000000000000..9bd16e789fcc5
> --- /dev/null
> +++ b/lib/arm/bswap.h
> @@ -0,0 +1,30 @@
> +#ifndef _ARM_BSWAP_H_
> +#define _ARM_BSWAP_H_
> +#include "libcflat.h"
> +
> +extern bool cpu_is_be;
> +
> +static inline u32 bswap32(u32 val)
> +{
> + u32 ret;
> + asm volatile("rev %0, %1" : "=r" (ret) : "r" (val));
> + return ret;
> +}
> +
> +static inline u16 bswap16(u16 val)
> +{
> + u16 ret;
> + asm volatile("rev16 %0, %1" : "=r" (ret) : "r" (val));
> + return ret;
> +}
> +
> +#define be32_to_cpu(x) (cpu_is_be ? x : bswap32(x))
> +#define cpu_to_be32(x) (cpu_is_be ? x : bswap32(x))
> +#define be16_to_cpu(x) (cpu_is_be ? x : bswap16(x))
> +#define cpu_to_be16(x) (cpu_is_be ? x : bswap16(x))
> +
> +#define le32_to_cpu(x) (cpu_is_be ? bswap32(x) : x)
> +#define cpu_to_le32(x) (cpu_is_be ? bswap32(x) : x)
> +#define le16_to_cpu(x) (cpu_is_be ? bswap16(x) : x)
> +#define cpu_to_le16(x) (cpu_is_be ? bswap16(x) : x)
> +#endif
> diff --git a/lib/arm/io.c b/lib/arm/io.c
> new file mode 100644
> index 0000000000000..951af60551a4c
> --- /dev/null
> +++ b/lib/arm/io.c
> @@ -0,0 +1,26 @@
> +#include "libcflat.h"
> +#include "iomaps.h"
> +#include "virtio-testdev.h"
> +
> +static volatile u8 *uart0_base;
> +
> +void puts(const char *s)
> +{
> + while (*s)
> + *uart0_base = *s++;
> +}
> +
> +void exit(int code)
> +{
> + virtio_testdev_exit(code);
> + halt(code);
> +}
> +
> +void io_init(void)
> +{
> + struct iomap *m = iomaps_find("pl011");
> + if (!m)
> + halt(ENXIO);
> + uart0_base = (u8 *)compat_ptr(m->addrs[0]);
> + virtio_testdev_init();
> +}
> diff --git a/lib/bswap.h b/lib/bswap.h
> index e63c4d37a8b9a..a428ed6c646dd 100644
> --- a/lib/bswap.h
> +++ b/lib/bswap.h
> @@ -1,7 +1,11 @@
> #ifndef _BSWAP_H_
> #define _BSWAP_H_
> +#ifdef __arm__
> +#include "arm/bswap.h"
> +#else
> #define le32_to_cpu(x) (x)
> #define cpu_to_le32(x) (x)
> #define le16_to_cpu(x) (x)
> #define cpu_to_le16(x) (x)
> #endif
> +#endif
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index 41791194657d0..dce9a0f516e7e 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -55,6 +55,7 @@ extern char *strcat(char *dest, const char *src);
> extern int strcmp(const char *a, const char *b);
>
> extern int printf(const char *fmt, ...);
> +extern int snprintf(char *buf, int size, const char *fmt, ...);
> extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
>
> extern void puts(const char *s);
> --
> 1.8.1.4
>
next prev parent reply other threads:[~2013-10-17 1:05 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-14 16:23 [PATCH 0/9] kvm-unit-tests/arm: initial drop Andrew Jones
2013-10-14 16:23 ` [PATCH 1/9] remove unused files Andrew Jones
2013-10-16 12:52 ` Gleb Natapov
2013-10-16 13:13 ` Alexander Graf
2013-10-16 13:13 ` Alexander Graf
2013-10-16 13:18 ` Andrew Jones
2013-10-14 16:23 ` [PATCH 2/9] makefile and run_tests tweaks Andrew Jones
2013-10-14 16:23 ` [PATCH 3/9] clean root dir of all x86-ness Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-17 9:35 ` Andrew Jones
2013-10-17 19:01 ` Christoffer Dall
2013-10-20 16:37 ` Andrew Jones
2013-10-14 16:23 ` [PATCH 4/9] Introduce a simple iomap structure Andrew Jones
2013-10-14 16:23 ` [PATCH 5/9] Add halt() and some error codes Andrew Jones
2013-10-14 16:23 ` [PATCH 6/9] Introduce virtio-testdev Andrew Jones
2013-10-15 8:39 ` Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-17 9:51 ` Andrew Jones
2013-10-17 19:01 ` Christoffer Dall
2013-10-17 1:06 ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 7/9] arm: replace arbitrary divisions Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-17 10:03 ` Andrew Jones
2013-10-17 18:59 ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 8/9] arm: initial drop Andrew Jones
2013-10-17 1:06 ` Christoffer Dall [this message]
2013-10-17 10:16 ` Andrew Jones
2013-10-17 13:28 ` Andrew Jones
2013-10-17 18:39 ` Christoffer Dall
2013-10-14 16:23 ` [PATCH 9/9] arm: add vectors support Andrew Jones
2013-10-17 1:06 ` Christoffer Dall
2013-10-17 10:38 ` Andrew Jones
2013-10-17 18:58 ` Christoffer Dall
2013-10-20 16:35 ` Andrew Jones
2013-10-21 9:59 ` Christoffer Dall
2013-11-20 23:06 ` [PATCH 0/9] kvm-unit-tests/arm: initial drop María Soler Heredia
2013-11-26 17:23 ` Andrew Jones
2013-12-29 9:24 ` Christoffer Dall
2014-01-02 18:56 ` Andrew Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131017010635.GK24837@cbox \
--to=christoffer.dall@linaro.org \
--cc=drjones@redhat.com \
--cc=gleb@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.