mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/ppc: Set up a basic C environment
Update ppc64/head.S to set up an initial boot stack, zero the .bss section, and jump to C. The required setup is done using 32-bit immediate address loads for now, but they will be changed to TOC-relative loads once the position-independent code model is enabled. Additionally, move the cpu0_boot_stack declaration to setup.c and change STACK_ORDER from 2 to 0. For now, ppc64 is using 64k pages and thus the larger STACK_ORDER is unnecessary. Finally, refactor the endian fixup trampoline into its own macro, since it will need to be used in multiple places, including every time we make a call into firmware. Signed-off-by: Shawn Anastasio <sanastasio@raptorengineering.com> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
0c683baa67
commit
3a4e6f67bc
5 files changed
+79
-20
No files matched your search
@@ -1,5 +1,7 @@
|
||||
obj-$(CONFIG_PPC64) += ppc64/
|
||||
|
||||
obj-y += setup.o
|
||||
|
||||
$(TARGET): $(TARGET)-syms
|
||||
cp -f $< $@
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
#ifndef _ASM_PPC_ASM_DEFNS_H
|
||||
#define _ASM_PPC_ASM_DEFNS_H
|
||||
|
||||
/*
|
||||
* Load a 64-bit immediate value into the specified GPR.
|
||||
*/
|
||||
#define LOAD_IMM64(reg, val) \
|
||||
lis reg, (val) @highest; \
|
||||
ori reg, reg, (val) @higher; \
|
||||
rldicr reg, reg, 32, 31; \
|
||||
oris reg, reg, (val) @h; \
|
||||
ori reg, reg, (val) @l;
|
||||
|
||||
#define LOAD_IMM32(reg, val) \
|
||||
lis reg, (val) @h; \
|
||||
ori reg, reg, (val) @l; \
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#define FIXUP_ENDIAN \
|
||||
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 */
|
||||
|
||||
#endif /* _ASM_PPC_ASM_DEFNS_H */
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
#define SMP_CACHE_BYTES (1 << 6)
|
||||
|
||||
#define STACK_ORDER 2
|
||||
#define STACK_ORDER 0
|
||||
#define STACK_SIZE (PAGE_SIZE << STACK_ORDER)
|
||||
|
||||
/* 288 bytes below the stack pointer must be preserved by interrupt handlers */
|
||||
|
||||
+17
-19
@@ -1,30 +1,28 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <asm/asm-defns.h>
|
||||
|
||||
.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.
|
||||
* NOTE: argument registers (r3-r9) must be preserved until the C entrypoint
|
||||
*/
|
||||
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 */
|
||||
FIXUP_ENDIAN
|
||||
|
||||
/* Now that the endianness is confirmed, continue */
|
||||
1: b 1b
|
||||
/* set up the TOC pointer */
|
||||
LOAD_IMM32(%r2, .TOC.)
|
||||
|
||||
/* set up the initial stack */
|
||||
LOAD_IMM32(%r1, cpu0_boot_stack)
|
||||
li %r11, 0
|
||||
stdu %r11, -STACK_FRAME_OVERHEAD(%r1)
|
||||
|
||||
/* call the C entrypoint */
|
||||
bl start_xen
|
||||
|
||||
/* should never return */
|
||||
trap
|
||||
|
||||
.size start, . - start
|
||||
.type start, %function
|
||||
@@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
#include <xen/init.h>
|
||||
|
||||
/* Xen stack for bringing up the first CPU. */
|
||||
unsigned char __initdata cpu0_boot_stack[STACK_SIZE] __aligned(STACK_SIZE);
|
||||
|
||||
/* Macro to adjust thread priority for hardware multithreading */
|
||||
#define HMT_very_low() asm volatile ( "or %r31, %r31, %r31" )
|
||||
|
||||
void __init noreturn start_xen(unsigned long r3, unsigned long r4,
|
||||
unsigned long r5, unsigned long r6,
|
||||
unsigned long r7)
|
||||
{
|
||||
for ( ; ; )
|
||||
/* Set current hardware thread to very low priority */
|
||||
HMT_very_low();
|
||||
|
||||
unreachable();
|
||||
}
|
||||