xen: Add files needed for minimal ppc64le build

Add the build system changes required to build for ppc64le (POWER8+).
As of now the resulting image simply boots to an infinite loop.

$ make XEN_TARGET_ARCH=ppc64 -C xen build

This port targets POWER8+ CPUs running in Little Endian mode specifically,
and does not boot on older machines. Additionally, this initial skeleton
only implements the PaPR/pseries boot protocol which allows it to be
booted in a standard QEMU virtual machine:

$ qemu-system-ppc64 -M pseries-5.2 -m 256M -kernel xen/xen

Signed-off-by: Shawn Anastasio <sanastasio@raptorengineering.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Shawn Anastasio authored and Andrew Cooper committed 2023-06-21 14:26:21 +01:00
1 parent 7f314e0aa5
commit b0582dd686
14 files changed
+379 -2

No files matched your search

+4
View File
@@ -0,0 +1,4 @@
CONFIG_PPC := y
CONFIG_PPC64 := y
CONFIG_XEN_INSTALL_SUFFIX :=
+3 -2
View File
@@ -38,7 +38,7 @@ EFI_MOUNTPOINT ?= $(BOOT_DIR)/efi
ARCH=$(XEN_TARGET_ARCH)
SRCARCH=$(shell echo $(ARCH) | \
sed -e 's/x86.*/x86/' -e s'/arm\(32\|64\)/arm/g' \
-e s'/riscv.*/riscv/g')
-e s'/riscv.*/riscv/g' -e s'/ppc.*/ppc/g')
export ARCH SRCARCH
# Allow someone to change their config file
@@ -244,7 +244,7 @@ include $(XEN_ROOT)/Config.mk
export TARGET_SUBARCH := $(XEN_TARGET_ARCH)
export TARGET_ARCH := $(shell echo $(XEN_TARGET_ARCH) | \
sed -e 's/x86.*/x86/' -e s'/arm\(32\|64\)/arm/g' \
-e s'/riscv.*/riscv/g')
-e s'/riscv.*/riscv/g' -e s'/ppc.*/ppc/g')
export CONFIG_SHELL := $(SHELL)
export CC CXX LD NM OBJCOPY OBJDUMP ADDR2LINE
@@ -563,6 +563,7 @@ _clean:
$(Q)$(MAKE) $(clean)=xsm
$(Q)$(MAKE) $(clean)=crypto
$(Q)$(MAKE) $(clean)=arch/arm
$(Q)$(MAKE) $(clean)=arch/ppc
$(Q)$(MAKE) $(clean)=arch/riscv
$(Q)$(MAKE) $(clean)=arch/x86
$(Q)$(MAKE) $(clean)=test
+42
View File
@@ -0,0 +1,42 @@
config PPC
def_bool y
config PPC64
def_bool y
select 64BIT
config ARCH_DEFCONFIG
string
default "arch/ppc/configs/ppc64_defconfig"
menu "Architecture Features"
source "arch/Kconfig"
endmenu
menu "ISA Selection"
choice
prompt "Base ISA"
default POWER_ISA_2_07B
help
This selects the base ISA version that Xen will target.
config POWER_ISA_2_07B
bool "Power ISA 2.07B (POWER8)"
help
Target version 2.07B of the Power ISA (POWER8) or later
config POWER_ISA_3_00
bool "Power ISA 3.00 (POWER9)"
help
Target version 3.00 of the Power ISA (POWER9) or later
endchoice
endmenu
source "common/Kconfig"
source "drivers/Kconfig"
View File
Whitespace-only changes.
+16
View File
@@ -0,0 +1,16 @@
obj-$(CONFIG_PPC64) += ppc64/
$(TARGET): $(TARGET)-syms
cp -f $< $@
$(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds
$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds -N $< $(build_id_linker) -o $@
$(NM) -pa --format=sysv $@ \
| $(objtree)/tools/symbols --all-symbols --xensyms --sysv --sort \
> $@.map
$(obj)/xen.lds: $(src)/xen.lds.S FORCE
$(call if_changed_dep,cpp_lds_S)
.PHONY: include
include:
View File
Whitespace-only changes.
+12
View File
@@ -0,0 +1,12 @@
########################################
# Power-specific definitions
ppc-march-$(CONFIG_POWER_ISA_2_07B) := power8
ppc-march-$(CONFIG_POWER_ISA_3_00) := power9
CFLAGS += -m64 -mlittle-endian -mcpu=$(ppc-march-y)
CFLAGS += -mstrict-align -mcmodel=large -mabi=elfv2 -mno-altivec -mno-vsx
# TODO: Drop override when more of the build is working
override ALL_OBJS-y = arch/$(TARGET_ARCH)/built_in.o
override ALL_LIBS-y =
+13
View File
@@ -0,0 +1,13 @@
# CONFIG_SCHED_CREDIT is not set
# CONFIG_SCHED_RTDS is not set
# CONFIG_SCHED_NULL is not set
# CONFIG_SCHED_ARINC653 is not set
# CONFIG_TRACEBUFFER is not set
# CONFIG_HYPFS is not set
# CONFIG_GRANT_TABLE is not set
# CONFIG_SPECULATIVE_HARDEN_ARRAY is not set
CONFIG_PPC64=y
CONFIG_DEBUG=y
CONFIG_DEBUG_INFO=y
CONFIG_EXPERT=y
+63
View File
@@ -0,0 +1,63 @@
#ifndef __PPC_CONFIG_H__
#define __PPC_CONFIG_H__
#include <xen/const.h>
#include <xen/page-size.h>
#if defined(CONFIG_PPC64)
#define LONG_BYTEORDER 3
#define ELFSIZE 64
#define MAX_VIRT_CPUS 1024u
#else
#error "Unsupported PowerPC variant"
#endif
#define BYTES_PER_LONG (1 << LONG_BYTEORDER)
#define BITS_PER_LONG (BYTES_PER_LONG << 3)
#define POINTER_ALIGN BYTES_PER_LONG
#define BITS_PER_LLONG 64
/* xen_ulong_t is always 64 bits */
#define BITS_PER_XEN_ULONG 64
#define CONFIG_PPC_L1_CACHE_SHIFT 7
#define CONFIG_PAGEALLOC_MAX_ORDER 18
#define CONFIG_DOMU_MAX_ORDER 9
#define CONFIG_HWDOM_MAX_ORDER 10
#define OPT_CONSOLE_STR "dtuart"
#define INVALID_VCPU_ID MAX_VIRT_CPUS
/* Linkage for PPC */
#ifdef __ASSEMBLY__
#define ALIGN .p2align 2
#define ENTRY(name) \
.globl name; \
ALIGN; \
name:
#endif
#define XEN_VIRT_START _AT(UL, 0x400000)
#define SMP_CACHE_BYTES (1 << 6)
#define STACK_ORDER 2
#define STACK_SIZE (PAGE_SIZE << STACK_ORDER)
/* 288 bytes below the stack pointer must be preserved by interrupt handlers */
#define STACK_VOLATILE_AREA 288
/* size of minimum stack frame; C code can write into the caller's stack */
#define STACK_FRAME_OVERHEAD 32
#endif /* __PPC_CONFIG_H__ */
/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/
+7
View File
@@ -0,0 +1,7 @@
#ifndef __PPC_PAGE_BITS_H__
#define __PPC_PAGE_BITS_H__
#define PAGE_SHIFT 16 /* 64 KiB Pages */
#define PADDR_BITS 48
#endif /* __PPC_PAGE_BITS_H__ */
+1
View File
@@ -0,0 +1 @@
obj-y += head.o
View File
Whitespace-only changes.
+30
View File
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
.section .text.header, "ax", %progbits
ENTRY(start)
/*
* Depending on how we were booted, the CPU could be running in either
* Little Endian or Big Endian mode. The following trampoline from Linux
* cleverly uses an instruction that encodes to a NOP if the CPU's
* endianness matches the assumption of the assembler (LE, in our case)
* or a branch to code that performs the endian switch in the other case.
*/
tdi 0, 0, 0x48 /* Reverse endian of b . + 8 */
b . + 44 /* Skip trampoline if endian is good */
.long 0xa600607d /* mfmsr r11 */
.long 0x01006b69 /* xori r11,r11,1 */
.long 0x00004039 /* li r10,0 */
.long 0x6401417d /* mtmsrd r10,1 */
.long 0x05009f42 /* bcl 20,31,$+4 */
.long 0xa602487d /* mflr r10 */
.long 0x14004a39 /* addi r10,r10,20 */
.long 0xa6035a7d /* mtsrr0 r10 */
.long 0xa6037b7d /* mtsrr1 r11 */
.long 0x2400004c /* rfid */
/* Now that the endianness is confirmed, continue */
1: b 1b
.size start, . - start
.type start, %function
+188
View File
@@ -0,0 +1,188 @@
#include <xen/lib.h>
#include <xen/xen.lds.h>
#undef ENTRY
#undef ALIGN
OUTPUT_ARCH(powerpc:common64)
ENTRY(start)
PHDRS
{
text PT_LOAD ;
#if defined(BUILD_ID)
note PT_NOTE ;
#endif
}
/**
* OpenFirmware's base load address is 0x400000 (XEN_VIRT_START).
* By defining sections this way, we can keep our virtual address base at 0x400000
* while keeping the physical base at 0x0.
*
* Otherwise, OpenFirmware incorrectly loads .text at 0x400000 + 0x400000 = 0x800000.
* Taken from x86/xen.lds.S
*/
#ifdef CONFIG_LD_IS_GNU
# define DECL_SECTION(x) x : AT(ADDR(#x) - XEN_VIRT_START)
#else
# define DECL_SECTION(x) x : AT(ADDR(x) - XEN_VIRT_START)
#endif
SECTIONS
{
. = XEN_VIRT_START;
DECL_SECTION(.text) {
_stext = .; /* Text section */
*(.text.header)
*(.text.cold)
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text)
#ifdef CONFIG_CC_SPLIT_SECTIONS
*(.text.*)
#endif
*(.fixup)
*(.gnu.warning)
. = ALIGN(POINTER_ALIGN);
_etext = .; /* End of text section */
} :text
. = ALIGN(PAGE_SIZE);
DECL_SECTION(.rodata) {
_srodata = .; /* Read-only data */
*(.rodata)
*(.rodata.*)
*(.data.rel.ro)
*(.data.rel.ro.*)
VPCI_ARRAY
. = ALIGN(POINTER_ALIGN);
_erodata = .; /* End of read-only data */
} :text
#if defined(BUILD_ID)
. = ALIGN(4);
DECL_SECTION(.note.gnu.build-id) {
__note_gnu_build_id_start = .;
*(.note.gnu.build-id)
__note_gnu_build_id_end = .;
} :note :text
#endif
_erodata = .; /* End of read-only data */
. = ALIGN(PAGE_SIZE);
DECL_SECTION(.data.ro_after_init) {
__ro_after_init_start = .;
*(.data.ro_after_init)
. = ALIGN(PAGE_SIZE);
__ro_after_init_end = .;
} : text
DECL_SECTION(.data.read_mostly) {
*(.data.read_mostly)
} :text
. = ALIGN(PAGE_SIZE);
DECL_SECTION(.data) { /* Data */
*(.data.page_aligned)
. = ALIGN(8);
__start_schedulers_array = .;
*(.data.schedulers)
__end_schedulers_array = .;
HYPFS_PARAM
*(.data .data.*)
CONSTRUCTORS
} :text
. = ALIGN(PAGE_SIZE); /* Init code and data */
__init_begin = .;
DECL_SECTION(.init.text) {
_sinittext = .;
*(.init.text)
_einittext = .;
. = ALIGN(PAGE_SIZE); /* Avoid mapping alt insns executable */
} :text
. = ALIGN(PAGE_SIZE);
DECL_SECTION(.init.data) {
*(.init.rodata)
*(.init.rodata.*)
. = ALIGN(POINTER_ALIGN);
__setup_start = .;
*(.init.setup)
__setup_end = .;
__initcall_start = .;
*(.initcallpresmp.init)
__presmp_initcall_end = .;
*(.initcall1.init)
__initcall_end = .;
LOCK_PROFILE_DATA
*(.init.data)
*(.init.data.rel)
*(.init.data.rel.*)
. = ALIGN(8);
__ctors_start = .;
*(.ctors)
*(.init_array)
*(SORT(.init_array.*))
__ctors_end = .;
} :text
DECL_SECTION(.got) {
*(.got)
} :text
DECL_SECTION(.got.plt) {
*(.got.plt)
} :text
. = ALIGN(POINTER_ALIGN);
__init_end = .;
DECL_SECTION(.bss) { /* BSS */
__bss_start = .;
*(.bss.stack_aligned)
*(.bss.page_aligned)
. = ALIGN(PAGE_SIZE);
__per_cpu_start = .;
*(.bss.percpu.page_aligned)
*(.bss.percpu)
. = ALIGN(SMP_CACHE_BYTES);
*(.bss.percpu.read_mostly)
. = ALIGN(SMP_CACHE_BYTES);
__per_cpu_data_end = .;
*(.bss .bss.*)
. = ALIGN(POINTER_ALIGN);
__bss_end = .;
} :text
_end = . ;
/* Section for the device tree blob (if any). */
DECL_SECTION(.dtb) { *(.dtb) } :text
DWARF2_DEBUG_SECTIONS
DISCARD_SECTIONS
STABS_DEBUG_SECTIONS
ELF_DETAILS_SECTIONS
}
ASSERT(IS_ALIGNED(__bss_start, POINTER_ALIGN), "__bss_start is misaligned")
ASSERT(IS_ALIGNED(__bss_end, POINTER_ALIGN), "__bss_end is misaligned")
ASSERT(!SIZEOF(.got), ".got non-empty")
ASSERT(!SIZEOF(.got.plt), ".got.plt non-empty")
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.