Revision d362e757
b/cpu-all.h | ||
---|---|---|
375 | 375 |
#define CPU_INTERRUPT_TGT_INT_0 0x0100 |
376 | 376 |
#define CPU_INTERRUPT_TGT_INT_1 0x0400 |
377 | 377 |
#define CPU_INTERRUPT_TGT_INT_2 0x0800 |
378 |
#define CPU_INTERRUPT_TGT_INT_3 0x2000 |
|
378 | 379 |
|
379 |
/* First unused bit: 0x2000. */
|
|
380 |
/* First unused bit: 0x4000. */
|
|
380 | 381 |
|
381 | 382 |
/* The set of all bits that should be masked when single-stepping. */ |
382 | 383 |
#define CPU_INTERRUPT_SSTEP_MASK \ |
b/hw/apic.h | ||
---|---|---|
18 | 18 |
uint8_t cpu_get_apic_tpr(DeviceState *s); |
19 | 19 |
void apic_init_reset(DeviceState *s); |
20 | 20 |
void apic_sipi(DeviceState *s); |
21 |
void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip, |
|
22 |
TPRAccess access); |
|
21 | 23 |
|
22 | 24 |
/* pc.c */ |
23 | 25 |
int cpu_is_bsp(CPUState *env); |
b/hw/apic_common.c | ||
---|---|---|
68 | 68 |
return s ? s->tpr >> 4 : 0; |
69 | 69 |
} |
70 | 70 |
|
71 |
void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip, |
|
72 |
TPRAccess access) |
|
73 |
{ |
|
74 |
} |
|
75 |
|
|
71 | 76 |
void apic_report_irq_delivered(int delivered) |
72 | 77 |
{ |
73 | 78 |
apic_irq_delivered += delivered; |
b/hw/mc146818rtc.c | ||
---|---|---|
25 | 25 |
#include "qemu-timer.h" |
26 | 26 |
#include "sysemu.h" |
27 | 27 |
#include "pc.h" |
28 |
#include "apic.h" |
|
29 | 28 |
#include "isa.h" |
30 | 29 |
#include "mc146818rtc.h" |
31 | 30 |
|
31 |
#ifdef TARGET_I386 |
|
32 |
#include "apic.h" |
|
33 |
#endif |
|
34 |
|
|
32 | 35 |
//#define DEBUG_CMOS |
33 | 36 |
//#define DEBUG_COALESCED |
34 | 37 |
|
b/target-i386/cpu.h | ||
---|---|---|
482 | 482 |
#define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_INT_0 |
483 | 483 |
#define CPU_INTERRUPT_INIT CPU_INTERRUPT_TGT_INT_1 |
484 | 484 |
#define CPU_INTERRUPT_SIPI CPU_INTERRUPT_TGT_INT_2 |
485 |
#define CPU_INTERRUPT_TPR CPU_INTERRUPT_TGT_INT_3 |
|
485 | 486 |
|
486 | 487 |
|
487 | 488 |
enum { |
... | ... | |
613 | 614 |
|
614 | 615 |
#define NB_MMU_MODES 2 |
615 | 616 |
|
617 |
typedef enum TPRAccess { |
|
618 |
TPR_ACCESS_READ, |
|
619 |
TPR_ACCESS_WRITE, |
|
620 |
} TPRAccess; |
|
621 |
|
|
616 | 622 |
typedef struct CPUX86State { |
617 | 623 |
/* standard registers */ |
618 | 624 |
target_ulong regs[CPU_NB_REGS]; |
... | ... | |
772 | 778 |
XMMReg ymmh_regs[CPU_NB_REGS]; |
773 | 779 |
|
774 | 780 |
uint64_t xcr0; |
781 |
|
|
782 |
TPRAccess tpr_access_type; |
|
775 | 783 |
} CPUX86State; |
776 | 784 |
|
777 | 785 |
CPUX86State *cpu_x86_init(const char *cpu_model); |
... | ... | |
1064 | 1072 |
|
1065 | 1073 |
uint32_t cpu_cc_compute_all(CPUState *env1, int op); |
1066 | 1074 |
|
1075 |
void cpu_report_tpr_access(CPUState *env, TPRAccess access); |
|
1076 |
|
|
1067 | 1077 |
#endif /* CPU_I386_H */ |
b/target-i386/helper.c | ||
---|---|---|
1189 | 1189 |
} |
1190 | 1190 |
} |
1191 | 1191 |
} |
1192 |
|
|
1193 |
void cpu_report_tpr_access(CPUState *env, TPRAccess access) |
|
1194 |
{ |
|
1195 |
TranslationBlock *tb; |
|
1196 |
|
|
1197 |
if (kvm_enabled()) { |
|
1198 |
env->tpr_access_type = access; |
|
1199 |
|
|
1200 |
cpu_interrupt(env, CPU_INTERRUPT_TPR); |
|
1201 |
} else { |
|
1202 |
tb = tb_find_pc(env->mem_io_pc); |
|
1203 |
cpu_restore_state(tb, env, env->mem_io_pc); |
|
1204 |
|
|
1205 |
apic_handle_tpr_access_report(env->apic_state, env->eip, access); |
|
1206 |
} |
|
1207 |
} |
|
1192 | 1208 |
#endif /* !CONFIG_USER_ONLY */ |
1193 | 1209 |
|
1194 | 1210 |
static void mce_init(CPUX86State *cenv) |
b/target-i386/kvm.c | ||
---|---|---|
1635 | 1635 |
} |
1636 | 1636 |
|
1637 | 1637 |
if (!kvm_irqchip_in_kernel()) { |
1638 |
/* Force the VCPU out of its inner loop to process the INIT request */ |
|
1639 |
if (env->interrupt_request & CPU_INTERRUPT_INIT) { |
|
1638 |
/* Force the VCPU out of its inner loop to process any INIT requests |
|
1639 |
* or pending TPR access reports. */ |
|
1640 |
if (env->interrupt_request & |
|
1641 |
(CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) { |
|
1640 | 1642 |
env->exit_request = 1; |
1641 | 1643 |
} |
1642 | 1644 |
|
... | ... | |
1730 | 1732 |
kvm_cpu_synchronize_state(env); |
1731 | 1733 |
do_cpu_sipi(env); |
1732 | 1734 |
} |
1735 |
if (env->interrupt_request & CPU_INTERRUPT_TPR) { |
|
1736 |
env->interrupt_request &= ~CPU_INTERRUPT_TPR; |
|
1737 |
kvm_cpu_synchronize_state(env); |
|
1738 |
apic_handle_tpr_access_report(env->apic_state, env->eip, |
|
1739 |
env->tpr_access_type); |
|
1740 |
} |
|
1733 | 1741 |
|
1734 | 1742 |
return env->halted; |
1735 | 1743 |
} |
... | ... | |
1746 | 1754 |
return 0; |
1747 | 1755 |
} |
1748 | 1756 |
|
1757 |
static int kvm_handle_tpr_access(CPUState *env) |
|
1758 |
{ |
|
1759 |
struct kvm_run *run = env->kvm_run; |
|
1760 |
|
|
1761 |
apic_handle_tpr_access_report(env->apic_state, run->tpr_access.rip, |
|
1762 |
run->tpr_access.is_write ? TPR_ACCESS_WRITE |
|
1763 |
: TPR_ACCESS_READ); |
|
1764 |
return 1; |
|
1765 |
} |
|
1766 |
|
|
1749 | 1767 |
int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp) |
1750 | 1768 |
{ |
1751 | 1769 |
static const uint8_t int3 = 0xcc; |
... | ... | |
1950 | 1968 |
case KVM_EXIT_SET_TPR: |
1951 | 1969 |
ret = 0; |
1952 | 1970 |
break; |
1971 |
case KVM_EXIT_TPR_ACCESS: |
|
1972 |
ret = kvm_handle_tpr_access(env); |
|
1973 |
break; |
|
1953 | 1974 |
case KVM_EXIT_FAIL_ENTRY: |
1954 | 1975 |
code = run->fail_entry.hardware_entry_failure_reason; |
1955 | 1976 |
fprintf(stderr, "KVM: entry failed, hardware error 0x%" PRIx64 "\n", |
Also available in: Unified diff