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 ---