Statistics
| Branch: | Revision:

root / hw / apic.c @ b072a3c8

History | View | Annotate | Download (20.2 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, see <http://www.gnu.org/licenses/>
18
 */
19
#include "apic_internal.h"
20
#include "apic.h"
21
#include "ioapic.h"
22
#include "host-utils.h"
23
#include "trace.h"
24
#include "pc.h"
25

    
26
#define MAX_APIC_WORDS 8
27

    
28
/* Intel APIC constants: from include/asm/msidef.h */
29
#define MSI_DATA_VECTOR_SHIFT                0
30
#define MSI_DATA_VECTOR_MASK                0x000000ff
31
#define MSI_DATA_DELIVERY_MODE_SHIFT        8
32
#define MSI_DATA_TRIGGER_SHIFT                15
33
#define MSI_DATA_LEVEL_SHIFT                14
34
#define MSI_ADDR_DEST_MODE_SHIFT        2
35
#define MSI_ADDR_DEST_ID_SHIFT                12
36
#define        MSI_ADDR_DEST_ID_MASK                0x00ffff0
37

    
38
static APICCommonState *local_apics[MAX_APICS + 1];
39

    
40
static void apic_set_irq(APICCommonState *s, int vector_num, int trigger_mode);
41
static void apic_update_irq(APICCommonState *s);
42
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
43
                                      uint8_t dest, uint8_t dest_mode);
44

    
45
/* Find first bit starting from msb */
46
static int fls_bit(uint32_t value)
47
{
48
    return 31 - clz32(value);
49
}
50

    
51
/* Find first bit starting from lsb */
52
static int ffs_bit(uint32_t value)
53
{
54
    return ctz32(value);
55
}
56

    
57
static inline void set_bit(uint32_t *tab, int index)
58
{
59
    int i, mask;
60
    i = index >> 5;
61
    mask = 1 << (index & 0x1f);
62
    tab[i] |= mask;
63
}
64

    
65
static inline void reset_bit(uint32_t *tab, int index)
66
{
67
    int i, mask;
68
    i = index >> 5;
69
    mask = 1 << (index & 0x1f);
70
    tab[i] &= ~mask;
71
}
72

    
73
static inline int get_bit(uint32_t *tab, int index)
74
{
75
    int i, mask;
76
    i = index >> 5;
77
    mask = 1 << (index & 0x1f);
78
    return !!(tab[i] & mask);
79
}
80

    
81
static void apic_local_deliver(APICCommonState *s, int vector)
82
{
83
    uint32_t lvt = s->lvt[vector];
84
    int trigger_mode;
85

    
86
    trace_apic_local_deliver(vector, (lvt >> 8) & 7);
87

    
88
    if (lvt & APIC_LVT_MASKED)
89
        return;
90

    
91
    switch ((lvt >> 8) & 7) {
92
    case APIC_DM_SMI:
93
        cpu_interrupt(s->cpu_env, CPU_INTERRUPT_SMI);
94
        break;
95

    
96
    case APIC_DM_NMI:
97
        cpu_interrupt(s->cpu_env, CPU_INTERRUPT_NMI);
98
        break;
99

    
100
    case APIC_DM_EXTINT:
101
        cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
102
        break;
103

    
104
    case APIC_DM_FIXED:
105
        trigger_mode = APIC_TRIGGER_EDGE;
106
        if ((vector == APIC_LVT_LINT0 || vector == APIC_LVT_LINT1) &&
107
            (lvt & APIC_LVT_LEVEL_TRIGGER))
108
            trigger_mode = APIC_TRIGGER_LEVEL;
109
        apic_set_irq(s, lvt & 0xff, trigger_mode);
110
    }
111
}
112

    
113
void apic_deliver_pic_intr(DeviceState *d, int level)
114
{
115
    APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
116

    
117
    if (level) {
118
        apic_local_deliver(s, APIC_LVT_LINT0);
119
    } else {
120
        uint32_t lvt = s->lvt[APIC_LVT_LINT0];
121

    
122
        switch ((lvt >> 8) & 7) {
123
        case APIC_DM_FIXED:
124
            if (!(lvt & APIC_LVT_LEVEL_TRIGGER))
125
                break;
126
            reset_bit(s->irr, lvt & 0xff);
127
            /* fall through */
128
        case APIC_DM_EXTINT:
129
            cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
130
            break;
131
        }
132
    }
133
}
134

    
135
static void apic_external_nmi(APICCommonState *s)
136
{
137
    apic_local_deliver(s, APIC_LVT_LINT1);
138
}
139

    
140
#define foreach_apic(apic, deliver_bitmask, code) \
141
{\
142
    int __i, __j, __mask;\
143
    for(__i = 0; __i < MAX_APIC_WORDS; __i++) {\
144
        __mask = deliver_bitmask[__i];\
145
        if (__mask) {\
146
            for(__j = 0; __j < 32; __j++) {\
147
                if (__mask & (1 << __j)) {\
148
                    apic = local_apics[__i * 32 + __j];\
149
                    if (apic) {\
150
                        code;\
151
                    }\
152
                }\
153
            }\
154
        }\
155
    }\
156
}
157

    
158
static void apic_bus_deliver(const uint32_t *deliver_bitmask,
159
                             uint8_t delivery_mode, uint8_t vector_num,
160
                             uint8_t trigger_mode)
