Changeset a35b458 in mainline for kernel/arch/amd64/src
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- kernel/arch/amd64/src
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/amd64.c
r3061bc1 ra35b458 92 92 multiboot_info_parse(signature, (multiboot_info_t *) info); 93 93 multiboot2_info_parse(signature, (multiboot2_info_t *) info); 94 94 95 95 #ifdef CONFIG_SMP 96 96 /* Copy AP bootstrap routines below 1 MB. */ … … 106 106 /* Enable FPU */ 107 107 cpu_setup_fpu(); 108 108 109 109 /* Initialize segmentation */ 110 110 pm_init(); 111 111 112 112 /* Disable I/O on nonprivileged levels, clear the nested-thread flag */ 113 113 write_rflags(read_rflags() & ~(RFLAGS_IOPL | RFLAGS_NT)); 114 114 /* Disable alignment check */ 115 115 write_cr0(read_cr0() & ~CR0_AM); 116 116 117 117 if (config.cpu_active == 1) { 118 118 interrupt_init(); 119 119 bios_init(); 120 120 121 121 /* PIC */ 122 122 i8259_init(); … … 132 132 /* Initialize IRQ routing */ 133 133 irq_init(IRQ_COUNT, IRQ_COUNT); 134 134 135 135 /* hard clock */ 136 136 i8254_init(); 137 137 138 138 #if (defined(CONFIG_FB) || defined(CONFIG_EGA)) 139 139 bool bfb = false; 140 140 #endif 141 141 142 142 #ifdef CONFIG_FB 143 143 bfb = bfb_init(); 144 144 #endif 145 145 146 146 #ifdef CONFIG_EGA 147 147 if (!bfb) { … … 151 151 } 152 152 #endif 153 153 154 154 /* Merge all memory zones to 1 big zone */ 155 155 zone_merge_all(); 156 156 } 157 157 158 158 /* Setup fast SYSCALL/SYSRET */ 159 159 syscall_setup_cpu(); … … 235 235 } 236 236 #endif 237 237 238 238 if (irqs_info != NULL) 239 239 sysinfo_set_item_val(irqs_info, NULL, true); -
kernel/arch/amd64/src/asm.S
r3061bc1 ra35b458 60 60 FUNCTION_BEGIN(memcpy_to_uspace) 61 61 movq MEMCPY_DST, %rax 62 62 63 63 movq MEMCPY_SIZE, %rcx 64 64 shrq $3, %rcx /* size / 8 */ 65 65 66 66 rep movsq /* copy as much as possible word by word */ 67 67 68 68 movq MEMCPY_SIZE, %rcx 69 69 andq $7, %rcx /* size % 8 */ 70 70 jz 0f 71 71 72 72 rep movsb /* copy the rest byte by byte */ 73 73 74 74 0: 75 75 ret /* return MEMCPY_SRC, success */ … … 92 92 popq %rax 93 93 movq %rax, %rdx 94 94 95 95 /* Flip the ID bit */ 96 96 xorl $RFLAGS_ID, %edx 97 97 98 98 /* Store RFLAGS */ 99 99 pushq %rdx 100 100 popfq 101 101 pushfq 102 102 103 103 /* Get the ID bit again */ 104 104 popq %rdx 105 105 andl $RFLAGS_ID, %eax 106 106 andl $RFLAGS_ID, %edx 107 107 108 108 /* 0 if not supported, 1 if supported */ 109 109 xorl %edx, %eax … … 114 114 /* Preserve %rbx across function calls */ 115 115 movq %rbx, %r10 116 116 117 117 /* Load the command into %eax */ 118 118 movl %edi, %eax 119 119 120 120 cpuid 121 121 movl %eax, 0(%rsi) … … 123 123 movl %ecx, 8(%rsi) 124 124 movl %edx, 12(%rsi) 125 125 126 126 movq %r10, %rbx 127 127 ret … … 161 161 * code. 162 162 */ 163 163 164 164 .iflt \i-32 165 165 .if (1 << \i) & ERROR_WORD_INTERRUPT_LIST … … 180 180 subq $(ISTATE_SOFT_SIZE + 8), %rsp 181 181 .endif 182 182 183 183 /* 184 184 * Save the general purpose registers. … … 230 230 movq $(\i), %rdi /* pass intnum in the first argument */ 231 231 movq %rsp, %rsi /* pass istate address in the second argument */ 232 232 233 233 cld 234 234 … … 250 250 movq ISTATE_OFFSET_R10(%rsp), %r10 251 251 movq ISTATE_OFFSET_R11(%rsp), %r11 252 252 253 253 /* $8 = Skip error word */ 254 254 addq $(ISTATE_SOFT_SIZE + 8), %rsp … … 288 288 /* Switch to hidden %gs */ 289 289 swapgs 290 290 291 291 movq %rsp, %gs:KSEG_OFFSET_USTACK_RSP /* save this thread's user RSP */ 292 292 movq %gs:KSEG_OFFSET_KSTACK_RSP, %rsp /* set this thread's kernel RSP */ … … 346 346 swapgs 347 347 sti 348 348 349 349 /* Copy the 4th argument where it is expected */ 350 350 movq %r10, %rcx … … 364 364 365 365 cli 366 366 367 367 /* 368 368 * Restore registers needed for return via the SYSRET instruction and … … 394 394 callq fault_from_uspace 395 395 /* not reached */ 396 396 397 397 bad_rip_msg: 398 398 .asciz "Invalid instruction pointer." … … 414 414 FUNCTION_BEGIN(early_putchar) 415 415 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB))) 416 416 417 417 /* Prologue, save preserved registers */ 418 418 pushq %rbp 419 419 movq %rsp, %rbp 420 420 pushq %rbx 421 421 422 422 movq %rdi, %rsi 423 423 movq $(PA2KA(0xb8000)), %rdi /* base of EGA text mode memory */ 424 424 xorl %eax, %eax 425 425 426 426 /* Read bits 8 - 15 of the cursor address */ 427 427 movw $0x3d4, %dx 428 428 movb $0xe, %al 429 429 outb %al, %dx 430 430 431 431 movw $0x3d5, %dx 432 432 inb %dx, %al 433 433 shl $8, %ax 434 434 435 435 /* Read bits 0 - 7 of the cursor address */ 436 436 movw $0x3d4, %dx 437 437 movb $0xf, %al 438 438 outb %al, %dx 439 439 440 440 movw $0x3d5, %dx 441 441 inb %dx, %al 442 442 443 443 /* Sanity check for the cursor on screen */ 444 444 cmp $2000, %ax 445 445 jb early_putchar_cursor_ok 446 446 447 447 movw $1998, %ax 448 448 449 449 early_putchar_cursor_ok: 450 450 451 451 movw %ax, %bx 452 452 shl $1, %rax 453 453 addq %rax, %rdi 454 454 455 455 movq %rsi, %rax 456 456 457 457 cmp $0x0a, %al 458 458 jne early_putchar_backspace 459 459 460 460 /* Interpret newline */ 461 461 462 462 movw %bx, %ax /* %bx -> %dx:%ax */ 463 463 xorw %dx, %dx 464 464 465 465 movw $80, %cx 466 466 idivw %cx, %ax /* %dx = %bx % 80 */ 467 467 468 468 /* %bx <- %bx + 80 - (%bx % 80) */ 469 469 addw %cx, %bx 470 470 subw %dx, %bx 471 471 472 472 jmp early_putchar_skip 473 473 474 474 early_putchar_backspace: 475 475 476 476 cmp $0x08, %al 477 477 jne early_putchar_print 478 478 479 479 /* Interpret backspace */ 480 480 481 481 cmp $0x0000, %bx 482 482 je early_putchar_skip 483 483 484 484 dec %bx 485 485 jmp early_putchar_skip 486 486 487 487 early_putchar_print: 488 488 489 489 /* Print character */ 490 490 491 491 movb $0x0e, %ah /* black background, yellow foreground */ 492 492 stosw 493 493 inc %bx 494 494 495 495 early_putchar_skip: 496 496 497 497 /* Sanity check for the cursor on the last line */ 498 498 cmp $2000, %bx 499 499 jb early_putchar_no_scroll 500 500 501 501 /* Scroll the screen (24 rows) */ 502 502 movq $(PA2KA(0xb80a0)), %rsi … … 504 504 movl $480, %ecx 505 505 rep movsq 506 506 507 507 /* Clear the 24th row */ 508 508 xorl %eax, %eax 509 509 movl $20, %ecx 510 510 rep stosq 511 511 512 512 /* Go to row 24 */ 513 513 movw $1920, %bx 514 514 515 515 early_putchar_no_scroll: 516 516 517 517 /* Write bits 8 - 15 of the cursor address */ 518 518 movw $0x3d4, %dx 519 519 movb $0xe, %al 520 520 outb %al, %dx 521 521 522 522 movw $0x3d5, %dx 523 523 movb %bh, %al 524 524 outb %al, %dx 525 525 526 526 /* Write bits 0 - 7 of the cursor address */ 527 527 movw $0x3d4, %dx 528 528 movb $0xf, %al 529 529 outb %al, %dx 530 530 531 531 movw $0x3d5, %dx 532 532 movb %bl, %al 533 533 outb %al, %dx 534 534 535 535 /* Epilogue, restore preserved registers */ 536 536 popq %rbx 537 537 leave 538 538 539 539 #endif 540 540 541 541 ret 542 542 FUNCTION_END(early_putchar) -
kernel/arch/amd64/src/boot/multiboot.S
r3061bc1 ra35b458 78 78 cli 79 79 cld 80 80 81 81 /* Initialize stack pointer */ 82 82 movl $START_STACK, %esp 83 83 84 84 /* 85 85 * Initialize Global Descriptor Table and … … 88 88 lgdtl bootstrap_gdtr 89 89 lidtl bootstrap_idtr 90 90 91 91 /* Kernel data + stack */ 92 92 movw $GDT_SELECTOR(KDATA_DES), %cx … … 94 94 movw %cx, %ds 95 95 movw %cx, %ss 96 96 97 97 /* 98 98 * Simics seems to remove hidden part of GS on entering user mode … … 102 102 movw %cx, %fs 103 103 movw %cx, %gs 104 104 105 105 jmpl $GDT_SELECTOR(KTEXT32_DES), $multiboot_meeting_point 106 106 multiboot_meeting_point: 107 107 108 108 /* 109 109 * Protected 32-bit. We want to reuse the code-seg descriptor, 110 110 * the Default operand size must not be 1 when entering long mode. 111 111 */ 112 112 113 113 /* Save multiboot arguments */ 114 114 movl %eax, multiboot_eax 115 115 movl %ebx, multiboot_ebx 116 116 117 117 pm_status $status_prot 118 118 119 119 movl $(INTEL_CPUID_EXTENDED), %eax 120 120 cpuid 121 121 cmp $(INTEL_CPUID_EXTENDED), %eax 122 122 ja extended_cpuid_supported 123 123 124 124 pm_error $err_extended_cpuid 125 125 126 126 extended_cpuid_supported: 127 127 128 128 movl $(AMD_CPUID_EXTENDED), %eax 129 129 cpuid 130 130 bt $(AMD_EXT_LONG_MODE), %edx 131 131 jc long_mode_supported 132 132 133 133 pm_error $err_long_mode 134 134 135 135 long_mode_supported: 136 136 137 137 bt $(AMD_EXT_NOEXECUTE), %edx 138 138 jc noexecute_supported 139 139 140 140 pm_error $err_noexecute 141 141 142 142 noexecute_supported: 143 143 144 144 movl $(INTEL_CPUID_STANDARD), %eax 145 145 cpuid 146 146 bt $(INTEL_FXSAVE), %edx 147 147 jc fx_supported 148 148 149 149 pm_error $err_fx 150 150 151 151 fx_supported: 152 152 153 153 bt $(INTEL_SSE2), %edx 154 154 jc sse2_supported 155 155 156 156 pm_error $err_sse2 157 157 158 158 sse2_supported: 159 159 160 160 #include "vesa_prot.inc" 161 161 162 162 pm2_status $status_prot2 163 163 164 164 /* 165 165 * Enable 64-bit page translation entries - CR4.PAE = 1. 166 166 * Paging is not enabled until after long mode is enabled. 167 167 */ 168 168 169 169 movl %cr4, %eax 170 170 orl $CR4_PAE, %eax 171 171 movl %eax, %cr4 172 172 173 173 /* Set up paging tables */ 174 174 leal ptl_0, %eax 175 175 movl %eax, %cr3 176 176 177 177 /* Enable long mode */ 178 178 movl $AMD_MSR_EFER, %ecx … … 180 180 orl $AMD_LME, %eax /* set LME = 1 */ 181 181 wrmsr 182 182 183 183 /* Enable paging to activate long mode (set CR0.PG = 1) */ 184 184 movl %cr0, %eax 185 185 orl $CR0_PG, %eax 186 186 movl %eax, %cr0 187 187 188 188 /* At this point we are in compatibility mode */ 189 189 jmpl $GDT_SELECTOR(KTEXT_DES), $start64 … … 204 204 movl $0xb8000, %edi /* base of EGA text mode memory */ 205 205 xorl %eax, %eax 206 206 207 207 /* Read bits 8 - 15 of the cursor address */ 208 208 movw $0x3d4, %dx 209 209 movb $0xe, %al 210 210 outb %al, %dx 211 211 212 212 movw $0x3d5, %dx 213 213 inb %dx, %al 214 214 shl $8, %ax 215 215 216 216 /* Read bits 0 - 7 of the cursor address */ 217 217 movw $0x3d4, %dx 218 218 movb $0xf, %al 219 219 outb %al, %dx 220 220 221 221 movw $0x3d5, %dx 222 222 inb %dx, %al 223 223 224 224 /* Sanity check for the cursor on screen */ 225 225 cmp $2000, %ax 226 226 jb err_cursor_ok 227 227 228 228 movw $1998, %ax 229 229 230 230 err_cursor_ok: 231 231 232 232 movw %ax, %bx 233 233 shl $1, %eax 234 234 addl %eax, %edi 235 235 236 236 err_ploop: 237 237 lodsb 238 238 239 239 cmp $0, %al 240 240 je err_ploop_end 241 241 242 242 movb $0x0c, %ah /* black background, light red foreground */ 243 243 stosw 244 244 245 245 /* Sanity check for the cursor on the last line */ 246 246 inc %bx 247 247 cmp $2000, %bx 248 248 jb err_ploop 249 249 250 250 /* Scroll the screen (24 rows) */ 251 251 movl %esi, %edx … … 254 254 movl $960, %ecx 255 255 rep movsl 256 256 257 257 /* Clear the 24th row */ 258 258 xorl %eax, %eax 259 259 movl $40, %ecx 260 260 rep stosl 261 261 262 262 /* Go to row 24 */ 263 263 movl %edx, %esi 264 264 movl $0xb8f00, %edi 265 265 movw $1920, %bx 266 266 267 267 jmp err_ploop 268 268 err_ploop_end: 269 269 270 270 /* Write bits 8 - 15 of the cursor address */ 271 271 movw $0x3d4, %dx 272 272 movb $0xe, %al 273 273 outb %al, %dx 274 274 275 275 movw $0x3d5, %dx 276 276 movb %bh, %al 277 277 outb %al, %dx 278 278 279 279 /* Write bits 0 - 7 of the cursor address */ 280 280 movw $0x3d4, %dx 281 281 movb $0xf, %al 282 282 outb %al, %dx 283 283 284 284 movw $0x3d5, %dx 285 285 movb %bl, %al 286 286 outb %al, %dx 287 287 288 288 cli 289 289 hlt1: … … 311 311 pushl %edx 312 312 pushl %edi 313 313 314 314 movl $0xb8000, %edi /* base of EGA text mode memory */ 315 315 xorl %eax, %eax 316 316 317 317 /* Read bits 8 - 15 of the cursor address */ 318 318 movw $0x3d4, %dx 319 319 movb $0xe, %al 320 320 outb %al, %dx 321 321 322 322 movw $0x3d5, %dx 323 323 inb %dx, %al 324 324 shl $8, %ax 325 325 326 326 /* Read bits 0 - 7 of the cursor address */ 327 327 movw $0x3d4, %dx 328 328 movb $0xf, %al 329 329 outb %al, %dx 330 330 331 331 movw $0x3d5, %dx 332 332 inb %dx, %al 333 333 334 334 /* Sanity check for the cursor on screen */ 335 335 cmp $2000, %ax 336 336 jb pm_puts_cursor_ok 337 337 338 338 movw $1998, %ax 339 339 340 340 pm_puts_cursor_ok: 341 341 342 342 movw %ax, %bx 343 343 shl $1, %eax 344 344 addl %eax, %edi 345 345 346 346 pm_puts_ploop: 347 347 lodsb 348 348 349 349 cmp $0, %al 350 350 je pm_puts_ploop_end 351 351 352 352 movb $0x0a, %ah /* black background, light green foreground */ 353 353 stosw 354 354 355 355 /* Sanity check for the cursor on the last line */ 356 356 inc %bx 357 357 cmp $2000, %bx 358 358 jb pm_puts_ploop 359 359 360 360 /* Scroll the screen (24 rows) */ 361 361 movl %esi, %edx … … 364 364 movl $960, %ecx 365 365 rep movsl 366 366 367 367 /* Clear the 24th row */ 368 368 xorl %eax, %eax 369 369 movl $40, %ecx 370 370 rep stosl 371 371 372 372 /* Go to row 24 */ 373 373 movl %edx, %esi 374 374 movl $0xb8f00, %edi 375 375 movw $1920, %bx 376 376 377 377 jmp pm_puts_ploop 378 378 pm_puts_ploop_end: 379 379 380 380 /* Write bits 8 - 15 of the cursor address */ 381 381 movw $0x3d4, %dx 382 382 movb $0xe, %al 383 383 outb %al, %dx 384 384 385 385 movw $0x3d5, %dx 386 386 movb %bh, %al 387 387 outb %al, %dx 388 388 389 389 /* Write bits 0 - 7 of the cursor address */ 390 390 movw $0x3d4, %dx 391 391 movb $0xf, %al 392 392 outb %al, %dx 393 393 394 394 movw $0x3d5, %dx 395 395 movb %bl, %al 396 396 outb %al, %dx 397 397 398 398 popl %edi 399 399 popl %edx … … 401 401 popl %ebx 402 402 popl %eax 403 403 404 404 ret 405 405 … … 414 414 415 415 start64: 416 416 417 417 /* 418 418 * Long mode. 419 419 */ 420 420 421 421 movq $(PA2KA(START_STACK)), %rsp 422 422 423 423 /* Create the first stack frame */ 424 424 pushq $0 425 425 movq %rsp, %rbp 426 426 427 427 long_status $status_long 428 428 429 429 /* Call amd64_pre_main(multiboot_eax, multiboot_ebx) */ 430 430 movl multiboot_eax, %edi 431 431 movl multiboot_ebx, %esi 432 432 433 433 #ifdef MEMORY_MODEL_large 434 434 movabsq $amd64_pre_main, %rax … … 437 437 callq amd64_pre_main 438 438 #endif 439 439 440 440 long_status $status_main 441 441 442 442 /* Call main_bsp() */ 443 443 #ifdef MEMORY_MODEL_large … … 447 447 callq main_bsp 448 448 #endif 449 449 450 450 /* Not reached */ 451 451 cli … … 468 468 */ 469 469 early_puts: 470 470 471 471 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB))) 472 472 473 473 /* Prologue, save preserved registers */ 474 474 pushq %rbp 475 475 movq %rsp, %rbp 476 476 pushq %rbx 477 477 478 478 movq %rdi, %rsi 479 479 movq $(PA2KA(0xb8000)), %rdi /* base of EGA text mode memory */ 480 480 xorq %rax, %rax 481 481 482 482 /* Read bits 8 - 15 of the cursor address */ 483 483 movw $0x3d4, %dx 484 484 movb $0xe, %al 485 485 outb %al, %dx 486 486 487 487 movw $0x3d5, %dx 488 488 inb %dx, %al 489 489 shl $8, %ax 490 490 491 491 /* Read bits 0 - 7 of the cursor address */ 492 492 movw $0x3d4, %dx 493 493 movb $0xf, %al 494 494 outb %al, %dx 495 495 496 496 movw $0x3d5, %dx 497 497 inb %dx, %al 498 498 499 499 /* Sanity check for the cursor on screen */ 500 500 cmp $2000, %ax 501 501 jb early_puts_cursor_ok 502 502 503 503 movw $1998, %ax 504 504 505 505 early_puts_cursor_ok: 506 506 507 507 movw %ax, %bx 508 508 shl $1, %rax 509 509 addq %rax, %rdi 510 510 511 511 early_puts_ploop: 512 512 lodsb 513 513 514 514 cmp $0, %al 515 515 je early_puts_ploop_end 516 516 517 517 movb $0x0e, %ah /* black background, yellow foreground */ 518 518 stosw 519 519 520 520 /* Sanity check for the cursor on the last line */ 521 521 inc %bx 522 522 cmp $2000, %bx 523 523 jb early_puts_ploop 524 524 525 525 /* Scroll the screen (24 rows) */ 526 526 movq %rsi, %rdx … … 529 529 movl $480, %ecx 530 530 rep movsq 531 531 532 532 /* Clear the 24th row */ 533 533 xorl %eax, %eax 534 534 movl $20, %ecx 535 535 rep stosq 536 536 537 537 /* Go to row 24 */ 538 538 movq %rdx, %rsi 539 539 movq $(PA2KA(0xb8f00)), %rdi 540 540 movw $1920, %bx 541 541 542 542 jmp early_puts_ploop 543 543 early_puts_ploop_end: 544 544 545 545 /* Write bits 8 - 15 of the cursor address */ 546 546 movw $0x3d4, %dx 547 547 movb $0xe, %al 548 548 outb %al, %dx 549 549 550 550 movw $0x3d5, %dx 551 551 movb %bh, %al 552 552 outb %al, %dx 553 553 554 554 /* Write bits 0 - 7 of the cursor address */ 555 555 movw $0x3d4, %dx 556 556 movb $0xf, %al 557 557 outb %al, %dx 558 558 559 559 movw $0x3d5, %dx 560 560 movb %bl, %al 561 561 outb %al, %dx 562 562 563 563 /* Epilogue, restore preserved registers */ 564 564 popq %rbx 565 565 leave 566 566 567 567 #endif 568 568 569 569 ret 570 570 -
kernel/arch/amd64/src/boot/multiboot2.S
r3061bc1 ra35b458 47 47 .long multiboot2_header_end - multiboot2_header_start 48 48 .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_HEADER_ARCH_I386 + (multiboot2_header_end - multiboot2_header_start)) 49 49 50 50 /* Information request tag */ 51 51 .align 8 … … 61 61 #endif 62 62 tag_info_req_end: 63 63 64 64 /* Address tag */ 65 65 .align 8 … … 73 73 .long 0 74 74 tag_address_end: 75 75 76 76 /* Entry address tag */ 77 77 .align 8 … … 82 82 .long multiboot2_image_start 83 83 tag_entry_address_end: 84 84 85 85 /* Flags tag */ 86 86 .align 8 … … 91 91 .long MULTIBOOT2_FLAGS_CONSOLE 92 92 tag_flags_end: 93 93 94 94 #ifdef CONFIG_FB 95 95 /* Framebuffer tag */ … … 104 104 tag_framebuffer_end: 105 105 #endif 106 106 107 107 /* Module alignment tag */ 108 108 .align 8 … … 113 113 .long 0 114 114 tag_module_align_end: 115 115 116 116 /* Tag terminator */ 117 117 .align 8 … … 126 126 cli 127 127 cld 128 128 129 129 /* Initialize stack pointer */ 130 130 movl $START_STACK, %esp 131 131 132 132 /* 133 133 * Initialize Global Descriptor Table and … … 136 136 lgdtl bootstrap_gdtr 137 137 lidtl bootstrap_idtr 138 138 139 139 /* Kernel data + stack */ 140 140 movw $GDT_SELECTOR(KDATA_DES), %cx … … 142 142 movw %cx, %ds 143 143 movw %cx, %ss 144 144 145 145 /* 146 146 * Simics seems to remove hidden part of GS on entering user mode … … 150 150 movw %cx, %fs 151 151 movw %cx, %gs 152 152 153 153 jmpl $GDT_SELECTOR(KTEXT32_DES), $multiboot2_meeting_point 154 154 multiboot2_meeting_point: 155 155 156 156 /* 157 157 * Protected 32-bit. We want to reuse the code-seg descriptor, 158 158 * the Default operand size must not be 1 when entering long mode. 159 159 */ 160 160 161 161 /* Save multiboot arguments */ 162 162 movl %eax, multiboot_eax 163 163 movl %ebx, multiboot_ebx 164 164 165 165 movl $(INTEL_CPUID_EXTENDED), %eax 166 166 cpuid 167 167 cmp $(INTEL_CPUID_EXTENDED), %eax 168 168 ja extended_cpuid_supported 169 170 jmp pm_error_halt 171 169 170 jmp pm_error_halt 171 172 172 extended_cpuid_supported: 173 173 174 174 movl $(AMD_CPUID_EXTENDED), %eax 175 175 cpuid 176 176 bt $(AMD_EXT_LONG_MODE), %edx 177 177 jc long_mode_supported 178 179 jmp pm_error_halt 180 178 179 jmp pm_error_halt 180 181 181 long_mode_supported: 182 182 183 183 bt $(AMD_EXT_NOEXECUTE), %edx 184 184 jc noexecute_supported 185 186 jmp pm_error_halt 187 185 186 jmp pm_error_halt 187 188 188 noexecute_supported: 189 189 190 190 movl $(INTEL_CPUID_STANDARD), %eax 191 191 cpuid 192 192 bt $(INTEL_FXSAVE), %edx 193 193 jc fx_supported 194 195 jmp pm_error_halt 196 194 195 jmp pm_error_halt 196 197 197 fx_supported: 198 198 199 199 bt $(INTEL_SSE2), %edx 200 200 jc sse2_supported 201 202 jmp pm_error_halt 203 201 202 jmp pm_error_halt 203 204 204 sse2_supported: 205 205 206 206 /* 207 207 * Enable 64-bit page translation entries - CR4.PAE = 1. 208 208 * Paging is not enabled until after long mode is enabled. 209 209 */ 210 210 211 211 movl %cr4, %eax 212 212 orl $CR4_PAE, %eax 213 213 movl %eax, %cr4 214 214 215 215 /* Set up paging tables */ 216 216 leal ptl_0, %eax 217 217 movl %eax, %cr3 218 218 219 219 /* Enable long mode */ 220 220 movl $AMD_MSR_EFER, %ecx … … 222 222 orl $AMD_LME, %eax /* set LME = 1 */ 223 223 wrmsr 224 224 225 225 /* Enable paging to activate long mode (set CR0.PG = 1) */ 226 226 movl %cr0, %eax 227 227 orl $CR0_PG, %eax 228 228 movl %eax, %cr0 229 229 230 230 /* At this point we are in compatibility mode */ 231 231 jmpl $GDT_SELECTOR(KTEXT_DES), $start64 … … 240 240 241 241 start64: 242 242 243 243 /* 244 244 * Long mode. 245 245 */ 246 246 247 247 movq $(PA2KA(START_STACK)), %rsp 248 248 249 249 /* Create the first stack frame */ 250 250 pushq $0 251 251 movq %rsp, %rbp 252 252 253 253 /* Call amd64_pre_main(multiboot_eax, multiboot_ebx) */ 254 254 movl multiboot_eax, %edi 255 255 movl multiboot_ebx, %esi 256 256 257 257 #ifdef MEMORY_MODEL_large 258 258 movabsq $amd64_pre_main, %rax … … 261 261 callq amd64_pre_main 262 262 #endif 263 263 264 264 /* Call main_bsp() */ 265 265 #ifdef MEMORY_MODEL_large … … 269 269 callq main_bsp 270 270 #endif 271 271 272 272 /* Not reached */ 273 273 cli -
kernel/arch/amd64/src/context.S
r3061bc1 ra35b458 40 40 FUNCTION_BEGIN(context_save_arch) 41 41 movq (%rsp), %rdx # the caller's return %rip 42 42 43 43 movq %rdx, CONTEXT_OFFSET_PC(%rdi) 44 44 movq %rsp, CONTEXT_OFFSET_SP(%rdi) 45 45 46 46 movq %rbx, CONTEXT_OFFSET_RBX(%rdi) 47 47 movq %rbp, CONTEXT_OFFSET_RBP(%rdi) … … 50 50 movq %r14, CONTEXT_OFFSET_R14(%rdi) 51 51 movq %r15, CONTEXT_OFFSET_R15(%rdi) 52 52 53 53 #ifdef MEMORY_MODEL_large 54 54 movabsq $vreg_ptr, %rsi … … 59 59 movq %fs:VREG_TP(%rsi), %rsi 60 60 movq %rsi, CONTEXT_OFFSET_TP(%rdi) 61 61 62 62 xorl %eax, %eax # context_save returns 1 63 63 incl %eax … … 78 78 movq CONTEXT_OFFSET_RBP(%rdi), %rbp 79 79 movq CONTEXT_OFFSET_RBX(%rdi), %rbx 80 80 81 81 movq CONTEXT_OFFSET_SP(%rdi), %rsp 82 82 83 83 movq CONTEXT_OFFSET_PC(%rdi), %rdx 84 84 movq %rdx, (%rsp) 85 85 86 86 movq CONTEXT_OFFSET_TP(%rdi), %rcx 87 87 #ifdef MEMORY_MODEL_large … … 92 92 #endif 93 93 movq %rcx, %fs:VREG_TP(%rsi) 94 94 95 95 xorl %eax, %eax # context_restore returns 0 96 96 ret -
kernel/arch/amd64/src/cpu/cpu.c
r3061bc1 ra35b458 106 106 { 107 107 cpu_info_t info; 108 108 109 109 CPU->arch.vendor = VendorUnknown; 110 110 if (has_cpuid()) { 111 111 cpuid(INTEL_CPUID_LEVEL, &info); 112 112 113 113 /* 114 114 * Check for AMD processor. … … 119 119 CPU->arch.vendor = VendorAMD; 120 120 } 121 121 122 122 /* 123 123 * Check for Intel processor. … … 128 128 CPU->arch.vendor = VendorIntel; 129 129 } 130 130 131 131 cpuid(INTEL_CPUID_STANDARD, &info); 132 132 CPU->arch.family = (info.cpuid_eax >> 8) & 0xf; -
kernel/arch/amd64/src/ddi/ddi.c
r3061bc1 ra35b458 59 59 /* First, copy the I/O Permission Bitmap. */ 60 60 irq_spinlock_lock(&TASK->lock, false); 61 61 62 62 size_t ver = TASK->arch.iomapver; 63 63 size_t elements = TASK->arch.iomap.elements; 64 64 65 65 if (elements > 0) { 66 66 assert(TASK->arch.iomap.bits); 67 67 68 68 bitmap_t iomap; 69 69 bitmap_initialize(&iomap, TSS_IOMAP_SIZE * 8, 70 70 CPU->arch.tss->iomap); 71 71 bitmap_copy(&iomap, &TASK->arch.iomap, elements); 72 72 73 73 /* 74 74 * Set the trailing bits in the last byte of the map to disable … … 77 77 bitmap_set_range(&iomap, elements, 78 78 ALIGN_UP(elements, 8) - elements); 79 79 80 80 /* 81 81 * It is safe to set the trailing eight bits because of the … … 84 84 bitmap_set_range(&iomap, ALIGN_UP(elements, 8), 8); 85 85 } 86 86 87 87 irq_spinlock_unlock(&TASK->lock, false); 88 88 89 89 /* 90 90 * Second, adjust TSS segment limit. … … 93 93 ptr_16_64_t cpugdtr; 94 94 gdtr_store(&cpugdtr); 95 95 96 96 descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base; 97 97 size_t size = bitmap_size(elements); 98 98 gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + size); 99 99 gdtr_load(&cpugdtr); 100 100 101 101 /* 102 102 * Before we load new TSS limit, the current TSS descriptor … … 106 106 tss_desc->type = AR_TSS; 107 107 tr_load(GDT_SELECTOR(TSS_DES)); 108 108 109 109 /* 110 110 * Update the generation count so that faults caused by -
kernel/arch/amd64/src/debug/stacktrace.c
r3061bc1 ra35b458 50 50 uint64_t *stack = (void *) ctx->fp; 51 51 *prev = stack[FRAME_OFFSET_FP_PREV]; 52 52 53 53 return true; 54 54 } … … 58 58 uint64_t *stack = (void *) ctx->fp; 59 59 *ra = stack[FRAME_OFFSET_RA]; 60 60 61 61 return true; 62 62 } -
kernel/arch/amd64/src/delay.S
r3061bc1 ra35b458 39 39 dec %rdi 40 40 jnz 0b 41 41 42 42 ret 43 43 FUNCTION_END(asm_delay_loop) … … 47 47 dec %rdi 48 48 jz 0b 49 49 50 50 ret 51 51 FUNCTION_END(asm_fake_loop) -
kernel/arch/amd64/src/interrupt.c
r3061bc1 ra35b458 70 70 "rfl=%0#18" PRIx64 "\terr=%0#18" PRIx64 "\n", 71 71 istate->cs, istate->rip, istate->rflags, istate->error_word); 72 72 73 73 if (istate_from_uspace(istate)) 74 74 log_printf("ss =%0#18" PRIx64 "\n", istate->ss); 75 75 76 76 log_printf("rax=%0#18" PRIx64 "\trbx=%0#18" PRIx64 "\t" 77 77 "rcx=%0#18" PRIx64 "\trdx=%0#18" PRIx64 "\n", 78 78 istate->rax, istate->rbx, istate->rcx, istate->rdx); 79 79 80 80 log_printf("rsi=%0#18" PRIx64 "\trdi=%0#18" PRIx64 "\t" 81 81 "rbp=%0#18" PRIx64 "\trsp=%0#18" PRIx64 "\n", … … 83 83 istate_from_uspace(istate) ? istate->rsp : 84 84 (uintptr_t) &istate->rsp); 85 85 86 86 log_printf("r8 =%0#18" PRIx64 "\tr9 =%0#18" PRIx64 "\t" 87 87 "r10=%0#18" PRIx64 "\tr11=%0#18" PRIx64 "\n", 88 88 istate->r8, istate->r9, istate->r10, istate->r11); 89 89 90 90 log_printf("r12=%0#18" PRIx64 "\tr13=%0#18" PRIx64 "\t" 91 91 "r14=%0#18" PRIx64 "\tr15=%0#18" PRIx64 "\n", … … 123 123 size_t ver = TASK->arch.iomapver; 124 124 irq_spinlock_unlock(&TASK->lock, false); 125 125 126 126 if (CPU->arch.iomapver_copy != ver) { 127 127 /* … … 176 176 { 177 177 assert(n >= IVT_IRQBASE); 178 178 179 179 unsigned int inum = n - IVT_IRQBASE; 180 180 bool ack = false; 181 181 assert(inum < IRQ_COUNT); 182 182 assert((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1)); 183 183 184 184 irq_t *irq = irq_dispatch_and_lock(inum); 185 185 if (irq) { … … 187 187 * The IRQ handler was found. 188 188 */ 189 189 190 190 if (irq->preack) { 191 191 /* Send EOI before processing the interrupt */ … … 204 204 #endif 205 205 } 206 206 207 207 if (!ack) 208 208 trap_virtual_eoi(); … … 212 212 { 213 213 unsigned int i; 214 214 215 215 for (i = 0; i < IVT_ITEMS; i++) 216 216 exc_register(i, "null", false, (iroutine_t) null_interrupt); 217 217 218 218 for (i = 0; i < IRQ_COUNT; i++) { 219 219 if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1)) … … 221 221 (iroutine_t) irq_interrupt); 222 222 } 223 223 224 224 exc_register(VECTOR_DE, "de_fault", true, (iroutine_t) de_fault); 225 225 exc_register(VECTOR_NM, "nm_fault", true, (iroutine_t) nm_fault); 226 226 exc_register(VECTOR_SS, "ss_fault", true, (iroutine_t) ss_fault); 227 227 exc_register(VECTOR_GP, "gp_fault", true, (iroutine_t) gp_fault); 228 228 229 229 #ifdef CONFIG_SMP 230 230 exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", true, -
kernel/arch/amd64/src/mm/page.c
r3061bc1 ra35b458 57 57 unsigned int identity_flags = 58 58 PAGE_GLOBAL | PAGE_CACHEABLE | PAGE_EXEC | PAGE_WRITE | PAGE_READ; 59 59 60 60 page_mapping_operations = &pt_mapping_operations; 61 61 62 62 page_table_lock(AS_KERNEL, true); 63 63 64 64 /* 65 65 * PA2KA(identity) mapping for all low-memory frames. … … 68 68 cur += FRAME_SIZE) 69 69 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags); 70 70 71 71 page_table_unlock(AS_KERNEL, true); 72 72 73 73 exc_register(VECTOR_PF, "page_fault", true, (iroutine_t) page_fault); 74 74 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); … … 78 78 { 79 79 uintptr_t badvaddr = read_cr2(); 80 80 81 81 if (istate->error_word & PFERR_CODE_RSVD) 82 82 panic("Reserved bit set in page table entry."); 83 83 84 84 pf_access_t access; 85 85 86 86 if (istate->error_word & PFERR_CODE_RW) 87 87 access = PF_ACCESS_WRITE; … … 90 90 else 91 91 access = PF_ACCESS_READ; 92 92 93 93 (void) as_page_fault(badvaddr, access, istate); 94 94 } -
kernel/arch/amd64/src/pm.c
r3061bc1 ra35b458 130 130 { 131 131 tss_descriptor_t *td = (tss_descriptor_t *) d; 132 132 133 133 td->base_0_15 = base & 0xffffU; 134 134 td->base_16_23 = ((base) >> 16) & 0xffU; … … 140 140 { 141 141 tss_descriptor_t *td = (tss_descriptor_t *) d; 142 142 143 143 td->limit_0_15 = limit & 0xffffU; 144 144 td->limit_16_19 = (limit >> 16) & 0x0fU; … … 167 167 idescriptor_t *d; 168 168 unsigned int i; 169 169 170 170 for (i = 0; i < IDT_ITEMS; i++) { 171 171 d = &idt[i]; 172 172 173 173 d->unused = 0; 174 174 d->selector = GDT_SELECTOR(KTEXT_DES); 175 175 176 176 d->present = 1; 177 177 d->type = AR_INTERRUPT; /* masking interrupt */ 178 178 } 179 179 180 180 d = &idt[0]; 181 181 idt_setoffset(d++, (uintptr_t) &int_0); … … 252 252 descriptor_t *gdt_p = (descriptor_t *) gdtr.base; 253 253 tss_descriptor_t *tss_desc; 254 254 255 255 /* 256 256 * Each CPU has its private GDT and TSS. 257 257 * All CPUs share one IDT. 258 258 */ 259 259 260 260 if (config.cpu_active == 1) { 261 261 idt_init(); … … 270 270 * ahead of page_init */ 271 271 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); 272 272 273 273 tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); 274 274 if (!tss_p) 275 275 panic("Cannot allocate TSS."); 276 276 } 277 277 278 278 tss_initialize(tss_p); 279 279 280 280 tss_desc = (tss_descriptor_t *) (&gdt_p[TSS_DES]); 281 281 tss_desc->present = 1; 282 282 tss_desc->type = AR_TSS; 283 283 tss_desc->dpl = PL_KERNEL; 284 284 285 285 gdt_tss_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p); 286 286 gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1); 287 287 288 288 gdtr_load(&gdtr); 289 289 idtr_load(&idtr); -
kernel/arch/amd64/src/smp/ap.S
r3061bc1 ra35b458 55 55 xorw %ax, %ax 56 56 movw %ax, %ds 57 57 58 58 lgdtl ap_gdtr # initialize Global Descriptor Table register 59 59 60 60 movl %cr0, %eax 61 61 orl $CR0_PE, %eax … … 71 71 movw $GDT_SELECTOR(UDATA_DES), %ax 72 72 movw %ax, %gs 73 73 74 74 # Enable 64-bit page transaltion entries (CR4.PAE = 1). 75 75 # Paging is not enabled until after long mode is enabled 76 76 77 77 movl %cr4, %eax 78 78 orl $CR4_PAE, %eax 79 79 movl %eax, %cr4 80 80 81 81 leal ptl_0, %eax 82 82 movl %eax, %cr3 83 83 84 84 # Enable long mode 85 85 movl $AMD_MSR_EFER, %ecx # EFER MSR number … … 87 87 orl $AMD_LME, %eax # Set LME=1 88 88 wrmsr # Write EFER 89 89 90 90 # Enable paging to activate long mode (set CR0.PG = 1) 91 91 movl %cr0, %eax 92 92 orl $CR0_PG, %eax 93 93 movl %eax, %cr0 94 94 95 95 # At this point we are in compatibility mode 96 96 jmpl $GDT_SELECTOR(KTEXT_DES), $start64 - BOOT_OFFSET + AP_BOOT_OFFSET … … 100 100 movabsq $ctx, %rsp 101 101 movq CONTEXT_OFFSET_SP(%rsp), %rsp 102 102 103 103 pushq $0 104 104 movq %rsp, %rbp 105 105 106 106 movabsq $main_ap, %rax 107 107 callq *%rax # never returns -
kernel/arch/amd64/src/syscall.c
r3061bc1 ra35b458 51 51 52 52 /* Setup syscall entry address */ 53 53 54 54 /* This is _mess_ - the 64-bit CS is argument + 16, 55 55 * the SS is argument + 8. The order is: -
kernel/arch/amd64/src/userspace.c
r3061bc1 ra35b458 49 49 { 50 50 uint64_t rflags = read_rflags(); 51 51 52 52 rflags &= ~RFLAGS_NT; 53 53 rflags |= RFLAGS_IF; 54 54 55 55 asm volatile ( 56 56 "pushq %[udata_des]\n" … … 60 60 "pushq %[entry]\n" 61 61 "movq %[uarg], %%rax\n" 62 62 63 63 /* %rdi is defined to hold pcb_ptr - set it to 0 */ 64 64 "xorq %%rdi, %%rdi\n" … … 73 73 : "rax" 74 74 ); 75 75 76 76 /* Unreachable */ 77 77 while (1);
Note:
See TracChangeset
for help on using the changeset viewer.