Statistics
| Branch: | Revision:

root / hw / apic.c @ b09ea7d5

History | View | Annotate | Download (24.3 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
    uint32_t idx;
87
    QEMUTimer *timer;
88
    int sipi_vector;
89
    int wait_for_sipi;
90
} APICState;
91

    
92
static int apic_io_memory;
93
static APICState *local_apics[MAX_APICS + 1];
94
static int last_apic_idx = 0;
95
static int apic_irq_delivered;
96

    
97

    
98
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
99
static void apic_update_irq(APICState *s);
100
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
101
                                      uint8_t dest, uint8_t dest_mode);
102

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

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

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

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

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

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

    
145
    if (lvt & APIC_LVT_MASKED)
146
        return;
147

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

    
153
    case APIC_DM_NMI:
154
        cpu_interrupt(env, CPU_INTERRUPT_NMI);
155
        break;
156

    
157
    case APIC_DM_EXTINT:
158
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
159
        break;
160

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

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

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

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

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

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

    
237
        case APIC_DM_FIXED:
238
            break;
239

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

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

    
250
        case APIC_DM_INIT:
251
            /* normal INIT IPI sent to processors */
252
            foreach_apic(apic_iter, deliver_bitmask,
253
                         cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_INIT) );
254
            return;
255

    
256
        case APIC_DM_EXTINT:
257
            /* handled in I/O APIC code */
258
            break;
259

    
260
        default:
261
            return;
262
    }
263

    
264
    foreach_apic(apic_iter, deliver_bitmask,
265
                 apic_set_irq(apic_iter, vector_num, trigger_mode) );
266
}
267

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

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

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

    
297
uint64_t cpu_get_apic_base(CPUState *env)
298
{
299
    APICState *s = env->apic_state;
300
#ifdef DEBUG_APIC
301
    printf("cpu_get_apic_base: %016" PRIx64 "\n",
302
           s ? (uint64_t)s->apicbase: 0);
303
#endif
304
    return s ? s->apicbase : 0;
305
}
306

    
307
void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
308
{
309
    APICState *s = env->apic_state;
310
    if (!s)
311
        return;
312
    s->tpr = (val & 0x0f) << 4;
313
    apic_update_irq(s);
314
}
315

    
316
uint8_t cpu_get_apic_tpr(CPUX86State *env)
317
{
318
    APICState *s = env->apic_state;
319
    return s ? s->tpr >> 4 : 0;
320
}
321

    
322
/* return -1 if no bit is set */
323
static int get_highest_priority_int(uint32_t *tab)
324
{
325
    int i;
326
    for(i = 7; i >= 0; i--) {
327
        if (tab[i] != 0) {
328
            return i * 32 + fls_bit(tab[i]);
329
        }
330
    }
331
    return -1;
332
}
333

    
334
static int apic_get_ppr(APICState *s)
335
{
336
    int tpr, isrv, ppr;
337

    
338
    tpr = (s->tpr >> 4);
339
    isrv = get_highest_priority_int(s->isr);
340
    if (isrv < 0)
341
        isrv = 0;
342
    isrv >>= 4;
343
    if (tpr >= isrv)
344
        ppr = s->tpr;
345
    else
346
        ppr = isrv << 4;
347
    return ppr;
348
}
349

    
350
static int apic_get_arb_pri(APICState *s)
351
{
352
    /* XXX: arbitration */
353
    return 0;
354
}
355

    
356
/* signal the CPU if an irq is pending */
357
static void apic_update_irq(APICState *s)
358
{
359
    int irrv, ppr;
360
    if (!(s->spurious_vec & APIC_SV_ENABLE))
361
        return;
362
    irrv = get_highest_priority_int(s->irr);
363
    if (irrv < 0)
364
        return;
365
    ppr = apic_get_ppr(s);
366
    if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
367
        return;
368
    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
369
}
370

    
371
void apic_reset_irq_delivered(void)
372
{
373
    apic_irq_delivered = 0;
374
}
375

    
376
int apic_get_irq_delivered(void)
377
{
378
    return apic_irq_delivered;
379
}
380

    
381
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
382
{
383
    apic_irq_delivered += !get_bit(s->irr, vector_num);
384

    
385
    set_bit(s->irr, vector_num);
386
    if (trigger_mode)
387
        set_bit(s->tmr, vector_num);
388
    else
389
        reset_bit(s->tmr, vector_num);
390
    apic_update_irq(s);
391
}
392

    
393
static void apic_eoi(APICState *s)
394
{
395
    int isrv;
396
    isrv = get_highest_priority_int(s->isr);
397
    if (isrv < 0)
398
        return;
399
    reset_bit(s->isr, isrv);
400
    /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
401
            set the remote IRR bit for level triggered interrupts. */
402
    apic_update_irq(s);
403
}
404

    
405
static int apic_find_dest(uint8_t dest)
406
{
407
    APICState *apic = local_apics[dest];
408
    int i;
409

    
410
    if (apic && apic->id == dest)
411
        return dest;  /* shortcut in case apic->id == apic->idx */
412

    
413
    for (i = 0; i < MAX_APICS; i++) {
414
        apic = local_apics[i];
415
        if (apic && apic->id == dest)
416
            return i;
417
    }
418

    
419
    return -1;
420
}
421

    
422
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
423
                                      uint8_t dest, uint8_t dest_mode)