161
{
162
    APICCommonState *apic_iter;
163

    
164
    switch (delivery_mode) {
165
        case APIC_DM_LOWPRI:
166
            /* XXX: search for focus processor, arbitration */
167
            {
168
                int i, d;
169
                d = -1;
170
                for(i = 0; i < MAX_APIC_WORDS; i++) {
171
                    if (deliver_bitmask[i]) {
172
                        d = i * 32 + ffs_bit(deliver_bitmask[i]);
173
                        break;
174
                    }
175
                }
176
                if (d >= 0) {
177
                    apic_iter = local_apics[d];
178
                    if (apic_iter) {
179
                        apic_set_irq(apic_iter, vector_num, trigger_mode);
180
                    }
181
                }
182
            }
183
            return;
184

    
185
        case APIC_DM_FIXED:
186
            break;
187

    
188
        case APIC_DM_SMI:
189
            foreach_apic(apic_iter, deliver_bitmask,
190
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_SMI) );
191
            return;
192

    
193
        case APIC_DM_NMI:
194
            foreach_apic(apic_iter, deliver_bitmask,
195
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_NMI) );
196
            return;
197

    
198
        case APIC_DM_INIT:
199
            /* normal INIT IPI sent to processors */
200
            foreach_apic(apic_iter, deliver_bitmask,
201
                         cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_INIT) );
202
            return;
203

    
204
        case APIC_DM_EXTINT:
205
            /* handled in I/O APIC code */
206
            break;
207

    
208
        default:
209
            return;
210
    }
211

    
212
    foreach_apic(apic_iter, deliver_bitmask,
213
                 apic_set_irq(apic_iter, vector_num, trigger_mode) );
214
}
215

    
216
void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode,
217
                      uint8_t vector_num, uint8_t trigger_mode)
218
{
219
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
220

    
221
    trace_apic_deliver_irq(dest, dest_mode, delivery_mode, vector_num,
222
                           trigger_mode);
223

    
224
    apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
225
    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, trigger_mode);
