mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-10 09:44:13 +00:00
dapf: Initialize DAPFs from the ADT
Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
parent
eb4fa83bbc
commit
4555cc5148
8 changed files with 171 additions and 28 deletions
1
Makefile
1
Makefile
|
@ -81,6 +81,7 @@ OBJECTS := \
|
|||
chickens_icestorm.o \
|
||||
clk.o \
|
||||
cpufreq.o \
|
||||
dapf.o \
|
||||
dart.o \
|
||||
dcp.o \
|
||||
dcp_iboot.o \
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
137
src/dapf.c
Normal 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
9
src/dapf.h
Normal 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
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue