19468e9c4SWei Liu /*
29468e9c4SWei Liu * Xen basic APIC support
39468e9c4SWei Liu *
49468e9c4SWei Liu * Copyright (c) 2012 Citrix
59468e9c4SWei Liu *
69468e9c4SWei Liu * Authors:
79468e9c4SWei Liu * Wei Liu <wei.liu2@citrix.com>
89468e9c4SWei Liu *
99468e9c4SWei Liu * This work is licensed under the terms of the GNU GPL version 2 or
109468e9c4SWei Liu * later. See the COPYING file in the top-level directory.
119468e9c4SWei Liu */
120b8fa32fSMarkus Armbruster
13b6a0aa05SPeter Maydell #include "qemu/osdep.h"
140d09e41aSPaolo Bonzini #include "hw/i386/apic_internal.h"
15a2cb15b0SMichael S. Tsirkin #include "hw/pci/msi.h"
160d09e41aSPaolo Bonzini #include "hw/xen/xen.h"
170b8fa32fSMarkus Armbruster #include "qemu/module.h"
189468e9c4SWei Liu
xen_apic_mem_read(void * opaque,hwaddr addr,unsigned size)19a8170e5eSAvi Kivity static uint64_t xen_apic_mem_read(void *opaque, hwaddr addr,
209468e9c4SWei Liu unsigned size)
219468e9c4SWei Liu {
229468e9c4SWei Liu return ~(uint64_t)0;
239468e9c4SWei Liu }
249468e9c4SWei Liu
xen_apic_mem_write(void * opaque,hwaddr addr,uint64_t data,unsigned size)25a8170e5eSAvi Kivity static void xen_apic_mem_write(void *opaque, hwaddr addr,
269468e9c4SWei Liu uint64_t data, unsigned size)
279468e9c4SWei Liu {
289468e9c4SWei Liu if (size != sizeof(uint32_t)) {
299468e9c4SWei Liu fprintf(stderr, "Xen: APIC write data size = %d, invalid\n", size);
309468e9c4SWei Liu return;
319468e9c4SWei Liu }
329468e9c4SWei Liu
339468e9c4SWei Liu xen_hvm_inject_msi(addr, data);
349468e9c4SWei Liu }
359468e9c4SWei Liu
369468e9c4SWei Liu static const MemoryRegionOps xen_apic_io_ops = {
379468e9c4SWei Liu .read = xen_apic_mem_read,
389468e9c4SWei Liu .write = xen_apic_mem_write,
39a115ab5bSPhilippe Mathieu-Daudé .endianness = DEVICE_LITTLE_ENDIAN,
409468e9c4SWei Liu };
419468e9c4SWei Liu
xen_apic_realize(DeviceState * dev,Error ** errp)42ff6986ceSxiaoqiang zhao static void xen_apic_realize(DeviceState *dev, Error **errp)
439468e9c4SWei Liu {
44ff6986ceSxiaoqiang zhao APICCommonState *s = APIC_COMMON(dev);
45ff6986ceSxiaoqiang zhao
46b33a5bbfSChunyan Liu s->vapic_control = 0;
4722fc860bSPaolo Bonzini memory_region_init_io(&s->io_memory, OBJECT(s), &xen_apic_io_ops, s,
4822fc860bSPaolo Bonzini "xen-apic-msi", APIC_SPACE_SIZE);
49226419d6SMichael S. Tsirkin msi_nonbroken = true;
509468e9c4SWei Liu }
519468e9c4SWei Liu
xen_apic_set_base(APICCommonState * s,uint64_t val)52774204cfSBui Quang Minh static int xen_apic_set_base(APICCommonState *s, uint64_t val)
539468e9c4SWei Liu {
54774204cfSBui Quang Minh return 0;
559468e9c4SWei Liu }
569468e9c4SWei Liu
xen_apic_set_tpr(APICCommonState * s,uint8_t val)579468e9c4SWei Liu static void xen_apic_set_tpr(APICCommonState *s, uint8_t val)
589468e9c4SWei Liu {
599468e9c4SWei Liu }
609468e9c4SWei Liu
xen_apic_get_tpr(APICCommonState * s)619468e9c4SWei Liu static uint8_t xen_apic_get_tpr(APICCommonState *s)
629468e9c4SWei Liu {
639468e9c4SWei Liu return 0;
649468e9c4SWei Liu }
659468e9c4SWei Liu
xen_apic_vapic_base_update(APICCommonState * s)669468e9c4SWei Liu static void xen_apic_vapic_base_update(APICCommonState *s)
679468e9c4SWei Liu {
689468e9c4SWei Liu }
699468e9c4SWei Liu
xen_apic_external_nmi(APICCommonState * s)709468e9c4SWei Liu static void xen_apic_external_nmi(APICCommonState *s)
719468e9c4SWei Liu {
729468e9c4SWei Liu }
739468e9c4SWei Liu
xen_send_msi(MSIMessage * msi)74267ee357SRadim Krčmář static void xen_send_msi(MSIMessage *msi)
75267ee357SRadim Krčmář {
76267ee357SRadim Krčmář xen_hvm_inject_msi(msi->address, msi->data);
77267ee357SRadim Krčmář }
78267ee357SRadim Krčmář
xen_apic_class_init(ObjectClass * klass,const void * data)79*12d1a768SPhilippe Mathieu-Daudé static void xen_apic_class_init(ObjectClass *klass, const void *data)
809468e9c4SWei Liu {
819468e9c4SWei Liu APICCommonClass *k = APIC_COMMON_CLASS(klass);
829468e9c4SWei Liu
83ff6986ceSxiaoqiang zhao k->realize = xen_apic_realize;
849468e9c4SWei Liu k->set_base = xen_apic_set_base;
859468e9c4SWei Liu k->set_tpr = xen_apic_set_tpr;
869468e9c4SWei Liu k->get_tpr = xen_apic_get_tpr;
879468e9c4SWei Liu k->vapic_base_update = xen_apic_vapic_base_update;
889468e9c4SWei Liu k->external_nmi = xen_apic_external_nmi;
89267ee357SRadim Krčmář k->send_msi = xen_send_msi;
909468e9c4SWei Liu }
919468e9c4SWei Liu
928c43a6f0SAndreas Färber static const TypeInfo xen_apic_info = {
939468e9c4SWei Liu .name = "xen-apic",
949468e9c4SWei Liu .parent = TYPE_APIC_COMMON,
959468e9c4SWei Liu .instance_size = sizeof(APICCommonState),
969468e9c4SWei Liu .class_init = xen_apic_class_init,
979468e9c4SWei Liu };
989468e9c4SWei Liu
xen_apic_register_types(void)999468e9c4SWei Liu static void xen_apic_register_types(void)
1009468e9c4SWei Liu {
1019468e9c4SWei Liu type_register_static(&xen_apic_info);
1029468e9c4SWei Liu }
1039468e9c4SWei Liu
1049468e9c4SWei Liu type_init(xen_apic_register_types)
105