Statistics
| Branch: | Revision:

root / hw / apic.c @ e2eb9d3e

History | View | Annotate | Download (27.7 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 "hw.h"
21
#include "pc.h"
22
#include "qemu-timer.h"
23

    
24
//#define DEBUG_APIC
25
//#define DEBUG_IOAPIC
26

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

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

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

    
49
#define APIC_TRIGGER_EDGE  0
50
#define APIC_TRIGGER_LEVEL 1
51

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

    
59
#define IOAPIC_NUM_PINS                        0x18
60

    
61
#define ESR_ILLEGAL_ADDRESS (1 << 7)
62

    
63
#define APIC_SV_ENABLE (1 << 8)
64

    
65
#define MAX_APICS 255
66
#define MAX_APIC_WORDS 8
67

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

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

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

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

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

    
103
static void apic_init_ipi(APICState *s);
104
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
105
static void apic_update_irq(APICState *s);
106

    
107
/* Find first bit starting from msb. Return 0 if value = 0 */
108
static int fls_bit(uint32_t value)
109
{
110
    unsigned int ret = 0;
111

    
112
#if defined(HOST_I386)
113
    __asm__ __volatile__ ("bsr %1, %0\n" : "+r" (ret) : "rm" (value));
114
    return ret;
115
#else
116
    if (value > 0xffff)
117
        value >>= 16, ret = 16;
118
    if (value > 0xff)
119
        value >>= 8, ret += 8;
120
    if (value > 0xf)
121
        value >>= 4, ret += 4;
122
    if (value > 0x3)
123
        value >>= 2, ret += 2;
124
    return ret + (value >> 1);
125
#endif
126
}
127

    
128
/* Find first bit starting from lsb. Return 0 if value = 0 */
129
static int ffs_bit(uint32_t value)
130
{
131
    unsigned int ret = 0;
132

    
133
#if defined(HOST_I386)
134
    __asm__ __volatile__ ("bsf %1, %0\n" : "+r" (ret) : "rm" (value));
135
    return ret;
136
#else
137
    if (!value)
138
        return 0;
139
    if (!(value & 0xffff))
140
        value >>= 16, ret = 16;
141
    if (!(value & 0xff))
142
        value >>= 8, ret += 8;
143
    if (!(value & 0xf))
144
        value >>= 4, ret += 4;
145
    if (!(value & 0x3))
146
        value >>= 2, ret += 2;
147
    if (!(value & 0x1))
148
        ret++;
149
    return ret;
150
#endif
151
}
152

    
153
static inline void set_bit(uint32_t *tab, int index)
154
{
155
    int i, mask;
156
    i = index >> 5;
157
    mask = 1 << (index & 0x1f);
158
    tab[i] |= mask;
159
}
160

    
161
static inline void reset_bit(uint32_t *tab, int index)
162
{
163
    int i, mask;
164
    i = index >> 5;
165
    mask = 1 << (index & 0x1f);
166
    tab[i] &= ~mask;
167
}
168

    
169
#define foreach_apic(apic, deliver_bitmask, code) \
170
{\
171
    int __i, __j, __mask;\
172
    for(__i = 0; __i < MAX_APIC_WORDS; __i++) {\
173
        __mask = deliver_bitmask[__i];\
174
        if (__mask) {\
175
            for(__j = 0; __j < 32; __j++) {\
176
                if (__mask & (1 << __j)) {\
177
                    apic = local_apics[__i * 32 + __j];\
178
                    if (apic) {\
179
                        code;\
180
                    }\
181
                }\
182
            }\
183
        }\
184
    }\
185
}
186

    
187
static void apic_bus_deliver(const uint32_t *deliver_bitmask,
188
                             uint8_t delivery_mode,
189
                             uint8_t vector_num, uint8_t polarity,
190
                             uint8_t trigger_mode)
191
{
192
    APICState *apic_iter;
193

    
194
    switch (delivery_mode) {
195
        case APIC_DM_LOWPRI:
196
            /* XXX: search for focus processor, arbitration */
197
            {
198
                int i, d;
199
                d = -1;
200
                for(i = 0; i < MAX_APIC_WORDS; i++) {
201
                    if (deliver_bitmask[i]) {
202
                        d = i * 32 + ffs_bit(deliver_bitmask[i]);
203
                        break;
204
                    }
205
                }
206
                if (d >= 0) {
207
                    apic_iter = local_apics[d];
208
                    if (apic_iter) {
209
                        apic_set_irq(apic_iter, vector_num, trigger_mode);
210
                    }
211
                }
212
            }
213
            return;
214

    
215
        case APIC_DM_FIXED:
216
            break;
217

    
218
        case APIC_DM_SMI:
219
            foreach_apic(apic_iter, deliver_bitmask,
220
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_SMI) );
221
            return;
222

    
223
        case APIC_DM_NMI:
224
            foreach_apic(apic_iter, deliver_bitmask,
225
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_NMI) );
226
            return;
227

    
228
        case APIC_DM_INIT:
229
            /* normal INIT IPI sent to processors */
230
            foreach_apic(apic_iter, deliver_bitmask,
231
                         apic_init_ipi(apic_iter) );
232
            return;
233

    
234
        case APIC_DM_EXTINT:
235
            /* handled in I/O APIC code */
236
            break;
237

    
238
        default:
239
            return;
240
    }
