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