2 * Architecture specific (ARM/XScale) functions for Linux crash dumps.
4 * Created by: Fleming Feng (fleming.feng@intel.com)
6 * Copyright(C) 2003 Intel Corp. All rights reserved.
8 * This code is released under version 2 of the GNU GPL.
12 * The hooks for dumping the kernel virtual memory to disk are in this
13 * file. Any time a modification is made to the virtual memory mechanism,
14 * these routines must be changed to use the new mechanisms.
16 #include <linux/init.h>
17 #include <linux/types.h>
18 #include <linux/kernel.h>
19 #include <linux/smp.h>
21 #include <linux/vmalloc.h>
22 #include <linux/dump.h>
24 #include <asm/processor.h>
25 #include <asm/hardirq.h>
26 #include <asm/kdebug.h>
28 static __s32 saved_irq_count; /* saved preempt_count() flags */
30 static int alloc_dha_stack(void)
35 if (dump_header_asm.dha_stack[0])
38 ptr = vmalloc(THREAD_SIZE * num_online_cpus());
40 printk("vmalloc for dha_stacks failed\n");
44 for( i = 0; i < num_online_cpus(); i++){
45 dump_header_asm.dha_stack[i] = (u32)((unsigned long)ptr +
52 static int free_dha_stack(void)
54 if (dump_header_asm.dha_stack[0]){
55 vfree((void*)dump_header_asm.dha_stack[0]);
56 dump_header_asm.dha_stack[0] = 0;
61 void __dump_save_regs(struct pt_regs* dest_regs, const struct pt_regs* regs)
64 /* Here, because the arm version uses _dump_regs_t,
65 * instead of pt_regs in dump_header_asm, while the
66 * the function is defined inside architecture independent
67 * header file include/linux/dump.h, the size of block of
68 * memory copied is not equal to pt_regs.
71 memcpy(dest_regs, regs, sizeof(_dump_regs_t));
76 /* FIXME: This is reserved for possible future usage for SMP system
77 * based on ARM/XScale. Currently, there is no information for an
78 * SMP system based on ARM/XScale, they are not used!
80 /* save registers on other processor */
82 __dump_save_other_cpus(void)
90 #else /* !CONFIG_SMP */
91 #define save_other_cpu_state() do { } while (0)
92 #endif /* !CONFIG_SMP */
95 * Kludge - dump from interrupt context is unreliable (Fixme)
97 * We do this so that softirqs initiated for dump i/o
98 * get processed and we don't hang while waiting for i/o
99 * to complete or in any irq synchronization attempt.
101 * This is not quite legal of course, as it has the side
102 * effect of making all interrupts & softirqs triggered
103 * while dump is in progress complete before currently
104 * pending softirqs and the currently executing interrupt
110 saved_irq_count = irq_count();
111 preempt_count() &= ~(HARDIRQ_MASK|SOFTIRQ_MASK);
117 preempt_count() |= saved_irq_count;
121 * Name: __dump_irq_enable
122 * Func: Reset system so interrupts are enabled.
123 * This is used for dump methods that requires interrupts
124 * Eventually, all methods will have interrupts disabled
125 * and this code can be removed.
127 * Re-enable interrupts
130 __dump_irq_enable(void)
137 /* Name: __dump_irq_restore
138 * Func: Resume the system state in an architecture-specific way.
141 __dump_irq_restore(void)
149 * Name: __dump_configure_header()
150 * Func: Meant to fill in arch specific header fields except per-cpu state
151 * already captured in dump_lcrash_configure_header.
154 __dump_configure_header(const struct pt_regs *regs)
160 * Name: dump_die_event
161 * Func: Called from notify_die
163 static int dump_die_event(struct notifier_block* this,
167 const struct die_args* args = (const struct die_args*)arg;
173 dump_execute(args->str, args->regs);
180 static struct notifier_block dump_die_block = {
181 .notifier_call = dump_die_event,
184 /* Name: __dump_init()
185 * Func: Initialize the dumping routine process.
188 __dump_init(uint64_t local_memory_start)
190 /* hook into PANIC and OOPS */
191 register_die_notifier(&dump_die_block);
195 * Name: __dump_open()
196 * Func: Open the dump device (architecture specific). This is in
197 * case it's necessary in the future.
209 * Name: __dump_cleanup()
210 * Func: Free any architecture specific data structures. This is called
211 * when the dump module is being removed.
217 unregister_die_notifier(&dump_die_block);
224 * Name: __dump_page_valid()
225 * Func: Check if page is valid to dump.
228 __dump_page_valid(unsigned long index)
230 if(!pfn_valid(index))
237 * Name: manual_handle_crashdump
238 * Func: Interface for the lkcd dump command. Calls dump_execute()
241 manual_handle_crashdump(void) {
245 get_current_general_regs(®s);
246 get_current_cp14_regs(®s);
247 get_current_cp15_regs(®s);
248 dump_execute("manual", ®s);