[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 |