diff options
Diffstat (limited to 'tools/src/dapf.c')
| -rw-r--r-- | tools/src/dapf.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/tools/src/dapf.c b/tools/src/dapf.c new file mode 100644 index 0000000..cbeb576 --- /dev/null +++ b/tools/src/dapf.c @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: MIT */ + +#include "dapf.h" +#include "adt.h" +#include "assert.h" +#include "malloc.h" +#include "memory.h" +#include "string.h" +#include "utils.h" + +struct dapf_t8020_config { + u64 start; + u64 end; + u8 unk1; + u8 r0_hi; + u8 r0_lo; + u8 unk2; + u32 r4; +} PACKED; + +static int dapf_init_t8020(const char *path, u64 base, int node) +{ + u32 length; + const char *prop = "filter-data-instance-0"; + const struct dapf_t8020_config *config = adt_getprop(adt, node, prop, &length); + + if (!config || !length || (length % sizeof(*config)) != 0) { + printf("dapf: Error getting ADT node %s property %s.\n", path, prop); + return -1; + } + + int count = length / sizeof(*config); + + for (int i = 0; i < count; i++) { + write32(base + 0x04, config[i].r4); + write64(base + 0x08, config[i].start); + write64(base + 0x10, config[i].end); + write32(base + 0x00, (config[i].r0_hi << 4) | config[i].r0_lo); + base += 0x40; + } + return 0; +} + +struct dapf_t8110_config { + u64 start; + u64 end; + u32 r20; + u32 unk1; + u32 r4; + u32 unk2[5]; + u8 unk3; + u8 r0_hi; + u8 r0_lo; + u8 unk4; +} PACKED; + +static int dapf_init_t8110(const char *path, u64 base, int node) +{ + u32 length; + const char *prop = "dapf-instance-0"; + const struct dapf_t8110_config *config = adt_getprop(adt, node, prop, &length); + + if (!config || !length) { + printf("dapf: Error getting ADT node %s property %s.\n", path, prop); + return -1; + } + + if (length % sizeof(*config) != 0) { + printf("dapf: Invalid length for %s property %s\n", path, prop); + return -1; + } + + int count = length / sizeof(*config); + + for (int i = 0; i < count; i++) { + write32(base + 0x04, config[i].r4); + write64(base + 0x08, config[i].start); + write64(base + 0x10, config[i].end); + write32(base + 0x00, (config[i].r0_hi << 4) | config[i].r0_lo); + write32(base + 0x20, config[i].r20); + base += 0x40; + } + return 0; +} + +int dapf_init(const char *path) +{ + int ret; + int dart_path[8]; + int node = adt_path_offset_trace(adt, path, dart_path); + if (node < 0) { + printf("dapf: Error getting DAPF %s node.\n", path); + return -1; + } + + u64 base; + if (adt_get_reg(adt, dart_path, "reg", 1, &base, NULL) < 0) { + printf("dapf: Error getting DAPF %s base address.\n", path); + return -1; + } + + if (adt_is_compatible(adt, node, "dart,t8020")) { + ret = dapf_init_t8020(path, base, node); + } else if (adt_is_compatible(adt, node, "dart,t6000")) { + ret = dapf_init_t8020(path, base, node); + } else if (adt_is_compatible(adt, node, "dart,t8110")) { + ret = dapf_init_t8110(path, base, node); + } else { + printf("dapf: DAPF %s at 0x%lx is of an unknown type\n", path, base); + return -1; + } + + if (!ret) + printf("dapf: Initialized %s\n", path); + + return ret; +} + +const char *dapf_paths[] = {"/arm-io/dart-aop", "/arm-io/dart-mtp", "/arm-io/dart-pmp", NULL}; + +int dapf_init_all(void) +{ + int ret = 0; + int count = 0; + + for (const char **path = dapf_paths; *path; path++) { + if (adt_path_offset(adt, *path) < 0) + continue; + + if (dapf_init(*path) < 0) { + ret = -1; + } + count += 1; + } + + return ret ? ret : count; +} |