226
}
227

    
228
static void apic_set_base(APICCommonState *s, uint64_t val)
229
{
230
    s->apicbase = (val & 0xfffff000) |
231
        (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
232
    /* if disabled, cannot be enabled again */
233
    if (!(val & MSR_IA32_APICBASE_ENABLE)) {
234
        s->apicbase &= ~MSR_IA32_APICBASE_ENABLE;
235
        cpu_clear_apic_feature(s->cpu_env);
236
        s->spurious_vec &= ~APIC_SV_ENABLE;
237
    }
238
}
239

    
240
static void apic_set_tpr(APICCommonState *s, uint8_t val)
241
{
242
    s->tpr = (val & 0x0f) << 4;
243
    apic_update_irq(s);
244
}
245

    
246
/* return -1 if no bit is set */
247
static int get_highest_priority_int(uint32_t *tab)
248
{
249
    int i;
250
    for(i = 7; i >= 0; i--) {
251
        if (tab[i] != 0) {
252
            return i * 32 + fls_bit(tab[i]);
253
        }
254
    }
255
    return -1;
256
}
257

    
258
static int apic_get_ppr(APICCommonState *s)
259
{
260
    int tpr, isrv, ppr;
261

    
262
    tpr = (s->tpr >> 4);
263
    isrv = get_highest_priority_int(s->isr);
264
    if (isrv < 0)
265
        isrv = 0;
266
    isrv >>= 4;
267
    if (tpr >= isrv)
268
        ppr = s->tpr;
269
    else
270
        ppr = isrv << 4;
271
    return ppr;
272
}
273

    
274
static int apic_get_arb_pri(APICCommonState *s)
275
{
276
    /* XXX: arbitration */
277
    return 0;
278
}
279

    
280

    
281
/*
282
 * <0 - low prio interrupt,
283
 * 0  - no interrupt,
284
 * >0 - interrupt number
285
 */
286
static int apic_irq_pending(APICCommonState *s)
287
{
288
    int irrv, ppr;
289
    irrv = get_highest_priority_int(s->irr);
290
    if (irrv < 0) {
291
        return 0;
292
    }
293
    ppr = apic_get_ppr(s);
294
    if (ppr && (irrv & 0xf0) <= (ppr & 0xf0)) {
295
        return -1;
296
    }
297

    
298
    return irrv;
299
}
300

    
301
/* signal the CPU if an irq is pending */
302
static void apic_update_irq(APICCommonState *s)
303
{
304
    if (!(s->spurious_vec & APIC_SV_ENABLE)) {
305
        return;
306
    }
307
    if (apic_irq_pending(s) > 0) {
308
        cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
309
    } else if (apic_accept_pic_intr(&s->busdev.qdev) &&
310
               pic_get_output(isa_pic)) {
311
        apic_deliver_pic_intr(&s->busdev.qdev, 1);
312
    }
313
}
314

    
315
static void apic_set_irq(APICCommonState *s, int vector_num, int trigger_mode)
316
{
317
    apic_report_irq_delivered(!get_bit(s->irr, vector_num));
318

    
319
    set_bit(s->irr, vector_num);
320
    if (trigger_mode)
321
        set_bit(s->tmr, vector_num);
322
    else
323
        reset_bit(s->tmr, vector_num);
324
    apic_update_irq(s);
325
}
326

    
327
static void apic_eoi(APICCommonState *s)
328
{
329
    int isrv;
330
    isrv = get_highest_priority_int(s->isr);
331
    if (isrv < 0)
332
        return;
333
    reset_bit(s->isr, isrv);
334
    if (!(s->spurious_vec & APIC_SV_DIRECTED_IO) && get_bit(s->tmr, isrv)) {
335
        ioapic_eoi_broadcast(isrv);
336
    }
337
    apic_update_irq(s);
338
}
339

    
340
static int apic_find_dest(uint8_t dest)
341
{
342
    APICCommonState *apic = local_apics[dest];
343
    int i;
344

    
345
    if (apic && apic->id == dest)
346
        return dest;  /* shortcut in case apic->id == apic->idx */
347

    
348
    for (i = 0; i < MAX_APICS; i++) {
349
        apic = local_apics[i];
350
        if (apic && apic->id == dest)
351
            return i;
352
        if (!apic)
353
            break;
354
    }
355

    
356
    return -1;
357
}
358

    
359
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
360
                                      uint8_t dest, uint8_t dest_mode)
361
{
362
    APICCommonState *apic_iter;
363
    int i;
364

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

    
396
static void apic_startup(APICCommonState *s, int vector_num)
397
{
398
    s->sipi_vector = vector_num;
399
    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_SIPI);
400
}
401

    
402
void apic_sipi(DeviceState *d)
403
{
404
    APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
405

    
406
    cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_SIPI);
407

    
408
    if (!s->wait_for_sipi)
409
        return;
410
    cpu_x86_load_seg_cache_sipi(s->cpu_env, s->sipi_vector);
411
    s->wait_for_sipi = 0;
412
}
413

    
414
static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode,
415
                         uint8_t delivery_mode, uint8_t vector_num,
416
                         uint8_t trigger_mode)
417
{
418
    APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
419
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
420
    int dest_shorthand = (s->icr[0] >> 18) & 3;
421
    APICCommonState *apic_iter;
422

    
423
    switch (dest_shorthand) {
424
    case 0:
425
        apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
426
        break;
427
    case 1:
428
        memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
429
        set_bit(deliver_bitmask, s->idx);
430
        break;
431
    case 2:
432
        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
433
        break;
434
    case 3:
435
        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
436
        reset_bit(deliver_bitmask, s->idx);
437
        break;
438
    }
439

    
440
    switch (delivery_mode) {
441
        case APIC_DM_INIT:
442
            {
443
                int trig_mode = (s->icr[0] >> 15) & 1;
444
                int level = (s->icr[0] >> 14) & 1;
445
                if (level == 0 && trig_mode == 1) {
446
                    foreach_apic(apic_iter, deliver_bitmask,
447
                                 apic_iter->arb_id = apic_iter->id );
448
                    return;
449
                }
450
            }
451
            break;
452

    
453
        case APIC_DM_SIPI:
454
            foreach_apic(apic_iter, deliver_bitmask,
455
                         apic_startup(apic_iter, vector_num) );
456
            return;
457
    }
458

    
459
    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, trigger_mode);
