Changeset 235 for trunk/hal/x86_64/core/hal_apic.c
- Timestamp:
- Jul 19, 2017, 10:03:41 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/x86_64/core/hal_apic.c
r234 r235 58 58 #define PIT_FREQUENCY 1193182 59 59 #define HZ 100 /* 1/HZ = 10ms */ 60 #define muHZ 1000000 /* 1/muHZ = 1 microsecond */ 60 61 61 62 #define PIT_TIMER0 0x40 … … 79 80 # define CMD_READBACK 0xc0 80 81 81 void hal_pit_init() 82 { 83 /* Initialize PIT clock 0 to the maximum counter value, 65535. */ 82 void hal_pit_reset(uint16_t val) 83 { 84 pit_ticks_base = 0; 85 86 /* Initialize PIT clock 0 to value given. */ 84 87 out8(PIT_CMD, CMD_COUNTER0|CMD_MODE2|CMD_16BIT); 85 out8(PIT_TIMER0, 0xFF);86 out8(PIT_TIMER0, 0xFF);88 out8(PIT_TIMER0, (val >> 0) & 0xFF); 89 out8(PIT_TIMER0, (val >> 8) & 0xFF); 87 90 } 88 91 … … 110 113 111 114 return ticks; 115 } 116 117 /* 118 * Wait approximately n microseconds. 119 */ 120 void 121 hal_pit_delay(uint64_t n) 122 { 123 uint64_t nticks; 124 125 nticks = 0; 126 hal_pit_reset(0); 127 128 while (n > 0) { 129 while (hal_pit_timer_read() - nticks < (PIT_FREQUENCY + muHZ/2) / muHZ) { 130 /* Wait 1/muHZ sec = 1 microsecond */ 131 } 132 nticks++; 133 n--; 134 } 112 135 } 113 136 … … 345 368 } 346 369 370 static void hal_lapic_icr_wait() 371 { 372 while ((hal_lapic_read(LAPIC_ICRLO) & LAPIC_DLSTAT_BUSY) != 0) { 373 pause(); 374 } 375 } 376 347 377 /* 348 378 * Use the PIT, which has a standard clock frequency, to determine the CPU's … … 357 387 hal_lapic_write(LAPIC_ICR_TIMER, 0xFFFFFFFF); 358 388 359 /* Initializethe PIT */360 hal_pit_ init();389 /* Reset the PIT */ 390 hal_pit_reset(-1); 361 391 362 392 pittick = hal_pit_timer_read() + 1; … … 423 453 /* -------------------------------------------------------------------------- */ 424 454 455 static void 456 hal_ipi_init(uint32_t gid) 457 { 458 /* clear the error status */ 459 hal_lapic_write(LAPIC_ESR, 0); 460 (void)hal_lapic_read(LAPIC_ESR); 461 462 /* send the IPI */ 463 hal_lapic_write(LAPIC_ICRHI, gid << LAPIC_ID_SHIFT); 464 hal_lapic_write(LAPIC_ICRLO, LAPIC_DLMODE_INIT | LAPIC_LEVEL_ASSERT); 465 hal_lapic_icr_wait(); 466 467 /* wait 10ms */ 468 hal_pit_delay(10000); 469 470 hal_lapic_write(LAPIC_ICRLO, 471 LAPIC_DLMODE_INIT | LAPIC_TRIGGER_LEVEL | LAPIC_LEVEL_DEASSERT); 472 hal_lapic_icr_wait(); 473 } 474 475 static void 476 hal_ipi_startup(uint32_t gid, paddr_t pa) 477 { 478 /* clear the error status */ 479 hal_lapic_write(LAPIC_ESR, 0); 480 (void)hal_lapic_read(LAPIC_ESR); 481 482 /* send the IPI */ 483 hal_lapic_icr_wait(); 484 hal_lapic_write(LAPIC_ICRHI, gid << LAPIC_ID_SHIFT); 485 hal_lapic_write(LAPIC_ICRLO, pa | LAPIC_DLMODE_STARTUP | 486 LAPIC_LEVEL_ASSERT); 487 hal_lapic_icr_wait(); 488 } 489 490 /* -------------------------------------------------------------------------- */ 491 492 int 493 start_secondary_cpu(uint32_t gid, paddr_t pa) 494 { 495 /* 496 * Bootstrap code must be addressable in real mode and it must be 497 * page-aligned. 498 */ 499 XASSERT(pa < 0x10000 && pa % PAGE_SIZE == 0); 500 501 /* 502 * Local cache flush, in case the BIOS has left the AP with its cache 503 * disabled. It may not be able to cope with MP coherency. 504 */ 505 wbinvd(); 506 507 hal_ipi_init(gid); 508 hal_pit_delay(10000); 509 510 hal_ipi_startup(gid, pa / PAGE_SIZE); 511 hal_pit_delay(200); 512 513 hal_ipi_startup(gid, pa / PAGE_SIZE); 514 hal_pit_delay(200); 515 516 return 0; 517 } 518 519 /* -------------------------------------------------------------------------- */ 520 425 521 void hal_apic_init() 426 522 {
Note: See TracChangeset
for help on using the changeset viewer.