Rev 2071 | Rev 2784 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2071 | Rev 2606 | ||
---|---|---|---|
Line 218... | Line 218... | ||
218 | # The handlers call exc_dispatch(). |
218 | # The handlers call exc_dispatch(). |
219 | # |
219 | # |
220 | .macro handler i n |
220 | .macro handler i n |
221 | 221 | ||
222 | /* |
222 | /* |
223 | * Choose between version with error code and version without error code. |
223 | * Choose between version with error code and version without error |
224 | * Both versions have to be of the same size. amd64 assembly is, however, |
224 | * code. Both versions have to be of the same size. amd64 assembly is, |
225 | * a little bit tricky. For instance, subq $0x80, %rsp and subq $0x78, %rsp |
225 | * however, a little bit tricky. For instance, subq $0x80, %rsp and |
226 | * can result in two instructions with different op-code lengths. |
226 | * subq $0x78, %rsp can result in two instructions with different |
- | 227 | * op-code lengths. |
|
227 | * Therefore we align the interrupt handlers. |
228 | * Therefore we align the interrupt handlers. |
228 | */ |
229 | */ |
229 | 230 | ||
230 | .iflt \i-32 |
231 | .iflt \i-32 |
231 | .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST |
232 | .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST |
Line 267... | Line 268... | ||
267 | interrupt_handlers: |
268 | interrupt_handlers: |
268 | h_start: |
269 | h_start: |
269 | handler 0 IDT_ITEMS |
270 | handler 0 IDT_ITEMS |
270 | h_end: |
271 | h_end: |
271 | 272 | ||
- | 273 | ## Low-level syscall handler |
|
- | 274 | # |
|
- | 275 | # Registers on entry: |
|
- | 276 | # |
|
- | 277 | # @param rcx Userspace return address. |
|
- | 278 | # @param r11 Userspace RLFAGS. |
|
272 | 279 | # |
|
- | 280 | # @param rax Syscall number. |
|
- | 281 | # @param rdi 1st syscall argument. |
|
- | 282 | # @param rsi 2nd syscall argument. |
|
- | 283 | # @param rdx 3rd syscall argument. |
|
- | 284 | # @param r10 4th syscall argument. Used instead of RCX because the |
|
- | 285 | # SYSCALL instruction clobbers it. |
|
- | 286 | # @param r8 5th syscall argument. |
|
- | 287 | # @param r9 6th syscall argument. |
|
- | 288 | # |
|
- | 289 | # @return Return value is in rax. |
|
- | 290 | # |
|
273 | syscall_entry: |
291 | syscall_entry: |
274 | # Switch to hidden gs |
292 | swapgs # Switch to hidden gs |
275 | swapgs |
293 | # |
276 | # %gs:0 now points to pointer to stack page |
294 | # %gs:0 Scratch space for this thread's user RSP |
277 | mov %gs:0, %r10 # We have a ptr to stack page in r10 |
295 | # %gs:8 Address to be used as this thread's kernel RSP |
278 | addq $PAGE_SIZE-16, %r10 # We need some space to store old %sp |
- | |
279 | 296 | # |
|
280 | movq %rsp, 0(%r10) # Save old stack pointer to stack |
297 | movq %rsp, %gs:0 # Save this thread's user RSP |
281 | movq %r10, %rsp # Change to new stack |
298 | movq %gs:8, %rsp # Set this thread's kernel RSP |
282 | pushq %rcx # Return address |
- | |
283 | pushq %r11 # Save flags |
- | |
284 | - | ||
285 | # Switch back to remain consistent |
299 | swapgs # Switch back to remain consistent |
286 | swapgs |
- | |
287 | - | ||
288 | sti |
300 | sti |
289 | movq %r9, %rcx # Exchange last parameter as a third |
- | |
290 | 301 | ||
- | 302 | pushq %rcx |
|
- | 303 | pushq %r11 |
|
- | 304 | ||
- | 305 | movq %r10, %rcx # Copy the 4th argument where it is expected |
|
- | 306 | pushq %rax |
|
291 | call syscall_handler |
307 | call syscall_handler |
292 | cli # We will be touching stack pointer |
308 | addq $8, %rsp |
293 | 309 | ||
294 | popq %r11 |
310 | popq %r11 |
295 | popq %rcx |
311 | popq %rcx |
- | 312 | ||
- | 313 | cli |
|
- | 314 | swapgs |
|
296 | movq 0(%rsp), %rsp |
315 | movq %gs:0, %rsp # Restore the user RSP |
- | 316 | swapgs |
|
- | 317 | ||
297 | sysretq |
318 | sysretq |
298 | - | ||
299 | 319 | ||
300 | .data |
320 | .data |
301 | .global interrupt_handler_size |
321 | .global interrupt_handler_size |
302 | 322 | ||
303 | interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS |
323 | interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS |