Set up a frame pointer on interrupt entry, to improve backtraces of
[pintos-anon] / src / threads / intr-stubs.S
1 #include "threads/loader.h"
2
3         .intel_syntax noprefix
4         .text
5
6 /* Main interrupt entry point.
7
8    An internal or external interrupt starts in one of the
9    intrNN_stub routines, which push the `struct intr_frame'
10    frame_pointer, error_code, and vec_no members on the stack,
11    then jump here.
12
13    We save the rest of the `struct intr_frame' members to the
14    stack, set up some registers as needed by the kernel, and then
15    call intr_handler(), which actually handles the interrupt.
16
17    We "fall through" to intr_exit to return from the interrupt.
18 */
19 .func intr_entry
20 intr_entry:
21         /* Save caller's registers. */
22         push ds
23         push es
24         push fs
25         push gs
26         pusha
27         
28         /* Set up kernel environment. */
29         cld                     /* String instructions go upward. */
30         mov eax, SEL_KDSEG      /* Initialize segment registers. */
31         mov ds, eax
32         mov es, eax
33         lea ebp, [esp + 56]     /* Set up frame pointer. */
34
35         /* Call interrupt handler. */
36         push esp
37 .globl intr_handler
38         call intr_handler
39         add esp, 4
40 .endfunc
41
42 /* Interrupt exit.
43
44    Restores the caller's registers, discards extra data on the
45    stack, and returns to the caller.
46
47    This is a separate function because it is called directly when
48    we launch a new user process (see execute_thread() in
49    userprog/process.c). */
50 .globl intr_exit
51 .func intr_exit
52 intr_exit:
53         /* Restore caller's registers. */
54         popa
55         pop gs
56         pop fs
57         pop es
58         pop ds
59
60         /* Discard `struct intr_frame' vec_no, error_code,
61            frame_pointer members. */
62         add esp, 12
63
64         /* Return to caller. */
65         iret
66 .endfunc
67
68 /* Interrupt stubs.
69
70    This defines 256 fragments of code, named `intr00_stub'
71    through `intrff_stub', each of which is used as the entry
72    point for the corresponding interrupt vector.  It also puts
73    the address of each of these functions in the correct spot in
74    `intr_stubs', an array of function pointers.
75
76    Most of the stubs do this:
77
78         1. Push EBP on the stack (frame_pointer in `struct intr_frame').
79
80         2. Push 0 on the stack (error_code).
81
82         3. Push the interrupt number on the stack (vec_no).
83
84    The CPU pushes an extra "error code" on the stack for a few
85    interrupts.  Because we want EBP to be where the error code
86    is, we follow a different path:
87
88         1. Push a duplicate copy of the error code on the stack.
89
90         2. Replace the original copy of the error code by EBP.
91
92         3. Push the interrupt number on the stack. */
93
94         .data
95 .globl intr_stubs
96 intr_stubs:
97
98 /* This implements steps 1 and 2, described above, in the common
99    case where we just push a 0 error code. */
100 #define zero                                    \
101         push ebp;                               \
102         push 0
103
104 /* This implements steps 1 and 2, described above, in the case
105    where the CPU already pushed an error code. */
106 #define REAL                                    \
107         push dword ptr [esp];                   \
108         mov [esp + 4], ebp
109
110 /* Emits a stub for interrupt vector NUMBER.
111    TYPE is `zero', for the case where we push a 0 error code,
112    or `REAL', if the CPU pushes an error code for us. */
113 #define STUB(NUMBER, TYPE)                      \
114         .text;                                  \
115 .globl intr##NUMBER##_stub;                     \
116 .func intr##NUMBER##_stub;                      \
117 intr##NUMBER##_stub:                            \
118         TYPE;                                   \
119         push 0x##NUMBER;                        \
120         jmp intr_entry;                         \
121 .endfunc;                                       \
122                                                 \
123         .data;                                  \
124         .long intr##NUMBER##_stub;
125
126 /* All the stubs. */
127 STUB(00, zero) STUB(01, zero) STUB(02, zero) STUB(03, zero)
128 STUB(04, zero) STUB(05, zero) STUB(06, zero) STUB(07, zero)
129 STUB(08, REAL) STUB(09, zero) STUB(0a, REAL) STUB(0b, REAL)
130 STUB(0c, zero) STUB(0d, REAL) STUB(0e, REAL) STUB(0f, zero)
131
132 STUB(10, zero) STUB(11, REAL) STUB(12, zero) STUB(13, zero)
133 STUB(14, zero) STUB(15, zero) STUB(16, zero) STUB(17, zero)
134 STUB(18, REAL) STUB(19, zero) STUB(1a, REAL) STUB(1b, REAL)
135 STUB(1c, zero) STUB(1d, REAL) STUB(1e, REAL) STUB(1f, zero)
136
137 STUB(20, zero) STUB(21, zero) STUB(22, zero) STUB(23, zero)
138 STUB(24, zero) STUB(25, zero) STUB(26, zero) STUB(27, zero)
139 STUB(28, zero) STUB(29, zero) STUB(2a, zero) STUB(2b, zero)
140 STUB(2c, zero) STUB(2d, zero) STUB(2e, zero) STUB(2f, zero)
141
142 STUB(30, zero) STUB(31, zero) STUB(32, zero) STUB(33, zero)
143 STUB(34, zero) STUB(35, zero) STUB(36, zero) STUB(37, zero)
144 STUB(38, zero) STUB(39, zero) STUB(3a, zero) STUB(3b, zero)
145 STUB(3c, zero) STUB(3d, zero) STUB(3e, zero) STUB(3f, zero)
146
147 STUB(40, zero) STUB(41, zero) STUB(42, zero) STUB(43, zero)
148 STUB(44, zero) STUB(45, zero) STUB(46, zero) STUB(47, zero)
149 STUB(48, zero) STUB(49, zero) STUB(4a, zero) STUB(4b, zero)
150 STUB(4c, zero) STUB(4d, zero) STUB(4e, zero) STUB(4f, zero)
151
152 STUB(50, zero) STUB(51, zero) STUB(52, zero) STUB(53, zero)
153 STUB(54, zero) STUB(55, zero) STUB(56, zero) STUB(57, zero)
154 STUB(58, zero) STUB(59, zero) STUB(5a, zero) STUB(5b, zero)
155 STUB(5c, zero) STUB(5d, zero) STUB(5e, zero) STUB(5f, zero)
156
157 STUB(60, zero) STUB(61, zero) STUB(62, zero) STUB(63, zero)
158 STUB(64, zero) STUB(65, zero) STUB(66, zero) STUB(67, zero)
159 STUB(68, zero) STUB(69, zero) STUB(6a, zero) STUB(6b, zero)
160 STUB(6c, zero) STUB(6d, zero) STUB(6e, zero) STUB(6f, zero)
161
162 STUB(70, zero) STUB(71, zero) STUB(72, zero) STUB(73, zero)
163 STUB(74, zero) STUB(75, zero) STUB(76, zero) STUB(77, zero)
164 STUB(78, zero) STUB(79, zero) STUB(7a, zero) STUB(7b, zero)
165 STUB(7c, zero) STUB(7d, zero) STUB(7e, zero) STUB(7f, zero)
166
167 STUB(80, zero) STUB(81, zero) STUB(82, zero) STUB(83, zero)
168 STUB(84, zero) STUB(85, zero) STUB(86, zero) STUB(87, zero)
169 STUB(88, zero) STUB(89, zero) STUB(8a, zero) STUB(8b, zero)
170 STUB(8c, zero) STUB(8d, zero) STUB(8e, zero) STUB(8f, zero)
171
172 STUB(90, zero) STUB(91, zero) STUB(92, zero) STUB(93, zero)
173 STUB(94, zero) STUB(95, zero) STUB(96, zero) STUB(97, zero)
174 STUB(98, zero) STUB(99, zero) STUB(9a, zero) STUB(9b, zero)
175 STUB(9c, zero) STUB(9d, zero) STUB(9e, zero) STUB(9f, zero)
176
177 STUB(a0, zero) STUB(a1, zero) STUB(a2, zero) STUB(a3, zero)
178 STUB(a4, zero) STUB(a5, zero) STUB(a6, zero) STUB(a7, zero)
179 STUB(a8, zero) STUB(a9, zero) STUB(aa, zero) STUB(ab, zero)
180 STUB(ac, zero) STUB(ad, zero) STUB(ae, zero) STUB(af, zero)
181
182 STUB(b0, zero) STUB(b1, zero) STUB(b2, zero) STUB(b3, zero)
183 STUB(b4, zero) STUB(b5, zero) STUB(b6, zero) STUB(b7, zero)
184 STUB(b8, zero) STUB(b9, zero) STUB(ba, zero) STUB(bb, zero)
185 STUB(bc, zero) STUB(bd, zero) STUB(be, zero) STUB(bf, zero)
186
187 STUB(c0, zero) STUB(c1, zero) STUB(c2, zero) STUB(c3, zero)
188 STUB(c4, zero) STUB(c5, zero) STUB(c6, zero) STUB(c7, zero)
189 STUB(c8, zero) STUB(c9, zero) STUB(ca, zero) STUB(cb, zero)
190 STUB(cc, zero) STUB(cd, zero) STUB(ce, zero) STUB(cf, zero)
191
192 STUB(d0, zero) STUB(d1, zero) STUB(d2, zero) STUB(d3, zero)
193 STUB(d4, zero) STUB(d5, zero) STUB(d6, zero) STUB(d7, zero)
194 STUB(d8, zero) STUB(d9, zero) STUB(da, zero) STUB(db, zero)
195 STUB(dc, zero) STUB(dd, zero) STUB(de, zero) STUB(df, zero)
196
197 STUB(e0, zero) STUB(e1, zero) STUB(e2, zero) STUB(e3, zero)
198 STUB(e4, zero) STUB(e5, zero) STUB(e6, zero) STUB(e7, zero)
199 STUB(e8, zero) STUB(e9, zero) STUB(ea, zero) STUB(eb, zero)
200 STUB(ec, zero) STUB(ed, zero) STUB(ee, zero) STUB(ef, zero)
201
202 STUB(f0, zero) STUB(f1, zero) STUB(f2, zero) STUB(f3, zero)
203 STUB(f4, zero) STUB(f5, zero) STUB(f6, zero) STUB(f7, zero)
204 STUB(f8, zero) STUB(f9, zero) STUB(fa, zero) STUB(fb, zero)
205 STUB(fc, zero) STUB(fd, zero) STUB(fe, zero) STUB(ff, zero)