summaryrefslogtreecommitdiff
path: root/tools/src/dapf.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/src/dapf.c')
-rw-r--r--tools/src/dapf.c137
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;
+}