dapf: Initialize DAPFs from the ADT

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2022-07-03 23:27:30 +09:00
parent eb4fa83bbc
commit 4555cc5148
8 changed files with 171 additions and 28 deletions

View file

@ -81,6 +81,7 @@ OBJECTS := \
chickens_icestorm.o \
clk.o \
cpufreq.o \
dapf.o \
dart.o \
dcp.o \
dcp_iboot.o \

View file

@ -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()

View file

@ -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__)

137
src/dapf.c Normal file
View file

@ -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;
}

9
src/dapf.h Normal file
View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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;