From e1a919d622d3d8462e3ccad691b8f7b104339526 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Thu, 28 Mar 2024 21:52:34 +1030 Subject: [PATCH] wip: dump controllers Signed-off-by: Andrew Jeffery --- src/cmd/read.c | 93 +++++++++++++++++++++++++++++++++++++++++-- src/devicetree/g5.dts | 2 + src/devicetree/g6.dts | 9 +++++ 3 files changed, 101 insertions(+), 3 deletions(-) diff --git a/src/cmd/read.c b/src/cmd/read.c index 40d3de8..69f0efc 100644 --- a/src/cmd/read.c +++ b/src/cmd/read.c @@ -12,12 +12,92 @@ #include "soc/sdmc.h" #include "soc/sfc.h" +#include + #include #include #include #include #include +static int cmd_dump_controller(struct soc *soc, const char *controller) +{ + struct soc_device_node dn; + struct soc_region region; + const uint32_t *pwidth; + const uint32_t *pshift; + uint32_t stride; + uint32_t width; + uint32_t shift; + uint32_t addr; + uint32_t end; + int len; + int rc; + + if (strcmp("fmc", controller)) { + return -EINVAL; + } + + rc = soc_device_from_name(soc, controller, &dn); + if (rc < 0) { + loge("failed to find device by name '%s': %d\n", controller, rc); + return -EINVAL; + } + + // FIXME: Move this to src/soc.c + pwidth = fdt_getprop(soc->fdt.start, dn.offset, "reg-io-width", &len); + if (len < 0) { + loge("'%s' lacks reg-io-width\n", controller); + return -ENOTSUP; + } + width = be32toh(*pwidth); + if (width > 0xf) { + loge("Invalid value for reg-io-width: %"PRIu32"\n", width); + return -EINVAL; + } + + pshift = fdt_getprop(soc->fdt.start, dn.offset, "reg-shift", &len); + if (len < 0) { + loge("'%s' lacks reg-shift\n", controller); + return -ENOTSUP; + } + shift = be32toh(*pshift); + if (shift > 2) { + loge("Invalid value for reg-shift: %"PRIu32"\n", shift); + return -EINVAL; + } + + rc = soc_device_get_memory(soc, &dn, ®ion); + if (rc < 0) { + loge("Failed to retrieve device memory: %d\n", rc); + return -ENODEV; + } + + end = region.start + region.length; + if (end == UINT32_MAX || end < region.start) { + loge("Invalid region: { start: 0x%"PRIx32", length: 0x%"PRIx32"}\n", + region.start, region.length); + return -EINVAL; + } + + // FIXME: Generalise + if (width != 4) { + loge("Unsupported reg-io-width: %"PRIu32"\n", width); + return -ENOTSUP; + } + + stride = width << shift; + for (addr = region.start; addr < end; addr += stride) { + uint32_t val; + rc = soc_readl(soc, addr, &val); + if (!rc) { + printf("0x%08"PRIx32": 0x%08"PRIx32"\n", addr, val); + } + } + + return 0; +} + static int cmd_dump_firmware(struct soc *soc) { struct soc_region flash; @@ -117,11 +197,18 @@ int cmd_read(const char *name __unused, int argc, char *argv[]) if ((rc = soc_probe(soc, ahb)) < 0) goto cleanup_host; - if (!strcmp("firmware", argv[0])) + if (!strcmp("controller", argv[0])) { + if (argc < 2) { + loge("Not enough arguments for controller subcommand\n"); + goto cleanup_host; + } + // FIXME: Don't hardcode the controller name + rc = cmd_dump_controller(soc, "fmc"); + } else if (!strcmp("firmware", argv[0])) { rc = cmd_dump_firmware(soc); - else if (!strcmp("ram", argv[0])) + } else if (!strcmp("ram", argv[0])) { rc = cmd_dump_ram(soc); - else { + } else { loge("Unsupported read type '%s'", argv[0]); rc = -EINVAL; } diff --git a/src/devicetree/g5.dts b/src/devicetree/g5.dts index b219a01..647f1d8 100644 --- a/src/devicetree/g5.dts +++ b/src/devicetree/g5.dts @@ -55,6 +55,8 @@ reg = <0x1e620000 0xc4 0x20000000 0x10000000>; compatible = "aspeed,ast2500-fmc"; + reg-io-width = <4>; + reg-shift = <0>; }; spi1: spi@1e630000 { diff --git a/src/devicetree/g6.dts b/src/devicetree/g6.dts index 113a5b0..e725a71 100644 --- a/src/devicetree/g6.dts +++ b/src/devicetree/g6.dts @@ -11,6 +11,7 @@ #size-cells = <1>; aliases { + fmc = &fmc; vuart = &vuart1; vuart1 = &vuart1; vuart2 = &vuart2; @@ -55,6 +56,14 @@ #address-cells = <1>; #size-cells = <1>; + fmc: spi@1e620000 { + reg = <0x1e620000 0x180 + 0x20000000 0x10000000>; + compatible = "aspeed,ast2600-fmc"; + reg-io-width = <4>; + reg-shift = <0>; + }; + sdmc: memory-controller@1e6e0000 { compatible = "aspeed,ast2600-sdram-controller"; reg = <0x1e6e0000 0xb8>;