Statistics
| Branch: | Revision:

root / hw / apic.c @ 487414f1

History | View | Annotate | Download (28.6 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., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
19
 */
20
#include "hw.h"
21
#include "pc.h"
22
#include "qemu-timer.h"
23
#include "host-utils.h"
24

    
25
//#define DEBUG_APIC
26
//#define DEBUG_IOAPIC
27

    
28
/* APIC Local Vector Table */
29
#define APIC_LVT_TIMER   0
30
#define APIC_LVT_THERMAL 1
31
#define APIC_LVT_PERFORM 2
32
#define APIC_LVT_LINT0   3
33
#define APIC_LVT_LINT1   4
34
#define APIC_LVT_ERROR   5
35
#define APIC_LVT_NB      6
36

    
37
/* APIC delivery modes */
38
#define APIC_DM_FIXED        0
39
#define APIC_DM_LOWPRI        1
40
#define APIC_DM_SMI        2
41
#define APIC_DM_NMI        4
42
#define APIC_DM_INIT        5
43
#define APIC_DM_SIPI        6
44
#define APIC_DM_EXTINT        7
45

    
46
/* APIC destination mode */
47
#define APIC_DESTMODE_FLAT        0xf
48
#define APIC_DESTMODE_CLUSTER        1
49

    
50
#define APIC_TRIGGER_EDGE  0
51
#define APIC_TRIGGER_LEVEL 1
52

    
53
#define        APIC_LVT_TIMER_PERIODIC                (1<<17)
54
#define        APIC_LVT_MASKED                        (1<<16)
55
#define        APIC_LVT_LEVEL_TRIGGER                (1<<15)
56
#define        APIC_LVT_REMOTE_IRR                (1<<14)
57
#define        APIC_INPUT_POLARITY                (1<<13)
58
#define        APIC_SEND_PENDING                (1<<12)
59

    
60
#define IOAPIC_NUM_PINS                        0x18
61

    
62
#define ESR_ILLEGAL_ADDRESS (1 << 7)
63

    
64
#define APIC_SV_ENABLE (1 << 8)
65

    
66
#define MAX_APICS 255
67
#define MAX_APIC_WORDS 8
68

    
69
typedef struct APICState {
70
    CPUState *cpu_env;
71
    uint32_t apicbase;
72
    uint8_t id;
73
    uint8_t arb_id;
74
    uint8_t tpr;
75
    uint32_t spurious_vec;
76
    uint8_t log_dest;
77
    uint8_t dest_mode;
78
    uint32_t isr[8];  /* in service register */
79
    uint32_t tmr[8];  /* trigger mode register */
80
    uint32_t irr[8]; /* interrupt request register */
81
    uint32_t lvt[APIC_LVT_NB];
82
    uint32_t esr; /* error register */
83
    uint32_t icr[2];
84

    
85
    uint32_t divide_conf;
86
    int count_shift;
87
    uint32_t initial_count;
88
    int64_t initial_count_load_time, next_time;
89
    QEMUTimer *timer;
90
} APICState;
91

    
92
struct IOAPICState {
93
    uint8_t id;
94
    uint8_t ioregsel;
95

    
96
    uint32_t irr;
97
    uint64_t ioredtbl[IOAPIC_NUM_PINS];
98
};
99

    
100
static int apic_io_memory;
101
static APICState *local_apics[MAX_APICS + 1];
102
static int last_apic_id = 0;
103
static int apic_irq_delivered;
104

    
105

    
106
static void apic_init_ipi(APICState *s);
107
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
108
static void apic_update_irq(APICState *s);
109

    
110
/* Find first bit starting from msb */
111
static int fls_bit(uint32_t value)
112
{
113
    return 31 - clz32(value);
114
}
115

    
116
/* Find first bit starting from lsb */
117
static int ffs_bit(uint32_t value)
118
{
119
    return ctz32(value);
120
}
121

    
122
static inline void set_bit(uint32_t *tab, int index)
123
{
124
    int i, mask;
125
    i = index >> 5;
126
    mask = 1 << (index & 0x1f);
127
    tab[i] |= mask;
128
}
129

    
130
static inline void reset_bit(uint32_t *tab, int index)
131
{
132
    int i, mask;
133
    i = index >> 5;
134
    mask = 1 << (index & 0x1f);
135
    tab[i] &= ~mask;
136
}
137

    
138
static inline int get_bit(uint32_t *tab, int index)
139
{
140
    int i, mask;
141
    i = index >> 5;
142
    mask = 1 << (index & 0x1f);
143
    return !!(tab[i] & mask);
144
}
145

    
146
static void apic_local_deliver(CPUState *env, int vector)
147
{
148
    APICState *s = env->apic_state;
149
    uint32_t lvt = s->lvt[vector];
150
    int trigger_mode;
151

    
152
    if (lvt & APIC_LVT_MASKED)
153
        return;
154

    
155
    switch ((lvt >> 8) & 7) {
156
    case APIC_DM_SMI:
157
        cpu_interrupt(env, CPU_INTERRUPT_SMI);
158
        break;
159

    
160
    case APIC_DM_NMI:
161
        cpu_interrupt(env, CPU_INTERRUPT_NMI);
162
        break;
163

    
164
    case APIC_DM_EXTINT:
165
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
166
        break;
167

    
168
    case APIC_DM_FIXED:
169
        trigger_mode = APIC_TRIGGER_EDGE;
170
        if ((vector == APIC_LVT_LINT0 || vector == APIC_LVT_LINT1) &&
171
            (lvt & APIC_LVT_LEVEL_TRIGGER))
172
            trigger_mode = APIC_TRIGGER_LEVEL;
173
        apic_set_irq(s, lvt & 0xff, trigger_mode);
174
    }
175
}
176

    
177
void apic_deliver_pic_intr(CPUState *env, int level)
178
{
179
    if (level)
180
        apic_local_deliver(env, APIC_LVT_LINT0);
181
    else {
182
        APICState *s = env->apic_state;
183
        uint32_t lvt = s->lvt[APIC_LVT_LINT0];
184

    
185
        switch ((lvt >> 8) & 7) {
186
        case APIC_DM_FIXED:
187
            if (!(lvt & APIC_LVT_LEVEL_TRIGGER))
188
                break;
189
            reset_bit(s->irr, lvt & 0xff);
190
            /* fall through */
191
        case APIC_DM_EXTINT:
192
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
193
            break;
194
        }
195
    }
196
}
197

    
198
#define foreach_apic(apic, deliver_bitmask, code) \
199
{\
200
    int __i, __j, __mask;\
201
    for(__i = 0; __i < MAX_APIC_WORDS; __i++) {\
202
        __mask = deliver_bitmask[__i];\
203
        if (__mask) {\
204
            for(__j = 0; __j < 32; __j++) {\
205
                if (__mask & (1 << __j)) {\
206
                    apic = local_apics[__i * 32 + __j];\
207
                    if (apic) {\
208
                        code;\
209
                    }\
210
                }\
211
            }\
212
        }\
213
    }\
214
}
215

    
216
static void apic_bus_deliver(const uint32_t *deliver_bitmask,
217
                             uint8_t delivery_mode,
218
                             uint8_t vector_num, uint8_t polarity,
219
                             uint8_t trigger_mode)
220
{
221
    APICState *apic_iter;
222

    
223
    switch (delivery_mode) {
224
        case APIC_DM_LOWPRI:
225
            /* XXX: search for focus processor, arbitration */
226
            {
227
                int i, d;
228
                d = -1;
229
                for(i = 0; i < MAX_APIC_WORDS; i++) {
230
                    if (deliver_bitmask[i]) {
231
                        d = i * 32 + ffs_bit(deliver_bitmask[i]);
232
                        break;
233
                    }
234
                }
235
                if (d >= 0) {
236
                    apic_iter = local_apics[d];
237
                    if (apic_iter) {
238
                        apic_set_irq(apic_iter, vector_num, trigger_mode);
239
                    }
240
                }
241
            }
242
            return;
243

    
244
        case APIC_DM_FIXED:
245
            break;
246

    
247
        case APIC_DM_SMI:
248
            foreach_apic(apic_iter, deliver_bitmask,
249
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_SMI) );
250
            return;
251

    
252
        case APIC_DM_NMI:
253
            foreach_apic(apic_iter, deliver_bitmask,
254
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_NMI) );
255
            return;
256

    
257
        case APIC_DM_INIT:
258
            /* normal INIT IPI sent to processors */
259
            foreach_apic(apic_iter, deliver_bitmask,
260
                         apic_init_ipi(apic_iter) );
261
            return;
262

    
263
        case APIC_DM_EXTINT:
264
            /* handled in I/O APIC code */
265
            break;
266

    
267
        default:
268
            return;
269
    }
270

    
271
    foreach_apic(apic_iter, deliver_bitmask,
272
                 apic_set_irq(apic_iter, vector_num, trigger_mode) );
273
}
274

    
275
void cpu_set_apic_base(CPUState *env, uint64_t val)
276
{
277
    APICState *s = env->apic_state;
278
#ifdef DEBUG_APIC
279
    printf("cpu_set_apic_base: %016" PRIx64 "\n", val);
280
#endif
281
    s->apicbase = (val & 0xfffff000) |
282
        (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
283
    /* if disabled, cannot be enabled again */
284
    if (!(val & MSR_IA32_APICBASE_ENABLE)) {
285
        s->apicbase &= ~MSR_IA32_APICBASE_ENABLE;
286
        env->cpuid_features &= ~CPUID_APIC;
287
        s->spurious_vec &= ~APIC_SV_ENABLE;
288
    }
289
}
290

    
291
uint64_t cpu_get_apic_base(CPUState *env)
292
{
293
    APICState *s = env->apic_state;
294
#ifdef DEBUG_APIC
295
    printf("cpu_get_apic_base: %016" PRIx64 "\n", (uint64_t)s->apicbase);
296
#endif
297
    return s->apicbase;
298
}
299

    
300
void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
301
{
302
    APICState *s = env->apic_state;
303
    s->tpr = (val & 0x0f) << 4;
304
    apic_update_irq(s);
305
}
306

    
307
uint8_t cpu_get_apic_tpr(CPUX86State *env)
308
{
309
    APICState *s = env->apic_state;
310
    return s->tpr >> 4;
311
}
312

    
313
/* return -1 if no bit is set */
314
static int get_highest_priority_int(uint32_t *tab)
315
{
316
    int i;
317
    for(i = 7; i >= 0; i--) {
318
        if (tab[i] != 0) {
319
            return i * 32 + fls_bit(tab[i]);
320
        }
321
    }
322
    return -1;
323
}
324

    
325
static int apic_get_ppr(APICState *s)
326
{
327
    int tpr, isrv, ppr;
328

    
329
    tpr = (s->tpr >> 4);
330
    isrv = get_highest_priority_int(s->isr);
331
    if (isrv < 0)
332
        isrv = 0;
333
    isrv >>= 4;
334
    if (tpr >= isrv)
335
        ppr = s->tpr;
336
    else
337
        ppr = isrv << 4;
338
    return ppr;
339
}
340

    
341
static int apic_get_arb_pri(APICState *s)
342
{
343
    /* XXX: arbitration */
344
    return 0;
345
}
346

    
347
/* signal the CPU if an irq is pending */
348
static void apic_update_irq(APICState *s)
349
{
350
    int irrv, ppr;
351
    if (!(s->spurious_vec & APIC_SV_ENABLE))
352
        return;
353
    irrv = get_highest_priority_int(s->irr);
354
    if (irrv < 0)
355
        return;
356
    ppr = apic_get_ppr(s);
357
    if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
358
        return;
359
    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
360
}
361

    
362
void apic_reset_irq_delivered(void)
363
{
364
    apic_irq_delivered = 0;
365
}
366

    
367
int apic_get_irq_delivered(void)
368
{
369
    return apic_irq_delivered;
370
}
371

    
372
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
373
{
374
    apic_irq_delivered += !get_bit(s->irr, vector_num);
375

    
376
    set_bit(s->irr, vector_num);
377
    if (trigger_mode)
378
        set_bit(s->tmr, vector_num);
379
    else
380
        reset_bit(s->tmr, vector_num);
381
    apic_update_irq(s);
382
}
383

    
384
static void apic_eoi(APICState *s)
385
{
386
    int isrv;
387
    isrv = get_highest_priority_int(s->isr);
388
    if (isrv < 0)
389
        return;
390
    reset_bit(s->isr, isrv);
391
    /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
392
            set the remote IRR bit for level triggered interrupts. */
393
    apic_update_irq(s);
394
}
395

    
396
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
397
                                      uint8_t dest, uint8_t dest_mode)
398
{
399
    APICState *apic_iter;
400
    int i;
401

    
402
    if (dest_mode == 0) {
403
        if (dest == 0xff) {
404
            memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t));
405
        } else {
406
            memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
407
            set_bit(deliver_bitmask, dest);
408
        }
409
    } else {
410
        /* XXX: cluster mode */
411
        memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
412
        for(i = 0; i < MAX_APICS; i++) {
413
            apic_iter = local_apics[i];
414
            if (apic_iter) {
415
                if (apic_iter->dest_mode == 0xf) {
416
                    if (dest & apic_iter->log_dest)
417
                        set_bit(deliver_bitmask, i);
418
                } else if (apic_iter->dest_mode == 0x0) {
419
                    if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) &&
420
                        (dest & apic_iter->log_dest & 0x0f)) {
421
                        set_bit(deliver_bitmask, i);
422
                    }
423
                }
424
            }
425
        }
426
    }
427
}
428

    
429

    
430
static void apic_init_ipi(APICState *s)
431
{
432
    int i;
433

    
434
    s->tpr = 0;
435
    s->spurious_vec = 0xff;
436
    s->log_dest = 0;
437
    s->dest_mode = 0xf;
438
    memset(s->isr, 0, sizeof(s->isr));
439
    memset(s->tmr, 0, sizeof(s->tmr));
440
    memset(s->irr, 0, sizeof(s->irr));
441
    for(i = 0; i < APIC_LVT_NB; i++)
442
        s->lvt[i] = 1 << 16; /* mask LVT */
443
    s->esr = 0;
444
    memset(s->icr, 0, sizeof(s->icr));
445
    s->divide_conf = 0;
446
    s->count_shift = 0;
447
    s->initial_count = 0;
448
    s->initial_count_load_time = 0;
449
    s->next_time = 0;
450

    
451
    cpu_reset(s->cpu_env);
452

    
453
    if (!(s->apicbase & MSR_IA32_APICBASE_BSP))
454
        s->cpu_env->halted = 1;
455
}
456

    
457
/* send a SIPI message to the CPU to start it */
458
static void apic_startup(APICState *s, int vector_num)
459
{
460
    CPUState *env = s->cpu_env;
461
    if (!env->halted)
462
        return;
463
    env->eip = 0;
464
    cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12,
465
                           0xffff, 0);
