diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2011-11-24 09:50:47 +0000 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2011-11-24 09:50:47 +0000 |
commit | 82c93c03db55158406330609d6365df68c5905d2 (patch) | |
tree | 28491e79cf0c55a82aca3010db96c2802566d290 | |
parent | e4682d17a2b3b2171dd87b594da534bc1b097b01 (diff) | |
parent | 4d3654275c8953a9695734c6ff5d0629c040c72c (diff) |
Merge branch 'master' into kvm-smpmarc-kvm-smp
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | boot.S | 61 | ||||
-rw-r--r-- | model.lds.S | 41 | ||||
-rw-r--r-- | monitor.S | 86 |
5 files changed, 183 insertions, 29 deletions
@@ -1,3 +1,6 @@ filesystem.cpio.gz linux-system.axf uImage +model.lds +*.o +*.swp @@ -6,7 +6,7 @@ # found in the LICENSE.txt file. CPPFLAGS += -DSMP -CPPFLAGS += -DUSE_INITRD +#CPPFLAGS += -DUSE_INITRD #CPPFLAGS += -DTHUMB2_KERNEL CPPFLAGS += -march=armv7-a CPPFLAGS += -DVEXPRESS @@ -16,14 +16,16 @@ CPPFLAGS += -DVEXPRESS #CPPFLAGS += -march=armv7-m #CPPFLAGS += -mthumb -Wa,-mthumb -Wa,-mimplicit-it=always +MONITOR = monitor.S BOOTLOADER = boot.S +KERNEL_SRC = ../linux-kvm-arm KERNEL = uImage FILESYSTEM = filesystem.cpio.gz IMAGE = linux-system.axf LD_SCRIPT = model.lds.S -CROSS_COMPILE = arm-none-linux-gnueabi- +CROSS_COMPILE ?= arm-unknown-eabi- CC = $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)ld @@ -31,13 +33,22 @@ LD = $(CROSS_COMPILE)ld all: $(IMAGE) clean: - rm -f $(IMAGE) boot.o model.lds + rm -f $(IMAGE) boot.o model.lds monitor.o uImage -$(IMAGE): boot.o model.lds $(KERNEL) $(FILESYSTEM) +$(KERNEL): ../linux-kvm-arm/arch/arm/boot/zImage + cd $(KERNEL_SRC); make -j4 uImage + cp $(KERNEL_SRC)/arch/arm/boot/uImage $(KERNEL) + +$(IMAGE): boot.o monitor.o model.lds $(KERNEL) $(FILESYSTEM) Makefile $(LD) -o $@ --script=model.lds boot.o: $(BOOTLOADER) $(CC) $(CPPFLAGS) -c -o $@ $< -model.lds: $(LD_SCRIPT) +monitor.o: $(MONITOR) + $(CC) $(CPPFLAGS) -c -o $@ $< + +model.lds: $(LD_SCRIPT) Makefile $(CC) $(CPPFLAGS) -E -P -C -o $@ $< + +.PHONY: all clean @@ -8,6 +8,7 @@ */ .syntax unified + .arch_extension sec .text .globl _start @@ -28,6 +29,45 @@ _start: @ @ CPU initialisation @ + mrc p15, 0, r4, c0, c0, 5 @ MPIDR (ARMv7 only) + and r4, r4, #15 @ CPU number + + @ + @ Hypervisor / TrustZone initialization + @ + + @ Set all interrupts to be non-secure + ldr r0, =0x2c001000 @ Dist GIC base + ldr r1, [r0, #0x04] @ Type Register + cmp r4, #0 + andeq r1, r1, #0x1f + movne r1, #0 + add r2, r0, #0x080 @ Security Register 0 + mvn r3, #0 +2: str r3, [r2] + sub r1, r1, #1 + add r2, r2, #4 @ Next security register + cmp r1, #-1 + bne 2b + + @ Set GIC priority mask bit [7] = 1 + ldr r0, =0x2c002000 @ CPU GIC base + mov r1, #0x80 + str r1, [r0, #0x4] @ GIC ICCPMR + + @ Set NSACR to allow coprocessor access from non-secure + mrc p15, 0, r0, c1, c1, 2 + ldr r1, =0x43fff + orr r0, r0, r1 + mcr p15, 0, r0, c1, c1, 2 + + @ Change to NS-mode + mov r0, #0xf0000000 + mcr p15, 0, r0, c12, c0, 1 @ Monitor vector base address + mov r7, #0xffffffff + smc #0 @ Change to NS-mode + + @ Check CPU nr again mrc p15, 0, r0, c0, c0, 5 @ MPIDR (ARMv7 only) and r0, r0, #15 @ CPU number cmp r0, #0 @ primary CPU? @@ -36,6 +76,7 @@ _start: @ @ Secondary CPUs (following the RealView SMP booting protocol) @ + ldr r1, =filesystem - 0x100 adr r2, 1f ldmia r2, {r3 - r7} @ move the code to a location @@ -56,10 +97,10 @@ _start: mov pc, r1 @ branch to the given address #endif +2: @ @ UART initialisation (38400 8N1) @ -2: #ifdef MACH_MPS ldr r0, =0x1f005000 @ UART3 base (MPS) #elif defined (VEXPRESS) @@ -103,15 +144,23 @@ atags: .long 0x54410009 #ifdef MACH_MPS .asciz "rdinit=/bin/sh console=ttyAMA3 mem=4M earlyprintk" -#elif defined(USE_INITRD) -#ifdef VEXPRESS - .asciz "console=ttyAMA0 mem=512M mem=512M@0x880000000 earlyprintk" -#else - .asciz "console=ttyAMA0 mem=256M earlyprintk" +#elif defined(VEXPRESS) + +#ifdef USE_INITRD + .asciz "console=ttyAMA0 mem=512M mem=512M@0x880000000 earlyprintk ip=192.168.27.200::192.168.27.1:255.255.255.0:angstrom:eth0:off" +#else /* VEXPRESS && !USE_INITRD */ + .asciz "console=ttyAMA0 mem=512M mem=512M@0x880000000 earlyprintk root=/dev/nfs nfsroot=192.168.27.93:/srv/nfs_root,tcp rw ip=dhcp nfsrootdebug" #endif + +#else /* ! VEXPRESS && ! MACH_MPS */ + +#ifdef USE_INITRD + .asciz "console=ttyAMA0 mem=256M earlyprintk" #else .asciz "root=/dev/nfs nfsroot=10.1.77.43:/work/debootstrap/arm ip=dhcp console=ttyAMA0 mem=256M earlyprintk" #endif + +#endif .align 2 1: diff --git a/model.lds.S b/model.lds.S index 816c338..4769480 100644 --- a/model.lds.S +++ b/model.lds.S @@ -11,36 +11,41 @@ OUTPUT_FORMAT("elf32-littlearm") OUTPUT_ARCH(arm) TARGET(binary) +INPUT(./monitor.o) INPUT(./boot.o) INPUT(./uImage) #ifdef USE_INITRD -INPUT(./filesystem.cpio.gz) + INPUT(./filesystem.cpio.gz) #endif -#ifdef MACH_MPS -PHYS_OFFSET = 0x10000000; -#elif defined (VEXPRESS) + + + PHYS_OFFSET = 0x80000000; -#else -PHYS_OFFSET = 0x70000000; -#endif +MON_OFFSET = 0xf0000000; + + + SECTIONS { - . = PHYS_OFFSET; - .text : { boot.o } + . = PHYS_OFFSET; + .text : { boot.o } - . = PHYS_OFFSET + 0x8000 - 0x40; - kernel = . + 0x40; - .kernel : { ./uImage } + . = PHYS_OFFSET + 0x8000 - 0x40; + kernel = . + 0x40; + .kernel : { ./uImage } - . = PHYS_OFFSET + 0x00800000; - filesystem = .; + . = PHYS_OFFSET + 0x00800000; + filesystem = .; #ifdef USE_INITRD - .filesystem : { ./filesystem.cpio.gz } - fs_size = . - filesystem; + .filesystem : { ./filesystem.cpio.gz } + fs_size = . - filesystem; #endif - .data : { *(.data) } - .bss : { *(.bss) } + .data : { *(.data) } + .bss : { *(.bss) } + + . = MON_OFFSET; + .monitor : { monitor.o } } diff --git a/monitor.S b/monitor.S new file mode 100644 index 0000000..052ab1e --- /dev/null +++ b/monitor.S @@ -0,0 +1,86 @@ +/* + * monitor.S - simple monitor code to switch to NS state before executing kernel + * + * Copyright (C) 2011 Columbia University. All rights reserved. + * Christoffer Dall <cdall@cs.columbia.edu> + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE.txt file. + */ + +#.syntax unified + .section monitor, "x" + + .word 0 + .word 0 + b 1f + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + + @ + @ Secure Monitor Call + @ +1: + ldr sp, =_monitor_stack + push {r11, r12} + + cmp r7, #0xffffffff + beq _non_sec + + @ Check smc number and VMID + bic r12, r7, #0xf + cmp r12, #0xfffffff0 + movnes pc, lr + and r12, r7, #0xf + cmp r12, #0x0 + popgt {r11, r12} + movgts pc, lr + + @ Check the VMID is 0 + mrrc p15, 6, r12, r11, c2 + lsr r11, r11, #16 + and r11, r11, #0xff + cmp r11, #0 + popne {r11, r12} + movnes pc, lr + + @ Jump to the right function + and r12, r7, #0xf + adr r11, _hyp_funcs + add r11, r11, r12, lsl #2 + ldr pc, [r11] + + @ + @ Jump table for the SMC hypervisor API calls + @ +_hyp_funcs: + .long _write_hvbar + + @ + @ Switch to non-secure mode + @ +_non_sec: + mrc p15, 0, r12, c1, c1, 0 @ Secure configuration register + bic r12, r12, #0x07f + ldr r11, =0x131 + orr r12, r12, r11 + mcr p15, 0, r12, c1, c1, 0 + pop {r11, r12} + movs pc, lr + + @ + @ Read/Write HVBAR + @ +_write_hvbar: + mcr p15, 4, r0, c12, c0, 0 + pop {r11, r12} + movs pc, lr + + .ltorg + + /* A bit of stack space for monitor mode */ + .align 12 +_monitor_stack: |