Statistics
| Branch: | Revision:

root / hw / apic.c @ 6295e564

History | View | Annotate | Download (23.4 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

    
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 ESR_ILLEGAL_ADDRESS (1 << 7)
60

    
61
#define APIC_SV_ENABLE (1 << 8)
62

    
63
#define MAX_APICS 255
64
#define MAX_APIC_WORDS 8
65

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

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

    
89
static int apic_io_memory;
90
static APICState *local_apics[MAX_APICS + 1];
91
static int last_apic_id = 0;
92
static int apic_irq_delivered;
93

    
94

    
95
static void apic_init_ipi(APICState *s);
96
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
97
static void apic_update_irq(APICState *s);
98
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
99
                                      uint8_t dest, uint8_t dest_mode);
100

    
101
/* Find first bit starting from msb */
102
static int fls_bit(uint32_t value)
103
{
104
    return 31 - clz32(value);
105
}
106

    
107
/* Find first bit starting from lsb */
108
static int ffs_bit(uint32_t value)
109
{
110
    return ctz32(value);
111
}
112

    
113
static inline void set_bit(uint32_t *tab, int index)
114
{
115
    int i, mask;
116
    i = index >> 5;
117
    mask = 1 << (index & 0x1f);
118
    tab[i] |= mask;
119
}
120

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

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

    
137
static void apic_local_deliver(CPUState *env, int vector)
138
{
139
    APICState *s = env->apic_state;
140
    uint32_t lvt = s->lvt[vector];
141
    int trigger_mode;
142

    
143
    if (lvt & APIC_LVT_MASKED)
144
        return;
145

    
146
    switch ((lvt >> 8) & 7) {
147
    case APIC_DM_SMI:
148
        cpu_interrupt(env, CPU_INTERRUPT_SMI);
149
        break;
150

    
151
    case APIC_DM_NMI:
152
        cpu_interrupt(env, CPU_INTERRUPT_NMI);
153
        break;
154

    
155
    case APIC_DM_EXTINT:
156
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
157
        break;
158

    
159
    case APIC_DM_FIXED:
160
        trigger_mode = APIC_TRIGGER_EDGE;
161
        if ((vector == APIC_LVT_LINT0 || vector == APIC_LVT_LINT1) &&
162
            (lvt & APIC_LVT_LEVEL_TRIGGER))
163
            trigger_mode = APIC_TRIGGER_LEVEL;
164
        apic_set_irq(s, lvt & 0xff, trigger_mode);
165
    }
166
}
167

    
168
void apic_deliver_pic_intr(CPUState *env, int level)
169
{
170
    if (level)
171
        apic_local_deliver(env, APIC_LVT_LINT0);
172
    else {
173
        APICState *s = env->apic_state;
174
        uint32_t lvt = s->lvt[APIC_LVT_LINT0];
175

    
176
        switch ((lvt >> 8) & 7) {
177
        case APIC_DM_FIXED:
178
            if (!(lvt & APIC_LVT_LEVEL_TRIGGER))
179
                break;
180
            reset_bit(s->irr, lvt & 0xff);
181
            /* fall through */
182
        case APIC_DM_EXTINT:
183
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
184
            break;
185
        }
186
    }
187
}
188

    
189
#define foreach_apic(apic, deliver_bitmask, code) \
190
{\
191
    int __i, __j, __mask;\
192
    for(__i = 0; __i < MAX_APIC_WORDS; __i++) {\
193
        __mask = deliver_bitmask[__i];\
194
        if (__mask) {\
195
            for(__j = 0; __j < 32; __j++) {\
196
                if (__mask & (1 << __j)) {\
197
                    apic = local_apics[__i * 32 + __j];\
198
                    if (apic) {\
199
                        code;\
200
                    }\
201
                }\
202
            }\
203
        }\
204
    }\
205
}
206

    
207
static void apic_bus_deliver(const uint32_t *deliver_bitmask,
208
                             uint8_t delivery_mode,
209
                             uint8_t vector_num, uint8_t polarity,
210
                             uint8_t trigger_mode)
211
{
212
    APICState *apic_iter;
213

    
214
    switch (delivery_mode) {
215
        case APIC_DM_LOWPRI:
216
            /* XXX: search for focus processor, arbitration */
217
            {
218
                int i, d;
219
                d = -1;
220
                for(i = 0; i < MAX_APIC_WORDS; i++) {
221
                    if (deliver_bitmask[i]) {
222
                        d = i * 32 + ffs_bit(deliver_bitmask[i]);
223
                        break;
224
                    }
225
                }
226
                if (d >= 0) {
227
                    apic_iter = local_apics[d];
228
                    if (apic_iter) {
229
                        apic_set_irq(apic_iter, vector_num, trigger_mode);
230
                    }
231
                }
232
            }
233
            return;
234

    
235
        case APIC_DM_FIXED:
236
            break;
237

    
238
        case APIC_DM_SMI:
239
            foreach_apic(apic_iter, deliver_bitmask,
240
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_SMI) );
241
            return;
242

    
243
        case APIC_DM_NMI:
244
            foreach_apic(apic_iter, deliver_bitmask,
245
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_NMI) );
246
            return;
247

    
248
        case APIC_DM_INIT:
249
            /* normal INIT IPI sent to processors */
250
            foreach_apic(apic_iter, deliver_bitmask,
251
                         apic_init_ipi(apic_iter) );
252
            return;
253

    
254
        case APIC_DM_EXTINT:
255
            /* handled in I/O APIC code */
256
            break;
257

    
258
        default:
259
            return;
260
    }
261

    
262
    foreach_apic(apic_iter, deliver_bitmask,
263
                 apic_set_irq(apic_iter, vector_num, trigger_mode) );
264
}
265

    
266
void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
267
                      uint8_t delivery_mode, uint8_t vector_num,
268
                      uint8_t polarity, uint8_t trigger_mode)
269
{
270
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
271

    
272
    apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
273
    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
274
                     trigger_mode);
275
}
276

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

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

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

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

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

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

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

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

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

    
364
void apic_reset_irq_delivered(void)
365
{
366
    apic_irq_delivered = 0;
367
}
368

    
369
int apic_get_irq_delivered(void)
370
{
371
    return apic_irq_delivered;
372
}
373

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

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

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

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

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

    
431

    
432
static void apic_init_ipi(APICState *s)
433
{
434
    int i;
435

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

    
453
    cpu_reset(s->cpu_env);
454

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

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

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

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

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

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

    
515
    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
516
                     trigger_mode);
517
}
518

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

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

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

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

    
548
    if (!s)
549
        return -1;
550

    
551
    lvt0 = s->lvt[APIC_LVT_LINT0];
552

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

    
557
    return 0;
558
}
559

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

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

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

    
603
static void apic_timer(void *opaque)
604
{
605
    APICState *s = opaque;
606

    
607
    apic_local_deliver(s->cpu_env, APIC_LVT_TIMER);
608
    apic_timer_update(s, s->next_time);
609
}
610

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

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

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

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

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

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

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

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

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

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

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

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

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

    
824
    qemu_put_timer(f, s->timer);
825
}
826

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

    
832
    if (version_id > 2)
833
        return -EINVAL;
834

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

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

    
865
static void apic_reset(void *opaque)
866
{
867
    APICState *s = opaque;
868

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

    
872
    apic_init_ipi(s);
873

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

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

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

    
896
int apic_init(CPUState *env)
897
{
898
    APICState *s;
899

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

    
908
    apic_reset(s);
909

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

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

    
924
    local_apics[s->id] = s;
925
    return 0;
926
}
927