ia64/xen-unstable

changeset 18438:a5bf2535e7bb

ioemu: support PCI Express Capability Structure version 1.
Signed-off-by: Yuji Shimada <shimada-yxb@necst.nec.co.jp>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Sep 04 11:28:17 2008 +0100 (2008-09-04)
parents 294fc8fc4ba0
children 7d1eadfe4631
files tools/ioemu/hw/pass-through.c tools/ioemu/hw/pass-through.h
line diff
     1.1 --- a/tools/ioemu/hw/pass-through.c	Thu Sep 04 11:26:25 2008 +0100
     1.2 +++ b/tools/ioemu/hw/pass-through.c	Thu Sep 04 11:28:17 2008 +0100
     1.3 @@ -57,6 +57,10 @@ static uint32_t pt_irqpin_reg_init(struc
     1.4      struct pt_reg_info_tbl *reg, uint32_t real_offset);
     1.5  static uint32_t pt_bar_reg_init(struct pt_dev *ptdev,
     1.6      struct pt_reg_info_tbl *reg, uint32_t real_offset);
     1.7 +static uint32_t pt_linkctrl_reg_init(struct pt_dev *ptdev,
     1.8 +    struct pt_reg_info_tbl *reg, uint32_t real_offset);
     1.9 +static uint32_t pt_devctrl2_reg_init(struct pt_dev *ptdev,
    1.10 +    struct pt_reg_info_tbl *reg, uint32_t real_offset);
    1.11  static uint32_t pt_linkctrl2_reg_init(struct pt_dev *ptdev,
    1.12      struct pt_reg_info_tbl *reg, uint32_t real_offset);
    1.13  static uint32_t pt_msgctrl_reg_init(struct pt_dev *ptdev,
    1.14 @@ -77,6 +81,8 @@ static uint8_t pt_msix_size_init(struct 
    1.15      struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset);
    1.16  static uint8_t pt_vendor_size_init(struct pt_dev *ptdev,
    1.17      struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset);
    1.18 +static uint8_t pt_pcie_size_init(struct pt_dev *ptdev,
    1.19 +    struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset);
    1.20  static int pt_byte_reg_read(struct pt_dev *ptdev,
    1.21      struct pt_reg_tbl *cfg_entry,
    1.22      uint8_t *valueu, uint8_t valid_mask);
    1.23 @@ -438,7 +444,7 @@ static struct pt_reg_info_tbl pt_emu_reg
    1.24          .init_val   = 0x0000,
    1.25          .ro_mask    = 0x0000,
    1.26          .emu_mask   = 0xFFFF,
    1.27 -        .init       = pt_common_reg_init,
    1.28 +        .init       = pt_linkctrl_reg_init,
    1.29          .u.w.read   = pt_word_reg_read,
    1.30          .u.w.write  = pt_linkctrl_reg_write,
    1.31      },
    1.32 @@ -449,7 +455,7 @@ static struct pt_reg_info_tbl pt_emu_reg
    1.33          .init_val   = 0x0000,
    1.34          .ro_mask    = 0x0000,
    1.35          .emu_mask   = 0xFFFF,
    1.36 -        .init       = pt_common_reg_init,
    1.37 +        .init       = pt_devctrl2_reg_init,
    1.38          .u.w.read   = pt_word_reg_read,
    1.39          .u.w.write  = pt_devctrl2_reg_write,
    1.40      },
    1.41 @@ -666,8 +672,8 @@ static const struct pt_reg_grp_info_tbl 
    1.42      {
    1.43          .grp_id     = PCI_CAP_ID_EXP,
    1.44          .grp_type   = GRP_TYPE_EMU,
    1.45 -        .grp_size   = 0x3C,
    1.46 -        .size_init  = pt_reg_grp_size_init,
    1.47 +        .grp_size   = 0xFF,
    1.48 +        .size_init  = pt_pcie_size_init,
    1.49          .emu_reg_tbl= pt_emu_reg_pcie_tbl,
    1.50      },
    1.51      /* MSI-X Capability Structure reg group */
    1.52 @@ -1869,12 +1875,57 @@ static uint32_t pt_bar_reg_init(struct p
    1.53      return reg_field;
    1.54  }
    1.55  
    1.56 +/* initialize Link Control register */
    1.57 +static uint32_t pt_linkctrl_reg_init(struct pt_dev *ptdev,
    1.58 +        struct pt_reg_info_tbl *reg, uint32_t real_offset)
    1.59 +{
    1.60 +    uint8_t cap_ver = 0;
    1.61 +    uint8_t dev_type = 0;
    1.62 +
    1.63 +    cap_ver = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] &
    1.64 +        (uint8_t)PCI_EXP_FLAGS_VERS);
    1.65 +    dev_type = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] &
    1.66 +        (uint8_t)PCI_EXP_FLAGS_TYPE) >> 4;
    1.67 +    
    1.68 +    /* no need to initialize in case of Root Complex Integrated Endpoint
    1.69 +     * with cap_ver 1.x 
    1.70 +     */
    1.71 +    if ((dev_type == PCI_EXP_TYPE_ROOT_INT_EP) && (cap_ver == 1))
    1.72 +        return PT_INVALID_REG;
    1.73 +
    1.74 +    return reg->init_val;
    1.75 +}
    1.76 +
    1.77 +/* initialize Device Control 2 register */
    1.78 +static uint32_t pt_devctrl2_reg_init(struct pt_dev *ptdev,
    1.79 +        struct pt_reg_info_tbl *reg, uint32_t real_offset)
    1.80 +{
    1.81 +    uint8_t cap_ver = 0;
    1.82 +
    1.83 +    cap_ver = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] &
    1.84 +        (uint8_t)PCI_EXP_FLAGS_VERS);
    1.85 +    
    1.86 +    /* no need to initialize in case of cap_ver 1.x */
    1.87 +    if (cap_ver == 1)
    1.88 +        return PT_INVALID_REG;
    1.89 +
    1.90 +    return reg->init_val;
    1.91 +}
    1.92 +
    1.93  /* initialize Link Control 2 register */
    1.94  static uint32_t pt_linkctrl2_reg_init(struct pt_dev *ptdev,
    1.95          struct pt_reg_info_tbl *reg, uint32_t real_offset)
    1.96  {
    1.97      int reg_field = 0;
    1.98 -
    1.99 +    uint8_t cap_ver = 0;
   1.100 +
   1.101 +    cap_ver = (ptdev->dev.config[(real_offset - reg->offset) + PCI_EXP_FLAGS] &
   1.102 +        (uint8_t)PCI_EXP_FLAGS_VERS);
   1.103 +    
   1.104 +    /* no need to initialize in case of cap_ver 1.x */
   1.105 +    if (cap_ver == 1)
   1.106 +        return PT_INVALID_REG;
   1.107 +    
   1.108      /* set Supported Link Speed */
   1.109      reg_field |= 
   1.110          (0x0F & 
   1.111 @@ -2036,6 +2087,91 @@ static uint8_t pt_vendor_size_init(struc
   1.112      return ptdev->dev.config[base_offset + 0x02];
   1.113  }
   1.114  
   1.115 +/* get PCI Express Capability Structure register group size */
   1.116 +static uint8_t pt_pcie_size_init(struct pt_dev *ptdev,
   1.117 +        struct pt_reg_grp_info_tbl *grp_reg, uint32_t base_offset)
   1.118 +{
   1.119 +    PCIDevice *d = &ptdev->dev;
   1.120 +    uint16_t exp_flag = 0;
   1.121 +    uint16_t type = 0;
   1.122 +    uint16_t vers = 0;
   1.123 +    uint8_t pcie_size = 0;
   1.124 +
   1.125 +    exp_flag = *((uint16_t*)(d->config + (base_offset + PCI_EXP_FLAGS)));
   1.126 +    type = (exp_flag & PCI_EXP_FLAGS_TYPE) >> 4;
   1.127 +    vers = (exp_flag & PCI_EXP_FLAGS_VERS);
   1.128 +
   1.129 +    /* calculate size depend on capability version and device/port type */
   1.130 +    /* in case of PCI Express Base Specification Rev 1.x */
   1.131 +    if (vers == 1)
   1.132 +    {
   1.133 +        /* The PCI Express Capabilities, Device Capabilities, and Device 
   1.134 +         * Status/Control registers are required for all PCI Express devices. 
   1.135 +         * The Link Capabilities and Link Status/Control are required for all 
   1.136 +         * Endpoints that are not Root Complex Integrated Endpoints. Endpoints 
   1.137 +         * are not required to implement registers other than those listed 
   1.138 +         * above and terminate the capability structure.
   1.139 +         */
   1.140 +        switch (type) {
   1.141 +        case PCI_EXP_TYPE_ENDPOINT:
   1.142 +        case PCI_EXP_TYPE_LEG_END:
   1.143 +            pcie_size = 0x14;
   1.144 +            break;
   1.145 +        case PCI_EXP_TYPE_ROOT_INT_EP:
   1.146 +            /* has no link */
   1.147 +            pcie_size = 0x0C;
   1.148 +            break;
   1.149 +        /* only EndPoint passthrough is supported */
   1.150 +        case PCI_EXP_TYPE_ROOT_PORT:
   1.151 +        case PCI_EXP_TYPE_UPSTREAM:
   1.152 +        case PCI_EXP_TYPE_DOWNSTREAM:
   1.153 +        case PCI_EXP_TYPE_PCI_BRIDGE:
   1.154 +        case PCI_EXP_TYPE_PCIE_BRIDGE:
   1.155 +        case PCI_EXP_TYPE_ROOT_EC:
   1.156 +        default:
   1.157 +            /* exit I/O emulator */
   1.158 +            PT_LOG("Internal error: Unsupported device/port type[%d]. "
   1.159 +                "I/O emulator exit.\n", type);
   1.160 +            exit(1);
   1.161 +        }
   1.162 +    }
   1.163 +    /* in case of PCI Express Base Specification Rev 2.0 */
   1.164 +    else if (vers == 2)
   1.165 +    {
   1.166 +        switch (type) {
   1.167 +        case PCI_EXP_TYPE_ENDPOINT:
   1.168 +        case PCI_EXP_TYPE_LEG_END:
   1.169 +        case PCI_EXP_TYPE_ROOT_INT_EP:
   1.170 +            /* For Functions that do not implement the registers, 
   1.171 +             * these spaces must be hardwired to 0b.
   1.172 +             */
   1.173 +            pcie_size = 0x3C;
   1.174 +            break;
   1.175 +        /* only EndPoint passthrough is supported */
   1.176 +        case PCI_EXP_TYPE_ROOT_PORT:
   1.177 +        case PCI_EXP_TYPE_UPSTREAM:
   1.178 +        case PCI_EXP_TYPE_DOWNSTREAM:
   1.179 +        case PCI_EXP_TYPE_PCI_BRIDGE:
   1.180 +        case PCI_EXP_TYPE_PCIE_BRIDGE:
   1.181 +        case PCI_EXP_TYPE_ROOT_EC:
   1.182 +        default:
   1.183 +            /* exit I/O emulator */
   1.184 +            PT_LOG("Internal error: Unsupported device/port type[%d]. "
   1.185 +                "I/O emulator exit.\n", type);
   1.186 +            exit(1);
   1.187 +        }
   1.188 +    }
   1.189 +    else
   1.190 +    {
   1.191 +        /* exit I/O emulator */
   1.192 +        PT_LOG("Internal error: Unsupported capability version[%d]. "
   1.193 +            "I/O emulator exit.\n", vers);
   1.194 +        exit(1);
   1.195 +    }
   1.196 +
   1.197 +    return pcie_size;
   1.198 +}
   1.199 +
   1.200  /* read byte size emulate register */
   1.201  static int pt_byte_reg_read(struct pt_dev *ptdev,
   1.202          struct pt_reg_tbl *cfg_entry,
     2.1 --- a/tools/ioemu/hw/pass-through.h	Thu Sep 04 11:26:25 2008 +0100
     2.2 +++ b/tools/ioemu/hw/pass-through.h	Thu Sep 04 11:28:17 2008 +0100
     2.3 @@ -62,6 +62,21 @@
     2.4  #define PCI_MSI_FLAGS_MASK_BIT  0x0100
     2.5  #endif
     2.6  
     2.7 +#ifndef PCI_EXP_TYPE_PCIE_BRIDGE
     2.8 +/* PCI/PCI-X to PCIE Bridge */
     2.9 +#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8
    2.10 +#endif
    2.11 +
    2.12 +#ifndef PCI_EXP_TYPE_ROOT_INT_EP
    2.13 +/* Root Complex Integrated Endpoint */
    2.14 +#define PCI_EXP_TYPE_ROOT_INT_EP 0x9
    2.15 +#endif
    2.16 +
    2.17 +#ifndef PCI_EXP_TYPE_ROOT_EC
    2.18 +/* Root Complex Event Collector */
    2.19 +#define PCI_EXP_TYPE_ROOT_EC     0xa
    2.20 +#endif
    2.21 +
    2.22  #define PT_INVALID_REG          0xFFFFFFFF      /* invalid register value */
    2.23  #define PT_BAR_ALLF             0xFFFFFFFF      /* BAR ALLF value */
    2.24  #define PT_BAR_MEM_RO_MASK      0x0000000F      /* BAR ReadOnly mask(Memory) */