qemu/hw/pci-host/xlnx-nwl-pcie-main.c
<<
>>
Prefs
   1/*
   2 * QEMU model of the AXIPCIE_MAIN Xilinx PCIe NWL
   3 *
   4 * Copyright (c) 2016-2020 Xilinx Inc.
   5 *
   6 * Autogenerated by xregqemu.py 2020-01-23.
   7 *
   8 * Permission is hereby granted, free of charge, to any person obtaining a copy
   9 * of this software and associated documentation files (the "Software"), to deal
  10 * in the Software without restriction, including without limitation the rights
  11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12 * copies of the Software, and to permit persons to whom the Software is
  13 * furnished to do so, subject to the following conditions:
  14 *
  15 * The above copyright notice and this permission notice shall be included in
  16 * all copies or substantial portions of the Software.
  17 *
  18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24 * THE SOFTWARE.
  25 */
  26
  27#include "qemu/osdep.h"
  28#include "hw/sysbus.h"
  29#include "hw/register.h"
  30#include "qemu/bitops.h"
  31#include "qemu/log.h"
  32#include "qapi/error.h"
  33#include "migration/vmstate.h"
  34#include "hw/qdev-properties.h"
  35
  36#include "hw/pci/msi.h"
  37
  38#include "hw/pci/pci.h"
  39#include "hw/pci/pcie.h"
  40#include "hw/pci/pci_bus.h"
  41#include "hw/pci/pcie_host.h"
  42#include "hw/pci/pcie_port.h"
  43#include "hw/irq.h"
  44
  45#ifndef XILINX_AXIPCIE_MAIN_ERR_DEBUG
  46#define XILINX_AXIPCIE_MAIN_ERR_DEBUG 0
  47#endif
  48
  49#define TYPE_XILINX_AXIPCIE_MAIN "xlnx.nwl-pcie-main"
  50#define TYPE_XILINX_AXIPCIE_MAIN_IOMMU_MEMORY_REGION "xlnx.nwl-pcie-main-iommu-memory-region"
  51
  52#define XILINX_AXIPCIE_MAIN(obj) \
  53     OBJECT_CHECK(AXIPCIE_MAIN, (obj), TYPE_XILINX_AXIPCIE_MAIN)
  54
  55REG32(BRIDGE_CORE_CFG_PCIE_RX0, 0x0)
  56    FIELD(BRIDGE_CORE_CFG_PCIE_RX0, CFG_DISABLE_PCIE_DMA_REG_ACCESS, 17, 1)
  57    FIELD(BRIDGE_CORE_CFG_PCIE_RX0, CFG_DISABLE_PCIE_BRIDGE_REG_ACCESS, 16, 1)
  58    FIELD(BRIDGE_CORE_CFG_PCIE_RX0, CFG_DMA_REG_BAR, 0, 3)
  59REG32(BRIDGE_CORE_CFG_PCIE_RX1, 0x4)
  60    FIELD(BRIDGE_CORE_CFG_PCIE_RX1, CFG_RD_UR_IS_UR_OK1S_N, 8, 1)
  61    FIELD(BRIDGE_CORE_CFG_PCIE_RX1, CFG_PCIE_RX_ARCACHE, 4, 4)
  62    FIELD(BRIDGE_CORE_CFG_PCIE_RX1, CFG_PCIE_RX_AWCACHE, 0, 4)
  63REG32(BRIDGE_CORE_CFG_AXI_MASTER, 0x8)
  64    FIELD(BRIDGE_CORE_CFG_AXI_MASTER, CFG_M_MAX_RD_REQ_SIZE, 4, 3)
  65    FIELD(BRIDGE_CORE_CFG_AXI_MASTER, CFG_M_MAX_WR_REQ_SIZE, 0, 3)
  66REG32(BRIDGE_CORE_CFG_PCIE_TX, 0xc)
  67    FIELD(BRIDGE_CORE_CFG_PCIE_TX, CFG_PCIE_TX_CUT_THROUGH, 0, 1)
  68REG32(BRIDGE_CORE_CFG_INTERRUPT, 0x10)
  69    FIELD(BRIDGE_CORE_CFG_INTERRUPT, CFG_PCIE_INT_AXI_PCIE_N, 0, 1)
  70REG32(BRIDGE_CORE_CFG_RAM_DISABLE0, 0x14)
  71    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_SGL_DST_DIS_COR, 14, 1)
  72    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_SGL_SRC_DIS_COR, 13, 1)
  73    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_CH_REG_DIS_COR, 12, 1)
  74    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_MSIX_TAB_DIS_COR, 11, 1)
  75    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_AXI_S_W_DIS_COR, 8, 1)
  76    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_AXI_M_R_DIS_COR, 6, 1)
  77    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_S_CD_DIS_COR, 5, 1)
  78    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_S_RA_DIS_COR, 4, 1)
  79    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_S_W_DIS_COR, 3, 1)
  80    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_S_WA_DIS_COR, 2, 1)
  81    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_TX_W_DIS_COR, 1, 1)
  82    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE0, CFG_RAM_DMA_PCIE_M_R_DIS_COR, 0, 1)
  83REG32(BRIDGE_CORE_CFG_RAM_DISABLE1, 0x18)
  84    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_SGL_DST_DIS_ERR, 14, 1)
  85    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_SGL_SRC_DIS_ERR, 13, 1)
  86    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_CH_REG_DIS_ERR, 12, 1)
  87    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_MSIX_TAB_DIS_ERR, 11, 1)
  88    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_AXI_S_W_DIS_ERR, 8, 1)
  89    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_AXI_M_R_DIS_ERR, 6, 1)
  90    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_S_CD_DIS_ERR, 5, 1)
  91    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_S_RA_DIS_ERR, 4, 1)
  92    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_S_W_DIS_ERR, 3, 1)
  93    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_S_WA_DIS_ERR, 2, 1)
  94    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_TX_W_DIS_ERR, 1, 1)
  95    FIELD(BRIDGE_CORE_CFG_RAM_DISABLE1, CFG_RAM_DMA_PCIE_M_R_DIS_ERR, 0, 1)
  96REG32(BRIDGE_CORE_CFG_PCIE_RELAXED_ORDER, 0x1c)
  97    FIELD(BRIDGE_CORE_CFG_PCIE_RELAXED_ORDER, CFG_ENABLE_CFGIO_WR_RO, 1, 1)
  98    FIELD(BRIDGE_CORE_CFG_PCIE_RELAXED_ORDER, CFG_ENABLE_DMA_RO, 0, 1)
  99REG32(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, 0x20)
 100    FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER,
 101          CFG_DESIRED_VEN_MSG_VEN_ID, 16, 16)
 102    FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER,
 103          CFG_DESIRED_VEN_MSG_VEN_INV, 15, 1)
 104    FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_DESIRED_VEN_MSG_EN, 14, 1)
 105    FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_OTH_MSG_FWD, 13, 1)
 106    FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_VEN_MSG_FWD, 7, 1)
 107    FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_SLT_MSG_FWD, 5, 1)
 108    FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_ERR_MSG_FWD, 3, 1)
 109    FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_INT_MSG_FWD, 2, 1)
 110    FIELD(BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER, CFG_ENABLE_PM_MSG_FWD, 1, 1)
 111REG32(BRIDGE_CORE_CFG_RQ_REQ_ORDER, 0x24)
 112    FIELD(BRIDGE_CORE_CFG_RQ_REQ_ORDER, CFG_PCIE_REQ_ORDER_STRICT, 31, 1)
 113    FIELD(BRIDGE_CORE_CFG_RQ_REQ_ORDER, CFG_AXI_REQ_ORDER_STRICT, 30, 1)
 114    FIELD(BRIDGE_CORE_CFG_RQ_REQ_ORDER, CFG_AXI_REQ_ORDER_ID_MASK, 0, 16)
 115REG32(BRIDGE_CORE_CFG_PCIE_CREDIT, 0x28)
 116    FIELD(BRIDGE_CORE_CFG_PCIE_CREDIT, CFG_PCIE_CREDIT_EN, 31, 1)
 117    FIELD(BRIDGE_CORE_CFG_PCIE_CREDIT, CFG_PCIE_CREDIT_CH_INF, 30, 1)
 118    FIELD(BRIDGE_CORE_CFG_PCIE_CREDIT, CFG_PCIE_CREDIT_CD_INF, 29, 1)
 119    FIELD(BRIDGE_CORE_CFG_PCIE_CREDIT, CFG_PCIE_CREDIT_CH_VAL, 16, 8)
 120    FIELD(BRIDGE_CORE_CFG_PCIE_CREDIT, CFG_PCIE_CREDIT_CD_VAL, 0, 12)
 121REG32(BRIDGE_CORE_CFG_AXI_M_W_TICK_COUNT, 0x2c)
 122    FIELD(BRIDGE_CORE_CFG_AXI_M_W_TICK_COUNT, AXI_M_W_TICK_COUNT, 0, 16)
 123REG32(BRIDGE_CORE_CFG_AXI_M_R_TICK_COUNT, 0x30)
 124    FIELD(BRIDGE_CORE_CFG_AXI_M_R_TICK_COUNT, AXI_M_R_TICK_COUNT, 0, 16)
 125REG32(BRIDGE_CORE_CFG_CRS_RPL_TICK_COUNT, 0x34)
 126    FIELD(BRIDGE_CORE_CFG_CRS_RPL_TICK_COUNT, CRS_RPL_TICK_COUNT, 0, 16)
 127REG32(E_BREG_CAPABILITIES, 0x200)
 128    FIELD(E_BREG_CAPABILITIES, BREG_SIZE_MAX, 24, 8)
 129    FIELD(E_BREG_CAPABILITIES, BREG_SIZE_OFFSET, 16, 8)
 130    FIELD(E_BREG_CAPABILITIES, BREG_PRESENT, 0, 1)
 131REG32(E_BREG_STATUS, 0x204)
 132    FIELD(E_BREG_STATUS, WR_PENDING_CTR, 16, 9)
 133    FIELD(E_BREG_STATUS, RD_PENDING_CTR, 0, 9)
 134REG32(E_BREG_CONTROL, 0x208)
 135    FIELD(E_BREG_CONTROL, BREG_SIZE, 16, 2)
 136    FIELD(E_BREG_CONTROL, BREG_SECURITY_ENABLE, 2, 1)
 137    FIELD(E_BREG_CONTROL, BREG_ENABLE_FORCE, 1, 1)
 138    FIELD(E_BREG_CONTROL, BREG_ENABLE, 0, 1)
 139REG32(E_BREG_BASE_LO, 0x210)
 140    FIELD(E_BREG_BASE_LO, BREG_BASE_LO, 12, 20)
 141REG32(E_BREG_BASE_HI, 0x214)
 142REG32(E_ECAM_CAPABILITIES, 0x220)
 143    FIELD(E_ECAM_CAPABILITIES, ECAM_SIZE_MAX, 24, 8)
 144    FIELD(E_ECAM_CAPABILITIES, ECAM_SIZE_OFFSET, 16, 8)
 145    FIELD(E_ECAM_CAPABILITIES, ECAM_PRESENT, 0, 1)
 146REG32(E_ECAM_STATUS, 0x224)
 147    FIELD(E_ECAM_STATUS, WR_PENDING_CTR, 16, 9)
 148    FIELD(E_ECAM_STATUS, RD_PENDING_CTR, 0, 9)
 149REG32(E_ECAM_CONTROL, 0x228)
 150    FIELD(E_ECAM_CONTROL, ECAM_SIZE, 16, 5)
 151    FIELD(E_ECAM_CONTROL, ECAM_SECURITY_ENABLE, 2, 1)
 152    FIELD(E_ECAM_CONTROL, ECAM_ENABLE, 0, 1)
 153REG32(E_ECAM_BASE_LO, 0x230)
 154    FIELD(E_ECAM_BASE_LO, ECAM_BASE_LO, 12, 20)
 155REG32(E_ECAM_BASE_HI, 0x234)
 156REG32(E_MSXT_CAPABILITIES, 0x240)
 157    FIELD(E_MSXT_CAPABILITIES, MSXT_SIZE_MAX, 24, 8)
 158    FIELD(E_MSXT_CAPABILITIES, MSXT_SIZE_OFFSET, 16, 8)
 159    FIELD(E_MSXT_CAPABILITIES, MSXT_PRESENT, 0, 1)
 160REG32(E_MSXT_STATUS, 0x244)
 161    FIELD(E_MSXT_STATUS, WR_PENDING_CTR, 16, 9)
 162    FIELD(E_MSXT_STATUS, RD_PENDING_CTR, 0, 9)
 163REG32(E_MSXT_CONTROL, 0x248)
 164    FIELD(E_MSXT_CONTROL, MSXT_SIZE, 16, 2)
 165    FIELD(E_MSXT_CONTROL, MSXT_SECURITY_ENABLE, 2, 1)
 166    FIELD(E_MSXT_CONTROL, MSXT_ENABLE, 0, 1)
 167REG32(E_MSXT_BASE_LO, 0x250)
 168    FIELD(E_MSXT_BASE_LO, MSXT_BASE_LO, 12, 20)
 169REG32(E_MSXT_BASE_HI, 0x254)
 170REG32(E_MSXP_CAPABILITIES, 0x260)
 171    FIELD(E_MSXP_CAPABILITIES, MSXP_SIZE_MAX, 24, 8)
 172    FIELD(E_MSXP_CAPABILITIES, MSXP_SIZE_OFFSET, 16, 8)
 173    FIELD(E_MSXP_CAPABILITIES, MSXP_PRESENT, 0, 1)
 174REG32(E_MSXP_STATUS, 0x264)
 175    FIELD(E_MSXP_STATUS, WR_PENDING_CTR, 16, 9)
 176    FIELD(E_MSXP_STATUS, RD_PENDING_CTR, 0, 9)
 177REG32(E_MSXP_CONTROL, 0x268)
 178    FIELD(E_MSXP_CONTROL, MSXP_SIZE, 16, 2)
 179    FIELD(E_MSXP_CONTROL, MSXP_SECURITY_ENABLE, 2, 1)
 180    FIELD(E_MSXP_CONTROL, MSXP_ENABLE, 0, 1)
 181REG32(E_MSXP_BASE_LO, 0x270)
 182    FIELD(E_MSXP_BASE_LO, MSXP_BASE_LO, 12, 20)
 183REG32(E_MSXP_BASE_HI, 0x274)
 184REG32(E_DREG_CAPABILITIES, 0x280)
 185    FIELD(E_DREG_CAPABILITIES, DMA_SIZE_MAX, 24, 8)
 186    FIELD(E_DREG_CAPABILITIES, DMA_SIZE_OFFSET, 16, 8)
 187    FIELD(E_DREG_CAPABILITIES, DMA_PRESENT, 0, 1)
 188REG32(E_DREG_STATUS, 0x284)
 189    FIELD(E_DREG_STATUS, WR_PENDING_CTR, 16, 9)
 190    FIELD(E_DREG_STATUS, RD_PENDING_CTR, 0, 9)
 191REG32(E_DREG_CONTROL, 0x288)
 192    FIELD(E_DREG_CONTROL, DMA_SIZE, 16, 2)
 193    FIELD(E_DREG_CONTROL, DMA_SECURITY_ENABLE, 2, 1)
 194    FIELD(E_DREG_CONTROL, DMA_ENABLE, 0, 1)
 195REG32(E_DREG_BASE_LO, 0x290)
 196    FIELD(E_DREG_BASE_LO, DMA_BASE_LO, 12, 20)
 197REG32(E_DREG_BASE_HI, 0x294)
 198REG32(E_ESUB_CAPABILITIES, 0x2e0)
 199    FIELD(E_ESUB_CAPABILITIES, SUBTRACTIVE_DECODE_PRESENT, 0, 1)
 200REG32(E_ESUB_STATUS, 0x2e4)
 201    FIELD(E_ESUB_STATUS, WR_PENDING_CTR, 16, 9)
 202    FIELD(E_ESUB_STATUS, RD_PENDING_CTR, 0, 9)
 203REG32(E_ESUB_CONTROL, 0x2e8)
 204    FIELD(E_ESUB_CONTROL, EGRESS_SUB_ENABLE, 0, 1)
 205REG32(I_MSII_CAPABILITIES, 0x300)
 206    FIELD(I_MSII_CAPABILITIES, I_MSII_SIZE_MAX, 24, 8)
 207    FIELD(I_MSII_CAPABILITIES, I_MSII_SIZE_OFFSET, 16, 8)
 208    FIELD(I_MSII_CAPABILITIES, I_MSII_PRESENT, 0, 1)
 209REG32(I_MSII_CONTROL, 0x308)
 210    FIELD(I_MSII_CONTROL, I_MSII_SIZE, 16, 5)
 211    FIELD(I_MSII_CONTROL, I_MSII_STATUS_ENABLE, 15, 1)
 212    FIELD(I_MSII_CONTROL, I_MSII_ENABLE, 0, 1)
 213REG32(I_MSII_BASE_LO, 0x310)
 214    FIELD(I_MSII_BASE_LO, I_MSII_BASE_LO, 12, 20)
 215REG32(I_MSII_BASE_HI, 0x314)
 216REG32(I_MSIX_CAPABILITIES, 0x320)
 217    FIELD(I_MSIX_CAPABILITIES, I_MSIX_SIZE_MAX, 24, 8)
 218    FIELD(I_MSIX_CAPABILITIES, I_MSIX_SIZE_OFFSET, 16, 8)
 219    FIELD(I_MSIX_CAPABILITIES, I_MSIX_PRESENT, 0, 1)
 220REG32(I_MSIX_CONTROL, 0x328)
 221    FIELD(I_MSIX_CONTROL, I_MSIX_SIZE, 16, 5)
 222    FIELD(I_MSIX_CONTROL, I_MSIX_ENABLE, 0, 1)
 223REG32(I_MSIX_BASE_LO, 0x330)
 224    FIELD(I_MSIX_BASE_LO, I_MSIX_BASE_LO, 12, 20)
 225REG32(I_MSIX_BASE_HI, 0x334)
 226REG32(I_ISUB_CAPABILITIES, 0x3e0)
 227    FIELD(I_ISUB_CAPABILITIES, SUBTRACTIVE_DECODE_PRESENT, 0, 1)
 228REG32(I_ISUB_STATUS, 0x3e4)
 229    FIELD(I_ISUB_STATUS, WR_PENDING_CTR, 16, 9)
 230    FIELD(I_ISUB_STATUS, RD_PENDING_CTR, 0, 9)
 231REG32(I_ISUB_CONTROL, 0x3e8)
 232    FIELD(I_ISUB_CONTROL, INGRESS_SUB_ENABLE, 0, 1)
 233REG32(MSGF_MISC_STATUS, 0x400)
 234    FIELD(MSGF_MISC_STATUS, PCIE_CORE_EVENT, 16, 16)
 235    FIELD(MSGF_MISC_STATUS, EGRESS_ADDRESS_TRANSLATION_ERROR, 7, 1)
 236    FIELD(MSGF_MISC_STATUS, INGRESS_ADDRESS_TRANSLATION_ERROR, 6, 1)
 237    FIELD(MSGF_MISC_STATUS, MASTER_ERROR, 5, 1)
 238    FIELD(MSGF_MISC_STATUS, SLAVE_ERROR, 4, 1)
 239    FIELD(MSGF_MISC_STATUS, UNCORRECTABLE_WRITE_ERROR, 3, 1)
 240    FIELD(MSGF_MISC_STATUS, RX_MSG_OVERFLOW, 1, 1)
 241    FIELD(MSGF_MISC_STATUS, RX_MSG_AVAIL, 0, 1)
 242REG32(MSGF_MISC_MASK, 0x404)
 243    FIELD(MSGF_MISC_MASK, PCIE_CORE_EVENT_MASK, 16, 16)
 244    FIELD(MSGF_MISC_MASK, EGRESS_ADDRESS_TRANSLATION_ERROR_MASK, 7, 1)
 245    FIELD(MSGF_MISC_MASK, INGRESS_ADDRESS_TRANSLATION_ERROR_MASK, 6, 1)
 246    FIELD(MSGF_MISC_MASK, MASTER_ERROR_MASK, 5, 1)
 247    FIELD(MSGF_MISC_MASK, SLAVE_ERROR_MASK, 4, 1)
 248    FIELD(MSGF_MISC_MASK, UNCORRECTABLE_WRITE_ERROR_MASK, 3, 1)
 249    FIELD(MSGF_MISC_MASK, RX_MSG_OVERFLOW_MASK, 1, 1)
 250    FIELD(MSGF_MISC_MASK, RX_MSG_AVAIL_MASK, 0, 1)
 251REG32(MSGF_MISC_SLAVE_ID, 0x408)
 252    FIELD(MSGF_MISC_SLAVE_ID, SLAVE_ERROR_ID, 0, 8)
 253REG32(MSGF_MISC_MASTER_ID, 0x40c)
 254    FIELD(MSGF_MISC_MASTER_ID, MASTER_ERROR_ID, 0, 8)
 255REG32(MSGF_MISC_INGRESS_ID, 0x410)
 256    FIELD(MSGF_MISC_INGRESS_ID, INGRESS_ERROR_ID, 0, 8)
 257REG32(MSGF_MISC_EGRESS_ID, 0x414)
 258    FIELD(MSGF_MISC_EGRESS_ID, EGRESS_ERROR_ID, 0, 8)
 259REG32(MSGF_LEG_STATUS, 0x420)
 260    FIELD(MSGF_LEG_STATUS, MSGF_LEG_STATUS_INTD, 3, 1)
 261    FIELD(MSGF_LEG_STATUS, MSGF_LEG_STATUS_INTC, 2, 1)
 262    FIELD(MSGF_LEG_STATUS, MSGF_LEG_STATUS_INTB, 1, 1)
 263    FIELD(MSGF_LEG_STATUS, MSGF_LEG_STATUS_INTA, 0, 1)
 264REG32(MSGF_LEG_MASK, 0x424)
 265    FIELD(MSGF_LEG_MASK, MSGF_LEG_MASK_INTD, 3, 1)
 266    FIELD(MSGF_LEG_MASK, MSGF_LEG_MASK_INTC, 2, 1)
 267    FIELD(MSGF_LEG_MASK, MSGF_LEG_MASK_INTB, 1, 1)
 268    FIELD(MSGF_LEG_MASK, MSGF_LEG_MASK_INTA, 0, 1)
 269REG32(MSGF_MSI_STATUS_LO, 0x440)
 270REG32(MSGF_MSI_STATUS_HI, 0x444)
 271REG32(MSGF_MSI_MASK_LO, 0x448)
 272REG32(MSGF_MSI_MASK_HI, 0x44c)
 273REG32(MSGF_DMA_STATUS, 0x460)
 274    FIELD(MSGF_DMA_STATUS, MSGF_DMA_STATUS, 0, 1)
 275REG32(MSGF_DMA_MASK, 0x464)
 276    FIELD(MSGF_DMA_MASK, MSGF_DMA_MASK, 0, 1)
 277REG32(MSGF_RX_FIFO_LEVEL, 0x480)
 278    FIELD(MSGF_RX_FIFO_LEVEL, LEVEL, 0, 8)
 279REG32(MSGF_RX_FIFO_POP, 0x484)
 280    FIELD(MSGF_RX_FIFO_POP, POP, 0, 1)
 281REG32(MSGF_RX_FIFO_TYPE, 0x488)
 282    FIELD(MSGF_RX_FIFO_TYPE, REQUESTER_ID, 16, 16)
 283    FIELD(MSGF_RX_FIFO_TYPE, INTR_TYPE, 0, 2)
 284REG32(MSGF_RX_FIFO_MSG, 0x48c)
 285    FIELD(MSGF_RX_FIFO_MSG, MESSAGE_TAG, 16, 8)
 286    FIELD(MSGF_RX_FIFO_MSG, MESSAGE_CODE, 8, 8)
 287    FIELD(MSGF_RX_FIFO_MSG, MESSAGE_PAYLOAD_PRESENT, 3, 1)
 288    FIELD(MSGF_RX_FIFO_MSG, MESSAGE_ROUTING, 0, 3)
 289REG32(MSGF_RX_FIFO_ADDRESS_LO, 0x490)
 290REG32(MSGF_RX_FIFO_ADDRESS_HI, 0x494)
 291REG32(MSGF_RX_FIFO_DATA, 0x498)
 292REG32(TX_PCIE_MSG_EXECUTE, 0x620)
 293    FIELD(TX_PCIE_MSG_EXECUTE, MSG_DONE_STATUS, 24, 2)
 294    FIELD(TX_PCIE_MSG_EXECUTE, MSG_DONE, 16, 1)
 295    FIELD(TX_PCIE_MSG_EXECUTE, MSG_BUSY, 8, 1)
 296    FIELD(TX_PCIE_MSG_EXECUTE, MSG_EXECUTE, 0, 1)
 297REG32(TX_PCIE_MSG_CONTROL, 0x624)
 298    FIELD(TX_PCIE_MSG_CONTROL, MSG_HAS_DATA, 24, 1)
 299    FIELD(TX_PCIE_MSG_CONTROL, MSG_TAG, 16, 8)
 300    FIELD(TX_PCIE_MSG_CONTROL, MSG_CODE, 8, 8)
 301    FIELD(TX_PCIE_MSG_CONTROL, MSG_FMT_TYPE, 0, 8)
 302REG32(TX_PCIE_MSG_SPECIFIC_LO, 0x628)
 303    FIELD(TX_PCIE_MSG_SPECIFIC_LO, MSG_TLP_HDR11, 24, 8)
 304    FIELD(TX_PCIE_MSG_SPECIFIC_LO, MSG_TLP_HDR10, 16, 8)
 305    FIELD(TX_PCIE_MSG_SPECIFIC_LO, MSG_TLP_HDR9, 8, 8)
 306    FIELD(TX_PCIE_MSG_SPECIFIC_LO, MSG_TLP_HDR8, 0, 8)
 307REG32(TX_PCIE_MSG_SPECIFIC_HI, 0x62c)
 308    FIELD(TX_PCIE_MSG_SPECIFIC_HI, MSG_TLP_HDR15, 24, 8)
 309    FIELD(TX_PCIE_MSG_SPECIFIC_HI, MSG_TLP_HDR14, 16, 8)
 310    FIELD(TX_PCIE_MSG_SPECIFIC_HI, MSG_TLP_HDR13, 8, 8)
 311    FIELD(TX_PCIE_MSG_SPECIFIC_HI, MSG_TLP_HDR12, 0, 8)
 312REG32(TX_PCIE_MSG_DATA, 0x630)
 313
 314#define R_MAX (R_TX_PCIE_MSG_DATA + 1)
 315
 316typedef struct AXIPCIE_MAIN {
 317    PCIExpressHost parent_obj;
 318    MemoryRegion *dma_mr;
 319    AddressSpace *dma_as;
 320    MemTxAttrs *attr;
 321
 322    IOMMUMemoryRegion iommu_attr;
 323    AddressSpace *iommu_attr_as;
 324
 325    MemoryRegion iomem;
 326    MemoryRegion io_ioport;
 327    MemoryRegion io_mmio;
 328    MemoryRegion io_msi;
 329
 330    qemu_irq irq_legacy;
 331    qemu_irq irq_msi[2];
 332
 333    uint32_t regs[R_MAX];
 334    RegisterInfo regs_info[R_MAX];
 335} AXIPCIE_MAIN;
 336
 337static void axipcie_main_update_irq(AXIPCIE_MAIN *s)
 338{
 339    bool legacy;
 340
 341    legacy = s->regs[R_MSGF_LEG_STATUS] & s->regs[R_MSGF_LEG_MASK];
 342    qemu_set_irq(s->irq_legacy, legacy);
 343}
 344
 345static void axipcie_set_irq(void *opaque, int irq_num, int level)
 346{
 347    AXIPCIE_MAIN *s = opaque;
 348
 349    s->regs[R_MSGF_LEG_STATUS] &= ~(1 << irq_num);
 350    s->regs[R_MSGF_LEG_STATUS] |= (!!level) << irq_num;
 351    axipcie_main_update_irq(s);
 352}
 353
 354static void legacy_mask_pw(RegisterInfo *reg, uint64_t val64)
 355{
 356    AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(reg->opaque);
 357    axipcie_main_update_irq(s);
 358}
 359
 360static void update_msi_irqs(AXIPCIE_MAIN *s)
 361{
 362    uint32_t p, m;
 363
 364    p = s->regs[R_MSGF_MSI_STATUS_LO];
 365    m = s->regs[R_MSGF_MSI_MASK_LO];
 366    qemu_set_irq(s->irq_msi[0], p & m);
 367
 368    p = s->regs[R_MSGF_MSI_STATUS_HI];
 369    m = s->regs[R_MSGF_MSI_MASK_HI];
 370    qemu_set_irq(s->irq_msi[1], p & m);
 371}
 372
 373static void msi_update_pw(RegisterInfo *reg, uint64_t val64)
 374{
 375    AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(reg->opaque);
 376    update_msi_irqs(s);
 377}
 378
 379static void msi_mr_update(AXIPCIE_MAIN *s)
 380{
 381    bool msi_en = ARRAY_FIELD_EX32(s->regs, I_MSII_CONTROL, I_MSII_ENABLE);
 382    bool msix_en = ARRAY_FIELD_EX32(s->regs, I_MSIX_CONTROL, I_MSIX_ENABLE);
 383    memory_region_set_enabled(&s->io_msi, msi_en || msix_en);
 384}
 385
 386static void msi_mr_pw(RegisterInfo *reg, uint64_t val64)
 387{
 388    AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(reg->opaque);
 389    msi_mr_update(s);
 390}
 391
 392static const RegisterAccessInfo axipcie_main_regs_info[] = {
 393    {   .name = "BRIDGE_CORE_CFG_PCIE_RX0",  .addr = A_BRIDGE_CORE_CFG_PCIE_RX0,
 394        .reset = 0x10000,
 395        .rsvd = 0xfffcfff8,
 396        .ro = 0xfffcfff8,
 397    },{ .name = "BRIDGE_CORE_CFG_PCIE_RX1",  .addr = A_BRIDGE_CORE_CFG_PCIE_RX1,
 398        .rsvd = 0xfffffe00,
 399        .ro = 0xfffffe00,
 400    },{ .name = "BRIDGE_CORE_CFG_AXI_MASTER",
 401        .addr = A_BRIDGE_CORE_CFG_AXI_MASTER,
 402        .rsvd = 0xffffff88,
 403        .ro = 0xffffff88,
 404    },{ .name = "BRIDGE_CORE_CFG_PCIE_TX",  .addr = A_BRIDGE_CORE_CFG_PCIE_TX,
 405        .rsvd = 0xfffffffe,
 406        .ro = 0xfffffffe,
 407    },{ .name = "BRIDGE_CORE_CFG_INTERRUPT",
 408        .addr = A_BRIDGE_CORE_CFG_INTERRUPT,
 409        .rsvd = 0xfffffffe,
 410        .ro = 0xfffffffe,
 411    },{ .name = "BRIDGE_CORE_CFG_RAM_DISABLE0",
 412        .addr = A_BRIDGE_CORE_CFG_RAM_DISABLE0,
 413        .rsvd = 0xffff8680,
 414        .ro = 0xffff8680,
 415    },{ .name = "BRIDGE_CORE_CFG_RAM_DISABLE1",
 416        .addr = A_BRIDGE_CORE_CFG_RAM_DISABLE1,
 417        .rsvd = 0xffff8680,
 418        .ro = 0xffff8680,
 419    },{ .name = "BRIDGE_CORE_CFG_PCIE_RELAXED_ORDER",
 420        .addr = A_BRIDGE_CORE_CFG_PCIE_RELAXED_ORDER,
 421        .reset = 0x3,
 422        .rsvd = 0xfffffffc,
 423        .ro = 0xfffffffc,
 424    },{ .name = "BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER",
 425        .addr = A_BRIDGE_CORE_CFG_PCIE_RX_MSG_FILTER,
 426        .rsvd = 0x1f51,
 427        .ro = 0x1f51,
 428    },{ .name = "BRIDGE_CORE_CFG_RQ_REQ_ORDER",
 429        .addr = A_BRIDGE_CORE_CFG_RQ_REQ_ORDER,
 430        .rsvd = 0x3fff0000,
 431        .ro = 0x3fff0000,
 432    },{ .name = "BRIDGE_CORE_CFG_PCIE_CREDIT",
 433        .addr = A_BRIDGE_CORE_CFG_PCIE_CREDIT,
 434        .reset = 0x200200,
 435        .rsvd = 0x1f00f000,
 436        .ro = 0x1f00f000,
 437    },{ .name = "BRIDGE_CORE_CFG_AXI_M_W_TICK_COUNT",
 438        .addr = A_BRIDGE_CORE_CFG_AXI_M_W_TICK_COUNT,
 439        .reset = 0xbea,
 440        .rsvd = 0xffff0000,
 441        .ro = 0xffff0000,
 442    },{ .name = "BRIDGE_CORE_CFG_AXI_M_R_TICK_COUNT",
 443        .addr = A_BRIDGE_CORE_CFG_AXI_M_R_TICK_COUNT,
 444        .reset = 0xbea,
 445        .rsvd = 0xffff0000,
 446        .ro = 0xffff0000,
 447    },{ .name = "BRIDGE_CORE_CFG_CRS_RPL_TICK_COUNT",
 448        .addr = A_BRIDGE_CORE_CFG_CRS_RPL_TICK_COUNT,
 449        .reset = 0x2210,
 450        .rsvd = 0xffff0000,
 451        .ro = 0xffff0000,
 452    },{ .name = "E_BREG_CAPABILITIES",  .addr = A_E_BREG_CAPABILITIES,
 453        .reset = 0x30c0001,
 454        .rsvd = 0xfffe,
 455        .ro = 0xffffffff,
 456    },{ .name = "E_BREG_STATUS",  .addr = A_E_BREG_STATUS,
 457        .rsvd = 0xfe00fe00,
 458        .ro = 0xffffffff,
 459    },{ .name = "E_BREG_CONTROL",  .addr = A_E_BREG_CONTROL,
 460        .reset = 0x2,
 461        .rsvd = 0xfffcfff8,
 462        .ro = 0xfffcfff8,
 463    },{ .name = "E_BREG_BASE_LO",  .addr = A_E_BREG_BASE_LO,
 464        .rsvd = 0xfff,
 465        .ro = 0xfff,
 466    },{ .name = "E_BREG_BASE_HI",  .addr = A_E_BREG_BASE_HI,
 467    },{ .name = "E_ECAM_CAPABILITIES",  .addr = A_E_ECAM_CAPABILITIES,
 468        .reset = 0x100c0001,
 469        .rsvd = 0xfffe,
 470        .ro = 0xffffffff,
 471    },{ .name = "E_ECAM_STATUS",  .addr = A_E_ECAM_STATUS,
 472        .rsvd = 0xfe00fe00,
 473        .ro = 0xffffffff,
 474    },{ .name = "E_ECAM_CONTROL",  .addr = A_E_ECAM_CONTROL,
 475        .rsvd = 0xffe0fffa,
 476        .ro = 0xffe0fffa,
 477    },{ .name = "E_ECAM_BASE_LO",  .addr = A_E_ECAM_BASE_LO,
 478        .rsvd = 0xfff,
 479        .ro = 0xfff,
 480    },{ .name = "E_ECAM_BASE_HI",  .addr = A_E_ECAM_BASE_HI,
 481    },{ .name = "E_MSXT_CAPABILITIES",  .addr = A_E_MSXT_CAPABILITIES,
 482        .reset = 0x30c0001,
 483        .rsvd = 0xfffe,
 484        .ro = 0xffffffff,
 485    },{ .name = "E_MSXT_STATUS",  .addr = A_E_MSXT_STATUS,
 486        .rsvd = 0xfe00fe00,
 487        .ro = 0xffffffff,
 488    },{ .name = "E_MSXT_CONTROL",  .addr = A_E_MSXT_CONTROL,
 489        .rsvd = 0xfffcfffa,
 490        .ro = 0xfffcfffa,
 491    },{ .name = "E_MSXT_BASE_LO",  .addr = A_E_MSXT_BASE_LO,
 492        .rsvd = 0xfff,
 493        .ro = 0xfff,
 494    },{ .name = "E_MSXT_BASE_HI",  .addr = A_E_MSXT_BASE_HI,
 495    },{ .name = "E_MSXP_CAPABILITIES",  .addr = A_E_MSXP_CAPABILITIES,
 496        .reset = 0x30c0001,
 497        .rsvd = 0xfffe,
 498        .ro = 0xffffffff,
 499    },{ .name = "E_MSXP_STATUS",  .addr = A_E_MSXP_STATUS,
 500        .rsvd = 0xfe00fe00,
 501        .ro = 0xffffffff,
 502    },{ .name = "E_MSXP_CONTROL",  .addr = A_E_MSXP_CONTROL,
 503        .rsvd = 0xfffcfffa,
 504        .ro = 0xfffcfffa,
 505    },{ .name = "E_MSXP_BASE_LO",  .addr = A_E_MSXP_BASE_LO,
 506        .rsvd = 0xfff,
 507        .ro = 0xfff,
 508    },{ .name = "E_MSXP_BASE_HI",  .addr = A_E_MSXP_BASE_HI,
 509    },{ .name = "E_DREG_CAPABILITIES",  .addr = A_E_DREG_CAPABILITIES,
 510        .reset = 0x30c0001,
 511        .rsvd = 0xfffe,
 512        .ro = 0xffffffff,
 513    },{ .name = "E_DREG_STATUS",  .addr = A_E_DREG_STATUS,
 514        .rsvd = 0xfe00fe00,
 515        .ro = 0xffffffff,
 516    },{ .name = "E_DREG_CONTROL",  .addr = A_E_DREG_CONTROL,
 517        .rsvd = 0xfffcfffa,
 518        .ro = 0xfffcfffa,
 519    },{ .name = "E_DREG_BASE_LO",  .addr = A_E_DREG_BASE_LO,
 520        .rsvd = 0xfff,
 521        .ro = 0xfff,
 522    },{ .name = "E_DREG_BASE_HI",  .addr = A_E_DREG_BASE_HI,
 523    },{ .name = "E_ESUB_CAPABILITIES",  .addr = A_E_ESUB_CAPABILITIES,
 524        .reset = 0x1,
 525        .rsvd = 0xfffffffe,
 526        .ro = 0xffffffff,
 527    },{ .name = "E_ESUB_STATUS",  .addr = A_E_ESUB_STATUS,
 528        .rsvd = 0xfe00fe00,
 529        .ro = 0xffffffff,
 530    },{ .name = "E_ESUB_CONTROL",  .addr = A_E_ESUB_CONTROL,
 531        .reset = 0x1,
 532        .rsvd = 0xfffffffe,
 533        .ro = 0xfffffffe,
 534    },{ .name = "I_MSII_CAPABILITIES",  .addr = A_I_MSII_CAPABILITIES,
 535        .reset = 0x1f0c0001,
 536        .rsvd = 0xfffe,
 537        .ro = 0xffffffff,
 538    },{ .name = "I_MSII_CONTROL",  .addr = A_I_MSII_CONTROL,
 539        .rsvd = 0xffe07ffe,
 540        .ro = 0xffe07ffe,
 541        .post_write = msi_mr_pw,
 542    },{ .name = "I_MSII_BASE_LO",  .addr = A_I_MSII_BASE_LO,
 543        .rsvd = 0xfff,
 544        .ro = 0xfff,
 545    },{ .name = "I_MSII_BASE_HI",  .addr = A_I_MSII_BASE_HI,
 546    },{ .name = "I_MSIX_CAPABILITIES",  .addr = A_I_MSIX_CAPABILITIES,
 547        .reset = 0x1f0c0001,
 548        .rsvd = 0xfffe,
 549        .ro = 0xffffffff,
 550    },{ .name = "I_MSIX_CONTROL",  .addr = A_I_MSIX_CONTROL,
 551        .rsvd = 0xffe0fffe,
 552        .ro = 0xffe0fffe,
 553        .post_write = msi_mr_pw,
 554    },{ .name = "I_MSIX_BASE_LO",  .addr = A_I_MSIX_BASE_LO,
 555        .rsvd = 0xfff,
 556        .ro = 0xfff,
 557    },{ .name = "I_MSIX_BASE_HI",  .addr = A_I_MSIX_BASE_HI,
 558    },{ .name = "I_ISUB_CAPABILITIES",  .addr = A_I_ISUB_CAPABILITIES,
 559        .reset = 0x1,
 560        .rsvd = 0xfffffffe,
 561        .ro = 0xffffffff,
 562    },{ .name = "I_ISUB_STATUS",  .addr = A_I_ISUB_STATUS,
 563        .rsvd = 0xfe00fe00,
 564        .ro = 0xffffffff,
 565    },{ .name = "I_ISUB_CONTROL",  .addr = A_I_ISUB_CONTROL,
 566        .rsvd = 0xfffffffe,
 567        .ro = 0xfffffffe,
 568    },{ .name = "MSGF_MISC_STATUS",  .addr = A_MSGF_MISC_STATUS,
 569        .rsvd = 0xff04,
 570        .ro = 0xff04,
 571        .w1c = 0xffff00fb,
 572    },{ .name = "MSGF_MISC_MASK",  .addr = A_MSGF_MISC_MASK,
 573        .rsvd = 0xff04,
 574        .ro = 0xff04,
 575    },{ .name = "MSGF_MISC_SLAVE_ID",  .addr = A_MSGF_MISC_SLAVE_ID,
 576        .rsvd = 0xffffff00,
 577        .ro = 0xffffffff,
 578    },{ .name = "MSGF_MISC_MASTER_ID",  .addr = A_MSGF_MISC_MASTER_ID,
 579        .rsvd = 0xffffff00,
 580        .ro = 0xffffffff,
 581    },{ .name = "MSGF_MISC_INGRESS_ID",  .addr = A_MSGF_MISC_INGRESS_ID,
 582        .rsvd = 0xffffff00,
 583        .ro = 0xffffffff,
 584    },{ .name = "MSGF_MISC_EGRESS_ID",  .addr = A_MSGF_MISC_EGRESS_ID,
 585        .rsvd = 0xffffff00,
 586        .ro = 0xffffffff,
 587    },{ .name = "MSGF_LEG_STATUS",  .addr = A_MSGF_LEG_STATUS,
 588        .rsvd = 0xfffffff0,
 589        .ro = 0xffffffff,
 590    },{ .name = "MSGF_LEG_MASK",  .addr = A_MSGF_LEG_MASK,
 591        .rsvd = 0xfffffff0,
 592        .ro = 0xfffffff0,
 593        .post_write = legacy_mask_pw,
 594    },{ .name = "MSGF_MSI_STATUS_LO",  .addr = A_MSGF_MSI_STATUS_LO,
 595        .w1c = 0xffffffff,
 596        .post_write = msi_update_pw,
 597    },{ .name = "MSGF_MSI_STATUS_HI",  .addr = A_MSGF_MSI_STATUS_HI,
 598        .w1c = 0xffffffff,
 599        .post_write = msi_update_pw,
 600    },{ .name = "MSGF_MSI_MASK_LO",  .addr = A_MSGF_MSI_MASK_LO,
 601        .post_write = msi_update_pw,
 602    },{ .name = "MSGF_MSI_MASK_HI",  .addr = A_MSGF_MSI_MASK_HI,
 603        .post_write = msi_update_pw,
 604    },{ .name = "MSGF_DMA_STATUS",  .addr = A_MSGF_DMA_STATUS,
 605        .rsvd = 0xfffffffe,
 606        .ro = 0xffffffff,
 607    },{ .name = "MSGF_DMA_MASK",  .addr = A_MSGF_DMA_MASK,
 608        .rsvd = 0xfffffffe,
 609        .ro = 0xfffffffe,
 610    },{ .name = "MSGF_RX_FIFO_LEVEL",  .addr = A_MSGF_RX_FIFO_LEVEL,
 611        .rsvd = 0xffffff00,
 612        .ro = 0xffffffff,
 613    },{ .name = "MSGF_RX_FIFO_POP",  .addr = A_MSGF_RX_FIFO_POP,
 614        .rsvd = 0xfffffffe,
 615        .ro = 0xffffffff,
 616    },{ .name = "MSGF_RX_FIFO_TYPE",  .addr = A_MSGF_RX_FIFO_TYPE,
 617        .rsvd = 0xfffc,
 618        .ro = 0xffffffff,
 619    },{ .name = "MSGF_RX_FIFO_MSG",  .addr = A_MSGF_RX_FIFO_MSG,
 620        .rsvd = 0xff0000f0,
 621        .ro = 0xffffffff,
 622    },{ .name = "MSGF_RX_FIFO_ADDRESS_LO",  .addr = A_MSGF_RX_FIFO_ADDRESS_LO,
 623        .ro = 0xffffffff,
 624    },{ .name = "MSGF_RX_FIFO_ADDRESS_HI",  .addr = A_MSGF_RX_FIFO_ADDRESS_HI,
 625        .ro = 0xffffffff,
 626    },{ .name = "MSGF_RX_FIFO_DATA",  .addr = A_MSGF_RX_FIFO_DATA,
 627        .ro = 0xffffffff,
 628    },{ .name = "TX_PCIE_MSG_EXECUTE",  .addr = A_TX_PCIE_MSG_EXECUTE,
 629        .rsvd = 0xfcfefefe,
 630        .ro = 0xffffffff,
 631    },{ .name = "TX_PCIE_MSG_CONTROL",  .addr = A_TX_PCIE_MSG_CONTROL,
 632        .rsvd = 0xfe000000,
 633        .ro = 0xfe000000,
 634    },{ .name = "TX_PCIE_MSG_SPECIFIC_LO",  .addr = A_TX_PCIE_MSG_SPECIFIC_LO,
 635    },{ .name = "TX_PCIE_MSG_SPECIFIC_HI",  .addr = A_TX_PCIE_MSG_SPECIFIC_HI,
 636    },{ .name = "TX_PCIE_MSG_DATA",  .addr = A_TX_PCIE_MSG_DATA,
 637    }
 638};
 639
 640static void axipcie_main_reset(DeviceState *dev)
 641{
 642    AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(dev);
 643    unsigned int i;
 644
 645    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
 646        register_reset(&s->regs_info[i]);
 647    }
 648
 649    msi_mr_update(s);
 650}
 651
 652static const MemoryRegionOps axipcie_main_ops = {
 653    .read = register_read_memory,
 654    .write = register_write_memory,
 655    .endianness = DEVICE_LITTLE_ENDIAN,
 656    .valid = {
 657        .min_access_size = 4,
 658        .max_access_size = 4,
 659    },
 660};
 661
 662
 663static uint64_t axipcie_msi_read(void *opaque, hwaddr addr, unsigned size)
 664{
 665    return 0;
 666}
 667
 668static void axipcie_msi_write(void *opaque, hwaddr addr, uint64_t value,
 669                      unsigned size)
 670{
 671    AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(opaque);
 672    unsigned int irq = value & 63;
 673
 674    if (irq < 32) {
 675        s->regs[R_MSGF_MSI_STATUS_LO] |= 1 << irq;
 676    } else {
 677        s->regs[R_MSGF_MSI_STATUS_HI] |= 1 << (irq - 32);
 678    }
 679    update_msi_irqs(s);
 680}
 681
 682static const MemoryRegionOps axipcie_msi_ops = {
 683    .read = axipcie_msi_read,
 684    .write = axipcie_msi_write,
 685    .endianness = DEVICE_LITTLE_ENDIAN,
 686    .valid = {
 687        .min_access_size = 4,
 688        .max_access_size = 4,
 689    },
 690};
 691
 692static IOMMUTLBEntry axipcie_translate(IOMMUMemoryRegion *mr, hwaddr addr,
 693                                       bool is_write, MemTxAttrs *attr)
 694{
 695    AXIPCIE_MAIN *s = container_of(mr, AXIPCIE_MAIN, iommu_attr);
 696    IOMMUTLBEntry ret = {
 697        .iova = addr,
 698        .translated_addr = addr,
 699        .addr_mask = ~(hwaddr)0,
 700        .perm = IOMMU_RW,
 701        .target_as = s->dma_as,
 702    };
 703
 704    if (s->attr) {
 705        *attr = *s->attr;
 706    }
 707    return ret;
 708}
 709
 710static AddressSpace *axipcie_dma_as(PCIBus *bus, void *opaque, int devfn)
 711{
 712    return opaque;
 713}
 714
 715static void axipcie_main_realize(DeviceState *dev, Error **errp)
 716{
 717    AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(dev);
 718    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
 719    PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev);
 720    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 721
 722    assert(s->dma_mr);
 723    s->dma_as = s->dma_mr ? address_space_init_shareable(s->dma_mr, NULL)
 724                          : &address_space_memory;
 725
 726    pcie_host_mmcfg_init(pex, PCIE_MMCFG_SIZE_MAX);
 727    memory_region_init(&s->io_mmio, OBJECT(s), "mmio", UINT64_MAX);
 728    /* Xilinx PCIe does not support memory-mapped legacy I/O. We
 729     * create a dummy MR to please pci_register_bus().  */
 730    memory_region_init(&s->io_ioport, OBJECT(s), "ioport", 64 * 1024);
 731
 732    sysbus_init_mmio(sbd, &pex->mmio);
 733    sysbus_init_mmio(sbd, &s->io_mmio);
 734    sysbus_init_irq(sbd, &s->irq_legacy);
 735    sysbus_init_irq(sbd, &s->irq_msi[0]);
 736    sysbus_init_irq(sbd, &s->irq_msi[1]);
 737
 738    pci->bus = pci_register_root_bus(dev, "pcie.0", axipcie_set_irq,
 739                                     pci_swizzle_map_irq_fn, s, &s->io_mmio,
 740                                     &s->io_ioport, PCI_DEVFN(0, 0), 4,
 741                                     TYPE_PCIE_BUS);
 742
 743    memory_region_init_iommu(&s->iommu_attr, sizeof(s->iommu_attr), 
 744                             TYPE_XILINX_AXIPCIE_MAIN_IOMMU_MEMORY_REGION,
 745                             OBJECT(s),
 746                             "axipcie-attr-iommu", UINT64_MAX);
 747    s->iommu_attr_as = address_space_init_shareable(MEMORY_REGION(&s->iommu_attr), NULL);
 748
 749    pci_setup_iommu(pci->bus, axipcie_dma_as, s->iommu_attr_as);
 750}
 751
 752static void axipcie_main_init(Object *obj)
 753{
 754    AXIPCIE_MAIN *s = XILINX_AXIPCIE_MAIN(obj);
 755    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 756    RegisterInfoArray *reg_array;
 757
 758    memory_region_init(&s->iomem, obj, TYPE_XILINX_AXIPCIE_MAIN, R_MAX * 4);
 759    reg_array =
 760        register_init_block32(DEVICE(obj), axipcie_main_regs_info,
 761                              ARRAY_SIZE(axipcie_main_regs_info),
 762                              s->regs_info, s->regs,
 763                              &axipcie_main_ops,
 764                              XILINX_AXIPCIE_MAIN_ERR_DEBUG,
 765                              R_MAX * 4);
 766    memory_region_add_subregion(&s->iomem, 0x0, &reg_array->mem);
 767    sysbus_init_mmio(sbd, &s->iomem);
 768    memory_region_init_io(&s->io_msi, obj, &axipcie_msi_ops, s,
 769                          "axipcie-msi", 0x100);
 770    sysbus_init_mmio(sbd, &s->io_msi);
 771    msi_nonbroken = true;
 772
 773    object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
 774                             (Object **)&s->dma_mr,
 775                             qdev_prop_allow_set_link_before_realize,
 776                             OBJ_PROP_LINK_STRONG);
 777    object_property_add_link(obj, "memattr", TYPE_MEMORY_TRANSACTION_ATTR,
 778                             (Object **)&s->attr,
 779                             qdev_prop_allow_set_link_before_realize,
 780                             OBJ_PROP_LINK_STRONG);
 781}
 782
 783static const VMStateDescription vmstate_axipcie_main = {
 784    .name = TYPE_XILINX_AXIPCIE_MAIN,
 785    .version_id = 1,
 786    .minimum_version_id = 1,
 787    .minimum_version_id_old = 1,
 788    .fields = (VMStateField[]) {
 789        VMSTATE_UINT32_ARRAY(regs, AXIPCIE_MAIN, R_MAX),
 790        VMSTATE_END_OF_LIST(),
 791    }
 792};
 793
 794static const char *axipcie_main_host_root_bus_path(PCIHostState *host_bridge,
 795                                                   PCIBus *rootbus)
 796{
 797    return "0000:00";
 798}
 799
 800static void axipcie_main_class_init(ObjectClass *klass, void *data)
 801{
 802    DeviceClass *dc = DEVICE_CLASS(klass);
 803    PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
 804
 805    dc->reset = axipcie_main_reset;
 806    dc->realize = axipcie_main_realize;
 807    dc->vmsd = &vmstate_axipcie_main;
 808
 809    hc->root_bus_path = axipcie_main_host_root_bus_path;
 810}
 811
 812static void axipcie_main_iommu_memory_region_class_init(ObjectClass *klass,
 813                                                   void *data)
 814{
 815    IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
 816
 817    imrc->translate_attr = axipcie_translate;
 818}
 819
 820static const TypeInfo axipcie_main_info = {
 821    .name          = TYPE_XILINX_AXIPCIE_MAIN,
 822    .parent        = TYPE_PCIE_HOST_BRIDGE,
 823    .instance_size = sizeof(AXIPCIE_MAIN),
 824    .class_init    = axipcie_main_class_init,
 825    .instance_init = axipcie_main_init,
 826};
 827
 828static const TypeInfo axipcie_main_iommu_memory_region_info = {
 829    .name = TYPE_XILINX_AXIPCIE_MAIN_IOMMU_MEMORY_REGION,
 830    .parent = TYPE_IOMMU_MEMORY_REGION,
 831    .class_init = axipcie_main_iommu_memory_region_class_init,
 832};
 833
 834
 835static void axipcie_main_register_types(void)
 836{
 837    type_register_static(&axipcie_main_info);
 838    type_register_static(&axipcie_main_iommu_memory_region_info);
 839}
 840
 841type_init(axipcie_main_register_types)
 842