powerpc: select endianness

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@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1456824930-15078-3-git-send-email-lvivier@redhat.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
index cc27ac8..b526668 100644
--- a/powerpc/Makefile.common
+++ b/powerpc/Makefile.common
@@ -11,7 +11,6 @@
 
 ##################################################################
 
-CFLAGS += $(arch_CFLAGS)
 CFLAGS += -std=gnu99
 CFLAGS += -ffreestanding
 CFLAGS += -Wextra
@@ -32,6 +31,7 @@
 cflatobjs += lib/powerpc/rtas.o
 
 FLATLIBS = $(libcflat) $(LIBFDT_archive)
+%.elf: CFLAGS += $(arch_CFLAGS)
 %.elf: LDFLAGS = $(arch_LDFLAGS) -nostdlib -pie
 %.elf: %.o $(FLATLIBS) powerpc/flat.lds
 	$(LD) $(LDFLAGS) -o $@ \
@@ -48,6 +48,7 @@
 	dd if=/dev/zero of=$@ bs=256 count=1
 	$(OBJCOPY) -O binary $^ >(cat - >>$@)
 
+$(TEST_DIR)/boot_rom.elf: CFLAGS = -mbig-endian
 $(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.ppc64 b/powerpc/Makefile.ppc64
index 2df44d4..3da3a83 100644
--- a/powerpc/Makefile.ppc64
+++ b/powerpc/Makefile.ppc64
@@ -5,8 +5,13 @@
 #
 bits = 64
 
-arch_CFLAGS = -mbig-endian
-arch_LDFLAGS = -EB
+ifeq ($(ENDIAN),little)
+    arch_CFLAGS = -mlittle-endian
+    arch_LDFLAGS = -EL
+else
+    arch_CFLAGS = -mbig-endian
+    arch_LDFLAGS = -EB
+endif
 
 cstart.o = $(TEST_DIR)/cstart64.o
 reloc.o  = $(TEST_DIR)/reloc64.o
diff --git a/powerpc/cstart64.S b/powerpc/cstart64.S
index 6072597..c87e3d6 100644
--- a/powerpc/cstart64.S
+++ b/powerpc/cstart64.S
@@ -8,6 +8,7 @@
 #define __ASSEMBLY__
 #include <asm/hcall.h>
 #include <asm/ppc_asm.h>
+#include <asm/rtas.h>
 
 .section .init
 
@@ -16,6 +17,7 @@
  */
 .globl start
 start:
+	FIXUP_ENDIAN
 	/*
 	 * 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,
@@ -84,12 +86,22 @@
 enter_rtas:
 	mflr	r0
 	std	r0, 16(r1)
+
+	LOAD_REG_ADDR(r10, rtas_return_loc)
+	mtlr	r10
 	LOAD_REG_ADDR(r11, rtas_entry)
 	ld	r10, 0(r11)
-//FIXME: change this bctrl to an rtas-prep, rfid, rtas-return sequence
-	mtctr	r10
-	nop
-	bctrl
+
+	mfmsr	r11
+	LOAD_REG_IMMEDIATE(r9, RTAS_MSR_MASK)
+	and	r11, r11, r9
+	mtsrr0	r10
+	mtsrr1	r11
+	rfid
+	b       .
+
+rtas_return_loc:
+	FIXUP_ENDIAN
 	ld	r0, 16(r1)
 	mtlr	r0
 	blr