[intelxl] Add driver for Intel 100 Gigabit Ethernet NICs
[ipxe.git] / 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 SIGFPE 8
19 #define SIGSTKFLT 16
20
21         .globl  gdbmach_sigfpe
22 gdbmach_sigfpe:
23         pushl   $SIGFPE
24         jmp     gdbmach_interrupt
25
26         .globl  gdbmach_sigtrap
27 gdbmach_sigtrap:
28         pushl   $SIGTRAP
29         jmp     gdbmach_interrupt
30
31         .globl  gdbmach_sigstkflt
32 gdbmach_sigstkflt:
33         pushl   $SIGSTKFLT
34         jmp     gdbmach_interrupt
35
36         .globl  gdbmach_sigill
37 gdbmach_sigill:
38         pushl   $SIGILL
39         jmp     gdbmach_interrupt
40
41 /* When invoked, the stack contains: eflags, cs, eip, signo. */
42 #define IH_OFFSET_GDB_REGS ( 0 )
43 #define IH_OFFSET_GDB_EIP ( IH_OFFSET_GDB_REGS + SIZEOF_I386_REGS )
44 #define IH_OFFSET_GDB_EFLAGS ( IH_OFFSET_GDB_EIP + 4 )
45 #define IH_OFFSET_GDB_SEG_REGS ( IH_OFFSET_GDB_EFLAGS + SIZEOF_I386_FLAGS )
46 #define IH_OFFSET_GDB_END ( IH_OFFSET_GDB_SEG_REGS + 6 * 4 )
47 #define IH_OFFSET_SIGNO ( IH_OFFSET_GDB_END )
48 #define IH_OFFSET_OLD_EIP ( IH_OFFSET_SIGNO + 4 )
49 #define IH_OFFSET_OLD_CS ( IH_OFFSET_OLD_EIP + 4 )
50 #define IH_OFFSET_OLD_EFLAGS ( IH_OFFSET_OLD_CS + 4 )
51 #define IH_OFFSET_END ( IH_OFFSET_OLD_EFLAGS + 4 )
52
53 /* We also access the stack whilst still storing or restoring
54  * the register snapshot.  Since ESP is in flux, we need
55  * special offsets.
56  */
57 #define IH_OFFSET_FLUX_OLD_CS ( IH_OFFSET_OLD_CS - 44 )
58 #define IH_OFFSET_FLUX_OLD_EFLAGS ( IH_OFFSET_OLD_EFLAGS - 40 )
59 #define IH_OFFSET_FLUX_OLD_EIP ( IH_OFFSET_OLD_EIP - 36 )
60 #define IH_OFFSET_FLUX_END ( IH_OFFSET_END - 20 )
61 gdbmach_interrupt:
62         /* Store CPU state in GDB register snapshot */
63         pushw   $0
64         pushw   %gs
65         pushw   $0
66         pushw   %fs
67         pushw   $0
68         pushw   %es
69         pushw   $0
70         pushw   %ds
71         pushw   $0
72         pushw   %ss
73         pushw   $0
74         pushw   IH_OFFSET_FLUX_OLD_CS + 2(%esp)
75         pushl   IH_OFFSET_FLUX_OLD_EFLAGS(%esp)
76         pushl   IH_OFFSET_FLUX_OLD_EIP(%esp)
77         pushl   %edi
78         pushl   %esi
79         pushl   %ebp
80         leal    IH_OFFSET_FLUX_END(%esp), %edi
81         pushl   %edi /* old ESP */
82         pushl   %ebx
83         pushl   %edx
84         pushl   %ecx
85         pushl   %eax
86
87         /* Switch to virtual addressing */
88         call    _intr_to_virt
89
90         /* Call GDB stub exception handler */
91         pushl   %esp
92         pushl   (IH_OFFSET_SIGNO + 4)(%esp)
93         call    gdbmach_handler
94         addl    $8, %esp
95
96         /* Copy register snapshot to new stack and switch to new stack */
97         movl    %esp, %esi
98         movl    (IH_OFFSET_GDB_SEG_REGS + 4)(%esp), %eax
99         movl    %eax, %es
100         movl    (IH_OFFSET_GDB_REGS + 16)(%esp), %edi
101         subl    $IH_OFFSET_END, %edi
102         movl    $(IH_OFFSET_END / 4), %ecx
103         pushl   %edi
104         ss rep movsl
105         popl    %edi
106         movl    %eax, %ss
107         movl    %edi, %esp
108
109         /* Restore CPU state from GDB register snapshot */
110         popl    %eax
111         popl    %ecx
112         popl    %edx
113         popl    %ebx
114         popl    %ebp /* Skip %esp: already loaded */
115         popl    %ebp
116         popl    %esi
117         popl    %edi
118         popl    IH_OFFSET_FLUX_OLD_EIP(%esp)
119         popl    IH_OFFSET_FLUX_OLD_EFLAGS(%esp)
120         popl    IH_OFFSET_FLUX_OLD_CS(%esp)
121         popl    %ds /* Skip %ss: already loaded */
122         popl    %ds
123         popl    %es
124         popl    %fs
125         popl    %gs
126
127         addl    $4, %esp /* drop signo */
128         iret