Statistics
| Branch: | Revision:

root / hw / apic.c @ 09b26c5e

History | View | Annotate | Download (26.5 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 "vl.h"
21

    
22
//#define DEBUG_APIC
23
//#define DEBUG_IOAPIC
24

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

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

    
43
/* APIC destination mode */
44
#define APIC_DESTMODE_FLAT        0xf
45
#define APIC_DESTMODE_CLUSTER        1
46

    
47
#define APIC_TRIGGER_EDGE  0
48
#define APIC_TRIGGER_LEVEL 1
49

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

    
57
#define IOAPIC_NUM_PINS                        0x18
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
struct IOAPICState {
90
    uint8_t id;
91
    uint8_t ioregsel;
92

    
93
    uint32_t irr;
94
    uint64_t ioredtbl[IOAPIC_NUM_PINS];
95
};
96

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

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

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

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

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

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

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

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

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

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

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

    
213
        case APIC_DM_FIXED:
214
            break;
215

    
216
        case APIC_DM_SMI:
217
        case APIC_DM_NMI:
218
            break;
219

    
220
        case APIC_DM_INIT:
221
            /* normal INIT IPI sent to processors */
222
            foreach_apic(apic_iter, deliver_bitmask, 
223
                         apic_init_ipi(apic_iter) );
224
            return;
225
    
226
        case APIC_DM_EXTINT:
227
            /* handled in I/O APIC code */
228
            break;
229

    
230
        default:
231
            return;
232
    }
233

    
234
    foreach_apic(apic_iter, deliver_bitmask, 
235
                 apic_set_irq(apic_iter, vector_num, trigger_mode) );
236
}
237

    
238
void cpu_set_apic_base(CPUState *env, uint64_t val)
239
{
240
    APICState *s = env->apic_state;
241
#ifdef DEBUG_APIC
242
    printf("cpu_set_apic_base: %016llx\n", val);
243
#endif
244
    s->apicbase = (val & 0xfffff000) | 
245
        (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
246
    /* if disabled, cannot be enabled again */
247
    if (!(val & MSR_IA32_APICBASE_ENABLE)) {
248
        s->apicbase &= ~MSR_IA32_APICBASE_ENABLE;
249
        env->cpuid_features &= ~CPUID_APIC;
250
        s->spurious_vec &= ~APIC_SV_ENABLE;
251
    }
252
}
253

    
254
uint64_t cpu_get_apic_base(CPUState *env)
255
{
256
    APICState *s = env->apic_state;
257
#ifdef DEBUG_APIC
258
    printf("cpu_get_apic_base: %016llx\n", (uint64_t)s->apicbase);
259
#endif
260
    return s->apicbase;
261
}
262

    
263
void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
264
{
265
    APICState *s = env->apic_state;
266
    s->tpr = (val & 0x0f) << 4;
267
    apic_update_irq(s);
268
}
269

    
270
uint8_t cpu_get_apic_tpr(CPUX86State *env)
271
{
272
    APICState *s = env->apic_state;
273
    return s->tpr >> 4;
274
}
275

    
276
/* return -1 if no bit is set */
277
static int get_highest_priority_int(uint32_t *tab)
278
{
279
    int i;
280
    for(i = 7; i >= 0; i--) {
281
        if (tab[i] != 0) {
282
            return i * 32 + fls_bit(tab[i]);
283
        }
284
    }
285
    return -1;
286
}
287

    
288
static int apic_get_ppr(APICState *s)
289
{
290
    int tpr, isrv, ppr;
291

    
292
    tpr = (s->tpr >> 4);
293
    isrv = get_highest_priority_int(s->isr);
294
    if (isrv < 0)
295
        isrv = 0;
296
    isrv >>= 4;
297
    if (tpr >= isrv)
298
        ppr = s->tpr;
299
    else
300
        ppr = isrv << 4;
301
    return ppr;
302
}
303

    
304
static int apic_get_arb_pri(APICState *s)
305
{
306
    /* XXX: arbitration */
307
    return 0;
308
}
309

    
310
/* signal the CPU if an irq is pending */
311
static void apic_update_irq(APICState *s)
312
{
313
    int irrv, ppr;
314
    if (!(s->spurious_vec & APIC_SV_ENABLE))
315
        return;
316
    irrv = get_highest_priority_int(s->irr);
317
    if (irrv < 0)
318
        return;
319
    ppr = apic_get_ppr(s);
320
    if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
321
        return;
322
    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
323
}
324

    
325
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
326
{
327
    set_bit(s->irr, vector_num);
328
    if (trigger_mode)
329
        set_bit(s->tmr, vector_num);
330
    else
331
        reset_bit(s->tmr, vector_num);
332
    apic_update_irq(s);
333
}
334

    
335
static void apic_eoi(APICState *s)
336
{
337
    int isrv;
338
    isrv = get_highest_priority_int(s->isr);
339
    if (isrv < 0)
340
        return;
341
    reset_bit(s->isr, isrv);
342
    /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
343
            set the remote IRR bit for level triggered interrupts. */
344
    apic_update_irq(s);
345
}
346

    
347
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
348
                                      uint8_t dest, uint8_t dest_mode)
