blob: 93922a7809c8ed062360cdb6170ba28819192df0 (
plain)
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
|
#include "common/types.h"
#include "drivers/uart.h"
#include "kernel/config.h"
inline uint32_t bswap(uint32_t x)
{
return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) |
((x & 0xFF0000) >> 8) | ((x >> 24) & 0xFF);
}
struct fdt_header
{
uint32 magic;
uint32 totalsize;
uint32 off_dt_struct;
uint32 off_dt_strings;
uint32 off_mem_rsvmap;
uint32 version;
uint32 last_comp_version;
uint32 boot_cpuid_phys;
uint32 size_dt_strings;
uint32 size_dt_struct;
};
#define FDT_MAGIC 0xd00dfeed
#define FDT_BEGIN_NODE 1
#define FDT_END_NODE 2
#define FDT_PROP 3
#define FDT_NOP 4
#define FDT_END 9
int strcmp(const char* s1, const char* s2)
{
while (*s1 && (*s1 == *s2))
{
s1++;
s2++;
}
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
}
int memcmp(const void *ptr1, const void *ptr2, uint32 num)
{
const unsigned char *p1 = (const unsigned char *)ptr1;
const unsigned char *p2 = (const unsigned char *)ptr2;
for (uint32 i = 0; i < num; i++)
{
if (p1[i] != p2[i])
return p1[i] - p2[i];
}
return 0;
}
void fdt_init(uint64 dtb)
{
if (dtb == 0) return;
struct fdt_header* header = (struct fdt_header*)dtb;
if (bswap(header->magic) != FDT_MAGIC)
return;
uint8* struct_ptr = (uint8*)(dtb + bswap(header->off_dt_struct));
char* strings_ptr = (char *)(dtb + bswap(header->off_dt_strings));
uint64 current_reg_addr = 0;
while (1)
{
uint32 token = bswap(*(uint32*)struct_ptr);
struct_ptr += 4;
if(token == FDT_END)break;
if(token == FDT_NOP)continue;
if(token == FDT_BEGIN_NODE)
{
while (*struct_ptr != 0)struct_ptr++;
struct_ptr++;
struct_ptr = (uint8*)(((uint64)struct_ptr + 3) & ~3);
}
else if(token == FDT_END_NODE)
{
}
else if (token == FDT_PROP)
{
uint32 len = bswap(*(uint32*)struct_ptr);
struct_ptr += 4;
uint32 nameoff = bswap(*(uint32*)struct_ptr);
struct_ptr += 4;
char* name = strings_ptr + nameoff;
uint8* data = struct_ptr;
struct_ptr += len;
struct_ptr = (uint8*)(((uint64)struct_ptr + 3) & ~3);
if(strcmp(name, "reg") == 0 && len >= 8)
{
uint32 hi = bswap(*(uint32*)data);
uint32 lo = bswap(*(uint32*)(data + 4));
current_reg_addr = ((uint64)hi << 32) | lo;
}
if(strcmp(name, "compatible") == 0)
{
if (g_uart_base == 0)
{
for(uint32 i = 0; i < len; i++)
{
if (data[i] == 'n' && data[i + 1] == 's' && data[i + 2] == '1')
{
g_uart_base = current_reg_addr;
break;
}
}
}
// if (g_clint_base == 0)
// {
// for (uint32 i = 0; i < len; i++)
// {
// if (data[i] == 'c' && data[i + 1] == 'l' && data[i + 2] == 'i' && data[i + 3] == 'n')
// {
// g_clint_base = current_reg_addr;
// break;
// }
// }
// }
}
}
}
}
|