hw/pci-bridge/cxl_root_port: Wire up MSI
Done to avoid fixing ACPI route description of traditional PCI interrupts on q35 and because we should probably move with the times anyway. Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Message-Id: <20230302133709.30373-5-Jonathan.Cameron@huawei.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Fan Ni <fan.ni@samsung.com>
This commit is contained in:
parent
47f0e7ab32
commit
7e33517fdd
@ -22,6 +22,7 @@
|
|||||||
#include "qemu/range.h"
|
#include "qemu/range.h"
|
||||||
#include "hw/pci/pci_bridge.h"
|
#include "hw/pci/pci_bridge.h"
|
||||||
#include "hw/pci/pcie_port.h"
|
#include "hw/pci/pcie_port.h"
|
||||||
|
#include "hw/pci/msi.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
@ -29,6 +30,10 @@
|
|||||||
|
|
||||||
#define CXL_ROOT_PORT_DID 0x7075
|
#define CXL_ROOT_PORT_DID 0x7075
|
||||||
|
|
||||||
|
#define CXL_RP_MSI_OFFSET 0x60
|
||||||
|
#define CXL_RP_MSI_SUPPORTED_FLAGS PCI_MSI_FLAGS_MASKBIT
|
||||||
|
#define CXL_RP_MSI_NR_VECTOR 2
|
||||||
|
|
||||||
/* Copied from the gen root port which we derive */
|
/* Copied from the gen root port which we derive */
|
||||||
#define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100
|
#define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100
|
||||||
#define GEN_PCIE_ROOT_PORT_ACS_OFFSET \
|
#define GEN_PCIE_ROOT_PORT_ACS_OFFSET \
|
||||||
@ -47,6 +52,49 @@ typedef struct CXLRootPort {
|
|||||||
#define TYPE_CXL_ROOT_PORT "cxl-rp"
|
#define TYPE_CXL_ROOT_PORT "cxl-rp"
|
||||||
DECLARE_INSTANCE_CHECKER(CXLRootPort, CXL_ROOT_PORT, TYPE_CXL_ROOT_PORT)
|
DECLARE_INSTANCE_CHECKER(CXLRootPort, CXL_ROOT_PORT, TYPE_CXL_ROOT_PORT)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If two MSI vector are allocated, Advanced Error Interrupt Message Number
|
||||||
|
* is 1. otherwise 0.
|
||||||
|
* 17.12.5.10 RPERRSTS, 32:27 bit Advanced Error Interrupt Message Number.
|
||||||
|
*/
|
||||||
|
static uint8_t cxl_rp_aer_vector(const PCIDevice *d)
|
||||||
|
{
|
||||||
|
switch (msi_nr_vectors_allocated(d)) {
|
||||||
|
case 1:
|
||||||
|
return 0;
|
||||||
|
case 2:
|
||||||
|
return 1;
|
||||||
|
case 4:
|
||||||
|
case 8:
|
||||||
|
case 16:
|
||||||
|
case 32:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
abort();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cxl_rp_interrupts_init(PCIDevice *d, Error **errp)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = msi_init(d, CXL_RP_MSI_OFFSET, CXL_RP_MSI_NR_VECTOR,
|
||||||
|
CXL_RP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
|
||||||
|
CXL_RP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT,
|
||||||
|
errp);
|
||||||
|
if (rc < 0) {
|
||||||
|
assert(rc == -ENOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cxl_rp_interrupts_uninit(PCIDevice *d)
|
||||||
|
{
|
||||||
|
msi_uninit(d);
|
||||||
|
}
|
||||||
|
|
||||||
static void latch_registers(CXLRootPort *crp)
|
static void latch_registers(CXLRootPort *crp)
|
||||||
{
|
{
|
||||||
uint32_t *reg_state = crp->cxl_cstate.crb.cache_mem_registers;
|
uint32_t *reg_state = crp->cxl_cstate.crb.cache_mem_registers;
|
||||||
@ -183,6 +231,15 @@ static void cxl_rp_dvsec_write_config(PCIDevice *dev, uint32_t addr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cxl_rp_aer_vector_update(PCIDevice *d)
|
||||||
|
{
|
||||||
|
PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
|
||||||
|
|
||||||
|
if (rpc->aer_vector) {
|
||||||
|
pcie_aer_root_set_vector(d, rpc->aer_vector(d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void cxl_rp_write_config(PCIDevice *d, uint32_t address, uint32_t val,
|
static void cxl_rp_write_config(PCIDevice *d, uint32_t address, uint32_t val,
|
||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
@ -192,6 +249,7 @@ static void cxl_rp_write_config(PCIDevice *d, uint32_t address, uint32_t val,
|
|||||||
|
|
||||||
pcie_cap_slot_get(d, &slt_ctl, &slt_sta);
|
pcie_cap_slot_get(d, &slt_ctl, &slt_sta);
|
||||||
pci_bridge_write_config(d, address, val, len);
|
pci_bridge_write_config(d, address, val, len);
|
||||||
|
cxl_rp_aer_vector_update(d);
|
||||||
pcie_cap_flr_write_config(d, address, val, len);
|
pcie_cap_flr_write_config(d, address, val, len);
|
||||||
pcie_cap_slot_write_config(d, slt_ctl, slt_sta, address, val, len);
|
pcie_cap_slot_write_config(d, slt_ctl, slt_sta, address, val, len);
|
||||||
pcie_aer_write_config(d, address, val, len);
|
pcie_aer_write_config(d, address, val, len);
|
||||||
@ -220,6 +278,9 @@ static void cxl_root_port_class_init(ObjectClass *oc, void *data)
|
|||||||
|
|
||||||
rpc->aer_offset = GEN_PCIE_ROOT_PORT_AER_OFFSET;
|
rpc->aer_offset = GEN_PCIE_ROOT_PORT_AER_OFFSET;
|
||||||
rpc->acs_offset = GEN_PCIE_ROOT_PORT_ACS_OFFSET;
|
rpc->acs_offset = GEN_PCIE_ROOT_PORT_ACS_OFFSET;
|
||||||
|
rpc->aer_vector = cxl_rp_aer_vector;
|
||||||
|
rpc->interrupts_init = cxl_rp_interrupts_init;
|
||||||
|
rpc->interrupts_uninit = cxl_rp_interrupts_uninit;
|
||||||
|
|
||||||
dc->hotpluggable = false;
|
dc->hotpluggable = false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user