Revision cf6d64bf
b/hw/apic.c | ||
---|---|---|
94 | 94 |
#define MSI_ADDR_BASE 0xfee00000 |
95 | 95 |
#define MSI_ADDR_SIZE 0x100000 |
96 | 96 |
|
97 |
typedef struct APICState {
|
|
97 |
struct APICState { |
|
98 | 98 |
CPUState *cpu_env; |
99 | 99 |
uint32_t apicbase; |
100 | 100 |
uint8_t id; |
... | ... | |
118 | 118 |
QEMUTimer *timer; |
119 | 119 |
int sipi_vector; |
120 | 120 |
int wait_for_sipi; |
121 |
} APICState;
|
|
121 |
}; |
|
122 | 122 |
|
123 | 123 |
static int apic_io_memory; |
124 | 124 |
static APICState *local_apics[MAX_APICS + 1]; |
... | ... | |
167 | 167 |
return !!(tab[i] & mask); |
168 | 168 |
} |
169 | 169 |
|
170 |
static void apic_local_deliver(CPUState *env, int vector)
|
|
170 |
static void apic_local_deliver(APICState *s, int vector)
|
|
171 | 171 |
{ |
172 |
APICState *s = env->apic_state; |
|
173 | 172 |
uint32_t lvt = s->lvt[vector]; |
174 | 173 |
int trigger_mode; |
175 | 174 |
|
... | ... | |
180 | 179 |
|
181 | 180 |
switch ((lvt >> 8) & 7) { |
182 | 181 |
case APIC_DM_SMI: |
183 |
cpu_interrupt(env, CPU_INTERRUPT_SMI); |
|
182 |
cpu_interrupt(s->cpu_env, CPU_INTERRUPT_SMI);
|
|
184 | 183 |
break; |
185 | 184 |
|
186 | 185 |
case APIC_DM_NMI: |
187 |
cpu_interrupt(env, CPU_INTERRUPT_NMI); |
|
186 |
cpu_interrupt(s->cpu_env, CPU_INTERRUPT_NMI);
|
|
188 | 187 |
break; |
189 | 188 |
|
190 | 189 |
case APIC_DM_EXTINT: |
191 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
190 |
cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
|
|
192 | 191 |
break; |
193 | 192 |
|
194 | 193 |
case APIC_DM_FIXED: |
... | ... | |
200 | 199 |
} |
201 | 200 |
} |
202 | 201 |
|
203 |
void apic_deliver_pic_intr(CPUState *env, int level)
|
|
202 |
void apic_deliver_pic_intr(APICState *s, int level)
|
|
204 | 203 |
{ |
205 |
if (level) |
|
206 |
apic_local_deliver(env, APIC_LVT_LINT0); |
|
207 |
else { |
|
208 |
APICState *s = env->apic_state; |
|
204 |
if (level) { |
|
205 |
apic_local_deliver(s, APIC_LVT_LINT0); |
|
206 |
} else { |
|
209 | 207 |
uint32_t lvt = s->lvt[APIC_LVT_LINT0]; |
210 | 208 |
|
211 | 209 |
switch ((lvt >> 8) & 7) { |
... | ... | |
215 | 213 |
reset_bit(s->irr, lvt & 0xff); |
216 | 214 |
/* fall through */ |
217 | 215 |
case APIC_DM_EXTINT: |
218 |
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
|
216 |
cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
|
|
219 | 217 |
break; |
220 | 218 |
} |
221 | 219 |
} |
... | ... | |
591 | 589 |
trigger_mode); |
592 | 590 |
} |
593 | 591 |
|
594 |
int apic_get_interrupt(CPUState *env)
|
|
592 |
int apic_get_interrupt(APICState *s)
|
|
595 | 593 |
{ |
596 |
APICState *s = env->apic_state; |
|
597 | 594 |
int intno; |
598 | 595 |
|
599 | 596 |
/* if the APIC is installed or enabled, we let the 8259 handle the |
... | ... | |
615 | 612 |
return intno; |
616 | 613 |
} |
617 | 614 |
|
618 |
int apic_accept_pic_intr(CPUState *env)
|
|
615 |
int apic_accept_pic_intr(APICState *s)
|
|
619 | 616 |
{ |
620 |
APICState *s = env->apic_state; |
|
621 | 617 |
uint32_t lvt0; |
622 | 618 |
|
623 | 619 |
if (!s) |
... | ... | |
679 | 675 |
{ |
680 | 676 |
APICState *s = opaque; |
681 | 677 |
|
682 |
apic_local_deliver(s->cpu_env, APIC_LVT_TIMER);
|
|
678 |
apic_local_deliver(s, APIC_LVT_TIMER); |
|
683 | 679 |
apic_timer_update(s, s->next_time); |
684 | 680 |
} |
685 | 681 |
|
b/hw/apic.h | ||
---|---|---|
1 | 1 |
#ifndef APIC_H |
2 | 2 |
#define APIC_H |
3 | 3 |
|
4 |
/* apic.c */ |
|
5 |
typedef struct APICState APICState; |
|
4 | 6 |
void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, |
5 | 7 |
uint8_t delivery_mode, |
6 | 8 |
uint8_t vector_num, uint8_t polarity, |
7 | 9 |
uint8_t trigger_mode); |
8 | 10 |
int apic_init(CPUState *env); |
9 |
int apic_accept_pic_intr(CPUState *env);
|
|
10 |
void apic_deliver_pic_intr(CPUState *env, int level);
|
|
11 |
int apic_get_interrupt(CPUState *env);
|
|
11 |
int apic_accept_pic_intr(APICState *s);
|
|
12 |
void apic_deliver_pic_intr(APICState *s, int level);
|
|
13 |
int apic_get_interrupt(APICState *s);
|
|
12 | 14 |
void apic_reset_irq_delivered(void); |
13 | 15 |
int apic_get_irq_delivered(void); |
14 | 16 |
|
b/hw/pc.c | ||
---|---|---|
145 | 145 |
{ |
146 | 146 |
int intno; |
147 | 147 |
|
148 |
intno = apic_get_interrupt(env); |
|
148 |
intno = apic_get_interrupt(env->apic_state);
|
|
149 | 149 |
if (intno >= 0) { |
150 | 150 |
/* set irq request if a PIC irq is still pending */ |
151 | 151 |
/* XXX: improve that */ |
... | ... | |
153 | 153 |
return intno; |
154 | 154 |
} |
155 | 155 |
/* read the irq from the PIC */ |
156 |
if (!apic_accept_pic_intr(env))
|
|
156 |
if (!apic_accept_pic_intr(env->apic_state)) {
|
|
157 | 157 |
return -1; |
158 |
} |
|
158 | 159 |
|
159 | 160 |
intno = pic_read_irq(isa_pic); |
160 | 161 |
return intno; |
... | ... | |
167 | 168 |
DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq); |
168 | 169 |
if (env->apic_state) { |
169 | 170 |
while (env) { |
170 |
if (apic_accept_pic_intr(env)) |
|
171 |
apic_deliver_pic_intr(env, level); |
|
171 |
if (apic_accept_pic_intr(env->apic_state)) { |
|
172 |
apic_deliver_pic_intr(env->apic_state, level); |
|
173 |
} |
|
172 | 174 |
env = env->next_cpu; |
173 | 175 |
} |
174 | 176 |
} else { |
Also available in: Unified diff