Statistics
| Branch: | Revision:

root / hw / apic.c @ db6e6ed7

History | View | Annotate | Download (24 kB)

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
}