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