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