Revision 0e26b7b8 hw/apic.c
b/hw/apic.c | ||
---|---|---|
320 | 320 |
/* if disabled, cannot be enabled again */ |
321 | 321 |
if (!(val & MSR_IA32_APICBASE_ENABLE)) { |
322 | 322 |
s->apicbase &= ~MSR_IA32_APICBASE_ENABLE; |
323 |
s->cpu_env->cpuid_features &= ~CPUID_APIC;
|
|
323 |
cpu_clear_apic_feature(s->cpu_env);
|
|
324 | 324 |
s->spurious_vec &= ~APIC_SV_ENABLE; |
325 | 325 |
} |
326 | 326 |
} |
... | ... | |
508 | 508 |
s->initial_count_load_time = 0; |
509 | 509 |
s->next_time = 0; |
510 | 510 |
s->wait_for_sipi = 1; |
511 |
|
|
512 |
s->cpu_env->halted = !(s->apicbase & MSR_IA32_APICBASE_BSP); |
|
513 | 511 |
} |
514 | 512 |
|
515 | 513 |
static void apic_startup(APICState *s, int vector_num) |
... | ... | |
524 | 522 |
|
525 | 523 |
if (!s->wait_for_sipi) |
526 | 524 |
return; |
527 |
|
|
528 |
s->cpu_env->eip = 0; |
|
529 |
cpu_x86_load_seg_cache(s->cpu_env, R_CS, s->sipi_vector << 8, |
|
530 |
s->sipi_vector << 12, |
|
531 |
s->cpu_env->segs[R_CS].limit, |
|
532 |
s->cpu_env->segs[R_CS].flags); |
|
533 |
s->cpu_env->halted = 0; |
|
525 |
cpu_x86_load_seg_cache_sipi(s->cpu_env, s->sipi_vector); |
|
534 | 526 |
s->wait_for_sipi = 0; |
535 | 527 |
} |
536 | 528 |
|
... | ... | |
692 | 684 |
|
693 | 685 |
static uint32_t apic_mem_readl(void *opaque, target_phys_addr_t addr) |
694 | 686 |
{ |
695 |
CPUState *env; |
|
696 | 687 |
APICState *s; |
697 | 688 |
uint32_t val; |
698 | 689 |
int index; |
699 | 690 |
|
700 |
env = cpu_single_env;
|
|
701 |
if (!env)
|
|
691 |
s = cpu_get_current_apic();
|
|
692 |
if (!s) {
|
|
702 | 693 |
return 0; |
703 |
s = env->apic_state;
|
|
694 |
}
|
|
704 | 695 |
|
705 | 696 |
index = (addr >> 4) & 0xff; |
706 | 697 |
switch(index) { |
... | ... | |
782 | 773 |
|
783 | 774 |
static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) |
784 | 775 |
{ |
785 |
CPUState *env; |
|
786 | 776 |
APICState *s; |
787 | 777 |
int index = (addr >> 4) & 0xff; |
788 | 778 |
if (addr > 0xfff || !index) { |
... | ... | |
795 | 785 |
return; |
796 | 786 |
} |
797 | 787 |
|
798 |
env = cpu_single_env;
|
|
799 |
if (!env)
|
|
788 |
s = cpu_get_current_apic();
|
|
789 |
if (!s) {
|
|
800 | 790 |
return; |
801 |
s = env->apic_state;
|
|
791 |
}
|
|
802 | 792 |
|
803 | 793 |
DPRINTF("write: " TARGET_FMT_plx " = %08x\n", addr, val); |
804 | 794 |
|
... | ... | |
949 | 939 |
s->apicbase = 0xfee00000 | |
950 | 940 |
(bsp ? MSR_IA32_APICBASE_BSP : 0) | MSR_IA32_APICBASE_ENABLE; |
951 | 941 |
|
952 |
cpu_reset(s->cpu_env); |
|
953 | 942 |
apic_init_reset(s); |
954 | 943 |
|
955 | 944 |
if (bsp) { |
... | ... | |
974 | 963 |
apic_mem_writel, |
975 | 964 |
}; |
976 | 965 |
|
977 |
int apic_init(CPUState *env)
|
|
966 |
APICState *apic_init(CPUState *env, uint32_t apic_id)
|
|
978 | 967 |
{ |
979 | 968 |
APICState *s; |
980 | 969 |
|
981 |
if (last_apic_idx >= MAX_APICS) |
|
982 |
return -1; |
|
970 |
if (last_apic_idx >= MAX_APICS) { |
|
971 |
return NULL; |
|
972 |
} |
|
983 | 973 |
s = qemu_mallocz(sizeof(APICState)); |
984 |
env->apic_state = s; |
|
985 | 974 |
s->idx = last_apic_idx++; |
986 |
s->id = env->cpuid_apic_id;
|
|
975 |
s->id = apic_id; |
|
987 | 976 |
s->cpu_env = env; |
988 | 977 |
|
989 | 978 |
msix_supported = 1; |
... | ... | |
1004 | 993 |
qemu_register_reset(apic_reset, s); |
1005 | 994 |
|
1006 | 995 |
local_apics[s->idx] = s; |
1007 |
return 0;
|
|
996 |
return s;
|
|
1008 | 997 |
} |
Also available in: Unified diff