Skip to content

Commit 2709f03

Browse files
committed
Merge branch 'remotes/lorenzo/pci/bridge-emul'
- Make emulated ROM BAR read-only by default (Pali Rohár) - Make some emulated legacy PCI bits read-only for PCIe devices (Pali Rohár) - Update reserved bits in emulated PCIe Capability (Pali Rohár) - Allow drivers to emulate different PCIe Capability versions (Pali Rohár) - Set emulated Capabilities List bit for all PCIe devices, since they must have at least a PCIe Capability (Pali Rohár) * remotes/lorenzo/pci/bridge-emul: PCI: pci-bridge-emul: Set PCI_STATUS_CAP_LIST for PCIe device PCI: pci-bridge-emul: Correctly set PCIe capabilities PCI: pci-bridge-emul: Fix definitions of reserved bits PCI: pci-bridge-emul: Properly mark reserved PCIe bits in PCI config space PCI: pci-bridge-emul: Make expansion ROM Base Address register read-only
2 parents a99f501 + 3be9d24 commit 2709f03

File tree

3 files changed

+65
-17
lines changed

3 files changed

+65
-17
lines changed

drivers/pci/controller/pci-aardvark.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,6 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
883883
return PCI_BRIDGE_EMUL_HANDLED;
884884
}
885885

886-
case PCI_CAP_LIST_ID:
887886
case PCI_EXP_DEVCAP:
888887
case PCI_EXP_DEVCTL:
889888
case PCI_EXP_DEVCAP2:
@@ -971,6 +970,9 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie)
971970
/* Support interrupt A for MSI feature */
972971
bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE;
973972

973+
/* Aardvark HW provides PCIe Capability structure in version 2 */
974+
bridge->pcie_conf.cap = cpu_to_le16(2);
975+
974976
/* Indicates supports for Completion Retry Status */
975977
bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS);
976978

drivers/pci/controller/pci-mvebu.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,8 @@ static struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = {
723723
static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
724724
{
725725
struct pci_bridge_emul *bridge = &port->bridge;
726+
u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP);
727+
u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS);
726728

727729
bridge->conf.vendor = PCI_VENDOR_ID_MARVELL;
728730
bridge->conf.device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16;
@@ -735,6 +737,12 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
735737
bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32;
736738
}
737739

740+
/*
741+
* Older mvebu hardware provides PCIe Capability structure only in
742+
* version 1. New hardware provides it in version 2.
743+
*/
744+
bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver);
745+
738746
bridge->has_pcie = true;
739747
bridge->data = port;
740748
bridge->ops = &mvebu_pci_bridge_emul_ops;

drivers/pci/pci-bridge-emul.c

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,13 @@ struct pci_bridge_reg_behavior pci_regs_behavior[PCI_STD_HEADER_SIZEOF / 4] = {
139139
.ro = GENMASK(7, 0),
140140
},
141141

142+
/*
143+
* If expansion ROM is unsupported then ROM Base Address register must
144+
* be implemented as read-only register that return 0 when read, same
145+
* as for unused Base Address registers.
146+
*/
142147
[PCI_ROM_ADDRESS1 / 4] = {
143-
.rw = GENMASK(31, 11) | BIT(0),
148+
.ro = ~0,
144149
},
145150

146151
/*
@@ -171,41 +176,55 @@ struct pci_bridge_reg_behavior pcie_cap_regs_behavior[PCI_CAP_PCIE_SIZEOF / 4] =
171176
[PCI_CAP_LIST_ID / 4] = {
172177
/*
173178
* Capability ID, Next Capability Pointer and
174-
* Capabilities register are all read-only.
179+
* bits [14:0] of Capabilities register are all read-only.
180+
* Bit 15 of Capabilities register is reserved.
175181
*/
176-
.ro = ~0,
182+
.ro = GENMASK(30, 0),
177183
},
178184

179185
[PCI_EXP_DEVCAP / 4] = {
180-
.ro = ~0,
186+
/*
187+
* Bits [31:29] and [17:16] are reserved.
188+
* Bits [27:18] are reserved for non-upstream ports.
189+
* Bits 28 and [14:6] are reserved for non-endpoint devices.
190+
* Other bits are read-only.
191+
*/
192+
.ro = BIT(15) | GENMASK(5, 0),
181193
},
182194