466
    env->halted = 0;
467
}
468

    
469
static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
470
                         uint8_t delivery_mode, uint8_t vector_num,
471
                         uint8_t polarity, uint8_t trigger_mode)
472
{
473
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
474
    int dest_shorthand = (s->icr[0] >> 18) & 3;
475
    APICState *apic_iter;
476

    
477
    switch (dest_shorthand) {
478
    case 0:
479
        apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
480
        break;
481
    case 1:
482
        memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
483
        set_bit(deliver_bitmask, s->id);
484
        break;
485
    case 2:
486
        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
487
        break;
488
    case 3:
489
        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
490
        reset_bit(deliver_bitmask, s->id);
491
        break;
492
    }
493

    
494
    switch (delivery_mode) {
495
        case APIC_DM_INIT:
496
            {
497
                int trig_mode = (s->icr[0] >> 15) & 1;
498
                int level = (s->icr[0] >> 14) & 1;
499
                if (level == 0 && trig_mode == 1) {
500
                    foreach_apic(apic_iter, deliver_bitmask,
501
                                 apic_iter->arb_id = apic_iter->id );
502
                    return;
503
                }
504
            }
505
            break;
506

    
507
        case APIC_DM_SIPI:
508
            foreach_apic(apic_iter, deliver_bitmask,
509
                         apic_startup(apic_iter, vector_num) );
510
            return;
511
    }
512

    
513
    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
514
                     trigger_mode);
515
}
516

    
517
int apic_get_interrupt(CPUState *env)
518
{
519
    APICState *s = env->apic_state;
520
    int intno;
521

    
522
    /* if the APIC is installed or enabled, we let the 8259 handle the
523
       IRQs */
524
    if (!s)
525
        return -1;
526
    if (!(s->spurious_vec & APIC_SV_ENABLE))
527
        return -1;
528

    
529
    /* XXX: spurious IRQ handling */
530
    intno = get_highest_priority_int(s->irr);
531
    if (intno < 0)
532
        return -1;
533
    if (s->tpr && intno <= s->tpr)
534
        return s->spurious_vec & 0xff;
535
    reset_bit(s->irr, intno);
536
    set_bit(s->isr, intno);
537
    apic_update_irq(s);
538
    return intno;
539
}
540

    
541
int apic_accept_pic_intr(CPUState *env)
542
{
543
    APICState *s = env->apic_state;
544
    uint32_t lvt0;
545

    
546
    if (!s)
547
        return -1;
548

    
549
    lvt0 = s->lvt[APIC_LVT_LINT0];
550

    
551
    if ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
552
        (lvt0 & APIC_LVT_MASKED) == 0)
553
        return 1;
554

    
555
    return 0;
556
}
557

    
558
static uint32_t apic_get_current_count(APICState *s)
559
{
560
    int64_t d;
561
    uint32_t val;
562
    d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >>
563
        s->count_shift;
564
    if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
565
        /* periodic */
566
        val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
567
    } else {
568
        if (d >= s->initial_count)
569
            val = 0;
570
        else
571
            val = s->initial_count - d;
572
    }
573
    return val;
