mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/ppc: Parse device tree for OPAL node on PowerNV
Communication with firmware boot services on PowerNV requires parsing the fdt blob passed by the bootloader in order to obtain the firmware entrypoint. Use Xen's libfdt to do this and store the information required for firmware calls, to be implemented in a future patch. The full xen/common build doesn't yet work, but libfdt and its xen/lib dependency can be made to build by defining a few stub headers. Signed-off-by: Shawn Anastasio <sanastasio@raptorengineering.com> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
c99f57a783
commit
6fc15ec32b
11 files changed
+121
-6
No files matched your search
@@ -1,5 +1,6 @@
|
||||
config PPC
|
||||
def_bool y
|
||||
select HAS_DEVICE_TREE
|
||||
|
||||
config PPC64
|
||||
def_bool y
|
||||
|
||||
@@ -2,6 +2,7 @@ obj-$(CONFIG_PPC64) += ppc64/
|
||||
|
||||
obj-y += boot-of.init.o
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.init.o
|
||||
obj-y += opal.o
|
||||
obj-y += setup.o
|
||||
|
||||
$(TARGET): $(TARGET)-syms
|
||||
|
||||
@@ -10,5 +10,4 @@ CFLAGS += -mstrict-align -mcmodel=medium -mabi=elfv2 -fPIC -mno-altivec -mno-vsx
|
||||
LDFLAGS += -m elf64lppc
|
||||
|
||||
# TODO: Drop override when more of the build is working
|
||||
override ALL_OBJS-y = arch/$(SRCARCH)/built_in.o
|
||||
override ALL_LIBS-y =
|
||||
override ALL_OBJS-y = arch/$(SRCARCH)/built_in.o common/libfdt/built_in.o lib/built_in.o
|
||||
@@ -4,7 +4,10 @@
|
||||
|
||||
#include <xen/types.h>
|
||||
|
||||
/* a collection of interfaces used during boot. */
|
||||
/*
|
||||
* OpenFirmware boot interfaces
|
||||
*/
|
||||
|
||||
enum {
|
||||
OF_FAILURE = -1,
|
||||
OF_SUCCESS = 0,
|
||||
@@ -20,4 +23,15 @@ struct of_service {
|
||||
int enter_of(struct of_service *args, unsigned long entry);
|
||||
void boot_of_init(unsigned long vec);
|
||||
|
||||
/*
|
||||
* OPAL boot interfaces
|
||||
*/
|
||||
|
||||
struct opal {
|
||||
uint64_t base;
|
||||
uint64_t entry;
|
||||
};
|
||||
|
||||
void boot_opal_init(const void *fdt);
|
||||
|
||||
#endif /* _ASM_PPC_BOOT_H */
|
||||
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _ASM_PPC_BUG_H
|
||||
#define _ASM_PPC_BUG_H
|
||||
|
||||
#include <xen/stringify.h>
|
||||
|
||||
/*
|
||||
* Power ISA guarantees that an instruction consisting of all zeroes is
|
||||
* illegal.
|
||||
*/
|
||||
#define BUG_OPCODE 0x00000000
|
||||
|
||||
#define BUG_INSTR ".long " __stringify(BUG_OPCODE)
|
||||
|
||||
#define BUG_FN_REG r0
|
||||
|
||||
#endif /* _ASM_PPC_BUG_H */
|
||||
@@ -0,0 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _ASM_PPC_CACHE_H
|
||||
#define _ASM_PPC_CACHE_H
|
||||
|
||||
#endif /* _ASM_PPC_CACHE_H */
|
||||
@@ -133,6 +133,17 @@ struct cpu_user_regs
|
||||
uint32_t entry_vector;
|
||||
};
|
||||
|
||||
#endif
|
||||
/*
|
||||
* panic() isn't available at the moment so an infinite loop will be
|
||||
* used temporarily.
|
||||
* TODO: change it to panic()
|
||||
*/
|
||||
static inline void noreturn die(void)
|
||||
{
|
||||
for ( ; ; )
|
||||
HMT_very_low();
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_PPC_PROCESSOR_H */
|
||||
@@ -0,0 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _ASM_PPC_STRING_H
|
||||
#define _ASM_PPC_STRING_H
|
||||
|
||||
#endif /* _ASM_PPC_STRING_H */
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _ASM_SYSTEM_H_
|
||||
#define _ASM_SYSTEM_H_
|
||||
|
||||
#define smp_wmb() __asm__ __volatile__ ( "lwsync" : : : "memory" )
|
||||
|
||||
#endif /* _ASM_SYSTEM_H */
|
||||
@@ -0,0 +1,48 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
#include <asm/boot.h>
|
||||
#include <asm/early_printk.h>
|
||||
#include <asm/opal-api.h>
|
||||
#include <asm/processor.h>
|
||||
#include <xen/types.h>
|
||||
#include <xen/libfdt/libfdt.h>
|
||||
#include <xen/init.h>
|
||||
#include <xen/lib.h>
|
||||
|
||||
/* Global OPAL struct containing entrypoint and base */
|
||||
struct opal opal;
|
||||
|
||||
void __init boot_opal_init(const void *fdt)
|
||||
{
|
||||
int opal_node;
|
||||
const __be64 *opal_base;
|
||||
const __be64 *opal_entry;
|
||||
|
||||
if ( fdt_check_header(fdt) < 0 )
|
||||
{
|
||||
/*
|
||||
* NOTE: This won't actually print since the early serial
|
||||
* console isn't set up yet.
|
||||
*/
|
||||
early_printk("Booted without valid FDT pointer in r3!\n");
|
||||
die();
|
||||
}
|
||||
|
||||
opal_node = fdt_path_offset(fdt, "/ibm,opal");
|
||||
if ( opal_node < 0 )
|
||||
{
|
||||
early_printk("Unable to find ibm,opal node!\n");
|
||||
die();
|
||||
}
|
||||
|
||||
opal_base = fdt_getprop(fdt, opal_node, "opal-base-address", NULL);
|
||||
opal_entry = fdt_getprop(fdt, opal_node, "opal-entry-address", NULL);
|
||||
if ( !opal_base || !opal_entry )
|
||||
{
|
||||
early_printk("Failed to get opal-base-address/opal-entry-address "
|
||||
"property from DT!\n");
|
||||
die();
|
||||
}
|
||||
|
||||
opal.base = be64_to_cpu(*opal_base);
|
||||
opal.entry = be64_to_cpu(*opal_entry);
|
||||
}
|
||||
@@ -18,8 +18,13 @@ void __init noreturn start_xen(unsigned long r3, unsigned long r4,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* kexec boot: Unimplemented */
|
||||
__builtin_trap();
|
||||
/*
|
||||
* kexec boot protocol
|
||||
*
|
||||
* TODO: This currently assumes an OPAL/PowerNV system, but it's also
|
||||
* possible to be kexec'd on an OF system.
|
||||
*/
|
||||
boot_opal_init((void *)r3);
|
||||
}
|
||||
|
||||
early_printk("Hello, ppc64le!\n");
|
||||
|
||||