|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 06/45] xen: arm64: initial build + config changes, start of day code
At 15:56 +0000 on 23 Jan (1358956572), Ian Campbell wrote:
> diff --git a/config/arm64.mk b/config/arm64.mk
> new file mode 100644
> index 0000000..b2457eb
> --- /dev/null
> +++ b/config/arm64.mk
> @@ -0,0 +1,12 @@
> +CONFIG_ARM := y
> +CONFIG_ARM_64 := y
> +CONFIG_ARM_$(XEN_OS) := y
> +
> +CFLAGS += #-marm -march= -mcpu= etc
> +
> +HAS_PL011 := y
> +
> +# Use only if calling $(LD) directly.
> +LDFLAGS_DIRECT += -maarch64elf
> +
> +CONFIG_LOAD_ADDRESS ?= 0x80000000
> diff --git a/xen/arch/arm/Rules.mk b/xen/arch/arm/Rules.mk
> index f83bfee..2250366 100644
> --- a/xen/arch/arm/Rules.mk
> +++ b/xen/arch/arm/Rules.mk
> @@ -25,6 +25,12 @@ arm32 := y
> arm64 := n
> endif
>
> +ifeq ($(TARGET_SUBARCH),arm64)
> +CFLAGS += -mcpu=generic
Should this go in config/arm64.mk? I realise the equivalent flags for
arm32 are in this file, just wondering if we ought to tidy them all into
config/.
> --- /dev/null
> +++ b/xen/arch/arm/arm64/head.S
> @@ -0,0 +1,405 @@
> +/*
> + * xen/arch/arm/head.S
> + *
> + * Start-of-day code for an ARMv8.
> + *
> + * Ian Campbell <ian.campbell@xxxxxxxxxx>
> + * Copyright (c) 2012 Citrix Systems.
> + *
> + * Based on ARMv7-A head.S by
> + * Tim Deegan <tim@xxxxxxx>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <asm/config.h>
> +#include <asm/page.h>
> +#include <asm/asm_defns.h>
> +
> +#define PT_PT 0xe7f /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=111 T=1 P=1 */
> +#define PT_MEM 0xe7d /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=111 T=0 P=1 */
> +#define PT_DEV 0xe71 /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=100 T=0 P=1 */
> +#define PT_DEV_L3 0xe73 /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=100 T=1 P=1 */
> +
> +/* Macro to print a string to the UART, if there is one.
> + * Clobbers r0-r3. */
> +#ifdef EARLY_UART_ADDRESS
> +#define PRINT(_s) \
> + adr x0, 98f ; \
> + bl puts ; \
> + b 99f ; \
> +98: .asciz _s ; \
> + .align 2 ; \
Backslashes are misaligned here; I suspect because of hard tabs.
> +99:
> +#else
> +#define PRINT(s)
> +#endif
> +
> + /*.aarch64*/
> +
> + /*
> + * Kernel startup entry point.
> + * ---------------------------
> + *
> + * The requirements are:
> + * MMU = off, D-cache = off, I-cache = on or off,
> + * x0 = physical address to the FDT blob.
> + *
> + * This must be the very first address in the loaded image.
> + * It should be linked at XEN_VIRT_START, and loaded at any
> + * 2MB-aligned address. All of text+data+bss must fit in 2MB,
> + * or the initial pagetable code below will need adjustment.
> + */
> +
> + .global start
> +start:
> + /*
> + * DO NOT MODIFY. Image header expected by Linux boot-loaders.
> + */
> + b real_start /* branch to kernel start, magic */
> + .long 0 /* reserved */
> + .quad 0 /* Image load offset from start of RAM
> */
> + .quad 0 /* reserved */
> + .quad 0 /* reserved */
> +
> +real_start:
> + msr DAIFSet, 0xf /* Disable all interrupts */
These are hard tabs; the data block just above uses spaces.
> +/*
> + * Exception Levels
> + */
> +#define EL0t 0x00000000
> +#define EL1t 0x00000004
> +#define EL1h 0x00000005
> +#define EL2t 0x00000008
> +#define EL2h 0x00000009
> +#define EL3t 0x0000000c
> +#define EL3h 0x0000000d
Do these belong in a header somewhere? If not maybe they can go at the
top of this file with the PT_ macros.
> +boot_cpu:
> +#ifdef EARLY_UART_ADDRESS
> + ldr x23, =EARLY_UART_ADDRESS /* x23 := UART base address */
> + cbnz x22, 1f
> + bl init_uart /* CPU 0 sets up the UART too */
> +1: PRINT("- CPU ")
> + mov x0, x22
> + bl putn
> + PRINT(" booting -\r\n")
> +#endif
> +
> + PRINT("- Current EL ")
> + mrs x0, CurrentEL
> + bl putn
> + PRINT(" -\r\n")
> +
> + /* Are we in EL3 */
> + mrs x0, CurrentEL
> + cmp x0, #EL3t
> + ccmp x0, #EL3h, #0x4, ne
> + b.eq 1f /* Yes */
> +
> + /* Are we in EL2 */
> + cmp x0, #EL2t
> + ccmp x0, #EL2h, #0x4, ne
> + b.eq 2f /* Yes */
> +
> + /* Otherwise, it must have been EL0 or EL1 */
> + PRINT("- CPU is not in EL3 or EL2 -\r\n")
> + b fail
> +
> +1: PRINT("- Started in EL3 -\r\n- Entering EL2 -\r\n")
> + ldr x1, =enter_el2_mode /* VA of function */
> + add x1, x1, x20 /* PA of function */
> + adr x30, hyp /* Set return address for call */
> + br x1 /* Call function */
> +
> +2: PRINT("- Started in Hyp mode -\r\n")
Some confusion here between 'EL2' and 'Hyp' -- are they the same thing?
Should we use 'el2' consistently?
> + PRINT("- Ready -\r\n")
> +
> + /* The boot CPU should go straight into C now */
> + cbz x22, launch
> +
> + /* Non-boot CPUs need to move on to the relocated pagetables */
> + //mov x0, #0
Should be removed?
> --- /dev/null
> +++ b/xen/arch/arm/arm64/mode_switch.S
> @@ -0,0 +1,83 @@
> +/*
> + * xen/arch/arm/arm64/mode_switch.S
> + *
> + * Start-of day code to take a CPU from EL3 to EL2. Largely taken from
> + bootwrapper.
^ missing '*'
> +.globl enter_el2_mode
> +enter_el2_mode:
> + mov x0, #0x30 // RES1
> + orr x0, x0, #(1 << 0) // Non-secure EL1
> + orr x0, x0, #(1 << 8) // HVC enable
> + orr x0, x0, #(1 << 10) // 64-bit EL2
Is this any better than ldr'ing a magic constant?
> + msr scr_el3, x0
> +
> + msr cptr_el3, xzr // Disable copro. traps to
> EL3
> +
> + ldr x0, =0x01800000 // 24Mhz
> + msr cntfrq_el0, x0
> +
> + /*
> + * Check for the primary CPU to avoid a race on the distributor
> + * registers.
> + */
> + cbnz x22, 1f
Hard tab.
> +
> + ldr x1, =(GIC_BASE_ADDRESS+GIC_DR_OFFSET) // GICD_CTLR
> + mov w0, #3 // EnableGrp0 | EnableGrp1
> + str w0, [x1]
> +
> +1: ldr x1, =(GIC_BASE_ADDRESS+GIC_DR_OFFSET+0x80) // GICD_IGROUPR
Can we use the gic.h constants here? I gues the '/4' everywhere makes
it ugly.
> + mov w0, #~0 // Grp1 interrupts
> + str w0, [x1], #4
> + b.ne 2f // Only local interrupts for
> secondary CPUs
Linewrap
> + str w0, [x1], #4
> + str w0, [x1], #4
> +
> +2: ldr x1, =(GIC_BASE_ADDRESS+GIC_CR_OFFSET) // GICC_CTLR
THis can be a '1:', I think.
> + ldr w0, [x1]
> + mov w0, #3 // EnableGrp0 | EnableGrp1
> + str w0, [x1]
> +
> + mov w0, #1 << 7 // allow NS access to
> GICC_PMR
> + str w0, [x1, #4] // GICC_PMR
> +
> + msr sctlr_el2, xzr
> +
> + /*
> + * Prepare the switch to the EL2_SP1 mode from EL3
> + */
> + msr elr_el3, x30 // Return to desired function
Are you passing an argument in x30? Or is x30 the link register?
> + mov x1, #0x3c9 // EL2_SP1 | D | A | I | F
> + msr spsr_el3, x1
> + eret
Maybe add an emacs block here?
Tim.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |