summaryrefslogtreecommitdiffstats
path: root/purgatory
diff options
context:
space:
mode:
authorR Sharada <sharada@in.ibm.com>2005-09-14 18:17:29 +0530
committerEric W. Biederman <ebiederm@xmission.com>2006-07-27 09:46:04 -0600
commit4abf375a85c4ce439017b3873e0933c518a79334 (patch)
tree975a46518eb29742099a6c4f24f5c8d5cd593ce0 /purgatory
parent0a6bd1c06f95feac368ffd9dd4a663807313e19c (diff)
downloadkexec-tools-4abf375a85c4ce439017b3873e0933c518a79334.tar.gz
build v2wrap from purgatory
This patch builds v2wrap from within purgatory Signed-off-by: Mohan Kumar <mohan@in.ibm.com> Signed-off-by: R Sharada <sharada@in.ibm.com> Signed-off-by: Maneesh Soni <maneesh@in.ibm.com>
Diffstat (limited to 'purgatory')
-rw-r--r--purgatory/Makefile12
-rw-r--r--purgatory/arch/ppc64/Makefile2
-rw-r--r--purgatory/arch/ppc64/v2wrap.S114
3 files changed, 127 insertions, 1 deletions
diff --git a/purgatory/Makefile b/purgatory/Makefile
index 93f58308..5dd03e71 100644
--- a/purgatory/Makefile
+++ b/purgatory/Makefile
@@ -6,6 +6,11 @@
# There is probably a cleaner way to do this but for now this
# should keep us from accidentially include unsafe library functions
# or headers.
+
+ifeq ($(ARCH),ppc64)
+LDFLAGS = -melf64ppc
+endif
+
PCFLAGS:=-Wall -Os \
-I$(shell $(CC) -print-file-name=include) \
-Ipurgatory/include -Ipurgatory/arch/$(ARCH)/include \
@@ -17,9 +22,11 @@ PCFLAGS += $(call cc-option, -fnostdinc)
PCFLAGS += $(call cc-option, -fno-zero-initialized-in-bss)
PURGATORY_C_SRCS:=
+ifneq ($(ARCH),ppc64)
PURGATORY_C_SRCS += purgatory/purgatory.c
PURGATORY_C_SRCS += purgatory/printf.c
PURGATORY_C_SRCS += purgatory/string.c
+endif
PURGATORY_S_OBJS:=
include purgatory/arch/$(ARCH)/Makefile
@@ -54,7 +61,12 @@ $(PURGATORY_S_OBJS): $(OBJDIR)/%.o: %.S $(OBJDIR)/%.d
$(PURGATORY): $(PURGATORY_OBJS) $(UTIL_LIB)
$(MKDIR) -p $(@D)
+ifneq ($(ARCH),ppc64)
$(LD) $(LDFLAGS) --no-undefined -e purgatory_start -r -o $@ $(PURGATORY_OBJS) $(UTIL_LIB)
+else
+ $(LD) -Ttext=0 -e 0 -o $(OBJDIR)/purgatory/v2wrap.elf $(PURGATORY_OBJS)
+ objcopy -O binary $(OBJDIR)/purgatory/v2wrap.elf $@
+endif
echo::
@echo "PURGATORY_C_SRCS $(PURGATORY_C_SRCS)"
diff --git a/purgatory/arch/ppc64/Makefile b/purgatory/arch/ppc64/Makefile
index c76794b2..6916c5fc 100644
--- a/purgatory/arch/ppc64/Makefile
+++ b/purgatory/arch/ppc64/Makefile
@@ -3,5 +3,5 @@
#
PURGATORY_C_SRCS+=
-PURGATORY_S_SRCS+=
+PURGATORY_S_SRCS+= purgatory/arch/ppc64/v2wrap.S
diff --git a/purgatory/arch/ppc64/v2wrap.S b/purgatory/arch/ppc64/v2wrap.S
new file mode 100644
index 00000000..6e5cdcea
--- /dev/null
+++ b/purgatory/arch/ppc64/v2wrap.S
@@ -0,0 +1,114 @@
+#
+# kexec: Linux boots Linux
+#
+# Copyright (C) 2004 - 2005, Milton D Miller II, IBM Corporation
+#
+# 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 (version 2 of the License).
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# v2wrap.S
+# a wrapper to place in front of a v2 device tree
+# to call a ppc64 kernel with the expected arguments
+# of kernel(device-tree, phys-offset, 0)
+#
+# calling convention:
+# r3 = physical number of this cpu (all cpus)
+# r4 = address of this chunk (master only)
+# master enters at start (aka first byte of this chunk)
+# slaves (additional cpus), if any, enter a copy of the
+# first 0x100 bytes of this code relocated to 0x0
+#
+# in other words,
+# a copy of the first 0x100 bytes of this code is copied to 0
+# and the slaves are sent to address 0x60
+# with r3 = their physical cpu number.
+
+
+# look a bit like a Linux kernel here ...
+ .machine ppc64
+ .org 0
+start: b master
+ tweq 0,0
+secondary_hold:
+ .llong 0
+
+ .org 0x20 # need a bit more space than after slave,
+master:
+ std 4,secondary_hold@l(0) # bring slaves up here to this copy
+ sync # try to get the slaves to see this
+ or 1,1,1 # low priority to let other thread catchup
+ isync
+ mr 5,3 # save cpu id to r5
+ addi 3,4,0x100 # r3 = boot param block
+ lwz 6,20(3) # fetch version number
+ cmpwi 0,6,2 # v2 ?
+ blt 80f
+ stw 5,28(3) # save my cpu number as boot_cpu_phys
+80: b 81f
+
+ .org 0x60 # ABI: slaves start at 60 with r3=phys
+slave: ld 4,secondary_hold@l(0);
+ cmpdi 0,4,0
+ beq slave
+
+ # ahh, master told us where he is running from
+ # jump into our copy of the code up there so this code can change
+ addi 5,4,1f-start
+ mtctr 5
+ bctr
+
+ # ok, now wait for the master to tell is to go back to the new block
+1: ld 5,copied@l(4)
+ cmpdi 0,5,0
+ beq 1b
+ ba 0x60
+
+
+
+ .long 0 # just an eye-catcher, delete if space needed
+ .long 0 # just an eye-catcher, delete if space needed
+
+81: # master continues here
+ or 3,3,3 # ok back to high, lets boot
+ lis 6,0x1
+ mtctr 6 # delay a bit for slaves to catch up
+83: bdnz 83b # before we overwrite 0-100 again
+
+ ld 4,-8(3) # kernel pointer is at -8(bb) by loader
+ addi 5,4,-8 # prepare copy with update form instructions
+ li 6,0x100/8
+ mtctr 6
+ li 6,-8
+85: ldu 7,8(5)
+ stdu 7,8(6)
+ bdnz 85b
+
+ li 5,0 # r5 will be 0 for kernel
+ dcbst 0,5 # store dcache, flush icache
+ dcbst 0,6 # 0 and 0xf8 covers us with 128 byte lines
+ mtctr 4 # prepare branch too
+ sync
+ icbi 0,5
+ icbi 0,6
+ sync
+ isync
+ std 6,-16(3) # send slaves back down
+ bctr # start kernel
+
+ .org 0xf0
+copied: .llong 0
+kernel: .llong 0
+ .org 0x100
+__end_stub:
+ .equ boot_block, . - start