241

    
242
    foreach_apic(apic_iter, deliver_bitmask,
243
                 apic_set_irq(apic_iter, vector_num, trigger_mode) );
244
}
245

    
246
void cpu_set_apic_base(CPUState *env, uint64_t val)
247
{
248
    APICState *s = env->apic_state;
249
#ifdef DEBUG_APIC
250
    printf("cpu_set_apic_base: %016" PRIx64 "\n", val);
251
#endif
252
    s->apicbase = (val & 0xfffff000) |
253
        (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
254
    /* if disabled, cannot be enabled again */
255
    if (!(val & MSR_IA32_APICBASE_ENABLE)) {
256
        s->apicbase &= ~MSR_IA32_APICBASE_ENABLE;
257
        env->cpuid_features &= ~CPUID_APIC;
258
        s->spurious_vec &= ~APIC_SV_ENABLE;
259
    }
260
}
261

    
262
uint64_t cpu_get_apic_base(CPUState *env)
263
{
264
    APICState *s = env->apic_state;
265
#ifdef DEBUG_APIC
266
    printf("cpu_get_apic_base: %016" PRIx64 "\n", (uint64_t)s->apicbase);
267
#endif
268
    return s->apicbase;
269
}
270

    
271
void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
272
{
273
    APICState *s = env->apic_state;
274
    s->tpr = (val & 0x0f) << 4;
275
    apic_update_irq(s);
276
}
277

    
278
uint8_t cpu_get_apic_tpr(CPUX86State *env)
279
{
280
    APICState *s = env->apic_state;
281
    return s->tpr >> 4;
282
}
283

    
284
/* return -1 if no bit is set */
285
static int get_highest_priority_int(uint32_t *tab)
286
{
287
    int i;
288
    for(i = 7; i >= 0; i--) {
289
        if (tab[i] != 0) {
290
            return i * 32 + fls_bit(tab[i]);
291
        }
292
    }
293
    return -1;
294
}
295

    
296
static int apic_get_ppr(APICState *s)
297
{
298
    int tpr, isrv, ppr;
299

    
300
    tpr = (s->tpr >> 4);
301
    isrv = get_highest_priority_int(s->isr);
302
    if (isrv < 0)
303
        isrv = 0;
304
    isrv >>= 4;
305
    if (tpr >= isrv)
306
        ppr = s->tpr;
307
    else
308
        ppr = isrv << 4;
309
    return ppr;
310
}
311

    
312
static int apic_get_arb_pri(APICState *s)
313
{
314
    /* XXX: arbitration */
315
    return 0;
316
}
317

    
318
/* signal the CPU if an irq is pending */
319
static void apic_update_irq(APICState *s)
320
{
321
    int irrv, ppr;
322
    if (!(s->spurious_vec & APIC_SV_ENABLE))
323
        return;
324
    irrv = get_highest_priority_int(s->irr);
325
    if (irrv < 0)
326
        return;
327
    ppr = apic_get_ppr(s);
328
    if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
329
        return;
330
    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
331
}
332

    
333
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
334
{
335
    set_bit(s->irr, vector_num);
336
    if (trigger_mode)
337
        set_bit(s->tmr, vector_num);
338
    else
339
        reset_bit(s->tmr, vector_num);
340
    apic_update_irq(s);
341
}
342

    
343
static void apic_eoi(APICState *s)
344
{
345
    int isrv;
346
    isrv = get_highest_priority_int(s->isr);
347
    if (isrv < 0)
348
        return;
349
    reset_bit(s->isr, isrv);
350
    /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
351
            set the remote IRR bit for level triggered interrupts. */
352
    apic_update_irq(s);
353
}
354

    
355
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
356
                                      uint8_t dest, uint8_t dest_mode)
357
{
358
    APICState *apic_iter;
359
    int i;
360

    
361
    if (dest_mode == 0) {
362
        if (dest == 0xff) {
363
            memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t));
364
        } else {
365
            memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
366
            set_bit(deliver_bitmask, dest);
367
        }
368
    } else {
369
        /* XXX: cluster mode */
370
        memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
371
        for(i = 0; i < MAX_APICS; i++) {
372
            apic_iter = local_apics[i];
373
            if (apic_iter) {
374
                if (apic_iter->dest_mode == 0xf) {
375
                    if (dest & apic_iter->log_dest)
376
                        set_bit(deliver_bitmask, i);
377
                } else if (apic_iter->dest_mode == 0x0) {
378
                    if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) &&
379
                        (dest & apic_iter->log_dest & 0x0f)) {
380
                        set_bit(deliver_bitmask, i);
381
                    }
382
                }
383
            }
384
        }
385
    }
386
}
387

    
388

    
389
static void apic_init_ipi(APICState *s)
390
{
391
    int i;
392

    
393
    s->tpr = 0;
394
    s->spurious_vec = 0xff;
395
    s->log_dest = 0;
396
    s->dest_mode = 0xf;
397
    memset(s->isr, 0, sizeof(s->isr));
398
    memset(s->tmr, 0, sizeof(s->tmr));
399
    memset(s->irr, 0, sizeof(s->irr));
400
    for(i = 0; i < APIC_LVT_NB; i++)
401
        s->lvt[i] = 1 << 16; /* mask LVT */
402
    s->esr = 0;
403
    memset(s->icr, 0, sizeof(s->icr));
404
    s->divide_conf = 0;
405
    s->count_shift = 0;
406
    s->initial_count = 0;
407
    s->initial_count_load_time = 0;
408
    s->next_time = 0;
409
}
410

    
411
/* send a SIPI message to the CPU to start it */
412
static void apic_startup(APICState *s, int vector_num)
413
{
414
    CPUState *env = s->cpu_env;
415
    if (!(env->hflags & HF_HALTED_MASK))
416
        return;
417
    env->eip = 0;
418
    cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12,
419
                           0xffff, 0);
420
    env->hflags &= ~HF_HALTED_MASK;
421
}
422

    
423
static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
424
                         uint8_t delivery_mode, uint8_t vector_num,
425
                         uint8_t polarity, uint8_t trigger_mode)
426
{
427
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
428
    int dest_shorthand = (s->icr[0] >> 18) & 3;
429
    APICState *apic_iter;
430

    
431
    switch (dest_shorthand) {
432
    case 0:
433
        apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
434
        break;
435
    case 1:
436
        memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
437
        set_bit(deliver_bitmask, s->id);
438
        break;
439
    case 2:
440
        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
441
        break;
442
    case 3:
443
        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
444
        reset_bit(deliver_bitmask, s->id);
445
        break;
446
    }
447

    
448
    switch (delivery_mode) {
449
        case APIC_DM_INIT:
450
            {
451
                int trig_mode = (s->icr[0] >> 15) & 1;
452
                int level = (s->icr[0] >> 14) & 1;
453
                if (level == 0 && trig_mode == 1) {
454
                    foreach_apic(apic_iter, deliver_bitmask,
455
                                 apic_iter->arb_id = apic_iter->id );
456
                    return;
457
                }
458
            }
459
            break;
460

    
461
        case APIC_DM_SIPI:
462
            foreach_apic(apic_iter, deliver_bitmask,
463
                         apic_startup(apic_iter, vector_num) );
464
            return;
465
    }
466

    
467
    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
468
                     trigger_mode);
469
}
470

    
471
int apic_get_interrupt(CPUState *env)
472
{
473
    APICState *s = env->apic_state;
474
    int intno;
475

    
476
    /* if the APIC is installed or enabled, we let the 8259 handle the
477
       IRQs */
478
    if (!s)
479
        return -1;
480
    if (!(s->spurious_vec & APIC_SV_ENABLE))
481
        return -1;
482

    
483
    /* XXX: spurious IRQ handling */
484
    intno = get_highest_priority_int(s->irr);
485
    if (intno < 0)
486
        return -1;
487
    if (s->tpr && intno <= s->tpr)
488
        return s->spurious_vec & 0xff;
489
    reset_bit(s->irr, intno);
490
    set_bit(s->isr, intno);
491
    apic_update_irq(s);
492
    return intno;
493
}
494

    
495
int apic_accept_pic_intr(CPUState *env)
496
{
497
    APICState *s = env->apic_state;
498
    uint32_t lvt0;
499

    
500
    if (!s)
501
        return -1;
502

    
503
    lvt0 = s->lvt[APIC_LVT_LINT0];
504

    
505
    if (s->id == 0 &&
506
        ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
507
         ((lvt0 & APIC_LVT_MASKED) == 0 &&
508
          ((lvt0 >> 8) & 0x7) == APIC_DM_EXTINT)))
509
        return 1;
510

    
511
    return 0;
512
}
513

    
514
static uint32_t apic_get_current_count(APICState *s)
515
{
516
    int64_t d;
517
    uint32_t val;
518
    d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >>
519
        s->count_shift;
520
    if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
521
        /* periodic */
522
        val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
523
    } else {
524
        if (d >= s->initial_count)
525
            val = 0;
526
        else
527
            val = s->initial_count - d;
528
    }
529
    return val;
530
}
531

    
532
static void apic_timer_update(APICState *s, int64_t current_time)
533
{
534
    int64_t next_time, d;
535

    
536
    if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
537
        d = (current_time - s->initial_count_load_time) >>
538
            s->count_shift;
539
        if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
540
            d = ((d / ((uint64_t)s->initial_count + 1)) + 1) * ((uint64_t)s->initial_count + 1);
541
        } else {
542
            if (d >= s->initial_count)
543
                goto no_timer;
544
            d = (uint64_t)s->initial_count + 1;
545
        }
546
        next_time = s->initial_count_load_time + (d << s->count_shift);
547
        qemu_mod_timer(s->timer, next_time);
548
        s->next_time = next_time;
549
    } else {
550
    no_timer:
551
        qemu_del_timer(s->timer);
552
    }
553
}
554

    
555
static void apic_timer(void *opaque)
556
{
557
    APICState *s = opaque;
558

    
559
    if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
560
        apic_set_irq(s, s->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);
561
    }
562
    apic_timer_update(s, s->next_time);
