diff options
author | R Sharada <sharada@in.ibm.com> | 2005-09-14 18:17:29 +0530 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2006-07-27 09:46:04 -0600 |
commit | 4abf375a85c4ce439017b3873e0933c518a79334 (patch) | |
tree | 975a46518eb29742099a6c4f24f5c8d5cd593ce0 /purgatory | |
parent | 0a6bd1c06f95feac368ffd9dd4a663807313e19c (diff) | |
download | kexec-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/Makefile | 12 | ||||
-rw-r--r-- | purgatory/arch/ppc64/Makefile | 2 | ||||
-rw-r--r-- | purgatory/arch/ppc64/v2wrap.S | 114 |
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 |