Re: [kvm-unit-tests PATCH 00/14] ppc64: initial drop
On Tue, Nov 03, 2015 at 10:40:18AM +0100, Paolo Bonzini wrote: > > > On 03/11/2015 08:08, Thomas Huth wrote: > > On 03/08/15 16:41, Andrew Jones wrote: > >> > This series is the first series of a series of series that will > >> > bring support to kvm-unit-tests for ppc64, and eventually ppc64le. > > Hi Andrew, > > > > may I ask about the current state of ppc64 support in the > > kvm-unit-tests? Is there a newer version available than the one you > > posted three months ago? > Hi Thomas, I haven't gotten around to preparing the v2 yet :-( I do have it on my TODO list, and I'm looking forward to working on it. Now that I know you're looking for it, I'll try to bump it up in priority. Thanks for the interest! > I've been a slob with all the kvm-unit-tests patches. Andrew, can you > send a single submission of all the patches, so that I can review them > and apply them? Hi Paolo, I've got several patches on my staging branch that I believe are ready. I plan to send those as a big "pull" series for your review soon. Thanks, drew > > Paolo > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [kvm-unit-tests PATCH 10/14] powerpc/ppc64: relocate linker VMAs
On Tue, Aug 04, 2015 at 01:53:24PM +1000, David Gibson wrote: On Mon, Aug 03, 2015 at 04:41:27PM +0200, Andrew Jones wrote: QEMU loads the unit test, but due to the way it translates the unit test's linker VMA to the LMA, we can't just link such that VMA == LMA. Thus, we link with VMA == 0x0, and then deal with relocation. Signed-off-by: Andrew Jones drjo...@redhat.com --- configure | 2 ++ powerpc/Makefile.common | 13 +--- powerpc/Makefile.ppc64 | 1 + powerpc/cstart64.S | 40 +++ powerpc/flat.lds| 13 +++- powerpc/reloc64.c | 55 + 6 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 powerpc/reloc64.c diff --git a/configure b/configure index b367224093369..b2ad199da7873 100755 --- a/configure +++ b/configure @@ -5,6 +5,7 @@ kerneldir=/lib/modules/$(uname -r)/build cc=gcc ld=ld objcopy=objcopy +objdump=objdump ar=ar arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'` host=$arch @@ -132,6 +133,7 @@ PROCESSOR=$processor CC=$cross_prefix$cc LD=$cross_prefix$ld OBJCOPY=$cross_prefix$objcopy +OBJDUMP=$cross_prefix$objdump AR=$cross_prefix$ar API=$api TEST_DIR=$testdir diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common index d6356540918a5..b130342dee60e 100644 --- a/powerpc/Makefile.common +++ b/powerpc/Makefile.common @@ -27,6 +27,7 @@ CFLAGS += -Wextra CFLAGS += -O2 CFLAGS += -I lib -I lib/libfdt CFLAGS += -Wa,-mregnames +CFLAGS += -fpie asm-offsets = lib/$(ARCH)/asm-offsets.h include scripts/asm-offsets.mak @@ -43,11 +44,17 @@ libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name) start_addr := $(shell printf %x\n $$(( $(phys_base) + $(kernel_offset) ))) FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) -%.elf: LDFLAGS = $(CFLAGS) -nostdlib +%.elf: LDFLAGS = $(CFLAGS) -nostdlib -pie %.elf: %.o $(FLATLIBS) powerpc/flat.lds $(CC) $(LDFLAGS) -o $@ \ -Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \ $(filter %.o, $^) $(FLATLIBS) + @echo -n Checking $@ for unsupported reloc types... + @if $(OBJDUMP) -R $@ | grep R_ | grep -v R_PPC64_RELATIVE; then \ + false; \ + else\ + echo looks good.;\ + fi powerpc_clean: libfdt_clean asm_offsets_clean $(RM) $(TEST_DIR)/*.{o,elf} \ @@ -59,5 +66,5 @@ generated_files = $(asm-offsets) test_cases: $(generated_files) $(tests-common) $(tests) -$(TEST_DIR)/$(TEST).elf: $(cstart.o) $(TEST_DIR)/$(TEST).o -$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o +$(TEST_DIR)/$(TEST).elf: $(cstart.o) $(reloc.o) $(TEST_DIR)/$(TEST).o +$(TEST_DIR)/selftest.elf: $(cstart.o) $(reloc.o) $(TEST_DIR)/selftest.o diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64 index 7c61933dfa8ba..7274e0d98b5a5 100644 --- a/powerpc/Makefile.ppc64 +++ b/powerpc/Makefile.ppc64 @@ -8,6 +8,7 @@ ldarch = elf64-powerpc #elf64-powerpcle (eventually) kernel_offset = 0x0 cstart.o = $(TEST_DIR)/cstart64.o +reloc.o = $(TEST_DIR)/reloc64.o cflatobjs += lib/ppc64/processor.o cflatobjs += lib/ppc64/spinlock.o diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S index 141d4563563d5..8edaaa6e251fc 100644 --- a/powerpc/cstart64.S +++ b/powerpc/cstart64.S @@ -26,18 +26,50 @@ */ .globl start start: - LOAD_REG_IMMEDIATE(r1, stackptr) - LOAD_REG_IMMEDIATE(r2, tocptr) + /* +* We were loaded at QEMU's kernel load address, but we're not +* allowed to link there due to how QEMU deals with linker VMAs, +* so we just linked at zero. This means the first thing to do is +* to find our stack and toc, and then do a relocate. +*/ + bl . + 4 bl 0f might make the connection to the following instructions clearer. Thanks, I'll change it. drew +0: mflrr31 + subir31, r31, 0b - start/* QEMU's kernel load address */ + ld r1, (p_stack - start)(r31) + ld r2, (p_toc - start)(r31) + add r1, r1, r31 + add r2, r2, r31 + + /* save DTB pointer */ + std r3, 56(r1) + + /* +* Call relocate. relocate is C code, but careful to not use +* any global references, as they may use absolute addresses, +* which are, obviously, not yet relocated. +*/ + mr r3, r31 + ld r4, (p_dyn - start)(r31) + add r4, r4, r31 + bl .relocate + + /* complete setup */ + ld r3, 56(r1) bl .setup /* run the test */ - LOAD_REG_IMMEDIATE(r5, __argc) - LOAD_REG_IMMEDIATE(r4, __argv) + LOAD_REG_ADDR(r5, __argc
Re: [kvm-unit-tests PATCH 11/14] powerpc/ppc64: add rtas_power_off
On Tue, Aug 04, 2015 at 02:09:52PM +1000, David Gibson wrote: On Mon, Aug 03, 2015 at 07:08:17PM +0200, Paolo Bonzini wrote: On 03/08/2015 16:41, Andrew Jones wrote: Add enough RTAS support to support power-off, and apply it to exit(). Signed-off-by: Andrew Jones drjo...@redhat.com Why not use virtio-mmio + testdev on ppc as well? Similar to how we're not using PSCI on ARM or ACPI on x86. Strange as it seems, MMIO is actually a PITA for a simple pseries guest like this. Basically, you have to enable the MMU - which requires a whole bunch of setup - in order to perform cache-inhibited loads and stores, which is what you need for IO. There are hypercalls to sidestep this (H_LOGICAL_CI_LOAD and H_LOGICAL_CI_STORE), but having a hypercall and KVM exit for every IO access may be hideously slow. In early development we did have a hypercall mediated virtio model, but it was abandoned once we got PCI working. So I think by yours and Alex's responses, if we want testdev support then we should target using pci to expose it. I'm ok with that, but prefer not to be distracted with it while getting ppc kickstarted. So, question for Paolo, are you OK with the exitcode snooper cheat? Thanks, drew -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au| minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [kvm-unit-tests PATCH 08/14] powerpc/ppc64: add HV putchar
On Tue, Aug 04, 2015 at 01:50:39PM +1000, David Gibson wrote: On Mon, Aug 03, 2015 at 04:41:25PM +0200, Andrew Jones wrote: Add the hvcall for putchar and use it in puts. That, along with a couple more lines in start to prepare for C code, and a branch to main(), gets us hello world. Run with qemu-system-ppc64 -M pseries\ -bios powerpc/boot_rom.bin \ -display none -serial stdio \ -kernel powerpc/selftest.elf (We're still not relocating yet, that comes in a later patch. Thus, testing hello-world at this point requires a hacked QEMU and linking the unit test at QEMU's kernel load address.) Signed-off-by: Andrew Jones drjo...@redhat.com --- lib/powerpc/io.c| 15 +-- powerpc/Makefile.common | 1 + powerpc/cstart64.S | 27 +++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c index cf3b6347e1e46..a7eaafeca9205 100644 --- a/lib/powerpc/io.c +++ b/lib/powerpc/io.c @@ -6,15 +6,26 @@ * This work is licensed under the terms of the GNU LGPL, version 2. */ #include libcflat.h +#include asm/spinlock.h + +extern void halt(int code); +extern void putchar(int c); + +static struct spinlock uart_lock; void io_init(void) { } -void puts(const char *s __unused) +void puts(const char *s) { + spin_lock(uart_lock); + while (*s) + putchar(*s++); + spin_unlock(uart_lock); } -void exit(int code __unused) +void exit(int code) { + halt(code); } diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common index 5cd3ea8085038..d6356540918a5 100644 --- a/powerpc/Makefile.common +++ b/powerpc/Makefile.common @@ -26,6 +26,7 @@ CFLAGS += -ffreestanding CFLAGS += -Wextra CFLAGS += -O2 CFLAGS += -I lib -I lib/libfdt +CFLAGS += -Wa,-mregnames asm-offsets = lib/$(ARCH)/asm-offsets.h include scripts/asm-offsets.mak diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S index d9b77f44f9e0e..d7c51cd352ee4 100644 --- a/powerpc/cstart64.S +++ b/powerpc/cstart64.S @@ -6,14 +6,41 @@ * This work is licensed under the terms of the GNU LGPL, version 2. */ +#define HVSC .long 0x4422 Unless your assembler is really old, you could probably use sc 1 inline, instead of this macro. Not that it really matters. It makes sense to switch to sc for a new project. I'll do that. +#define H_PUT_TERM_CHAR0x58 + +#define LOAD_REG_IMMEDIATE(reg,expr) \ + lis reg,(expr)@highest; \ + ori reg,reg,(expr)@higher; \ + rldicr reg,reg,32,31; \ + orisreg,reg,(expr)@h; \ + ori reg,reg,(expr)@l; + +#define LOAD_REG_ADDR(reg,name)\ + ld reg,name@got(r2) + .section .init .globl start start: + LOAD_REG_IMMEDIATE(r1, stackptr) + LOAD_REG_IMMEDIATE(r2, tocptr) + bl .main + bl .exit Is this built for ppc64 or ppc64le? IIUC under the new ABI version usually used on ppc64le, function descriptors are no longer used. And even under the old ABI, I think the assembler now has the smarts to avoid explicitly referencing the .-symbols. For now only building for ppc64, but eventually both. I'll remove the dots. Thanks, drew b halt .text +.align 3 .globl halt halt: 1: b 1b + +.globl putchar +putchar: + sldir6, r3, 56 + li r3, H_PUT_TERM_CHAR + li r4, 0 /* vty-reg 0 means to use the default vty */ + li r5, 1 /* sending just 1 byte */ + HVSC + blr -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au| minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [kvm-unit-tests PATCH 11/14] powerpc/ppc64: add rtas_power_off
On Tue, Aug 04, 2015 at 02:11:30PM +1000, David Gibson wrote: On Mon, Aug 03, 2015 at 04:41:28PM +0200, Andrew Jones wrote: Add enough RTAS support to support power-off, and apply it to exit(). Signed-off-by: Andrew Jones drjo...@redhat.com --- lib/powerpc/asm/rtas.h | 27 lib/powerpc/io.c| 3 ++ lib/powerpc/rtas.c | 84 + lib/ppc64/asm/rtas.h| 1 + powerpc/Makefile.common | 1 + powerpc/cstart64.S | 9 ++ 6 files changed, 125 insertions(+) create mode 100644 lib/powerpc/asm/rtas.h create mode 100644 lib/powerpc/rtas.c create mode 100644 lib/ppc64/asm/rtas.h diff --git a/lib/powerpc/asm/rtas.h b/lib/powerpc/asm/rtas.h new file mode 100644 index 0..53ce126c69a42 --- /dev/null +++ b/lib/powerpc/asm/rtas.h @@ -0,0 +1,27 @@ +#ifndef _ASMPOWERPC_RTAS_H_ +#define _ASMPOWERPC_RTAS_H_ +/* + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@redhat.com + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include libcflat.h + +#define RTAS_UNKNOWN_SERVICE (-1) + +struct rtas_args { + u32 token; + u32 nargs; + u32 nret; + u32 args[16]; + u32 *rets; +}; + +extern void rtas_init(void); +extern void enter_rtas(unsigned long args); +extern int rtas_token(const char *service); +extern int rtas_call(int token, int nargs, int nret, int *outputs, ...); + +extern void rtas_power_off(void); + +#endif /* _ASMPOWERPC_RTAS_H_ */ diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c index a7eaafeca9205..25cdd0ad961ee 100644 --- a/lib/powerpc/io.c +++ b/lib/powerpc/io.c @@ -7,6 +7,7 @@ */ #include libcflat.h #include asm/spinlock.h +#include asm/rtas.h extern void halt(int code); extern void putchar(int c); @@ -15,6 +16,7 @@ static struct spinlock uart_lock; void io_init(void) { + rtas_init(); } void puts(const char *s) @@ -27,5 +29,6 @@ void puts(const char *s) void exit(int code) { + rtas_power_off(); halt(code); } diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c new file mode 100644 index 0..39f7d4428ee77 --- /dev/null +++ b/lib/powerpc/rtas.c @@ -0,0 +1,84 @@ +/* + * powerpc RTAS + * + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@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/io.h +#include asm/rtas.h + +static struct spinlock lock; +struct rtas_args rtas_args; +static int rtas_node; + +void rtas_init(void) +{ + if (!dt_available()) { + printf(%s: No device tree!\n, __func__); + abort(); + } + + rtas_node = fdt_path_offset(dt_fdt(), /rtas); + if (rtas_node 0) { + printf(%s: /rtas node: %s\n, __func__, + fdt_strerror(rtas_node)); + abort(); + } +} + +int rtas_token(const char *service) +{ + const struct fdt_property *prop; + u32 *token; + + prop = fdt_get_property(dt_fdt(), rtas_node, service, NULL); Oh.. one other thing here. This is only safe if you never alter the device tree blob you're given (or at least, not after rtas_init()). That may well be the case, but I don't know your code well enough to be sure. Otherwise, the rtas node could get moved by other dt changes, meaning the offset stored in rtas_node is no longer valid. I hadn't planned on modifying the DT, but if you can conceive of a test they may want to, then we should do this right. I guess doing it right just means to hunt down rtas_node each time, that's easy. Thanks, drew + if (prop) { + token = (u32 *)prop-data; + return fdt32_to_cpu(*token); + } + return RTAS_UNKNOWN_SERVICE; +} + +int rtas_call(int token, int nargs, int nret, int *outputs, ...) +{ + va_list list; + int ret, i; + + spin_lock(lock); + + rtas_args.token = cpu_to_be32(token); + rtas_args.nargs = cpu_to_be32(nargs); + rtas_args.nret = cpu_to_be32(nret); + rtas_args.rets = rtas_args.args[nargs]; + + va_start(list, outputs); + for (i = 0; i nargs; ++i) + rtas_args.args[i] = cpu_to_be32(va_arg(list, u32)); + va_end(list); + + for (i = 0; i nret; ++i) + rtas_args.rets[i] = 0; + + enter_rtas(__pa(rtas_args)); + + if (nret 1 outputs != NULL) + for (i = 0; i nret - 1; ++i) + outputs[i] = be32_to_cpu(rtas_args.rets[i + 1]); + + ret = nret 0 ? be32_to_cpu(rtas_args.rets[0]) : 0; + + spin_unlock(lock); + return ret; +} + +void rtas_power_off(void) +{ + printf(RTAS power-off returned %d\n, + rtas_call
Re: [kvm-unit-tests PATCH 11/14] powerpc/ppc64: add rtas_power_off
On Tue, Aug 04, 2015 at 02:03:24PM +1000, David Gibson wrote: On Mon, Aug 03, 2015 at 04:41:28PM +0200, Andrew Jones wrote: Add enough RTAS support to support power-off, and apply it to exit(). Signed-off-by: Andrew Jones drjo...@redhat.com --- lib/powerpc/asm/rtas.h | 27 lib/powerpc/io.c| 3 ++ lib/powerpc/rtas.c | 84 + lib/ppc64/asm/rtas.h| 1 + powerpc/Makefile.common | 1 + powerpc/cstart64.S | 9 ++ 6 files changed, 125 insertions(+) create mode 100644 lib/powerpc/asm/rtas.h create mode 100644 lib/powerpc/rtas.c create mode 100644 lib/ppc64/asm/rtas.h diff --git a/lib/powerpc/asm/rtas.h b/lib/powerpc/asm/rtas.h new file mode 100644 index 0..53ce126c69a42 --- /dev/null +++ b/lib/powerpc/asm/rtas.h @@ -0,0 +1,27 @@ +#ifndef _ASMPOWERPC_RTAS_H_ +#define _ASMPOWERPC_RTAS_H_ +/* + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@redhat.com + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include libcflat.h + +#define RTAS_UNKNOWN_SERVICE (-1) + +struct rtas_args { + u32 token; + u32 nargs; + u32 nret; + u32 args[16]; + u32 *rets; +}; + +extern void rtas_init(void); +extern void enter_rtas(unsigned long args); +extern int rtas_token(const char *service); +extern int rtas_call(int token, int nargs, int nret, int *outputs, ...); + +extern void rtas_power_off(void); + +#endif /* _ASMPOWERPC_RTAS_H_ */ diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c index a7eaafeca9205..25cdd0ad961ee 100644 --- a/lib/powerpc/io.c +++ b/lib/powerpc/io.c @@ -7,6 +7,7 @@ */ #include libcflat.h #include asm/spinlock.h +#include asm/rtas.h extern void halt(int code); extern void putchar(int c); @@ -15,6 +16,7 @@ static struct spinlock uart_lock; void io_init(void) { + rtas_init(); } void puts(const char *s) @@ -27,5 +29,6 @@ void puts(const char *s) void exit(int code) { + rtas_power_off(); halt(code); } diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c new file mode 100644 index 0..39f7d4428ee77 --- /dev/null +++ b/lib/powerpc/rtas.c @@ -0,0 +1,84 @@ +/* + * powerpc RTAS + * + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@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/io.h +#include asm/rtas.h + +static struct spinlock lock; +struct rtas_args rtas_args; +static int rtas_node; + +void rtas_init(void) +{ + if (!dt_available()) { + printf(%s: No device tree!\n, __func__); + abort(); + } + + rtas_node = fdt_path_offset(dt_fdt(), /rtas); + if (rtas_node 0) { + printf(%s: /rtas node: %s\n, __func__, + fdt_strerror(rtas_node)); + abort(); + } +} + +int rtas_token(const char *service) +{ + const struct fdt_property *prop; + u32 *token; + + prop = fdt_get_property(dt_fdt(), rtas_node, service, NULL); + if (prop) { + token = (u32 *)prop-data; + return fdt32_to_cpu(*token); + } + return RTAS_UNKNOWN_SERVICE; +} + +int rtas_call(int token, int nargs, int nret, int *outputs, ...) +{ + va_list list; + int ret, i; + + spin_lock(lock); + + rtas_args.token = cpu_to_be32(token); + rtas_args.nargs = cpu_to_be32(nargs); + rtas_args.nret = cpu_to_be32(nret); + rtas_args.rets = rtas_args.args[nargs]; + + va_start(list, outputs); + for (i = 0; i nargs; ++i) + rtas_args.args[i] = cpu_to_be32(va_arg(list, u32)); + va_end(list); + + for (i = 0; i nret; ++i) + rtas_args.rets[i] = 0; + + enter_rtas(__pa(rtas_args)); + + if (nret 1 outputs != NULL) + for (i = 0; i nret - 1; ++i) + outputs[i] = be32_to_cpu(rtas_args.rets[i + 1]); + + ret = nret 0 ? be32_to_cpu(rtas_args.rets[0]) : 0; + + spin_unlock(lock); + return ret; +} + +void rtas_power_off(void) +{ + printf(RTAS power-off returned %d\n, + rtas_call(rtas_token(power-off), 2, 1, NULL, -1, -1)); + assert(0); +} diff --git a/lib/ppc64/asm/rtas.h b/lib/ppc64/asm/rtas.h new file mode 100644 index 0..fe77f635cd860 --- /dev/null +++ b/lib/ppc64/asm/rtas.h @@ -0,0 +1 @@ +#include ../../powerpc/asm/rtas.h diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common index b130342dee60e..f4eff7f8eccb4 100644 --- a/powerpc/Makefile.common +++ b/powerpc/Makefile.common @@ -39,6 +39,7 @@ cflatobjs += lib/powerpc/io.o cflatobjs += lib/powerpc/setup.o cflatobjs += lib/powerpc
Re: [kvm-unit-tests PATCH 11/14] powerpc/ppc64: add rtas_power_off
On Tue, Aug 04, 2015 at 03:15:25PM +0200, Paolo Bonzini wrote: On 04/08/2015 09:47, Andrew Jones wrote: In early development we did have a hypercall mediated virtio model, but it was abandoned once we got PCI working. So I think by yours and Alex's responses, if we want testdev support then we should target using pci to expose it. I'm ok with that, but prefer not to be distracted with it while getting ppc kickstarted. So, question for Paolo, are you OK with the exitcode snooper cheat? If we want that we should use it for x86 and ARM as well. However, attaching the char testdev to a spapr-vty (virtio-mmio made little sense) should be easy. OK, I'll look at doing the vty approach first. Thanks, drew -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[kvm-unit-tests PATCH 11/14] powerpc/ppc64: add rtas_power_off
Add enough RTAS support to support power-off, and apply it to exit(). Signed-off-by: Andrew Jones drjo...@redhat.com --- lib/powerpc/asm/rtas.h | 27 lib/powerpc/io.c| 3 ++ lib/powerpc/rtas.c | 84 + lib/ppc64/asm/rtas.h| 1 + powerpc/Makefile.common | 1 + powerpc/cstart64.S | 9 ++ 6 files changed, 125 insertions(+) create mode 100644 lib/powerpc/asm/rtas.h create mode 100644 lib/powerpc/rtas.c create mode 100644 lib/ppc64/asm/rtas.h diff --git a/lib/powerpc/asm/rtas.h b/lib/powerpc/asm/rtas.h new file mode 100644 index 0..53ce126c69a42 --- /dev/null +++ b/lib/powerpc/asm/rtas.h @@ -0,0 +1,27 @@ +#ifndef _ASMPOWERPC_RTAS_H_ +#define _ASMPOWERPC_RTAS_H_ +/* + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@redhat.com + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include libcflat.h + +#define RTAS_UNKNOWN_SERVICE (-1) + +struct rtas_args { + u32 token; + u32 nargs; + u32 nret; + u32 args[16]; + u32 *rets; +}; + +extern void rtas_init(void); +extern void enter_rtas(unsigned long args); +extern int rtas_token(const char *service); +extern int rtas_call(int token, int nargs, int nret, int *outputs, ...); + +extern void rtas_power_off(void); + +#endif /* _ASMPOWERPC_RTAS_H_ */ diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c index a7eaafeca9205..25cdd0ad961ee 100644 --- a/lib/powerpc/io.c +++ b/lib/powerpc/io.c @@ -7,6 +7,7 @@ */ #include libcflat.h #include asm/spinlock.h +#include asm/rtas.h extern void halt(int code); extern void putchar(int c); @@ -15,6 +16,7 @@ static struct spinlock uart_lock; void io_init(void) { + rtas_init(); } void puts(const char *s) @@ -27,5 +29,6 @@ void puts(const char *s) void exit(int code) { + rtas_power_off(); halt(code); } diff --git a/lib/powerpc/rtas.c b/lib/powerpc/rtas.c new file mode 100644 index 0..39f7d4428ee77 --- /dev/null +++ b/lib/powerpc/rtas.c @@ -0,0 +1,84 @@ +/* + * powerpc RTAS + * + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@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/io.h +#include asm/rtas.h + +static struct spinlock lock; +struct rtas_args rtas_args; +static int rtas_node; + +void rtas_init(void) +{ + if (!dt_available()) { + printf(%s: No device tree!\n, __func__); + abort(); + } + + rtas_node = fdt_path_offset(dt_fdt(), /rtas); + if (rtas_node 0) { + printf(%s: /rtas node: %s\n, __func__, + fdt_strerror(rtas_node)); + abort(); + } +} + +int rtas_token(const char *service) +{ + const struct fdt_property *prop; + u32 *token; + + prop = fdt_get_property(dt_fdt(), rtas_node, service, NULL); + if (prop) { + token = (u32 *)prop-data; + return fdt32_to_cpu(*token); + } + return RTAS_UNKNOWN_SERVICE; +} + +int rtas_call(int token, int nargs, int nret, int *outputs, ...) +{ + va_list list; + int ret, i; + + spin_lock(lock); + + rtas_args.token = cpu_to_be32(token); + rtas_args.nargs = cpu_to_be32(nargs); + rtas_args.nret = cpu_to_be32(nret); + rtas_args.rets = rtas_args.args[nargs]; + + va_start(list, outputs); + for (i = 0; i nargs; ++i) + rtas_args.args[i] = cpu_to_be32(va_arg(list, u32)); + va_end(list); + + for (i = 0; i nret; ++i) + rtas_args.rets[i] = 0; + + enter_rtas(__pa(rtas_args)); + + if (nret 1 outputs != NULL) + for (i = 0; i nret - 1; ++i) + outputs[i] = be32_to_cpu(rtas_args.rets[i + 1]); + + ret = nret 0 ? be32_to_cpu(rtas_args.rets[0]) : 0; + + spin_unlock(lock); + return ret; +} + +void rtas_power_off(void) +{ + printf(RTAS power-off returned %d\n, + rtas_call(rtas_token(power-off), 2, 1, NULL, -1, -1)); + assert(0); +} diff --git a/lib/ppc64/asm/rtas.h b/lib/ppc64/asm/rtas.h new file mode 100644 index 0..fe77f635cd860 --- /dev/null +++ b/lib/ppc64/asm/rtas.h @@ -0,0 +1 @@ +#include ../../powerpc/asm/rtas.h diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common index b130342dee60e..f4eff7f8eccb4 100644 --- a/powerpc/Makefile.common +++ b/powerpc/Makefile.common @@ -39,6 +39,7 @@ cflatobjs += lib/powerpc/io.o cflatobjs += lib/powerpc/setup.o cflatobjs += lib/powerpc/mmu.o cflatobjs += lib/powerpc/smp.o +cflatobjs += lib/powerpc/rtas.o libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name) start_addr := $(shell printf %x\n $$(( $(phys_base) + $(kernel_offset) ))) diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S index 8edaaa6e251fc..1c48083efa33c
[kvm-unit-tests PATCH 04/14] powerpc/ppc64: start skeleton framework
Use the arm/arm64 framework as a template to start a skeleton for powerpc/ppc64. Copy the arm makefiles and linker script verbatim. We'll modify them for powerpc with the next patch, making it clear what needs to be changed. Signed-off-by: Andrew Jones drjo...@redhat.com --- configure | 2 ++ lib/powerpc/.gitignore | 1 + lib/powerpc/io.c| 20 lib/powerpc/mmu.c | 0 lib/powerpc/setup.c | 0 lib/powerpc/smp.c | 0 lib/ppc64/.gitignore| 1 + lib/ppc64/asm-offsets.c | 12 +++ lib/ppc64/asm/asm-offsets.h | 1 + lib/ppc64/asm/io.h | 5 +++ lib/ppc64/asm/page.h| 1 + lib/ppc64/asm/spinlock.h| 11 +++ lib/ppc64/processor.c | 0 lib/ppc64/spinlock.c| 11 +++ powerpc/Makefile| 1 + powerpc/Makefile.common | 80 + powerpc/Makefile.ppc64 | 20 powerpc/cstart64.S | 19 +++ powerpc/flat.lds| 27 +++ powerpc/selftest.c | 7 20 files changed, 219 insertions(+) create mode 100644 lib/powerpc/.gitignore create mode 100644 lib/powerpc/io.c create mode 100644 lib/powerpc/mmu.c create mode 100644 lib/powerpc/setup.c create mode 100644 lib/powerpc/smp.c create mode 100644 lib/ppc64/.gitignore create mode 100644 lib/ppc64/asm-offsets.c create mode 100644 lib/ppc64/asm/asm-offsets.h create mode 100644 lib/ppc64/asm/io.h create mode 100644 lib/ppc64/asm/page.h create mode 100644 lib/ppc64/asm/spinlock.h create mode 100644 lib/ppc64/processor.c create mode 100644 lib/ppc64/spinlock.c create mode 100644 powerpc/Makefile create mode 100644 powerpc/Makefile.common create mode 100644 powerpc/Makefile.ppc64 create mode 100644 powerpc/cstart64.S create mode 100644 powerpc/flat.lds create mode 100644 powerpc/selftest.c diff --git a/configure b/configure index 078b70ce096a6..b367224093369 100755 --- a/configure +++ b/configure @@ -80,6 +80,8 @@ if [ $arch = i386 ] || [ $arch = x86_64 ]; then testdir=x86 elif [ $arch = arm ] || [ $arch = arm64 ]; then testdir=arm +elif [ $arch = ppc64 ]; then +testdir=powerpc else testdir=$arch fi diff --git a/lib/powerpc/.gitignore b/lib/powerpc/.gitignore new file mode 100644 index 0..84872bf197c67 --- /dev/null +++ b/lib/powerpc/.gitignore @@ -0,0 +1 @@ +asm-offsets.[hs] diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c new file mode 100644 index 0..cf3b6347e1e46 --- /dev/null +++ b/lib/powerpc/io.c @@ -0,0 +1,20 @@ +/* + * Each architecture must implement puts() and exit(). + * + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@redhat.com + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include libcflat.h + +void io_init(void) +{ +} + +void puts(const char *s __unused) +{ +} + +void exit(int code __unused) +{ +} diff --git a/lib/powerpc/mmu.c b/lib/powerpc/mmu.c new file mode 100644 index 0..e69de29bb2d1d diff --git a/lib/powerpc/setup.c b/lib/powerpc/setup.c new file mode 100644 index 0..e69de29bb2d1d diff --git a/lib/powerpc/smp.c b/lib/powerpc/smp.c new file mode 100644 index 0..e69de29bb2d1d diff --git a/lib/ppc64/.gitignore b/lib/ppc64/.gitignore new file mode 100644 index 0..84872bf197c67 --- /dev/null +++ b/lib/ppc64/.gitignore @@ -0,0 +1 @@ +asm-offsets.[hs] diff --git a/lib/ppc64/asm-offsets.c b/lib/ppc64/asm-offsets.c new file mode 100644 index 0..895296e19b060 --- /dev/null +++ b/lib/ppc64/asm-offsets.c @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@redhat.com + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include libcflat.h +#include kbuild.h + +int main(void) +{ + return 0; +} diff --git a/lib/ppc64/asm/asm-offsets.h b/lib/ppc64/asm/asm-offsets.h new file mode 100644 index 0..d370ee36a182b --- /dev/null +++ b/lib/ppc64/asm/asm-offsets.h @@ -0,0 +1 @@ +#include generated/asm-offsets.h diff --git a/lib/ppc64/asm/io.h b/lib/ppc64/asm/io.h new file mode 100644 index 0..c0801d4762ba6 --- /dev/null +++ b/lib/ppc64/asm/io.h @@ -0,0 +1,5 @@ +#ifndef _ASMPPC64_IO_H_ +#define _ASMPPC64_IO_H_ +#define __cpu_is_be() (1) +#include asm-generic/io.h +#endif diff --git a/lib/ppc64/asm/page.h b/lib/ppc64/asm/page.h new file mode 100644 index 0..1a8b62711f288 --- /dev/null +++ b/lib/ppc64/asm/page.h @@ -0,0 +1 @@ +#include asm-generic/page.h diff --git a/lib/ppc64/asm/spinlock.h b/lib/ppc64/asm/spinlock.h new file mode 100644 index 0..002cdb194b1db --- /dev/null +++ b/lib/ppc64/asm/spinlock.h @@ -0,0 +1,11 @@ +#ifndef _ASMPPC64_SPINLOCK_H_ +#define _ASMPPC64_SPINLOCK_H_ + +struct spinlock { + int v; +}; + +extern void spin_lock(struct spinlock *lock); +extern void spin_unlock(struct spinlock *lock); + +#endif /* _ASMPPC64_SPINLOCK_H_ */ diff
[kvm-unit-tests PATCH 05/14] powerpc/pp64: ppc-ify makefiles and linker script
Signed-off-by: Andrew Jones drjo...@redhat.com --- powerpc/Makefile.common | 44 +--- powerpc/Makefile.ppc64 | 16 powerpc/flat.lds| 14 ++ 3 files changed, 31 insertions(+), 43 deletions(-) diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common index f50d9f9d4e0f6..5cd3ea8085038 100644 --- a/powerpc/Makefile.common +++ b/powerpc/Makefile.common @@ -1,17 +1,15 @@ # -# arm common makefile +# powerpc common makefile # # Authors: Andrew Jones drjo...@redhat.com # ifeq ($(LOADADDR),) - # qemu mach-virt default load address - LOADADDR = 0x4000 + LOADADDR = 0x0 endif tests-common = \ - $(TEST_DIR)/selftest.flat \ - $(TEST_DIR)/spinlock-test.flat + $(TEST_DIR)/selftest.elf ifneq ($(TEST),) tests = $(TEST_DIR)/$(TEST).flat @@ -35,39 +33,24 @@ include scripts/asm-offsets.mak cflatobjs += lib/util.o cflatobjs += lib/alloc.o cflatobjs += lib/devicetree.o -cflatobjs += lib/virtio.o -cflatobjs += lib/virtio-mmio.o -cflatobjs += lib/chr-testdev.o -cflatobjs += lib/prng.o -cflatobjs += lib/arm/io.o -cflatobjs += lib/arm/setup.o -cflatobjs += lib/arm/mmu.o -cflatobjs += lib/arm/bitops.o -cflatobjs += lib/arm/psci.o -cflatobjs += lib/arm/smp.o - -libeabi = lib/arm/libeabi.a -eabiobjs = lib/arm/eabi_compat.o +cflatobjs += lib/powerpc/io.o +cflatobjs += lib/powerpc/setup.o +cflatobjs += lib/powerpc/mmu.o +cflatobjs += lib/powerpc/smp.o libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name) start_addr := $(shell printf %x\n $$(( $(phys_base) + $(kernel_offset) ))) -FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi) +FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) %.elf: LDFLAGS = $(CFLAGS) -nostdlib -%.elf: %.o $(FLATLIBS) arm/flat.lds +%.elf: %.o $(FLATLIBS) powerpc/flat.lds $(CC) $(LDFLAGS) -o $@ \ - -Wl,-T,arm/flat.lds,--build-id=none,-Ttext=$(start_addr) \ + -Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \ $(filter %.o, $^) $(FLATLIBS) -%.flat: %.elf - $(OBJCOPY) -O binary $^ $@ - -$(libeabi): $(eabiobjs) - $(AR) rcs $@ $^ - -arm_clean: libfdt_clean asm_offsets_clean - $(RM) $(TEST_DIR)/*.{o,flat,elf} $(libeabi) $(eabiobjs) \ - $(TEST_DIR)/.*.d lib/arm/.*.d +powerpc_clean: libfdt_clean asm_offsets_clean + $(RM) $(TEST_DIR)/*.{o,elf} \ + $(TEST_DIR)/.*.d lib/powerpc/.*.d ## @@ -77,4 +60,3 @@ test_cases: $(generated_files) $(tests-common) $(tests) $(TEST_DIR)/$(TEST).elf: $(cstart.o) $(TEST_DIR)/$(TEST).o $(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o -$(TEST_DIR)/spinlock-test.elf: $(cstart.o) $(TEST_DIR)/spinlock-test.o diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64 index 0b0761c729c7c..7c61933dfa8ba 100644 --- a/powerpc/Makefile.ppc64 +++ b/powerpc/Makefile.ppc64 @@ -1,20 +1,20 @@ # -# arm64 makefile +# ppc64 makefile # # Authors: Andrew Jones drjo...@redhat.com # bits = 64 -ldarch = elf64-littleaarch64 -kernel_offset = 0x8 +ldarch = elf64-powerpc #elf64-powerpcle (eventually) +kernel_offset = 0x0 cstart.o = $(TEST_DIR)/cstart64.o -cflatobjs += lib/arm64/processor.o -cflatobjs += lib/arm64/spinlock.o +cflatobjs += lib/ppc64/processor.o +cflatobjs += lib/ppc64/spinlock.o -# arm64 specific tests +# ppc64 specific tests tests = include $(TEST_DIR)/Makefile.common -arch_clean: arm_clean - $(RM) lib/arm64/.*.d +arch_clean: powerpc_clean + $(RM) lib/ppc64/.*.d diff --git a/powerpc/flat.lds b/powerpc/flat.lds index efdf5d7109ffb..bd075efb2c51b 100644 --- a/powerpc/flat.lds +++ b/powerpc/flat.lds @@ -4,6 +4,8 @@ SECTIONS .text : { *(.init) *(.text) *(.text.*) } . = ALIGN(64K); etext = .; +.opd : { *(.opd) } +. = ALIGN(16); .data : { *(.data) } @@ -11,16 +13,20 @@ SECTIONS .rodata : { *(.rodata) } . = ALIGN(16); .bss : { *(.bss) } +. = ALIGN(16); +/* + * tocptr is tocbase + 32K, allowing toc offsets to be +-32K + */ +tocptr = . + 32K; +.got : { *(.toc) *(.got) } . = ALIGN(64K); edata = .; . += 64K; . = ALIGN(64K); /* - * stack depth is 16K for arm and PAGE_SIZE for arm64, see THREAD_SIZE - * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm - * sp must always be strictly less than the true stacktop + * stackptr set with initial stack frame (64 bytes) preallocated */ -stackptr = . - 16; +stackptr = . - 64; stacktop = .; } -- 2.4.3 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[kvm-unit-tests PATCH 07/14] powerpc/ppc64: add bootloader to bounce into memory
Committing the binary, since there's little point in rebuilding, and it requires SLOF's build_romfs tool, which is not part of this source repository. Signed-off-by: Andrew Jones drjo...@redhat.com --- powerpc/boot_rom.bin | Bin 0 - 280 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 powerpc/boot_rom.bin diff --git a/powerpc/boot_rom.bin b/powerpc/boot_rom.bin new file mode 100644 index ..606e1204047afb21e1a90469d7e708496e596e7e GIT binary patch literal 280 zcmZQz0D~J4ilGBa!zhi6)Wnq3A_j)s#PrN$LnC8|1fxVsQC5ClYB5Y5Lt$!esR5ja zjiDgQE-vZ}lQD!bfON3u)_MP-07;mdOctnNj8IymxFj(73c^L`~P4eWcwelS1bkq DUsxnq literal 0 HcmV?d1 -- 2.4.3 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[kvm-unit-tests PATCH 02/14] lib: share arm-selftest utility functions
arm-selftest has a couple utility functions that could be useful to other unit tests, even other architectures. So move them out. split_var moves to lib/util, where we can add other random utilities over time. assert_args inspires report_abort, which allows us to report a message, using the current prefix, that we're aborting (outputs ABORT vs. PASS/FAIL). This is useful for cases when unit tests can't complete due to missing dependencies of some sort, such as missing/invalid inputs from the user. Signed-off-by: Andrew Jones drjo...@redhat.com --- arm/selftest.c | 33 - config/config-arm-common.mak | 1 + lib/libcflat.h | 11 ++- lib/report.c | 16 lib/util.c | 20 lib/util.h | 23 +++ 6 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 lib/util.c create mode 100644 lib/util.h diff --git a/arm/selftest.c b/arm/selftest.c index fc9ec609d875e..74abd048add6c 100644 --- a/arm/selftest.c +++ b/arm/selftest.c @@ -6,6 +6,7 @@ * This work is licensed under the terms of the GNU LGPL, version 2. */ #include libcflat.h +#include util.h #include alloc.h #include devicetree.h #include asm/setup.h @@ -18,28 +19,6 @@ #include asm/cpumask.h #include asm/barrier.h -static void assert_args(int num_args, int needed_args) -{ - if (num_args needed_args) { - printf(selftest: not enough arguments\n); - 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; @@ -48,7 +27,7 @@ static void check_setup(int argc, char **argv) for (i = 0; i argc; ++i) { - var = split_var(argv[i], val); + var = parse_keyval(argv[i], val); if (!var) continue; @@ -72,7 +51,8 @@ static void check_setup(int argc, char **argv) report_prefix_pop(); } - assert_args(nr_tests, 2); + if (nr_tests 2) + report_abort(missing input); } static struct pt_regs expected_regs; @@ -344,7 +324,10 @@ static void cpu_report(void) int main(int argc, char **argv) { report_prefix_push(selftest); - assert_args(argc, 1); + + if (argc 1) + report_abort(no test specified); + report_prefix_push(argv[0]); if (strcmp(argv[0], setup) == 0) { diff --git a/config/config-arm-common.mak b/config/config-arm-common.mak index f35b8b9231c03..4cff846930796 100644 --- a/config/config-arm-common.mak +++ b/config/config-arm-common.mak @@ -32,6 +32,7 @@ CFLAGS += -I lib -I lib/libfdt asm-offsets = lib/$(ARCH)/asm-offsets.h include config/asm-offsets.mak +cflatobjs += lib/util.o cflatobjs += lib/alloc.o cflatobjs += lib/devicetree.o cflatobjs += lib/virtio.o diff --git a/lib/libcflat.h b/lib/libcflat.h index 9747ccdbc9f1d..8411f6c5d92e3 100644 --- a/lib/libcflat.h +++ b/lib/libcflat.h @@ -57,11 +57,12 @@ 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); -void report_prefix_push(const char *prefix); -void report_prefix_pop(void); -void report(const char *msg_fmt, bool pass, ...); -void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...); -int report_summary(void); +extern void report_prefix_push(const char *prefix); +extern void report_prefix_pop(void); +extern void report(const char *msg_fmt, bool pass, ...); +extern void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...); +extern void report_abort(const char *msg_fmt, ...); +extern int report_summary(void); #define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0])) diff --git a/lib/report.c b/lib/report.c index 35e664108a921..62916c4ac3c8a 100644 --- a/lib/report.c +++ b/lib/report.c @@ -96,3 +96,19 @@ int report_summary(void) spin_unlock(lock); } + +void report_abort(const char *msg_fmt, ...) +{ + va_list va; + char buf[2000]; + + puts(ABORT: ); + puts(prefixes); + va_start(va, msg_fmt); + vsnprintf(buf, sizeof(buf), msg_fmt, va); + va_end(va); + puts(buf); + puts(\n); + report_summary(); + abort(); +} diff --git a/lib/util.c b/lib/util.c new file mode 100644 index 0..9dcec30ac8b5f --- /dev/null +++ b/lib/util.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@redhat.com + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include libcflat.h + +char *parse_keyval(char *s, long *val) +{ + char *p; + + p = strchr(s, '='); + if (!p
[kvm-unit-tests PATCH 14/14] mkstandalone: add support for powerpc
PowerPC needs firmware and an exit code snooper. Signed-off-by: Andrew Jones drjo...@redhat.com --- configure | 3 +++ powerpc/run | 2 +- scripts/mkstandalone.sh | 50 + 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/configure b/configure index e1f70bd79d4f7..7b332269e0d2e 100755 --- a/configure +++ b/configure @@ -11,6 +11,7 @@ arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'` host=$arch cross_prefix= snooper= +firmware= usage() { cat -EOF @@ -85,6 +86,7 @@ elif [ $arch = arm ] || [ $arch = arm64 ]; then elif [ $arch = powerpc ] || [ $arch = ppc64 ]; then testdir=powerpc snooper=snoop_exitcode +firmware=$testdir/boot_rom.bin else testdir=$arch fi @@ -140,4 +142,5 @@ AR=$cross_prefix$ar API=$api TEST_DIR=$testdir SNOOPER=$snooper +FIRMWARE=$firmware EOF diff --git a/powerpc/run b/powerpc/run index 5bc826765eff8..1d5b1c9135299 100755 --- a/powerpc/run +++ b/powerpc/run @@ -29,7 +29,7 @@ if ! $qemu -machine '?' 21 | grep 'pseries' /dev/null; then exit 2 fi -boot_rom='powerpc/boot_rom.bin' +boot_rom=$FIRMWARE if [ -f powerpc/rom/boot_rom.bin ]; then boot_rom='powerpc/rom/boot_rom.bin' fi diff --git a/scripts/mkstandalone.sh b/scripts/mkstandalone.sh index 4a6e4a3ada1a3..dd10ece6940de 100755 --- a/scripts/mkstandalone.sh +++ b/scripts/mkstandalone.sh @@ -17,6 +17,10 @@ elif [ -n $one_kernel ] [ -z $one_testname ]; then one_testname=${one_kernel_base%.*} fi +if [ $SNOOPER ]; then + snooper=| $SNOOPER +fi + unittests=$TEST_DIR/unittests.cfg mkdir -p tests @@ -51,6 +55,22 @@ function mkstandalone() #!/bin/sh EOF +if [ $SNOOPER = snoop_exitcode ]; then + cat EOF $standalone +snoop_exitcode() +{ + while read line; do + if echo \$line | grep 'EXIT: STATUS=' /dev/null; then + code=\`echo \$line | cut -d= -f2\` + fi + echo \$line + done + exit \$code +} + +EOF +fi + if [ $arch ]; then cat EOF $standalone ARCH=\`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'\` @@ -82,7 +102,21 @@ exit 1 EOF else cat EOF $standalone -trap 'rm -f \$bin; exit 1' HUP INT TERM +trap 'rm -f \$fwbin \$bin; exit 1' HUP INT TERM + +EOF +if [ -f $FIRMWARE ]; then + cat EOF $standalone +fwbin=\`mktemp\` +base64 -d 'BIN_EOF' | zcat \$fwbin +EOF +gzip - $FIRMWARE | base64 $standalone + cat EOF $standalone +BIN_EOF + +EOF +fi + cat EOF $standalone bin=\`mktemp\` base64 -d 'BIN_EOF' | zcat \$bin EOF @@ -101,9 +135,17 @@ while \$qemu \$cmdline -smp \$MAX_SMP 21 | grep 'exceeds max cpus' /dev/null MAX_SMP=\`expr \$MAX_SMP - 1\` done -cmdline=\`echo '$cmdline' | sed s%$kernel%\$bin%\` +cmdline='$cmdline' +EOF +if [ $FIRMWARE ]; then + cat EOF $standalone +cmdline=\`echo \$cmdline | sed s%$FIRMWARE%\$fwbin%\` +EOF +fi + cat EOF $standalone +cmdline=\`echo \$cmdline | sed s%$kernel%\$bin%\` echo \$qemu $cmdline -smp $smp $opts -\$qemu \$cmdline -smp $smp $opts +\$qemu \$cmdline -smp $smp $opts $snooper ret=\$? echo Return value from qemu: \$ret if [ \$ret -le 1 ]; then @@ -111,7 +153,7 @@ if [ \$ret -le 1 ]; then else echo FAIL $testname 12 fi -rm -f \$bin +rm -f \$fwbin \$bin exit 0 EOF fi -- 2.4.3 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[kvm-unit-tests PATCH 10/14] powerpc/ppc64: relocate linker VMAs
QEMU loads the unit test, but due to the way it translates the unit test's linker VMA to the LMA, we can't just link such that VMA == LMA. Thus, we link with VMA == 0x0, and then deal with relocation. Signed-off-by: Andrew Jones drjo...@redhat.com --- configure | 2 ++ powerpc/Makefile.common | 13 +--- powerpc/Makefile.ppc64 | 1 + powerpc/cstart64.S | 40 +++ powerpc/flat.lds| 13 +++- powerpc/reloc64.c | 55 + 6 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 powerpc/reloc64.c diff --git a/configure b/configure index b367224093369..b2ad199da7873 100755 --- a/configure +++ b/configure @@ -5,6 +5,7 @@ kerneldir=/lib/modules/$(uname -r)/build cc=gcc ld=ld objcopy=objcopy +objdump=objdump ar=ar arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'` host=$arch @@ -132,6 +133,7 @@ PROCESSOR=$processor CC=$cross_prefix$cc LD=$cross_prefix$ld OBJCOPY=$cross_prefix$objcopy +OBJDUMP=$cross_prefix$objdump AR=$cross_prefix$ar API=$api TEST_DIR=$testdir diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common index d6356540918a5..b130342dee60e 100644 --- a/powerpc/Makefile.common +++ b/powerpc/Makefile.common @@ -27,6 +27,7 @@ CFLAGS += -Wextra CFLAGS += -O2 CFLAGS += -I lib -I lib/libfdt CFLAGS += -Wa,-mregnames +CFLAGS += -fpie asm-offsets = lib/$(ARCH)/asm-offsets.h include scripts/asm-offsets.mak @@ -43,11 +44,17 @@ libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name) start_addr := $(shell printf %x\n $$(( $(phys_base) + $(kernel_offset) ))) FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) -%.elf: LDFLAGS = $(CFLAGS) -nostdlib +%.elf: LDFLAGS = $(CFLAGS) -nostdlib -pie %.elf: %.o $(FLATLIBS) powerpc/flat.lds $(CC) $(LDFLAGS) -o $@ \ -Wl,-T,powerpc/flat.lds,--build-id=none,-Ttext=$(start_addr) \ $(filter %.o, $^) $(FLATLIBS) + @echo -n Checking $@ for unsupported reloc types... + @if $(OBJDUMP) -R $@ | grep R_ | grep -v R_PPC64_RELATIVE; then \ + false; \ + else\ + echo looks good.;\ + fi powerpc_clean: libfdt_clean asm_offsets_clean $(RM) $(TEST_DIR)/*.{o,elf} \ @@ -59,5 +66,5 @@ generated_files = $(asm-offsets) test_cases: $(generated_files) $(tests-common) $(tests) -$(TEST_DIR)/$(TEST).elf: $(cstart.o) $(TEST_DIR)/$(TEST).o -$(TEST_DIR)/selftest.elf: $(cstart.o) $(TEST_DIR)/selftest.o +$(TEST_DIR)/$(TEST).elf: $(cstart.o) $(reloc.o) $(TEST_DIR)/$(TEST).o +$(TEST_DIR)/selftest.elf: $(cstart.o) $(reloc.o) $(TEST_DIR)/selftest.o diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64 index 7c61933dfa8ba..7274e0d98b5a5 100644 --- a/powerpc/Makefile.ppc64 +++ b/powerpc/Makefile.ppc64 @@ -8,6 +8,7 @@ ldarch = elf64-powerpc #elf64-powerpcle (eventually) kernel_offset = 0x0 cstart.o = $(TEST_DIR)/cstart64.o +reloc.o = $(TEST_DIR)/reloc64.o cflatobjs += lib/ppc64/processor.o cflatobjs += lib/ppc64/spinlock.o diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S index 141d4563563d5..8edaaa6e251fc 100644 --- a/powerpc/cstart64.S +++ b/powerpc/cstart64.S @@ -26,18 +26,50 @@ */ .globl start start: - LOAD_REG_IMMEDIATE(r1, stackptr) - LOAD_REG_IMMEDIATE(r2, tocptr) + /* +* We were loaded at QEMU's kernel load address, but we're not +* allowed to link there due to how QEMU deals with linker VMAs, +* so we just linked at zero. This means the first thing to do is +* to find our stack and toc, and then do a relocate. +*/ + bl . + 4 +0: mflrr31 + subir31, r31, 0b - start/* QEMU's kernel load address */ + ld r1, (p_stack - start)(r31) + ld r2, (p_toc - start)(r31) + add r1, r1, r31 + add r2, r2, r31 + + /* save DTB pointer */ + std r3, 56(r1) + + /* +* Call relocate. relocate is C code, but careful to not use +* any global references, as they may use absolute addresses, +* which are, obviously, not yet relocated. +*/ + mr r3, r31 + ld r4, (p_dyn - start)(r31) + add r4, r4, r31 + bl .relocate + + /* complete setup */ + ld r3, 56(r1) bl .setup /* run the test */ - LOAD_REG_IMMEDIATE(r5, __argc) - LOAD_REG_IMMEDIATE(r4, __argv) + LOAD_REG_ADDR(r5, __argc) + LOAD_REG_ADDR(r4, __argv) lwz r3, 0(r5) bl .main bl .exit b halt +.align 3 +p_stack: .llong stackptr +p_toc: .llong tocptr +p_dyn: .llong dynamic_start + .text .align 3 diff --git a/powerpc/flat.lds b/powerpc/flat.lds index bd075efb2c51b
[kvm-unit-tests PATCH 00/14] ppc64: initial drop
This series is the first series of a series of series that will bring support to kvm-unit-tests for ppc64, and eventually ppc64le. (Yes, the word 'series' is four times in that sentence. And now I've typed 'series' five times! Wait, now six times! OK, moving on...) This series brings basic setup; starts a test's C entry point, main(), and printf, exit, and malloc work. Three more series following this one will bring; vector support, mmu support, and smp support, at which point I believe the framework can just evolve with the creation of unit tests. Executive summary of the patches is as follows 01: A needed fix to asm-generic/io.h. This could go in without the rest of the series, but it's only needed for BE. 02: Share arm/selftest.c utility functions (for powerpc/selftest.c) 03: Split makefiles up and rename them. This is almost an RFC, since it generates some churn, but I think it has value now that we're adding another architecture. 04-05: Here's the framework start; empty skeleton plus some tweaks. 06-07: Adds a bootloader. As we target the SPAPR machine type that requires one. 08: printf support 09: More of setup's framework, and do more setup. 10: Relocate support (since we can't link LMA == VMA) 11: exit() support 12-14: Unit test running scripts These patches are available here https://github.com/rhdrjones/kvm-unit-tests/commits/ppc64/initial-drop and they're based on this branch https://github.com/rhdrjones/kvm-unit-tests/commits/staging which is based on (upstream's next branch) http://git.kernel.org/cgit/virt/kvm/kvm-unit-tests.git/log/?h=next Thanks, drew Andrew Jones (14): lib: asm-generic: add missing casts lib: share arm-selftest utility functions config: no need to mix arch makefiles powerpc/ppc64: start skeleton framework powerpc/pp64: ppc-ify makefiles and linker script powerpc/ppc64: add boot rom source powerpc/ppc64: add bootloader to bounce into memory powerpc/ppc64: add HV putchar powerpc/ppc64: adapt arm's setup powerpc/ppc64: relocate linker VMAs powerpc/ppc64: add rtas_power_off scripts: add exit code snooper powerpc/ppc64: add run script and unittests.cfg mkstandalone: add support for powerpc Makefile | 2 +- README | 3 +- arm/Makefile | 1 + config/config-arm.mak = arm/Makefile.arm | 2 +- config/config-arm64.mak = arm/Makefile.arm64 | 2 +- .../config-arm-common.mak = arm/Makefile.common | 3 +- arm/selftest.c | 33 ++- configure | 10 +++ lib/arm/io.c | 1 + lib/asm-generic/io.h | 12 +-- lib/libcflat.h | 14 +-- lib/powerpc/.gitignore | 1 + lib/powerpc/asm/rtas.h | 27 ++ lib/powerpc/asm/setup.h| 27 ++ lib/powerpc/io.c | 35 lib/powerpc/mmu.c | 0 lib/powerpc/rtas.c | 84 ++ lib/powerpc/setup.c| 82 ++ lib/powerpc/smp.c | 0 lib/ppc64/.gitignore | 1 + lib/ppc64/asm-offsets.c| 12 +++ lib/ppc64/asm/asm-offsets.h| 1 + lib/ppc64/asm/io.h | 5 ++ lib/ppc64/asm/page.h | 1 + lib/ppc64/asm/rtas.h | 1 + lib/ppc64/asm/setup.h | 1 + lib/ppc64/asm/spinlock.h | 11 +++ lib/ppc64/processor.c | 0 lib/ppc64/spinlock.c | 11 +++ lib/report.c | 16 lib/util.c | 20 + lib/util.h | 23 + powerpc/Makefile | 1 + powerpc/Makefile.common| 71 +++ powerpc/Makefile.ppc64 | 21 + powerpc/boot_rom.bin | Bin 0 - 280 bytes powerpc/cstart64.S | 96 + powerpc/flat.lds | 44 ++ powerpc/reloc64.c | 55 powerpc/rom/.gitignore | 1 + powerpc/rom/Makefile | 36 powerpc/rom/header.img | 1 + powerpc/rom/rom.ffs| 4 + powerpc
[kvm-unit-tests PATCH 01/14] lib: asm-generic: add missing casts
Signed-off-by: Andrew Jones drjo...@redhat.com --- lib/asm-generic/io.h | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/asm-generic/io.h b/lib/asm-generic/io.h index a9939d3a5921f..abd245676e97a 100644 --- a/lib/asm-generic/io.h +++ b/lib/asm-generic/io.h @@ -104,27 +104,27 @@ static inline u64 __bswap64(u64 x) #endif #define le16_to_cpu(x) \ - ({ u16 __r = __cpu_is_be() ? __bswap16(x) : (x); __r; }) + ({ u16 __r = __cpu_is_be() ? __bswap16((u16)x) : ((u16)x); __r; }) #define cpu_to_le16 le16_to_cpu #define le32_to_cpu(x) \ - ({ u32 __r = __cpu_is_be() ? __bswap32(x) : (x); __r; }) + ({ u32 __r = __cpu_is_be() ? __bswap32((u32)x) : ((u32)x); __r; }) #define cpu_to_le32 le32_to_cpu #define le64_to_cpu(x) \ - ({ u64 __r = __cpu_is_be() ? __bswap64(x) : (x); __r; }) + ({ u64 __r = __cpu_is_be() ? __bswap64((u64)x) : ((u64)x); __r; }) #define cpu_to_le64 le64_to_cpu #define be16_to_cpu(x) \ - ({ u16 __r = !__cpu_is_be() ? __bswap16(x) : (x); __r; }) + ({ u16 __r = !__cpu_is_be() ? __bswap16((u16)x) : ((u16)x); __r; }) #define cpu_to_be16 be16_to_cpu #define be32_to_cpu(x) \ - ({ u32 __r = !__cpu_is_be() ? __bswap32(x) : (x); __r; }) + ({ u32 __r = !__cpu_is_be() ? __bswap32((u32)x) : ((u32)x); __r; }) #define cpu_to_be32 be32_to_cpu #define be64_to_cpu(x) \ - ({ u64 __r = !__cpu_is_be() ? __bswap64(x) : (x); __r; }) + ({ u64 __r = !__cpu_is_be() ? __bswap64((u64)x) : ((u64)x); __r; }) #define cpu_to_be64 be64_to_cpu #ifndef rmb -- 2.4.3 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[kvm-unit-tests PATCH 13/14] powerpc/ppc64: add run script and unittests.cfg
Now that we have all the pieces, pull them together into the run script. To run a test do ./powerpc-run powerpc/test.elf To run all tests in unittests.cfg do ./run_tests.sh Signed-off-by: Andrew Jones drjo...@redhat.com --- powerpc/run | 57 +++ powerpc/unittests.cfg | 19 + 2 files changed, 76 insertions(+) create mode 100755 powerpc/run create mode 100644 powerpc/unittests.cfg diff --git a/powerpc/run b/powerpc/run new file mode 100755 index 0..5bc826765eff8 --- /dev/null +++ b/powerpc/run @@ -0,0 +1,57 @@ +#!/bin/bash + +if [ ! -f config.mak ]; then + echo run ./configure first. See ./configure -h + exit 2 +fi +source config.mak +source scripts/functions.bash + +processor=$PROCESSOR + +# Default to using KVM if available +if [ -c /dev/kvm ]; then + if [ $HOST = ppc64 ] [ $ARCH = ppc64 ]; then + usingkvm=yes + fi +fi + +qemu=${QEMU:-qemu-system-$ARCH_NAME} +qpath=$(which $qemu 2/dev/null) + +if [ -z $qpath ]; then + echo $qemu not found. + exit 2 +fi + +if ! $qemu -machine '?' 21 | grep 'pseries' /dev/null; then + echo $qpath doesn't support pSeries ('-machine pseries'). Exiting. + exit 2 +fi + +boot_rom='powerpc/boot_rom.bin' +if [ -f powerpc/rom/boot_rom.bin ]; then + boot_rom='powerpc/rom/boot_rom.bin' +fi + +M='-machine pseries' +if [ $DRYRUN != yes ]; then + if [ $usingkvm = yes ]; then + M+=',accel=kvm' + else + echo Running with TCG + M+=',accel=tcg' + fi +else + M+=',accel=kvm:tcg' +fi + +command=$qemu $M -bios $boot_rom -display none -serial stdio -kernel +echo $command $@ + +if [ $DRYRUN != yes ]; then + $command $@ | $SNOOPER + ret=$? + echo Return value from qemu: $ret + exit $ret +fi diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg new file mode 100644 index 0..5da2c6242a1f9 --- /dev/null +++ b/powerpc/unittests.cfg @@ -0,0 +1,19 @@ +# Define your new unittest following the convention: +# [unittest_name] +# file = foo.elf # Name of the kernel to be used +# smp = 2# Number of processors the VM will use during this test +# # Use $MAX_SMP to use the maximum the host supports. +# extra_params = -append params... # Additional parameters used +# arch = powerpc/ppc64 # 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.elf +smp = 2 +extra_params = -m 256 -append 'setup smp=2 mem=256' +groups = selftest -- 2.4.3 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[kvm-unit-tests PATCH 06/14] powerpc/ppc64: add boot rom source
Make a one line replacement for SLOF. This bootloader just jumps to 0x40, because we know the kernel will be there. This commit allows rebuilding of the bootloader, as long as the SLOF build_romfs tool is present, but since it would be a pain to require that tool for ever build, we'll just commit the binary rom image too with the next commit. Signed-off-by: Andrew Jones drjo...@redhat.com --- powerpc/rom/.gitignore | 1 + powerpc/rom/Makefile | 36 powerpc/rom/header.img | 1 + powerpc/rom/rom.ffs| 4 powerpc/rom/stage1.S | 5 + 5 files changed, 47 insertions(+) create mode 100644 powerpc/rom/.gitignore create mode 100644 powerpc/rom/Makefile create mode 100644 powerpc/rom/header.img create mode 100644 powerpc/rom/rom.ffs create mode 100644 powerpc/rom/stage1.S diff --git a/powerpc/rom/.gitignore b/powerpc/rom/.gitignore new file mode 100644 index 0..a8a0dcec44720 --- /dev/null +++ b/powerpc/rom/.gitignore @@ -0,0 +1 @@ +*.bin diff --git a/powerpc/rom/Makefile b/powerpc/rom/Makefile new file mode 100644 index 0..03b8bf7e0b5d2 --- /dev/null +++ b/powerpc/rom/Makefile @@ -0,0 +1,36 @@ +# +# powerpc boot_rom makefile +# +# Authors: Andrew Jones drjo...@redhat.com +# + +# Use SLOF's build_romfs tool (git://git.qemu-project.org/SLOF.git) +BUILD_ROMFS ?= build_romfs + +ifeq ($(wildcard ../../config.mak),) +$(error run ./configure first. See ./configure -h) +endif + +include ../../config.mak + +.PHONY: clean distclean + +all: boot_rom.bin + +boot_rom.bin: stage1.bin + $(BUILD_ROMFS) rom.ffs boot_rom.bin + +stage1.bin: stage1.elf + $(OBJCOPY) -O binary $^ $@ + +stage1.elf: stage1.o + $(LD) -nostdlib -Ttext=0x100 --entry=start --build-id=none -o $@ $ + +stage1.o: stage1.S + $(CC) -c -o $@ $ + +clean: + $(RM) stage1.{o,elf,bin} + +distclean: clean + $(RM) boot_rom.bin diff --git a/powerpc/rom/header.img b/powerpc/rom/header.img new file mode 100644 index 0..794129c95eec5 --- /dev/null +++ b/powerpc/rom/header.img @@ -0,0 +1 @@ +Key.Polynome..Mask...Polynome.Length.Header.and.File.length... und weiter im Text! diff --git a/powerpc/rom/rom.ffs b/powerpc/rom/rom.ffs new file mode 100644 index 0..b7851c00c462b --- /dev/null +++ b/powerpc/rom/rom.ffs @@ -0,0 +1,4 @@ +# FFile-Name Real Filename Flags ROM-Offset i/a +#--|---|---|-- +header header.img 0 0 +stage1 stage1.bin 1 0x100 diff --git a/powerpc/rom/stage1.S b/powerpc/rom/stage1.S new file mode 100644 index 0..ae2c08ddce3c1 --- /dev/null +++ b/powerpc/rom/stage1.S @@ -0,0 +1,5 @@ +#define SPAPR_KERNEL_LOAD_ADDR 0x40 +.text +.globl start +start: + b SPAPR_KERNEL_LOAD_ADDR - 0x100 -- 2.4.3 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[kvm-unit-tests PATCH 08/14] powerpc/ppc64: add HV putchar
Add the hvcall for putchar and use it in puts. That, along with a couple more lines in start to prepare for C code, and a branch to main(), gets us hello world. Run with qemu-system-ppc64 -M pseries\ -bios powerpc/boot_rom.bin \ -display none -serial stdio \ -kernel powerpc/selftest.elf (We're still not relocating yet, that comes in a later patch. Thus, testing hello-world at this point requires a hacked QEMU and linking the unit test at QEMU's kernel load address.) Signed-off-by: Andrew Jones drjo...@redhat.com --- lib/powerpc/io.c| 15 +-- powerpc/Makefile.common | 1 + powerpc/cstart64.S | 27 +++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c index cf3b6347e1e46..a7eaafeca9205 100644 --- a/lib/powerpc/io.c +++ b/lib/powerpc/io.c @@ -6,15 +6,26 @@ * This work is licensed under the terms of the GNU LGPL, version 2. */ #include libcflat.h +#include asm/spinlock.h + +extern void halt(int code); +extern void putchar(int c); + +static struct spinlock uart_lock; void io_init(void) { } -void puts(const char *s __unused) +void puts(const char *s) { + spin_lock(uart_lock); + while (*s) + putchar(*s++); + spin_unlock(uart_lock); } -void exit(int code __unused) +void exit(int code) { + halt(code); } diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common index 5cd3ea8085038..d6356540918a5 100644 --- a/powerpc/Makefile.common +++ b/powerpc/Makefile.common @@ -26,6 +26,7 @@ CFLAGS += -ffreestanding CFLAGS += -Wextra CFLAGS += -O2 CFLAGS += -I lib -I lib/libfdt +CFLAGS += -Wa,-mregnames asm-offsets = lib/$(ARCH)/asm-offsets.h include scripts/asm-offsets.mak diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S index d9b77f44f9e0e..d7c51cd352ee4 100644 --- a/powerpc/cstart64.S +++ b/powerpc/cstart64.S @@ -6,14 +6,41 @@ * This work is licensed under the terms of the GNU LGPL, version 2. */ +#define HVSC .long 0x4422 +#define H_PUT_TERM_CHAR0x58 + +#define LOAD_REG_IMMEDIATE(reg,expr) \ + lis reg,(expr)@highest; \ + ori reg,reg,(expr)@higher; \ + rldicr reg,reg,32,31; \ + orisreg,reg,(expr)@h; \ + ori reg,reg,(expr)@l; + +#define LOAD_REG_ADDR(reg,name)\ + ld reg,name@got(r2) + .section .init .globl start start: + LOAD_REG_IMMEDIATE(r1, stackptr) + LOAD_REG_IMMEDIATE(r2, tocptr) + bl .main + bl .exit b halt .text +.align 3 .globl halt halt: 1: b 1b + +.globl putchar +putchar: + sldir6, r3, 56 + li r3, H_PUT_TERM_CHAR + li r4, 0 /* vty-reg 0 means to use the default vty */ + li r5, 1 /* sending just 1 byte */ + HVSC + blr -- 2.4.3 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[kvm-unit-tests PATCH 03/14] config: no need to mix arch makefiles
Move the config/config-*.mak files to their own directories and rename to Makefile.* README is also updated to reflect the change, as well as to remove an optimistic reference to a non-existent docs directory. Signed-off-by: Andrew Jones drjo...@redhat.com --- Makefile| 2 +- README | 3 +-- arm/Makefile| 1 + config/config-arm.mak = arm/Makefile.arm | 2 +- config/config-arm64.mak = arm/Makefile.arm64 | 2 +- config/config-arm-common.mak = arm/Makefile.common | 2 +- {config = scripts}/asm-offsets.mak | 0 x86/Makefile| 1 + config/config-x86-common.mak = x86/Makefile.common | 0 config/config-i386.mak = x86/Makefile.i386 | 2 +- config/config-x86_64.mak = x86/Makefile.x86_64 | 2 +- 11 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 arm/Makefile rename config/config-arm.mak = arm/Makefile.arm (90%) rename config/config-arm64.mak = arm/Makefile.arm64 (89%) rename config/config-arm-common.mak = arm/Makefile.common (98%) rename {config = scripts}/asm-offsets.mak (100%) create mode 100644 x86/Makefile rename config/config-x86-common.mak = x86/Makefile.common (100%) rename config/config-i386.mak = x86/Makefile.i386 (91%) rename config/config-x86_64.mak = x86/Makefile.x86_64 (92%) diff --git a/Makefile b/Makefile index 0d5933474cd8c..2dcc323592299 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ LIBFDT_include = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_INCLUDES)) LIBFDT_version = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_VERSION)) #include architecure specific make rules -include config/config-$(ARCH).mak +include $(TEST_DIR)/Makefile # cc-option # Usage: OP_CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0) diff --git a/README b/README index 0884aafa21d18..4cb30892699f4 100644 --- a/README +++ b/README @@ -28,8 +28,7 @@ each as a standalone test. Directory structure: .: configure script, top-level Makefile, and run_tests.sh -./config: collection of architecture dependent makefiles -./docs:documentation files +./scripts: helper scripts for building and running tests ./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 diff --git a/arm/Makefile b/arm/Makefile new file mode 100644 index 0..369a38b2d1703 --- /dev/null +++ b/arm/Makefile @@ -0,0 +1 @@ +include $(TEST_DIR)/Makefile.$(ARCH) diff --git a/config/config-arm.mak b/arm/Makefile.arm similarity index 90% rename from config/config-arm.mak rename to arm/Makefile.arm index ae6c2e7134883..946422872532d 100644 --- a/config/config-arm.mak +++ b/arm/Makefile.arm @@ -18,6 +18,6 @@ cflatobjs += lib/arm/processor.o # arm specific tests tests = -include config/config-arm-common.mak +include $(TEST_DIR)/Makefile.common arch_clean: arm_clean diff --git a/config/config-arm64.mak b/arm/Makefile.arm64 similarity index 89% rename from config/config-arm64.mak rename to arm/Makefile.arm64 index d61b703c8140e..0b0761c729c7c 100644 --- a/config/config-arm64.mak +++ b/arm/Makefile.arm64 @@ -14,7 +14,7 @@ cflatobjs += lib/arm64/spinlock.o # arm64 specific tests tests = -include config/config-arm-common.mak +include $(TEST_DIR)/Makefile.common arch_clean: arm_clean $(RM) lib/arm64/.*.d diff --git a/config/config-arm-common.mak b/arm/Makefile.common similarity index 98% rename from config/config-arm-common.mak rename to arm/Makefile.common index 4cff846930796..f50d9f9d4e0f6 100644 --- a/config/config-arm-common.mak +++ b/arm/Makefile.common @@ -30,7 +30,7 @@ CFLAGS += -O2 CFLAGS += -I lib -I lib/libfdt asm-offsets = lib/$(ARCH)/asm-offsets.h -include config/asm-offsets.mak +include scripts/asm-offsets.mak cflatobjs += lib/util.o cflatobjs += lib/alloc.o diff --git a/config/asm-offsets.mak b/scripts/asm-offsets.mak similarity index 100% rename from config/asm-offsets.mak rename to scripts/asm-offsets.mak diff --git a/x86/Makefile b/x86/Makefile new file mode 100644 index 0..369a38b2d1703 --- /dev/null +++ b/x86/Makefile @@ -0,0 +1 @@ +include $(TEST_DIR)/Makefile.$(ARCH) diff --git a/config/config-x86-common.mak b/x86/Makefile.common similarity index 100% rename from config/config-x86-common.mak rename to x86/Makefile.common diff --git a/config/config-i386.mak b/x86/Makefile.i386 similarity index 91% rename from config/config-i386.mak rename to x86/Makefile.i386 index 691381ca69c85..ec189ce735bad 100644 --- a/config/config-i386.mak +++ b/x86/Makefile.i386 @@ -6,7 +6,7 @@ CFLAGS += -I $(KERNELDIR)/include tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat \ $(TEST_DIR)/cmpxchg8b.flat -include config/config-x86-common.mak +include $(TEST_DIR)/Makefile.common
[kvm-unit-tests PATCH 09/14] powerpc/ppc64: adapt arm's setup
Copy arm's setup code (also DT based) over to powerpc, adapting it a bit. Also bring over arm's setup selftest, giving powerpc its first test. Signed-off-by: Andrew Jones drjo...@redhat.com --- lib/powerpc/asm/setup.h | 27 lib/powerpc/setup.c | 82 + lib/ppc64/asm/setup.h | 1 + powerpc/cstart64.S | 9 ++ powerpc/selftest.c | 64 -- 5 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 lib/powerpc/asm/setup.h create mode 100644 lib/ppc64/asm/setup.h diff --git a/lib/powerpc/asm/setup.h b/lib/powerpc/asm/setup.h new file mode 100644 index 0..745226a8cf067 --- /dev/null +++ b/lib/powerpc/asm/setup.h @@ -0,0 +1,27 @@ +#ifndef _ASMPOWERPC_SETUP_H_ +#define _ASMPOWERPC_SETUP_H_ +/* + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@redhat.com + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include libcflat.h + +#define NR_CPUS8 /* arbitrarily set for now */ +extern u32 cpus[NR_CPUS]; +extern int nr_cpus; + +extern phys_addr_t __physical_start, __physical_end; + +#define PHYSICAL_START (__physical_start) +#define PHYSICAL_END (__physical_end) + +#ifdef __powerpc64__ +#define L1_CACHE_SHIFT 7 +#else +#define L1_CACHE_SHIFT 5 +#endif +#define L1_CACHE_BYTES (1 L1_CACHE_SHIFT) +#define SMP_CACHE_BYTESL1_CACHE_BYTES + +#endif /* _ASMPOWERPC_SETUP_H_ */ diff --git a/lib/powerpc/setup.c b/lib/powerpc/setup.c index e69de29bb2d1d..1794d1f39066a 100644 --- a/lib/powerpc/setup.c +++ b/lib/powerpc/setup.c @@ -0,0 +1,82 @@ +/* + * Initialize machine setup information and I/O. + * + * After running setup() unit tests may query how many cpus they have + * (nr_cpus), how much memory they have (PHYSICAL_END - PHYSICAL_START), + * may use dynamic memory allocation (malloc, etc.), printf, and exit. + * Finally, argc and argv are also ready to be passed to main(). + * + * Copyright (C) 2015, Red Hat Inc, Andrew Jones drjo...@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 alloc.h +#include asm/setup.h +#include asm/page.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] = (~0U) }; +int nr_cpus; + +phys_addr_t __physical_start, __physical_end; + +static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused) +{ + int cpu = nr_cpus++; + assert(cpu NR_CPUS); + cpus[cpu] = regval; +} + +static void cpu_init(void) +{ + nr_cpus = 0; + assert(dt_for_each_cpu_node(cpu_set, NULL) == 0); +} + +static void mem_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 mem_start, mem_end; + + assert(dt_get_memory_params(regs, 1)); + + mem_start = regs[0].addr; + mem_end = mem_start + regs[0].size; + +// assert(!(mem_start ~PHYS_MASK) !((mem_end-1) ~PHYS_MASK)); + assert(freemem_start = mem_start freemem_start mem_end); + + __physical_start = mem_start; /* PHYSICAL_START */ + __physical_end = mem_end; /* PHYSICAL_END */ + + phys_alloc_init(freemem_start, mem_end - freemem_start); + phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES); +} + +void setup(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); + + mem_init(PAGE_ALIGN((unsigned long)stacktop + fdt_size)); + io_init(); + cpu_init(); + + assert(dt_get_bootargs(bootargs) == 0); + setup_args(bootargs); +} diff --git a/lib/ppc64/asm/setup.h b/lib/ppc64/asm/setup.h new file mode 100644 index 0..20192985928a4 --- /dev/null +++ b/lib/ppc64/asm/setup.h @@ -0,0 +1 @@ +#include ../../powerpc/asm/setup.h diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S index d7c51cd352ee4..141d4563563d5 100644 --- a/powerpc/cstart64.S +++ b/powerpc/cstart64.S @@ -21,10 +21,19 @@ .section .init +/* + * start is the entry point. r3 points to the DTB + */ .globl start start: LOAD_REG_IMMEDIATE(r1, stackptr) LOAD_REG_IMMEDIATE(r2, tocptr) + bl .setup + + /* run the test */ + LOAD_REG_IMMEDIATE(r5, __argc) + LOAD_REG_IMMEDIATE(r4, __argv) + lwz r3, 0(r5) bl .main bl .exit b halt diff --git a/powerpc/selftest.c b/powerpc/selftest.c index 2f2a5215dd55c..b1d5e73029f46 100644 --- a/powerpc
[kvm-unit-tests PATCH 12/14] scripts: add exit code snooper
Add a function that reads test output streams and just forwards it on to stdout, except when a line is 'EXIT: STATUS=%d', at which point it grabs the status to use as the exit code. Tests that always exit with zero (due to how they inform QEMU to quit), can now return other status codes. Run with . scripts/functions.bash $test_cmdline | snoop_exitcode The unit test must call print_exit_line(code) before invoking its method to quit QEMU. For arm and powerpc, we just add the print_exit_line calls to their exit() functions right now. Signed-off-by: Andrew Jones drjo...@redhat.com --- configure | 5 - lib/arm/io.c | 1 + lib/libcflat.h | 3 +++ lib/powerpc/io.c | 1 + scripts/functions.bash | 11 +++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/configure b/configure index b2ad199da7873..e1f70bd79d4f7 100755 --- a/configure +++ b/configure @@ -10,6 +10,7 @@ ar=ar arch=`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'` host=$arch cross_prefix= +snooper= usage() { cat -EOF @@ -81,8 +82,9 @@ if [ $arch = i386 ] || [ $arch = x86_64 ]; then testdir=x86 elif [ $arch = arm ] || [ $arch = arm64 ]; then testdir=arm -elif [ $arch = ppc64 ]; then +elif [ $arch = powerpc ] || [ $arch = ppc64 ]; then testdir=powerpc +snooper=snoop_exitcode else testdir=$arch fi @@ -137,4 +139,5 @@ OBJDUMP=$cross_prefix$objdump AR=$cross_prefix$ar API=$api TEST_DIR=$testdir +SNOOPER=$snooper EOF diff --git a/lib/arm/io.c b/lib/arm/io.c index a08d394e4aa1c..487071d2edcd3 100644 --- a/lib/arm/io.c +++ b/lib/arm/io.c @@ -78,6 +78,7 @@ void puts(const char *s) void exit(int code) { + print_exit_line(code); chr_testdev_exit(code); halt(code); } diff --git a/lib/libcflat.h b/lib/libcflat.h index 8411f6c5d92e3..c3d90a0af831a 100644 --- a/lib/libcflat.h +++ b/lib/libcflat.h @@ -77,4 +77,7 @@ do { \ abort();\ } while (0) +#define print_exit_line(code) \ + printf(\nEXIT: STATUS=%d\n, ((code) 1) | 1) + #endif diff --git a/lib/powerpc/io.c b/lib/powerpc/io.c index 25cdd0ad961ee..b68d33b9ef740 100644 --- a/lib/powerpc/io.c +++ b/lib/powerpc/io.c @@ -29,6 +29,7 @@ void puts(const char *s) void exit(int code) { + print_exit_line(code); rtas_power_off(); halt(code); } diff --git a/scripts/functions.bash b/scripts/functions.bash index 7ed5a517250bc..7b4a5e4e63c9b 100644 --- a/scripts/functions.bash +++ b/scripts/functions.bash @@ -40,3 +40,14 @@ function for_each_unittest() $cmd $testname $groups $smp $kernel $opts $arch $check exec {fd}- } + +function snoop_exitcode() +{ + while read line; do + if [[ $line =~ ^EXIT:\ STATUS=(.*)$ ]]; then + code=${BASH_REMATCH[1]} + fi + echo $line + done + exit $code +} -- 2.4.3 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [kvm-unit-tests PATCH 11/14] powerpc/ppc64: add rtas_power_off
On Mon, Aug 03, 2015 at 07:08:17PM +0200, Paolo Bonzini wrote: On 03/08/2015 16:41, Andrew Jones wrote: Add enough RTAS support to support power-off, and apply it to exit(). Signed-off-by: Andrew Jones drjo...@redhat.com Why not use virtio-mmio + testdev on ppc as well? Similar to how we're not using PSCI on ARM or ACPI on x86. I have some longer term plans to add minimal virtio-pci support to kvm-unit-tests, and then we could plug virtio-serial+chr-testdev into that. I didn't think I could use virtio-mmio directly with spapr, but maybe I can? Actually, I sort of like this approach more in some respects though, as it doesn't require a special testdev or virtio support, keeping the unit test extra minimal. In fact, I was even thinking about posting patches (which I've already written) that allow chr-testdev to be optional for ARM too, now that it could use the exitcode snooper. Thanks, drew Paolo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
ppc kvm-unit-tests?
Hi Alex, I'm looking at adding arm to kvm-unit-tests. One the first things I'd like to do is clean up the kvm-unit-tests repo a bit. There's some arch-specific files (including ppc) laying around in the root dir that I'd sweep up before adding another arch to the mix. Although, checking the git history of the ppc ones even indicates they've never been used. They appear to have been put there during the initial drop by Avi, likely expecting to continue development with them later. So my question to you is, do you use kvm- unit-tests? or plan to? Otherwise, maybe we can just remove ppc altogether during the clean up. Thanks, drew -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html