Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / arch / i386 / core / gdbidt.S
1 /*
2  * Interrupt handlers for GDB stub
3  */
4
5 #define SIZEOF_I386_REGS        32
6 #define SIZEOF_I386_FLAGS       4
7
8 /****************************************************************************
9  * Interrupt handlers
10  ****************************************************************************
11  */
12         .section ".text", "ax", @progbits
13         .code32
14
15 /* POSIX signal numbers for reporting traps to GDB */
16 #define SIGILL 4
17 #define SIGTRAP 5
18 #define SIGBUS 7
19 #define SIGFPE 8
20 #define SIGSEGV 11
21 #define SIGSTKFLT 16
22
23         .globl  gdbmach_nocode_sigfpe
24 gdbmach_nocode_sigfpe:
25         pushl   $SIGFPE
26         jmp     gdbmach_interrupt
27
28         .globl  gdbmach_nocode_sigtrap
29 gdbmach_nocode_sigtrap:
30         pushl   $SIGTRAP
31         jmp     gdbmach_interrupt
32
33         .globl  gdbmach_nocode_sigstkflt
34 gdbmach_nocode_sigstkflt:
35         pushl   $SIGSTKFLT
36         jmp     gdbmach_interrupt
37
38         .globl  gdbmach_nocode_sigill
39 gdbmach_nocode_sigill:
40         pushl   $SIGILL
41         jmp     gdbmach_interrupt
42
43         .globl  gdbmach_withcode_sigbus
44 gdbmach_withcode_sigbus:
45         movl    $SIGBUS, (%esp)
46         jmp     gdbmach_interrupt
47
48         .globl  gdbmach_withcode_sigsegv
49 gdbmach_withcode_sigsegv:
50         movl    $SIGSEGV, (%esp)
51         jmp     gdbmach_interrupt
52
53 /* When invoked, the stack contains: eflags, cs, eip, signo. */
54 #define IH_OFFSET_GDB_REGS ( 0 )
55 #define IH_OFFSET_GDB_EIP ( IH_OFFSET_GDB_REGS + SIZEOF_I386_REGS )
56 #define IH_OFFSET_GDB_EFLAGS ( IH_OFFSET_GDB_EIP + 4 )
57 #define IH_OFFSET_GDB_SEG_REGS ( IH_OFFSET_GDB_EFLAGS + SIZEOF_I386_FLAGS )
58 #define IH_OFFSET_GDB_END ( IH_OFFSET_GDB_SEG_REGS + 6 * 4 )
59 #define IH_OFFSET_SIGNO ( IH_OFFSET_GDB_END )
60 #define IH_OFFSET_OLD_EIP ( IH_OFFSET_SIGNO + 4 )
61 #define IH_OFFSET_OLD_CS ( IH_OFFSET_OLD_EIP + 4 )
62 #define IH_OFFSET_OLD_EFLAGS ( IH_OFFSET_OLD_CS + 4 )
63 #define IH_OFFSET_END ( IH_OFFSET_OLD_EFLAGS + 4 )
64
65 /* We also access the stack whilst still storing or restoring
66  * the register snapshot.  Since ESP is in flux, we need
67  * special offsets.
68  */
69 #define IH_OFFSET_FLUX_OLD_CS ( IH_OFFSET_OLD_CS - 44 )
70 #define IH_OFFSET_FLUX_OLD_EFLAGS ( IH_OFFSET_OLD_EFLAGS - 40 )
71 #define IH_OFFSET_FLUX_OLD_EIP ( IH_OFFSET_OLD_EIP - 36 )
72 #define IH_OFFSET_FLUX_END ( IH_OFFSET_END - 20 )
73 gdbmach_interrupt:
74         /* Store CPU state in GDB register snapshot */
75         pushw   $0
76         pushw   %gs
77         pushw   $0
78         pushw   %fs
79         pushw   $0
80         pushw   %es
81         pushw   $0
82         pushw   %ds
83         pushw   $0
84         pushw   %ss
85         pushw   $0
86         pushw   IH_OFFSET_FLUX_OLD_CS + 2(%esp)
87         pushl   IH_OFFSET_FLUX_OLD_EFLAGS(%esp)
88         pushl   IH_OFFSET_FLUX_OLD_EIP(%esp)
89         pushl   %edi
90         pushl   %esi
91         pushl   %ebp
92         leal    IH_OFFSET_FLUX_END(%esp), %edi
93         pushl   %edi /* old ESP */
94         pushl   %ebx
95         pushl   %edx
96         pushl   %ecx
97         pushl   %eax
98
99         /* Switch to virtual addressing */
100         call    _intr_to_virt
101
102         /* Call GDB stub exception handler */
103         pushl   %esp
104         pushl   (IH_OFFSET_SIGNO + 4)(%esp)
105         call    gdbmach_handler
106         addl    $8, %esp
107
108         /* Copy register snapshot to new stack and switch to new stack */
109         movl    %esp, %esi
110         movl    (IH_OFFSET_GDB_SEG_REGS + 4)(%esp), %eax
111         movl    %eax, %es
112         movl    (IH_OFFSET_GDB_REGS + 16)(%esp), %edi
113         subl    $IH_OFFSET_END, %edi
114         movl    $(IH_OFFSET_END / 4), %ecx
115         pushl   %edi
116         ss rep movsl
117         popl    %edi
118         movl    %eax, %ss
119         movl    %edi, %esp
120
121         /* Restore CPU state from GDB register snapshot */
122         popl    %eax
123         popl    %ecx
124         popl    %edx
125         popl    %ebx
126         popl    %ebp /* Skip %esp: already loaded */
127         popl    %ebp
128         popl    %esi
129         popl    %edi
130         popl    IH_OFFSET_FLUX_OLD_EIP(%esp)
131         popl    IH_OFFSET_FLUX_OLD_EFLAGS(%esp)
132         popl    IH_OFFSET_FLUX_OLD_CS(%esp)
133         popl    %ds /* Skip %ss: already loaded */
134         popl    %ds
135         popl    %es
136         popl    %fs
137         popl    %gs
138
139         addl    $4, %esp /* drop signo */
140         iret