Lines Matching refs:bridge

8  * PCI bridge when the HW doesn't provide such a root port PCI
9 * bridge.
11 * It emulates a PCI bridge by providing a fake PCI configuration
21 #include "pci-bridge-emul.h"
71 * bridge that is not capable of a burst transfer of more than
77 * BIST register: implemented as read-only, as "A bridge that
152 * are RO, and bridge control (31:16) are a mix of RW, RO,
318 pci_bridge_emul_read_ssid(struct pci_bridge_emul *bridge, int reg, u32 *value)
323 ((bridge->pcie_start > bridge->ssid_start) ? (bridge->pcie_start << 8) : 0);
327 *value = bridge->subsystem_vendor_id |
328 (bridge->subsystem_id << 16);
338 * bridge configuration space. The caller needs to have initialized
343 int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
346 BUILD_BUG_ON(sizeof(bridge->conf) != PCI_BRIDGE_CONF_END);
353 bridge->conf.class_revision |=
355 bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE;
356 bridge->conf.cache_line_size = 0x10;
357 bridge->conf.status = cpu_to_le16(PCI_STATUS_CAP_LIST);
358 bridge->pci_regs_behavior = kmemdup(pci_regs_behavior,
361 if (!bridge->pci_regs_behavior)
365 if (!bridge->ssid_start && !bridge->pcie_start) {
366 if (bridge->subsystem_vendor_id)
367 bridge->ssid_start = PCI_BRIDGE_CONF_END;
368 if (bridge->has_pcie)
369 bridge->pcie_start = bridge->ssid_start + PCI_CAP_SSID_SIZEOF;
370 } else if (!bridge->ssid_start && bridge->subsystem_vendor_id) {
371 if (bridge->pcie_start - PCI_BRIDGE_CONF_END >= PCI_CAP_SSID_SIZEOF)
372 bridge->ssid_start = PCI_BRIDGE_CONF_END;
374 bridge->ssid_start = bridge->pcie_start + PCI_CAP_PCIE_SIZEOF;
375 } else if (!bridge->pcie_start && bridge->has_pcie) {
376 if (bridge->ssid_start - PCI_BRIDGE_CONF_END >= PCI_CAP_PCIE_SIZEOF)
377 bridge->pcie_start = PCI_BRIDGE_CONF_END;
379 bridge->pcie_start = bridge->ssid_start + PCI_CAP_SSID_SIZEOF;
382 bridge->conf.capabilities_pointer = min(bridge->ssid_start, bridge->pcie_start);
384 if (bridge->conf.capabilities_pointer)
385 bridge->conf.status |= cpu_to_le16(PCI_STATUS_CAP_LIST);
387 if (bridge->has_pcie) {
388 bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP;
389 bridge->pcie_conf.next = (bridge->ssid_start > bridge->pcie_start) ?
390 bridge->ssid_start : 0;
391 bridge->pcie_conf.cap |= cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4);
392 bridge->pcie_cap_regs_behavior =
396 if (!bridge->pcie_cap_regs_behavior) {
397 kfree(bridge->pci_regs_behavior);
401 bridge->pci_regs_behavior[PCI_CACHE_LINE_SIZE / 4].ro &=
403 bridge->pci_regs_behavior[PCI_COMMAND / 4].ro &=
409 bridge->pci_regs_behavior[PCI_PRIMARY_BUS / 4].ro &=
411 bridge->pci_regs_behavior[PCI_IO_BASE / 4].ro &=
414 bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].rw &=
417 bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].ro &=
419 bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].w1c &=
424 bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].ro = ~0;
425 bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].rw = 0;
429 bridge->pci_regs_behavior[PCI_COMMAND / 4].ro |= PCI_COMMAND_IO;
430 bridge->pci_regs_behavior[PCI_COMMAND / 4].rw &= ~PCI_COMMAND_IO;
431 bridge->pci_regs_behavior[PCI_IO_BASE / 4].ro |= GENMASK(15, 0);
432 bridge->pci_regs_behavior[PCI_IO_BASE / 4].rw &= ~GENMASK(15, 0);
433 bridge->pci_regs_behavior[PCI_IO_BASE_UPPER16 / 4].ro = ~0;
434 bridge->pci_regs_behavior[PCI_IO_BASE_UPPER16 / 4].rw = 0;
445 void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge)
447 if (bridge->has_pcie)
448 kfree(bridge->pcie_cap_regs_behavior);
449 kfree(bridge->pci_regs_behavior);
455 * configuration space of the fake bridge. It will call back the
458 int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
463 pci_bridge_emul_read_status_t (*read_op)(struct pci_bridge_emul *bridge,
470 read_op = bridge->ops->read_base;
471 cfgspace = (__le32 *) &bridge->conf;
472 behavior = bridge->pci_regs_behavior;
473 } else if (reg >= bridge->ssid_start && reg < bridge->ssid_start + PCI_CAP_SSID_SIZEOF &&
474 bridge->subsystem_vendor_id) {
476 reg -= bridge->ssid_start;
480 } else if (reg >= bridge->pcie_start && reg < bridge->pcie_start + PCI_CAP_PCIE_SIZEOF &&
481 bridge->has_pcie) {
483 reg -= bridge->pcie_start;
484 read_op = bridge->ops->read_pcie;
485 cfgspace = (__le32 *) &bridge->pcie_conf;
486 behavior = bridge->pcie_cap_regs_behavior;
487 } else if (reg >= PCI_CFG_SPACE_SIZE && bridge->has_pcie) {
490 read_op = bridge->ops->read_ext;
500 ret = read_op(bridge, reg, value);
532 * configuration space of the fake bridge. It will call back the
535 int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
540 void (*write_op)(struct pci_bridge_emul *bridge, int reg,
545 ret = pci_bridge_emul_conf_read(bridge, reg, 4, &old);
551 write_op = bridge->ops->write_base;
552 cfgspace = (__le32 *) &bridge->conf;
553 behavior = bridge->pci_regs_behavior;
554 } else if (reg >= bridge->pcie_start && reg < bridge->pcie_start + PCI_CAP_PCIE_SIZEOF &&
555 bridge->has_pcie) {
557 reg -= bridge->pcie_start;
558 write_op = bridge->ops->write_pcie;
559 cfgspace = (__le32 *) &bridge->pcie_conf;
560 behavior = bridge->pcie_cap_regs_behavior;
561 } else if (reg >= PCI_CFG_SPACE_SIZE && bridge->has_pcie) {
564 write_op = bridge->ops->write_ext;
617 write_op(bridge, reg, old, new, mask);