349
{
350
    APICState *apic_iter;
351
    int i;
352

    
353
    if (dest_mode == 0) {
354
        if (dest == 0xff) {
355
            memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t));
356
        } else {
357
            memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
358
            set_bit(deliver_bitmask, dest);
359
        }
360
    } else {
361
        /* XXX: cluster mode */
362
        memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
363
        for(i = 0; i < MAX_APICS; i++) {
364
            apic_iter = local_apics[i];
365
            if (apic_iter) {
366
                if (apic_iter->dest_mode == 0xf) {
367
                    if (dest & apic_iter->log_dest)
368
                        set_bit(deliver_bitmask, i);
369
                } else if (apic_iter->dest_mode == 0x0) {
370
                    if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) &&
371
                        (dest & apic_iter->log_dest & 0x0f)) {
372
                        set_bit(deliver_bitmask, i);
373
                    }
374
                }
375
            }
376
        }
377
    }
378
}
379

    
380

    
381
static void apic_init_ipi(APICState *s)
382
{
383
    int i;
384

    
385
    for(i = 0; i < APIC_LVT_NB; i++)
386
        s->lvt[i] = 1 << 16; /* mask LVT */
387
    s->tpr = 0;
388
    s->spurious_vec = 0xff;
389
    s->log_dest = 0;
390
    s->dest_mode = 0xf;
391
    memset(s->isr, 0, sizeof(s->isr));
392
    memset(s->tmr, 0, sizeof(s->tmr));
393
    memset(s->irr, 0, sizeof(s->irr));
394
    memset(s->lvt, 0, sizeof(s->lvt));
395
    s->esr = 0;
396
    memset(s->icr, 0, sizeof(s->icr));
397
    s->divide_conf = 0;
398
    s->count_shift = 0;
399
    s->initial_count = 0;
400
    s->initial_count_load_time = 0;
401
    s->next_time = 0;
402
}
403

    
404
/* send a SIPI message to the CPU to start it */
405
static void apic_startup(APICState *s, int vector_num)
406
{
407
    CPUState *env = s->cpu_env;
408
    if (!(env->hflags & HF_HALTED_MASK))
409
        return;
410
    env->eip = 0;
411
    cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12, 
412
                           0xffff, 0);
413
    env->hflags &= ~HF_HALTED_MASK;
414
}
415

    
416
static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
417
                         uint8_t delivery_mode, uint8_t vector_num,
418
                         uint8_t polarity, uint8_t trigger_mode)
419
{
420
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
421
    int dest_shorthand = (s->icr[0] >> 18) & 3;
422
    APICState *apic_iter;
423

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

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

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

    
460
    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
461
                     trigger_mode);
462
}
463

    
464
int apic_get_interrupt(CPUState *env)
465
{
466
    APICState *s = env->apic_state;
467
    int intno;
468

    
469
    /* if the APIC is installed or enabled, we let the 8259 handle the
470
       IRQs */
471
    if (!s)
472
        return -1;
473
    if (!(s->spurious_vec & APIC_SV_ENABLE))
474
        return -1;
475
    
476
    /* XXX: spurious IRQ handling */
477
    intno = get_highest_priority_int(s->irr);
478
    if (intno < 0)
479
        return -1;
480
    reset_bit(s->irr, intno);
481
    if (s->tpr && intno <= s->tpr)
482
        return s->spurious_vec & 0xff;
483
    set_bit(s->isr, intno);
484
    apic_update_irq(s);
485
    return intno;
486
}
487

    
488
static uint32_t apic_get_current_count(APICState *s)
489
{
490
    int64_t d;
491
    uint32_t val;
492
    d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >> 
493
        s->count_shift;
494
    if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
495
        /* periodic */
496
        val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
497
    } else {
498
        if (d >= s->initial_count)
499
            val = 0;
500
        else
501
            val = s->initial_count - d;
502
    }
503
    return val;
504
}
505

    
506
static void apic_timer_update(APICState *s, int64_t current_time)
507
{
508
    int64_t next_time, d;
509
    
510
    if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
511
        d = (current_time - s->initial_count_load_time) >> 
512
            s->count_shift;
513
        if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
514
            d = ((d / ((uint64_t)s->initial_count + 1)) + 1) * ((uint64_t)s->initial_count + 1);
515
        } else {
516
            if (d >= s->initial_count)
517
                goto no_timer;
518
            d = (uint64_t)s->initial_count + 1;
519
        }
520
        next_time = s->initial_count_load_time + (d << s->count_shift);
521
        qemu_mod_timer(s->timer, next_time);
522
        s->next_time = next_time;
523
    } else {
524
    no_timer:
525
        qemu_del_timer(s->timer);
526
    }
527
}
528

    
529
static void apic_timer(void *opaque)
530
{
531
    APICState *s = opaque;
532

    
533
    if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
534
        apic_set_irq(s, s->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);
535
    }
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
    CPUState *env;
560
    APICState *s;
561
    uint32_t val;
562
    int index;
563

    
564
    env = cpu_single_env;
565
    if (!env)
566
        return 0;
567
    s = env->apic_state;
568

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

    
635
static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
636
{
637
    CPUState *env;
638
    APICState *s;
639
    int index;
640

    
641
    env = cpu_single_env;
642
    if (!env)
643
        return;
644
    s = env->apic_state;
645

    
646
#ifdef DEBUG_APIC
647
    printf("APIC write: %08x = %08x\n", (uint32_t)addr, val);
648
#endif
649

    
650
    index = (addr >> 4) & 0xff;
651
    switch(index) {
652
    case 0x02:
653
        s->id = (val >> 24);
654
        break;
655
    case 0x03:
656
        break;
657
    case 0x08:
658
        s->tpr = val;
659
        apic_update_irq(s);
660
        break;
661
    case 0x09:
662
    case 0x0a:
663
        break;
664
    case 0x0b: /* EOI */
665
        apic_eoi(s);
666
        break;
667
    case 0x0d:
668
        s->log_dest = val >> 24;
669
        break;
670
    case 0x0e:
671
        s->dest_mode = val >> 28;
672
        break;
673
    case 0x0f:
674
        s->spurious_vec = val & 0x1ff;
675
        apic_update_irq(s);
676
        break;
677
    case 0x10 ... 0x17:
678
    case 0x18 ... 0x1f:
679
    case 0x20 ... 0x27:
680
    case 0x28:
681
        break;
682
    case 0x30:
683
        s->icr[0] = val;
684
        apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
685
                     (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
686
                     (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
687
        break;
688
    case 0x31:
689
        s->icr[1] = val;
690
        break;
691
    case 0x32 ... 0x37:
692
        {
693
            int n = index - 0x32;
694
            s->lvt[n] = val;
695
            if (n == APIC_LVT_TIMER)
696
                apic_timer_update(s, qemu_get_clock(vm_clock));
697
        }
698
        break;
699
    case 0x38:
700
        s->initial_count = val;
701
        s->initial_count_load_time = qemu_get_clock(vm_clock);
702
        apic_timer_update(s, s->initial_count_load_time);
703
        break;
704
    case 0x39:
705
        break;
706
    case 0x3e:
707
        {
708
            int v;
709
            s->divide_conf = val & 0xb;
710
            v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
711
            s->count_shift = (v + 1) & 7;
712
        }
713
        break;
714
    default:
715
        s->esr |= ESR_ILLEGAL_ADDRESS;
716
        break;
717
    }
718
}
719

    
720
static void apic_save(QEMUFile *f, void *opaque)
721
{
722
    APICState *s = opaque;
723
    int i;
724

    
725
    qemu_put_be32s(f, &s->apicbase);
726
    qemu_put_8s(f, &s->id);
727
    qemu_put_8s(f, &s->arb_id);
728
    qemu_put_8s(f, &s->tpr);
729
    qemu_put_be32s(f, &s->spurious_vec);
730
    qemu_put_8s(f, &s->log_dest);
731
    qemu_put_8s(f, &s->dest_mode);
732
    for (i = 0; i < 8; i++) {
733
        qemu_put_be32s(f, &s->isr[i]);
734
        qemu_put_be32s(f, &s->tmr[i]);
735
        qemu_put_be32s(f, &s->irr[i]);
736
    }
737
    for (i = 0; i < APIC_LVT_NB; i++) {
738
        qemu_put_be32s(f, &s->lvt[i]);
739
    }
740
    qemu_put_be32s(f, &s->esr);
741
    qemu_put_be32s(f, &s->icr[0]);
742
    qemu_put_be32s(f, &s->icr[1]);
743
    qemu_put_be32s(f, &s->divide_conf);
744
    qemu_put_be32s(f, &s->count_shift);
745
    qemu_put_be32s(f, &s->initial_count);
746
    qemu_put_be64s(f, &s->initial_count_load_time);
747
    qemu_put_be64s(f, &s->next_time);
748
}
749

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

    
755
    if (version_id != 1)
756
        return -EINVAL;
757

    
758
    /* XXX: what if the base changes? (registered memory regions) */
759
    qemu_get_be32s(f, &s->apicbase);
760
    qemu_get_8s(f, &s->id);
761
    qemu_get_8s(f, &s->arb_id);
762
    qemu_get_8s(f, &s->tpr);
763
    qemu_get_be32s(f, &s->spurious_vec);
764
    qemu_get_8s(f, &s->log_dest);
765
    qemu_get_8s(f, &s->dest_mode);
766
    for (i = 0; i < 8; i++) {
767
        qemu_get_be32s(f, &s->isr[i]);
768
        qemu_get_be32s(f, &s->tmr[i]);
769
        qemu_get_be32s(f, &s->irr[i]);
770
    }
771
    for (i = 0; i < APIC_LVT_NB; i++) {
772
        qemu_get_be32s(f, &s->lvt[i]);
773
    }
774
    qemu_get_be32s(f, &s->esr);
775
    qemu_get_be32s(f, &s->icr[0]);
776
    qemu_get_be32s(f, &s->icr[1]);
777
    qemu_get_be32s(f, &s->divide_conf);
778
    qemu_get_be32s(f, &s->count_shift);
779
    qemu_get_be32s(f, &s->initial_count);
780
    qemu_get_be64s(f, &s->initial_count_load_time);
781
    qemu_get_be64s(f, &s->next_time);
782
    return 0;
783
}
784

    
785
static void apic_reset(void *opaque)
786
{
787
    APICState *s = opaque;
788
    apic_init_ipi(s);
789
}
790

    
791
static CPUReadMemoryFunc *apic_mem_read[3] = {
792
    apic_mem_readb,
793
    apic_mem_readw,
794
    apic_mem_readl,
795
};
796

    
797
static CPUWriteMemoryFunc *apic_mem_write[3] = {
798
    apic_mem_writeb,
799
    apic_mem_writew,
800
    apic_mem_writel,
801
};
802

    
803
int apic_init(CPUState *env)
804
{
805
    APICState *s;
806

    
807
    if (last_apic_id >= MAX_APICS)
808
        return -1;
809
    s = qemu_mallocz(sizeof(APICState));
810
    if (!s)
811
        return -1;
812
    env->apic_state = s;
813
    apic_init_ipi(s);
814
    s->id = last_apic_id++;
815
    s->cpu_env = env;
816
    s->apicbase = 0xfee00000 | 
817
        (s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
818

    
819
    /* XXX: mapping more APICs at the same memory location */
820
    if (apic_io_memory == 0) {
821
        /* NOTE: the APIC is directly connected to the CPU - it is not
822
           on the global memory bus. */
823
        apic_io_memory = cpu_register_io_memory(0, apic_mem_read, 
824
                                                apic_mem_write, NULL);
825
        cpu_register_physical_memory(s->apicbase & ~0xfff, 0x1000,
826
                                     apic_io_memory);
827
    }
828
    s->timer = qemu_new_timer(vm_clock, apic_timer, s);
829

    
830
    register_savevm("apic", 0, 1, apic_save, apic_load, s);
831
    qemu_register_reset(apic_reset, s);
832
    
833
    local_apics[s->id] = s;
834
    return 0;
835
}
836

    
837
static void ioapic_service(IOAPICState *s)
838
{
839
    uint8_t i;
840
    uint8_t trig_mode;
841
    uint8_t vector;
842
    uint8_t delivery_mode;
843
    uint32_t mask;
844
    uint64_t entry;
845
    uint8_t dest;
846
    uint8_t dest_mode;
847
    uint8_t polarity;
848
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
849

    
850
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
851
        mask = 1 << i;
852
        if (s->irr & mask) {
853
            entry = s->ioredtbl[i];
854
            if (!(entry & APIC_LVT_MASKED)) {
855
                trig_mode = ((entry >> 15) & 1);
856
                dest = entry >> 56;
857
                dest_mode = (entry >> 11) & 1;
858
                delivery_mode = (entry >> 8) & 7;
859
                polarity = (entry >> 13) & 1;
860
                if (trig_mode == APIC_TRIGGER_EDGE)
861
                    s->irr &= ~mask;
862
                if (delivery_mode == APIC_DM_EXTINT)
863
                    vector = pic_read_irq(isa_pic);
864
                else
865
                    vector = entry & 0xff;
866
                
867
                apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
868
                apic_bus_deliver(deliver_bitmask, delivery_mode, 
869
                                 vector, polarity, trig_mode);
870
            }
871
        }
872
    }
873
}
874

    
875
void ioapic_set_irq(void *opaque, int vector, int level)
876
{
877
    IOAPICState *s = opaque;
878

    
879
    if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
880
        uint32_t mask = 1 << vector;
881
        uint64_t entry = s->ioredtbl[vector];
882

    
883
        if ((entry >> 15) & 1) {
884
            /* level triggered */
885
            if (level) {
886
                s->irr |= mask;
887
                ioapic_service(s);
888
            } else {
889
                s->irr &= ~mask;
890
            }
891
        } else {
892
            /* edge triggered */
893
            if (level) {
894
                s->irr |= mask;
895
                ioapic_service(s);
896
            }
897
        }
898
    }
899
}
900

    
901
static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
902
{
903
    IOAPICState *s = opaque;
904
    int index;
905
    uint32_t val = 0;
906

    
907
    addr &= 0xff;
908
    if (addr == 0x00) {
909
        val = s->ioregsel;
910
    } else if (addr == 0x10) {
911
        switch (s->ioregsel) {
912
            case 0x00:
913
                val = s->id << 24;
914
                break;
915
            case 0x01:
916
                val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */
917
                break;
918
            case 0x02:
919
                val = 0;
920
                break;
921
            default:
922
                index = (s->ioregsel - 0x10) >> 1;
923
                if (index >= 0 && index < IOAPIC_NUM_PINS) {
924
                    if (s->ioregsel & 1)
925
                        val = s->ioredtbl[index] >> 32;
926
                    else
927
                        val = s->ioredtbl[index] & 0xffffffff;
928
                }
929
        }
930
#ifdef DEBUG_IOAPIC
931
        printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val);
932
#endif
933
    }
934
    return val;
935
}
936

    
937
static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
938
{
939
    IOAPICState *s = opaque;
940
    int index;
941

    
942
    addr &= 0xff;
943
    if (addr == 0x00)  {
944
        s->ioregsel = val;
945
        return;
946
    } else if (addr == 0x10) {
947
#ifdef DEBUG_IOAPIC
948
        printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val);
949
#endif
950
        switch (s->ioregsel) {
951
            case 0x00:
952
                s->id = (val >> 24) & 0xff;
953
                return;
954
            case 0x01:
955
            case 0x02:
956
                return;
957
            default:
958
                index = (s->ioregsel - 0x10) >> 1;
959
                if (index >= 0 && index < IOAPIC_NUM_PINS) {
960
                    if (s->ioregsel & 1) {
961
                        s->ioredtbl[index] &= 0xffffffff;
962
                        s->ioredtbl[index] |= (uint64_t)val << 32;
963
                    } else {
964
                        s->ioredtbl[index] &= ~0xffffffffULL;
965
                        s->ioredtbl[index] |= val;
966
                    }
967
                    ioapic_service(s);
968
                }
969
        }
970
    }
971
}
972

    
973
static void ioapic_save(QEMUFile *f, void *opaque)
974
{
975
    IOAPICState *s = opaque;
976
    int i;
977

    
978
    qemu_put_8s(f, &s->id);
979
    qemu_put_8s(f, &s->ioregsel);
980
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
981
        qemu_put_be64s(f, &s->ioredtbl[i]);
982
    }
983
}
984

    
985
static int ioapic_load(QEMUFile *f, void *opaque, int version_id)
986
{
987
    IOAPICState *s = opaque;
988
    int i;
989

    
990
    if (version_id != 1)
991
        return -EINVAL;
992

    
993
    qemu_get_8s(f, &s->id);
994
    qemu_get_8s(f, &s->ioregsel);
995
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
996
        qemu_get_be64s(f, &s->ioredtbl[i]);
997
    }
998
    return 0;
999
}
1000

    
1001
static void ioapic_reset(void *opaque)
1002
{
1003
    IOAPICState *s = opaque;
1004
    int i;
1005

    
1006
    memset(s, 0, sizeof(*s));
1007
    for(i = 0; i < IOAPIC_NUM_PINS; i++)
1008
        s->ioredtbl[i] = 1 << 16; /* mask LVT */
1009
}
1010

    
1011
static CPUReadMemoryFunc *ioapic_mem_read[3] = {
1012
    ioapic_mem_readl,
1013
    ioapic_mem_readl,
1014
    ioapic_mem_readl,
1015
};
1016

    
1017
static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
1018
    ioapic_mem_writel,
1019
    ioapic_mem_writel,
1020
    ioapic_mem_writel,
1021
};
1022

    
1023
IOAPICState *ioapic_init(void)
1024
{
1025
    IOAPICState *s;
1026
    int io_memory;
1027

    
1028
    s = qemu_mallocz(sizeof(IOAPICState));
1029
    if (!s)
1030
        return NULL;
1031
    ioapic_reset(s);
1032
    s->id = last_apic_id++;
1033

    
1034
    io_memory = cpu_register_io_memory(0, ioapic_mem_read, 
1035
                                       ioapic_mem_write, s);
1036
    cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
1037

    
1038
    register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
1039
    qemu_register_reset(ioapic_reset, s);
1040
    
1041
    return s;
1042
}