cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

apic.c (24554B)


      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.1 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, see <http://www.gnu.org/licenses/>
     18 */
     19#include "qemu/osdep.h"
     20#include "qemu/thread.h"
     21#include "hw/i386/apic_internal.h"
     22#include "hw/i386/apic.h"
     23#include "hw/i386/ioapic.h"
     24#include "hw/intc/i8259.h"
     25#include "hw/pci/msi.h"
     26#include "qemu/host-utils.h"
     27#include "sysemu/kvm.h"
     28#include "trace.h"
     29#include "hw/i386/apic-msidef.h"
     30#include "qapi/error.h"
     31#include "qom/object.h"
     32
     33#define MAX_APICS 255
     34#define MAX_APIC_WORDS 8
     35
     36#define SYNC_FROM_VAPIC                 0x1
     37#define SYNC_TO_VAPIC                   0x2
     38#define SYNC_ISR_IRR_TO_VAPIC           0x4
     39
     40static APICCommonState *local_apics[MAX_APICS + 1];
     41
     42#define TYPE_APIC "apic"
     43/*This is reusing the APICCommonState typedef from APIC_COMMON */
     44DECLARE_INSTANCE_CHECKER(APICCommonState, APIC,
     45                         TYPE_APIC)
     46
     47static void apic_set_irq(APICCommonState *s, int vector_num, int trigger_mode);
     48static void apic_update_irq(APICCommonState *s);
     49static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
     50                                      uint8_t dest, uint8_t dest_mode);
     51
     52/* Find first bit starting from msb */
     53static int apic_fls_bit(uint32_t value)
     54{
     55    return 31 - clz32(value);
     56}
     57
     58/* Find first bit starting from lsb */
     59static int apic_ffs_bit(uint32_t value)
     60{
     61    return ctz32(value);
     62}
     63
     64static inline void apic_reset_bit(uint32_t *tab, int index)
     65{
     66    int i, mask;
     67    i = index >> 5;
     68    mask = 1 << (index & 0x1f);
     69    tab[i] &= ~mask;
     70}
     71
     72/* return -1 if no bit is set */
     73static int get_highest_priority_int(uint32_t *tab)
     74{
     75    int i;
     76    for (i = 7; i >= 0; i--) {
     77        if (tab[i] != 0) {
     78            return i * 32 + apic_fls_bit(tab[i]);
     79        }
     80    }
     81    return -1;
     82}
     83
     84static void apic_sync_vapic(APICCommonState *s, int sync_type)
     85{
     86    VAPICState vapic_state;
     87    size_t length;
     88    off_t start;
     89    int vector;
     90
     91    if (!s->vapic_paddr) {
     92        return;
     93    }
     94    if (sync_type & SYNC_FROM_VAPIC) {
     95        cpu_physical_memory_read(s->vapic_paddr, &vapic_state,
     96                                 sizeof(vapic_state));
     97        s->tpr = vapic_state.tpr;
     98    }
     99    if (sync_type & (SYNC_TO_VAPIC | SYNC_ISR_IRR_TO_VAPIC)) {
    100        start = offsetof(VAPICState, isr);
    101        length = offsetof(VAPICState, enabled) - offsetof(VAPICState, isr);
    102
    103        if (sync_type & SYNC_TO_VAPIC) {
    104            assert(qemu_cpu_is_self(CPU(s->cpu)));
    105
    106            vapic_state.tpr = s->tpr;
    107            vapic_state.enabled = 1;
    108            start = 0;
    109            length = sizeof(VAPICState);
    110        }
    111
    112        vector = get_highest_priority_int(s->isr);
    113        if (vector < 0) {
    114            vector = 0;
    115        }
    116        vapic_state.isr = vector & 0xf0;
    117
    118        vapic_state.zero = 0;
    119
    120        vector = get_highest_priority_int(s->irr);
    121        if (vector < 0) {
    122            vector = 0;
    123        }
    124        vapic_state.irr = vector & 0xff;
    125
    126        address_space_write_rom(&address_space_memory,
    127                                s->vapic_paddr + start,
    128                                MEMTXATTRS_UNSPECIFIED,
    129                                ((void *)&vapic_state) + start, length);
    130    }
    131}
    132
    133static void apic_vapic_base_update(APICCommonState *s)
    134{
    135    apic_sync_vapic(s, SYNC_TO_VAPIC);
    136}
    137
    138static void apic_local_deliver(APICCommonState *s, int vector)
    139{
    140    uint32_t lvt = s->lvt[vector];
    141    int trigger_mode;
    142
    143    trace_apic_local_deliver(vector, (lvt >> 8) & 7);
    144
    145    if (lvt & APIC_LVT_MASKED)
    146        return;
    147
    148    switch ((lvt >> 8) & 7) {
    149    case APIC_DM_SMI:
    150        cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_SMI);
    151        break;
    152
    153    case APIC_DM_NMI:
    154        cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_NMI);
    155        break;
    156
    157    case APIC_DM_EXTINT:
    158        cpu_interrupt(CPU(s->cpu), 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
    170void apic_deliver_pic_intr(DeviceState *dev, int level)
    171{
    172    APICCommonState *s = APIC(dev);
    173
    174    if (level) {
    175        apic_local_deliver(s, APIC_LVT_LINT0);
    176    } else {
    177        uint32_t lvt = s->lvt[APIC_LVT_LINT0];
    178
    179        switch ((lvt >> 8) & 7) {
    180        case APIC_DM_FIXED:
    181            if (!(lvt & APIC_LVT_LEVEL_TRIGGER))
    182                break;
    183            apic_reset_bit(s->irr, lvt & 0xff);
    184            /* fall through */
    185        case APIC_DM_EXTINT:
    186            apic_update_irq(s);
    187            break;
    188        }
    189    }
    190}
    191
    192static void apic_external_nmi(APICCommonState *s)
    193{
    194    apic_local_deliver(s, APIC_LVT_LINT1);
    195}
    196
    197#define foreach_apic(apic, deliver_bitmask, code) \
    198{\
    199    int __i, __j;\
    200    for(__i = 0; __i < MAX_APIC_WORDS; __i++) {\
    201        uint32_t __mask = deliver_bitmask[__i];\
    202        if (__mask) {\
    203            for(__j = 0; __j < 32; __j++) {\
    204                if (__mask & (1U << __j)) {\
    205                    apic = local_apics[__i * 32 + __j];\
    206                    if (apic) {\
    207                        code;\
    208                    }\
    209                }\
    210            }\
    211        }\
    212    }\
    213}
    214
    215static void apic_bus_deliver(const uint32_t *deliver_bitmask,
    216                             uint8_t delivery_mode, uint8_t vector_num,
    217                             uint8_t trigger_mode)
    218{
    219    APICCommonState *apic_iter;
    220
    221    switch (delivery_mode) {
    222        case APIC_DM_LOWPRI:
    223            /* XXX: search for focus processor, arbitration */
    224            {
    225                int i, d;
    226                d = -1;
    227                for(i = 0; i < MAX_APIC_WORDS; i++) {
    228                    if (deliver_bitmask[i]) {
    229                        d = i * 32 + apic_ffs_bit(deliver_bitmask[i]);
    230                        break;
    231                    }
    232                }
    233                if (d >= 0) {
    234                    apic_iter = local_apics[d];
    235                    if (apic_iter) {
    236                        apic_set_irq(apic_iter, vector_num, trigger_mode);
    237                    }
    238                }
    239            }
    240            return;
    241
    242        case APIC_DM_FIXED:
    243            break;
    244
    245        case APIC_DM_SMI:
    246            foreach_apic(apic_iter, deliver_bitmask,
    247                cpu_interrupt(CPU(apic_iter->cpu), CPU_INTERRUPT_SMI)
    248            );
    249            return;
    250
    251        case APIC_DM_NMI:
    252            foreach_apic(apic_iter, deliver_bitmask,
    253                cpu_interrupt(CPU(apic_iter->cpu), CPU_INTERRUPT_NMI)
    254            );
    255            return;
    256
    257        case APIC_DM_INIT:
    258            /* normal INIT IPI sent to processors */
    259            foreach_apic(apic_iter, deliver_bitmask,
    260                         cpu_interrupt(CPU(apic_iter->cpu),
    261                                       CPU_INTERRUPT_INIT)
    262            );
    263            return;
    264
    265        case APIC_DM_EXTINT:
    266            /* handled in I/O APIC code */
    267            break;
    268
    269        default:
    270            return;
    271    }
    272
    273    foreach_apic(apic_iter, deliver_bitmask,
    274                 apic_set_irq(apic_iter, vector_num, trigger_mode) );
    275}
    276
    277void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode,
    278                      uint8_t vector_num, uint8_t trigger_mode)
    279{
    280    uint32_t deliver_bitmask[MAX_APIC_WORDS];
    281
    282    trace_apic_deliver_irq(dest, dest_mode, delivery_mode, vector_num,
    283                           trigger_mode);
    284
    285    apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
    286    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, trigger_mode);
    287}
    288
    289static void apic_set_base(APICCommonState *s, uint64_t val)
    290{
    291    s->apicbase = (val & 0xfffff000) |
    292        (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
    293    /* if disabled, cannot be enabled again */
    294    if (!(val & MSR_IA32_APICBASE_ENABLE)) {
    295        s->apicbase &= ~MSR_IA32_APICBASE_ENABLE;
    296        cpu_clear_apic_feature(&s->cpu->env);
    297        s->spurious_vec &= ~APIC_SV_ENABLE;
    298    }
    299}
    300
    301static void apic_set_tpr(APICCommonState *s, uint8_t val)
    302{
    303    /* Updates from cr8 are ignored while the VAPIC is active */
    304    if (!s->vapic_paddr) {
    305        s->tpr = val << 4;
    306        apic_update_irq(s);
    307    }
    308}
    309
    310int apic_get_highest_priority_irr(DeviceState *dev)
    311{
    312    APICCommonState *s;
    313
    314    if (!dev) {
    315        /* no interrupts */
    316        return -1;
    317    }
    318    s = APIC_COMMON(dev);
    319    return get_highest_priority_int(s->irr);
    320}
    321
    322static uint8_t apic_get_tpr(APICCommonState *s)
    323{
    324    apic_sync_vapic(s, SYNC_FROM_VAPIC);
    325    return s->tpr >> 4;
    326}
    327
    328int apic_get_ppr(APICCommonState *s)
    329{
    330    int tpr, isrv, ppr;
    331
    332    tpr = (s->tpr >> 4);
    333    isrv = get_highest_priority_int(s->isr);
    334    if (isrv < 0)
    335        isrv = 0;
    336    isrv >>= 4;
    337    if (tpr >= isrv)
    338        ppr = s->tpr;
    339    else
    340        ppr = isrv << 4;
    341    return ppr;
    342}
    343
    344static int apic_get_arb_pri(APICCommonState *s)
    345{
    346    /* XXX: arbitration */
    347    return 0;
    348}
    349
    350
    351/*
    352 * <0 - low prio interrupt,
    353 * 0  - no interrupt,
    354 * >0 - interrupt number
    355 */
    356static int apic_irq_pending(APICCommonState *s)
    357{
    358    int irrv, ppr;
    359
    360    if (!(s->spurious_vec & APIC_SV_ENABLE)) {
    361        return 0;
    362    }
    363
    364    irrv = get_highest_priority_int(s->irr);
    365    if (irrv < 0) {
    366        return 0;
    367    }
    368    ppr = apic_get_ppr(s);
    369    if (ppr && (irrv & 0xf0) <= (ppr & 0xf0)) {
    370        return -1;
    371    }
    372
    373    return irrv;
    374}
    375
    376/* signal the CPU if an irq is pending */
    377static void apic_update_irq(APICCommonState *s)
    378{
    379    CPUState *cpu;
    380    DeviceState *dev = (DeviceState *)s;
    381
    382    cpu = CPU(s->cpu);
    383    if (!qemu_cpu_is_self(cpu)) {
    384        cpu_interrupt(cpu, CPU_INTERRUPT_POLL);
    385    } else if (apic_irq_pending(s) > 0) {
    386        cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
    387    } else if (!apic_accept_pic_intr(dev) || !pic_get_output(isa_pic)) {
    388        cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
    389    }
    390}
    391
    392void apic_poll_irq(DeviceState *dev)
    393{
    394    APICCommonState *s = APIC(dev);
    395
    396    apic_sync_vapic(s, SYNC_FROM_VAPIC);
    397    apic_update_irq(s);
    398}
    399
    400static void apic_set_irq(APICCommonState *s, int vector_num, int trigger_mode)
    401{
    402    apic_report_irq_delivered(!apic_get_bit(s->irr, vector_num));
    403
    404    apic_set_bit(s->irr, vector_num);
    405    if (trigger_mode)
    406        apic_set_bit(s->tmr, vector_num);
    407    else
    408        apic_reset_bit(s->tmr, vector_num);
    409    if (s->vapic_paddr) {
    410        apic_sync_vapic(s, SYNC_ISR_IRR_TO_VAPIC);
    411        /*
    412         * The vcpu thread needs to see the new IRR before we pull its current
    413         * TPR value. That way, if we miss a lowering of the TRP, the guest
    414         * has the chance to notice the new IRR and poll for IRQs on its own.
    415         */
    416        smp_wmb();
    417        apic_sync_vapic(s, SYNC_FROM_VAPIC);
    418    }
    419    apic_update_irq(s);
    420}
    421
    422static void apic_eoi(APICCommonState *s)
    423{
    424    int isrv;
    425    isrv = get_highest_priority_int(s->isr);
    426    if (isrv < 0)
    427        return;
    428    apic_reset_bit(s->isr, isrv);
    429    if (!(s->spurious_vec & APIC_SV_DIRECTED_IO) && apic_get_bit(s->tmr, isrv)) {
    430        ioapic_eoi_broadcast(isrv);
    431    }
    432    apic_sync_vapic(s, SYNC_FROM_VAPIC | SYNC_TO_VAPIC);
    433    apic_update_irq(s);
    434}
    435
    436static int apic_find_dest(uint8_t dest)
    437{
    438    APICCommonState *apic = local_apics[dest];
    439    int i;
    440
    441    if (apic && apic->id == dest)
    442        return dest;  /* shortcut in case apic->id == local_apics[dest]->id */
    443
    444    for (i = 0; i < MAX_APICS; i++) {
    445        apic = local_apics[i];
    446        if (apic && apic->id == dest)
    447            return i;
    448        if (!apic)
    449            break;
    450    }
    451
    452    return -1;
    453}
    454
    455static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
    456                                      uint8_t dest, uint8_t dest_mode)
    457{
    458    APICCommonState *apic_iter;
    459    int i;
    460
    461    if (dest_mode == 0) {
    462        if (dest == 0xff) {
    463            memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t));
    464        } else {
    465            int idx = apic_find_dest(dest);
    466            memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
    467            if (idx >= 0)
    468                apic_set_bit(deliver_bitmask, idx);
    469        }
    470    } else {
    471        /* XXX: cluster mode */
    472        memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
    473        for(i = 0; i < MAX_APICS; i++) {
    474            apic_iter = local_apics[i];
    475            if (apic_iter) {
    476                if (apic_iter->dest_mode == 0xf) {
    477                    if (dest & apic_iter->log_dest)
    478                        apic_set_bit(deliver_bitmask, i);
    479                } else if (apic_iter->dest_mode == 0x0) {
    480                    if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) &&
    481                        (dest & apic_iter->log_dest & 0x0f)) {
    482                        apic_set_bit(deliver_bitmask, i);
    483                    }
    484                }
    485            } else {
    486                break;
    487            }
    488        }
    489    }
    490}
    491
    492static void apic_startup(APICCommonState *s, int vector_num)
    493{
    494    s->sipi_vector = vector_num;
    495    cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI);
    496}
    497
    498void apic_sipi(DeviceState *dev)
    499{
    500    APICCommonState *s = APIC(dev);
    501
    502    cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI);
    503
    504    if (!s->wait_for_sipi)
    505        return;
    506    cpu_x86_load_seg_cache_sipi(s->cpu, s->sipi_vector);
    507    s->wait_for_sipi = 0;
    508}
    509
    510static void apic_deliver(DeviceState *dev, uint8_t dest, uint8_t dest_mode,
    511                         uint8_t delivery_mode, uint8_t vector_num,
    512                         uint8_t trigger_mode)
    513{
    514    APICCommonState *s = APIC(dev);
    515    uint32_t deliver_bitmask[MAX_APIC_WORDS];
    516    int dest_shorthand = (s->icr[0] >> 18) & 3;
    517    APICCommonState *apic_iter;
    518
    519    switch (dest_shorthand) {
    520    case 0:
    521        apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
    522        break;
    523    case 1:
    524        memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
    525        apic_set_bit(deliver_bitmask, s->id);
    526        break;
    527    case 2:
    528        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
    529        break;
    530    case 3:
    531        memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
    532        apic_reset_bit(deliver_bitmask, s->id);
    533        break;
    534    }
    535
    536    switch (delivery_mode) {
    537        case APIC_DM_INIT:
    538            {
    539                int trig_mode = (s->icr[0] >> 15) & 1;
    540                int level = (s->icr[0] >> 14) & 1;
    541                if (level == 0 && trig_mode == 1) {
    542                    foreach_apic(apic_iter, deliver_bitmask,
    543                                 apic_iter->arb_id = apic_iter->id );
    544                    return;
    545                }
    546            }
    547            break;
    548
    549        case APIC_DM_SIPI:
    550            foreach_apic(apic_iter, deliver_bitmask,
    551                         apic_startup(apic_iter, vector_num) );
    552            return;
    553    }
    554
    555    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, trigger_mode);
    556}
    557
    558static bool apic_check_pic(APICCommonState *s)
    559{
    560    DeviceState *dev = (DeviceState *)s;
    561
    562    if (!apic_accept_pic_intr(dev) || !pic_get_output(isa_pic)) {
    563        return false;
    564    }
    565    apic_deliver_pic_intr(dev, 1);
    566    return true;
    567}
    568
    569int apic_get_interrupt(DeviceState *dev)
    570{
    571    APICCommonState *s = APIC(dev);
    572    int intno;
    573
    574    /* if the APIC is installed or enabled, we let the 8259 handle the
    575       IRQs */
    576    if (!s)
    577        return -1;
    578    if (!(s->spurious_vec & APIC_SV_ENABLE))
    579        return -1;
    580
    581    apic_sync_vapic(s, SYNC_FROM_VAPIC);
    582    intno = apic_irq_pending(s);
    583
    584    /* if there is an interrupt from the 8259, let the caller handle
    585     * that first since ExtINT interrupts ignore the priority.
    586     */
    587    if (intno == 0 || apic_check_pic(s)) {
    588        apic_sync_vapic(s, SYNC_TO_VAPIC);
    589        return -1;
    590    } else if (intno < 0) {
    591        apic_sync_vapic(s, SYNC_TO_VAPIC);
    592        return s->spurious_vec & 0xff;
    593    }
    594    apic_reset_bit(s->irr, intno);
    595    apic_set_bit(s->isr, intno);
    596    apic_sync_vapic(s, SYNC_TO_VAPIC);
    597
    598    apic_update_irq(s);
    599
    600    return intno;
    601}
    602
    603int apic_accept_pic_intr(DeviceState *dev)
    604{
    605    APICCommonState *s = APIC(dev);
    606    uint32_t lvt0;
    607
    608    if (!s)
    609        return -1;
    610
    611    lvt0 = s->lvt[APIC_LVT_LINT0];
    612
    613    if ((s->apicbase & MSR_IA32_APICBASE_ENABLE) == 0 ||
    614        (lvt0 & APIC_LVT_MASKED) == 0)
    615        return isa_pic != NULL;
    616
    617    return 0;
    618}
    619
    620static void apic_timer_update(APICCommonState *s, int64_t current_time)
    621{
    622    if (apic_next_timer(s, current_time)) {
    623        timer_mod(s->timer, s->next_time);
    624    } else {
    625        timer_del(s->timer);
    626    }
    627}
    628
    629static void apic_timer(void *opaque)
    630{
    631    APICCommonState *s = opaque;
    632
    633    apic_local_deliver(s, APIC_LVT_TIMER);
    634    apic_timer_update(s, s->next_time);
    635}
    636
    637static uint64_t apic_mem_read(void *opaque, hwaddr addr, unsigned size)
    638{
    639    DeviceState *dev;
    640    APICCommonState *s;
    641    uint32_t val;
    642    int index;
    643
    644    if (size < 4) {
    645        return 0;
    646    }
    647
    648    dev = cpu_get_current_apic();
    649    if (!dev) {
    650        return 0;
    651    }
    652    s = APIC(dev);
    653
    654    index = (addr >> 4) & 0xff;
    655    switch(index) {
    656    case 0x02: /* id */
    657        val = s->id << 24;
    658        break;
    659    case 0x03: /* version */
    660        val = s->version | ((APIC_LVT_NB - 1) << 16);
    661        break;
    662    case 0x08:
    663        apic_sync_vapic(s, SYNC_FROM_VAPIC);
    664        if (apic_report_tpr_access) {
    665            cpu_report_tpr_access(&s->cpu->env, TPR_ACCESS_READ);
    666        }
    667        val = s->tpr;
    668        break;
    669    case 0x09:
    670        val = apic_get_arb_pri(s);
    671        break;
    672    case 0x0a:
    673        /* ppr */
    674        val = apic_get_ppr(s);
    675        break;
    676    case 0x0b:
    677        val = 0;
    678        break;
    679    case 0x0d:
    680        val = s->log_dest << 24;
    681        break;
    682    case 0x0e:
    683        val = (s->dest_mode << 28) | 0xfffffff;
    684        break;
    685    case 0x0f:
    686        val = s->spurious_vec;
    687        break;
    688    case 0x10 ... 0x17:
    689        val = s->isr[index & 7];
    690        break;
    691    case 0x18 ... 0x1f:
    692        val = s->tmr[index & 7];
    693        break;
    694    case 0x20 ... 0x27:
    695        val = s->irr[index & 7];
    696        break;
    697    case 0x28:
    698        val = s->esr;
    699        break;
    700    case 0x30:
    701    case 0x31:
    702        val = s->icr[index & 1];
    703        break;
    704    case 0x32 ... 0x37:
    705        val = s->lvt[index - 0x32];
    706        break;
    707    case 0x38:
    708        val = s->initial_count;
    709        break;
    710    case 0x39:
    711        val = apic_get_current_count(s);
    712        break;
    713    case 0x3e:
    714        val = s->divide_conf;
    715        break;
    716    default:
    717        s->esr |= APIC_ESR_ILLEGAL_ADDRESS;
    718        val = 0;
    719        break;
    720    }
    721    trace_apic_mem_readl(addr, val);
    722    return val;
    723}
    724
    725static void apic_send_msi(MSIMessage *msi)
    726{
    727    uint64_t addr = msi->address;
    728    uint32_t data = msi->data;
    729    uint8_t dest = (addr & MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
    730    uint8_t vector = (data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT;
    731    uint8_t dest_mode = (addr >> MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
    732    uint8_t trigger_mode = (data >> MSI_DATA_TRIGGER_SHIFT) & 0x1;
    733    uint8_t delivery = (data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
    734    /* XXX: Ignore redirection hint. */
    735    apic_deliver_irq(dest, dest_mode, delivery, vector, trigger_mode);
    736}
    737
    738static void apic_mem_write(void *opaque, hwaddr addr, uint64_t val,
    739                           unsigned size)
    740{
    741    DeviceState *dev;
    742    APICCommonState *s;
    743    int index = (addr >> 4) & 0xff;
    744
    745    if (size < 4) {
    746        return;
    747    }
    748
    749    if (addr > 0xfff || !index) {
    750        /* MSI and MMIO APIC are at the same memory location,
    751         * but actually not on the global bus: MSI is on PCI bus
    752         * APIC is connected directly to the CPU.
    753         * Mapping them on the global bus happens to work because
    754         * MSI registers are reserved in APIC MMIO and vice versa. */
    755        MSIMessage msi = { .address = addr, .data = val };
    756        apic_send_msi(&msi);
    757        return;
    758    }
    759
    760    dev = cpu_get_current_apic();
    761    if (!dev) {
    762        return;
    763    }
    764    s = APIC(dev);
    765
    766    trace_apic_mem_writel(addr, val);
    767
    768    switch(index) {
    769    case 0x02:
    770        s->id = (val >> 24);
    771        break;
    772    case 0x03:
    773        break;
    774    case 0x08:
    775        if (apic_report_tpr_access) {
    776            cpu_report_tpr_access(&s->cpu->env, TPR_ACCESS_WRITE);
    777        }
    778        s->tpr = val;
    779        apic_sync_vapic(s, SYNC_TO_VAPIC);
    780        apic_update_irq(s);
    781        break;
    782    case 0x09:
    783    case 0x0a:
    784        break;
    785    case 0x0b: /* EOI */
    786        apic_eoi(s);
    787        break;
    788    case 0x0d:
    789        s->log_dest = val >> 24;
    790        break;
    791    case 0x0e:
    792        s->dest_mode = val >> 28;
    793        break;
    794    case 0x0f:
    795        s->spurious_vec = val & 0x1ff;
    796        apic_update_irq(s);
    797        break;
    798    case 0x10 ... 0x17:
    799    case 0x18 ... 0x1f:
    800    case 0x20 ... 0x27:
    801    case 0x28:
    802        break;
    803    case 0x30:
    804        s->icr[0] = val;
    805        apic_deliver(dev, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
    806                     (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
    807                     (s->icr[0] >> 15) & 1);
    808        break;
    809    case 0x31:
    810        s->icr[1] = val;
    811        break;
    812    case 0x32 ... 0x37:
    813        {
    814            int n = index - 0x32;
    815            s->lvt[n] = val;
    816            if (n == APIC_LVT_TIMER) {
    817                apic_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
    818            } else if (n == APIC_LVT_LINT0 && apic_check_pic(s)) {
    819                apic_update_irq(s);
    820            }
    821        }
    822        break;
    823    case 0x38:
    824        s->initial_count = val;
    825        s->initial_count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    826        apic_timer_update(s, s->initial_count_load_time);
    827        break;
    828    case 0x39:
    829        break;
    830    case 0x3e:
    831        {
    832            int v;
    833            s->divide_conf = val & 0xb;
    834            v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
    835            s->count_shift = (v + 1) & 7;
    836        }
    837        break;
    838    default:
    839        s->esr |= APIC_ESR_ILLEGAL_ADDRESS;
    840        break;
    841    }
    842}
    843
    844static void apic_pre_save(APICCommonState *s)
    845{
    846    apic_sync_vapic(s, SYNC_FROM_VAPIC);
    847}
    848
    849static void apic_post_load(APICCommonState *s)
    850{
    851    if (s->timer_expiry != -1) {
    852        timer_mod(s->timer, s->timer_expiry);
    853    } else {
    854        timer_del(s->timer);
    855    }
    856}
    857
    858static const MemoryRegionOps apic_io_ops = {
    859    .read = apic_mem_read,
    860    .write = apic_mem_write,
    861    .impl.min_access_size = 1,
    862    .impl.max_access_size = 4,
    863    .valid.min_access_size = 1,
    864    .valid.max_access_size = 4,
    865    .endianness = DEVICE_NATIVE_ENDIAN,
    866};
    867
    868static void apic_realize(DeviceState *dev, Error **errp)
    869{
    870    APICCommonState *s = APIC(dev);
    871
    872    if (s->id >= MAX_APICS) {
    873        error_setg(errp, "%s initialization failed. APIC ID %d is invalid",
    874                   object_get_typename(OBJECT(dev)), s->id);
    875        return;
    876    }
    877
    878    if (kvm_enabled()) {
    879        warn_report("Userspace local APIC is deprecated for KVM.");
    880        warn_report("Do not use kernel-irqchip except for the -M isapc machine type.");
    881    }
    882
    883    memory_region_init_io(&s->io_memory, OBJECT(s), &apic_io_ops, s, "apic-msi",
    884                          APIC_SPACE_SIZE);
    885
    886    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, apic_timer, s);
    887    local_apics[s->id] = s;
    888
    889    msi_nonbroken = true;
    890}
    891
    892static void apic_unrealize(DeviceState *dev)
    893{
    894    APICCommonState *s = APIC(dev);
    895
    896    timer_free(s->timer);
    897    local_apics[s->id] = NULL;
    898}
    899
    900static void apic_class_init(ObjectClass *klass, void *data)
    901{
    902    APICCommonClass *k = APIC_COMMON_CLASS(klass);
    903
    904    k->realize = apic_realize;
    905    k->unrealize = apic_unrealize;
    906    k->set_base = apic_set_base;
    907    k->set_tpr = apic_set_tpr;
    908    k->get_tpr = apic_get_tpr;
    909    k->vapic_base_update = apic_vapic_base_update;
    910    k->external_nmi = apic_external_nmi;
    911    k->pre_save = apic_pre_save;
    912    k->post_load = apic_post_load;
    913    k->send_msi = apic_send_msi;
    914}
    915
    916static const TypeInfo apic_info = {
    917    .name          = TYPE_APIC,
    918    .instance_size = sizeof(APICCommonState),
    919    .parent        = TYPE_APIC_COMMON,
    920    .class_init    = apic_class_init,
    921};
    922
    923static void apic_register_types(void)
    924{
    925    type_register_static(&apic_info);
    926}
    927
    928type_init(apic_register_types)