~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/apic.c

  • Committer: bellard
  • Date: 2003-03-23 20:17:16 UTC
  • Revision ID: git-v1:3ef693a03205217a5def9318b443c8cb6de17217
distribution patches


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@44 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  APIC support
3
 
 *
4
 
 *  Copyright (c) 2004-2005 Fabrice Bellard
5
 
 *
6
 
 * This library is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU Lesser General Public
8
 
 * License as published by the Free Software Foundation; either
9
 
 * version 2 of the License, or (at your option) any later version.
10
 
 *
11
 
 * This library is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 
 * Lesser General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU Lesser General Public
17
 
 * License along with this library; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 */
20
 
#include "hw.h"
21
 
#include "pc.h"
22
 
#include "qemu-timer.h"
23
 
#include "host-utils.h"
24
 
 
25
 
//#define DEBUG_APIC
26
 
//#define DEBUG_IOAPIC
27
 
 
28
 
/* APIC Local Vector Table */
29
 
#define APIC_LVT_TIMER   0
30
 
#define APIC_LVT_THERMAL 1
31
 
#define APIC_LVT_PERFORM 2
32
 
#define APIC_LVT_LINT0   3
33
 
#define APIC_LVT_LINT1   4
34
 
#define APIC_LVT_ERROR   5
35
 
#define APIC_LVT_NB      6
36
 
 
37
 
/* APIC delivery modes */
38
 
#define APIC_DM_FIXED   0
39
 
#define APIC_DM_LOWPRI  1
40
 
#define APIC_DM_SMI     2
41
 
#define APIC_DM_NMI     4
42
 
#define APIC_DM_INIT    5
43
 
#define APIC_DM_SIPI    6
44
 
#define APIC_DM_EXTINT  7
45
 
 
46
 
/* APIC destination mode */
47
 
#define APIC_DESTMODE_FLAT      0xf
48
 
#define APIC_DESTMODE_CLUSTER   1
49
 
 
50
 
#define APIC_TRIGGER_EDGE  0
51
 
#define APIC_TRIGGER_LEVEL 1
52
 
 
53
 
#define APIC_LVT_TIMER_PERIODIC         (1<<17)
54
 
#define APIC_LVT_MASKED                 (1<<16)
55
 
#define APIC_LVT_LEVEL_TRIGGER          (1<<15)
56
 
#define APIC_LVT_REMOTE_IRR             (1<<14)
57
 
#define APIC_INPUT_POLARITY             (1<<13)
58
 
#define APIC_SEND_PENDING               (1<<12)
59
 
 
60
 
#define IOAPIC_NUM_PINS                 0x18
61
 
 
62
 
#define ESR_ILLEGAL_ADDRESS (1 << 7)
63
 
 
64
 
#define APIC_SV_ENABLE (1 << 8)
65
 
 
66
 
#define MAX_APICS 255
67
 
#define MAX_APIC_WORDS 8
68
 
 
69
 
typedef struct APICState {
70
 
    CPUState *cpu_env;
71
 
    uint32_t apicbase;
72
 
    uint8_t id;
73
 
    uint8_t arb_id;
74
 
    uint8_t tpr;
75
 
    uint32_t spurious_vec;
76
 
    uint8_t log_dest;
77
 
    uint8_t dest_mode;
78
 
    uint32_t isr[8];  /* in service register */
79
 
    uint32_t tmr[8];  /* trigger mode register */
80
 
    uint32_t irr[8]; /* interrupt request register */
81
 
    uint32_t lvt[APIC_LVT_NB];
82
 
    uint32_t esr; /* error register */
83
 
    uint32_t icr[2];
84
 
 
85
 
    uint32_t divide_conf;
86
 
    int count_shift;
87
 
    uint32_t initial_count;
88
 
    int64_t initial_count_load_time, next_time;
89
 
    QEMUTimer *timer;
90
 
} APICState;
91
 
 
92
 
struct IOAPICState {
93
 
    uint8_t id;
94
 
    uint8_t ioregsel;
95
 
 
96
 
    uint32_t irr;
97
 
    uint64_t ioredtbl[IOAPIC_NUM_PINS];
98
 
};
99
 
 
100
 
static int apic_io_memory;
101
 
static APICState *local_apics[MAX_APICS + 1];
102
 
static int last_apic_id = 0;
103
 
 
104
 
static void apic_init_ipi(APICState *s);
105
 
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
106
 
static void apic_update_irq(APICState *s);
107
 
 
108
 
/* Find first bit starting from msb */
109
 
static int fls_bit(uint32_t value)
110
 
{
111
 
    return 31 - clz32(value);
112
 
}
113
 
 
114
 
/* Find first bit starting from lsb */
115
 
static int ffs_bit(uint32_t value)
116
 
{
117
 
    return ctz32(value);
118
 
}
119
 
 
120
 
static inline void set_bit(uint32_t *tab, int index)
121
 
{
122
 
    int i, mask;
123
 
    i = index >> 5;
124
 
    mask = 1 << (index & 0x1f);
125
 
    tab[i] |= mask;
126
 
}
127
 
 
128
 
static inline void reset_bit(uint32_t *tab, int index)
129
 
{
130
 
    int i, mask;
131
 
    i = index >> 5;
132
 
    mask = 1 << (index & 0x1f);
133
 
    tab[i] &= ~mask;
134
 
}
135
 
 
136
 
static void apic_local_deliver(CPUState *env, int vector)
137
 
{
138
 
    APICState *s = env->apic_state;
139
 
    uint32_t lvt = s->lvt[vector];
140
 
    int trigger_mode;
141
 
 
142
 
    if (lvt & APIC_LVT_MASKED)
143
 
        return;
144
 
 
145
 
    switch ((lvt >> 8) & 7) {
146
 
    case APIC_DM_SMI:
147
 
        cpu_interrupt(env, CPU_INTERRUPT_SMI);
148
 
        break;
149
 
 
150
 
    case APIC_DM_NMI:
151
 
        cpu_interrupt(env, CPU_INTERRUPT_NMI);
152
 
        break;
153
 
 
154
 
    case APIC_DM_EXTINT:
155
 
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
156
 
        break;
157
 
 
158
 
    case APIC_DM_FIXED:
159
 
        trigger_mode = APIC_TRIGGER_EDGE;
160
 
        if ((vector == APIC_LVT_LINT0 || vector == APIC_LVT_LINT1) &&
161
 
            (lvt & APIC_LVT_LEVEL_TRIGGER))
162
 
            trigger_mode = APIC_TRIGGER_LEVEL;
163
 
        apic_set_irq(s, lvt & 0xff, trigger_mode);
164
 
    }
165
 
}
166
 
 
167
 
void apic_deliver_pic_intr(CPUState *env, int level)
168
 
{
169
 
    if (level)
170
 
        apic_local_deliver(env, APIC_LVT_LINT0);
171
 
    else {
172
 
        APICState *s = env->apic_state;
173
 
        uint32_t lvt = s->lvt[APIC_LVT_LINT0];
174
 
 
175
 
        switch ((lvt >> 8) & 7) {
176
 
        case APIC_DM_FIXED:
177
 
            if (!(lvt & APIC_LVT_LEVEL_TRIGGER))
178
 
                break;
179
 
            reset_bit(s->irr, lvt & 0xff);
180
 
            /* fall through */
181
 
        case APIC_DM_EXTINT:
182
 
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
183
 
            break;
184
 
        }
185
 
    }
186
 
}
187
 
 
188
 
#define foreach_apic(apic, deliver_bitmask, code) \
189
 
{\
190
 
    int __i, __j, __mask;\
191
 
    for(__i = 0; __i < MAX_APIC_WORDS; __i++) {\
192
 
        __mask = deliver_bitmask[__i];\
193
 
        if (__mask) {\
194
 
            for(__j = 0; __j < 32; __j++) {\
195
 
                if (__mask & (1 << __j)) {\
196
 
                    apic = local_apics[__i * 32 + __j];\
197
 
                    if (apic) {\
198
 
                        code;\
199
 
                    }\
200
 
                }\
201
 
            }\
202
 
        }\
203
 
    }\
204
 
}
205
 
 
206
 
static void apic_bus_deliver(const uint32_t *deliver_bitmask,
207
 
                             uint8_t delivery_mode,
208
 
                             uint8_t vector_num, uint8_t polarity,
209
 
                             uint8_t trigger_mode)
210
 
{
211
 
    APICState *apic_iter;
212
 
 
213
 
    switch (delivery_mode) {
214
 
        case APIC_DM_LOWPRI:
215
 
            /* XXX: search for focus processor, arbitration */
216
 
            {
217
 
                int i, d;
218
 
                d = -1;
219
 
                for(i = 0; i < MAX_APIC_WORDS; i++) {
220
 
                    if (deliver_bitmask[i]) {
221
 
                        d = i * 32 + ffs_bit(deliver_bitmask[i]);
222
 
                        break;
223
 
                    }
224
 
                }
225
 
                if (d >= 0) {
226
 
                    apic_iter = local_apics[d];
227
 
                    if (apic_iter) {
228
 
                        apic_set_irq(apic_iter, vector_num, trigger_mode);
229
 
                    }
230
 
                }
231
 
            }
232
 
            return;
233
 
 
234
 
        case APIC_DM_FIXED:
235
 
            break;
236
 
 
237
 
        case APIC_DM_SMI:
238
 
            foreach_apic(apic_iter, deliver_bitmask,
239
 
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_SMI) );
240
 
            return;
241
 
 
242
 
        case APIC_DM_NMI:
243
 
            foreach_apic(apic_iter, deliver_bitmask,
244
 
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_NMI) );
245
 
            return;
246
 
 
247
 
        case APIC_DM_INIT:
248
 
            /* normal INIT IPI sent to processors */
249
 
            foreach_apic(apic_iter, deliver_bitmask,
250
 
                         apic_init_ipi(apic_iter) );
251
 
            return;
252
 
 
253
 
        case APIC_DM_EXTINT:
254
 
            /* handled in I/O APIC code */
255
 
            break;
256
 
 
257
 
        default:
258
 
            return;
259
 
    }
260
 
 
261
 
    foreach_apic(apic_iter, deliver_bitmask,
262
 
                 apic_set_irq(apic_iter, vector_num, trigger_mode) );
263
 
}
264
 
 
265
 
void cpu_set_apic_base(CPUState *env, uint64_t val)
266
 
{
267
 
    APICState *s = env->apic_state;
268
 
#ifdef DEBUG_APIC
269
 
    printf("cpu_set_apic_base: %016" PRIx64 "\n", val);
270
 
#endif
271
 
    s->apicbase = (val & 0xfffff000) |
272
 
        (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
273
 
    /* if disabled, cannot be enabled again */
274
 
    if (!(val & MSR_IA32_APICBASE_ENABLE)) {
275
 
        s->apicbase &= ~MSR_IA32_APICBASE_ENABLE;
276
 
        env->cpuid_features &= ~CPUID_APIC;
277
 
        s->spurious_vec &= ~APIC_SV_ENABLE;
278
 
    }
279
 
}
280
 
 
281
 
uint64_t cpu_get_apic_base(CPUState *env)
282
 
{
283
 
    APICState *s = env->apic_state;
284
 
#ifdef DEBUG_APIC
285
 
    printf("cpu_get_apic_base: %016" PRIx64 "\n", (uint64_t)s->apicbase);
286
 
#endif
287
 
    return s->apicbase;
288
 
}
289
 
 
290
 
void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
291
 
{
292
 
    APICState *s = env->apic_state;
293
 
    s->tpr = (val & 0x0f) << 4;
294
 
    apic_update_irq(s);
295
 
}
296
 
 
297
 
uint8_t cpu_get_apic_tpr(CPUX86State *env)
298
 
{
299
 
    APICState *s = env->apic_state;
300
 
    return s->tpr >> 4;
301
 
}
302
 
 
303
 
/* return -1 if no bit is set */
304
 
static int get_highest_priority_int(uint32_t *tab)
305
 
{
306
 
    int i;
307
 
    for(i = 7; i >= 0; i--) {
308
 
        if (tab[i] != 0) {
309
 
            return i * 32 + fls_bit(tab[i]);
310
 
        }
311
 
    }
312
 
    return -1;
313
 
}
314
 
 
315
 
static int apic_get_ppr(APICState *s)
316
 
{
317
 
    int tpr, isrv, ppr;
318
 
 
319
 
    tpr = (s->tpr >> 4);
320
 
    isrv = get_highest_priority_int(s->isr);
321
 
    if (isrv < 0)
322
 
        isrv = 0;
323
 
    isrv >>= 4;
324
 
    if (tpr >= isrv)
325
 
        ppr = s->tpr;
326
 
    else
327
 
        ppr = isrv << 4;
328
 
    return ppr;
329
 
}
330
 
 
331
 
static int apic_get_arb_pri(APICState *s)
332
 
{
333
 
    /* XXX: arbitration */
334
 
    return 0;
335
 
}
336
 
 
337
 
/* signal the CPU if an irq is pending */
338
 
static void apic_update_irq(APICState *s)
339
 
{
340
 
    int irrv, ppr;
341
 
    if (!(s->spurious_vec & APIC_SV_ENABLE))
342
 
        return;
343
 
    irrv = get_highest_priority_int(s->irr);
344
 
    if (irrv < 0)
345
 
        return;
346
 
    ppr = apic_get_ppr(s);
347
 
    if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
348
 
        return;
349
 
    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
350
 
}
351
 
 
352
 
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
353
 
{
354
 
    set_bit(s->irr, vector_num);
355
 
    if (trigger_mode)
356
 
        set_bit(s->tmr, vector_num);
357
 
    else
358
 
        reset_bit(s->tmr, vector_num);
359
 
    apic_update_irq(s);
360
 
}
361
 
 
362
 
static void apic_eoi(APICState *s)
363
 
{
364
 
    int isrv;
365
 
    isrv = get_highest_priority_int(s->isr);
366
 
    if (isrv < 0)
367
 
        return;
368
 
    reset_bit(s->isr, isrv);
369
 
    /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
370
 
            set the remote IRR bit for level triggered interrupts. */
371
 
    apic_update_irq(s);
372
 
}
373
 
 
374
 
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
375
 
                                      uint8_t dest, uint8_t dest_mode)
376
 
{
377
 
    APICState *apic_iter;
378
 
    int i;
379
 
 
380
 
    if (dest_mode == 0) {
381
 
        if (dest == 0xff) {
382
 
            memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t));
383
 
        } else {
384
 
            memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
385
 
            set_bit(deliver_bitmask, dest);
386
 
        }
387
 
    } else {
388
 
        /* XXX: cluster mode */
389
 
        memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
390
 
        for(i = 0; i < MAX_APICS; i++) {
391
 
            apic_iter = local_apics[i];
392
 
            if (apic_iter) {
393
 
                if (apic_iter->dest_mode == 0xf) {
394
 
                    if (dest & apic_iter->log_dest)
395
 
                        set_bit(deliver_bitmask, i);
396
 
                } else if (apic_iter->dest_mode == 0x0) {
397
 
                    if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) &&
398
 
                        (dest & apic_iter->log_dest & 0x0f)) {
399
 
                        set_bit(deliver_bitmask, i);
400
 
                    }
401
 
                }
402
 
            }
403
 
        }
404
 
    }
405
 
}
406
 
 
407
 
 
408
 
static void apic_init_ipi(APICState *s)
409
 
{
410
 
    int i;
411
 
 
412
 
    s->tpr = 0;
413
 
    s->spurious_vec = 0xff;
414
 
    s->log_dest = 0;
415
 
    s->dest_mode = 0xf;
416
 
    memset(s->isr, 0, sizeof(s->isr));
417
 
    memset(s->tmr, 0, sizeof(s->tmr));
418
 
    memset(s->irr, 0, sizeof(s->irr));
419
 
    for(i = 0; i < APIC_LVT_NB; i++)
420
 
        s->lvt[i] = 1 << 16; /* mask LVT */
421
 
    s->esr = 0;
422
 
    memset(s->icr, 0, sizeof(s->icr));
423
 
    s->divide_conf = 0;
424
 
    s->count_shift = 0;
425
 
    s->initial_count = 0;
426
 
    s->initial_count_load_time = 0;
427
 
    s->next_time = 0;
428
 
 
429
 
    cpu_reset(s->cpu_env);
430
 
 
431
 
    if (!(s->apicbase & MSR_IA32_APICBASE_BSP))
432
 
        s->cpu_env->halted = 1;
433
 
}
434
 
 
435
 
/* send a SIPI message to the CPU to start it */
436
 
static void apic_startup(APICState *s, int vector_num)
437
 
{
438
 
    CPUState *env = s->cpu_env;
439
 
    if (!env->halted)
440
 
        return;
441
 
    env->eip = 0;
442
 
    cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12,
443
 
                           0xffff, 0);
444
 
    env->halted = 0;
445
 
}
446
 
 
447
 
static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
448
 
                         uint8_t delivery_mode, uint8_t vector_num,
449
 
                         uint8_t polarity, uint8_t trigger_mode)
450
 
{
451
 
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
452
 
    int dest_shorthand = (s->icr[0] >> 18) & 3;
453
 
    APICState *apic_iter;
454
 
 
455
 
    switch (dest_shorthand) {
456
 
    case 0:
457
 
        apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
458
 
        break;
459
 
    case 1:
460
 
        memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
461
 
        set_bit(deliver_bitmask, s->id);
462
 
        break;
463
 
    case 2:
464
 
        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
465
 
        break;
466
 
    case 3:
467
 
        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
468
 
        reset_bit(deliver_bitmask, s->id);
469
 
        break;
470
 
    }
471
 
 
472
 
    switch (delivery_mode) {
473
 
        case APIC_DM_INIT:
474
 
            {
475
 
                int trig_mode = (s->icr[0] >> 15) & 1;
476
 
                int level = (s->icr[0] >> 14) & 1;
477
 
                if (level == 0 && trig_mode == 1) {
478
 
                    foreach_apic(apic_iter, deliver_bitmask,
479
 
                                 apic_iter->arb_id = apic_iter->id );
480
 
                    return;
481
 
                }
482
 
            }
483
 
            break;
484
 
 
485
 
        case APIC_DM_SIPI:
486
 
            foreach_apic(apic_iter, deliver_bitmask,
487
 
                         apic_startup(apic_iter, vector_num) );
488
 
            return;
489
 
    }
490
 
 
491
 
    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
492
 
                     trigger_mode);
493
 
}
494
 
 
495
 
int apic_get_interrupt(CPUState *env)
496
 
{
497
 
    APICState *s = env->apic_state;
498
 
    int intno;
499
 
 
500
 
    /* if the APIC is installed or enabled, we let the 8259 handle the
501
 
       IRQs */
502
 
    if (!s)
503
 
        return -1;
504
 
    if (!(s->spurious_vec & APIC_SV_ENABLE))
505
 
        return -1;
506
 
 
507
 
    /* XXX: spurious IRQ handling */
508
 
    intno = get_highest_priority_int(s->irr);
509
 
    if (intno < 0)
510
 
        return -1;
511
 
    if (s->tpr && intno <= s->tpr)
512
 
        return s->spurious_vec & 0xff;
513
 
    reset_bit(s->irr, intno);
514
 
    set_bit(s->isr, intno);
515
 
    apic_update_irq(s);
516
 
    return intno;
517
 
}
518
 
 
519
 
int apic_accept_pic_intr(CPUState *env)
520
 
{
521
 
    APICState *s = env->apic_state;
522
 
    uint32_t lvt0;
523
 
 
524
 
    if (!s)
525
 
        return -1;
526
 
 
527
 
    lvt0 = s->lvt[APIC_LVT_LINT0];
528
 
 
529
 
    if ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
530
 
        (lvt0 & APIC_LVT_MASKED) == 0)
531
 
        return 1;
532
 
 
533
 
    return 0;
534
 
}
535
 
 
536
 
static uint32_t apic_get_current_count(APICState *s)
537
 
{
538
 
    int64_t d;
539
 
    uint32_t val;
540
 
    d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >>
541
 
        s->count_shift;
542
 
    if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
543
 
        /* periodic */
544
 
        val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
545
 
    } else {
546
 
        if (d >= s->initial_count)
547
 
            val = 0;
548
 
        else
549
 
            val = s->initial_count - d;
550
 
    }
551
 
    return val;
552
 
}
553
 
 
554
 
static void apic_timer_update(APICState *s, int64_t current_time)
555
 
{
556
 
    int64_t next_time, d;
557
 
 
558
 
    if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
559
 
        d = (current_time - s->initial_count_load_time) >>
560
 
            s->count_shift;
561
 
        if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
562
 
            if (!s->initial_count)
563
 
                goto no_timer;
564
 
            d = ((d / ((uint64_t)s->initial_count + 1)) + 1) * ((uint64_t)s->initial_count + 1);
565
 
        } else {
566
 
            if (d >= s->initial_count)
567
 
                goto no_timer;
568
 
            d = (uint64_t)s->initial_count + 1;
569
 
        }
570
 
        next_time = s->initial_count_load_time + (d << s->count_shift);
571
 
        qemu_mod_timer(s->timer, next_time);
572
 
        s->next_time = next_time;
573
 
    } else {
574
 
    no_timer:
575
 
        qemu_del_timer(s->timer);
576
 
    }
577
 
}
578
 
 
579
 
static void apic_timer(void *opaque)
580
 
{
581
 
    APICState *s = opaque;
582
 
 
583
 
    apic_local_deliver(s->cpu_env, APIC_LVT_TIMER);
584
 
    apic_timer_update(s, s->next_time);
585
 
}
586
 
 
587
 
static uint32_t apic_mem_readb(void *opaque, target_phys_addr_t addr)
588
 
{
589
 
    return 0;
590
 
}
591
 
 
592
 
static uint32_t apic_mem_readw(void *opaque, target_phys_addr_t addr)
593
 
{
594
 
    return 0;
595
 
}
596
 
 
597
 
static void apic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
598
 
{
599
 
}
600
 
 
601
 
static void apic_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
602
 
{
603
 
}
604
 
 
605
 
static uint32_t apic_mem_readl(void *opaque, target_phys_addr_t addr)
606
 
{
607
 
    CPUState *env;
608
 
    APICState *s;
609
 
    uint32_t val;
610
 
    int index;
611
 
 
612
 
    env = cpu_single_env;
613
 
    if (!env)
614
 
        return 0;
615
 
    s = env->apic_state;
616
 
 
617
 
    index = (addr >> 4) & 0xff;
618
 
    switch(index) {
619
 
    case 0x02: /* id */
620
 
        val = s->id << 24;
621
 
        break;
622
 
    case 0x03: /* version */
623
 
        val = 0x11 | ((APIC_LVT_NB - 1) << 16); /* version 0x11 */
624
 
        break;
625
 
    case 0x08:
626
 
        val = s->tpr;
627
 
        break;
628
 
    case 0x09:
629
 
        val = apic_get_arb_pri(s);
630
 
        break;
631
 
    case 0x0a:
632
 
        /* ppr */
633
 
        val = apic_get_ppr(s);
634
 
        break;
635
 
    case 0x0b:
636
 
        val = 0;
637
 
        break;
638
 
    case 0x0d:
639
 
        val = s->log_dest << 24;
640
 
        break;
641
 
    case 0x0e:
642
 
        val = s->dest_mode << 28;
643
 
        break;
644
 
    case 0x0f:
645
 
        val = s->spurious_vec;
646
 
        break;
647
 
    case 0x10 ... 0x17:
648
 
        val = s->isr[index & 7];
649
 
        break;
650
 
    case 0x18 ... 0x1f:
651
 
        val = s->tmr[index & 7];
652
 
        break;
653
 
    case 0x20 ... 0x27:
654
 
        val = s->irr[index & 7];
655
 
        break;
656
 
    case 0x28:
657
 
        val = s->esr;
658
 
        break;
659
 
    case 0x30:
660
 
    case 0x31:
661
 
        val = s->icr[index & 1];
662
 
        break;
663
 
    case 0x32 ... 0x37:
664
 
        val = s->lvt[index - 0x32];
665
 
        break;
666
 
    case 0x38:
667
 
        val = s->initial_count;
668
 
        break;
669
 
    case 0x39:
670
 
        val = apic_get_current_count(s);
671
 
        break;
672
 
    case 0x3e:
673
 
        val = s->divide_conf;
674
 
        break;
675
 
    default:
676
 
        s->esr |= ESR_ILLEGAL_ADDRESS;
677
 
        val = 0;
678
 
        break;
679
 
    }
680
 
#ifdef DEBUG_APIC
681
 
    printf("APIC read: %08x = %08x\n", (uint32_t)addr, val);
682
 
#endif
683
 
    return val;
684
 
}
685
 
 
686
 
static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
687
 
{
688
 
    CPUState *env;
689
 
    APICState *s;
690
 
    int index;
691
 
 
692
 
    env = cpu_single_env;
693
 
    if (!env)
694
 
        return;
695
 
    s = env->apic_state;
696
 
 
697
 
#ifdef DEBUG_APIC
698
 
    printf("APIC write: %08x = %08x\n", (uint32_t)addr, val);
699
 
#endif
700
 
 
701
 
    index = (addr >> 4) & 0xff;
702
 
    switch(index) {
703
 
    case 0x02:
704
 
        s->id = (val >> 24);
705
 
        break;
706
 
    case 0x03:
707
 
        break;
708
 
    case 0x08:
709
 
        s->tpr = val;
710
 
        apic_update_irq(s);
711
 
        break;
712
 
    case 0x09:
713
 
    case 0x0a:
714
 
        break;
715
 
    case 0x0b: /* EOI */
716
 
        apic_eoi(s);
717
 
        break;
718
 
    case 0x0d:
719
 
        s->log_dest = val >> 24;
720
 
        break;
721
 
    case 0x0e:
722
 
        s->dest_mode = val >> 28;
723
 
        break;
724
 
    case 0x0f:
725
 
        s->spurious_vec = val & 0x1ff;
726
 
        apic_update_irq(s);
727
 
        break;
728
 
    case 0x10 ... 0x17:
729
 
    case 0x18 ... 0x1f:
730
 
    case 0x20 ... 0x27:
731
 
    case 0x28:
732
 
        break;
733
 
    case 0x30:
734
 
        s->icr[0] = val;
735
 
        apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
736
 
                     (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
737
 
                     (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
738
 
        break;
739
 
    case 0x31:
740
 
        s->icr[1] = val;
741
 
        break;
742
 
    case 0x32 ... 0x37:
743
 
        {
744
 
            int n = index - 0x32;
745
 
            s->lvt[n] = val;
746
 
            if (n == APIC_LVT_TIMER)
747
 
                apic_timer_update(s, qemu_get_clock(vm_clock));
748
 
        }
749
 
        break;
750
 
    case 0x38:
751
 
        s->initial_count = val;
752
 
        s->initial_count_load_time = qemu_get_clock(vm_clock);
753
 
        apic_timer_update(s, s->initial_count_load_time);
754
 
        break;
755
 
    case 0x39:
756
 
        break;
757
 
    case 0x3e:
758
 
        {
759
 
            int v;
760
 
            s->divide_conf = val & 0xb;
761
 
            v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
762
 
            s->count_shift = (v + 1) & 7;
763
 
        }
764
 
        break;
765
 
    default:
766
 
        s->esr |= ESR_ILLEGAL_ADDRESS;
767
 
        break;
768
 
    }
769
 
}
770
 
 
771
 
static void apic_save(QEMUFile *f, void *opaque)
772
 
{
773
 
    APICState *s = opaque;
774
 
    int i;
775
 
 
776
 
    qemu_put_be32s(f, &s->apicbase);
777
 
    qemu_put_8s(f, &s->id);
778
 
    qemu_put_8s(f, &s->arb_id);
779
 
    qemu_put_8s(f, &s->tpr);
780
 
    qemu_put_be32s(f, &s->spurious_vec);
781
 
    qemu_put_8s(f, &s->log_dest);
782
 
    qemu_put_8s(f, &s->dest_mode);
783
 
    for (i = 0; i < 8; i++) {
784
 
        qemu_put_be32s(f, &s->isr[i]);
785
 
        qemu_put_be32s(f, &s->tmr[i]);
786
 
        qemu_put_be32s(f, &s->irr[i]);
787
 
    }
788
 
    for (i = 0; i < APIC_LVT_NB; i++) {
789
 
        qemu_put_be32s(f, &s->lvt[i]);
790
 
    }
791
 
    qemu_put_be32s(f, &s->esr);
792
 
    qemu_put_be32s(f, &s->icr[0]);
793
 
    qemu_put_be32s(f, &s->icr[1]);
794
 
    qemu_put_be32s(f, &s->divide_conf);
795
 
    qemu_put_be32(f, s->count_shift);
796
 
    qemu_put_be32s(f, &s->initial_count);
797
 
    qemu_put_be64(f, s->initial_count_load_time);
798
 
    qemu_put_be64(f, s->next_time);
799
 
 
800
 
    qemu_put_timer(f, s->timer);
801
 
}
802
 
 
803
 
static int apic_load(QEMUFile *f, void *opaque, int version_id)
804
 
{
805
 
    APICState *s = opaque;
806
 
    int i;
807
 
 
808
 
    if (version_id > 2)
809
 
        return -EINVAL;
810
 
 
811
 
    /* XXX: what if the base changes? (registered memory regions) */
812
 
    qemu_get_be32s(f, &s->apicbase);
813
 
    qemu_get_8s(f, &s->id);
814
 
    qemu_get_8s(f, &s->arb_id);
815
 
    qemu_get_8s(f, &s->tpr);
816
 
    qemu_get_be32s(f, &s->spurious_vec);
817
 
    qemu_get_8s(f, &s->log_dest);
818
 
    qemu_get_8s(f, &s->dest_mode);
819
 
    for (i = 0; i < 8; i++) {
820
 
        qemu_get_be32s(f, &s->isr[i]);
821
 
        qemu_get_be32s(f, &s->tmr[i]);
822
 
        qemu_get_be32s(f, &s->irr[i]);
823
 
    }
824
 
    for (i = 0; i < APIC_LVT_NB; i++) {
825
 
        qemu_get_be32s(f, &s->lvt[i]);
826
 
    }
827
 
    qemu_get_be32s(f, &s->esr);
828
 
    qemu_get_be32s(f, &s->icr[0]);
829
 
    qemu_get_be32s(f, &s->icr[1]);
830
 
    qemu_get_be32s(f, &s->divide_conf);
831
 
    s->count_shift=qemu_get_be32(f);
832
 
    qemu_get_be32s(f, &s->initial_count);
833
 
    s->initial_count_load_time=qemu_get_be64(f);
834
 
    s->next_time=qemu_get_be64(f);
835
 
 
836
 
    if (version_id >= 2)
837
 
        qemu_get_timer(f, s->timer);
838
 
    return 0;
839
 
}
840
 
 
841
 
static void apic_reset(void *opaque)
842
 
{
843
 
    APICState *s = opaque;
844
 
 
845
 
    s->apicbase = 0xfee00000 |
846
 
        (s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
847
 
 
848
 
    apic_init_ipi(s);
849
 
 
850
 
    if (s->id == 0) {
851
 
        /*
852
 
         * LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
853
 
         * time typically by BIOS, so PIC interrupt can be delivered to the
854
 
         * processor when local APIC is enabled.
855
 
         */
856
 
        s->lvt[APIC_LVT_LINT0] = 0x700;
857
 
    }
858
 
}
859
 
 
860
 
static CPUReadMemoryFunc *apic_mem_read[3] = {
861
 
    apic_mem_readb,
862
 
    apic_mem_readw,
863
 
    apic_mem_readl,
864
 
};
865
 
 
866
 
static CPUWriteMemoryFunc *apic_mem_write[3] = {
867
 
    apic_mem_writeb,
868
 
    apic_mem_writew,
869
 
    apic_mem_writel,
870
 
};
871
 
 
872
 
int apic_init(CPUState *env)
873
 
{
874
 
    APICState *s;
875
 
 
876
 
    if (last_apic_id >= MAX_APICS)
877
 
        return -1;
878
 
    s = qemu_mallocz(sizeof(APICState));
879
 
    if (!s)
880
 
        return -1;
881
 
    env->apic_state = s;
882
 
    s->id = last_apic_id++;
883
 
    env->cpuid_apic_id = s->id;
884
 
    s->cpu_env = env;
885
 
 
886
 
    apic_reset(s);
887
 
 
888
 
    /* XXX: mapping more APICs at the same memory location */
889
 
    if (apic_io_memory == 0) {
890
 
        /* NOTE: the APIC is directly connected to the CPU - it is not
891
 
           on the global memory bus. */
892
 
        apic_io_memory = cpu_register_io_memory(0, apic_mem_read,
893
 
                                                apic_mem_write, NULL);
894
 
        cpu_register_physical_memory(s->apicbase & ~0xfff, 0x1000,
895
 
                                     apic_io_memory);
896
 
    }
897
 
    s->timer = qemu_new_timer(vm_clock, apic_timer, s);
898
 
 
899
 
    register_savevm("apic", s->id, 2, apic_save, apic_load, s);
900
 
    qemu_register_reset(apic_reset, s);
901
 
 
902
 
    local_apics[s->id] = s;
903
 
    return 0;
904
 
}
905
 
 
906
 
static void ioapic_service(IOAPICState *s)
907
 
{
908
 
    uint8_t i;
909
 
    uint8_t trig_mode;
910
 
    uint8_t vector;
911
 
    uint8_t delivery_mode;
912
 
    uint32_t mask;
913
 
    uint64_t entry;
914
 
    uint8_t dest;
915
 
    uint8_t dest_mode;
916
 
    uint8_t polarity;
917
 
    uint32_t deliver_bitmask[MAX_APIC_WORDS];
918
 
 
919
 
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
920
 
        mask = 1 << i;
921
 
        if (s->irr & mask) {
922
 
            entry = s->ioredtbl[i];
923
 
            if (!(entry & APIC_LVT_MASKED)) {
924
 
                trig_mode = ((entry >> 15) & 1);
925
 
                dest = entry >> 56;
926
 
                dest_mode = (entry >> 11) & 1;
927
 
                delivery_mode = (entry >> 8) & 7;
928
 
                polarity = (entry >> 13) & 1;
929
 
                if (trig_mode == APIC_TRIGGER_EDGE)
930
 
                    s->irr &= ~mask;
931
 
                if (delivery_mode == APIC_DM_EXTINT)
932
 
                    vector = pic_read_irq(isa_pic);
933
 
                else
934
 
                    vector = entry & 0xff;
935
 
 
936
 
                apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
937
 
                apic_bus_deliver(deliver_bitmask, delivery_mode,
938
 
                                 vector, polarity, trig_mode);
939
 
            }
940
 
        }
941
 
    }
942
 
}
943
 
 
944
 
void ioapic_set_irq(void *opaque, int vector, int level)
945
 
{
946
 
    IOAPICState *s = opaque;
947
 
 
948
 
    if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
949
 
        uint32_t mask = 1 << vector;
950
 
        uint64_t entry = s->ioredtbl[vector];
951
 
 
952
 
        if ((entry >> 15) & 1) {
953
 
            /* level triggered */
954
 
            if (level) {
955
 
                s->irr |= mask;
956
 
                ioapic_service(s);
957
 
            } else {
958
 
                s->irr &= ~mask;
959
 
            }
960
 
        } else {
961
 
            /* edge triggered */
962
 
            if (level) {
963
 
                s->irr |= mask;
964
 
                ioapic_service(s);
965
 
            }
966
 
        }
967
 
    }
968
 
}
969
 
 
970
 
static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
971
 
{
972
 
    IOAPICState *s = opaque;
973
 
    int index;
974
 
    uint32_t val = 0;
975
 
 
976
 
    addr &= 0xff;
977
 
    if (addr == 0x00) {
978
 
        val = s->ioregsel;
979
 
    } else if (addr == 0x10) {
980
 
        switch (s->ioregsel) {
981
 
            case 0x00:
982
 
                val = s->id << 24;
983
 
                break;
984
 
            case 0x01:
985
 
                val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */
986
 
                break;
987
 
            case 0x02:
988
 
                val = 0;
989
 
                break;
990
 
            default:
991
 
                index = (s->ioregsel - 0x10) >> 1;
992
 
                if (index >= 0 && index < IOAPIC_NUM_PINS) {
993
 
                    if (s->ioregsel & 1)
994
 
                        val = s->ioredtbl[index] >> 32;
995
 
                    else
996
 
                        val = s->ioredtbl[index] & 0xffffffff;
997
 
                }
998
 
        }
999
 
#ifdef DEBUG_IOAPIC
1000
 
        printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val);
1001
 
#endif
1002
 
    }
1003
 
    return val;
1004
 
}
1005
 
 
1006
 
static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1007
 
{
1008
 
    IOAPICState *s = opaque;
1009
 
    int index;
1010
 
 
1011
 
    addr &= 0xff;
1012
 
    if (addr == 0x00)  {
1013
 
        s->ioregsel = val;
1014
 
        return;
1015
 
    } else if (addr == 0x10) {
1016
 
#ifdef DEBUG_IOAPIC
1017
 
        printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val);
1018
 
#endif
1019
 
        switch (s->ioregsel) {
1020
 
            case 0x00:
1021
 
                s->id = (val >> 24) & 0xff;
1022
 
                return;
1023
 
            case 0x01:
1024
 
            case 0x02:
1025
 
                return;
1026
 
            default:
1027
 
                index = (s->ioregsel - 0x10) >> 1;
1028
 
                if (index >= 0 && index < IOAPIC_NUM_PINS) {
1029
 
                    if (s->ioregsel & 1) {
1030
 
                        s->ioredtbl[index] &= 0xffffffff;
1031
 
                        s->ioredtbl[index] |= (uint64_t)val << 32;
1032
 
                    } else {
1033
 
                        s->ioredtbl[index] &= ~0xffffffffULL;
1034
 
                        s->ioredtbl[index] |= val;
1035
 
                    }
1036
 
                    ioapic_service(s);
1037
 
                }
1038
 
        }
1039
 
    }
1040
 
}
1041
 
 
1042
 
static void ioapic_save(QEMUFile *f, void *opaque)
1043
 
{
1044
 
    IOAPICState *s = opaque;
1045
 
    int i;
1046
 
 
1047
 
    qemu_put_8s(f, &s->id);
1048
 
    qemu_put_8s(f, &s->ioregsel);
1049
 
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
1050
 
        qemu_put_be64s(f, &s->ioredtbl[i]);
1051
 
    }
1052
 
}
1053
 
 
1054
 
static int ioapic_load(QEMUFile *f, void *opaque, int version_id)
1055
 
{
1056
 
    IOAPICState *s = opaque;
1057
 
    int i;
1058
 
 
1059
 
    if (version_id != 1)
1060
 
        return -EINVAL;
1061
 
 
1062
 
    qemu_get_8s(f, &s->id);
1063
 
    qemu_get_8s(f, &s->ioregsel);
1064
 
    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
1065
 
        qemu_get_be64s(f, &s->ioredtbl[i]);
1066
 
    }
1067
 
    return 0;
1068
 
}
1069
 
 
1070
 
static void ioapic_reset(void *opaque)
1071
 
{
1072
 
    IOAPICState *s = opaque;
1073
 
    int i;
1074
 
 
1075
 
    memset(s, 0, sizeof(*s));
1076
 
    for(i = 0; i < IOAPIC_NUM_PINS; i++)
1077
 
        s->ioredtbl[i] = 1 << 16; /* mask LVT */
1078
 
}
1079
 
 
1080
 
static CPUReadMemoryFunc *ioapic_mem_read[3] = {
1081
 
    ioapic_mem_readl,
1082
 
    ioapic_mem_readl,
1083
 
    ioapic_mem_readl,
1084
 
};
1085
 
 
1086
 
static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
1087
 
    ioapic_mem_writel,
1088
 
    ioapic_mem_writel,
1089
 
    ioapic_mem_writel,
1090
 
};
1091
 
 
1092
 
IOAPICState *ioapic_init(void)
1093
 
{
1094
 
    IOAPICState *s;
1095
 
    int io_memory;
1096
 
 
1097
 
    s = qemu_mallocz(sizeof(IOAPICState));
1098
 
    if (!s)
1099
 
        return NULL;
1100
 
    ioapic_reset(s);
1101
 
    s->id = last_apic_id++;
1102
 
 
1103
 
    io_memory = cpu_register_io_memory(0, ioapic_mem_read,
1104
 
                                       ioapic_mem_write, s);
1105
 
    cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
1106
 
 
1107
 
    register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
1108
 
    qemu_register_reset(ioapic_reset, s);
1109
 
 
1110
 
    return s;
1111
 
}