563
}
564

    
565
static uint32_t apic_mem_readb(void *opaque, target_phys_addr_t addr)
566
{
567
    return 0;
568
}
569

    
570
static uint32_t apic_mem_readw(void *opaque, target_phys_addr_t addr)
571
{
572
    return 0;
573
}
574

    
575
static void apic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
576
{
577
}
578

    
579
static void apic_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
580
{
581
}
582

    
583
static uint32_t apic_mem_readl(void *opaque, target_phys_addr_t addr)
584
{
585
    CPUState *env;
586
    APICState *s;
587
    uint32_t val;
588
    int index;
589

    
590
    env = cpu_single_env;
591
    if (!env)
592
        return 0;
593
    s = env->apic_state;
594

    
595
    index = (addr >> 4) & 0xff;
596
    switch(index) {
597
    case 0x02: /* id */
598
        val = s->id << 24;
599
        break;
600
    case 0x03: /* version */
601
        val = 0x11 | ((APIC_LVT_NB - 1) << 16); /* version 0x11 */
602
        break;
603
    case 0x08:
604
        val = s->tpr;
605
        break;
606
    case 0x09:
607
        val = apic_get_arb_pri(s);
608
        break;
609
    case 0x0a:
610
        /* ppr */
611
        val = apic_get_ppr(s);
612
        break;
613
    case 0x0b:
614
        val = 0;
615
        break;
616
    case 0x0d:
617
        val = s->log_dest << 24;
618
        break;
619
    case 0x0e:
620
        val = s->dest_mode << 28;
621
        break;
622
    case 0x0f:
623
        val = s->spurious_vec;
624
        break;
625
    case 0x10 ... 0x17:
626
        val = s->isr[index & 7];
627
        break;
628
    case 0x18 ... 0x1f:
629
        val = s->tmr[index & 7];
630
        break;
631
    case 0x20 ... 0x27:
632
        val = s->irr[index & 7];
633
        break;
634
    case 0x28:
635
        val = s->esr;
636
        break;
637
    case 0x30:
638
    case 0x31:
639
        val = s->icr[index & 1];
640
        break;
641
    case 0x32 ... 0x37:
642
        val = s->lvt[index - 0x32];
643
        break;
644
    case 0x38:
645
        val = s->initial_count;
646
        break;
647
    case 0x39:
648
        val = apic_get_current_count(s);
649
        break;
650
    case 0x3e:
651
        val = s->divide_conf;
652
        break;
653
    default:
654
        s->esr |= ESR_ILLEGAL_ADDRESS;
655
        val = 0;
656
        break;
657
    }
658
#ifdef DEBUG_APIC
659
    printf("APIC read: %08x = %08x\n", (uint32_t)addr, val);
660
#endif
661
    return val;
662
}
663

    
664
static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
665
{
666
    CPUState *env;
667
    APICState *s;
668
    int index;
669

    
670
    env = cpu_single_env;
671
    if (!env)
672
        return;
673
    s = env->apic_state;
674

    
675
#ifdef DEBUG_APIC
676
    printf("APIC write: %08x = %08x\n", (uint32_t)addr, val);
677
#endif
678

    
679
    index = (addr >> 4) & 0xff;
680
    switch(index) {
681
    case 0x02:
682
        s->id = (val >> 24);
683
        break;
684
    case 0x03:
685
        break;
686
    case 0x08:
687
        s->tpr = val;
688
        apic_update_irq(s);
689
        break;
690
    case 0x09:
691
    case 0x0a:
692
        break;
693
    case 0x0b: /* EOI */
694
        apic_eoi(s);
695
        break;
696
    case 0x0d:
697
        s->log_dest = val >> 24;
698
        break;
699
    case 0x0e:
700
        s->dest_mode = val >> 28;
701
        break;
702
    case 0x0f:
703
        s->spurious_vec = val & 0x1ff;
704
        apic_update_irq(s);
705
        break;
706
    case 0x10 ... 0x17:
707
    case 0x18 ... 0x1f:
708
    case 0x20 ... 0x27:
709
    case 0x28:
710
        break;
711
    case 0x30:
712
        s->icr[0] = val;
713
        apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
714
                     (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
715
                     (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
716
        break;
717
    case 0x31:
718
        s->icr[1] = val;
719
        break;
720
    case 0x32 ... 0x37:
721
        {
722
            int n = index - 0x32;
723
            s->lvt[n] = val;
724
            if (n == APIC_LVT_TIMER)
725
                apic_timer_update(s, qemu_get_clock(vm_clock));
726
        }
727
        break;
728
    case 0x38:
729
        s->initial_count = val;
730
        s->initial_count_load_time = qemu_get_clock(vm_clock);
731
        apic_timer_update(s, s->initial_count_load_time);
732
        break;
733
    case 0x39:
734
        break;
735
    case 0x3e:
736
        {
737
            int v;
738
            s->divide_conf = val & 0xb;
739
            v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
740
            s->count_shift = (v + 1) & 7;
741
        }
742
        break;
743
    default:
744
        s->esr |= ESR_ILLEGAL_ADDRESS;
745
        break;
746
    }
747
}
748

    
749
static void apic_save(QEMUFile *f, void *opaque)
750
{
751
    APICState *s = opaque;
752
    int i;
753

    
754
    qemu_put_be32s(f, &s->apicbase);
755
    qemu_put_8s(f, &s->id);
756
    qemu_put_8s(f, &s->arb_id);
757
    qemu_put_8s(f, &s->tpr);
758
    qemu_put_be32s(f, &s->spurious_vec);
759
    qemu_put_8s(f, &s->log_dest);
760
    qemu_put_8s(f, &s->dest_mode);
761
    for (i = 0; i < 8; i++) {
762
        qemu_put_be32s(f, &s->isr[i]);
763
        qemu_put_be32s(f, &s->tmr[i]);
764
        qemu_put_be32s(f, &s->irr[i]);
765
    }
766
    for (i = 0; i < APIC_LVT_NB; i++) {
767
        qemu_put_be32s(f, &s->lvt[i]);
768
    }
769
    qemu_put_be32s(f, &s->esr);
770
    qemu_put_be32s(f, &s->icr[0]);
771
    qemu_put_be32s(f, &s->icr[1]);
772
    qemu_put_be32s(f, &s->divide_conf);
773
    qemu_put_be32(f, s->count_shift);
774
    qemu_put_be32s(f, &s->initial_count);
775
    qemu_put_be64(f, s->initial_count_load_time);
776
    qemu_put_be64(f, s->next_time);
777

    
778
    qemu_put_timer(f, s->timer);
779
}
780

    
781
static int apic_load(QEMUFile *f, void *opaque, int version_id)
782
{
783
    APICState *s = opaque;
784
    int i;
785

    
786
    if (version_id > 2)
787
        return -EINVAL;
788

    
789
    /* XXX: what if the base changes? (registered memory regions) */
790
    qemu_get_be32s(f, &s->apicbase);
791
    qemu_get_8s(f, &s->id);
792
    qemu_get_8s(f, &s->arb_id);
793
    qemu_get_8s(f, &s->tpr);
794
    qemu_get_be32s(f, &s->spurious_vec);
795
    qemu_get_8s(f, &s->log_dest);
796
    qemu_get_8s(f, &s->dest_mode);
797
    for (i = 0; i < 8; i++) {
798
        qemu_get_be32s(f, &s->isr[i]);
799
        qemu_get_be32s(f, &s->tmr[i]);
800
        qemu_get_be32s(f, &s->irr[i]);
801
    }
802
    for (i = 0; i < APIC_LVT_NB; i++) {
803
        qemu_get_be32s(f, &s->lvt[i]);
804
    }
805
    qemu_get_be32s(f, &s->esr);
806
    qemu_get_be32s(f, &s->icr[0]);
807
    qemu_get_be32s(f, &s->icr[1]);
808
    qemu_get_be32s(f, &s->divide_conf);
809
    s->count_shift=qemu_get_be32(f);
810
    qemu_get_be32s(f, &s->initial_count);
811
    s->initial_count_load_time=qemu_get_be64(f);
812
    s->next_time=qemu_get_be64(f);
813

    
814
    if (version_id >= 2)
815
        qemu_get_timer(f, s->timer);
816
    return 0;
817
}
818

    
819
static void apic_reset(void *opaque)
820
{
821
    APICState *s = opaque;
822
    apic_init_ipi(s);
823

    
824
    /*
825
     * LINT0 delivery mode is set to ExtInt at initialization time
826
     * typically by BIOS, so PIC interrupt can be delivered to the
827
     * processor when local APIC is enabled.
828
     */
829
    s->lvt[APIC_LVT_LINT0] = 0x700;
830
}
831

    
832
static CPUReadMemoryFunc *apic_mem_read[3] = {
833
    apic_mem_readb,
834
    apic_mem_readw,
835
    apic_mem_readl,
836
};
837

    
838
static CPUWriteMemoryFunc *apic_mem_write[3] = {
839
    apic_mem_writeb,
840
    apic_mem_writew,
841
    apic_mem_writel,
842
};
843

    
844
int apic_init(CPUState *env)
845
{
846
    APICState *s;
847

    
848
    if (last_apic_id >= MAX_APICS)
849
        return -1;
850
    s = qemu_mallocz(sizeof(APICState));
851
    if (!s)
852
        return -1;
853
    env->apic_state = s;
854
    apic_init_ipi(s);
855
    s->id = last_apic_id++;
856
    env->cpuid_apic_id = s->id;
857
    s->cpu_env = env;
858
    s->apicbase = 0xfee00000 |
859
        (s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
860

    
861
    /*
862
     * LINT0 delivery mode is set to ExtInt at initialization time
863
     * typically by BIOS, so PIC interrupt can be delivered to the
864
     * processor when local APIC is enabled.
865
     */
866
    s->lvt[APIC_LVT_LINT0] = 0x700;
867

    
868
    /* XXX: mapping more APICs at the same memory location */
869
    if (apic_io_memory == 0) {
870
        /* NOTE: the APIC is directly connected to the CPU - it is not
871
           on the global memory bus. */
872
        apic_io_memory = cpu_register_io_memory(0, apic_mem_read,
873
                                                apic_mem_write, NULL);
874
        cpu_register_physical_memory(s->apicbase & ~0xfff, 0x1000,
875
                                     apic_io_memory);
876
    }
877
    s->timer = qemu_new_timer(vm_clock, apic_timer, s);
878

    
879
    register_savevm("apic", s->id, 2, apic_save, apic_load, s);
880
    qemu_register_reset(apic_reset, s);
881

    
882
    local_apics[s->id] = s;
883
    return 0;
884
}
885

    
886
static void ioapic_service(IOAPICState *s)
887
{
888
    uint8_t i;
889
    uint8_t trig_mode;
890
    uint8_t vector;
891
    uint8_t delivery_mode;
892
    uint32_t mask;
893
    uint64_t entry;
894
    uint8_t dest;
895
    uint8_t dest_mode;
896
    uint8_t polarity;
897
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
898

    
899
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
900
        mask = 1 << i;
901
        if (s->irr & mask) {
902
            entry = s->ioredtbl[i];
903
            if (!(entry & APIC_LVT_MASKED)) {
904
                trig_mode = ((entry >> 15) & 1);
905
                dest = entry >> 56;
906
                dest_mode = (entry >> 11) & 1;
907
                delivery_mode = (entry >> 8) & 7;
908
                polarity = (entry >> 13) & 1;
909
                if (trig_mode == APIC_TRIGGER_EDGE)
910
                    s->irr &= ~mask;
911
                if (delivery_mode == APIC_DM_EXTINT)
912
                    vector = pic_read_irq(isa_pic);
913
                else
914
                    vector = entry & 0xff;
915

    
916
                apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
917
                apic_bus_deliver(deliver_bitmask, delivery_mode,
918
                                 vector, polarity, trig_mode);
919
            }
920
        }
921
    }
922
}
923

    
924
void ioapic_set_irq(void *opaque, int vector, int level)
925
{
926
    IOAPICState *s = opaque;
927

    
928
    if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
929
        uint32_t mask = 1 << vector;
930
        uint64_t entry = s->ioredtbl[vector];
931

    
932
        if ((entry >> 15) & 1) {
933
            /* level triggered */
934
            if (level) {
935
                s->irr |= mask;
936
                ioapic_service(s);
937
            } else {
938
                s->irr &= ~mask;
939
            }
940
        } else {
941
            /* edge triggered */
942
            if (level) {
943
                s->irr |= mask;
944
                ioapic_service(s);
945
            }
946
        }
947
    }
948
}
949

    
950
static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
951
{
952
    IOAPICState *s = opaque;
953
    int index;
954
    uint32_t val = 0;
955

    
956
    addr &= 0xff;
957
    if (addr == 0x00) {
958
        val = s->ioregsel;
959
    } else if (addr == 0x10) {
960
        switch (s->ioregsel) {
961
            case 0x00:
962
                val = s->id << 24;
963
                break;
964
            case 0x01:
965
                val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */
966
                break;
967
            case 0x02:
968
                val = 0;
969
                break;
970
            default:
971
                index = (s->ioregsel - 0x10) >> 1;
972
                if (index >= 0 && index < IOAPIC_NUM_PINS) {
973
                    if (s->ioregsel & 1)
974
                        val = s->ioredtbl[index] >> 32;
975
                    else
976
                        val = s->ioredtbl[index] & 0xffffffff;
977
                }
978
        }
979
#ifdef DEBUG_IOAPIC
980
        printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val);
981
#endif
982
    }
983
    return val;
984
}
985

    
986
static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
987
{
988
    IOAPICState *s = opaque;
989
    int index;
990

    
991
    addr &= 0xff;
992
    if (addr == 0x00)  {
993
        s->ioregsel = val;
994
        return;
995
    } else if (addr == 0x10) {
996
#ifdef DEBUG_IOAPIC
997
        printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val);
998
#endif
999
        switch (s->ioregsel) {
1000
            case 0x00:
1001
                s->id = (val >> 24) & 0xff;
1002
                return;
1003
            case 0x01:
1004
            case 0x02:
1005
                return;
1006
            default:
1007
                index = (s->ioregsel - 0x10) >> 1;
1008
                if (index >= 0 && index < IOAPIC_NUM_PINS) {
1009
                    if (s->ioregsel & 1) {
1010
                        s->ioredtbl[index] &= 0xffffffff;
1011
                        s->ioredtbl[index] |= (uint64_t)val << 32;
1012
                    } else {
1013
                        s->ioredtbl[index] &= ~0xffffffffULL;
1014
                        s->ioredtbl[index] |= val;
1015
                    }
1016
                    ioapic_service(s);
1017
                }
1018
        }
1019
    }
