[RFC] bootwrapper: Add support for the TC1 and TC2 CoreTiles

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- A new output binary (board.axf) has been added exclusively for
  board usage, which uses a different linker script (board.lds.S).
- BootMonitor has already placed secondary CPUs in wfi state,
  generate a software interrupt first and point other cores to
  jump to the right location by writing the address to SYS_FLAGS.
- Make room for atags, which are populated from BootMonitor's loader,
  at memory address 0x80000100.
- Code relocation for secondary cores in wfe state, has been moved
  further back to a safer location than the initrd region.

Usage example in BootMonitor (atags passing idea by Marc Zyngier):
  - load zImageDT LOAD_ADRESS 0x80008000
  - flash linux boot board earlyprintk console=ttyAMA0 mem=...

Or run the image itself, with default atags being set via config.mk:
  - load zImageDT LOAD_ADDRESS 0x80008000
  - flash run board

Tested on:
  - Dual/single cluster FastModels
  - V2P-CA15-TC1 CoreTile
  - V2P-CA15-A7-TC2 CoreTile (single cluster and big.LITTLE operation)

Signed-off-by: Alexander Spyridakis <a.spyridakis@xxxxxxxxxxxxxxxxxxxxxx>
---
 Makefile          |   19 +++++++++---
 board.lds.S       |   21 +++++++++++++
 boot.S            |   85 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 config-default.mk |    2 +-
 4 files changed, 118 insertions(+), 9 deletions(-)
 create mode 100644 board.lds.S

diff --git a/Makefile b/Makefile
index 0997dcf..c0f10ca 100644
--- a/Makefile
+++ b/Makefile
@@ -21,8 +21,9 @@ KERNEL		= uImage
 
 IMAGE		= linux-system.axf
 SEMIIMG 	= linux-system-semi.axf
+BOARD		= board.axf
 LD_SCRIPT	= model.lds.S
-
+B_LD_SCRIPT	= board.lds.S
 
 CC		= $(CROSS_COMPILE)gcc
 LD		= $(CROSS_COMPILE)ld
@@ -31,14 +32,15 @@ LD		= $(CROSS_COMPILE)ld
 export CROSS_COMPILE ARCH
 
 # Build all wrappers
-all: $(IMAGE) $(SEMIIMG)
+all: $(IMAGE) $(SEMIIMG) $(BOARD)
 
 # Build just the semihosting wrapper
 semi: $(SEMIIMG)
 
 clean distclean:
-	rm -f $(IMAGE) $(SEMIIMG) \
-	model.lds modelsemi.lds $(OBJS) $(KERNEL)
+	rm -f $(IMAGE) $(SEMIIMG) $(BOARD) \
+	model.lds modelsemi.lds board.lds \
+	board.o $(OBJS) $(KERNEL)
 
 $(KERNEL): $(KERNEL_SRC)/arch/arm/boot/uImage
 	cp $< $@
@@ -49,9 +51,15 @@ $(IMAGE): $(OBJS) model.lds $(KERNEL) $(FILESYSTEM) Makefile
 $(SEMIIMG): $(OBJS) modelsemi.lds
 	$(LD) -o $@ $(OBJS) --script=modelsemi.lds
 
+$(BOARD): board.o board.lds Makefile
+	$(LD) -o board.axf --script=board.lds
+
 boot.o: $(BOOTLOADER)
 	$(CC) $(CPPFLAGS) -DKCMD='$(KCMD)' -c -o $@ $<
 
+board.o: $(BOOTLOADER)
+	$(CC) $(CPPFLAGS) -DKCMD='$(KCMD)' -DVE_BOARD -c -o $@ $<
+
 %.o: %.c
 	$(CC) $(CPPFLAGS) -O2 -ffreestanding -I. -Ilibfdt -c -o $@ $<
 
@@ -61,6 +69,9 @@ model.lds: $(LD_SCRIPT) Makefile
 modelsemi.lds: $(LD_SCRIPT) Makefile
 	$(CC) $(CPPFLAGS) -DSEMIHOSTING=1 -E -P -C -o $@ $<
 
+board.lds: $(B_LD_SCRIPT) Makefile
+	$(CC) $(CPPFLAGS) -DBOARD -E -P -C -o $@ $<
+
 $(KERNEL_SRC)/arch/arm/boot/uImage: force
 	$(MAKE) -C $(KERNEL_SRC) -j4 uImage
 
diff --git a/board.lds.S b/board.lds.S
new file mode 100644
index 0000000..560f65e
--- /dev/null
+++ b/board.lds.S
@@ -0,0 +1,21 @@
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+TARGET(binary)
+
+INPUT(./board.o)
+
+PHYS_OFFSET = 0x80000000;
+MON_OFFSET  = 0xf0000000;
+
+SECTIONS
+{
+ . = PHYS_OFFSET;
+
+ .text : { board.o }
+
+ . = PHYS_OFFSET + 0x8000;
+ kernel = .;
+
+ . = PHYS_OFFSET + 0x00d00000;
+ fs_start = .;
+}
diff --git a/boot.S b/boot.S
index dd453e3..5d6e6a1 100644
--- a/boot.S
+++ b/boot.S
@@ -12,6 +12,9 @@
 	.arch_extension virt
 	.text
 
