Changeset 4003861 in mainline
- Timestamp:
- 2010-07-14T13:11:59Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 074c9bd, aa0d227
- Parents:
- 6b1a85c (diff), f77e591d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- kernel/arch
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/include/asm.h
r6b1a85c r4003861 435 435 GEN_WRITE_REG(dr7) 436 436 437 extern size_t interrupt_handler_size;438 extern void interrupt_handlers(void);439 440 437 extern void asm_delay_loop(uint32_t); 441 438 extern void asm_fake_loop(uint32_t); 442 439 440 extern uintptr_t int_0; 441 extern uintptr_t int_1; 442 extern uintptr_t int_2; 443 extern uintptr_t int_3; 444 extern uintptr_t int_4; 445 extern uintptr_t int_5; 446 extern uintptr_t int_6; 447 extern uintptr_t int_7; 448 extern uintptr_t int_8; 449 extern uintptr_t int_9; 450 extern uintptr_t int_10; 451 extern uintptr_t int_11; 452 extern uintptr_t int_12; 453 extern uintptr_t int_13; 454 extern uintptr_t int_14; 455 extern uintptr_t int_15; 456 extern uintptr_t int_16; 457 extern uintptr_t int_17; 458 extern uintptr_t int_18; 459 extern uintptr_t int_19; 460 extern uintptr_t int_20; 461 extern uintptr_t int_21; 462 extern uintptr_t int_22; 463 extern uintptr_t int_23; 464 extern uintptr_t int_24; 465 extern uintptr_t int_25; 466 extern uintptr_t int_26; 467 extern uintptr_t int_27; 468 extern uintptr_t int_28; 469 extern uintptr_t int_29; 470 extern uintptr_t int_30; 471 extern uintptr_t int_31; 472 extern uintptr_t int_32; 473 extern uintptr_t int_33; 474 extern uintptr_t int_34; 475 extern uintptr_t int_35; 476 extern uintptr_t int_36; 477 extern uintptr_t int_37; 478 extern uintptr_t int_38; 479 extern uintptr_t int_39; 480 extern uintptr_t int_40; 481 extern uintptr_t int_41; 482 extern uintptr_t int_42; 483 extern uintptr_t int_43; 484 extern uintptr_t int_44; 485 extern uintptr_t int_45; 486 extern uintptr_t int_46; 487 extern uintptr_t int_47; 488 extern uintptr_t int_48; 489 extern uintptr_t int_49; 490 extern uintptr_t int_50; 491 extern uintptr_t int_51; 492 extern uintptr_t int_52; 493 extern uintptr_t int_53; 494 extern uintptr_t int_54; 495 extern uintptr_t int_55; 496 extern uintptr_t int_56; 497 extern uintptr_t int_57; 498 extern uintptr_t int_58; 499 extern uintptr_t int_59; 500 extern uintptr_t int_60; 501 extern uintptr_t int_61; 502 extern uintptr_t int_62; 503 extern uintptr_t int_63; 504 443 505 #endif 444 506 -
kernel/arch/amd64/src/asm.S
r6b1a85c r4003861 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 -
kernel/arch/amd64/src/interrupt.c
r6b1a85c r4003861 65 65 void istate_decode(istate_t *istate) 66 66 { 67 printf("error_word=%#llx\n", istate->error_word); 68 printf("cs =%#0.16llx\trflags=%#0.16llx\n", istate->cs, 69 istate->rflags); 70 printf("rax=%#0.16llx\trbx=%#0.16llx\trcx=%#0.16llx\n", istate->rax, 71 istate->rcx, istate->rdx); 72 printf("rsi=%#0.16llx\trdi=%#0.16llx\tr8 =%#0.16llx\n", istate->rsi, 73 istate->rdi, istate->r8); 74 printf("r9 =%#0.16llx\tr10=%#0.16llx\tr11=%#0.16llx\n", istate->r9, 75 istate->r10, istate->r11); 67 printf("cs =%p\trip=%p\trfl=%p\terr=%p\n", 68 istate->cs, istate->rip, istate->rflags, istate->error_word); 69 70 if (istate_from_uspace(istate)) 71 printf("ss =%p\n", istate->ss); 72 73 printf("rax=%p\trbx=%p\trcx=%p\trdx=%p\n", 74 istate->rax, istate->rbx, istate->rcx, istate->rdx); 75 printf("rsi=%p\trdi=%p\trbp=%p\trsp=%p\n", 76 istate->rsi, istate->rdi, istate->rbp, 77 istate_from_uspace(istate) ? istate->rsp : (uintptr_t)&istate->rsp); 78 printf("r8 =%p\tr9 =%p\tr10=%p\tr11=%p\n", 79 istate->r8, istate->r9, istate->r10, istate->r11); 80 printf("r12=%p\tr13=%p\tr14=%p\tr15=%p\n", 81 istate->r12, istate->r13, istate->r14, istate->r15); 76 82 } 77 83 -
kernel/arch/amd64/src/pm.c
r6b1a85c r4003861 175 175 d->present = 1; 176 176 d->type = AR_INTERRUPT; /* masking interrupt */ 177 178 idt_setoffset(d, ((uintptr_t) interrupt_handlers) +179 i * interrupt_handler_size);180 177 } 178 179 d = &idt[0]; 180 idt_setoffset(d++, (uintptr_t) &int_0); 181 idt_setoffset(d++, (uintptr_t) &int_1); 182 idt_setoffset(d++, (uintptr_t) &int_2); 183 idt_setoffset(d++, (uintptr_t) &int_3); 184 idt_setoffset(d++, (uintptr_t) &int_4); 185 idt_setoffset(d++, (uintptr_t) &int_5); 186 idt_setoffset(d++, (uintptr_t) &int_6); 187 idt_setoffset(d++, (uintptr_t) &int_7); 188 idt_setoffset(d++, (uintptr_t) &int_8); 189 idt_setoffset(d++, (uintptr_t) &int_9); 190 idt_setoffset(d++, (uintptr_t) &int_10); 191 idt_setoffset(d++, (uintptr_t) &int_11); 192 idt_setoffset(d++, (uintptr_t) &int_12); 193 idt_setoffset(d++, (uintptr_t) &int_13); 194 idt_setoffset(d++, (uintptr_t) &int_14); 195 idt_setoffset(d++, (uintptr_t) &int_15); 196 idt_setoffset(d++, (uintptr_t) &int_16); 197 idt_setoffset(d++, (uintptr_t) &int_17); 198 idt_setoffset(d++, (uintptr_t) &int_18); 199 idt_setoffset(d++, (uintptr_t) &int_19); 200 idt_setoffset(d++, (uintptr_t) &int_20); 201 idt_setoffset(d++, (uintptr_t) &int_21); 202 idt_setoffset(d++, (uintptr_t) &int_22); 203 idt_setoffset(d++, (uintptr_t) &int_23); 204 idt_setoffset(d++, (uintptr_t) &int_24); 205 idt_setoffset(d++, (uintptr_t) &int_25); 206 idt_setoffset(d++, (uintptr_t) &int_26); 207 idt_setoffset(d++, (uintptr_t) &int_27); 208 idt_setoffset(d++, (uintptr_t) &int_28); 209 idt_setoffset(d++, (uintptr_t) &int_29); 210 idt_setoffset(d++, (uintptr_t) &int_30); 211 idt_setoffset(d++, (uintptr_t) &int_31); 212 idt_setoffset(d++, (uintptr_t) &int_32); 213 idt_setoffset(d++, (uintptr_t) &int_33); 214 idt_setoffset(d++, (uintptr_t) &int_34); 215 idt_setoffset(d++, (uintptr_t) &int_35); 216 idt_setoffset(d++, (uintptr_t) &int_36); 217 idt_setoffset(d++, (uintptr_t) &int_37); 218 idt_setoffset(d++, (uintptr_t) &int_38); 219 idt_setoffset(d++, (uintptr_t) &int_39); 220 idt_setoffset(d++, (uintptr_t) &int_40); 221 idt_setoffset(d++, (uintptr_t) &int_41); 222 idt_setoffset(d++, (uintptr_t) &int_42); 223 idt_setoffset(d++, (uintptr_t) &int_43); 224 idt_setoffset(d++, (uintptr_t) &int_44); 225 idt_setoffset(d++, (uintptr_t) &int_45); 226 idt_setoffset(d++, (uintptr_t) &int_46); 227 idt_setoffset(d++, (uintptr_t) &int_47); 228 idt_setoffset(d++, (uintptr_t) &int_48); 229 idt_setoffset(d++, (uintptr_t) &int_49); 230 idt_setoffset(d++, (uintptr_t) &int_50); 231 idt_setoffset(d++, (uintptr_t) &int_51); 232 idt_setoffset(d++, (uintptr_t) &int_52); 233 idt_setoffset(d++, (uintptr_t) &int_53); 234 idt_setoffset(d++, (uintptr_t) &int_54); 235 idt_setoffset(d++, (uintptr_t) &int_55); 236 idt_setoffset(d++, (uintptr_t) &int_56); 237 idt_setoffset(d++, (uintptr_t) &int_57); 238 idt_setoffset(d++, (uintptr_t) &int_58); 239 idt_setoffset(d++, (uintptr_t) &int_59); 240 idt_setoffset(d++, (uintptr_t) &int_60); 241 idt_setoffset(d++, (uintptr_t) &int_61); 242 idt_setoffset(d++, (uintptr_t) &int_62); 243 idt_setoffset(d++, (uintptr_t) &int_63); 181 244 } 182 245 -
kernel/arch/amd64/src/proc/scheduler.c
r6b1a85c r4003861 38 38 #include <proc/thread.h> 39 39 #include <arch.h> 40 #include <arch/context.h>41 40 #include <arch/asm.h> 42 41 #include <print.h> … … 57 56 { 58 57 CPU->arch.tss->rsp0 = 59 (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];58 (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE]; 60 59 61 60 /* -
kernel/arch/amd64/src/proc/thread.c
r6b1a85c r4003861 34 34 35 35 #include <proc/thread.h> 36 #include <arch/interrupt.h> 36 37 37 38 /** Perform amd64 specific thread initialization. … … 49 50 */ 50 51 thread->arch.syscall_rsp[SYSCALL_KSTACK_RSP] = 51 (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof( uint64_t)];52 (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof(istate_t)]; 52 53 } 53 54 -
kernel/arch/ia32/include/asm.h
r6b1a85c r4003861 42 42 #include <config.h> 43 43 #include <trace.h> 44 45 extern uint32_t interrupt_handler_size;46 44 47 45 /** Halt CPU -
kernel/arch/ia32/src/asm.S
r6b1a85c r4003861 175 175 176 176 /* 177 * Size of the entire istate structure including the error word and the178 * hardware-saved part.179 */180 #define ISTATE_REAL_SIZE (ISTATE_SOFT_SIZE + 24)181 182 /*183 177 * The SYSENTER syscall mechanism can be used for syscalls with 184 178 * four or fewer arguments. To pass these four arguments, we … … 191 185 .global sysenter_handler 192 186 sysenter_handler: 193 subl $(ISTATE_REAL_SIZE), %esp 187 188 /* 189 * Note that the space needed for the istate structure has been 190 * preallocated on the stack by before_thread_runs_arch(). 191 */ 194 192 195 193 /* … … 260 258 movl ISTATE_OFFSET_ESP(%esp), %ecx 261 259 262 addl $(ISTATE_REAL_SIZE), %esp263 264 260 sysexit /* return to userspace */ 265 261 … … 353 349 #define ERROR_WORD_INTERRUPT_LIST 0x00027d00 354 350 355 /** Declare interrupt handlers356 *357 * Declare interrupt handlers for n interrupt358 * vectors starting at vector i.359 *360 */361 351 .macro handler i 362 352 .global int_\i -
kernel/arch/ia32/src/interrupt.c
r6b1a85c r4003861 65 65 void istate_decode(istate_t *istate) 66 66 { 67 printf(" error_word=%p\n", istate->error_word);68 printf("eflags=%p\n", istate->eflags);69 70 printf(" cs =%p\tds =%p\tes =%p\n", istate->cs, istate->ds, istate->es);71 printf("fs =%p\tgs =%p", istate->fs, istate->gs);67 printf("cs =%p\teip=%p\tefl=%p\terr=%p\n", 68 istate->cs, istate->eip, istate->eflags, istate->error_word); 69 70 printf("ds =%p\tes =%p\tfs =%p\tgs =%p\n", 71 istate->ds, istate->es, istate->fs, istate->gs); 72 72 if (istate_from_uspace(istate)) 73 printf("\tss =%p\n", istate->ss); 74 else 75 printf("\n"); 76 77 printf("eax=%p\tebx=%p\tecx=%p\n", istate->eax, istate->ebx, 78 istate->ecx); 79 printf("edx=%p\tedi=%p\tesi=%p\n", istate->edx, istate->edi, 80 istate->esi); 81 printf("ebp=%p\tesp=%p\teip=%p\n", istate->ebp, 82 istate_from_uspace(istate) ? istate->esp : (uintptr_t) &istate->esp, 83 istate->eip); 73 printf("ss =%p\n", istate->ss); 74 75 printf("eax=%p\tebx=%p\tecx=%p\tedx=%p\n", 76 istate->eax, istate->ebx, istate->ecx, istate->edx); 77 printf("esi=%p\tedi=%p\tebp=%p\tesp=%p\n", 78 istate->esi, istate->edi, istate->ebp, 79 istate_from_uspace(istate) ? istate->esp : (uintptr_t)&istate->esp); 84 80 } 85 81 -
kernel/arch/ia32/src/proc/scheduler.c
r6b1a85c r4003861 38 38 #include <proc/thread.h> 39 39 #include <arch.h> 40 #include <arch/ context.h> /* SP_DELTA */40 #include <arch/interrupt.h> 41 41 #include <arch/pm.h> 42 42 #include <arch/asm.h> … … 58 58 void before_thread_runs_arch(void) 59 59 { 60 uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - 61 SP_DELTA]; 60 uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE]; 62 61 63 62 if (CPU->arch.fi.bits.sep) { 64 63 /* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */ 65 write_msr(IA32_MSR_SYSENTER_ESP, kstk );64 write_msr(IA32_MSR_SYSENTER_ESP, kstk - sizeof(istate_t)); 66 65 } 67 66
Note:
See TracChangeset
for help on using the changeset viewer.