88 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Generic PCI Express Root Port emulation
 | 
						|
 *
 | 
						|
 * Copyright (C) 2017 Red Hat Inc
 | 
						|
 *
 | 
						|
 * Authors:
 | 
						|
 *   Marcel Apfelbaum <marcel@redhat.com>
 | 
						|
 *
 | 
						|
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 | 
						|
 * See the COPYING file in the top-level directory.
 | 
						|
 */
 | 
						|
 | 
						|
#include "qemu/osdep.h"
 | 
						|
#include "qapi/error.h"
 | 
						|
#include "hw/pci/msix.h"
 | 
						|
#include "hw/pci/pcie_port.h"
 | 
						|
 | 
						|
#define TYPE_GEN_PCIE_ROOT_PORT                "pcie-root-port"
 | 
						|
 | 
						|
#define GEN_PCIE_ROOT_PORT_AER_OFFSET           0x100
 | 
						|
#define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR       1
 | 
						|
 | 
						|
static uint8_t gen_rp_aer_vector(const PCIDevice *d)
 | 
						|
{
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int gen_rp_interrupts_init(PCIDevice *d, Error **errp)
 | 
						|
{
 | 
						|
    int rc;
 | 
						|
 | 
						|
    rc = msix_init_exclusive_bar(d, GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR, 0, errp);
 | 
						|
 | 
						|
    if (rc < 0) {
 | 
						|
        assert(rc == -ENOTSUP);
 | 
						|
    } else {
 | 
						|
        msix_vector_use(d, 0);
 | 
						|
    }
 | 
						|
 | 
						|
    return rc;
 | 
						|
}
 | 
						|
 | 
						|
static void gen_rp_interrupts_uninit(PCIDevice *d)
 | 
						|
{
 | 
						|
    msix_uninit_exclusive_bar(d);
 | 
						|
}
 | 
						|
 | 
						|
static const VMStateDescription vmstate_rp_dev = {
 | 
						|
    .name = "pcie-root-port",
 | 
						|
    .version_id = 1,
 | 
						|
    .minimum_version_id = 1,
 | 
						|
    .post_load = pcie_cap_slot_post_load,
 | 
						|
    .fields = (VMStateField[]) {
 | 
						|
        VMSTATE_PCI_DEVICE(parent_obj.parent_obj.parent_obj, PCIESlot),
 | 
						|
        VMSTATE_STRUCT(parent_obj.parent_obj.parent_obj.exp.aer_log,
 | 
						|
                       PCIESlot, 0, vmstate_pcie_aer_log, PCIEAERLog),
 | 
						|
        VMSTATE_END_OF_LIST()
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
static void gen_rp_dev_class_init(ObjectClass *klass, void *data)
 | 
						|
{
 | 
						|
    DeviceClass *dc = DEVICE_CLASS(klass);
 | 
						|
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 | 
						|
    PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
 | 
						|
 | 
						|
    k->vendor_id = PCI_VENDOR_ID_REDHAT;
 | 
						|
    k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_RP;
 | 
						|
    dc->desc = "PCI Express Root Port";
 | 
						|
    dc->vmsd = &vmstate_rp_dev;
 | 
						|
    rpc->aer_vector = gen_rp_aer_vector;
 | 
						|
    rpc->interrupts_init = gen_rp_interrupts_init;
 | 
						|
    rpc->interrupts_uninit = gen_rp_interrupts_uninit;
 | 
						|
    rpc->aer_offset = GEN_PCIE_ROOT_PORT_AER_OFFSET;
 | 
						|
}
 | 
						|
 | 
						|
static const TypeInfo gen_rp_dev_info = {
 | 
						|
    .name          = TYPE_GEN_PCIE_ROOT_PORT,
 | 
						|
    .parent        = TYPE_PCIE_ROOT_PORT,
 | 
						|
    .class_init    = gen_rp_dev_class_init,
 | 
						|
};
 | 
						|
 | 
						|
 static void gen_rp_register_types(void)
 | 
						|
 {
 | 
						|
    type_register_static(&gen_rp_dev_info);
 | 
						|
 }
 | 
						|
 type_init(gen_rp_register_types)
 |