This patch allows to build tests for ppc64 little endian target (ppc64le) on big and little endian hosts. We add a new parameter to configure to select the endianness of the tests (--endian=little or --endian=big). I have built and tested big and little endian tests on a little endian host, a big endian host, with kvm_hv and kvm_pr, and on x86_64 with ppc64 as a TCG target. Signed-off-by: Laurent Vivier <lvivier@xxxxxxxxxx> --- v2: replace FIXUP_ENDIAN from linux by a home made version (B_BE and RETURN_FROM_BE) Makefile | 11 ++++++----- configure | 6 ++++++ lib/powerpc/asm/ppc_asm.h | 36 ++++++++++++++++++++++++++++++++++++ lib/ppc64/asm/io.h | 8 ++++++++ lib/ppc64/asm/ppc_asm.h | 1 + powerpc/Makefile | 2 +- powerpc/Makefile.big | 21 +++++++++++++++++++++ powerpc/Makefile.common | 18 ++++++++++-------- powerpc/Makefile.little | 21 +++++++++++++++++++++ powerpc/Makefile.ppc64 | 22 ---------------------- powerpc/cstart64.S | 14 ++++++++++---- 11 files changed, 120 insertions(+), 40 deletions(-) create mode 100644 lib/powerpc/asm/ppc_asm.h create mode 100644 lib/ppc64/asm/ppc_asm.h create mode 100644 powerpc/Makefile.big create mode 100644 powerpc/Makefile.little delete mode 100644 powerpc/Makefile.ppc64 diff --git a/Makefile b/Makefile index ddba941..8ed244a 100644 --- a/Makefile +++ b/Makefile @@ -40,12 +40,13 @@ include $(TEST_DIR)/Makefile 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 += -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, "") +main_CFLAGS = -g +main_CFLAGS += $(autodepend-flags) -Wall +main_CFLAGS += $(call cc-option, -fomit-frame-pointer, "") +main_CFLAGS += $(call cc-option, -fno-stack-protector, "") +main_CFLAGS += $(call cc-option, -fno-stack-protector-all, "") +CFLAGS += $(main_CFLAGS) CXXFLAGS += $(CFLAGS) autodepend-flags = -MMD -MF $(dir $*).$(notdir $*).d diff --git a/configure b/configure index a685cca..0043ee9 100755 --- a/configure +++ b/configure @@ -10,6 +10,7 @@ ar=ar arch=`uname -m | sed -e 's/i.86/i386/;s/arm.*/arm/;s/ppc64.*/ppc64/'` host=$arch cross_prefix= +endian=big # default for ppc64, the only user usage() { cat <<-EOF @@ -23,6 +24,7 @@ usage() { --ld=LD ld linker to use ($ld) --prefix=PREFIX where to install things ($prefix) --kerneldir=DIR kernel build directory for kvm.h ($kerneldir) + --endian=ENDIAN endianness to compile for (little or big) EOF exit 1 } @@ -50,6 +52,9 @@ while [[ "$1" = -* ]]; do --cross-prefix) cross_prefix="$arg" ;; + --endian) + endian="$arg" + ;; --cc) cc="$arg" ;; @@ -139,4 +144,5 @@ AR=$cross_prefix$ar API=$api TEST_DIR=$testdir FIRMWARE=$firmware +ENDIAN=$endian EOF diff --git a/lib/powerpc/asm/ppc_asm.h b/lib/powerpc/asm/ppc_asm.h new file mode 100644 index 0000000..f0ab241 --- /dev/null +++ b/lib/powerpc/asm/ppc_asm.h @@ -0,0 +1,36 @@ +#ifndef _ASMPOWERPC_PPC_ASM_H +#define _ASMPOWERPC_PPC_ASM_H + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + +#define B_BE(addr) \ + mtctr addr; \ + nop; \ + bctr + +#define RETURN_FROM_BE + +#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +#define B_BE(addr) \ + mfmsr r11; \ + xori r11,r11,1; \ + mtsrr0 addr; \ + mtsrr1 r11; \ + rfid; \ + b . + +#define RETURN_FROM_BE \ + .long 0x05000048; /* bl . + 4 */ \ + .long 0xa602487d; /* mflr r10 */ \ + .long 0x20004a39; /* addi r10,r10,32 */ \ + .long 0xa600607d; /* mfmsr r11 */ \ + .long 0x01006b69; /* xori r11,r11,1 */ \ + .long 0xa6035a7d; /* mtsrr0 r10 */ \ + .long 0xa6037b7d; /* mtsrr1 r11 */ \ + .long 0x2400004c; /* rfid */ \ + .long 0x00000048; /* b . */ \ + +#endif /* __BYTE_ORDER__ */ + +#endif /* _ASMPOWERPC_PPC_ASM_H */ diff --git a/lib/ppc64/asm/io.h b/lib/ppc64/asm/io.h index c0801d4..4f2c31b 100644 --- a/lib/ppc64/asm/io.h +++ b/lib/ppc64/asm/io.h @@ -1,5 +1,13 @@ #ifndef _ASMPPC64_IO_H_ #define _ASMPPC64_IO_H_ + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define __cpu_is_be() (0) +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #define __cpu_is_be() (1) +#else +#error Undefined byte order +#endif + #include <asm-generic/io.h> #endif diff --git a/lib/ppc64/asm/ppc_asm.h b/lib/ppc64/asm/ppc_asm.h new file mode 100644 index 0000000..e3929ee --- /dev/null +++ b/lib/ppc64/asm/ppc_asm.h @@ -0,0 +1 @@ +#include "../../powerpc/asm/ppc_asm.h" diff --git a/powerpc/Makefile b/powerpc/Makefile index 369a38b..cc39a09 100644 --- a/powerpc/Makefile +++ b/powerpc/Makefile @@ -1 +1 @@ -include $(TEST_DIR)/Makefile.$(ARCH) +include $(TEST_DIR)/Makefile.$(ENDIAN) diff --git a/powerpc/Makefile.big b/powerpc/Makefile.big new file mode 100644 index 0000000..d81c52d --- /dev/null +++ b/powerpc/Makefile.big @@ -0,0 +1,21 @@ +# +# ppc64 big-endian makefile +# +# Authors: Andrew Jones <drjones@xxxxxxxxxx> +# +bits = 64 + +arch_CFLAGS = -mbig-endian +arch_LDFLAGS = -EB + +cstart.o = $(TEST_DIR)/cstart64.o +reloc.o = $(TEST_DIR)/reloc64.o +cflatobjs += lib/ppc64/spinlock.o + +# ppc64 specific tests +tests = + +include $(TEST_DIR)/Makefile.common + +arch_clean: powerpc_clean + $(RM) lib/ppc64/.*.d diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common index cc27ac8..b088af6 100644 --- a/powerpc/Makefile.common +++ b/powerpc/Makefile.common @@ -11,14 +11,15 @@ all: $(TEST_DIR)/boot_rom.bin test_cases ################################################################## -CFLAGS += $(arch_CFLAGS) -CFLAGS += -std=gnu99 -CFLAGS += -ffreestanding -CFLAGS += -Wextra -CFLAGS += -O2 -CFLAGS += -I lib -I lib/libfdt -CFLAGS += -Wa,-mregnames -CFLAGS += -fpie +common_CFLAGS = -std=gnu99 +common_CFLAGS += -ffreestanding +common_CFLAGS += -Wextra +common_CFLAGS += -O2 +common_CFLAGS += -I lib -I lib/libfdt +common_CFLAGS += -Wa,-mregnames +common_CFLAGS += -fpie + +CFLAGS += $(arch_CFLAGS) $(common_CFLAGS) asm-offsets = lib/$(ARCH)/asm-offsets.h include scripts/asm-offsets.mak @@ -48,6 +49,7 @@ $(TEST_DIR)/boot_rom.bin: $(TEST_DIR)/boot_rom.elf dd if=/dev/zero of=$@ bs=256 count=1 $(OBJCOPY) -O binary $^ >(cat - >>$@) +$(TEST_DIR)/boot_rom.elf: CFLAGS = -mbig-endian $(common_CFLAGS) $(main_CFLAGS) $(TEST_DIR)/boot_rom.elf: $(TEST_DIR)/boot_rom.o $(LD) -EB -nostdlib -Ttext=0x100 --entry=start --build-id=none -o $@ $< diff --git a/powerpc/Makefile.little b/powerpc/Makefile.little new file mode 100644 index 0000000..c37d2fc --- /dev/null +++ b/powerpc/Makefile.little @@ -0,0 +1,21 @@ +# +# ppc64 little-endian makefile +# +# Authors: Andrew Jones <drjones@xxxxxxxxxx> +# +bits = 64 + +arch_CFLAGS = -mlittle-endian +arch_LDFLAGS = -EL + +cstart.o = $(TEST_DIR)/cstart64.o +reloc.o = $(TEST_DIR)/reloc64.o +cflatobjs += lib/ppc64/spinlock.o + +# ppc64 specific tests +tests = + +include $(TEST_DIR)/Makefile.common + +arch_clean: powerpc_clean + $(RM) lib/ppc64/.*.d diff --git a/powerpc/Makefile.ppc64 b/powerpc/Makefile.ppc64 deleted file mode 100644 index 1cf277e..0000000 --- a/powerpc/Makefile.ppc64 +++ /dev/null @@ -1,22 +0,0 @@ -# -# ppc64 makefile -# -# Authors: Andrew Jones <drjones@xxxxxxxxxx> -# -bits = 64 -ldarch = elf64-powerpc - -arch_CFLAGS = -mbig-endian -arch_LDFLAGS = -EB - -cstart.o = $(TEST_DIR)/cstart64.o -reloc.o = $(TEST_DIR)/reloc64.o -cflatobjs += lib/ppc64/spinlock.o - -# ppc64 specific tests -tests = - -include $(TEST_DIR)/Makefile.common - -arch_clean: powerpc_clean - $(RM) lib/ppc64/.*.d diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S index f5530fb..60557a9 100644 --- a/powerpc/cstart64.S +++ b/powerpc/cstart64.S @@ -7,6 +7,7 @@ */ #define __ASSEMBLY__ #include <asm/hcall.h> +#include <asm/ppc_asm.h> #define LOAD_REG_IMMEDIATE(reg,expr) \ lis reg,(expr)@highest; \ @@ -25,6 +26,7 @@ */ .globl start start: + RETURN_FROM_BE /* * 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, @@ -93,11 +95,15 @@ halt: enter_rtas: mflr r0 std r0, 16(r1) + + LOAD_REG_ADDR(r10,rtas_return_loc) + mtlr r10 + LOAD_REG_ADDR(r10, rtas_blob) -//FIXME: change this bctrl to an rtas-prep, rfid, rtas-return sequence - mtctr r10 - nop - bctrl + B_BE(r10) + +rtas_return_loc: + RETURN_FROM_BE ld r0, 16(r1) mtlr r0 blr -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html