pcie.c (84a5a8014801a83d1b8d15fa7f0fde03db081530) | pcie.c (6383292ac884f01be609f69d888f54c099af622e) |
---|---|
1/* 2 * pcie.c 3 * 4 * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp> 5 * VA Linux Systems Japan K.K. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by --- 29 unchanged lines hidden (view full) --- 38#endif 39#define PCIE_DEV_PRINTF(dev, fmt, ...) \ 40 PCIE_DPRINTF("%s:%x "fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__) 41 42 43/*************************************************************************** 44 * pci express capability helper functions 45 */ | 1/* 2 * pcie.c 3 * 4 * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp> 5 * VA Linux Systems Japan K.K. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by --- 29 unchanged lines hidden (view full) --- 38#endif 39#define PCIE_DEV_PRINTF(dev, fmt, ...) \ 40 PCIE_DPRINTF("%s:%x "fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__) 41 42 43/*************************************************************************** 44 * pci express capability helper functions 45 */ |
46int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port) 47{ 48 int pos; 49 uint8_t *exp_cap; | |
50 | 46 |
51 assert(pci_is_express(dev)); 52 53 pos = pci_add_capability(dev, PCI_CAP_ID_EXP, offset, 54 PCI_EXP_VER2_SIZEOF); 55 if (pos < 0) { 56 return pos; 57 } 58 dev->exp.exp_cap = pos; 59 exp_cap = dev->config + pos; 60 | 47static void 48pcie_cap_v1_fill(uint8_t *exp_cap, uint8_t port, uint8_t type, uint8_t version) 49{ |
61 /* capability register | 50 /* capability register |
62 interrupt message number defaults to 0 */ | 51 interrupt message number defaults to 0 */ |
63 pci_set_word(exp_cap + PCI_EXP_FLAGS, 64 ((type << PCI_EXP_FLAGS_TYPE_SHIFT) & PCI_EXP_FLAGS_TYPE) | | 52 pci_set_word(exp_cap + PCI_EXP_FLAGS, 53 ((type << PCI_EXP_FLAGS_TYPE_SHIFT) & PCI_EXP_FLAGS_TYPE) | |
65 PCI_EXP_FLAGS_VER2); | 54 version); |
66 67 /* device capability register 68 * table 7-12: 69 * roll based error reporting bit must be set by all 70 * Functions conforming to the ECN, PCI Express Base 71 * Specification, Revision 1.1., or subsequent PCI Express Base 72 * Specification revisions. 73 */ 74 pci_set_long(exp_cap + PCI_EXP_DEVCAP, PCI_EXP_DEVCAP_RBER); 75 76 pci_set_long(exp_cap + PCI_EXP_LNKCAP, 77 (port << PCI_EXP_LNKCAP_PN_SHIFT) | 78 PCI_EXP_LNKCAP_ASPMS_0S | 79 PCI_EXP_LNK_MLW_1 | 80 PCI_EXP_LNK_LS_25); 81 82 pci_set_word(exp_cap + PCI_EXP_LNKSTA, 83 PCI_EXP_LNK_MLW_1 | PCI_EXP_LNK_LS_25 |PCI_EXP_LNKSTA_DLLLA); | 55 56 /* device capability register 57 * table 7-12: 58 * roll based error reporting bit must be set by all 59 * Functions conforming to the ECN, PCI Express Base 60 * Specification, Revision 1.1., or subsequent PCI Express Base 61 * Specification revisions. 62 */ 63 pci_set_long(exp_cap + PCI_EXP_DEVCAP, PCI_EXP_DEVCAP_RBER); 64 65 pci_set_long(exp_cap + PCI_EXP_LNKCAP, 66 (port << PCI_EXP_LNKCAP_PN_SHIFT) | 67 PCI_EXP_LNKCAP_ASPMS_0S | 68 PCI_EXP_LNK_MLW_1 | 69 PCI_EXP_LNK_LS_25); 70 71 pci_set_word(exp_cap + PCI_EXP_LNKSTA, 72 PCI_EXP_LNK_MLW_1 | PCI_EXP_LNK_LS_25 |PCI_EXP_LNKSTA_DLLLA); |
73} |
|
84 | 74 |
75int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port) 76{ 77 /* PCIe cap v2 init */ 78 int pos; 79 uint8_t *exp_cap; 80 81 assert(pci_is_express(dev)); 82 83 pos = pci_add_capability(dev, PCI_CAP_ID_EXP, offset, PCI_EXP_VER2_SIZEOF); 84 if (pos < 0) { 85 return pos; 86 } 87 dev->exp.exp_cap = pos; 88 exp_cap = dev->config + pos; 89 90 /* Filling values common with v1 */ 91 pcie_cap_v1_fill(exp_cap, port, type, PCI_EXP_FLAGS_VER2); 92 93 /* Filling v2 specific values */ |
|
85 pci_set_long(exp_cap + PCI_EXP_DEVCAP2, 86 PCI_EXP_DEVCAP2_EFF | PCI_EXP_DEVCAP2_EETLPP); 87 88 pci_set_word(dev->wmask + pos + PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_EETLPPB); 89 return pos; 90} 91 | 94 pci_set_long(exp_cap + PCI_EXP_DEVCAP2, 95 PCI_EXP_DEVCAP2_EFF | PCI_EXP_DEVCAP2_EETLPP); 96 97 pci_set_word(dev->wmask + pos + PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_EETLPPB); 98 return pos; 99} 100 |
92int pcie_endpoint_cap_init(PCIDevice *dev, uint8_t offset) | 101int pcie_cap_v1_init(PCIDevice *dev, uint8_t offset, uint8_t type, 102 uint8_t port) |
93{ | 103{ |
104 /* PCIe cap v1 init */ 105 int pos; 106 uint8_t *exp_cap; 107 108 assert(pci_is_express(dev)); 109 110 pos = pci_add_capability(dev, PCI_CAP_ID_EXP, offset, PCI_EXP_VER1_SIZEOF); 111 if (pos < 0) { 112 return pos; 113 } 114 dev->exp.exp_cap = pos; 115 exp_cap = dev->config + pos; 116 117 pcie_cap_v1_fill(exp_cap, port, type, PCI_EXP_FLAGS_VER1); 118 119 return pos; 120} 121 122static int 123pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size) 124{ |
|
94 uint8_t type = PCI_EXP_TYPE_ENDPOINT; 95 96 /* 97 * Windows guests will report Code 10, device cannot start, if 98 * a regular Endpoint type is exposed on a root complex. These 99 * should instead be Root Complex Integrated Endpoints. 100 */ 101 if (pci_bus_is_express(dev->bus) && pci_bus_is_root(dev->bus)) { 102 type = PCI_EXP_TYPE_RC_END; 103 } 104 | 125 uint8_t type = PCI_EXP_TYPE_ENDPOINT; 126 127 /* 128 * Windows guests will report Code 10, device cannot start, if 129 * a regular Endpoint type is exposed on a root complex. These 130 * should instead be Root Complex Integrated Endpoints. 131 */ 132 if (pci_bus_is_express(dev->bus) && pci_bus_is_root(dev->bus)) { 133 type = PCI_EXP_TYPE_RC_END; 134 } 135 |
105 return pcie_cap_init(dev, offset, type, 0); | 136 return (cap_size == PCI_EXP_VER1_SIZEOF) 137 ? pcie_cap_v1_init(dev, offset, type, 0) 138 : pcie_cap_init(dev, offset, type, 0); |
106} 107 | 139} 140 |
141int pcie_endpoint_cap_init(PCIDevice *dev, uint8_t offset) 142{ 143 return pcie_endpoint_cap_common_init(dev, offset, PCI_EXP_VER2_SIZEOF); 144} 145 146int pcie_endpoint_cap_v1_init(PCIDevice *dev, uint8_t offset) 147{ 148 return pcie_endpoint_cap_common_init(dev, offset, PCI_EXP_VER1_SIZEOF); 149} 150 |
|
108void pcie_cap_exit(PCIDevice *dev) 109{ 110 pci_del_capability(dev, PCI_CAP_ID_EXP, PCI_EXP_VER2_SIZEOF); 111} 112 | 151void pcie_cap_exit(PCIDevice *dev) 152{ 153 pci_del_capability(dev, PCI_CAP_ID_EXP, PCI_EXP_VER2_SIZEOF); 154} 155 |
156void pcie_cap_v1_exit(PCIDevice *dev) 157{ 158 pci_del_capability(dev, PCI_CAP_ID_EXP, PCI_EXP_VER1_SIZEOF); 159} 160 |
|
113uint8_t pcie_cap_get_type(const PCIDevice *dev) 114{ 115 uint32_t pos = dev->exp.exp_cap; 116 assert(pos > 0); 117 return (pci_get_word(dev->config + pos + PCI_EXP_FLAGS) & 118 PCI_EXP_FLAGS_TYPE) >> PCI_EXP_FLAGS_TYPE_SHIFT; 119} 120 --- 529 unchanged lines hidden --- | 161uint8_t pcie_cap_get_type(const PCIDevice *dev) 162{ 163 uint32_t pos = dev->exp.exp_cap; 164 assert(pos > 0); 165 return (pci_get_word(dev->config + pos + PCI_EXP_FLAGS) & 166 PCI_EXP_FLAGS_TYPE) >> PCI_EXP_FLAGS_TYPE_SHIFT; 167} 168 --- 529 unchanged lines hidden --- |