diff options
author | R Sharada <sharada@in.ibm.com> | 2006-07-27 10:49:16 -0600 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2006-07-27 10:49:16 -0600 |
commit | 92aade5b19bfdd14dfa47ed1426bd90d2064cfe8 (patch) | |
tree | 034da0012c5ebdadfa08f6cd4228f28632e69f91 /purgatory | |
parent | 9768c7e89f1a5cb4933d2ea996321d8ec7e162bd (diff) | |
download | kexec-tools-92aade5b19bfdd14dfa47ed1426bd90d2064cfe8.tar.gz |
ppc64 kdump purgatory backup support
This patch implements the purgatory support to take backup
of the first 32KB of the first kernel
- Modified the v2wrap code to make the secondary cpus spin
directly in the v2wrap after pulling them out of kexec_wait
- Use the elf_rel function support to set the various
symbols used in purgatory
- load device-tree as a separate segment
- other miscellaneous compiler warnings cleanup
- add purgatory code support for backup
- build purgatory as relocatable for ppc64
Signed-off-by: R Sharada <sharada@in.ibm.com>
Signed-off-by: Mohan Kumar M <mohan@in.ibm.com>
Signed-off-by: Maneesh Soni <maneesh@in.ibm.com>
Diffstat (limited to 'purgatory')
-rw-r--r-- | purgatory/Makefile | 11 | ||||
-rw-r--r-- | purgatory/arch/ppc64/Makefile | 5 | ||||
-rw-r--r-- | purgatory/arch/ppc64/console-ppc64.c | 27 | ||||
-rw-r--r-- | purgatory/arch/ppc64/crashdump_backup.c | 41 | ||||
-rw-r--r-- | purgatory/arch/ppc64/purgatory-ppc64.c | 41 | ||||
-rw-r--r-- | purgatory/arch/ppc64/purgatory-ppc64.h | 6 | ||||
-rw-r--r-- | purgatory/arch/ppc64/v2wrap.S | 102 |
7 files changed, 178 insertions, 55 deletions
diff --git a/purgatory/Makefile b/purgatory/Makefile index 5dd03e71..50ce99fe 100644 --- a/purgatory/Makefile +++ b/purgatory/Makefile @@ -21,13 +21,11 @@ PCFLAGS += $(call cc-option, -fnobuiltin) PCFLAGS += $(call cc-option, -fnostdinc) PCFLAGS += $(call cc-option, -fno-zero-initialized-in-bss) -PURGATORY_C_SRCS:= -ifneq ($(ARCH),ppc64) +PURGATORY_C_SRCS:= PURGATORY_C_SRCS += purgatory/purgatory.c PURGATORY_C_SRCS += purgatory/printf.c PURGATORY_C_SRCS += purgatory/string.c -endif -PURGATORY_S_OBJS:= +PURGATORY_S_OBJS:= include purgatory/arch/$(ARCH)/Makefile @@ -61,12 +59,7 @@ $(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 6916c5fc..82b16543 100644 --- a/purgatory/arch/ppc64/Makefile +++ b/purgatory/arch/ppc64/Makefile @@ -2,6 +2,7 @@ # Purgatory ppc # -PURGATORY_C_SRCS+= PURGATORY_S_SRCS+= purgatory/arch/ppc64/v2wrap.S - +PURGATORY_C_SRCS += purgatory/arch/ppc64/purgatory-ppc64.c +PURGATORY_C_SRCS += purgatory/arch/ppc64/console-ppc64.c +PURGATORY_C_SRCS += purgatory/arch/ppc64/crashdump_backup.c diff --git a/purgatory/arch/ppc64/console-ppc64.c b/purgatory/arch/ppc64/console-ppc64.c new file mode 100644 index 00000000..d6da7b37 --- /dev/null +++ b/purgatory/arch/ppc64/console-ppc64.c @@ -0,0 +1,27 @@ +/* + * kexec: Linux boots Linux + * + * Created by: Mohan Kumar M (mohan@in.ibm.com) + * + * Copyright (C) IBM Corporation, 2005. All rights reserved + * + * 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. + */ + +#include <purgatory.h> + +void putchar(int c) +{ + return; +} diff --git a/purgatory/arch/ppc64/crashdump_backup.c b/purgatory/arch/ppc64/crashdump_backup.c new file mode 100644 index 00000000..07f7847e --- /dev/null +++ b/purgatory/arch/ppc64/crashdump_backup.c @@ -0,0 +1,41 @@ +/* + * kexec: Linux boots Linux + * + * Created by: Mohan Kumar M (mohan@in.ibm.com) + * + * Copyright (C) IBM Corporation, 2005. All rights reserved + * + * 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. + */ + +#include <stdint.h> +#include <string.h> + +#define BACKUP_REGION_SOURCE 0x0 +#define BACKUP_REGION_SIZE 32*1024 + +extern unsigned long backup_start; + +/* Backup first 32KB of memory to backup region reserved by kexec */ +void crashdump_backup_memory(void) +{ + void *dest, *src; + + src = (void *)BACKUP_REGION_SOURCE; + + if (backup_start) { + dest = (void *)(backup_start); + memcpy(dest, src, BACKUP_REGION_SIZE); + } +} diff --git a/purgatory/arch/ppc64/purgatory-ppc64.c b/purgatory/arch/ppc64/purgatory-ppc64.c new file mode 100644 index 00000000..93f28d2e --- /dev/null +++ b/purgatory/arch/ppc64/purgatory-ppc64.c @@ -0,0 +1,41 @@ +/* + * kexec: Linux boots Linux + * + * Created by: Mohan Kumar M (mohan@in.ibm.com) + * + * Copyright (C) IBM Corporation, 2005. All rights reserved + * + * 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. + */ + +#include <purgatory.h> +#include "purgatory-ppc64.h" + +unsigned int panic_kernel = 0; +unsigned long backup_start = 0; +unsigned long stack = 0; +unsigned long dt_offset = 0; +unsigned long my_toc = 0; +unsigned long kernel = 0; + +void setup_arch(void) +{ + return; +} + +void post_verification_setup_arch(void) +{ + if (panic_kernel) + crashdump_backup_memory(); +} diff --git a/purgatory/arch/ppc64/purgatory-ppc64.h b/purgatory/arch/ppc64/purgatory-ppc64.h new file mode 100644 index 00000000..52eaf439 --- /dev/null +++ b/purgatory/arch/ppc64/purgatory-ppc64.h @@ -0,0 +1,6 @@ +#ifndef PURGATORY_PPC64_H +#define PURGATORY_PPC64_H + +void crashdump_backup_memory(void); + +#endif /* PURGATORY_PPC64_H */ diff --git a/purgatory/arch/ppc64/v2wrap.S b/purgatory/arch/ppc64/v2wrap.S index 6e5cdcea..7514d686 100644 --- a/purgatory/arch/ppc64/v2wrap.S +++ b/purgatory/arch/ppc64/v2wrap.S @@ -2,6 +2,7 @@ # kexec: Linux boots Linux # # Copyright (C) 2004 - 2005, Milton D Miller II, IBM Corporation +# Copyright (C) 2006, Mohan Kumar M (mohan@in.ibm.com), 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 @@ -18,14 +19,17 @@ # # v2wrap.S -# a wrapper to place in front of a v2 device tree -# to call a ppc64 kernel with the expected arguments +# a wrapper to call purgatory code to backup first +# 32kB of first kernel into the backup region +# reserved by kexec-tools. +# Invokes 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) +# master enters at purgatory_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 # @@ -34,50 +38,50 @@ # and the slaves are sent to address 0x60 # with r3 = their physical cpu number. +#define LOADADDR(rn,name) \ + lis rn,name##@highest; \ + ori rn,rn,name##@higher; \ + rldicr rn,rn,32,31; \ + oris rn,rn,name##@h; \ + ori rn,rn,name##@l # look a bit like a Linux kernel here ... .machine ppc64 - .org 0 -start: b master + .globl purgatory_start +purgatory_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 + mr 17,3 # save cpu id to r17 + mr 15,4 # save physical address in reg15 + + LOADADDR(6,my_toc) + ld 2,0(6) #setup toc - # 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 + LOADADDR(6,stack) + ld 1,0(6) #setup stack + subi 1,1,112 + bl .purgatory + nop + b 81f + .org purgatory_start + 0x60 # ABI: slaves start at 60 with r3=phys +slave: + # load slave spin code address and branch into that + LOADADDR(6,slave_spin) + ld 4,0(6) + mtctr 4 + bctr - .long 0 # just an eye-catcher, delete if space needed - .long 0 # just an eye-catcher, delete if space needed +spin: .long 1 +slave_spin_code: + lis 5,spin@ha + lwz 5,spin@l(5) + cmpwi 0,5,0 + bne slave_spin_code + ba 0x60 81: # master continues here or 3,3,3 # ok back to high, lets boot @@ -85,7 +89,17 @@ slave: ld 4,secondary_hold@l(0); 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 + LOADADDR(16, dt_offset) + ld 3,0(16) # load device-tree address + mr 16,3 # save dt address in reg16 + lwz 6,20(3) # fetch version number + cmpwi 0,6,2 # v2 ? + blt 80f + stw 17,28(3) # save my cpu number as boot_cpu_phys +80: + LOADADDR(6,kernel) + ld 4,0(6) # load the kernel address + addi 5,4,-8 # prepare copy with update form instructions li 6,0x100/8 mtctr 6 @@ -103,12 +117,12 @@ slave: ld 4,secondary_hold@l(0); icbi 0,6 sync isync - std 6,-16(3) # send slaves back down + lis 6,spin@ha + li 0,0 + stw 0,spin@l(6) + mr 3,16 # restore dt address + bctr # start kernel - .org 0xf0 -copied: .llong 0 -kernel: .llong 0 - .org 0x100 -__end_stub: - .equ boot_block, . - start +slave_spin: .llong slave_spin_code + |