Changeset a35b458 in mainline for kernel/arch/ia32/src/smp/apic.c
- 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)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note:
See TracChangeset
for help on using the changeset viewer.