Changeset a35b458 in mainline for kernel/arch/ia32/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/ia32/src
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/src/asm.S
r3061bc1 ra35b458 63 63 movl %edi, %edx /* save %edi */ 64 64 movl %esi, %eax /* save %esi */ 65 65 66 66 movl MEMCPY_SIZE(%esp), %ecx 67 67 shrl $2, %ecx /* size / 4 */ 68 68 69 69 movl MEMCPY_DST(%esp), %edi 70 70 movl MEMCPY_SRC(%esp), %esi 71 71 72 72 /* Copy whole words */ 73 73 rep movsl 74 74 75 75 movl MEMCPY_SIZE(%esp), %ecx 76 76 andl $3, %ecx /* size % 4 */ 77 77 jz 0f 78 78 79 79 /* Copy the rest byte by byte */ 80 80 rep movsb 81 81 82 82 0: 83 83 84 84 movl %edx, %edi 85 85 movl %eax, %esi 86 86 87 87 /* MEMCPY_DST(%esp), success */ 88 88 movl MEMCPY_DST(%esp), %eax … … 99 99 movl %edx, %edi 100 100 movl %eax, %esi 101 101 102 102 /* Return 0, failure */ 103 103 xorl %eax, %eax … … 112 112 movl %cr0, %edx 113 113 orl $CR0_PG, %edx /* paging on */ 114 114 115 115 /* Clear Cache Disable and not Write Though */ 116 116 andl $~(CR0_CD | CR0_NW), %edx 117 117 movl %edx, %cr0 118 118 jmp 0f 119 119 120 120 0: 121 121 ret … … 174 174 movl %edi, ISTATE_OFFSET_EDI(%esp) /* observability; not needed */ 175 175 movl %ebp, ISTATE_OFFSET_EBP(%esp) /* observability; not needed */ 176 176 177 177 /* 178 178 * Fake up the stack trace linkage. … … 190 190 movl $(GDT_SELECTOR(VREG_DES)), %eax 191 191 movl %eax, %gs 192 192 193 193 /* 194 194 * Sanitize EFLAGS. … … 207 207 208 208 call syscall_handler 209 209 210 210 /* 211 211 * Prepare return address and userspace stack for SYSEXIT. … … 252 252 movl %es, %ecx 253 253 movl %ds, %edx 254 254 255 255 movl %ecx, ISTATE_OFFSET_ES(%esp) 256 256 movl %edx, ISTATE_OFFSET_DS(%esp) … … 264 264 movl $(GDT_SELECTOR(VREG_DES)), %eax 265 265 movl %eax, %gs 266 266 267 267 movl $0, ISTATE_OFFSET_EBP_FRAME(%esp) 268 268 movl ISTATE_OFFSET_EIP(%esp), %eax 269 269 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 270 270 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 271 271 272 272 cld 273 273 274 274 /* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */ 275 275 call syscall_handler 276 276 277 277 /* 278 278 * Restore the segment registers. … … 286 286 movl ISTATE_OFFSET_ES(%esp), %ecx 287 287 movl ISTATE_OFFSET_DS(%esp), %edx 288 288 289 289 movl %ecx, %es 290 290 movl %edx, %ds 291 291 292 292 /* 293 293 * Restore the preserved registers the handler cloberred itself … … 295 295 */ 296 296 movl ISTATE_OFFSET_EBP(%esp), %ebp 297 297 298 298 addl $(ISTATE_SOFT_SIZE + 4), %esp 299 299 iret 300 300 301 301 /** 302 302 * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int … … 333 333 subl $(ISTATE_SOFT_SIZE + 4), %esp 334 334 .endif 335 335 336 336 /* 337 337 * Save the general purpose registers. … … 344 344 movl %esi, ISTATE_OFFSET_ESI(%esp) 345 345 movl %ebp, ISTATE_OFFSET_EBP(%esp) 346 346 347 347 /* 348 348 * Save the segment registers. … … 356 356 movl %es, %ecx 357 357 movl %ds, %edx 358 358 359 359 movl %ecx, ISTATE_OFFSET_ES(%esp) 360 360 movl %edx, ISTATE_OFFSET_DS(%esp) 361 361 362 362 /* 363 363 * Switch to kernel selectors. … … 368 368 movl $(GDT_SELECTOR(VREG_DES)), %eax 369 369 movl %eax, %gs 370 370 371 371 /* 372 372 * Imitate a regular stack frame linkage. … … 387 387 movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp) 388 388 leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp 389 389 390 390 cld 391 391 392 392 pushl %esp /* pass istate address */ 393 393 pushl $(\i) /* pass intnum */ 394 394 395 395 /* Call exc_dispatch(intnum, istate) */ 396 396 call exc_dispatch 397 397 398 398 addl $8, %esp /* clear arguments from the stack */ 399 399 400 400 /* 401 401 * Restore the selector registers. … … 409 409 movl ISTATE_OFFSET_ES(%esp), %ecx 410 410 movl ISTATE_OFFSET_DS(%esp), %edx 411 411 412 412 movl %ecx, %es 413 413 movl %edx, %ds 414 414 415 415 /* 416 416 * Restore the scratch registers and the preserved … … 422 422 movl ISTATE_OFFSET_EDX(%esp), %edx 423 423 movl ISTATE_OFFSET_EBP(%esp), %ebp 424 424 425 425 addl $(ISTATE_SOFT_SIZE + 4), %esp 426 426 iret … … 452 452 */ 453 453 FUNCTION_BEGIN(early_putchar) 454 454 455 455 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB))) 456 456 457 457 /* Prologue, save preserved registers */ 458 458 pushl %ebp … … 461 461 pushl %esi 462 462 pushl %edi 463 463 464 464 movl $(PA2KA(0xb8000)), %edi /* base of EGA text mode memory */ 465 465 xorl %eax, %eax 466 466 467 467 /* Read bits 8 - 15 of the cursor address */ 468 468 movw $0x3d4, %dx 469 469 movb $0xe, %al 470 470 outb %al, %dx 471 471 472 472 movw $0x3d5, %dx 473 473 inb %dx, %al 474 474 shl $8, %ax 475 475 476 476 /* Read bits 0 - 7 of the cursor address */ 477 477 movw $0x3d4, %dx 478 478 movb $0xf, %al 479 479 outb %al, %dx 480 480 481 481 movw $0x3d5, %dx 482 482 inb %dx, %al 483 483 484 484 /* Sanity check for the cursor on screen */ 485 485 cmp $2000, %ax 486 486 jb early_putchar_cursor_ok 487 487 488 488 movw $1998, %ax 489 489 490 490 early_putchar_cursor_ok: 491 491 492 492 movw %ax, %bx 493 493 shl $1, %eax 494 494 addl %eax, %edi 495 495 496 496 movl 0x08(%ebp), %eax 497 497 498 498 cmp $0x0a, %al 499 499 jne early_putchar_backspace 500 500 501 501 /* Interpret newline */ 502 502 503 503 movw %bx, %ax /* %bx -> %dx:%ax */ 504 504 xorw %dx, %dx 505 505 506 506 movw $80, %cx 507 507 idivw %cx, %ax /* %dx = %bx % 80 */ 508 508 509 509 /* %bx <- %bx + 80 - (%bx % 80) */ 510 510 addw %cx, %bx 511 511 subw %dx, %bx 512 512 513 513 jmp early_putchar_skip 514 514 515 515 early_putchar_backspace: 516 516 517 517 cmp $0x08, %al 518 518 jne early_putchar_print 519 519 520 520 /* Interpret backspace */ 521 521 522 522 cmp $0x0000, %bx 523 523 je early_putchar_skip 524 524 525 525 dec %bx 526 526 jmp early_putchar_skip 527 527 528 528 early_putchar_print: 529 529 530 530 /* Print character */ 531 531 532 532 movb $0x0e, %ah /* black background, yellow foreground */ 533 533 stosw 534 534 inc %bx 535 535 536 536 early_putchar_skip: 537 537 538 538 /* Sanity check for the cursor on the last line */ 539 539 cmp $2000, %bx 540 540 jb early_putchar_no_scroll 541 541 542 542 /* Scroll the screen (24 rows) */ 543 543 movl $(PA2KA(0xb80a0)), %esi … … 545 545 movl $960, %ecx 546 546 rep movsl 547 547 548 548 /* Clear the 24th row */ 549 549 xorl %eax, %eax 550 550 movl $40, %ecx 551 551 rep stosl 552 552 553 553 /* Go to row 24 */ 554 554 movw $1920, %bx 555 555 556 556 early_putchar_no_scroll: 557 557 558 558 /* Write bits 8 - 15 of the cursor address */ 559 559 movw $0x3d4, %dx 560 560 movb $0xe, %al 561 561 outb %al, %dx 562 562 563 563 movw $0x3d5, %dx 564 564 movb %bh, %al 565 565 outb %al, %dx 566 566 567 567 /* Write bits 0 - 7 of the cursor address */ 568 568 movw $0x3d4, %dx 569 569 movb $0xf, %al 570 570 outb %al, %dx 571 571 572 572 movw $0x3d5, %dx 573 573 movb %bl, %al 574 574 outb %al, %dx 575 575 576 576 /* Epilogue, restore preserved registers */ 577 577 popl %edi … … 579 579 popl %ebx 580 580 leave 581 581 582 582 #endif 583 583 584 584 ret 585 585 FUNCTION_END(early_putchar) -
kernel/arch/ia32/src/atomic.S
r3061bc1 ra35b458 39 39 pushl %eax 40 40 pushl %ebx 41 41 42 42 movl 12(%esp),%ebx 43 43 … … 56 56 ret 57 57 FUNCTION_END(spinlock_arch) 58 58 59 59 #endif -
kernel/arch/ia32/src/boot/multiboot.S
r3061bc1 ra35b458 77 77 cli 78 78 cld 79 79 80 80 /* Initialize stack pointer */ 81 81 movl $START_STACK, %esp 82 82 83 83 /* 84 84 * Initialize Global Descriptor Table and … … 87 87 lgdtl bootstrap_gdtr 88 88 lidtl bootstrap_idtr 89 89 90 90 /* Kernel data + stack */ 91 91 movw $GDT_SELECTOR(KDATA_DES), %cx … … 95 95 movw %cx, %ds 96 96 movw %cx, %ss 97 97 98 98 jmpl $GDT_SELECTOR(KTEXT_DES), $multiboot_meeting_point 99 99 multiboot_meeting_point: 100 100 101 101 /* Save multiboot arguments */ 102 102 movl %eax, multiboot_eax 103 103 movl %ebx, multiboot_ebx 104 104 105 105 pm_status $status_prot 106 106 107 107 #include "vesa_prot.inc" 108 108 109 109 #ifndef PROCESSOR_i486 110 110 111 111 pm_status $status_prot2 112 112 113 113 movl $(INTEL_CPUID_LEVEL), %eax 114 114 cpuid 115 115 cmp $0x0, %eax /* any function > 0? */ 116 116 jbe pse_unsupported 117 117 118 118 movl $(INTEL_CPUID_STANDARD), %eax 119 119 cpuid 120 120 bt $(INTEL_PSE), %edx 121 121 jnc pse_unsupported 122 122 123 123 /* Map kernel and turn paging on */ 124 124 pm_status $status_pse 125 125 call map_kernel_pse 126 126 jmp stack_init 127 127 128 128 #endif /* PROCESSOR_i486 */ 129 129 130 130 pse_unsupported: 131 131 132 132 /* Map kernel and turn paging on */ 133 133 pm_status $status_non_pse 134 134 call map_kernel_non_pse 135 135 136 136 stack_init: 137 137 138 138 /* Create the first stack frame */ 139 139 pushl $0 140 140 movl %esp, %ebp 141 141 142 142 pm2_status $status_prot3 143 143 144 144 /* Call ia32_pre_main(multiboot_eax, multiboot_ebx) */ 145 145 pushl multiboot_ebx 146 146 pushl multiboot_eax 147 147 call ia32_pre_main 148 148 149 149 pm2_status $status_main 150 150 151 151 /* Call main_bsp() */ 152 152 call main_bsp 153 153 154 154 /* Not reached */ 155 155 cli … … 170 170 andl $~CR4_PAE, %ecx /* PAE off */ 171 171 movl %ecx, %cr4 172 172 173 173 movl $(page_directory + 0), %esi 174 174 movl $(page_directory + 2048), %edi 175 175 xorl %ecx, %ecx 176 176 xorl %ebx, %ebx 177 177 178 178 floop_pse: 179 179 movl $(PDE_4M | PDE_RW | PDE_P), %eax … … 184 184 movl %eax, (%edi, %ecx, 4) 185 185 addl $(4 * 1024 * 1024), %ebx 186 186 187 187 incl %ecx 188 188 cmpl $512, %ecx 189 189 jl floop_pse 190 190 191 191 movl %esi, %cr3 192 192 193 193 movl %cr0, %ebx 194 194 orl $CR0_PG, %ebx /* paging on */ … … 208 208 andl $~CR4_PAE, %ecx /* PAE off */ 209 209 movl %ecx, %cr4 210 210 211 211 call calc_kernel_end 212 212 call find_mem_for_pt 213 213 214 214 mov kernel_end, %esi 215 215 mov free_area, %ecx 216 216 217 217 cmpl %esi, %ecx 218 218 jbe use_kernel_end 219 219 220 220 mov %ecx, %esi 221 221 222 222 /* Align address down to 4k */ 223 223 andl $(~(PAGE_SIZE - 1)), %esi 224 224 225 225 use_kernel_end: 226 226 227 227 /* Align address to 4k */ 228 228 addl $(PAGE_SIZE - 1), %esi 229 229 andl $(~(PAGE_SIZE - 1)), %esi 230 230 231 231 /* Allocate space for page tables */ 232 232 movl %esi, pt_loc 233 233 movl $KA2PA(ballocs), %edi 234 234 235 235 movl %esi, (%edi) 236 236 addl $4, %edi 237 237 movl $(2 * 1024 * 1024), (%edi) 238 238 239 239 /* Fill page tables */ 240 240 xorl %ecx, %ecx 241 241 xorl %ebx, %ebx 242 242 243 243 floop_pt: 244 244 movl $(PTE_RW | PTE_P), %eax … … 246 246 movl %eax, (%esi, %ecx, 4) 247 247 addl $PAGE_SIZE, %ebx 248 248 249 249 incl %ecx 250 250 cmpl $(512 * 1024), %ecx 251 251 252 252 jl floop_pt 253 253 254 254 /* Fill page directory */ 255 255 movl $(page_directory + 0), %esi … … 257 257 xorl %ecx, %ecx 258 258 movl pt_loc, %ebx 259 259 260 260 floop: 261 261 movl $(PDE_RW | PDE_P), %eax 262 262 orl %ebx, %eax 263 263 264 264 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */ 265 265 movl %eax, (%esi, %ecx, 4) 266 266 267 267 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */ 268 268 movl %eax, (%edi, %ecx, 4) 269 269 addl $PAGE_SIZE, %ebx 270 270 271 271 incl %ecx 272 272 cmpl $512, %ecx 273 273 274 274 jl floop 275 275 276 276 movl %esi, %cr3 277 277 278 278 movl %cr0, %ebx 279 279 orl $CR0_PG, %ebx /* paging on */ 280 280 movl %ebx, %cr0 281 281 282 282 ret 283 283 FUNCTION_END(map_kernel_non_pse) … … 288 288 movl (%edi), %esi 289 289 leal KA2PA(0)(%esi), %esi 290 290 291 291 movl $KA2PA(hardcoded_ktext_size), %edi 292 292 addl (%edi), %esi 293 293 leal KA2PA(0)(%esi), %esi 294 294 295 295 movl $KA2PA(hardcoded_kdata_size), %edi 296 296 addl (%edi), %esi 297 297 leal KA2PA(0)(%esi), %esi 298 298 movl %esi, kernel_end 299 299 300 300 ret 301 301 … … 305 305 cmpl $MULTIBOOT_LOADER_MAGIC, multiboot_eax 306 306 je check_multiboot_map 307 307 308 308 ret 309 309 310 310 check_multiboot_map: 311 311 312 312 /* Copy address of the multiboot info to ebx */ 313 313 movl multiboot_ebx, %ebx 314 314 315 315 /* Check if memory map flag is present */ 316 316 movl (%ebx), %edx 317 317 andl $MULTIBOOT_INFO_FLAGS_MMAP, %edx 318 318 jnz use_multiboot_map 319 319 320 320 ret 321 321 322 322 use_multiboot_map: 323 323 324 324 /* Copy address of the memory map to edx */ 325 325 movl MULTIBOOT_INFO_OFFSET_MMAP_ADDR(%ebx), %edx 326 326 movl %edx, %ecx 327 327 328 328 addl MULTIBOOT_INFO_OFFSET_MMAP_LENGTH(%ebx), %ecx 329 329 330 330 /* Find a free region at least 2M in size */ 331 331 check_memmap_loop: 332 332 333 333 /* Is this a free region? */ 334 334 cmpl $MEMMAP_MEMORY_AVAILABLE, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_TYPE(%edx) 335 335 jnz next_region 336 336 337 337 /* Check size */ 338 338 cmpl $0, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE + 4(%edx) … … 340 340 cmpl $(2 * 1024 * 1024 + PAGE_SIZE), MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE(%edx) 341 341 jbe next_region 342 342 343 343 cmpl $0, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_BASE_ADDRESS + 4(%edx) 344 344 jz found_region 345 345 346 346 next_region: 347 347 348 348 cmp %ecx, %edx 349 349 jbe next_region_do 350 350 351 351 ret 352 352 353 353 next_region_do: 354 354 355 355 addl MULTIBOOT_MEMMAP_OFFSET_SIZE(%edx), %edx 356 356 addl $MULTIBOOT_MEMMAP_SIZE_SIZE, %edx 357 357 jmp check_memmap_loop 358 358 359 359 found_region: 360 360 361 361 /* Use end of the found region */ 362 362 mov MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_BASE_ADDRESS(%edx), %ecx … … 364 364 sub $(2 * 1024 * 1024), %ecx 365 365 mov %ecx, free_area 366 366 367 367 ret 368 368 … … 381 381 movl $0xb8000, %edi /* base of EGA text mode memory */ 382 382 xorl %eax, %eax 383 383 384 384 /* Read bits 8 - 15 of the cursor address */ 385 385 movw $0x3d4, %dx 386 386 movb $0xe, %al 387 387 outb %al, %dx 388 388 389 389 movw $0x3d5, %dx 390 390 inb %dx, %al 391 391 shl $8, %ax 392 392 393 393 /* Read bits 0 - 7 of the cursor address */ 394 394 movw $0x3d4, %dx 395 395 movb $0xf, %al 396 396 outb %al, %dx 397 397 398 398 movw $0x3d5, %dx 399 399 inb %dx, %al 400 400 401 401 /* Sanity check for the cursor on screen */ 402 402 cmp $2000, %ax 403 403 jb err_cursor_ok 404 404 405 405 movw $1998, %ax 406 406 407 407 err_cursor_ok: 408 408 409 409 movw %ax, %bx 410 410 shl $1, %eax 411 411 addl %eax, %edi 412 412 413 413 err_ploop: 414 414 lodsb 415 415 416 416 cmp $0, %al 417 417 je err_ploop_end 418 418 419 419 movb $0x0c, %ah /* black background, light red foreground */ 420 420 stosw 421 421 422 422 /* Sanity check for the cursor on the last line */ 423 423 inc %bx 424 424 cmp $2000, %bx 425 425 jb err_ploop 426 426 427 427 /* Scroll the screen (24 rows) */ 428 428 movl %esi, %edx … … 431 431 movl $960, %ecx 432 432 rep movsl 433 433 434 434 /* Clear the 24th row */ 435 435 xorl %eax, %eax 436 436 movl $40, %ecx 437 437 rep stosl 438 438 439 439 /* Go to row 24 */ 440 440 movl %edx, %esi 441 441 movl $0xb8f00, %edi 442 442 movw $1920, %bx 443 443 444 444 jmp err_ploop 445 445 err_ploop_end: 446 446 447 447 /* Write bits 8 - 15 of the cursor address */ 448 448 movw $0x3d4, %dx 449 449 movb $0xe, %al 450 450 outb %al, %dx 451 451 452 452 movw $0x3d5, %dx 453 453 movb %bh, %al 454 454 outb %al, %dx 455 455 456 456 /* Write bits 0 - 7 of the cursor address */ 457 457 movw $0x3d4, %dx 458 458 movb $0xf, %al 459 459 outb %al, %dx 460 460 461 461 movw $0x3d5, %dx 462 462 movb %bl, %al 463 463 outb %al, %dx 464 464 465 465 cli 466 466 hlt1: … … 486 486 pushl %edx 487 487 pushl %edi 488 488 489 489 movl $0xb8000, %edi /* base of EGA text mode memory */ 490 490 xorl %eax, %eax 491 491 492 492 /* Read bits 8 - 15 of the cursor address */ 493 493 movw $0x3d4, %dx 494 494 movb $0xe, %al 495 495 outb %al, %dx 496 496 497 497 movw $0x3d5, %dx 498 498 inb %dx, %al 499 499 shl $8, %ax 500 500 501 501 /* Read bits 0 - 7 of the cursor address */ 502 502 movw $0x3d4, %dx 503 503 movb $0xf, %al 504 504 outb %al, %dx 505 505 506 506 movw $0x3d5, %dx 507 507 inb %dx, %al 508 508 509 509 /* Sanity check for the cursor on screen */ 510 510 cmp $2000, %ax 511 511 jb pm_puts_cursor_ok 512 512 513 513 movw $1998, %ax 514 514 515 515 pm_puts_cursor_ok: 516 516 517 517 movw %ax, %bx 518 518 shl $1, %eax 519 519 addl %eax, %edi 520 520 521 521 pm_puts_ploop: 522 522 lodsb 523 523 524 524 cmp $0, %al 525 525 je pm_puts_ploop_end 526 526 527 527 movb $0x0a, %ah /* black background, light green foreground */ 528 528 stosw 529 529 530 530 /* Sanity check for the cursor on the last line */ 531 531 inc %bx 532 532 cmp $2000, %bx 533 533 jb pm_puts_ploop 534 534 535 535 /* Scroll the screen (24 rows) */ 536 536 movl %esi, %edx … … 539 539 movl $960, %ecx 540 540 rep movsl 541 541 542 542 /* Clear the 24th row */ 543 543 xorl %eax, %eax 544 544 movl $40, %ecx 545 545 rep stosl 546 546 547 547 /* Go to row 24 */ 548 548 movl %edx, %esi 549 549 movl $0xb8f00, %edi 550 550 movw $1920, %bx 551 551 552 552 jmp pm_puts_ploop 553 553 pm_puts_ploop_end: 554 554 555 555 /* Write bits 8 - 15 of the cursor address */ 556 556 movw $0x3d4, %dx 557 557 movb $0xe, %al 558 558 outb %al, %dx 559 559 560 560 movw $0x3d5, %dx 561 561 movb %bh, %al 562 562 outb %al, %dx 563 563 564 564 /* Write bits 0 - 7 of the cursor address */ 565 565 movw $0x3d4, %dx 566 566 movb $0xf, %al 567 567 outb %al, %dx 568 568 569 569 movw $0x3d5, %dx 570 570 movb %bl, %al 571 571 outb %al, %dx 572 572 573 573 popl %edi 574 574 popl %edx … … 576 576 popl %ebx 577 577 popl %eax 578 578 579 579 ret 580 580 … … 591 591 */ 592 592 early_puts: 593 593 594 594 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB))) 595 595 596 596 /* Prologue, save preserved registers */ 597 597 pushl %ebp … … 600 600 pushl %esi 601 601 pushl %edi 602 602 603 603 movl 0x08(%ebp), %esi 604 604 movl $(PA2KA(0xb8000)), %edi /* base of EGA text mode memory */ 605 605 xorl %eax, %eax 606 606 607 607 /* Read bits 8 - 15 of the cursor address */ 608 608 movw $0x3d4, %dx 609 609 movb $0xe, %al 610 610 outb %al, %dx 611 611 612 612 movw $0x3d5, %dx 613 613 inb %dx, %al 614 614 shl $8, %ax 615 615 616 616 /* Read bits 0 - 7 of the cursor address */ 617 617 movw $0x3d4, %dx 618 618 movb $0xf, %al 619 619 outb %al, %dx 620 620 621 621 movw $0x3d5, %dx 622 622 inb %dx, %al 623 623 624 624 /* Sanity check for the cursor on screen */ 625 625 cmp $2000, %ax 626 626 jb early_puts_cursor_ok 627 627 628 628 movw $1998, %ax 629 629 630 630 early_puts_cursor_ok: 631 631 632 632 movw %ax, %bx 633 633 shl $1, %eax 634 634 addl %eax, %edi 635 635 636 636 early_puts_ploop: 637 637 lodsb 638 638 639 639 cmp $0, %al 640 640 je early_puts_ploop_end 641 641 642 642 movb $0x0e, %ah /* black background, yellow foreground */ 643 643 stosw 644 644 645 645 /* Sanity check for the cursor on the last line */ 646 646 inc %bx 647 647 cmp $2000, %bx 648 648 jb early_puts_ploop 649 649 650 650 /* Scroll the screen (24 rows) */ 651 651 movl %esi, %edx … … 654 654 movl $960, %ecx 655 655 rep movsl 656 656 657 657 /* Clear the 24th row */ 658 658 xorl %eax, %eax 659 659 movl $40, %ecx 660 660 rep stosl 661 661 662 662 /* Go to row 24 */ 663 663 movl %edx, %esi 664 664 movl $(PA2KA(0xb8f00)), %edi 665 665 movw $1920, %bx 666 666 667 667 jmp early_puts_ploop 668 668 early_puts_ploop_end: 669 669 670 670 /* Write bits 8 - 15 of the cursor address */ 671 671 movw $0x3d4, %dx 672 672 movb $0xe, %al 673 673 outb %al, %dx 674 674 675 675 movw $0x3d5, %dx 676 676 movb %bh, %al 677 677 outb %al, %dx 678 678 679 679 /* Write bits 0 - 7 of the cursor address */ 680 680 movw $0x3d4, %dx 681 681 movb $0xf, %al 682 682 outb %al, %dx 683 683 684 684 movw $0x3d5, %dx 685 685 movb %bl, %al 686 686 outb %al, %dx 687 687 688 688 /* Epilogue, restore preserved registers */ 689 689 popl %edi … … 691 691 popl %ebx 692 692 leave 693 693 694 694 #endif 695 695 696 696 ret 697 697 -
kernel/arch/ia32/src/boot/multiboot2.S
r3061bc1 ra35b458 45 45 .long multiboot2_header_end - multiboot2_header_start 46 46 .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_HEADER_ARCH_I386 + (multiboot2_header_end - multiboot2_header_start)) 47 47 48 48 /* Information request tag */ 49 49 .align 8 … … 59 59 #endif 60 60 tag_info_req_end: 61 61 62 62 /* Address tag */ 63 63 .align 8 … … 71 71 .long 0 72 72 tag_address_end: 73 73 74 74 /* Entry address tag */ 75 75 .align 8 … … 80 80 .long multiboot2_image_start 81 81 tag_entry_address_end: 82 82 83 83 /* Flags tag */ 84 84 .align 8 … … 89 89 .long MULTIBOOT2_FLAGS_CONSOLE 90 90 tag_flags_end: 91 91 92 92 #ifdef CONFIG_FB 93 93 /* Framebuffer tag */ … … 102 102 tag_framebuffer_end: 103 103 #endif 104 104 105 105 /* Module alignment tag */ 106 106 .align 8 … … 111 111 .long 0 112 112 tag_module_align_end: 113 113 114 114 /* Tag terminator */ 115 115 .align 8 … … 124 124 cli 125 125 cld 126 126 127 127 /* Initialize stack pointer */ 128 128 movl $START_STACK, %esp 129 129 130 130 /* 131 131 * Initialize Global Descriptor Table and … … 134 134 lgdtl bootstrap_gdtr 135 135 lidtl bootstrap_idtr 136 136 137 137 /* Kernel data + stack */ 138 138 movw $GDT_SELECTOR(KDATA_DES), %cx … … 142 142 movw %cx, %ds 143 143 movw %cx, %ss 144 144 145 145 jmpl $GDT_SELECTOR(KTEXT_DES), $multiboot2_meeting_point 146 146 multiboot2_meeting_point: 147 147 148 148 /* Save multiboot arguments */ 149 149 movl %eax, multiboot_eax 150 150 movl %ebx, multiboot_ebx 151 151 152 152 #ifndef PROCESSOR_i486 153 153 154 154 movl $(INTEL_CPUID_LEVEL), %eax 155 155 cpuid 156 156 cmp $0x0, %eax /* any function > 0? */ 157 157 jbe pse_unsupported 158 158 159 159 movl $(INTEL_CPUID_STANDARD), %eax 160 160 cpuid 161 161 bt $(INTEL_PSE), %edx 162 162 jnc pse_unsupported 163 163 164 164 /* Map kernel and turn paging on */ 165 165 call map_kernel_pse 166 166 jmp stack_init 167 167 168 168 #endif /* PROCESSOR_i486 */ 169 169 170 170 pse_unsupported: 171 171 172 172 /* Map kernel and turn paging on */ 173 173 call map_kernel_non_pse 174 174 175 175 stack_init: 176 176 177 177 /* Create the first stack frame */ 178 178 pushl $0 179 179 movl %esp, %ebp 180 180 181 181 /* Call ia32_pre_main(multiboot_eax, multiboot_ebx) */ 182 182 pushl multiboot_ebx 183 183 pushl multiboot_eax 184 184 call ia32_pre_main 185 185 186 186 /* Call main_bsp() */ 187 187 call main_bsp 188 188 189 189 /* Not reached */ 190 190 cli -
kernel/arch/ia32/src/cpu/cpu.c
r3061bc1 ra35b458 84 84 cpu_info_t info; 85 85 uint32_t help = 0; 86 86 87 87 CPU->arch.tss = tss_p; 88 88 CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss); 89 89 90 90 CPU->fpu_owner = NULL; 91 91 92 92 cpuid(INTEL_CPUID_STANDARD, &info); 93 93 94 94 CPU->arch.fi.word = info.cpuid_edx; 95 95 96 96 if (CPU->arch.fi.bits.fxsr) 97 97 fpu_fxsr(); 98 98 else 99 99 fpu_fsr(); 100 100 101 101 if (CPU->arch.fi.bits.sse) { 102 102 asm volatile ( … … 108 108 ); 109 109 } 110 110 111 111 #ifndef PROCESSOR_i486 112 112 if (CPU->arch.fi.bits.sep) { … … 132 132 && (info.cpuid_edx == AMD_CPUID_EDX)) 133 133 CPU->arch.vendor = VendorAMD; 134 134 135 135 /* 136 136 * Check for Intel processor. … … 140 140 && (info.cpuid_edx == INTEL_CPUID_EDX)) 141 141 CPU->arch.vendor = VendorIntel; 142 142 143 143 cpuid(INTEL_CPUID_STANDARD, &info); 144 144 CPU->arch.family = (info.cpuid_eax >> 8) & 0x0fU; -
kernel/arch/ia32/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_32_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_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 … … 105 105 gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL; 106 106 tr_load(GDT_SELECTOR(TSS_DES)); 107 107 108 108 /* 109 109 * Update the generation count so that faults caused by -
kernel/arch/ia32/src/drivers/i8254.c
r3061bc1 ra35b458 89 89 i8254_irq.handler = i8254_irq_handler; 90 90 irq_register(&i8254_irq); 91 91 92 92 i8254_normal_operation(); 93 93 } … … 111 111 pio_write_8(CLK_PORT1, 0xff); 112 112 pio_write_8(CLK_PORT1, 0xff); 113 113 114 114 uint8_t not_ok; 115 115 uint32_t t1; 116 116 uint32_t t2; 117 117 118 118 do { 119 119 /* will read both status and count */ … … 123 123 t1 |= pio_read_8(CLK_PORT1) << 8; 124 124 } while (not_ok); 125 125 126 126 asm_delay_loop(LOOPS); 127 127 128 128 pio_write_8(CLK_PORT4, 0xd2); 129 129 t2 = pio_read_8(CLK_PORT1); 130 130 t2 |= pio_read_8(CLK_PORT1) << 8; 131 131 132 132 /* 133 133 * We want to determine the overhead of the calibrating mechanism. … … 136 136 uint32_t o1 = pio_read_8(CLK_PORT1); 137 137 o1 |= pio_read_8(CLK_PORT1) << 8; 138 138 139 139 asm_fake_loop(LOOPS); 140 140 141 141 pio_write_8(CLK_PORT4, 0xd2); 142 142 uint32_t o2 = pio_read_8(CLK_PORT1); 143 143 o2 |= pio_read_8(CLK_PORT1) << 8; 144 144 145 145 CPU->delay_loop_const = 146 146 ((MAGIC_NUMBER * LOOPS) / 1000) / ((t1 - t2) - (o1 - o2)) + 147 147 (((MAGIC_NUMBER * LOOPS) / 1000) % ((t1 - t2) - (o1 - o2)) ? 1 : 0); 148 148 149 149 uint64_t clk1 = get_cycle(); 150 150 delay(1 << SHIFT); 151 151 uint64_t clk2 = get_cycle(); 152 152 153 153 CPU->frequency_mhz = (clk2 - clk1) >> SHIFT; 154 154 155 155 return; 156 156 } -
kernel/arch/ia32/src/fpu_context.c
r3061bc1 ra35b458 59 59 X87_DENORMAL_EXC_FLAG = (1 << 1), 60 60 X87_INVALID_OP_EXC_FLAG = (1 << 0), 61 61 62 62 X87_ALL_MASK = X87_PRECISION_MASK | X87_UNDERFLOW_MASK | X87_OVERFLOW_MASK | X87_ZERO_DIV_MASK | X87_DENORMAL_OP_MASK | X87_INVALID_OP_MASK, 63 63 }; … … 129 129 uint32_t help0 = 0; 130 130 uint32_t help1 = 0; 131 131 132 132 asm volatile ( 133 133 "fninit\n" -
kernel/arch/ia32/src/ia32.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. */ … … 107 107 interrupt_init(); 108 108 bios_init(); 109 109 110 110 /* PIC */ 111 111 i8259_init(); … … 120 120 /* Initialize IRQ routing */ 121 121 irq_init(IRQ_COUNT, IRQ_COUNT); 122 122 123 123 /* hard clock */ 124 124 i8254_init(); 125 125 126 126 #if (defined(CONFIG_FB) || defined(CONFIG_EGA)) 127 127 bool bfb = false; 128 128 #endif 129 129 130 130 #ifdef CONFIG_FB 131 131 bfb = bfb_init(); 132 132 #endif 133 133 134 134 #ifdef CONFIG_EGA 135 135 if (!bfb) { … … 139 139 } 140 140 #endif 141 141 142 142 /* Merge all memory zones to 1 big zone */ 143 143 zone_merge_all(); … … 220 220 } 221 221 #endif 222 222 223 223 if (irqs_info != NULL) 224 224 sysinfo_set_item_val(irqs_info, NULL, true); -
kernel/arch/ia32/src/interrupt.c
r3061bc1 ra35b458 72 72 "efl=%0#10" PRIx32 "\terr=%0#10" PRIx32 "\n", 73 73 istate->cs, istate->eip, istate->eflags, istate->error_word); 74 74 75 75 printf("ds =%0#10" PRIx32 "\tes =%0#10" PRIx32 "\t" 76 76 "fs =%0#10" PRIx32 "\tgs =%0#10" PRIx32 "\n", 77 77 istate->ds, istate->es, istate->fs, istate->gs); 78 78 79 79 if (istate_from_uspace(istate)) 80 80 printf("ss =%0#10" PRIx32 "\n", istate->ss); 81 81 82 82 printf("eax=%0#10" PRIx32 "\tebx=%0#10" PRIx32 "\t" 83 83 "ecx=%0#10" PRIx32 "\tedx=%0#10" PRIx32 "\n", 84 84 istate->eax, istate->ebx, istate->ecx, istate->edx); 85 85 86 86 printf("esi=%0#10" PRIx32 "\tedi=%0#10" PRIx32 "\t" 87 87 "ebp=%0#10" PRIx32 "\tesp=%0#10" PRIxn "\n", … … 119 119 size_t ver = TASK->arch.iomapver; 120 120 irq_spinlock_unlock(&TASK->lock, false); 121 121 122 122 if (CPU->arch.iomapver_copy != ver) { 123 123 /* … … 149 149 : [mxcsr] "=m" (mxcsr) 150 150 ); 151 151 152 152 fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR=%#0" PRIx32 ".", 153 153 mxcsr); … … 185 185 { 186 186 assert(n >= IVT_IRQBASE); 187 187 188 188 unsigned int inum = n - IVT_IRQBASE; 189 189 bool ack = false; 190 190 assert(inum < IRQ_COUNT); 191 191 assert((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1)); 192 192 193 193 irq_t *irq = irq_dispatch_and_lock(inum); 194 194 if (irq) { … … 196 196 * The IRQ handler was found. 197 197 */ 198 198 199 199 if (irq->preack) { 200 200 /* Send EOI before processing the interrupt */ … … 212 212 #endif 213 213 } 214 214 215 215 if (!ack) 216 216 trap_virtual_eoi(); … … 220 220 { 221 221 unsigned int i; 222 222 223 223 for (i = 0; i < IVT_ITEMS; i++) 224 224 exc_register(i, "null", false, (iroutine_t) null_interrupt); 225 225 226 226 for (i = 0; i < IRQ_COUNT; i++) { 227 227 if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1)) … … 229 229 (iroutine_t) irq_interrupt); 230 230 } 231 231 232 232 exc_register(VECTOR_DE, "de_fault", true, (iroutine_t) de_fault); 233 233 exc_register(VECTOR_NM, "nm_fault", true, (iroutine_t) nm_fault); … … 235 235 exc_register(VECTOR_GP, "gp_fault", true, (iroutine_t) gp_fault); 236 236 exc_register(VECTOR_XM, "simd_fp", true, (iroutine_t) simd_fp_exception); 237 237 238 238 #ifdef CONFIG_SMP 239 239 exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", true, -
kernel/arch/ia32/src/mm/frame.c
r3061bc1 ra35b458 54 54 { 55 55 unsigned int i; 56 56 57 57 for (i = 0; i < e820counter; i++) { 58 58 uint64_t base64 = e820table[i].base_address; 59 59 uint64_t size64 = e820table[i].size; 60 60 61 61 #ifdef KARCH_ia32 62 62 /* … … 65 65 if (base64 >= PHYSMEM_LIMIT32) 66 66 continue; 67 67 68 68 if (base64 + size64 > PHYSMEM_LIMIT32) 69 69 size64 = PHYSMEM_LIMIT32 - base64; 70 70 #endif 71 71 72 72 uintptr_t base = (uintptr_t) base64; 73 73 size_t size = (size_t) size64; 74 74 75 75 if (!frame_adjust_zone_bounds(low, &base, &size)) 76 76 continue; 77 77 78 78 if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { 79 79 /* To be safe, make the available zone possibly smaller */ … … 81 81 uint64_t new_size = ALIGN_DOWN(size - (new_base - base), 82 82 FRAME_SIZE); 83 83 84 84 size_t count = SIZE2FRAMES(new_size); 85 85 pfn_t pfn = ADDR2PFN(new_base); 86 86 pfn_t conf; 87 87 88 88 if (low) { 89 89 if ((minconf < pfn) || (minconf >= pfn + count)) … … 105 105 uint64_t new_size = ALIGN_UP(size + (base - new_base), 106 106 FRAME_SIZE); 107 107 108 108 zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0, 109 109 ZONE_FIRMWARE); … … 113 113 uint64_t new_size = ALIGN_UP(size + (base - new_base), 114 114 FRAME_SIZE); 115 115 116 116 zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0, 117 117 ZONE_RESERVED); … … 133 133 unsigned int i; 134 134 printf("[base ] [size ] [name ]\n"); 135 135 136 136 for (i = 0; i < e820counter; i++) { 137 137 const char *name; 138 138 139 139 if (e820table[i].type <= MEMMAP_MEMORY_UNUSABLE) 140 140 name = e820names[e820table[i].type]; 141 141 else 142 142 name = "invalid"; 143 143 144 144 printf("%#018" PRIx64 " %#018" PRIx64" %s\n", e820table[i].base_address, 145 145 e820table[i].size, name); … … 150 150 { 151 151 pfn_t minconf; 152 152 153 153 if (config.cpu_active == 1) { 154 154 minconf = 1; 155 155 156 156 #ifdef CONFIG_SMP 157 157 minconf = max(minconf, … … 159 159 hardcoded_unmapped_kdata_size)); 160 160 #endif 161 161 162 162 init_e820_memory(minconf, true); 163 163 164 164 /* Reserve frame 0 (BIOS data) */ 165 165 frame_mark_unavailable(0, 1); 166 166 167 167 #ifdef CONFIG_SMP 168 168 /* Reserve AP real mode bootstrap memory */ -
kernel/arch/ia32/src/mm/page.c
r3061bc1 ra35b458 54 54 uintptr_t cur; 55 55 int flags; 56 56 57 57 if (config.cpu_active > 1) { 58 58 /* Fast path for non-boot CPUs */ … … 63 63 64 64 page_mapping_operations = &pt_mapping_operations; 65 65 66 66 /* 67 67 * PA2KA(identity) mapping for all low-memory frames. … … 74 74 } 75 75 page_table_unlock(AS_KERNEL, true); 76 76 77 77 exc_register(VECTOR_PF, "page_fault", true, (iroutine_t) page_fault); 78 78 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); 79 79 80 80 paging_on(); 81 81 } … … 85 85 uintptr_t badvaddr; 86 86 pf_access_t access; 87 87 88 88 badvaddr = read_cr2(); 89 89 90 90 if (istate->error_word & PFERR_CODE_RSVD) 91 91 panic("Reserved bit set in page directory."); 92 92 93 93 if (istate->error_word & PFERR_CODE_RW) 94 94 access = PF_ACCESS_WRITE; 95 95 else 96 96 access = PF_ACCESS_READ; 97 97 98 98 (void) as_page_fault(badvaddr, access, istate); 99 99 } -
kernel/arch/ia32/src/pm.c
r3061bc1 ra35b458 269 269 gdtr_load(&gdtr); 270 270 idtr_load(&idtr); 271 271 272 272 /* 273 273 * Each CPU has its private GDT and TSS. … … 289 289 290 290 tss_initialize(tss_p); 291 291 292 292 gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL; 293 293 gdt_p[TSS_DES].special = 1; 294 294 gdt_p[TSS_DES].granularity = 0; 295 295 296 296 gdt_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p); 297 297 gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1); … … 302 302 */ 303 303 tr_load(GDT_SELECTOR(TSS_DES)); 304 304 305 305 /* Disable I/O on nonprivileged levels and clear NT flag. */ 306 306 write_eflags(read_eflags() & ~(EFLAGS_IOPL | EFLAGS_NT)); -
kernel/arch/ia32/src/proc/scheduler.c
r3061bc1 ra35b458 59 59 { 60 60 uintptr_t kstk = (uintptr_t) &THREAD->kstack[STACK_SIZE]; 61 61 62 62 #ifndef PROCESSOR_i486 63 63 if (CPU->arch.fi.bits.sep) { … … 66 66 } 67 67 #endif 68 68 69 69 /* Set kernel stack for CPL3 -> CPL0 switch via interrupt */ 70 70 CPU->arch.tss->esp0 = kstk; -
kernel/arch/ia32/src/smp/ap.S
r3061bc1 ra35b458 62 62 /* initialize Global Descriptor Table register */ 63 63 lgdtl ap_gdtr 64 64 65 65 /* switch to protected mode */ 66 66 movl %cr0, %eax … … 68 68 movl %eax, %cr0 69 69 jmpl $KTEXT, $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET 70 70 71 71 jump_to_kernel: 72 72 .code32 … … 84 84 */ 85 85 call map_kernel_pse 86 86 87 87 addl $PA2KA(0), %esp /* PA2KA(ctx.sp) */ 88 88 89 89 /* create the first stack frame */ 90 90 pushl $0 -
kernel/arch/ia32/src/smp/apic.c
r3061bc1 ra35b458 164 164 { 165 165 l_apic_id_t idreg; 166 166 167 167 idreg.value = l_apic[L_APIC_ID]; 168 168 return idreg.apic_id; … … 174 174 exc_register(VECTOR_APIC_SPUR, "apic_spurious", false, 175 175 (iroutine_t) apic_spurious); 176 176 177 177 enable_irqs_function = io_apic_enable_irqs; 178 178 disable_irqs_function = io_apic_disable_irqs; 179 179 eoi_function = l_apic_eoi; 180 180 irqs_info = "apic"; 181 181 182 182 /* 183 183 * Configure interrupt routing. … … 186 186 */ 187 187 io_apic_disable_irqs(0xffffU); 188 188 189 189 irq_initialize(&l_apic_timer_irq); 190 190 l_apic_timer_irq.preack = true; … … 193 193 l_apic_timer_irq.handler = l_apic_timer_irq_handler; 194 194 irq_register(&l_apic_timer_irq); 195 195 196 196 uint8_t i; 197 197 for (i = 0; i < IRQ_COUNT; i++) { 198 198 int pin; 199 199 200 200 if ((pin = smp_irq_to_pin(i)) != -1) 201 201 io_apic_change_ioredtbl((uint8_t) pin, DEST_ALL, (uint8_t) (IVT_IRQBASE + i), LOPRI); 202 202 } 203 203 204 204 /* 205 205 * Ensure that io_apic has unique ID. 206 206 */ 207 207 io_apic_id_t idreg; 208 208 209 209 idreg.value = io_apic_read(IOAPICID); 210 210 if ((1 << idreg.apic_id) & apic_id_mask) { /* See if IO APIC ID is used already */ … … 217 217 } 218 218 } 219 219 220 220 /* 221 221 * Configure the BSP's lapic. … … 223 223 l_apic_init(); 224 224 l_apic_debug(); 225 225 226 226 bsp_l_apic = l_apic_id(); 227 227 } … … 237 237 { 238 238 esr_t esr; 239 239 240 240 esr.value = l_apic[ESR]; 241 241 242 242 if (esr.err_bitmap) { 243 243 log_begin(LF_ARCH, LVL_ERROR); … … 259 259 log_end(); 260 260 } 261 261 262 262 return !esr.err_bitmap; 263 263 } … … 267 267 { 268 268 icr_t icr; 269 269 270 270 do { 271 271 icr.lo = l_apic[ICRlo]; … … 286 286 /* Wait for a destination cpu to accept our previous ipi. */ 287 287 l_apic_wait_for_delivery(); 288 288 289 289 icr.lo = l_apic[ICRlo]; 290 290 icr.hi = l_apic[ICRhi]; 291 291 292 292 icr.delmod = DELMOD_FIXED; 293 293 icr.destmod = DESTMOD_PHYS; … … 301 301 l_apic[ICRhi] = icr.hi; 302 302 l_apic[ICRlo] = icr.lo; 303 303 304 304 return apic_poll_errors(); 305 305 } … … 318 318 /* Wait for a destination cpu to accept our previous ipi. */ 319 319 l_apic_wait_for_delivery(); 320 320 321 321 icr.lo = l_apic[ICRlo]; 322 322 icr.delmod = DELMOD_FIXED; … … 326 326 icr.trigger_mode = TRIGMOD_LEVEL; 327 327 icr.vector = vector; 328 328 329 329 l_apic[ICRlo] = icr.lo; 330 330 331 331 return apic_poll_errors(); 332 332 } … … 345 345 */ 346 346 icr_t icr; 347 347 348 348 icr.lo = l_apic[ICRlo]; 349 349 icr.hi = l_apic[ICRhi]; 350 350 351 351 icr.delmod = DELMOD_INIT; 352 352 icr.destmod = DESTMOD_PHYS; … … 356 356 icr.vector = 0; 357 357 icr.dest = apicid; 358 358 359 359 l_apic[ICRhi] = icr.hi; 360 360 l_apic[ICRlo] = icr.lo; 361 361 362 362 /* 363 363 * According to MP Specification, 20us should be enough to … … 365 365 */ 366 366 delay(20); 367 367 368 368 if (!apic_poll_errors()) 369 369 return 0; 370 370 371 371 l_apic_wait_for_delivery(); 372 372 … … 379 379 icr.vector = 0; 380 380 l_apic[ICRlo] = icr.lo; 381 381 382 382 /* 383 383 * Wait 10ms as MP Specification specifies. 384 384 */ 385 385 delay(10000); 386 386 387 387 if (!is_82489DX_apic(l_apic[LAVR])) { 388 388 /* … … 402 402 } 403 403 } 404 404 405 405 return apic_poll_errors(); 406 406 } … … 411 411 /* Initialize LVT Error register. */ 412 412 lvt_error_t error; 413 413 414 414 error.value = l_apic[LVT_Err]; 415 415 error.masked = true; 416 416 l_apic[LVT_Err] = error.value; 417 417 418 418 /* Initialize LVT LINT0 register. */ 419 419 lvt_lint_t lint; 420 420 421 421 lint.value = l_apic[LVT_LINT0]; 422 422 lint.masked = true; 423 423 l_apic[LVT_LINT0] = lint.value; 424 424 425 425 /* Initialize LVT LINT1 register. */ 426 426 lint.value = l_apic[LVT_LINT1]; 427 427 lint.masked = true; 428 428 l_apic[LVT_LINT1] = lint.value; 429 429 430 430 /* Task Priority Register initialization. */ 431 431 tpr_t tpr; 432 432 433 433 tpr.value = l_apic[TPR]; 434 434 tpr.pri_sc = 0; 435 435 tpr.pri = 0; 436 436 l_apic[TPR] = tpr.value; 437 437 438 438 /* Spurious-Interrupt Vector Register initialization. */ 439 439 svr_t svr; 440 440 441 441 svr.value = l_apic[SVR]; 442 442 svr.vector = VECTOR_APIC_SPUR; … … 444 444 svr.focus_checking = true; 445 445 l_apic[SVR] = svr.value; 446 446 447 447 if (CPU->arch.family >= 6) 448 448 enable_l_apic_in_msr(); 449 449 450 450 /* Interrupt Command Register initialization. */ 451 451 icr_t icr; 452 452 453 453 icr.lo = l_apic[ICRlo]; 454 454 icr.delmod = DELMOD_INIT; … … 458 458 icr.trigger_mode = TRIGMOD_LEVEL; 459 459 l_apic[ICRlo] = icr.lo; 460 460 461 461 /* Timer Divide Configuration Register initialization. */ 462 462 tdcr_t tdcr; 463 463 464 464 tdcr.value = l_apic[TDCR]; 465 465 tdcr.div_value = DIVIDE_1; 466 466 l_apic[TDCR] = tdcr.value; 467 467 468 468 /* Program local timer. */ 469 469 lvt_tm_t tm; 470 470 471 471 tm.value = l_apic[LVT_Tm]; 472 472 tm.vector = VECTOR_CLK; … … 474 474 tm.masked = false; 475 475 l_apic[LVT_Tm] = tm.value; 476 476 477 477 /* 478 478 * Measure and configure the timer to generate timer … … 481 481 uint32_t t1 = l_apic[CCRT]; 482 482 l_apic[ICRT] = 0xffffffff; 483 483 484 484 while (l_apic[CCRT] == t1); 485 485 486 486 t1 = l_apic[CCRT]; 487 487 delay(1000000 / HZ); 488 488 uint32_t t2 = l_apic[CCRT]; 489 489 490 490 l_apic[ICRT] = t1 - t2; 491 491 492 492 /* Program Logical Destination Register. */ 493 493 assert(CPU->id < 8); 494 494 ldr_t ldr; 495 495 496 496 ldr.value = l_apic[LDR]; 497 497 ldr.id = (uint8_t) (1 << CPU->id); 498 498 l_apic[LDR] = ldr.value; 499 499 500 500 /* Program Destination Format Register for Flat mode. */ 501 501 dfr_t dfr; 502 502 503 503 dfr.value = l_apic[DFR]; 504 504 dfr.model = MODEL_FLAT; … … 519 519 log_printf("LVT on cpu%u, LAPIC ID: %" PRIu8 "\n", 520 520 CPU->id, l_apic_id()); 521 521 522 522 lvt_tm_t tm; 523 523 tm.value = l_apic[LVT_Tm]; … … 525 525 tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], 526 526 tm_mode_str[tm.mode]); 527 527 528 528 lvt_lint_t lint; 529 529 lint.value = l_apic[LVT_LINT0]; … … 532 532 intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], 533 533 mask_str[lint.masked]); 534 534 535 535 lint.value = l_apic[LVT_LINT1]; 536 536 log_printf("LVT LINT1: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n", … … 538 538 intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], 539 539 mask_str[lint.masked]); 540 540 541 541 lvt_error_t error; 542 542 error.value = l_apic[LVT_Err]; … … 557 557 { 558 558 io_regsel_t regsel; 559 559 560 560 regsel.value = io_apic[IOREGSEL]; 561 561 regsel.reg_addr = address; … … 573 573 { 574 574 io_regsel_t regsel; 575 575 576 576 regsel.value = io_apic[IOREGSEL]; 577 577 regsel.reg_addr = address; … … 592 592 { 593 593 unsigned int dlvr; 594 594 595 595 if (flags & LOPRI) 596 596 dlvr = DELMOD_LOWPRI; 597 597 else 598 598 dlvr = DELMOD_FIXED; 599 599 600 600 io_redirection_reg_t reg; 601 601 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 602 602 reg.hi = io_apic_read((uint8_t) (IOREDTBL + pin * 2 + 1)); 603 603 604 604 reg.dest = dest; 605 605 reg.destmod = DESTMOD_LOGIC; … … 608 608 reg.delmod = dlvr; 609 609 reg.intvec = vec; 610 610 611 611 io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo); 612 612 io_apic_write((uint8_t) (IOREDTBL + pin * 2 + 1), reg.hi); … … 630 630 if (pin != -1) { 631 631 io_redirection_reg_t reg; 632 632 633 633 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 634 634 reg.masked = true; 635 635 io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo); 636 636 } 637 637 638 638 } 639 639 } … … 657 657 if (pin != -1) { 658 658 io_redirection_reg_t reg; 659 659 660 660 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 661 661 reg.masked = false; 662 662 io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo); 663 663 } 664 664 665 665 } 666 666 } -
kernel/arch/ia32/src/smp/mps.c
r3061bc1 ra35b458 75 75 { 76 76 assert(i < processor_entry_cnt); 77 77 78 78 return processor_entries[i].l_apic_id; 79 79 } … … 82 82 { 83 83 assert(i < processor_entry_cnt); 84 84 85 85 /* 86 86 * FIXME: The current local APIC driver limits usable … … 90 90 if (i > 7) 91 91 return false; 92 92 93 93 return ((processor_entries[i].cpu_flags & 0x01) == 0x01); 94 94 } … … 97 97 { 98 98 assert(i < processor_entry_cnt); 99 99 100 100 return ((processor_entries[i].cpu_flags & 0x02) == 0x02); 101 101 } … … 104 104 { 105 105 size_t i; 106 106 107 107 for (i = 0; i < io_intr_entry_cnt; i++) { 108 108 if (io_intr_entries[i].src_bus_irq == irq && … … 110 110 return io_intr_entries[i].dst_io_apic_pin; 111 111 } 112 112 113 113 return -1; 114 114 } … … 131 131 unsigned int i; 132 132 uint8_t sum; 133 133 134 134 for (i = 0, sum = 0; i < 16; i++) 135 135 sum = (uint8_t) (sum + base[i]); 136 136 137 137 return (sum == 0); 138 138 } … … 147 147 uint8_t sum; 148 148 uint16_t i; 149 149 150 150 /* Compute the checksum for the base table */ 151 151 for (i = 0, sum = 0; i < ct->base_table_length; i++) 152 152 sum = (uint8_t) (sum + base[i]); 153 153 154 154 if (sum) 155 155 return false; 156 156 157 157 /* Compute the checksum for the extended table */ 158 158 for (i = 0, sum = 0; i < ct->ext_table_length; i++) 159 159 sum = (uint8_t) (sum + ext[i]); 160 160 161 161 return (sum == ct->ext_table_checksum); 162 162 } … … 169 169 if ((pr->cpu_flags & (1 << 0)) == 0) 170 170 return; 171 171 172 172 apic_id_mask |= (1 << pr->l_apic_id); 173 173 } … … 177 177 #ifdef MPSCT_VERBOSE 178 178 char buf[7]; 179 179 180 180 memcpy((void *) buf, (void *) bus->bus_type, 6); 181 181 buf[6] = 0; 182 182 183 183 log(LF_ARCH, LVL_DEBUG, "MPS: bus=%" PRIu8 " (%s)", bus->bus_id, buf); 184 184 #endif … … 190 190 if ((ioa->io_apic_flags & 1) == 0) 191 191 return; 192 192 193 193 if (io_apic_cnt++ > 0) { 194 194 /* … … 197 197 return; 198 198 } 199 199 200 200 io_apic = (uint32_t *) (uintptr_t) ioa->io_apic; 201 201 } … … 207 207 log_begin(LF_ARCH, LVL_DEBUG); 208 208 log_printf("MPS: "); 209 209 210 210 switch (iointr->intr_type) { 211 211 case 0: … … 222 222 break; 223 223 } 224 224 225 225 log_printf(", "); 226 226 227 227 switch (iointr->poel & 3) { 228 228 case 0: … … 239 239 break; 240 240 } 241 241 242 242 log_printf(", "); 243 243 244 244 switch ((iointr->poel >> 2) & 3) { 245 245 case 0: … … 256 256 break; 257 257 } 258 258 259 259 log_printf(", bus=%" PRIu8 " irq=%" PRIu8 " io_apic=%" PRIu8" pin=%" 260 260 PRIu8, iointr->src_bus_id, iointr->src_bus_irq, … … 270 270 log_begin(LF_ARCH, LVL_DEBUG); 271 271 log_printf("MPS: "); 272 272 273 273 switch (lintr->intr_type) { 274 274 case 0: … … 285 285 break; 286 286 } 287 287 288 288 log_printf(", "); 289 289 290 290 switch (lintr->poel & 3) { 291 291 case 0: … … 302 302 break; 303 303 } 304 304 305 305 log_printf(", "); 306 306 307 307 switch ((lintr->poel >> 2) & 3) { 308 308 case 0: … … 319 319 break; 320 320 } 321 321 322 322 log_printf(", bus=%" PRIu8 " irq=%" PRIu8 " l_apic=%" PRIu8" pin=%" 323 323 PRIu8, lintr->src_bus_id, lintr->src_bus_irq, … … 331 331 uint8_t *ext = (uint8_t *) ct + ct->base_table_length; 332 332 uint8_t *cur; 333 333 334 334 for (cur = ext; cur < ext + ct->ext_table_length; 335 335 cur += cur[CT_EXT_ENTRY_LEN]) { … … 349 349 return; 350 350 } 351 351 352 352 if (!mps_ct_check()) { 353 353 log(LF_ARCH, LVL_WARN, "MPS: Wrong ct checksum"); 354 354 return; 355 355 } 356 356 357 357 if (ct->oem_table) { 358 358 log(LF_ARCH, LVL_WARN, "MPS: ct->oem_table not supported"); 359 359 return; 360 360 } 361 361 362 362 l_apic = (uint32_t *) (uintptr_t) ct->l_apic; 363 363 364 364 uint8_t *cur = &ct->base_table[0]; 365 365 uint16_t i; 366 366 367 367 for (i = 0; i < ct->entry_count; i++) { 368 368 switch (*cur) { … … 411 411 } 412 412 } 413 413 414 414 /* 415 415 * Process extended entries. … … 432 432 unsigned int j; 433 433 unsigned int length[2] = { 1024, 64 * 1024 }; 434 434 435 435 /* 436 436 * Find MP Floating Pointer Structure … … 439 439 * 2. search 64K starting at 0xf0000 440 440 */ 441 441 442 442 addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); 443 443 for (i = 0; i < 2; i++) { … … 450 450 } 451 451 } 452 452 453 453 return; 454 454 455 455 fs_found: 456 456 log(LF_ARCH, LVL_NOTE, "%p: MPS Floating Pointer Structure", fs); 457 457 458 458 if ((fs->config_type == 0) && (fs->configuration_table)) { 459 459 if (fs->mpfib2 >> 7) { … … 461 461 return; 462 462 } 463 463 464 464 ct = (struct mps_ct *) PA2KA((uintptr_t) fs->configuration_table); 465 465 configure_via_ct(); 466 466 } else 467 467 configure_via_default(fs->config_type); 468 468 469 469 if (processor_entry_cnt > 0) 470 470 config.cpu_count = processor_entry_cnt; -
kernel/arch/ia32/src/smp/smp.c
r3061bc1 ra35b458 68 68 ops = &madt_config_operations; 69 69 } 70 70 71 71 if (config.cpu_count == 1) { 72 72 mps_init(); 73 73 ops = &mps_config_operations; 74 74 } 75 75 76 76 if (config.cpu_count > 1) { 77 77 l_apic = (uint32_t *) km_map((uintptr_t) l_apic, PAGE_SIZE, … … 86 86 assert(ops != NULL); 87 87 assert(cpus != NULL); 88 88 89 89 for (unsigned int i = 0; i < config.cpu_count; ++i) { 90 90 cpus[i].arch.id = ops->cpu_apic_id(i); … … 102 102 { 103 103 unsigned int i; 104 104 105 105 assert(ops != NULL); 106 106 … … 110 110 */ 111 111 cpu_arch_id_init(); 112 112 113 113 /* 114 114 * We need to access data in frame 0. 115 115 * We boldly make use of kernel address space mapping. 116 116 */ 117 117 118 118 /* 119 119 * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot() … … 122 122 (uint16_t) (((uintptr_t) ap_boot) >> 4); /* segment */ 123 123 *((uint16_t *) (PA2KA(0x467 + 2))) = 0; /* offset */ 124 124 125 125 /* 126 126 * Save 0xa to address 0xf of the CMOS RAM. … … 129 129 pio_write_8((ioport8_t *) 0x70, 0xf); 130 130 pio_write_8((ioport8_t *) 0x71, 0xa); 131 131 132 132 pic_disable_irqs(0xffff); 133 133 apic_init(); 134 134 135 135 for (i = 0; i < config.cpu_count; i++) { 136 136 /* … … 139 139 if (!ops->cpu_enabled(i)) 140 140 continue; 141 141 142 142 /* 143 143 * The bootstrap processor is already up. … … 145 145 if (ops->cpu_bootstrap(i)) 146 146 continue; 147 147 148 148 if (ops->cpu_apic_id(i) == bsp_l_apic) { 149 149 log(LF_ARCH, LVL_ERROR, "kmp: bad processor entry #%u, " … … 151 151 continue; 152 152 } 153 153 154 154 /* 155 155 * Prepare new GDT for CPU in question. 156 156 */ 157 157 158 158 /* XXX Flag FRAME_LOW_4_GiB was removed temporarily, 159 159 * it needs to be replaced by a generic fuctionality of … … 165 165 if (!gdt_new) 166 166 panic("Cannot allocate memory for GDT."); 167 167 168 168 memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t)); 169 169 memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0); … … 171 171 protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); 172 172 gdtr.base = (uintptr_t) gdt_new; 173 173 174 174 if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) { 175 175 /* -
kernel/arch/ia32/src/userspace.c
r3061bc1 ra35b458 50 50 { 51 51 uint32_t eflags = read_eflags(); 52 52 53 53 asm volatile ( 54 54 /* Set up GS register (virtual register segment) */ 55 55 "movl %[vreg_des], %%gs\n" 56 56 57 57 "pushl %[udata_des]\n" 58 58 "pushl %[stack_top]\n" … … 61 61 "pushl %[entry]\n" 62 62 "movl %[uarg], %%eax\n" 63 63 64 64 /* %edi is defined to hold pcb_ptr - set it to 0 */ 65 65 "xorl %%edi, %%edi\n" 66 66 67 67 "iret\n" 68 68 : … … 77 77 [vreg_des] "r" (GDT_SELECTOR(VREG_DES)) 78 78 : "eax"); 79 79 80 80 /* Unreachable */ 81 81 while (1);
Note:
See TracChangeset
for help on using the changeset viewer.