diff options
author | Mario Six <mario.six@gdsys.cc> | 2018-08-09 14:51:18 +0200 |
---|---|---|
committer | Anatolij Gustschin <agust@denx.de> | 2018-08-11 08:09:39 +0200 |
commit | 9a8bcabd8adac3382bc23bef450a6793e5144110 (patch) | |
tree | 65209a7afa8abbc2a55ec2dfb9acf22fe50a010d /drivers/axi/axi-emul-uclass.c | |
parent | 9fc8706d65fc812f4e1a2da78d3b4411c866db63 (diff) | |
download | u-boot-9a8bcabd8adac3382bc23bef450a6793e5144110.tar.gz |
axi: Add AXI sandbox driver and simple emulator
Add test infrastructure and tests for the AXI uclass.
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
Diffstat (limited to 'drivers/axi/axi-emul-uclass.c')
-rw-r--r-- | drivers/axi/axi-emul-uclass.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/axi/axi-emul-uclass.c b/drivers/axi/axi-emul-uclass.c new file mode 100644 index 0000000000..06c42006ee --- /dev/null +++ b/drivers/axi/axi-emul-uclass.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018 + * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + */ + +#include <common.h> +#include <axi.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <asm/axi.h> + +int axi_sandbox_get_emul(struct udevice *bus, ulong address, + enum axi_size_t size, struct udevice **emulp) +{ + struct udevice *dev; + u32 reg[2]; + uint offset; + + switch (size) { + case AXI_SIZE_8: + offset = 1; + break; + case AXI_SIZE_16: + offset = 2; + break; + case AXI_SIZE_32: + offset = 4; + break; + default: + debug("%s: Unknown AXI transfer size '%d'", bus->name, size); + offset = 0; + } + + /* + * Note: device_find_* don't activate the devices; they're activated + * as-needed below. + */ + for (device_find_first_child(bus, &dev); + dev; + device_find_next_child(&dev)) { + int ret; + + ret = dev_read_u32_array(dev, "reg", reg, ARRAY_SIZE(reg)); + if (ret) { + debug("%s: Could not read 'reg' property of %s\n", + bus->name, dev->name); + continue; + } + + /* + * Does the transfer's address fall into this device's address + * space? + */ + if (address >= reg[0] && address <= reg[0] + reg[1] - offset) { + /* If yes, activate it... */ + if (device_probe(dev)) { + debug("%s: Could not activate %s\n", + bus->name, dev->name); + return -ENODEV; + } + + /* ...and return it */ + *emulp = dev; + return 0; + } + } + + return -ENODEV; +} + +int axi_get_store(struct udevice *dev, u8 **storep) +{ + struct axi_emul_ops *ops = axi_emul_get_ops(dev); + + if (!ops->get_store) + return -ENOSYS; + + return ops->get_store(dev, storep); +} + +UCLASS_DRIVER(axi_emul) = { + .id = UCLASS_AXI_EMUL, + .name = "axi_emul", +}; |