1020
}
1021

    
1022
static void ioapic_save(QEMUFile *f, void *opaque)
1023
{
1024
    IOAPICState *s = opaque;
1025
    int i;
1026

    
1027
    qemu_put_8s(f, &s->id);
1028
    qemu_put_8s(f, &s->ioregsel);
1029
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
1030
        qemu_put_be64s(f, &s->ioredtbl[i]);
1031
    }
1032
}
1033

    
1034
static int ioapic_load(QEMUFile *f, void *opaque, int version_id)
1035
{
1036
    IOAPICState *s = opaque;
1037
    int i;
1038

    
1039
    if (version_id != 1)
1040
        return -EINVAL;
1041

    
1042
    qemu_get_8s(f, &s->id);
1043
    qemu_get_8s(f, &s->ioregsel);
1044
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
1045
        qemu_get_be64s(f, &s->ioredtbl[i]);
1046
    }
1047
    return 0;
1048
}
1049

    
1050
static void ioapic_reset(void *opaque)
1051
{
1052
    IOAPICState *s = opaque;
1053
    int i;
1054

    
1055
    memset(s, 0, sizeof(*s));
1056
    for(i = 0; i < IOAPIC_NUM_PINS; i++)
1057
        s->ioredtbl[i] = 1 << 16; /* mask LVT */
1058
}
1059

    
1060
static CPUReadMemoryFunc *ioapic_mem_read[3] = {
1061
    ioapic_mem_readl,
1062
    ioapic_mem_readl,
1063
    ioapic_mem_readl,
1064
};
1065

    
1066
static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
1067
    ioapic_mem_writel,
1068
    ioapic_mem_writel,
1069
    ioapic_mem_writel,
1070
};
1071

    
1072
IOAPICState *ioapic_init(void)
1073
{
1074
    IOAPICState *s;
1075
    int io_memory;
1076

    
1077
    s = qemu_mallocz(sizeof(IOAPICState));
1078
    if (!s)
1079
        return NULL;
1080
    ioapic_reset(s);
1081
    s->id = last_apic_id++;
1082

    
1083
    io_memory = cpu_register_io_memory(0, ioapic_mem_read,
1084
                                       ioapic_mem_write, s);
1085
    cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
1086

    
1087
    register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
1088
    qemu_register_reset(ioapic_reset, s);
1089

    
1090
    return s;
1091
}