From 4555cc51486d29caa743a4bd02b4e41a6759af6c Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 3 Jul 2022 23:27:30 +0900 Subject: [PATCH] dapf: Initialize DAPFs from the ADT Signed-off-by: Hector Martin --- Makefile | 1 + proxyclient/experiments/aop.py | 27 +------ proxyclient/m1n1/proxy.py | 8 ++ src/dapf.c | 137 +++++++++++++++++++++++++++++++++ src/dapf.h | 9 +++ src/kboot.c | 2 + src/proxy.c | 8 ++ src/proxy.h | 7 +- 8 files changed, 171 insertions(+), 28 deletions(-) create mode 100644 src/dapf.c create mode 100644 src/dapf.h diff --git a/Makefile b/Makefile index 75887b3a..d078ab8c 100644 --- a/Makefile +++ b/Makefile @@ -81,6 +81,7 @@ OBJECTS := \ chickens_icestorm.o \ clk.o \ cpufreq.o \ + dapf.o \ dart.o \ dcp.o \ dcp_iboot.o \ diff --git a/proxyclient/experiments/aop.py b/proxyclient/experiments/aop.py index 3e2dc4da..7fe3d7ac 100755 --- a/proxyclient/experiments/aop.py +++ b/proxyclient/experiments/aop.py @@ -11,30 +11,6 @@ from m1n1.shell import run_shell from m1n1.hw.dart import DART, DARTRegs from m1n1.fw.asc import StandardASC, ASCDummyEndpoint - -DAPFFirmwareData = SafeGreedyRange(Struct( - "addr_from" / Hex(Int64ul), - "addr_to" / Hex(Int64ul), - "unk1" / Hex(Int32ul), - "unk2" / Hex(Int32ul), -)) - - -def set_dapf_from_adt(adtpath): - node = u.adt[adtpath] - dapf_base, dapf_len = node.get_reg(1) - - fw_data = DAPFFirmwareData.parse(node.filter_data_instance_0) - for entry, b in zip(fw_data, - range(dapf_base, dapf_base + dapf_len, 0x40)): - p.write32(b + 0x04, entry.unk2) # a guess - p.write32(b + 0x08, entry.addr_from & (1<<32)-1) - p.write32(b + 0x0c, entry.addr_from >> 32) - p.write32(b + 0x10, entry.addr_to & (1<<32)-1) - p.write32(b + 0x14, entry.addr_to >> 32) - p.write32(b, 0x31) - - class ASCArgumentSection: def __init__(self, bytes_): self.blob = bytearray(bytes_) @@ -138,8 +114,7 @@ class AOPClient(StandardASC): args.update(keyvals) self.write_bootargs(args) - -set_dapf_from_adt("/arm-io/dart-aop") +p.dapf_init_all() dart = DART.from_adt(u, "/arm-io/dart-aop") dart.initialize() diff --git a/proxyclient/m1n1/proxy.py b/proxyclient/m1n1/proxy.py index f47ce908..550ea675 100644 --- a/proxyclient/m1n1/proxy.py +++ b/proxyclient/m1n1/proxy.py @@ -618,6 +618,9 @@ class M1N1Proxy(Reloadable): P_DISPLAY_CONFIGURE = 0x1101 P_DISPLAY_SHUTDOWN = 0x1102 + P_DAPF_INIT_ALL = 0x1200 + P_DAPF_INIT = 0x1201 + def __init__(self, iface, debug=False): self.debug = debug self.iface = iface @@ -1063,6 +1066,11 @@ class M1N1Proxy(Reloadable): def display_shutdown(self, mode): return self.request(self.P_DISPLAY_SHUTDOWN, mode) + def dapf_init_all(self): + return self.request(self.P_DAPF_INIT_ALL) + def dapf_init(self, path): + return self.request(self.P_DAPF_INIT, path) + __all__.extend(k for k, v in globals().items() if (callable(v) or isinstance(v, type)) and v.__module__ == __name__) diff --git a/src/dapf.c b/src/dapf.c new file mode 100644 index 00000000..cbeb576f --- /dev/null +++ b/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; +} diff --git a/src/dapf.h b/src/dapf.h new file mode 100644 index 00000000..2a7e1bf1 --- /dev/null +++ b/src/dapf.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef DAPF_H +#define DAPF_H + +int dapf_init_all(void); +int dapf_init(const char *path); + +#endif diff --git a/src/kboot.c b/src/kboot.c index c5e9567b..cb80d695 100644 --- a/src/kboot.c +++ b/src/kboot.c @@ -3,6 +3,7 @@ #include "kboot.h" #include "adt.h" #include "assert.h" +#include "dapf.h" #include "exception.h" #include "malloc.h" #include "memory.h" @@ -1113,6 +1114,7 @@ int kboot_boot(void *kernel) { usb_init(); pcie_init(); + dapf_init_all(); printf("Setting SMP mode to WFE...\n"); smp_set_wfe_mode(true); diff --git a/src/proxy.c b/src/proxy.c index 5e57f5d2..b9a1d88c 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: MIT */ #include "proxy.h" +#include "dapf.h" #include "dart.h" #include "display.h" #include "exception.h" @@ -539,6 +540,13 @@ int proxy_process(ProxyRequest *request, ProxyReply *reply) display_shutdown(request->args[0]); break; + case P_DAPF_INIT_ALL: + reply->retval = dapf_init_all(); + break; + case P_DAPF_INIT: + reply->retval = dapf_init((const char *)request->args[0]); + break; + default: reply->status = S_BADCMD; break; diff --git a/src/proxy.h b/src/proxy.h index 8f9b8d7d..7ebd0566 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -151,8 +151,11 @@ typedef enum { P_MCC_GET_CARVEOUTS = 0x1000, P_DISPLAY_INIT = 0x1100, - P_DISPLAY_CONFIGURE = 0x1101, - P_DISPLAY_SHUTDOWN = 0x1102, + P_DISPLAY_CONFIGURE, + P_DISPLAY_SHUTDOWN, + + P_DAPF_INIT_ALL = 0x1200, + P_DAPF_INIT, } ProxyOp;