183195
[PCI_EXP_DEVCTL / 4] = {
184-
/* Device control register is RW */
185-
.rw = GENMASK(15, 0),
196+
/*
197+
* Device control register is RW, except bit 15 which is
198+
* reserved for non-endpoints or non-PCIe-to-PCI/X bridges.
199+
*/
200+
.rw = GENMASK(14, 0),
186201

187202
/*
188203
* Device status register has bits 6 and [3:0] W1C, [5:4] RO,
189-
* the rest is reserved
204+
* the rest is reserved. Also bit 6 is reserved for non-upstream
205+
* ports.
190206
*/
191-
.w1c = (BIT(6) | GENMASK(3, 0)) << 16,
207+
.w1c = GENMASK(3, 0) << 16,
192208
.ro = GENMASK(5, 4) << 16,
193209
},
194210

195211
[PCI_EXP_LNKCAP / 4] = {
196-
/* All bits are RO, except bit 23 which is reserved */
197-
.ro = lower_32_bits(~BIT(23)),
212+
/*
213+
* All bits are RO, except bit 23 which is reserved and
214+
* bit 18 which is reserved for non-upstream ports.
215+
*/
216+
.ro = lower_32_bits(~(BIT(23) | PCI_EXP_LNKCAP_CLKPM)),
198217
},
199218

200219
[PCI_EXP_LNKCTL / 4] = {
201220
/*
202221
* Link control has bits [15:14], [11:3] and [1:0] RW, the
203-
* rest is reserved.
222+
* rest is reserved. Bit 8 is reserved for non-upstream ports.
204223
*
205224
* Link status has bits [13:0] RO, and bits [15:14]
206225
* W1C.
207226
*/
208-
.rw = GENMASK(15, 14) | GENMASK(11, 3) | GENMASK(1, 0),
227+
.rw = GENMASK(15, 14) | GENMASK(11, 9) | GENMASK(7, 3) | GENMASK(1, 0),
209228
.ro = GENMASK(13, 0) << 16,
210229
.w1c = GENMASK(15, 14) << 16,
211230
},
@@ -324,11 +343,9 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
324343

325344
if (bridge->has_pcie) {
326345
bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START;
346+
bridge->conf.status |= cpu_to_le16(PCI_STATUS_CAP_LIST);
327347
bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP;
328-
/* Set PCIe v2, root port, slot support */
329-
bridge->pcie_conf.cap =
330-
cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4 | 2 |
331-
PCI_EXP_FLAGS_SLOT);
348+
bridge->pcie_conf.cap |= cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4);
332349
bridge->pcie_cap_regs_behavior =
333350
kmemdup(pcie_cap_regs_behavior,
334351
sizeof(pcie_cap_regs_behavior),
@@ -337,6 +354,27 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
337354
kfree(bridge->pci_regs_behavior);
338355
return -ENOMEM;
339356
}
357+
/* These bits are applicable only for PCI and reserved on PCIe */
358+
bridge->pci_regs_behavior[PCI_CACHE_LINE_SIZE / 4].ro &=
359+
~GENMASK(15, 8);
360+
bridge->pci_regs_behavior[PCI_COMMAND / 4].ro &=
361+
~((PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE |
362+
PCI_COMMAND_VGA_PALETTE | PCI_COMMAND_WAIT |
363+
PCI_COMMAND_FAST_BACK) |
364+
(PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK |
365+
PCI_STATUS_DEVSEL_MASK) << 16);
366+
bridge->pci_regs_behavior[PCI_PRIMARY_BUS / 4].ro &=
367+
~GENMASK(31, 24);
368+
bridge->pci_regs_behavior[PCI_IO_BASE / 4].ro &=
369+
~((PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK |
370+
PCI_STATUS_DEVSEL_MASK) << 16);
371+
bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].rw &=
372+
~((PCI_BRIDGE_CTL_MASTER_ABORT |
373+
BIT(8) | BIT(9) | BIT(11)) << 16);
374+
bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].ro &=
375+
~((PCI_BRIDGE_CTL_FAST_BACK) << 16);
376+
bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].w1c &=
377+
~(BIT(10) << 16);
340378
}
341379

342380
if (flags & PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR) {

0 commit comments

Comments
 (0)