424
{
425
    APICState *apic_iter;
426
    int i;
427

    
428
    if (dest_mode == 0) {
429
        if (dest == 0xff) {
430
            memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t));
431
        } else {
432
            int idx = apic_find_dest(dest);
433
            memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
434
            if (idx >= 0)
435
                set_bit(deliver_bitmask, idx);
436
        }
437
    } else {
438
        /* XXX: cluster mode */
439
        memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
440
        for(i = 0; i < MAX_APICS; i++) {
441
            apic_iter = local_apics[i];
442
            if (apic_iter) {
443
                if (apic_iter->dest_mode == 0xf) {
444
                    if (dest & apic_iter->log_dest)
445
                        set_bit(deliver_bitmask, i);
446
                } else if (apic_iter->dest_mode == 0x0) {
447
                    if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) &&
448
                        (dest & apic_iter->log_dest & 0x0f)) {
449
                        set_bit(deliver_bitmask, i);
450
                    }
451
                }
452
            }
453
        }
454
    }
455
}
456

    
457

    
458
void apic_init_reset(CPUState *env)
459
{
460
    APICState *s = env->apic_state;
461
    int i;
462

    
463
    if (!s)
464
        return;
465

    
466
    s->tpr = 0;
467
    s->spurious_vec = 0xff;
468
    s->log_dest = 0;
469
    s->dest_mode = 0xf;
470
    memset(s->isr, 0, sizeof(s->isr));
471
    memset(s->tmr, 0, sizeof(s->tmr));
472
    memset(s->irr, 0, sizeof(s->irr));
473
    for(i = 0; i < APIC_LVT_NB; i++)
474
        s->lvt[i] = 1 << 16; /* mask LVT */
475
    s->esr = 0;
476
    memset(s->icr, 0, sizeof(s->icr));
477
    s->divide_conf = 0;
478
    s->count_shift = 0;
479
    s->initial_count = 0;
480
    s->initial_count_load_time = 0;
481
    s->next_time = 0;
482
    s->wait_for_sipi = 1;
483

    
484
    env->halted = !(s->apicbase & MSR_IA32_APICBASE_BSP);
485
}
486

    
487
static void apic_startup(APICState *s, int vector_num)
488
{
489
    s->sipi_vector = vector_num;
490
    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_SIPI);
491
}
492

    
493
void apic_sipi(CPUState *env)
494
{
495
    APICState *s = env->apic_state;
496

    
497
    cpu_reset_interrupt(env, CPU_INTERRUPT_SIPI);
498

    
499
    if (!s->wait_for_sipi)
500
        return;
501

    
502
    env->eip = 0;
503
    cpu_x86_load_seg_cache(env, R_CS, s->sipi_vector << 8, s->sipi_vector << 12,
504
                           0xffff, 0);
505
    env->halted = 0;
506
    s->wait_for_sipi = 0;
507
}
508

    
509
static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
510
                         uint8_t delivery_mode, uint8_t vector_num,
511
                         uint8_t polarity, uint8_t trigger_mode)
512
{
513
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
514
    int dest_shorthand = (s->icr[0] >> 18) & 3;
515
    APICState *apic_iter;
516

    
517
    switch (dest_shorthand) {
518
    case 0:
519
        apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
520
        break;
521
    case 1:
522
        memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
523
        set_bit(deliver_bitmask, s->idx);
524
        break;
525
    case 2:
526
        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
527
        break;
528
    case 3:
529
        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
530
        reset_bit(deliver_bitmask, s->idx);
531
        break;
532
    }
533

    
534
    switch (delivery_mode) {
535
        case APIC_DM_INIT:
536
            {
537
                int trig_mode = (s->icr[0] >> 15) & 1;
538
                int level = (s->icr[0] >> 14) & 1;
539
                if (level == 0 && trig_mode == 1) {
540
                    foreach_apic(apic_iter, deliver_bitmask,
541
                                 apic_iter->arb_id = apic_iter->id );
542
                    return;
543
                }
544
            }
545
            break;
546

    
547
        case APIC_DM_SIPI:
548
            foreach_apic(apic_iter, deliver_bitmask,
549
                         apic_startup(apic_iter, vector_num) );
550
            return;
551
    }
552

    
553
    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
554
                     trigger_mode);
