Lines Matching +full:ports +full:- +full:implemented
1 // SPDX-License-Identifier: GPL-2.0
21 #include "pci-bridge-emul.h"
28 * struct pci_bridge_reg_behavior - register bits behaviors
29 * @ro: Read-Only bits
30 * @rw: Read-Write bits
31 * @w1c: Write-1-to-Clear bits
36 * multi-bit fields) when read".
39 /* Read-only bits */
42 /* Read-write bits */
45 /* Write-1-to-clear bits */
66 * Cache Line Size register: implement as read-only, we do not
70 * Latency Timer Register: implemented as read-only, as "A
75 * Header Type: always read-only
77 * BIST register: implemented as read-only, as "A bridge that
79 * read-only register that returns 0 when read"
84 * Base Address registers not used must be implemented as
85 * read-only registers that return 0 when read.
93 /* Secondary latency is read-only */
110 /* The high 12-bits of mem base/limit are RW */
118 /* The high 12-bits of pref mem base/limit are RW */
143 * be implemented as read-only register that return 0 when read, same
178 * bits [14:0] of Capabilities register are all read-only.
187 * Bits [27:18] are reserved for non-upstream ports.
188 * Bits 28 and [14:6] are reserved for non-endpoint devices.
189 * Other bits are read-only.
197 * reserved for non-endpoints or non-PCIe-to-PCI/X bridges.
203 * the rest is reserved. Also bit 6 is reserved for non-upstream
204 * ports.
213 * bit 18 which is reserved for non-upstream ports.
221 * rest is reserved. Bit 8 is reserved for non-upstream ports.
276 * Also bits [26:24] are reserved for non-upstream ports.
284 * non-upstream ports.
323 ((bridge->pcie_start > bridge->ssid_start) ? (bridge->pcie_start << 8) : 0); in pci_bridge_emul_read_ssid()
327 *value = bridge->subsystem_vendor_id | in pci_bridge_emul_read_ssid()
328 (bridge->subsystem_id << 16); in pci_bridge_emul_read_ssid()
340 * (typically at least vendor, device, revision), the ->ops pointer,
341 * and optionally ->data and ->has_pcie.
346 BUILD_BUG_ON(sizeof(bridge->conf) != PCI_BRIDGE_CONF_END); in pci_bridge_emul_init()
351 * 24-bit value: PCI_CLASS_BRIDGE_PCI_NORMAL in pci_bridge_emul_init()
353 bridge->conf.class_revision |= in pci_bridge_emul_init()
355 bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE; in pci_bridge_emul_init()
356 bridge->conf.cache_line_size = 0x10; in pci_bridge_emul_init()
357 bridge->conf.status = cpu_to_le16(PCI_STATUS_CAP_LIST); in pci_bridge_emul_init()
358 bridge->pci_regs_behavior = kmemdup(pci_regs_behavior, in pci_bridge_emul_init()
361 if (!bridge->pci_regs_behavior) in pci_bridge_emul_init()
362 return -ENOMEM; in pci_bridge_emul_init()
365 if (!bridge->ssid_start && !bridge->pcie_start) { in pci_bridge_emul_init()
366 if (bridge->subsystem_vendor_id) in pci_bridge_emul_init()
367 bridge->ssid_start = PCI_BRIDGE_CONF_END; in pci_bridge_emul_init()
368 if (bridge->has_pcie) in pci_bridge_emul_init()
369 bridge->pcie_start = bridge->ssid_start + PCI_CAP_SSID_SIZEOF; in pci_bridge_emul_init()
370 } else if (!bridge->ssid_start && bridge->subsystem_vendor_id) { in pci_bridge_emul_init()
371 if (bridge->pcie_start - PCI_BRIDGE_CONF_END >= PCI_CAP_SSID_SIZEOF) in pci_bridge_emul_init()
372 bridge->ssid_start = PCI_BRIDGE_CONF_END; in pci_bridge_emul_init()
374 bridge->ssid_start = bridge->pcie_start + PCI_CAP_PCIE_SIZEOF; in pci_bridge_emul_init()
375 } else if (!bridge->pcie_start && bridge->has_pcie) { in pci_bridge_emul_init()
376 if (bridge->ssid_start - PCI_BRIDGE_CONF_END >= PCI_CAP_PCIE_SIZEOF) in pci_bridge_emul_init()
377 bridge->pcie_start = PCI_BRIDGE_CONF_END; in pci_bridge_emul_init()
379 bridge->pcie_start = bridge->ssid_start + PCI_CAP_SSID_SIZEOF; in pci_bridge_emul_init()
382 bridge->conf.capabilities_pointer = min(bridge->ssid_start, bridge->pcie_start); in pci_bridge_emul_init()
384 if (bridge->conf.capabilities_pointer) in pci_bridge_emul_init()
385 bridge->conf.status |= cpu_to_le16(PCI_STATUS_CAP_LIST); in pci_bridge_emul_init()
387 if (bridge->has_pcie) { in pci_bridge_emul_init()
388 bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP; in pci_bridge_emul_init()
389 bridge->pcie_conf.next = (bridge->ssid_start > bridge->pcie_start) ? in pci_bridge_emul_init()
390 bridge->ssid_start : 0; in pci_bridge_emul_init()
391 bridge->pcie_conf.cap |= cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4); in pci_bridge_emul_init()
392 bridge->pcie_cap_regs_behavior = in pci_bridge_emul_init()
396 if (!bridge->pcie_cap_regs_behavior) { in pci_bridge_emul_init()
397 kfree(bridge->pci_regs_behavior); in pci_bridge_emul_init()
398 return -ENOMEM; in pci_bridge_emul_init()
401 bridge->pci_regs_behavior[PCI_CACHE_LINE_SIZE / 4].ro &= in pci_bridge_emul_init()
403 bridge->pci_regs_behavior[PCI_COMMAND / 4].ro &= in pci_bridge_emul_init()
409 bridge->pci_regs_behavior[PCI_PRIMARY_BUS / 4].ro &= in pci_bridge_emul_init()
411 bridge->pci_regs_behavior[PCI_IO_BASE / 4].ro &= in pci_bridge_emul_init()
414 bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].rw &= in pci_bridge_emul_init()
417 bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].ro &= in pci_bridge_emul_init()
419 bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].w1c &= in pci_bridge_emul_init()
424 bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].ro = ~0; in pci_bridge_emul_init()
425 bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].rw = 0; in pci_bridge_emul_init()
429 bridge->pci_regs_behavior[PCI_COMMAND / 4].ro |= PCI_COMMAND_IO; in pci_bridge_emul_init()
430 bridge->pci_regs_behavior[PCI_COMMAND / 4].rw &= ~PCI_COMMAND_IO; in pci_bridge_emul_init()
431 bridge->pci_regs_behavior[PCI_IO_BASE / 4].ro |= GENMASK(15, 0); in pci_bridge_emul_init()
432 bridge->pci_regs_behavior[PCI_IO_BASE / 4].rw &= ~GENMASK(15, 0); in pci_bridge_emul_init()
433 bridge->pci_regs_behavior[PCI_IO_BASE_UPPER16 / 4].ro = ~0; in pci_bridge_emul_init()
434 bridge->pci_regs_behavior[PCI_IO_BASE_UPPER16 / 4].rw = 0; in pci_bridge_emul_init()
447 if (bridge->has_pcie) in pci_bridge_emul_cleanup()
448 kfree(bridge->pcie_cap_regs_behavior); in pci_bridge_emul_cleanup()
449 kfree(bridge->pci_regs_behavior); in pci_bridge_emul_cleanup()
456 * ->ops->read_base or ->ops->read_pcie operations.
470 read_op = bridge->ops->read_base; in pci_bridge_emul_conf_read()
471 cfgspace = (__le32 *) &bridge->conf; in pci_bridge_emul_conf_read()
472 behavior = bridge->pci_regs_behavior; in pci_bridge_emul_conf_read()
473 } else if (reg >= bridge->ssid_start && reg < bridge->ssid_start + PCI_CAP_SSID_SIZEOF && in pci_bridge_emul_conf_read()
474 bridge->subsystem_vendor_id) { in pci_bridge_emul_conf_read()
476 reg -= bridge->ssid_start; in pci_bridge_emul_conf_read()
480 } else if (reg >= bridge->pcie_start && reg < bridge->pcie_start + PCI_CAP_PCIE_SIZEOF && in pci_bridge_emul_conf_read()
481 bridge->has_pcie) { in pci_bridge_emul_conf_read()
483 reg -= bridge->pcie_start; in pci_bridge_emul_conf_read()
484 read_op = bridge->ops->read_pcie; in pci_bridge_emul_conf_read()
485 cfgspace = (__le32 *) &bridge->pcie_conf; in pci_bridge_emul_conf_read()
486 behavior = bridge->pcie_cap_regs_behavior; in pci_bridge_emul_conf_read()
487 } else if (reg >= PCI_CFG_SPACE_SIZE && bridge->has_pcie) { in pci_bridge_emul_conf_read()
489 reg -= PCI_CFG_SPACE_SIZE; in pci_bridge_emul_conf_read()
490 read_op = bridge->ops->read_ext; in pci_bridge_emul_conf_read()
494 /* Not implemented */ in pci_bridge_emul_conf_read()
533 * ->ops->write_base or ->ops->write_pcie operations.
551 write_op = bridge->ops->write_base; in pci_bridge_emul_conf_write()
552 cfgspace = (__le32 *) &bridge->conf; in pci_bridge_emul_conf_write()
553 behavior = bridge->pci_regs_behavior; in pci_bridge_emul_conf_write()
554 } else if (reg >= bridge->pcie_start && reg < bridge->pcie_start + PCI_CAP_PCIE_SIZEOF && in pci_bridge_emul_conf_write()
555 bridge->has_pcie) { in pci_bridge_emul_conf_write()
557 reg -= bridge->pcie_start; in pci_bridge_emul_conf_write()
558 write_op = bridge->ops->write_pcie; in pci_bridge_emul_conf_write()
559 cfgspace = (__le32 *) &bridge->pcie_conf; in pci_bridge_emul_conf_write()
560 behavior = bridge->pcie_cap_regs_behavior; in pci_bridge_emul_conf_write()
561 } else if (reg >= PCI_CFG_SPACE_SIZE && bridge->has_pcie) { in pci_bridge_emul_conf_write()
563 reg -= PCI_CFG_SPACE_SIZE; in pci_bridge_emul_conf_write()
564 write_op = bridge->ops->write_ext; in pci_bridge_emul_conf_write()
568 /* Not implemented */ in pci_bridge_emul_conf_write()