+	.equ GICD_CTLR, 0x2c001000
+	.equ VE_SYS_FLAGS, 0x1c010030
+
 .macro enter_hyp
 	@ We assume we're entered in Secure Supervisor mode. To
 	@ get to Hyp mode we have to pass through Monitor mode
@@ -68,11 +71,60 @@ vectors:
 	@ ...and return to calling code in NS state
 	movs	pc, lr
 
-
 	.globl	start
 start:
 #ifdef SMP
 #ifdef VEXPRESS
+#ifdef VE_BOARD
+	@ On the VE board only CPU0 should be awake at this stage
+	@ BootMonitor's linux loader, will pass machine id and atags to r1 and r2
+	@ Save those two registers, instead of passing our own defaults
+	cmp	r2, #0
+	ldrne	r0, =bootregs
+	stmne	r0, {r1, r2}
+
+	@ Update SYS_FLAGS with the address that secondary cores will jump to
+	ldr	r0, =VE_SYS_FLAGS
+	ldr	r1, =SEC_CORE_ENTRY
+	str	r1, [r0]
+
+	@ Generate Software Interrupt to wake secondary cores
+	ldr	r0, =GICD_CTLR
+	ldr	r1, =(1 << 24)
+	str	r1, [r0, #0xf00]
+
+	b	SEC_CORE_ENTRY
+
+.org 0x100
+atags:
+	@ ATAG_CORE
+	.long	2
+	.long	0x54410001
+
+	@ ATAG_CMDLINE
+	.long	(1f - .) >> 2
+	.long	0x54410009
+        /* The kernel boot command line is defined in config.mk */
+        .asciz KCMD
+	.align	2
+1:
+
+#ifdef USE_INITRD
+	@ ATAG_INITRD2
+	.long	4
+	.long	0x54420005
+	.long	fs_start
+	.long	FS_SIZE
+#endif
+
+	@ ATAG_NONE
+	.long	0
+	.long	0x00000000
+
+@ BootMonitor will write the atags at 0x80000100, move code as far as we can.
+.org 0xe00
+SEC_CORE_ENTRY:
+#endif
 	@
 	@ Program architected timer frequency
 	@
@@ -95,7 +147,7 @@ start:
 	@
 
 	@ Set all interrupts to be non-secure
-	ldr	r0, =0x2c001000			@ Dist GIC base
+	ldr	r0, =GICD_CTLR			@ Dist GIC base
 	ldr	r1, [r0, #0x04]			@ Type Register
 	cmp	r4, #0
 	andeq	r1, r1, #0x1f
@@ -130,12 +182,19 @@ start:
 	@
 	enter_hyp
 
-	ldr	r1, =fs_start - 0x100
+#ifdef VE_BOARD
+	@ Clear SYS_FLAGS to let the kernel wake the rest of the cores properly
+	ldr	r0, =VE_SYS_FLAGS
+	mvn	r1, #0
+	str	r1, [r0, 0x04]
+#endif
+
+	ldr	r1, =MON_OFFSET - 0x100
 	adr	r2, 1f
 	ldmia	r2, {r3 - r7}			@ move the code to a location
 	stmia	r1, {r3 - r7}			@ less likely to be overridden
 #ifdef VEXPRESS
-	ldr	r0, =0x1c010030			@ VE SYS_FLAGS register
+	ldr	r0, =VE_SYS_FLAGS			@ VE SYS_FLAGS register
 #else
 	ldr	r0, =0x10000030			@ RealView SYS_FLAGS register
 #endif
@@ -151,6 +210,7 @@ start:
 #endif
 
 2:
+#ifndef VE_BOARD
 	@
 	@ UART initialisation (38400 8N1)
 	@
@@ -214,3 +274,20 @@ kernel_cmd:
 	.asciz KCMD
 #endif
 kernel_cmd_end:
+#else /* VE_BOARD */
+	enter_hyp
+
+	@
+	@ Kernel parameters
+	@
+	ldr	r0, =bootregs
+	ldm	r0, {r1, r2}
+	mov	r0, #0
+	mov	r3, #0
+	ldr	lr, =kernel
+	mov	pc, lr				@ jump to the kernel
+
+bootregs:
+	.long	2272		@ r1
+	.long	atags		@ r2
+#endif /* VE_BOARD */
diff --git a/config-default.mk b/config-default.mk
index 6c73934..0ba1a06 100644
--- a/config-default.mk
+++ b/config-default.mk
@@ -28,7 +28,7 @@ SYSTEM ?= vexpress
 # Turn this on to use an initrd whose contents are in filesystem.cpio.gz
 USE_INITRD ?= no
 ifeq ($(USE_INITRD),yes)
-CPPFLAGS	+= -DUSE_INITRD
+CPPFLAGS	+= -DUSE_INITRD -DFS_SIZE=$(shell stat -c %s $(FILESYSTEM))
 FILESYSTEM	?= filesystem.cpio.gz
 else
 FILESYSTEM =
-- 
1.7.9.5

_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm


[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux