~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to hw/apic.c

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno, Aurelien Jarno
  • Date: 2009-03-22 10:13:17 UTC
  • mfrom: (1.2.1 upstream) (6.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20090322101317-iigjtnu5qil35dtb
Tags: 0.10.1-1
[ Aurelien Jarno ]
* New upstream stable release:
  - patches/80_stable-branch.patch: remove.
* debian/control: 
  - Remove depends on proll.
  - Move depends on device-tree-compiler to build-depends.
  - Bump Standards-Version to 3.8.1 (no changes).
* patches/82_qemu-img_decimal.patch: new patch from upstream to make
  qemu-img accept sizes with decimal values (closes: bug#501400).

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 *
16
16
 * You should have received a copy of the GNU Lesser General Public
17
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
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
19
19
 */
20
20
#include "hw.h"
21
21
#include "pc.h"
22
22
#include "qemu-timer.h"
 
23
#include "host-utils.h"
23
24
 
24
25
//#define DEBUG_APIC
25
26
//#define DEBUG_IOAPIC
99
100
static int apic_io_memory;
100
101
static APICState *local_apics[MAX_APICS + 1];
101
102
static int last_apic_id = 0;
 
103
static int apic_irq_delivered;
 
104
 
102
105
 
103
106
static void apic_init_ipi(APICState *s);
104
107
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
105
108
static void apic_update_irq(APICState *s);
106
109
 
107
 
/* Find first bit starting from msb. Return 0 if value = 0 */
 
110
/* Find first bit starting from msb */
108
111
static int fls_bit(uint32_t value)
109
112
{
110
 
    unsigned int ret = 0;
111
 
 
112
 
#if defined(HOST_I386)
113
 
    __asm__ __volatile__ ("bsr %1, %0\n" : "+r" (ret) : "rm" (value));
114
 
    return ret;
115
 
#else
116
 
    if (value > 0xffff)
117
 
        value >>= 16, ret = 16;
118
 
    if (value > 0xff)
119
 
        value >>= 8, ret += 8;
120
 
    if (value > 0xf)
121
 
        value >>= 4, ret += 4;
122
 
    if (value > 0x3)
123
 
        value >>= 2, ret += 2;
124
 
    return ret + (value >> 1);
125
 
#endif
 
113
    return 31 - clz32(value);
126
114
}
127
115
 
128
 
/* Find first bit starting from lsb. Return 0 if value = 0 */
 
116
/* Find first bit starting from lsb */
129
117
static int ffs_bit(uint32_t value)
130
118
{
131
 
    unsigned int ret = 0;
132
 
 
133
 
#if defined(HOST_I386)
134
 
    __asm__ __volatile__ ("bsf %1, %0\n" : "+r" (ret) : "rm" (value));
135
 
    return ret;
136
 
#else
137
 
    if (!value)
138
 
        return 0;
139
 
    if (!(value & 0xffff))
140
 
        value >>= 16, ret = 16;
141
 
    if (!(value & 0xff))
142
 
        value >>= 8, ret += 8;
143
 
    if (!(value & 0xf))
144
 
        value >>= 4, ret += 4;
145
 
    if (!(value & 0x3))
146
 
        value >>= 2, ret += 2;
147
 
    if (!(value & 0x1))
148
 
        ret++;
149
 
    return ret;
150
 
#endif
 
119
    return ctz32(value);
151
120
}
152
121
 
153
122
static inline void set_bit(uint32_t *tab, int index)
166
135
    tab[i] &= ~mask;
167
136
}
168
137
 
 
138
static inline int get_bit(uint32_t *tab, int index)
 
139
{
 
140
    int i, mask;
 
141
    i = index >> 5;
 
142
    mask = 1 << (index & 0x1f);
 
143
    return !!(tab[i] & mask);
 
144
}
 
145
 
 
146
static void apic_local_deliver(CPUState *env, int vector)
 
147
{
 
148
    APICState *s = env->apic_state;
 
149
    uint32_t lvt = s->lvt[vector];
 
150
    int trigger_mode;
 
151
 
 
152
    if (lvt & APIC_LVT_MASKED)
 
153
        return;
 
154
 
 
155
    switch ((lvt >> 8) & 7) {
 
156
    case APIC_DM_SMI:
 
157
        cpu_interrupt(env, CPU_INTERRUPT_SMI);
 
158
        break;
 
159
 
 
160
    case APIC_DM_NMI:
 
161
        cpu_interrupt(env, CPU_INTERRUPT_NMI);
 
162
        break;
 
163
 
 
164
    case APIC_DM_EXTINT:
 
165
        cpu_interrupt(env, CPU_INTERRUPT_HARD);
 
166
        break;
 
167
 
 
168
    case APIC_DM_FIXED:
 
169
        trigger_mode = APIC_TRIGGER_EDGE;
 
170
        if ((vector == APIC_LVT_LINT0 || vector == APIC_LVT_LINT1) &&
 
171
            (lvt & APIC_LVT_LEVEL_TRIGGER))
 
172
            trigger_mode = APIC_TRIGGER_LEVEL;
 
173
        apic_set_irq(s, lvt & 0xff, trigger_mode);
 
174
    }
 
175
}
 
176
 
 
177
void apic_deliver_pic_intr(CPUState *env, int level)
 
178
{
 
179
    if (level)
 
180
        apic_local_deliver(env, APIC_LVT_LINT0);
 
181
    else {
 
182
        APICState *s = env->apic_state;
 
183
        uint32_t lvt = s->lvt[APIC_LVT_LINT0];
 
184
 
 
185
        switch ((lvt >> 8) & 7) {
 
186
        case APIC_DM_FIXED:
 
187
            if (!(lvt & APIC_LVT_LEVEL_TRIGGER))
 
188
                break;
 
189
            reset_bit(s->irr, lvt & 0xff);
 
190
            /* fall through */
 
191
        case APIC_DM_EXTINT:
 
192
            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 
193
            break;
 
194
        }
 
195
    }
 
196
}
 
197
 
169
198
#define foreach_apic(apic, deliver_bitmask, code) \
170
199
{\
171
200
    int __i, __j, __mask;\
216
245
            break;
217
246
 
218
247
        case APIC_DM_SMI:
 
248
            foreach_apic(apic_iter, deliver_bitmask,
 
249
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_SMI) );
 
250
            return;
 
251
 
219
252
        case APIC_DM_NMI:
220
 
            break;
 
253
            foreach_apic(apic_iter, deliver_bitmask,
 
254
                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_NMI) );
 
255
            return;
221
256
 
222
257
        case APIC_DM_INIT:
223
258
            /* normal INIT IPI sent to processors */
324
359
    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
325
360
}
326
361
 
 
362
void apic_reset_irq_delivered(void)
 
363
{
 
364
    apic_irq_delivered = 0;
 
365
}
 
366
 
 
367
int apic_get_irq_delivered(void)
 
368
{
 
369
    return apic_irq_delivered;
 
370
}
 
371
 
327
372
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
328
373
{
 
374
    apic_irq_delivered += !get_bit(s->irr, vector_num);
 
375
 
329
376
    set_bit(s->irr, vector_num);
330
377
    if (trigger_mode)
331
378
        set_bit(s->tmr, vector_num);
400
447
    s->initial_count = 0;
401
448
    s->initial_count_load_time = 0;
402
449
    s->next_time = 0;
 
450
 
 
451
    cpu_reset(s->cpu_env);
 
452
 
 
453
    if (!(s->apicbase & MSR_IA32_APICBASE_BSP))
 
454
        s->cpu_env->halted = 1;
403
455
}
404
456
 
405
457
/* send a SIPI message to the CPU to start it */
406
458
static void apic_startup(APICState *s, int vector_num)
407
459
{
408
460
    CPUState *env = s->cpu_env;
409
 
    if (!(env->hflags & HF_HALTED_MASK))
 
461
    if (!env->halted)
410
462
        return;
411
463
    env->eip = 0;
412
464
    cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12,
413
465
                           0xffff, 0);
414
 
    env->hflags &= ~HF_HALTED_MASK;
 
466
    env->halted = 0;
415
467
}
416
468
 
417
469
static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
496
548
 
497
549
    lvt0 = s->lvt[APIC_LVT_LINT0];
498
550
 
499
 
    if (s->id == 0 &&
500
 
        ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
501
 
         ((lvt0 & APIC_LVT_MASKED) == 0 &&
502
 
          ((lvt0 >> 8) & 0x7) == APIC_DM_EXTINT)))
 
551
    if ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
 
552
        (lvt0 & APIC_LVT_MASKED) == 0)
503
553
        return 1;
504
554
 
505
555
    return 0;
531
581
        d = (current_time - s->initial_count_load_time) >>
532
582
            s->count_shift;
533
583
        if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
 
584
            if (!s->initial_count)
 
585
                goto no_timer;
534
586
            d = ((d / ((uint64_t)s->initial_count + 1)) + 1) * ((uint64_t)s->initial_count + 1);
535
587
        } else {
536
588
            if (d >= s->initial_count)
550
602
{
551
603
    APICState *s = opaque;
552
604
 
553
 
    if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
554
 
        apic_set_irq(s, s->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);
555
 
    }
 
605
    apic_local_deliver(s->cpu_env, APIC_LVT_TIMER);
556
606
    apic_timer_update(s, s->next_time);
557
607
}
558
608
 
604
654
        /* ppr */
605
655
        val = apic_get_ppr(s);
606
656
        break;
 
657
    case 0x0b:
 
658
        val = 0;
 
659
        break;
607
660
    case 0x0d:
608
661
        val = s->log_dest << 24;
609
662
        break;
810
863
static void apic_reset(void *opaque)
811
864
{
812
865
    APICState *s = opaque;
 
866
 
 
867
    s->apicbase = 0xfee00000 |
 
868
        (s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
 
869
 
813
870
    apic_init_ipi(s);
814
871
 
815
 
    /*
816
 
     * LINT0 delivery mode is set to ExtInt at initialization time
817
 
     * typically by BIOS, so PIC interrupt can be delivered to the
818
 
     * processor when local APIC is enabled.
819
 
     */
820
 
    s->lvt[APIC_LVT_LINT0] = 0x700;
 
872
    if (s->id == 0) {
 
873
        /*
 
874
         * LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
 
875
         * time typically by BIOS, so PIC interrupt can be delivered to the
 
876
         * processor when local APIC is enabled.
 
877
         */
 
878
        s->lvt[APIC_LVT_LINT0] = 0x700;
 
879
    }
821
880
}
822
881
 
823
882
static CPUReadMemoryFunc *apic_mem_read[3] = {
839
898
    if (last_apic_id >= MAX_APICS)
840
899
        return -1;
841
900
    s = qemu_mallocz(sizeof(APICState));
842
 
    if (!s)
843
 
        return -1;
844
901
    env->apic_state = s;
845
 
    apic_init_ipi(s);
846
902
    s->id = last_apic_id++;
847
903
    env->cpuid_apic_id = s->id;
848
904
    s->cpu_env = env;
849
 
    s->apicbase = 0xfee00000 |
850
 
        (s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
851
905
 
852
 
    /*
853
 
     * LINT0 delivery mode is set to ExtInt at initialization time
854
 
     * typically by BIOS, so PIC interrupt can be delivered to the
855
 
     * processor when local APIC is enabled.
856
 
     */
857
 
    s->lvt[APIC_LVT_LINT0] = 0x700;
 
906
    apic_reset(s);
858
907
 
859
908
    /* XXX: mapping more APICs at the same memory location */
860
909
    if (apic_io_memory == 0) {
916
965
{
917
966
    IOAPICState *s = opaque;
918
967
 
 
968
    /* ISA IRQs map to GSI 1-1 except for IRQ0 which maps
 
969
     * to GSI 2.  GSI maps to ioapic 1-1.  This is not
 
970
     * the cleanest way of doing it but it should work. */
 
971
 
 
972
    if (vector == 0)
 
973
        vector = 2;
 
974
 
919
975
    if (vector >= 0 && vector < IOAPIC_NUM_PINS) {
920
976
        uint32_t mask = 1 << vector;
921
977
        uint64_t entry = s->ioredtbl[vector];
1066
1122
    int io_memory;
1067
1123
 
1068
1124
    s = qemu_mallocz(sizeof(IOAPICState));
1069
 
    if (!s)
1070
 
        return NULL;
1071
1125
    ioapic_reset(s);
1072
1126
    s->id = last_apic_id++;
1073
1127