dm: sandbox: Add a simple PCI driver

Add a driver which can access emulations of devices and make them available
in sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
master
Simon Glass 9 years ago
parent 9569c40668
commit 537849aaa1
  1. 10
      drivers/pci/Kconfig
  2. 1
      drivers/pci/Makefile
  3. 79
      drivers/pci/pci_sandbox.c

@ -9,4 +9,14 @@ config DM_PCI
available PCI devices, allows scanning of PCI buses and provides
device configuration support.
config PCI_SANDBOX
bool "Sandbox PCI support"
depends on SANDBOX && DM_PCI
help
Support PCI on sandbox, as an emulated bus. This permits testing of
PCI feature such as bus scanning, device configuration and device
access. The available (emulated) devices are defined statically in
the device tree but the normal PCI scan technique is used to find
then.
endmenu

@ -7,6 +7,7 @@
ifneq ($(CONFIG_DM_PCI),)
obj-$(CONFIG_PCI) += pci-uclass.o pci_compat.o
obj-$(CONFIG_PCI_SANDBOX) += pci_sandbox.o
else
obj-$(CONFIG_PCI) += pci.o
endif

@ -0,0 +1,79 @@
/*
* Copyright (c) 2014 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <fdtdec.h>
#include <inttypes.h>
#include <pci.h>
#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
static int sandbox_pci_write_config(struct udevice *bus, pci_dev_t devfn,
uint offset, ulong value,
enum pci_size_t size)
{
struct dm_pci_emul_ops *ops;
struct udevice *emul;
int ret;
ret = sandbox_pci_get_emul(bus, devfn, &emul);
if (ret)
return ret == -ENODEV ? 0 : ret;
ops = pci_get_emul_ops(emul);
if (!ops || !ops->write_config)
return -ENOSYS;
return ops->write_config(emul, offset, value, size);
}
static int sandbox_pci_read_config(struct udevice *bus, pci_dev_t devfn,
uint offset, ulong *valuep,
enum pci_size_t size)
{
struct dm_pci_emul_ops *ops;
struct udevice *emul;
int ret;
/* Prepare the default response */
*valuep = pci_get_ff(size);
ret = sandbox_pci_get_emul(bus, devfn, &emul);
if (ret)
return ret == -ENODEV ? 0 : ret;
ops = pci_get_emul_ops(emul);
if (!ops || !ops->read_config)
return -ENOSYS;
return ops->read_config(emul, offset, valuep, size);
}
static int sandbox_pci_child_post_bind(struct udevice *dev)
{
/* Attach an emulator if we can */
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
}
static const struct dm_pci_ops sandbox_pci_ops = {
.read_config = sandbox_pci_read_config,
.write_config = sandbox_pci_write_config,
};
static const struct udevice_id sandbox_pci_ids[] = {
{ .compatible = "sandbox,pci" },
{ }
};
U_BOOT_DRIVER(pci_sandbox) = {
.name = "pci_sandbox",
.id = UCLASS_PCI,
.of_match = sandbox_pci_ids,
.ops = &sandbox_pci_ops,
.child_post_bind = sandbox_pci_child_post_bind,
.per_child_platdata_auto_alloc_size =
sizeof(struct pci_child_platdata),
};
Loading…
Cancel
Save