555
}
556

    
557
int apic_get_interrupt(CPUState *env)
558
{
559
    APICState *s = env->apic_state;
560
    int intno;
561

    
562
    /* if the APIC is installed or enabled, we let the 8259 handle the
563
       IRQs */
564
    if (!s)
565
        return -1;
566
    if (!(s->spurious_vec & APIC_SV_ENABLE))
567
        return -1;
568

    
569
    /* XXX: spurious IRQ handling */
570
    intno = get_highest_priority_int(s->irr);
571
    if (intno < 0)
572
        return -1;
573
    if (s->tpr && intno <= s->tpr)
574
        return s->spurious_vec & 0xff;
575
    reset_bit(s->irr, intno);
576
    set_bit(s->isr, intno);
577
    apic_update_irq(s);
578
    return intno;
579
}
580

    
581
int apic_accept_pic_intr(CPUState *env)
582
{
583
    APICState *s = env->apic_state;
584
    uint32_t lvt0;
585

    
586
    if (!s)
587
        return -1;
588

    
589
    lvt0 = s->lvt[APIC_LVT_LINT0];
590

    
591
    if ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
592
        (lvt0 & APIC_LVT_MASKED) == 0)
593
        return 1;
594

    
595
    return 0;
596
}
597

    
598
static uint32_t apic_get_current_count(APICState *s)
599
{
600
    int64_t d;
601
    uint32_t val;
602
    d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >>
603
        s->count_shift;
604
    if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
605
        /* periodic */
606
        val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
607
    } else {
608
        if (d >= s->initial_count)
609
            val = 0;
610
        else
611
            val = s->initial_count - d;
612
    }
613
    return val;
614
}
615

    
616
static void apic_timer_update(APICState *s, int64_t current_time)
617
{
618
    int64_t next_time, d;
619

    
620
    if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
621
        d = (current_time - s->initial_count_load_time) >>
622
            s->count_shift;
623
        if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
624
            if (!s->initial_count)
625
                goto no_timer;
626
            d = ((d / ((uint64_t)s->initial_count + 1)) + 1) * ((uint64_t)s->initial_count + 1);
627
        } else {
628
            if (d >= s->initial_count)
629
                goto no_timer;
630
            d = (uint64_t)s->initial_count + 1;
631
        }
632
        next_time = s->initial_count_load_time + (d << s->count_shift);
633
        qemu_mod_timer(s->timer, next_time);
634
        s->next_time = next_time;
635
    } else {
636
    no_timer:
637
        qemu_del_timer(s->timer);
638
    }
639
}
640

    
641
static void apic_timer(void *opaque)
642
{
643
    APICState *s = opaque;
644

    
645
    apic_local_deliver(s->cpu_env, APIC_LVT_TIMER);
646
    apic_timer_update(s, s->next_time);
647
}
648

    
649
static uint32_t apic_mem_readb(void *opaque, target_phys_addr_t addr)
650
{
651
    return 0;
652
}
653

    
654
static uint32_t apic_mem_readw(void *opaque, target_phys_addr_t addr)
655
{
656
    return 0;
657
}
658

    
659
static void apic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
660
{
661
}
662

    
663
static void apic_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
664
{
665
}
666

    
667
static uint32_t apic_mem_readl(void *opaque, target_phys_addr_t addr)
668
{
669
    CPUState *env;
670
    APICState *s;
671
    uint32_t val;
672
    int index;
673

    
674
    env = cpu_single_env;
675
    if (!env)
676
        return 0;
677
    s = env->apic_state;
678

    
679
    index = (addr >> 4) & 0xff;
680
    switch(index) {
681
    case 0x02: /* id */
682
        val = s->id << 24;
683
        break;
684
    case 0x03: /* version */
685
        val = 0x11 | ((APIC_LVT_NB - 1) << 16); /* version 0x11 */
686
        break;
687
    case 0x08:
688
        val = s->tpr;
689
        break;
690
    case 0x09:
691
        val = apic_get_arb_pri(s);
692
        break;
693
    case 0x0a:
694
        /* ppr */
695
        val = apic_get_ppr(s);
696
        break;
697
    case 0x0b:
698
        val = 0;
699
        break;
700
    case 0x0d:
701
        val = s->log_dest << 24;
702
        break;
703
    case 0x0e:
704
        val = s->dest_mode << 28;
705
        break;
706
    case 0x0f:
707
        val = s->spurious_vec;
708
        break;
709
    case 0x10 ... 0x17:
710
        val = s->isr[index & 7];
711
        break;
712
    case 0x18 ... 0x1f:
713
        val = s->tmr[index & 7];
714
        break;
715
    case 0x20 ... 0x27:
716
        val = s->irr[index & 7];
717
        break;
718
    case 0x28:
719
        val = s->esr;
720
        break;
721
    case 0x30:
722
    case 0x31:
723
        val = s->icr[index & 1];
724
        break;
725
    case 0x32 ... 0x37:
726
        val = s->lvt[index - 0x32];
727
        break;
728
    case 0x38:
729
        val = s->initial_count;
730
        break;
731
    case 0x39:
732
        val = apic_get_current_count(s);
733
        break;
734
    case 0x3e:
735
        val = s->divide_conf;
736
        break;
737
    default:
738
        s->esr |= ESR_ILLEGAL_ADDRESS;
739
        val = 0;
740
        break;
741
    }
742
#ifdef DEBUG_APIC
743
    printf("APIC read: %08x = %08x\n", (uint32_t)addr, val);
744
#endif
745
    return val;
746
}
747

    
748
static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
749
{
750
    CPUState *env;
751
    APICState *s;
752
    int index;
753

    
754
    env = cpu_single_env;
755
    if (!env)
756
        return;
757
    s = env->apic_state;
758

    
759
#ifdef DEBUG_APIC
760
    printf("APIC write: %08x = %08x\n", (uint32_t)addr, val);
761
#endif
762

    
763
    index = (addr >> 4) & 0xff;
764
    switch(index) {
765
    case 0x02:
766
        s->id = (val >> 24);
767
        break;
768
    case 0x03:
769
        break;
770
    case 0x08:
771
        s->tpr = val;
772
        apic_update_irq(s);
773
        break;
774
    case 0x09:
775
    case 0x0a:
776
        break;
777
    case 0x0b: /* EOI */
778
        apic_eoi(s);
779
        break;
780
    case 0x0d:
781
        s->log_dest = val >> 24;
782
        break;
783
    case 0x0e:
784
        s->dest_mode = val >> 28;
785
        break;
786
    case 0x0f:
787
        s->spurious_vec = val & 0x1ff;
788
        apic_update_irq(s);
789
        break;
790
    case 0x10 ... 0x17:
791
    case 0x18 ... 0x1f:
792
    case 0x20 ... 0x27:
793
    case 0x28:
794
        break;
795
    case 0x30:
796
        s->icr[0] = val;
797
        apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
798
                     (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
799
                     (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
800
        break;
801
    case 0x31:
802
        s->icr[1] = val;
803
        break;
804
    case 0x32 ... 0x37:
805
        {
806
            int n = index - 0x32;
807
            s->lvt[n] = val;
808
            if (n == APIC_LVT_TIMER)
809
                apic_timer_update(s, qemu_get_clock(vm_clock));
810
        }
811
        break;
812
    case 0x38:
813
        s->initial_count = val;
814
        s->initial_count_load_time = qemu_get_clock(vm_clock);
815
        apic_timer_update(s, s->initial_count_load_time);
816
        break;
817
    case 0x39:
818
        break;
819
    case 0x3e:
820
        {
821
            int v;
822
            s->divide_conf = val & 0xb;
823
            v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
824
            s->count_shift = (v + 1) & 7;
825
        }
826
        break;
827
    default:
828
        s->esr |= ESR_ILLEGAL_ADDRESS;
829
        break;
830
    }
831
}
832

    
833
static void apic_save(QEMUFile *f, void *opaque)
834
{
835
    APICState *s = opaque;
836
    int i;
837

    
838
    qemu_put_be32s(f, &s->apicbase);
839
    qemu_put_8s(f, &s->id);
840
    qemu_put_8s(f, &s->arb_id);
841
    qemu_put_8s(f, &s->tpr);
842
    qemu_put_be32s(f, &s->spurious_vec);
843
    qemu_put_8s(f, &s->log_dest);
844
    qemu_put_8s(f, &s->dest_mode);
845
    for (i = 0; i < 8; i++) {
846
        qemu_put_be32s(f, &s->isr[i]);
847
        qemu_put_be32s(f, &s->tmr[i]);
848
        qemu_put_be32s(f, &s->irr[i]);
849
    }
850
    for (i = 0; i < APIC_LVT_NB; i++) {
851
        qemu_put_be32s(f, &s->lvt[i]);
852
    }
853
    qemu_put_be32s(f, &s->esr);
854
    qemu_put_be32s(f, &s->icr[0]);
855
    qemu_put_be32s(f, &s->icr[1]);
856
    qemu_put_be32s(f, &s->divide_conf);
857
    qemu_put_be32(f, s->count_shift);
858
    qemu_put_be32s(f, &s->initial_count);
859
    qemu_put_be64(f, s->initial_count_load_time);
860
    qemu_put_be64(f, s->next_time);
861

    
862
    qemu_put_timer(f, s->timer);
863
}
864

    
865
static int apic_load(QEMUFile *f, void *opaque, int version_id)
866
{
867
    APICState *s = opaque;
868
    int i;
869

    
870
    if (version_id > 2)
871
        return -EINVAL;
872

    
873
    /* XXX: what if the base changes? (registered memory regions) */
874
    qemu_get_be32s(f, &s->apicbase);
875
    qemu_get_8s(f, &s->id);
876
    qemu_get_8s(f, &s->arb_id);
877
    qemu_get_8s(f, &s->tpr);
878
    qemu_get_be32s(f, &s->spurious_vec);
879
    qemu_get_8s(f, &s->log_dest);
880
    qemu_get_8s(f, &s->dest_mode);
881
    for (i = 0; i < 8; i++) {
882
        qemu_get_be32s(f, &s->isr[i]);
883
        qemu_get_be32s(f, &s->tmr[i]);
884
        qemu_get_be32s(f, &s->irr[i]);
885
    }
886
    for (i = 0; i < APIC_LVT_NB; i++) {
887
        qemu_get_be32s(f, &s->lvt[i]);
888
    }
889
    qemu_get_be32s(f, &s->esr);
890
    qemu_get_be32s(f, &s->icr[0]);
891
    qemu_get_be32s(f, &s->icr[1]);
892
    qemu_get_be32s(f, &s->divide_conf);
893
    s->count_shift=qemu_get_be32(f);
894
    qemu_get_be32s(f, &s->initial_count);
895
    s->initial_count_load_time=qemu_get_be64(f);
896
    s->next_time=qemu_get_be64(f);
897

    
898
    if (version_id >= 2)
899
        qemu_get_timer(f, s->timer);
900
    return 0;
901
}
902

    
903
static void apic_reset(void *opaque)
904
{
905
    APICState *s = opaque;
906
    int bsp = cpu_is_bsp(s->cpu_env);
907

    
908
    s->apicbase = 0xfee00000 |
909
        (bsp ? MSR_IA32_APICBASE_BSP : 0) | MSR_IA32_APICBASE_ENABLE;
910

    
911
    cpu_reset(s->cpu_env);
912
    apic_init_reset(s->cpu_env);
913

    
914
    if (bsp) {
915
        /*
916
         * LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
917
         * time typically by BIOS, so PIC interrupt can be delivered to the
918
         * processor when local APIC is enabled.
919
         */
920
        s->lvt[APIC_LVT_LINT0] = 0x700;
921
    }
922
}
923

    
924
static CPUReadMemoryFunc *apic_mem_read[3] = {
925
    apic_mem_readb,
926
    apic_mem_readw,
927
    apic_mem_readl,
928
};
929

    
930
static CPUWriteMemoryFunc *apic_mem_write[3] = {
931
    apic_mem_writeb,
932
    apic_mem_writew,
933
    apic_mem_writel,
934
};
935

    
936
int apic_init(CPUState *env)
937
{
938
    APICState *s;
939

    
940
    if (last_apic_idx >= MAX_APICS)
941
        return -1;
942
    s = qemu_mallocz(sizeof(APICState));
943
    env->apic_state = s;
944
    s->idx = last_apic_idx++;
945
    s->id = env->cpuid_apic_id;
946
    s->cpu_env = env;
947

    
948
    apic_reset(s);
949

    
950
    /* XXX: mapping more APICs at the same memory location */
951
    if (apic_io_memory == 0) {
952
        /* NOTE: the APIC is directly connected to the CPU - it is not
953
           on the global memory bus. */
954
        apic_io_memory = cpu_register_io_memory(apic_mem_read,
955
                                                apic_mem_write, NULL);
956
        cpu_register_physical_memory(s->apicbase & ~0xfff, 0x1000,
957
                                     apic_io_memory);
958
    }
959
    s->timer = qemu_new_timer(vm_clock, apic_timer, s);
960

    
961
    register_savevm("apic", s->idx, 2, apic_save, apic_load, s);
962
    qemu_register_reset(apic_reset, 0, s);
963

    
964
    local_apics[s->idx] = s;
965
    return 0;
966
}
967