- 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.spyrida...@virtualopensystems.com>
---
 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


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to