summaryrefslogtreecommitdiffstats
path: root/purgatory
diff options
context:
space:
mode:
authorR Sharada <sharada@in.ibm.com>2006-07-27 10:49:16 -0600
committerEric W. Biederman <ebiederm@xmission.com>2006-07-27 10:49:16 -0600
commit92aade5b19bfdd14dfa47ed1426bd90d2064cfe8 (patch)
tree034da0012c5ebdadfa08f6cd4228f28632e69f91 /purgatory
parent9768c7e89f1a5cb4933d2ea996321d8ec7e162bd (diff)
downloadkexec-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/Makefile11
-rw-r--r--purgatory/arch/ppc64/Makefile5
-rw-r--r--purgatory/arch/ppc64/console-ppc64.c27
-rw-r--r--purgatory/arch/ppc64/crashdump_backup.c41
-rw-r--r--purgatory/arch/ppc64/purgatory-ppc64.c41
-rw-r--r--purgatory/arch/ppc64/purgatory-ppc64.h6
-rw-r--r--purgatory/arch/ppc64/v2wrap.S102
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
+