Message ID | 3176762c2eb09d01d65a348e296a94cf0356ff46.1690934409.git.sanastasio@raptorengineering.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | xen/ppc: Add PowerNV bare metal support | expand |
On 02.08.2023 02:11, Shawn Anastasio wrote: > Implement the OPAL firmware calls required to write to the serial > console on PowerNV systems. Unlike pseries/Open Firmware, the OPAL > firmware interface can be used past early boot and as such the relevant > functions are not marked as __init. > > Signed-off-by: Shawn Anastasio <sanastasio@raptorengineering.com> Constraint as before and with two nits Acked-by: Jan Beulich <jbeulich@suse.com> > @@ -20,8 +22,20 @@ > * Load the address of a symbol from the TOC into the specified GPR. > */ > #define LOAD_REG_ADDR(reg,name) \ > - addis reg,%r2,name@toc@ha; \ > - addi reg,reg,name@toc@l > + addis reg, %r2, name@toc@ha; \ > + addi reg, reg, name@toc@l > + > +/* > + * Declare a global assembly function with a proper TOC setup prologue > + */ > +#define _GLOBAL_TOC(name) \ > + .balign 4; \ > + .type name, @function; \ > + .globl name; \ > +name: \ > +0: addis %r2, %r12, (.TOC.-0b)@ha; \ > + addi %r2, %r2, (.TOC.-0b)@l; \ Strictly speaking the - want surrounding by blanks, but I wonder whether to PPC eyes these constructs look more natural without. Please clarify. > --- /dev/null > +++ b/xen/arch/ppc/ppc64/opal-calls.S > @@ -0,0 +1,81 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* > + * Adapted from Linux's arch/powerpc/boot/opal-calls.S > + * > + * Copyright (c) 2016 IBM Corporation. > + * Copyright Raptor Engineering, LLC > + */ > + > +#include <asm/asm-defns.h> > +#include <asm/opal-api.h> > +#include <asm/msr.h> > + > + .text > + > +#define OPAL_CALL(name, token) \ > + .globl name; \ > +name: \ > + li %r0, token; \ > + b opal_call > + > + _GLOBAL_TOC(opal_call) Any reason for the leading blank here? Where necessary I again think these small items can be taken care of while committing. Jan
On 8/7/23 10:05 AM, Jan Beulich wrote: > On 02.08.2023 02:11, Shawn Anastasio wrote: >> Implement the OPAL firmware calls required to write to the serial >> console on PowerNV systems. Unlike pseries/Open Firmware, the OPAL >> firmware interface can be used past early boot and as such the relevant >> functions are not marked as __init. >> >> Signed-off-by: Shawn Anastasio <sanastasio@raptorengineering.com> > > Constraint as before and with two nits > Acked-by: Jan Beulich <jbeulich@suse.com> > >> @@ -20,8 +22,20 @@ >> * Load the address of a symbol from the TOC into the specified GPR. >> */ >> #define LOAD_REG_ADDR(reg,name) \ >> - addis reg,%r2,name@toc@ha; \ >> - addi reg,reg,name@toc@l >> + addis reg, %r2, name@toc@ha; \ >> + addi reg, reg, name@toc@l >> + >> +/* >> + * Declare a global assembly function with a proper TOC setup prologue >> + */ >> +#define _GLOBAL_TOC(name) \ >> + .balign 4; \ >> + .type name, @function; \ >> + .globl name; \ >> +name: \ >> +0: addis %r2, %r12, (.TOC.-0b)@ha; \ >> + addi %r2, %r2, (.TOC.-0b)@l; \ > > Strictly speaking the - want surrounding by blanks, but I wonder whether > to PPC eyes these constructs look more natural without. Please clarify. This is admittedly very subjective, but to my eyes the code as-is looks perfectly natural. That said, I wouldn't be opposed to adding spaces if that's what you prefer. >> --- /dev/null >> +++ b/xen/arch/ppc/ppc64/opal-calls.S >> @@ -0,0 +1,81 @@ >> +/* SPDX-License-Identifier: GPL-2.0-or-later */ >> +/* >> + * Adapted from Linux's arch/powerpc/boot/opal-calls.S >> + * >> + * Copyright (c) 2016 IBM Corporation. >> + * Copyright Raptor Engineering, LLC >> + */ >> + >> +#include <asm/asm-defns.h> >> +#include <asm/opal-api.h> >> +#include <asm/msr.h> >> + >> + .text >> + >> +#define OPAL_CALL(name, token) \ >> + .globl name; \ >> +name: \ >> + li %r0, token; \ >> + b opal_call >> + >> + _GLOBAL_TOC(opal_call) > > Any reason for the leading blank here? No -- that was a mistake on my part. > > Where necessary I again think these small items can be taken care of > while committing. Sounds good. > Jan Thanks, Shawn
diff --git a/xen/arch/ppc/include/asm/asm-defns.h b/xen/arch/ppc/include/asm/asm-defns.h index 5821f9024d..f1c49808bd 100644 --- a/xen/arch/ppc/include/asm/asm-defns.h +++ b/xen/arch/ppc/include/asm/asm-defns.h @@ -2,6 +2,8 @@ #ifndef _ASM_PPC_ASM_DEFNS_H #define _ASM_PPC_ASM_DEFNS_H +#include <asm/asm-offsets.h> + /* * Load a 64-bit immediate value into the specified GPR. */ @@ -20,8 +22,20 @@ * Load the address of a symbol from the TOC into the specified GPR. */ #define LOAD_REG_ADDR(reg,name) \ - addis reg,%r2,name@toc@ha; \ - addi reg,reg,name@toc@l + addis reg, %r2, name@toc@ha; \ + addi reg, reg, name@toc@l + +/* + * Declare a global assembly function with a proper TOC setup prologue + */ +#define _GLOBAL_TOC(name) \ + .balign 4; \ + .type name, @function; \ + .globl name; \ +name: \ +0: addis %r2, %r12, (.TOC.-0b)@ha; \ + addi %r2, %r2, (.TOC.-0b)@l; \ + .localentry name, .-name /* * Depending on how we were booted, the CPU could be running in either diff --git a/xen/arch/ppc/opal.c b/xen/arch/ppc/opal.c index 251de8ac23..1183b7d5ef 100644 --- a/xen/arch/ppc/opal.c +++ b/xen/arch/ppc/opal.c @@ -8,9 +8,29 @@ #include <xen/init.h> #include <xen/lib.h> -/* Global OPAL struct containing entrypoint and base */ +/* Global OPAL struct containing entrypoint and base used by opal-calls.S */ struct opal opal; +int64_t opal_console_write(int64_t term_number, uint64_t *length, + const void *buffer); +int64_t opal_console_flush(int64_t term_number); +int64_t opal_reinit_cpus(uint64_t flags); + +static void opal_putchar(char c) +{ + uint64_t len; + + if ( c == '\n' ) + { + char buf = '\r'; + len = cpu_to_be64(1); + opal_console_write(0, &len, &buf); + } + len = cpu_to_be64(1); + opal_console_write(0, &len, &c); + opal_console_flush(0); +} + void __init boot_opal_init(const void *fdt) { int opal_node; @@ -45,4 +65,10 @@ void __init boot_opal_init(const void *fdt) opal.base = be64_to_cpu(*opal_base); opal.entry = be64_to_cpu(*opal_entry); + + early_printk_init(opal_putchar); + + /* Ask OPAL to set HID0 for Little Endian interrupts + Radix TLB support */ + opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_LE | OPAL_REINIT_CPUS_MMU_RADIX | + OPAL_REINIT_CPUS_MMU_HASH); } diff --git a/xen/arch/ppc/ppc64/Makefile b/xen/arch/ppc/ppc64/Makefile index f4956daaa9..b9a91dc15f 100644 --- a/xen/arch/ppc/ppc64/Makefile +++ b/xen/arch/ppc/ppc64/Makefile @@ -1,2 +1,3 @@ obj-y += head.o obj-y += of-call.o +obj-y += opal-calls.o diff --git a/xen/arch/ppc/ppc64/asm-offsets.c b/xen/arch/ppc/ppc64/asm-offsets.c index e1129cb0f4..c15c1bf136 100644 --- a/xen/arch/ppc/ppc64/asm-offsets.c +++ b/xen/arch/ppc/ppc64/asm-offsets.c @@ -6,6 +6,7 @@ #include <xen/macros.h> #include <asm/processor.h> +#include <asm/boot.h> #define DEFINE(_sym, _val) \ asm volatile ( "\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \ @@ -46,6 +47,9 @@ void __dummy__(void) OFFSET(UREGS_cr, struct cpu_user_regs, cr); OFFSET(UREGS_fpscr, struct cpu_user_regs, fpscr); DEFINE(UREGS_sizeof, sizeof(struct cpu_user_regs)); + + OFFSET(OPAL_base, struct opal, base); + OFFSET(OPAL_entry, struct opal, entry); } /* diff --git a/xen/arch/ppc/ppc64/opal-calls.S b/xen/arch/ppc/ppc64/opal-calls.S new file mode 100644 index 0000000000..cc5de75c8a --- /dev/null +++ b/xen/arch/ppc/ppc64/opal-calls.S @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Adapted from Linux's arch/powerpc/boot/opal-calls.S + * + * Copyright (c) 2016 IBM Corporation. + * Copyright Raptor Engineering, LLC + */ + +#include <asm/asm-defns.h> +#include <asm/opal-api.h> +#include <asm/msr.h> + + .text + +#define OPAL_CALL(name, token) \ + .globl name; \ +name: \ + li %r0, token; \ + b opal_call + + _GLOBAL_TOC(opal_call) + /* Back up LR, CR, r2 in caller's stack frame */ + mflr %r11 + mfcr %r12 + std %r2, 24(%r1) + std %r11, 16(%r1) + stw %r12, 8(%r1) + + /* Use r14 (non-volatile) to store the virtual address of opal_return_mmu */ + std %r14, -8(%r1) + stdu %r1, -48(%r1) + LOAD_REG_ADDR(%r14, opal_return_mmu) + + /* + * Setup new MSR without LE or MMU. Original MSR will be preserved across + * opal call in r13 + */ + mfmsr %r13 + li %r11, MSR_LE | MSR_IR | MSR_DR + andc %r12, %r13, %r11 + mthsrr1 %r12 + + LOAD_REG_ADDR(%r11, opal_return_real) + mtlr %r11 + + /* Load the opal call entry point and base */ + LOAD_REG_ADDR(%r11, opal) + ld %r12, OPAL_entry(%r11) + ld %r2, OPAL_base(%r11) + mthsrr0 %r12 + hrfid + +opal_return_real: + /* + * OPAL will always return to us in Big Endian mode. Since we are going + * to restore the old MSR with the correct endianness and MMU status set, we + * can avoid an unnecessary FIXUP_ENDIAN trampoline by just encoding the + * required Big Endian instructions to restore the old MSR direclty. + */ + .long 0xa64bbb7d /* mthsrr1 %r13 (Old MSR) */ + .long 0xa64bda7d /* mthsrr0 %r14 (Virtual address of opal_return_mmu) */ + .long 0x2402004c /* hrfid */ + +opal_return_mmu: + /* + * We're back in the correct endianness and MMU mode, restore registers + * and return + */ + addi %r1, %r1, 48 + ld %r14, -8(%r1) + lwz %r11, 8(%r1) + ld %r12, 16(%r1) + ld %r2, 24(%r1) + mtcr %r11 + mtlr %r12 + + blr + +OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE) +OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH) +OPAL_CALL(opal_reinit_cpus, OPAL_REINIT_CPUS)
Implement the OPAL firmware calls required to write to the serial console on PowerNV systems. Unlike pseries/Open Firmware, the OPAL firmware interface can be used past early boot and as such the relevant functions are not marked as __init. Signed-off-by: Shawn Anastasio <sanastasio@raptorengineering.com> --- Changed in v2: - Include asm-offsets in asm-defns.h - Clean up assembly formatting in asm-defns.h - Clean up formatting of opal.c - Clean up stray semicolon in OPAL_CALL macro in opal-calls.S xen/arch/ppc/include/asm/asm-defns.h | 18 ++++++- xen/arch/ppc/opal.c | 28 +++++++++- xen/arch/ppc/ppc64/Makefile | 1 + xen/arch/ppc/ppc64/asm-offsets.c | 4 ++ xen/arch/ppc/ppc64/opal-calls.S | 81 ++++++++++++++++++++++++++++ 5 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 xen/arch/ppc/ppc64/opal-calls.S -- 2.30.2