460
}
461

    
462
int apic_get_interrupt(DeviceState *d)
463
{
464
    APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
465
    int intno;
466

    
467
    /* if the APIC is installed or enabled, we let the 8259 handle the
468
       IRQs */
469
    if (!s)
470
        return -1;
471
    if (!(s->spurious_vec & APIC_SV_ENABLE))
472
        return -1;
473

    
474
    intno = apic_irq_pending(s);
475

    
476
    if (intno == 0) {
477
        return -1;
478
    } else if (intno < 0) {
479
        return s->spurious_vec & 0xff;
480
    }
481
    reset_bit(s->irr, intno);
482
    set_bit(s->isr, intno);
483
    apic_update_irq(s);
484
    return intno;
485
}
486

    
487
int apic_accept_pic_intr(DeviceState *d)
488
{
489
    APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
490
    uint32_t lvt0;
491

    
492
    if (!s)
493
        return -1;
494

    
495
    lvt0 = s->lvt[APIC_LVT_LINT0];
496

    
497
    if ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
498
        (lvt0 & APIC_LVT_MASKED) == 0)
499
        return 1;
500

    
501
    return 0;
502
}
503

    
504
static uint32_t apic_get_current_count(APICCommonState *s)
505
{
506
    int64_t d;
507
    uint32_t val;
508
    d = (qemu_get_clock_ns(vm_clock) - s->initial_count_load_time) >>
509
        s->count_shift;
510
    if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
511
        /* periodic */
512
        val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
513
    } else {
514
        if (d >= s->initial_count)
515
            val = 0;
516
        else
517
            val = s->initial_count - d;
518
    }
519
    return val;
