This commit was manufactured by cvs2svn to create branch
[linux-2.6.git] / include / asm-i386 / crashdump.h
1 #ifndef _ASM_I386_CRASHDUMP_H
2 #define _ASM_I386_CRASHDUMP_H
3
4 /*
5  * linux/include/asm-i386/crashdump.h
6  *
7  * Copyright (c) 2003, 2004 Red Hat, Inc. All rights reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2, or (at your option)
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  */
24
25 #ifdef __KERNEL__
26
27 #include <asm/irq.h>
28
29 /*
30  *  Structure taken from arch/i386/kernel/irq.c.  It used to live in asm/irq.h.
31  */
32 #ifdef CONFIG_4KSTACKS
33 union dump_irq_ctx {
34         struct thread_info      tinfo;
35         u32                     stack[THREAD_SIZE/sizeof(u32)];
36 };
37 #endif
38
39 extern int page_is_ram (unsigned long);
40 extern unsigned long next_ram_page (unsigned long);
41
42 #define platform_timestamp(x) rdtscll(x)
43
44 #define platform_fix_regs()                                             \
45 {                                                                       \
46        unsigned long esp;                                               \
47        unsigned short ss;                                               \
48        esp = (unsigned long) ((char *)regs + sizeof (struct pt_regs));  \
49        ss = __KERNEL_DS;                                                \
50        if (regs->xcs & 3) {                                             \
51                esp = regs->esp;                                         \
52                ss = regs->xss & 0xffff;                                 \
53        }                                                                \
54        myregs = *regs;                                                  \
55        myregs.esp = esp;                                                \
56        myregs.xss = (myregs.xss & 0xffff0000) | ss;                     \
57 };
58
59 static inline void platform_init_stack(void **stackptr)
60 {
61 #ifdef CONFIG_4KSTACKS
62         *stackptr = (void *)kmalloc(sizeof(union dump_irq_ctx), GFP_KERNEL);
63         if (*stackptr)
64                 memset(*stackptr, 0, sizeof(union dump_irq_ctx));
65         else
66                 printk(KERN_WARNING
67                        "crashdump: unable to allocate separate stack\n");
68 #else
69         *stackptr = NULL;
70 #endif
71 }
72
73 typedef asmlinkage void (*crashdump_func_t)(struct pt_regs *, void *);
74
75 static inline void platform_start_crashdump(void *stackptr,
76                                            crashdump_func_t dumpfunc,
77                                            struct pt_regs *regs)
78 {
79         if (!stackptr)
80                 dumpfunc(regs, NULL);
81 #ifdef CONFIG_4KSTACKS
82         else {
83                 u32 *dsp;
84                 union dump_irq_ctx * curctx;
85                 union dump_irq_ctx * dumpctx;
86
87                 curctx = (union dump_irq_ctx *) current_thread_info();
88                 dumpctx = (union dump_irq_ctx *) stackptr;
89
90                 /* build the stack frame on the IRQ stack */
91                 dsp = (u32*) ((char*)dumpctx + sizeof(*dumpctx));
92                 dumpctx->tinfo.task = curctx->tinfo.task;
93                 dumpctx->tinfo.previous_esp = current_stack_pointer;
94
95                 *--dsp = (u32) NULL;
96                 *--dsp = (u32) regs;
97
98                 asm volatile(
99                         "       xchgl   %%ebx,%%esp     \n"
100                         "       call    *%%eax          \n"
101                         "       xchgl   %%ebx,%%esp     \n"
102                         : : "a"(dumpfunc), "b"(dsp)
103                         : "memory", "cc", "edx", "ecx"
104                 );
105         }
106 #endif
107 }
108
109 #define platform_cleanup_stack(stackptr)        \
110 do {                                            \
111         if (stackptr)                           \
112                 kfree(stackptr);                \
113 } while (0)
114
115 #define platform_freeze_cpu()                                   \
116 {                                                               \
117         for (;;) local_irq_disable();                           \
118 }
119
120
121 #endif /* __KERNEL__ */
122
123 #endif /* _ASM_I386_CRASHDUMP_H */