1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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;
}
|