574
}
575

    
576
static void apic_timer_update(APICState *s, int64_t current_time)
577
{
578
    int64_t next_time, d;
579

    
580
    if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
581
        d = (current_time - s->initial_count_load_time) >>
582
            s->count_shift;
583
        if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
584
            if (!s->initial_count)
585
                goto no_timer;
586
            d = ((d / ((uint64_t)s->initial_count + 1)) + 1) * ((uint64_t)s->initial_count + 1);
587
        } else {
588
            if (d >= s->initial_count)
589
                goto no_timer;
590
            d = (uint64_t)s->initial_count + 1;
591
        }
592
        next_time = s->initial_count_load_time + (d << s->count_shift);
593
        qemu_mod_timer(s->timer, next_time);
594
        s->next_time = next_time;
595
    } else {
596
    no_timer:
597
        qemu_del_timer(s->timer);
598
    }
599
}
600

    
601
static void apic_timer(void *opaque)
602
{
603
    APICState *s = opaque;
604

    
605
    apic_local_deliver(s->cpu_env, APIC_LVT_TIMER);
606
    apic_timer_update(s, s->next_time);
607
}
608

    
609
static uint32_t apic_mem_readb(void *opaque, target_phys_addr_t addr)
610
{
611
    return 0;
612
}
613

    
614
static uint32_t apic_mem_readw(void *opaque, target_phys_addr_t addr)
615
{
616
    return 0;
617
}
618

    
619
static void apic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
620
{
621
}
622

    
623
static void apic_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
624
{
625
}
626

    
627
static uint32_t apic_mem_readl(void *opaque, target_phys_addr_t addr)
628
{
629
    CPUState *env;
630
    APICState *s;
631
    uint32_t val;
632
    int index;
633

    
634
    env = cpu_single_env;
635
    if (!env)
636
        return 0;
637
    s = env->apic_state;
638

    
639
    index = (addr >> 4) & 0xff;
640
    switch(index) {
641
    case 0x02: /* id */
642
        val = s->id << 24;
643
        break;
644
    case 0x03: /* version */
645
        val = 0x11 | ((APIC_LVT_NB - 1) << 16); /* version 0x11 */
646
        break;
647
    case 0x08:
648
        val = s->tpr;
649
        break;
650
    case 0x09:
651
        val = apic_get_arb_pri(s);
652
        break;
653
    case 0x0a:
654
        /* ppr */
655
        val = apic_get_ppr(s);
656
        break;
657
    case 0x0b:
658
        val = 0;
659
        break;
660
    case 0x0d:
661
        val = s->log_dest << 24;
662
        break;
663
    case 0x0e:
664
        val = s->dest_mode << 28;
665
        break;
666
    case 0x0f:
667
        val = s->spurious_vec;
668
        break;
669
    case 0x10 ... 0x17:
670
        val = s->isr[index & 7];
671
        break;
672
    case 0x18 ... 0x1f:
673
        val = s->tmr[index & 7];
674
        break;
675
    case 0x20 ... 0x27:
676
        val = s->irr[index & 7];
677
        break;
678
    case 0x28:
679
        val = s->esr;
680
        break;
681
    case 0x30:
682
    case 0x31:
683
        val = s->icr[index & 1];
684
        break;
685
    case 0x32 ... 0x37:
686
        val = s->lvt[index - 0x32];
687
        break;
688
    case 0x38:
689
        val = s->initial_count;
690
        break;
691
    case 0x39:
692
        val = apic_get_current_count(s);
693
        break;
694
    case 0x3e:
695
        val = s->divide_conf;
696
        break;
697
    default:
698
        s->esr |= ESR_ILLEGAL_ADDRESS;
699
        val = 0;
700
        break;
701
    }
702
#ifdef DEBUG_APIC
703
    printf("APIC read: %08x = %08x\n", (uint32_t)addr, val);
704
#endif
705
    return val;
706
}
707

    
708
static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
709
{
710
    CPUState *env;
711
    APICState *s;
712
    int index;
713

    
714
    env = cpu_single_env;
715
    if (!env)
716
        return;
717
    s = env->apic_state;
718

    
719
#ifdef DEBUG_APIC
720
    printf("APIC write: %08x = %08x\n", (uint32_t)addr, val);
721
#endif
722

    
723
    index = (addr >> 4) & 0xff;
724
    switch(index) {
725
    case 0x02:
726
        s->id = (val >> 24);
727
        break;
728
    case 0x03:
729
        break;
730
    case 0x08:
731
        s->tpr = val;
732
        apic_update_irq(s);
733
        break;
734
    case 0x09:
735
    case 0x0a:
736
        break;
737
    case 0x0b: /* EOI */
738
        apic_eoi(s);
739
        break;
740
    case 0x0d:
741
        s->log_dest = val >> 24;
742
        break;
743
    case 0x0e:
744
        s->dest_mode = val >> 28;
745
        break;
746
    case 0x0f:
747
        s->spurious_vec = val & 0x1ff;
748
        apic_update_irq(s);
749
        break;
750
    case 0x10 ... 0x17:
751
    case 0x18 ... 0x1f:
752
    case 0x20 ... 0x27:
753
    case 0x28:
754
        break;
755
    case 0x30:
756
        s->icr[0] = val;
757
        apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
758
                     (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
759
                     (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
760
        break;
761
    case 0x31:
762
        s->icr[1] = val;
763
        break;
764
    case 0x32 ... 0x37:
765
        {
766
            int n = index - 0x32;
767
            s->lvt[n] = val;
768
            if (n == APIC_LVT_TIMER)
769
                apic_timer_update(s, qemu_get_clock(vm_clock));
770
        }
771
        break;
772
    case 0x38:
773
        s->initial_count = val;
774
        s->initial_count_load_time = qemu_get_clock(vm_clock);
775
        apic_timer_update(s, s->initial_count_load_time);
776
        break;
777
    case 0x39:
778
        break;
779
    case 0x3e:
780
        {
781
            int v;
782
            s->divide_conf = val & 0xb;
783
            v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
784
            s->count_shift = (v + 1) & 7;
785
        }
786
        break;
787
    default:
788
        s->esr |= ESR_ILLEGAL_ADDRESS;
789
        break;
790
    }
791
}
792

    
793
static void apic_save(QEMUFile *f, void *opaque)
794
{
795
    APICState *s = opaque;
796
    int i;
797

    
798
    qemu_put_be32s(f, &s->apicbase);
799
    qemu_put_8s(f, &s->id);
800
    qemu_put_8s(f, &s->arb_id);
801
    qemu_put_8s(f, &s->tpr);
802
    qemu_put_be32s(f, &s->spurious_vec);
803
    qemu_put_8s(f, &s->log_dest);
804
    qemu_put_8s(f, &s->dest_mode);
805
    for (i = 0; i < 8; i++) {
806
        qemu_put_be32s(f, &s->isr[i]);
807
        qemu_put_be32s(f, &s->tmr[i]);
808
        qemu_put_be32s(f, &s->irr[i]);
809
    }
810
    for (i = 0; i < APIC_LVT_NB; i++) {
811
        qemu_put_be32s(f, &s->lvt[i]);
812
    }
813
    qemu_put_be32s(f, &s->esr);
814
    qemu_put_be32s(f, &s->icr[0]);
815
    qemu_put_be32s(f, &s->icr[1]);
816
    qemu_put_be32s(f, &s->divide_conf);
817
    qemu_put_be32(f, s->count_shift);
818
    qemu_put_be32s(f, &s->initial_count);
819
    qemu_put_be64(f, s->initial_count_load_time);
820
    qemu_put_be64(f, s->next_time);
821

    
822
    qemu_put_timer(f, s->timer);
823
}
824

    
825
static int apic_load(QEMUFile *f, void *opaque, int version_id)
826
{
827
    APICState *s = opaque;
828
    int i;
829

    
830
    if (version_id > 2)
831
        return -EINVAL;
832

    
833
    /* XXX: what if the base changes? (registered memory regions) */
834
    qemu_get_be32s(f, &s->apicbase);
835
    qemu_get_8s(f, &s->id);
836
    qemu_get_8s(f, &s->arb_id);
837
    qemu_get_8s(f, &s->tpr);
838
    qemu_get_be32s(f, &s->spurious_vec);
839
    qemu_get_8s(f, &s->log_dest);
840
    qemu_get_8s(f, &s->dest_mode);
841
    for (i = 0; i < 8; i++) {
842
        qemu_get_be32s(f, &s->isr[i]);
843
        qemu_get_be32s(f, &s->tmr[i]);
844
        qemu_get_be32s(f, &s->irr[i]);
845
    }
846
    for (i = 0; i < APIC_LVT_NB; i++) {
847
        qemu_get_be32s(f, &s->lvt[i]);
848
    }
849
    qemu_get_be32s(f, &s->esr);
850
    qemu_get_be32s(f, &s->icr[0]);
851
    qemu_get_be32s(f, &s->icr[1]);
852
    qemu_get_be32s(f, &s->divide_conf);
853
    s->count_shift=qemu_get_be32(f);
854
    qemu_get_be32s(f, &s->initial_count);
855
    s->initial_count_load_time=qemu_get_be64(f);
856
    s->next_time=qemu_get_be64(f);
857

    
858
    if (version_id >= 2)
859
        qemu_get_timer(f, s->timer);
860
    return 0;
861
}
862

    
863
static void apic_reset(void *opaque)
864
{
865
    APICState *s = opaque;
866

    
867
    s->apicbase = 0xfee00000 |
868
        (s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
869

    
870
    apic_init_ipi(s);
871

    
872
    if (s->id == 0) {
873
        /*
874
         * LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
875
         * time typically by BIOS, so PIC interrupt can be delivered to the
876
         * processor when local APIC is enabled.
877
         */
878
        s->lvt[APIC_LVT_LINT0] = 0x700;
879
    }
880
}
881

    
882
static CPUReadMemoryFunc *apic_mem_read[3] = {
883
    apic_mem_readb,
884
    apic_mem_readw,
885
    apic_mem_readl,
886
};
887

    
888
static CPUWriteMemoryFunc *apic_mem_write[3] = {
889
    apic_mem_writeb,
890
    apic_mem_writew,
891
    apic_mem_writel,
892
};
893

    
894
int apic_init(CPUState *env)
895
{
896
    APICState *s;
897

    
898
    if (last_apic_id >= MAX_APICS)
899
        return -1;
900
    s = qemu_mallocz(sizeof(APICState));
901
    env->apic_state = s;
902
    s->id = last_apic_id++;
903
    env->cpuid_apic_id = s->id;
904
    s->cpu_env = env;
905

    
906
    apic_reset(s);
907

    
908
    /* XXX: mapping more APICs at the same memory location */
909
    if (apic_io_memory == 0) {
910
        /* NOTE: the APIC is directly connected to the CPU - it is not
911
           on the global memory bus. */
912
        apic_io_memory = cpu_register_io_memory(0, apic_mem_read,
913
                                                apic_mem_write, NULL);
914
        cpu_register_physical_memory(s->apicbase & ~0xfff, 0x1000,
915
                                     apic_io_memory);
916
    }
917
    s->timer = qemu_new_timer(vm_clock, apic_timer, s);
918

    
919
    register_savevm("apic", s->id, 2, apic_save, apic_load, s);
920
    qemu_register_reset(apic_reset, s);
921

    
922
    local_apics[s->id] = s;
923
    return 0;
924
}
925

    
926
static void ioapic_service(IOAPICState *s)
927
{
928
    uint8_t i;
929
    uint8_t trig_mode;
930
    uint8_t vector;
931
    uint8_t delivery_mode;
932
    uint32_t mask;
933
    uint64_t entry;
934
    uint8_t dest;
935
    uint8_t dest_mode;
936
    uint8_t polarity;
937
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
938

    
939
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
940
        mask = 1 << i;
941
        if (s->irr & mask) {
942
            entry = s->ioredtbl[i];
943
            if (!(entry & APIC_LVT_MASKED)) {
944
                trig_mode = ((entry >> 15) & 1);
945
                dest = entry >> 56;
946
                dest_mode = (entry >> 11) & 1;
947
                delivery_mode = (entry >> 8) & 7;
948
                polarity = (entry >> 13) & 1;
949
                if (trig_mode == APIC_TRIGGER_EDGE)
950
                    s->irr &= ~mask;
951
                if (delivery_mode == APIC_DM_EXTINT)
952
                    vector = pic_read_irq(isa_pic);
953
                else
954
                    vector = entry & 0xff;
955

    
956
                apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
957
                apic_bus_deliver(deliver_bitmask, delivery_mode,
958
                                 vector, polarity, trig_mode);
959
            }
960
        }
961
    }
962
}
963

    
964
void ioapic_set_irq(void *opaque, int vector, int level)
965
{
966
    IOAPICState *s = opaque;
967

    
968
    /* ISA IRQs map to GSI 1-1 except for IRQ0 which maps
969
     * to GSI 2.  GSI maps to ioapic 1-1.  This is not
970
     * the cleanest way of doing it but it should work. */
971

    
972
    if (vector == 0)
973
        vector = 2;
974

    
975
    if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
976
        uint32_t mask = 1 << vector;
977
        uint64_t entry = s->ioredtbl[vector];
978

    
979
        if ((entry >> 15) & 1) {
980
            /* level triggered */
981
            if (level) {
982
                s->irr |= mask;
983
                ioapic_service(s);
984
            } else {
985
                s->irr &= ~mask;
986
            }
987
        } else {
988
            /* edge triggered */
989
            if (level) {
990
                s->irr |= mask;
991
                ioapic_service(s);
992
            }
993
        }
994
    }
995
}
996

    
997
static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
998
{
999
    IOAPICState *s = opaque;
1000
    int index;
1001
    uint32_t val = 0;
1002

    
1003
    addr &= 0xff;
1004
    if (addr == 0x00) {
1005
        val = s->ioregsel;
1006
    } else if (addr == 0x10) {
1007
        switch (s->ioregsel) {
1008
            case 0x00:
1009
                val = s->id << 24;
1010
                break;
1011
            case 0x01:
1012
                val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */
1013
                break;
1014
            case 0x02:
1015
                val = 0;
1016
                break;
1017
            default:
1018
                index = (s->ioregsel - 0x10) >> 1;
1019
                if (index >= 0 && index < IOAPIC_NUM_PINS) {
1020
                    if (s->ioregsel & 1)
1021
                        val = s->ioredtbl[index] >> 32;
1022
                    else
1023
                        val = s->ioredtbl[index] & 0xffffffff;
1024
                }
1025
        }
1026
#ifdef DEBUG_IOAPIC
1027
        printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val);
1028
#endif
1029
    }
1030
    return val;
1031
}
1032

    
1033
static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1034
{
1035
    IOAPICState *s = opaque;
1036
    int index;
1037

    
1038
    addr &= 0xff;
1039
    if (addr == 0x00)  {
1040
        s->ioregsel = val;
1041
        return;
1042
    } else if (addr == 0x10) {
1043
#ifdef DEBUG_IOAPIC
1044
        printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val);
1045
#endif
1046
        switch (s->ioregsel) {
1047
            case 0x00:
1048
                s->id = (val >> 24) & 0xff;
1049
                return;
1050
            case 0x01:
1051
            case 0x02:
1052
                return;
1053
            default:
1054
                index = (s->ioregsel - 0x10) >> 1;
1055
                if (index >= 0 && index < IOAPIC_NUM_PINS) {
1056
                    if (s->ioregsel & 1) {
1057
                        s->ioredtbl[index] &= 0xffffffff;
1058
                        s->ioredtbl[index] |= (uint64_t)val << 32;
1059
                    } else {
1060
                        s->ioredtbl[index] &= ~0xffffffffULL;
1061
                        s->ioredtbl[index] |= val;
1062
                    }
1063
                    ioapic_service(s);
1064
                }
1065
        }
1066
    }
