Newer
Older
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
#include "hw/memlayout.h"
#define SDB_INTERCONNET 0x00
#define SDB_DEVICE 0x01
#define SDB_BRIDGE 0x02
#define SDB_EMPTY 0xFF
typedef struct pair64 {
uint32_t high;
uint32_t low;
} pair64_t;
struct sdb_empty {
int8_t reserved[63];
uint8_t record_type;
};
struct sdb_product {
pair64_t vendor_id;
uint32_t device_id;
uint32_t version;
uint32_t date;
int8_t name[19];
uint8_t record_type;
};
struct sdb_component {
pair64_t addr_first;
pair64_t addr_last;
struct sdb_product product;
};
struct sdb_device {
uint16_t abi_class;
uint8_t abi_ver_major;
uint8_t abi_ver_minor;
uint32_t bus_specific;
struct sdb_component sdb_component;
};
struct sdb_bridge {
pair64_t sdb_child;
struct sdb_component sdb_component;
};
struct sdb_interconnect {
uint32_t sdb_magic;
uint16_t sdb_records;
uint8_t sdb_version;
uint8_t sdb_bus_type;
struct sdb_component sdb_component;
};
typedef union sdb_record {
struct sdb_empty empty;
struct sdb_device device;
struct sdb_bridge bridge;
struct sdb_interconnect interconnect;
} sdb_record_t;
static unsigned char* find_device_deep(unsigned int base, unsigned int sdb, unsigned int devid) {
sdb_record_t* record = (sdb_record_t*)sdb;
int records = record->interconnect.sdb_records;
int i;
for (i = 0; i < records; ++i, ++record) {
if (record->empty.record_type == SDB_BRIDGE) {
unsigned char* out =
find_device_deep(
base + record->bridge.sdb_component.addr_first.low,
record->bridge.sdb_child.low,
devid);
if (out) return out;
}
if (record->empty.record_type == SDB_DEVICE &&
record->device.sdb_component.product.device_id == devid) {
break;
}
}
if (i == records) return 0;
return (unsigned char*)(base + record->device.sdb_component.addr_first.low);
}
static void print_devices_deep(unsigned int base, unsigned int sdb) {
sdb_record_t* record = (sdb_record_t*)sdb;
int records = record->interconnect.sdb_records;
int i;
char buf[20];
for (i = 0; i < records; ++i, ++record) {
if (record->empty.record_type == SDB_BRIDGE)
print_devices_deep(
base + record->bridge.sdb_component.addr_first.low,
record->bridge.sdb_child.low);
if (record->empty.record_type != SDB_DEVICE) continue;
memcpy(buf, record->device.sdb_component.product.name, 19);
buf[19] = 0;
mprintf("%8x:%8x 0x%8x %s\n",
record->device.sdb_component.product.vendor_id.low,
record->device.sdb_component.product.device_id,
base + record->device.sdb_component.addr_first.low,
buf);
}
}
static unsigned char* find_device(unsigned int devid) {
find_device_deep(0, SDB_ADDRESS, devid);
}
void sdb_print_devices(void) {
mprintf("SDB memory map:\n");
print_devices_deep(0, SDB_ADDRESS);
mprintf("---\n");
}
void sdb_find_devices(void) {
BASE_MINIC = find_device(0xab28633a);
BASE_EP = find_device(0x650c2d4f);
BASE_SOFTPLL = find_device(0x65158dc0);
BASE_PPS_GEN = find_device(0xde0d8ced);
BASE_SYSCON = find_device(0xff07fc47);
BASE_UART = find_device(0xe2d13d04);
BASE_ONEWIRE = find_device(0x779c5443);
BASE_ETHERBONE_CFG = find_device(0x68202b22);