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