1067
}
1068

    
1069
static void ioapic_save(QEMUFile *f, void *opaque)
1070
{
1071
    IOAPICState *s = opaque;
1072
    int i;
1073

    
1074
    qemu_put_8s(f, &s->id);
1075
    qemu_put_8s(f, &s->ioregsel);
1076
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
1077
        qemu_put_be64s(f, &s->ioredtbl[i]);
1078
    }
1079
}
1080

    
1081
static int ioapic_load(QEMUFile *f, void *opaque, int version_id)
1082
{
1083
    IOAPICState *s = opaque;
1084
    int i;
1085

    
1086
    if (version_id != 1)
1087
        return -EINVAL;
1088

    
1089
    qemu_get_8s(f, &s->id);
1090
    qemu_get_8s(f, &s->ioregsel);
1091
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
1092
        qemu_get_be64s(f, &s->ioredtbl[i]);
1093
    }
1094
    return 0;
1095
}
1096

    
1097
static void ioapic_reset(void *opaque)
1098
{
1099
    IOAPICState *s = opaque;
1100
    int i;
1101

    
1102
    memset(s, 0, sizeof(*s));
1103
    for(i = 0; i < IOAPIC_NUM_PINS; i++)
1104
        s->ioredtbl[i] = 1 << 16; /* mask LVT */
1105
}
1106

    
1107
static CPUReadMemoryFunc *ioapic_mem_read[3] = {
1108
    ioapic_mem_readl,
1109
    ioapic_mem_readl,
1110
    ioapic_mem_readl,
1111
};
1112

    
1113
static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
1114
    ioapic_mem_writel,
1115
    ioapic_mem_writel,
1116
    ioapic_mem_writel,
1117
};
1118

    
1119
IOAPICState *ioapic_init(void)
1120
{
1121
    IOAPICState *s;
1122
    int io_memory;
1123

    
1124
    s = qemu_mallocz(sizeof(IOAPICState));
1125
    ioapic_reset(s);
1126
    s->id = last_apic_id++;
1127

    
1128
    io_memory = cpu_register_io_memory(0, ioapic_mem_read,
1129
                                       ioapic_mem_write, s);
1130
    cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
1131

    
1132
    register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
1133
    qemu_register_reset(ioapic_reset, s);
1134

    
1135
    return s;
1136
}