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