1 /*
2 * APIC support
3 *
4 * Copyright (c) 2004-2005 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
19 */
20 #include "hw/hw.h"
21 #include "hw/i386/pc.h"
22 #include "qemu/timer.h"
23 #include "qemu/host-utils.h"
24
25 //#define DEBUG_APIC
26
27 /* APIC Local Vector Table */
28 #define APIC_LVT_TIMER 0
29 #define APIC_LVT_THERMAL 1
30 #define APIC_LVT_PERFORM 2
31 #define APIC_LVT_LINT0 3
32 #define APIC_LVT_LINT1 4
33 #define APIC_LVT_ERROR 5
34 #define APIC_LVT_NB 6
35
36 /* APIC delivery modes */
37 #define APIC_DM_FIXED 0
38 #define APIC_DM_LOWPRI 1
39 #define APIC_DM_SMI 2
40 #define APIC_DM_NMI 4
41 #define APIC_DM_INIT 5
42 #define APIC_DM_SIPI 6
43 #define APIC_DM_EXTINT 7
44
45 /* APIC destination mode */
46 #define APIC_DESTMODE_FLAT 0xf
47 #define APIC_DESTMODE_CLUSTER 1
48
49 #define APIC_TRIGGER_EDGE 0
50 #define APIC_TRIGGER_LEVEL 1
51
52 #define APIC_LVT_TIMER_PERIODIC (1<<17)
53 #define APIC_LVT_MASKED (1<<16)
54 #define APIC_LVT_LEVEL_TRIGGER (1<<15)
55 #define APIC_LVT_REMOTE_IRR (1<<14)
56 #define APIC_INPUT_POLARITY (1<<13)
57 #define APIC_SEND_PENDING (1<<12)
58
59 #define ESR_ILLEGAL_ADDRESS (1 << 7)
60
61 #define APIC_SV_ENABLE (1 << 8)
62
63 #define MAX_APICS 255
64 #define MAX_APIC_WORDS 8
65
66 typedef struct APICState {
67 CPUOldState *cpu_env;
68 uint32_t apicbase;
69 uint8_t id;
70 uint8_t arb_id;
71 uint8_t tpr;
72 uint32_t spurious_vec;
73 uint8_t log_dest;
74 uint8_t dest_mode;
75 uint32_t isr[8]; /* in service register */
76 uint32_t tmr[8]; /* trigger mode register */
77 uint32_t irr[8]; /* interrupt request register */
78 uint32_t lvt[APIC_LVT_NB];
79 uint32_t esr; /* error register */
80 uint32_t icr[2];
81
82 uint32_t divide_conf;
83 int count_shift;
84 uint32_t initial_count;
85 int64_t initial_count_load_time, next_time;
86 uint32_t idx;
87 QEMUTimer *timer;
88 int sipi_vector;
89 int wait_for_sipi;
90 } APICState;
91
92 static int apic_io_memory;
93 static APICState *local_apics[MAX_APICS + 1];
94 static int last_apic_idx = 0;
95 static int apic_irq_delivered;
96
97
98 static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
99 static void apic_update_irq(APICState *s);
100 static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
101 uint8_t dest, uint8_t dest_mode);
102
103 /* Find first bit starting from msb */
fls_bit(uint32_t value)104 static int fls_bit(uint32_t value)
105 {
106 return 31 - clz32(value);
107 }
108
109 /* Find first bit starting from lsb */
ffs_bit(uint32_t value)110 static int ffs_bit(uint32_t value)
111 {
112 return ctz32(value);
113 }
114
set_bit(uint32_t * tab,int index)115 static inline void set_bit(uint32_t *tab, int index)
116 {
117 int i, mask;
118 i = index >> 5;
119 mask = 1 << (index & 0x1f);
120 tab[i] |= mask;
121 }
122
reset_bit(uint32_t * tab,int index)123 static inline void reset_bit(uint32_t *tab, int index)
124 {
125 int i, mask;
126 i = index >> 5;
127 mask = 1 << (index & 0x1f);
128 tab[i] &= ~mask;
129 }
130
get_bit(uint32_t * tab,int index)131 static inline int get_bit(uint32_t *tab, int index)
132 {
133 int i, mask;
134 i = index >> 5;
135 mask = 1 << (index & 0x1f);
136 return !!(tab[i] & mask);
137 }
138
apic_local_deliver(CPUOldState * env,int vector)139 static void apic_local_deliver(CPUOldState *env, int vector)
140 {
141 CPUState *cpu = ENV_GET_CPU(env);
142 APICState *s = env->apic_state;
143 uint32_t lvt = s->lvt[vector];
144 int trigger_mode;
145
146 if (lvt & APIC_LVT_MASKED)
147 return;
148
149 switch ((lvt >> 8) & 7) {
150 case APIC_DM_SMI:
151 cpu_interrupt(cpu, CPU_INTERRUPT_SMI);
152 break;
153
154 case APIC_DM_NMI:
155 cpu_interrupt(cpu, CPU_INTERRUPT_NMI);
156 break;
157
158 case APIC_DM_EXTINT:
159 cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
160 break;
161
162 case APIC_DM_FIXED:
163 trigger_mode = APIC_TRIGGER_EDGE;
164 if ((vector == APIC_LVT_LINT0 || vector == APIC_LVT_LINT1) &&
165 (lvt & APIC_LVT_LEVEL_TRIGGER))
166 trigger_mode = APIC_TRIGGER_LEVEL;
167 apic_set_irq(s, lvt & 0xff, trigger_mode);
168 }
169 }
170
apic_deliver_pic_intr(CPUOldState * env,int level)171 void apic_deliver_pic_intr(CPUOldState *env, int level)
172 {
173 if (level)
174 apic_local_deliver(env, APIC_LVT_LINT0);
175 else {
176 APICState *s = env->apic_state;
177 uint32_t lvt = s->lvt[APIC_LVT_LINT0];
178
179 switch ((lvt >> 8) & 7) {
180 case APIC_DM_FIXED:
181 if (!(lvt & APIC_LVT_LEVEL_TRIGGER))
182 break;
183 reset_bit(s->irr, lvt & 0xff);
184 /* fall through */
185 case APIC_DM_EXTINT:
186 cpu_reset_interrupt(ENV_GET_CPU(env), CPU_INTERRUPT_HARD);
187 break;
188 }
189 }
190 }
191
192 #define foreach_apic(apic, deliver_bitmask, code) \
193 {\
194 int __i, __j, __mask;\
195 for(__i = 0; __i < MAX_APIC_WORDS; __i++) {\
196 __mask = deliver_bitmask[__i];\
197 if (__mask) {\
198 for(__j = 0; __j < 32; __j++) {\
199 if (__mask & (1 << __j)) {\
200 apic = local_apics[__i * 32 + __j];\
201 if (apic) {\
202 code;\
203 }\
204 }\
205 }\
206 }\
207 }\
208 }
209
apic_bus_deliver(const uint32_t * deliver_bitmask,uint8_t delivery_mode,uint8_t vector_num,uint8_t polarity,uint8_t trigger_mode)210 static void apic_bus_deliver(const uint32_t *deliver_bitmask,
211 uint8_t delivery_mode,
212 uint8_t vector_num, uint8_t polarity,
213 uint8_t trigger_mode)
214 {
215 APICState *apic_iter;
216
217 switch (delivery_mode) {
218 case APIC_DM_LOWPRI:
219 /* XXX: search for focus processor, arbitration */
220 {
221 int i, d;
222 d = -1;
223 for(i = 0; i < MAX_APIC_WORDS; i++) {
224 if (deliver_bitmask[i]) {
225 d = i * 32 + ffs_bit(deliver_bitmask[i]);
226 break;
227 }
228 }
229 if (d >= 0) {
230 apic_iter = local_apics[d];
231 if (apic_iter) {
232 apic_set_irq(apic_iter, vector_num, trigger_mode);
233 }
234 }
235 }
236 return;
237
238 case APIC_DM_FIXED:
239 break;
240
241 case APIC_DM_SMI:
242 foreach_apic(apic_iter, deliver_bitmask,
243 cpu_interrupt(ENV_GET_CPU(apic_iter->cpu_env), CPU_INTERRUPT_SMI) );
244 return;
245
246 case APIC_DM_NMI:
247 foreach_apic(apic_iter, deliver_bitmask,
248 cpu_interrupt(ENV_GET_CPU(apic_iter->cpu_env), CPU_INTERRUPT_NMI) );
249 return;
250
251 case APIC_DM_INIT:
252 /* normal INIT IPI sent to processors */
253 foreach_apic(apic_iter, deliver_bitmask,
254 cpu_interrupt(ENV_GET_CPU(apic_iter->cpu_env), CPU_INTERRUPT_INIT) );
255 return;
256
257 case APIC_DM_EXTINT:
258 /* handled in I/O APIC code */
259 break;
260
261 default:
262 return;
263 }
264
265 foreach_apic(apic_iter, deliver_bitmask,
266 apic_set_irq(apic_iter, vector_num, trigger_mode) );
267 }
268
apic_deliver_irq(uint8_t dest,uint8_t dest_mode,uint8_t delivery_mode,uint8_t vector_num,uint8_t polarity,uint8_t trigger_mode)269 void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
270 uint8_t delivery_mode, uint8_t vector_num,
271 uint8_t polarity, uint8_t trigger_mode)
272 {
273 uint32_t deliver_bitmask[MAX_APIC_WORDS];
274
275 apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
276 apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
277 trigger_mode);
278 }
279
cpu_set_apic_base(CPUOldState * env,uint64_t val)280 void cpu_set_apic_base(CPUOldState *env, uint64_t val)
281 {
282 APICState *s = env->apic_state;
283 #ifdef DEBUG_APIC
284 printf("cpu_set_apic_base: %016" PRIx64 "\n", val);
285 #endif
286 if (!s)
287 return;
288 s->apicbase = (val & 0xfffff000) |
289 (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
290 /* if disabled, cannot be enabled again */
291 if (!(val & MSR_IA32_APICBASE_ENABLE)) {
292 s->apicbase &= ~MSR_IA32_APICBASE_ENABLE;
293 env->cpuid_features &= ~CPUID_APIC;
294 s->spurious_vec &= ~APIC_SV_ENABLE;
295 }
296 }
297
cpu_get_apic_base(CPUOldState * env)298 uint64_t cpu_get_apic_base(CPUOldState *env)
299 {
300 APICState *s = env->apic_state;
301 #ifdef DEBUG_APIC
302 printf("cpu_get_apic_base: %016" PRIx64 "\n",
303 s ? (uint64_t)s->apicbase: 0);
304 #endif
305 return s ? s->apicbase : 0;
306 }
307
cpu_set_apic_tpr(CPUX86State * env,uint8_t val)308 void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
309 {
310 APICState *s = env->apic_state;
311 if (!s)
312 return;
313 s->tpr = (val & 0x0f) << 4;
314 apic_update_irq(s);
315 }
316
cpu_get_apic_tpr(CPUX86State * env)317 uint8_t cpu_get_apic_tpr(CPUX86State *env)
318 {
319 APICState *s = env->apic_state;
320 return s ? s->tpr >> 4 : 0;
321 }
322
323 /* return -1 if no bit is set */
get_highest_priority_int(uint32_t * tab)324 static int get_highest_priority_int(uint32_t *tab)
325 {
326 int i;
327 for(i = 7; i >= 0; i--) {
328 if (tab[i] != 0) {
329 return i * 32 + fls_bit(tab[i]);
330 }
331 }
332 return -1;
333 }
334
apic_get_ppr(APICState * s)335 static int apic_get_ppr(APICState *s)
336 {
337 int tpr, isrv, ppr;
338
339 tpr = (s->tpr >> 4);
340 isrv = get_highest_priority_int(s->isr);
341 if (isrv < 0)
342 isrv = 0;
343 isrv >>= 4;
344 if (tpr >= isrv)
345 ppr = s->tpr;
346 else
347 ppr = isrv << 4;
348 return ppr;
349 }
350
apic_get_arb_pri(APICState * s)351 static int apic_get_arb_pri(APICState *s)
352 {
353 /* XXX: arbitration */
354 return 0;
355 }
356
357 /* signal the CPU if an irq is pending */
apic_update_irq(APICState * s)358 static void apic_update_irq(APICState *s)
359 {
360 int irrv, ppr;
361 if (!(s->spurious_vec & APIC_SV_ENABLE))
362 return;
363 irrv = get_highest_priority_int(s->irr);
364 if (irrv < 0)
365 return;
366 ppr = apic_get_ppr(s);
367 if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
368 return;
369 cpu_interrupt(ENV_GET_CPU(s->cpu_env), CPU_INTERRUPT_HARD);
370 }
371
apic_reset_irq_delivered(void)372 void apic_reset_irq_delivered(void)
373 {
374 apic_irq_delivered = 0;
375 }
376
apic_get_irq_delivered(void)377 int apic_get_irq_delivered(void)
378 {
379 return apic_irq_delivered;
380 }
381
apic_set_irq(APICState * s,int vector_num,int trigger_mode)382 static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
383 {
384 apic_irq_delivered += !get_bit(s->irr, vector_num);
385
386 set_bit(s->irr, vector_num);
387 if (trigger_mode)
388 set_bit(s->tmr, vector_num);
389 else
390 reset_bit(s->tmr, vector_num);
391 apic_update_irq(s);
392 }
393
apic_eoi(APICState * s)394 static void apic_eoi(APICState *s)
395 {
396 int isrv;
397 isrv = get_highest_priority_int(s->isr);
398 if (isrv < 0)
399 return;
400 reset_bit(s->isr, isrv);
401 /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
402 set the remote IRR bit for level triggered interrupts. */
403 apic_update_irq(s);
404 }
405
apic_find_dest(uint8_t dest)406 static int apic_find_dest(uint8_t dest)
407 {
408 APICState *apic = local_apics[dest];
409 int i;
410
411 if (apic && apic->id == dest)
412 return dest; /* shortcut in case apic->id == apic->idx */
413
414 for (i = 0; i < MAX_APICS; i++) {
415 apic = local_apics[i];
416 if (apic && apic->id == dest)
417 return i;
418 }
419
420 return -1;
421 }
422
apic_get_delivery_bitmask(uint32_t * deliver_bitmask,uint8_t dest,uint8_t dest_mode)423 static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
424 uint8_t dest, uint8_t dest_mode)
425 {
426 APICState *apic_iter;
427 int i;
428
429 if (dest_mode == 0) {
430 if (dest == 0xff) {
431 memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t));
432 } else {
433 int idx = apic_find_dest(dest);
434 memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
435 if (idx >= 0)
436 set_bit(deliver_bitmask, idx);
437 }
438 } else {
439 /* XXX: cluster mode */
440 memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
441 for(i = 0; i < MAX_APICS; i++) {
442 apic_iter = local_apics[i];
443 if (apic_iter) {
444 if (apic_iter->dest_mode == 0xf) {
445 if (dest & apic_iter->log_dest)
446 set_bit(deliver_bitmask, i);
447 } else if (apic_iter->dest_mode == 0x0) {
448 if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) &&
449 (dest & apic_iter->log_dest & 0x0f)) {
450 set_bit(deliver_bitmask, i);
451 }
452 }
453 }
454 }
455 }
456 }
457
458
apic_init_reset(CPUOldState * env)459 void apic_init_reset(CPUOldState *env)
460 {
461 APICState *s = env->apic_state;
462 int i;
463
464 if (!s)
465 return;
466
467 s->tpr = 0;
468 s->spurious_vec = 0xff;
469 s->log_dest = 0;
470 s->dest_mode = 0xf;
471 memset(s->isr, 0, sizeof(s->isr));
472 memset(s->tmr, 0, sizeof(s->tmr));
473 memset(s->irr, 0, sizeof(s->irr));
474 for(i = 0; i < APIC_LVT_NB; i++)
475 s->lvt[i] = 1 << 16; /* mask LVT */
476 s->esr = 0;
477 memset(s->icr, 0, sizeof(s->icr));
478 s->divide_conf = 0;
479 s->count_shift = 0;
480 s->initial_count = 0;
481 s->initial_count_load_time = 0;
482 s->next_time = 0;
483 s->wait_for_sipi = 1;
484
485 ENV_GET_CPU(env)->halted = !(s->apicbase & MSR_IA32_APICBASE_BSP);
486 }
487
apic_startup(APICState * s,int vector_num)488 static void apic_startup(APICState *s, int vector_num)
489 {
490 s->sipi_vector = vector_num;
491 cpu_interrupt(ENV_GET_CPU(s->cpu_env), CPU_INTERRUPT_SIPI);
492 }
493
apic_sipi(CPUOldState * env)494 void apic_sipi(CPUOldState *env)
495 {
496 CPUState *cpu = ENV_GET_CPU(env);
497 APICState *s = env->apic_state;
498
499 cpu_reset_interrupt(cpu, CPU_INTERRUPT_SIPI);
500
501 if (!s->wait_for_sipi)
502 return;
503
504 env->eip = 0;
505 cpu_x86_load_seg_cache(env, R_CS, s->sipi_vector << 8, s->sipi_vector << 12,
506 0xffff, 0);
507 cpu->halted = 0;
508 s->wait_for_sipi = 0;
509 }
510
apic_deliver(APICState * s,uint8_t dest,uint8_t dest_mode,uint8_t delivery_mode,uint8_t vector_num,uint8_t polarity,uint8_t trigger_mode)511 static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
512 uint8_t delivery_mode, uint8_t vector_num,
513 uint8_t polarity, uint8_t trigger_mode)
514 {
515 uint32_t deliver_bitmask[MAX_APIC_WORDS];
516 int dest_shorthand = (s->icr[0] >> 18) & 3;
517 APICState *apic_iter;
518
519 switch (dest_shorthand) {
520 case 0:
521 apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
522 break;
523 case 1:
524 memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
525 set_bit(deliver_bitmask, s->idx);
526 break;
527 case 2:
528 memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
529 break;
530 case 3:
531 memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
532 reset_bit(deliver_bitmask, s->idx);
533 break;
534 }
535
536 switch (delivery_mode) {
537 case APIC_DM_INIT:
538 {
539 int trig_mode = (s->icr[0] >> 15) & 1;
540 int level = (s->icr[0] >> 14) & 1;
541 if (level == 0 && trig_mode == 1) {
542 foreach_apic(apic_iter, deliver_bitmask,
543 apic_iter->arb_id = apic_iter->id );
544 return;
545 }
546 }
547 break;
548
549 case APIC_DM_SIPI:
550 foreach_apic(apic_iter, deliver_bitmask,
551 apic_startup(apic_iter, vector_num) );
552 return;
553 }
554
555 apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
556 trigger_mode);
557 }
558
apic_get_interrupt(CPUOldState * env)559 int apic_get_interrupt(CPUOldState *env)
560 {
561 APICState *s = env->apic_state;
562 int intno;
563
564 /* if the APIC is installed or enabled, we let the 8259 handle the
565 IRQs */
566 if (!s)
567 return -1;
568 if (!(s->spurious_vec & APIC_SV_ENABLE))
569 return -1;
570
571 /* XXX: spurious IRQ handling */
572 intno = get_highest_priority_int(s->irr);
573 if (intno < 0)
574 return -1;
575 if (s->tpr && intno <= s->tpr)
576 return s->spurious_vec & 0xff;
577 reset_bit(s->irr, intno);
578 set_bit(s->isr, intno);
579 apic_update_irq(s);
580 return intno;
581 }
582
apic_accept_pic_intr(CPUOldState * env)583 int apic_accept_pic_intr(CPUOldState *env)
584 {
585 APICState *s = env->apic_state;
586 uint32_t lvt0;
587
588 if (!s)
589 return -1;
590
591 lvt0 = s->lvt[APIC_LVT_LINT0];
592
593 if ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
594 (lvt0 & APIC_LVT_MASKED) == 0)
595 return 1;
596
597 return 0;
598 }
599
apic_get_current_count(APICState * s)600 static uint32_t apic_get_current_count(APICState *s)
601 {
602 int64_t d;
603 uint32_t val;
604 d = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->initial_count_load_time) >>
605 s->count_shift;
606 if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
607 /* periodic */
608 val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
609 } else {
610 if (d >= s->initial_count)
611 val = 0;
612 else
613 val = s->initial_count - d;
614 }
615 return val;
616 }
617
apic_timer_update(APICState * s,int64_t current_time)618 static void apic_timer_update(APICState *s, int64_t current_time)
619 {
620 int64_t next_time, d;
621
622 if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
623 d = (current_time - s->initial_count_load_time) >>
624 s->count_shift;
625 if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
626 if (!s->initial_count)
627 goto no_timer;
628 d = ((d / ((uint64_t)s->initial_count + 1)) + 1) * ((uint64_t)s->initial_count + 1);
629 } else {
630 if (d >= s->initial_count)
631 goto no_timer;
632 d = (uint64_t)s->initial_count + 1;
633 }
634 next_time = s->initial_count_load_time + (d << s->count_shift);
635 timer_mod(s->timer, next_time);
636 s->next_time = next_time;
637 } else {
638 no_timer:
639 timer_del(s->timer);
640 }
641 }
642
apic_timer(void * opaque)643 static void apic_timer(void *opaque)
644 {
645 APICState *s = opaque;
646
647 apic_local_deliver(s->cpu_env, APIC_LVT_TIMER);
648 apic_timer_update(s, s->next_time);
649 }
650
apic_mem_readb(void * opaque,hwaddr addr)651 static uint32_t apic_mem_readb(void *opaque, hwaddr addr)
652 {
653 return 0;
654 }
655
apic_mem_readw(void * opaque,hwaddr addr)656 static uint32_t apic_mem_readw(void *opaque, hwaddr addr)
657 {
658 return 0;
659 }
660
apic_mem_writeb(void * opaque,hwaddr addr,uint32_t val)661 static void apic_mem_writeb(void *opaque, hwaddr addr, uint32_t val)
662 {
663 }
664
apic_mem_writew(void * opaque,hwaddr addr,uint32_t val)665 static void apic_mem_writew(void *opaque, hwaddr addr, uint32_t val)
666 {
667 }
668
apic_mem_readl(void * opaque,hwaddr addr)669 static uint32_t apic_mem_readl(void *opaque, hwaddr addr)
670 {
671 CPUOldState *env;
672 APICState *s;
673 uint32_t val;
674 int index;
675
676 env = cpu_single_env;
677 if (!env)
678 return 0;
679 s = env->apic_state;
680
681 index = (addr >> 4) & 0xff;
682 switch(index) {
683 case 0x02: /* id */
684 val = s->id << 24;
685 break;
686 case 0x03: /* version */
687 val = 0x11 | ((APIC_LVT_NB - 1) << 16); /* version 0x11 */
688 break;
689 case 0x08:
690 val = s->tpr;
691 break;
692 case 0x09:
693 val = apic_get_arb_pri(s);
694 break;
695 case 0x0a:
696 /* ppr */
697 val = apic_get_ppr(s);
698 break;
699 case 0x0b:
700 val = 0;
701 break;
702 case 0x0d:
703 val = s->log_dest << 24;
704 break;
705 case 0x0e:
706 val = s->dest_mode << 28;
707 break;
708 case 0x0f:
709 val = s->spurious_vec;
710 break;
711 case 0x10 ... 0x17:
712 val = s->isr[index & 7];
713 break;
714 case 0x18 ... 0x1f:
715 val = s->tmr[index & 7];
716 break;
717 case 0x20 ... 0x27:
718 val = s->irr[index & 7];
719 break;
720 case 0x28:
721 val = s->esr;
722 break;
723 case 0x30:
724 case 0x31:
725 val = s->icr[index & 1];
726 break;
727 case 0x32 ... 0x37:
728 val = s->lvt[index - 0x32];
729 break;
730 case 0x38:
731 val = s->initial_count;
732 break;
733 case 0x39:
734 val = apic_get_current_count(s);
735 break;
736 case 0x3e:
737 val = s->divide_conf;
738 break;
739 default:
740 s->esr |= ESR_ILLEGAL_ADDRESS;
741 val = 0;
742 break;
743 }
744 #ifdef DEBUG_APIC
745 printf("APIC read: %08x = %08x\n", (uint32_t)addr, val);
746 #endif
747 return val;
748 }
749
apic_mem_writel(void * opaque,hwaddr addr,uint32_t val)750 static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
751 {
752 CPUOldState *env;
753 APICState *s;
754 int index;
755
756 env = cpu_single_env;
757 if (!env)
758 return;
759 s = env->apic_state;
760
761 #ifdef DEBUG_APIC
762 printf("APIC write: %08x = %08x\n", (uint32_t)addr, val);
763 #endif
764
765 index = (addr >> 4) & 0xff;
766 switch(index) {
767 case 0x02:
768 s->id = (val >> 24);
769 break;
770 case 0x03:
771 break;
772 case 0x08:
773 s->tpr = val;
774 apic_update_irq(s);
775 break;
776 case 0x09:
777 case 0x0a:
778 break;
779 case 0x0b: /* EOI */
780 apic_eoi(s);
781 break;
782 case 0x0d:
783 s->log_dest = val >> 24;
784 break;
785 case 0x0e:
786 s->dest_mode = val >> 28;
787 break;
788 case 0x0f:
789 s->spurious_vec = val & 0x1ff;
790 apic_update_irq(s);
791 break;
792 case 0x10 ... 0x17:
793 case 0x18 ... 0x1f:
794 case 0x20 ... 0x27:
795 case 0x28:
796 break;
797 case 0x30:
798 s->icr[0] = val;
799 apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
800 (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
801 (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
802 break;
803 case 0x31:
804 s->icr[1] = val;
805 break;
806 case 0x32 ... 0x37:
807 {
808 int n = index - 0x32;
809 s->lvt[n] = val;
810 if (n == APIC_LVT_TIMER)
811 apic_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
812 }
813 break;
814 case 0x38:
815 s->initial_count = val;
816 s->initial_count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
817 apic_timer_update(s, s->initial_count_load_time);
818 break;
819 case 0x39:
820 break;
821 case 0x3e:
822 {
823 int v;
824 s->divide_conf = val & 0xb;
825 v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
826 s->count_shift = (v + 1) & 7;
827 }
828 break;
829 default:
830 s->esr |= ESR_ILLEGAL_ADDRESS;
831 break;
832 }
833 }
834
apic_save(QEMUFile * f,void * opaque)835 static void apic_save(QEMUFile *f, void *opaque)
836 {
837 APICState *s = opaque;
838 int i;
839
840 qemu_put_be32s(f, &s->apicbase);
841 qemu_put_8s(f, &s->id);
842 qemu_put_8s(f, &s->arb_id);
843 qemu_put_8s(f, &s->tpr);
844 qemu_put_be32s(f, &s->spurious_vec);
845 qemu_put_8s(f, &s->log_dest);
846 qemu_put_8s(f, &s->dest_mode);
847 for (i = 0; i < 8; i++) {
848 qemu_put_be32s(f, &s->isr[i]);
849 qemu_put_be32s(f, &s->tmr[i]);
850 qemu_put_be32s(f, &s->irr[i]);
851 }
852 for (i = 0; i < APIC_LVT_NB; i++) {
853 qemu_put_be32s(f, &s->lvt[i]);
854 }
855 qemu_put_be32s(f, &s->esr);
856 qemu_put_be32s(f, &s->icr[0]);
857 qemu_put_be32s(f, &s->icr[1]);
858 qemu_put_be32s(f, &s->divide_conf);
859 qemu_put_be32(f, s->count_shift);
860 qemu_put_be32s(f, &s->initial_count);
861 qemu_put_be64(f, s->initial_count_load_time);
862 qemu_put_be64(f, s->next_time);
863
864 timer_put(f, s->timer);
865 }
866
apic_load(QEMUFile * f,void * opaque,int version_id)867 static int apic_load(QEMUFile *f, void *opaque, int version_id)
868 {
869 APICState *s = opaque;
870 int i;
871
872 if (version_id > 2)
873 return -EINVAL;
874
875 /* XXX: what if the base changes? (registered memory regions) */
876 qemu_get_be32s(f, &s->apicbase);
877 qemu_get_8s(f, &s->id);
878 qemu_get_8s(f, &s->arb_id);
879 qemu_get_8s(f, &s->tpr);
880 qemu_get_be32s(f, &s->spurious_vec);
881 qemu_get_8s(f, &s->log_dest);
882 qemu_get_8s(f, &s->dest_mode);
883 for (i = 0; i < 8; i++) {
884 qemu_get_be32s(f, &s->isr[i]);
885 qemu_get_be32s(f, &s->tmr[i]);
886 qemu_get_be32s(f, &s->irr[i]);
887 }
888 for (i = 0; i < APIC_LVT_NB; i++) {
889 qemu_get_be32s(f, &s->lvt[i]);
890 }
891 qemu_get_be32s(f, &s->esr);
892 qemu_get_be32s(f, &s->icr[0]);
893 qemu_get_be32s(f, &s->icr[1]);
894 qemu_get_be32s(f, &s->divide_conf);
895 s->count_shift=qemu_get_be32(f);
896 qemu_get_be32s(f, &s->initial_count);
897 s->initial_count_load_time=qemu_get_be64(f);
898 s->next_time=qemu_get_be64(f);
899
900 if (version_id >= 2)
901 timer_get(f, s->timer);
902 return 0;
903 }
904
apic_reset(void * opaque)905 static void apic_reset(void *opaque)
906 {
907 APICState *s = opaque;
908 int bsp = cpu_is_bsp(s->cpu_env);
909
910 s->apicbase = 0xfee00000 |
911 (bsp ? MSR_IA32_APICBASE_BSP : 0) | MSR_IA32_APICBASE_ENABLE;
912
913 cpu_reset(ENV_GET_CPU(s->cpu_env));
914 apic_init_reset(s->cpu_env);
915
916 if (bsp) {
917 /*
918 * LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
919 * time typically by BIOS, so PIC interrupt can be delivered to the
920 * processor when local APIC is enabled.
921 */
922 s->lvt[APIC_LVT_LINT0] = 0x700;
923 }
924 }
925
926 static CPUReadMemoryFunc *apic_mem_read[3] = {
927 apic_mem_readb,
928 apic_mem_readw,
929 apic_mem_readl,
930 };
931
932 static CPUWriteMemoryFunc *apic_mem_write[3] = {
933 apic_mem_writeb,
934 apic_mem_writew,
935 apic_mem_writel,
936 };
937
apic_init(CPUOldState * env)938 int apic_init(CPUOldState *env)
939 {
940 APICState *s;
941
942 if (last_apic_idx >= MAX_APICS)
943 return -1;
944 s = g_malloc0(sizeof(APICState));
945 env->apic_state = s;
946 s->idx = last_apic_idx++;
947 s->id = env->cpuid_apic_id;
948 s->cpu_env = env;
949
950 apic_reset(s);
951
952 /* XXX: mapping more APICs at the same memory location */
953 if (apic_io_memory == 0) {
954 /* NOTE: the APIC is directly connected to the CPU - it is not
955 on the global memory bus. */
956 apic_io_memory = cpu_register_io_memory(apic_mem_read,
957 apic_mem_write, NULL);
958 cpu_register_physical_memory(s->apicbase & ~0xfff, 0x1000,
959 apic_io_memory);
960 }
961 s->timer = timer_new(QEMU_CLOCK_VIRTUAL, SCALE_NS, apic_timer, s);
962
963 register_savevm(NULL, "apic", s->idx, 2, apic_save, apic_load, s);
964 qemu_register_reset(apic_reset, 0, s);
965
966 local_apics[s->idx] = s;
967 return 0;
968 }
969
970