| 121 |
/* normal INIT IPI sent to processors */ |
/* normal INIT IPI sent to processors */ |
| 122 |
for (apic_iter = first_local_apic; apic_iter != NULL; |
for (apic_iter = first_local_apic; apic_iter != NULL; |
| 123 |
apic_iter = apic_iter->next_apic) { |
apic_iter = apic_iter->next_apic) { |
| 124 |
apic_init_ipi(apic_iter); |
if (deliver_bitmask & (1 << apic_iter->id)) |
| 125 |
|
apic_init_ipi(apic_iter); |
| 126 |
} |
} |
| 127 |
return; |
return; |
| 128 |
|
|
| 318 |
s->tpr = 0; |
s->tpr = 0; |
| 319 |
s->spurious_vec = 0xff; |
s->spurious_vec = 0xff; |
| 320 |
s->log_dest = 0; |
s->log_dest = 0; |
| 321 |
s->dest_mode = 0; |
s->dest_mode = 0xf; |
| 322 |
memset(s->isr, 0, sizeof(s->isr)); |
memset(s->isr, 0, sizeof(s->isr)); |
| 323 |
memset(s->tmr, 0, sizeof(s->tmr)); |
memset(s->tmr, 0, sizeof(s->tmr)); |
| 324 |
memset(s->irr, 0, sizeof(s->irr)); |
memset(s->irr, 0, sizeof(s->irr)); |
| 332 |
s->next_time = 0; |
s->next_time = 0; |
| 333 |
} |
} |
| 334 |
|
|
| 335 |
|
/* send a SIPI message to the CPU to start it */ |
| 336 |
|
static void apic_startup(APICState *s, int vector_num) |
| 337 |
|
{ |
| 338 |
|
CPUState *env = s->cpu_env; |
| 339 |
|
if (!env->cpu_halted) |
| 340 |
|
return; |
| 341 |
|
env->eip = 0; |
| 342 |
|
cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12, |
| 343 |
|
0xffff, 0); |
| 344 |
|
env->cpu_halted = 0; |
| 345 |
|
} |
| 346 |
|
|
| 347 |
static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode, |
static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode, |
| 348 |
uint8_t delivery_mode, uint8_t vector_num, |
uint8_t delivery_mode, uint8_t vector_num, |
| 349 |
uint8_t polarity, uint8_t trigger_mode) |
uint8_t polarity, uint8_t trigger_mode) |
| 352 |
int dest_shorthand = (s->icr[0] >> 18) & 3; |
int dest_shorthand = (s->icr[0] >> 18) & 3; |
| 353 |
APICState *apic_iter; |
APICState *apic_iter; |
| 354 |
|
|
| 355 |
|
switch (dest_shorthand) { |
| 356 |
|
case 0: |
| 357 |
|
deliver_bitmask = apic_get_delivery_bitmask(dest, dest_mode); |
| 358 |
|
break; |
| 359 |
|
case 1: |
| 360 |
|
deliver_bitmask = (1 << s->id); |
| 361 |
|
break; |
| 362 |
|
case 2: |
| 363 |
|
deliver_bitmask = 0xffffffff; |
| 364 |
|
break; |
| 365 |
|
case 3: |
| 366 |
|
deliver_bitmask = 0xffffffff & ~(1 << s->id); |
| 367 |
|
break; |
| 368 |
|
} |
| 369 |
|
|
| 370 |
switch (delivery_mode) { |
switch (delivery_mode) { |
| 371 |
case APIC_DM_LOWPRI: |
case APIC_DM_LOWPRI: |
| 372 |
/* XXX: serch for focus processor, arbitration */ |
/* XXX: search for focus processor, arbitration */ |
| 373 |
dest = s->id; |
dest = s->id; |
| 374 |
|
break; |
| 375 |
|
|
| 376 |
case APIC_DM_INIT: |
case APIC_DM_INIT: |
| 377 |
{ |
{ |
| 393 |
for (apic_iter = first_local_apic; apic_iter != NULL; |
for (apic_iter = first_local_apic; apic_iter != NULL; |
| 394 |
apic_iter = apic_iter->next_apic) { |
apic_iter = apic_iter->next_apic) { |
| 395 |
if (deliver_bitmask & (1 << apic_iter->id)) { |
if (deliver_bitmask & (1 << apic_iter->id)) { |
| 396 |
/* XXX: SMP support */ |
apic_startup(apic_iter, vector_num); |
|
/* apic_startup(apic_iter); */ |
|
| 397 |
} |
} |
| 398 |
} |
} |
| 399 |
return; |
return; |
| 400 |
} |
} |
| 401 |
|
|
|
switch (dest_shorthand) { |
|
|
case 0: |
|
|
deliver_bitmask = apic_get_delivery_bitmask(dest, dest_mode); |
|
|
break; |
|
|
case 1: |
|
|
deliver_bitmask = (1 << s->id); |
|
|
break; |
|
|
case 2: |
|
|
deliver_bitmask = 0xffffffff; |
|
|
break; |
|
|
case 3: |
|
|
deliver_bitmask = 0xffffffff & ~(1 << s->id); |
|
|
break; |
|
|
} |
|
|
|
|
| 402 |
apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity, |
apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity, |
| 403 |
trigger_mode); |
trigger_mode); |
| 404 |
} |
} |
| 547 |
case 0x28: |
case 0x28: |
| 548 |
val = s->esr; |
val = s->esr; |
| 549 |
break; |
break; |
|
case 0x32 ... 0x37: |
|
|
val = s->lvt[index - 0x32]; |
|
|
break; |
|
| 550 |
case 0x30: |
case 0x30: |
| 551 |
case 0x31: |
case 0x31: |
| 552 |
val = s->icr[index & 1]; |
val = s->icr[index & 1]; |
| 553 |
break; |
break; |
| 554 |
|
case 0x32 ... 0x37: |
| 555 |
|
val = s->lvt[index - 0x32]; |
| 556 |
|
break; |
| 557 |
case 0x38: |
case 0x38: |
| 558 |
val = s->initial_count; |
val = s->initial_count; |
| 559 |
break; |
break; |
| 594 |
case 0x02: |
case 0x02: |
| 595 |
s->id = (val >> 24); |
s->id = (val >> 24); |
| 596 |
break; |
break; |
| 597 |
|
case 0x03: |
| 598 |
|
break; |
| 599 |
case 0x08: |
case 0x08: |
| 600 |
s->tpr = val; |
s->tpr = val; |
| 601 |
apic_update_irq(s); |
apic_update_irq(s); |
| 602 |
break; |
break; |
| 603 |
|
case 0x09: |
| 604 |
|
case 0x0a: |
| 605 |
|
break; |
| 606 |
case 0x0b: /* EOI */ |
case 0x0b: /* EOI */ |
| 607 |
apic_eoi(s); |
apic_eoi(s); |
| 608 |
break; |
break; |
| 616 |
s->spurious_vec = val & 0x1ff; |
s->spurious_vec = val & 0x1ff; |
| 617 |
apic_update_irq(s); |
apic_update_irq(s); |
| 618 |
break; |
break; |
| 619 |
|
case 0x10 ... 0x17: |
| 620 |
|
case 0x18 ... 0x1f: |
| 621 |
|
case 0x20 ... 0x27: |
| 622 |
|
case 0x28: |
| 623 |
|
break; |
| 624 |
case 0x30: |
case 0x30: |
| 625 |
s->icr[0] = val; |
s->icr[0] = val; |
| 626 |
apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1, |
apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1, |
| 643 |
s->initial_count_load_time = qemu_get_clock(vm_clock); |
s->initial_count_load_time = qemu_get_clock(vm_clock); |
| 644 |
apic_timer_update(s, s->initial_count_load_time); |
apic_timer_update(s, s->initial_count_load_time); |
| 645 |
break; |
break; |
| 646 |
|
case 0x39: |
| 647 |
|
break; |
| 648 |
case 0x3e: |
case 0x3e: |
| 649 |
{ |
{ |
| 650 |
int v; |
int v; |