summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2011-11-24 09:50:47 +0000
committerMarc Zyngier <marc.zyngier@arm.com>2011-11-24 09:50:47 +0000
commit82c93c03db55158406330609d6365df68c5905d2 (patch)
tree28491e79cf0c55a82aca3010db96c2802566d290
parente4682d17a2b3b2171dd87b594da534bc1b097b01 (diff)
parent4d3654275c8953a9695734c6ff5d0629c040c72c (diff)
Merge branch 'master' into kvm-smpmarc-kvm-smp
-rw-r--r--.gitignore3
-rw-r--r--Makefile21
-rw-r--r--boot.S61
-rw-r--r--model.lds.S41
-rw-r--r--monitor.S86
5 files changed, 183 insertions, 29 deletions
diff --git a/.gitignore b/.gitignore
index 04d0c55..05aa345 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
filesystem.cpio.gz
linux-system.axf
uImage
+model.lds
+*.o
+*.swp
diff --git a/Makefile b/Makefile
index 31443c8..6dc9912 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/boot.S b/boot.S
index 433c428..6de3721 100644
--- a/boot.S
+++ b/boot.S
@@ -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: