Merge git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / arch / powerpc / kernel / crash.c
1 /*
2  * Architecture specific (PPC64) functions for kexec based crash dumps.
3  *
4  * Copyright (C) 2005, IBM Corp.
5  *
6  * Created by: Haren Myneni
7  *
8  * This source code is licensed under the GNU General Public License,
9  * Version 2.  See the file COPYING for more details.
10  *
11  */
12
13 #undef DEBUG
14
15 #include <linux/kernel.h>
16 #include <linux/smp.h>
17 #include <linux/reboot.h>
18 #include <linux/kexec.h>
19 #include <linux/bootmem.h>
20 #include <linux/crash_dump.h>
21 #include <linux/irq.h>
22 #include <linux/delay.h>
23 #include <linux/elf.h>
24 #include <linux/elfcore.h>
25 #include <linux/init.h>
26 #include <linux/types.h>
27
28 #include <asm/processor.h>
29 #include <asm/machdep.h>
30 #include <asm/kdump.h>
31 #include <asm/lmb.h>
32 #include <asm/firmware.h>
33
34 #ifdef DEBUG
35 #include <asm/udbg.h>
36 #define DBG(fmt...) udbg_printf(fmt)
37 #else
38 #define DBG(fmt...)
39 #endif
40
41 /* This keeps a track of which one is crashing cpu. */
42 int crashing_cpu = -1;
43
44 static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
45                                                                size_t data_len)
46 {
47         struct elf_note note;
48
49         note.n_namesz = strlen(name) + 1;
50         note.n_descsz = data_len;
51         note.n_type   = type;
52         memcpy(buf, &note, sizeof(note));
53         buf += (sizeof(note) +3)/4;
54         memcpy(buf, name, note.n_namesz);
55         buf += (note.n_namesz + 3)/4;
56         memcpy(buf, data, note.n_descsz);
57         buf += (note.n_descsz + 3)/4;
58
59         return buf;
60 }
61
62 static void final_note(u32 *buf)
63 {
64         struct elf_note note;
65
66         note.n_namesz = 0;
67         note.n_descsz = 0;
68         note.n_type   = 0;
69         memcpy(buf, &note, sizeof(note));
70 }
71
72 static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
73 {
74         struct elf_prstatus prstatus;
75         u32 *buf;
76
77         if ((cpu < 0) || (cpu >= NR_CPUS))
78                 return;
79
80         /* Using ELF notes here is opportunistic.
81          * I need a well defined structure format
82          * for the data I pass, and I need tags
83          * on the data to indicate what information I have
84          * squirrelled away.  ELF notes happen to provide
85          * all of that that no need to invent something new.
86          */
87         buf = &crash_notes[cpu][0];
88         memset(&prstatus, 0, sizeof(prstatus));
89         prstatus.pr_pid = current->pid;
90         elf_core_copy_regs(&prstatus.pr_reg, regs);
91         buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
92                         sizeof(prstatus));
93         final_note(buf);
94 }
95
96 /* FIXME Merge this with xmon_save_regs ?? */
97 static inline void crash_get_current_regs(struct pt_regs *regs)
98 {
99         unsigned long tmp1, tmp2;
100
101         __asm__ __volatile__ (
102                 "std    0,0(%2)\n"
103                 "std    1,8(%2)\n"
104                 "std    2,16(%2)\n"
105                 "std    3,24(%2)\n"
106                 "std    4,32(%2)\n"
107                 "std    5,40(%2)\n"
108                 "std    6,48(%2)\n"
109                 "std    7,56(%2)\n"
110                 "std    8,64(%2)\n"
111                 "std    9,72(%2)\n"
112                 "std    10,80(%2)\n"
113                 "std    11,88(%2)\n"
114                 "std    12,96(%2)\n"
115                 "std    13,104(%2)\n"
116                 "std    14,112(%2)\n"
117                 "std    15,120(%2)\n"
118                 "std    16,128(%2)\n"
119                 "std    17,136(%2)\n"
120                 "std    18,144(%2)\n"
121                 "std    19,152(%2)\n"
122                 "std    20,160(%2)\n"
123                 "std    21,168(%2)\n"
124                 "std    22,176(%2)\n"
125                 "std    23,184(%2)\n"
126                 "std    24,192(%2)\n"
127                 "std    25,200(%2)\n"
128                 "std    26,208(%2)\n"
129                 "std    27,216(%2)\n"
130                 "std    28,224(%2)\n"
131                 "std    29,232(%2)\n"
132                 "std    30,240(%2)\n"
133                 "std    31,248(%2)\n"
134                 "mfmsr  %0\n"
135                 "std    %0, 264(%2)\n"
136                 "mfctr  %0\n"
137                 "std    %0, 280(%2)\n"
138                 "mflr   %0\n"
139                 "std    %0, 288(%2)\n"
140                 "bl     1f\n"
141         "1:      mflr   %1\n"
142                 "std    %1, 256(%2)\n"
143                 "mtlr   %0\n"
144                 "mfxer  %0\n"
145                 "std    %0, 296(%2)\n"
146                 : "=&r" (tmp1), "=&r" (tmp2)
147                 : "b" (regs));
148 }
149
150 /* We may have saved_regs from where the error came from
151  * or it is NULL if via a direct panic().
152  */
153 static void crash_save_self(struct pt_regs *saved_regs)
154 {
155         struct pt_regs regs;
156         int cpu;
157
158         cpu = smp_processor_id();
159         if (saved_regs)
160                 memcpy(&regs, saved_regs, sizeof(regs));
161         else
162                 crash_get_current_regs(&regs);
163         crash_save_this_cpu(&regs, cpu);
164 }
165
166 #ifdef CONFIG_SMP
167 static atomic_t waiting_for_crash_ipi;
168
169 void crash_ipi_callback(struct pt_regs *regs)
170 {
171         int cpu = smp_processor_id();
172
173         if (cpu == crashing_cpu)
174                 return;
175
176         if (!cpu_online(cpu))
177                 return;
178
179         if (ppc_md.kexec_cpu_down)
180                 ppc_md.kexec_cpu_down(1, 1);
181
182         local_irq_disable();
183
184         crash_save_this_cpu(regs, cpu);
185         atomic_dec(&waiting_for_crash_ipi);
186         kexec_smp_wait();
187         /* NOTREACHED */
188 }
189
190 static void crash_kexec_prepare_cpus(void)
191 {
192         unsigned int msecs;
193
194         atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
195
196         crash_send_ipi(crash_ipi_callback);
197         smp_wmb();
198
199         /*
200          * FIXME: Until we will have the way to stop other CPUSs reliabally,
201          * the crash CPU will send an IPI and wait for other CPUs to
202          * respond. If not, proceed the kexec boot even though we failed to
203          * capture other CPU states.
204          */
205         msecs = 1000000;
206         while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) {
207                 barrier();
208                 mdelay(1);
209         }
210
211         /* Would it be better to replace the trap vector here? */
212
213         /*
214          * FIXME: In case if we do not get all CPUs, one possibility: ask the
215          * user to do soft reset such that we get all.
216          * IPI handler is already set by the panic cpu initially. Therefore,
217          * all cpus could invoke this handler from die() and the panic CPU
218          * will call machine_kexec() directly from this handler to do
219          * kexec boot.
220          */
221         if (atomic_read(&waiting_for_crash_ipi))
222                 printk(KERN_ALERT "done waiting: %d cpus not responding\n",
223                         atomic_read(&waiting_for_crash_ipi));
224         /* Leave the IPI callback set */
225 }
226 #else
227 static void crash_kexec_prepare_cpus(void)
228 {
229         /*
230          * move the secondarys to us so that we can copy
231          * the new kernel 0-0x100 safely
232          *
233          * do this if kexec in setup.c ?
234          */
235         smp_release_cpus();
236 }
237
238 #endif
239
240 void default_machine_crash_shutdown(struct pt_regs *regs)
241 {
242         /*
243          * This function is only called after the system
244          * has paniced or is otherwise in a critical state.
245          * The minimum amount of code to allow a kexec'd kernel
246          * to run successfully needs to happen here.
247          *
248          * In practice this means stopping other cpus in
249          * an SMP system.
250          * The kernel is broken so disable interrupts.
251          */
252         local_irq_disable();
253
254         if (ppc_md.kexec_cpu_down)
255                 ppc_md.kexec_cpu_down(1, 0);
256
257         /*
258          * Make a note of crashing cpu. Will be used in machine_kexec
259          * such that another IPI will not be sent.
260          */
261         crashing_cpu = smp_processor_id();
262         crash_kexec_prepare_cpus();
263         crash_save_self(regs);
264 }