summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2015-03-05 12:25:28 -0700
committerSimon Glass <sjg@chromium.org>2015-04-16 19:27:43 -0600
commit36d0d3b4b4974f4183609ac8b4d77a1f46acba55 (patch)
tree859816b8b1c7b1c755ab2853a7736287bf9eab5d /include
parent537849aaa1b8f90d99f4c31a2945ab0b817aa599 (diff)
downloadu-boot-imx-36d0d3b4b4974f4183609ac8b4d77a1f46acba55.zip
u-boot-imx-36d0d3b4b4974f4183609ac8b4d77a1f46acba55.tar.gz
u-boot-imx-36d0d3b4b4974f4183609ac8b4d77a1f46acba55.tar.bz2
dm: sandbox: pci: Add a PCI emulation uclass
Since sandbox does not have real devices (unless it borrows those from the host) it must use emulations. Provide a uclass which permits PCI operations to be passed through to an emulation device. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'include')
-rw-r--r--include/dm/uclass-id.h1
-rw-r--r--include/pci.h108
2 files changed, 109 insertions, 0 deletions
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index b984407..0b6e850 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -20,6 +20,7 @@ enum uclass_id {
UCLASS_TEST_BUS,
UCLASS_SPI_EMUL, /* sandbox SPI device emulator */
UCLASS_I2C_EMUL, /* sandbox I2C device emulator */
+ UCLASS_PCI_EMUL, /* sandbox PCI device emulator */
UCLASS_SIMPLE_BUS,
/* U-Boot uclasses start here */
diff --git a/include/pci.h b/include/pci.h
index 07345fd..07b1e9a 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -992,6 +992,114 @@ static inline int pci_read_config_byte(pci_dev_t pcidev, int offset,
return pci_read_config8(pcidev, offset, valuep);
}
+/**
+ * struct dm_pci_emul_ops - PCI device emulator operations
+ */
+struct dm_pci_emul_ops {
+ /**
+ * get_devfn(): Check which device and function this emulators
+ *
+ * @dev: device to check
+ * @return the device and function this emulates, or -ve on error
+ */
+ int (*get_devfn)(struct udevice *dev);
+ /**
+ * read_config() - Read a PCI configuration value
+ *
+ * @dev: Emulated device to read from
+ * @offset: Byte offset within the device's configuration space
+ * @valuep: Place to put the returned value
+ * @size: Access size
+ * @return 0 if OK, -ve on error
+ */
+ int (*read_config)(struct udevice *dev, uint offset, ulong *valuep,
+ enum pci_size_t size);
+ /**
+ * write_config() - Write a PCI configuration value
+ *
+ * @dev: Emulated device to write to
+ * @offset: Byte offset within the device's configuration space
+ * @value: Value to write
+ * @size: Access size
+ * @return 0 if OK, -ve on error
+ */
+ int (*write_config)(struct udevice *dev, uint offset, ulong value,
+ enum pci_size_t size);
+ /**
+ * read_io() - Read a PCI I/O value
+ *
+ * @dev: Emulated device to read from
+ * @addr: I/O address to read
+ * @valuep: Place to put the returned value
+ * @size: Access size
+ * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+ * other -ve value on error
+ */
+ int (*read_io)(struct udevice *dev, unsigned int addr, ulong *valuep,
+ enum pci_size_t size);
+ /**
+ * write_io() - Write a PCI I/O value
+ *
+ * @dev: Emulated device to write from
+ * @addr: I/O address to write
+ * @value: Value to write
+ * @size: Access size
+ * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+ * other -ve value on error
+ */
+ int (*write_io)(struct udevice *dev, unsigned int addr,
+ ulong value, enum pci_size_t size);
+ /**
+ * map_physmem() - Map a device into sandbox memory
+ *
+ * @dev: Emulated device to map
+ * @addr: Memory address, normally corresponding to a PCI BAR.
+ * The device should have been configured to have a BAR
+ * at this address.
+ * @lenp: On entry, the size of the area to map, On exit it is
+ * updated to the size actually mapped, which may be less
+ * if the device has less space
+ * @ptrp: Returns a pointer to the mapped address. The device's
+ * space can be accessed as @lenp bytes starting here
+ * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+ * other -ve value on error
+ */
+ int (*map_physmem)(struct udevice *dev, phys_addr_t addr,
+ unsigned long *lenp, void **ptrp);
+ /**
+ * unmap_physmem() - undo a memory mapping
+ *
+ * This must be called after map_physmem() to undo the mapping.
+ * Some devices can use this to check what has been written into
+ * their mapped memory and perform an operations they require on it.
+ * In this way, map/unmap can be used as a sort of handshake between
+ * the emulated device and its users.
+ *
+ * @dev: Emuated device to unmap
+ * @vaddr: Mapped memory address, as passed to map_physmem()
+ * @len: Size of area mapped, as returned by map_physmem()
+ * @return 0 if OK, -ve on error
+ */
+ int (*unmap_physmem)(struct udevice *dev, const void *vaddr,
+ unsigned long len);
+};
+
+/* Get access to a PCI device emulator's operations */
+#define pci_get_emul_ops(dev) ((struct dm_pci_emul_ops *)(dev)->driver->ops)
+
+/**
+ * sandbox_pci_get_emul() - Get the emulation device for a PCI device
+ *
+ * Searches for a suitable emulator for the given PCI bus device
+ *
+ * @bus: PCI bus to search
+ * @find_devfn: PCI device and function address (PCI_DEVFN())
+ * @emulp: Returns emulated device if found
+ * @return 0 if found, -ENODEV if not found
+ */
+int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn,
+ struct udevice **emulp);
+
#endif
#endif /* __ASSEMBLY__ */