520
}
521

    
522
static void apic_timer_update(APICCommonState *s, int64_t current_time)
523
{
524
    if (apic_next_timer(s, current_time)) {
525
        qemu_mod_timer(s->timer, s->next_time);
526
    } else {
527
        qemu_del_timer(s->timer);
528
    }
529
}
530

    
531
static void apic_timer(void *opaque)
532
{
533
    APICCommonState *s = opaque;
534

    
535
    apic_local_deliver(s, APIC_LVT_TIMER);
536
    apic_timer_update(s, s->next_time);
537
}
538

    
539
static uint32_t apic_mem_readb(void *opaque, target_phys_addr_t addr)
540
{
541
    return 0;
542
}
543

    
544
static uint32_t apic_mem_readw(void *opaque, target_phys_addr_t addr)
545
{
546
    return 0;
547
}
548

    
549
static void apic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
550
{
551
}
552

    
553
static void apic_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
554
{
555
}
556

    
557
static uint32_t apic_mem_readl(void *opaque, target_phys_addr_t addr)
558
{
559
    DeviceState *d;
560
    APICCommonState *s;
561
    uint32_t val;
562
    int index;
563

    
564
    d = cpu_get_current_apic();
565
    if (!d) {
566
        return 0;
567
    }
568
    s = DO_UPCAST(APICCommonState, busdev.qdev, d);
569

    
570
    index = (addr >> 4) & 0xff;
571
    switch(index) {
572
    case 0x02: /* id */
573
        val = s->id << 24;
574
        break;
575
    case 0x03: /* version */
576
        val = 0x11 | ((APIC_LVT_NB - 1) << 16); /* version 0x11 */
577
        break;
578
    case 0x08:
579
        val = s->tpr;
580
        break;
581
    case 0x09:
582
        val = apic_get_arb_pri(s);
583
        break;
584
    case 0x0a:
585
        /* ppr */
586
        val = apic_get_ppr(s);
587
        break;
588
    case 0x0b:
589
        val = 0;
590
        break;
591
    case 0x0d:
592
        val = s->log_dest << 24;
593
        break;
594
    case 0x0e:
595
        val = s->dest_mode << 28;
596
        break;
597
    case 0x0f:
598
        val = s->spurious_vec;
599
        break;
600
    case 0x10 ... 0x17:
601
        val = s->isr[index & 7];
602
        break;
603
    case 0x18 ... 0x1f:
604
        val = s->tmr[index & 7];
605
        break;
606
    case 0x20 ... 0x27:
607
        val = s->irr[index & 7];
608
        break;
609
    case 0x28:
610
        val = s->esr;
611
        break;
612
    case 0x30:
613
    case 0x31:
614
        val = s->icr[index & 1];
615
        break;
616
    case 0x32 ... 0x37:
617
        val = s->lvt[index - 0x32];
618
        break;
619
    case 0x38:
620
        val = s->initial_count;
621
        break;
622
    case 0x39:
623
        val = apic_get_current_count(s);
624
        break;
625
    case 0x3e:
626
        val = s->divide_conf;
627
        break;
628
    default:
629
        s->esr |= ESR_ILLEGAL_ADDRESS;
630
        val = 0;
631
        break;
632
    }
633
    trace_apic_mem_readl(addr, val);
634
    return val;
635
}
636

    
637
static void apic_send_msi(target_phys_addr_t addr, uint32_t data)
638
{
639
    uint8_t dest = (addr & MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
640
    uint8_t vector = (data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT;
641
    uint8_t dest_mode = (addr >> MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
642
    uint8_t trigger_mode = (data >> MSI_DATA_TRIGGER_SHIFT) & 0x1;
643
    uint8_t delivery = (data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
644
    /* XXX: Ignore redirection hint. */
645
    apic_deliver_irq(dest, dest_mode, delivery, vector, trigger_mode);
646
}
647

    
648
static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
649
{
650
    DeviceState *d;
651
    APICCommonState *s;
652
    int index = (addr >> 4) & 0xff;
653
    if (addr > 0xfff || !index) {
654
        /* MSI and MMIO APIC are at the same memory location,
655
         * but actually not on the global bus: MSI is on PCI bus
656
         * APIC is connected directly to the CPU.
657
         * Mapping them on the global bus happens to work because
658
         * MSI registers are reserved in APIC MMIO and vice versa. */
659
        apic_send_msi(addr, val);
660
        return;
661
    }
662

    
663
    d = cpu_get_current_apic();
664
    if (!d) {
665
        return;
666
    }
667
    s = DO_UPCAST(APICCommonState, busdev.qdev, d);
668

    
669
    trace_apic_mem_writel(addr, val);
670

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

    
740
static void apic_post_load(APICCommonState *s)
741
{
742
    if (s->timer_expiry != -1) {
743
        qemu_mod_timer(s->timer, s->timer_expiry);
744
    } else {
745
        qemu_del_timer(s->timer);
746
    }
747
}
748

    
749
static const MemoryRegionOps apic_io_ops = {
750
    .old_mmio = {
751
        .read = { apic_mem_readb, apic_mem_readw, apic_mem_readl, },
752
        .write = { apic_mem_writeb, apic_mem_writew, apic_mem_writel, },
753
    },
754
    .endianness = DEVICE_NATIVE_ENDIAN,
755
};
756

    
757
static void apic_init(APICCommonState *s)
758
{
759
    memory_region_init_io(&s->io_memory, &apic_io_ops, s, "apic-msi",
760
                          MSI_SPACE_SIZE);
761

    
762
    s->timer = qemu_new_timer_ns(vm_clock, apic_timer, s);
763
    local_apics[s->idx] = s;
764
}
765

    
766
static void apic_class_init(ObjectClass *klass, void *data)
767
{
768
    APICCommonClass *k = APIC_COMMON_CLASS(klass);
769

    
770
    k->init = apic_init;
771
    k->set_base = apic_set_base;
772
    k->set_tpr = apic_set_tpr;
773
    k->external_nmi = apic_external_nmi;
774
    k->post_load = apic_post_load;
775
}
776

    
777
static TypeInfo apic_info = {
778
    .name          = "apic",
779
    .instance_size = sizeof(APICCommonState),
780
    .parent        = TYPE_APIC_COMMON,
781
    .class_init    = apic_class_init,
782
};
783

    
784
static void apic_register_types(void)
785
{
786
    type_register_static(&apic_info);
787
}
788

    
789
type_init(apic_register_types)