Changes in kernel/arch/amd64/src/asm.S [c0e9f3f:f77e591d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/asm.S
rc0e9f3f rf77e591d 192 192 #define ERROR_WORD_INTERRUPT_LIST 0x00027D00 193 193 194 #define INTERRUPT_ALIGN 256 195 196 /** Declare interrupt handlers 197 * 198 * Declare interrupt handlers for n interrupt 199 * vectors starting at vector i. 200 * 201 * The handlers call exc_dispatch(). 202 * 203 */ 204 .macro handler i n 205 194 .macro handler i 195 .global int_\i 196 int_\i: 197 206 198 /* 207 199 * Choose between version with error code and version without error 208 * code. Both versions have to be of the same size. amd64 assembly is, 209 * however, a little bit tricky. For instance, subq $0x80, %rsp and 210 * subq $0x78, %rsp can result in two instructions with different 211 * op-code lengths. 212 * Therefore we align the interrupt handlers. 200 * code. 213 201 */ 214 202 … … 290 278 addq $(ISTATE_SOFT_SIZE + 8), %rsp 291 279 iretq 292 293 .align INTERRUPT_ALIGN294 .if (\n - \i) - 1295 handler "(\i + 1)", \n296 .endif297 280 .endm 298 281 299 .align INTERRUPT_ALIGN 282 #define LIST_0_63 \ 283 0, 1, 2, 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\ 284 28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,\ 285 53,54,55,56,57,58,59,60,61,62,63 286 300 287 interrupt_handlers: 301 h_start: 302 handler 0 IDT_ITEMS303 h_end: 288 .irp cnt, LIST_0_63 289 handler \cnt 290 .endr 304 291 305 292 /** Low-level syscall handler … … 334 321 movq %gs:8, %rsp /* set this thread's kernel RSP */ 335 322 336 /* Switch back to remain consistent */ 323 /* 324 * Note that the space needed for the imitated istate structure has been 325 * preallocated for us in thread_create_arch() and set in 326 * before_thread_runs_arch(). 327 */ 328 329 /* 330 * Save the general purpose registers and push the 7th argument (syscall 331 * number) onto the stack. Note that the istate structure has a layout 332 * which supports this. 333 */ 334 movq %rax, ISTATE_OFFSET_RAX(%rsp) /* 7th argument, passed on stack */ 335 movq %rbx, ISTATE_OFFSET_RBX(%rsp) /* observability */ 336 movq %rcx, ISTATE_OFFSET_RCX(%rsp) /* userspace RIP */ 337 movq %rdx, ISTATE_OFFSET_RDX(%rsp) /* 3rd argument, observability */ 338 movq %rsi, ISTATE_OFFSET_RSI(%rsp) /* 2nd argument, observability */ 339 movq %rdi, ISTATE_OFFSET_RDI(%rsp) /* 1st argument, observability */ 340 movq %rbp, ISTATE_OFFSET_RBP(%rsp) /* need to preserve userspace RBP */ 341 movq %r8, ISTATE_OFFSET_R8(%rsp) /* 5th argument, observability */ 342 movq %r9, ISTATE_OFFSET_R9(%rsp) /* 6th argument, observability */ 343 movq %r10, ISTATE_OFFSET_R10(%rsp) /* 4th argument, observability */ 344 movq %r11, ISTATE_OFFSET_R11(%rsp) /* low 32 bits userspace RFLAGS */ 345 movq %r12, ISTATE_OFFSET_R12(%rsp) /* observability */ 346 movq %r13, ISTATE_OFFSET_R13(%rsp) /* observability */ 347 movq %r14, ISTATE_OFFSET_R14(%rsp) /* observability */ 348 movq %r15, ISTATE_OFFSET_R15(%rsp) /* observability */ 349 350 /* 351 * Save the return address and the userspace stack on locations that 352 * would normally be taken by them. 353 */ 354 movq %gs:0, %rax 355 movq %rax, ISTATE_OFFSET_RSP(%rsp) 356 movq %rcx, ISTATE_OFFSET_RIP(%rsp) 357 358 /* 359 * Imitate a regular stack frame linkage. 360 */ 361 movq $0, ISTATE_OFFSET_RBP_FRAME(%rsp) 362 movq %rcx, ISTATE_OFFSET_RIP_FRAME(%rsp) 363 leaq ISTATE_OFFSET_RBP_FRAME(%rsp), %rbp 364 365 /* Switch back to normal %gs */ 337 366 swapgs 338 367 sti 339 368 340 pushq %rcx341 pushq %r11342 pushq %rbp343 344 xorq %rbp, %rbp /* stop the stack traces here */345 346 369 /* Copy the 4th argument where it is expected */ 347 370 movq %r10, %rcx 348 pushq %rax 349 371 372 /* 373 * Call syscall_handler() with the 7th argument passed on stack. 374 */ 350 375 call syscall_handler 351 376 352 addq $8, %rsp353 354 popq %rbp355 popq %r11356 popq %rcx357 358 377 cli 359 swapgs 360 361 /* Restore the user RSP */ 362 movq %gs:0, %rsp 363 swapgs 364 378 379 /* 380 * Restore registers needed for return via the SYSRET instruction and 381 * the clobbered preserved registers (i.e. RBP). 382 */ 383 movq ISTATE_OFFSET_RBP(%rsp), %rbp 384 movq ISTATE_OFFSET_RCX(%rsp), %rcx 385 movq ISTATE_OFFSET_R11(%rsp), %r11 386 movq ISTATE_OFFSET_RSP(%rsp), %rsp 387 365 388 sysretq 366 389 … … 509 532 ret 510 533 511 .data512 .global interrupt_handler_size513 514 interrupt_handler_size: .quad (h_end - h_start) / IDT_ITEMS
Note:
See TracChangeset
for help on using the changeset viewer.