Completely print out FDT
This commit is contained in:
parent
fb9829c93f
commit
75b3835bed
@ -16,18 +16,117 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "init.h"
|
||||
#include "fdt.h"
|
||||
|
||||
void fdt_init(fdt_header* fdt) {
|
||||
// Swap fdt_header values from big endian to little endian
|
||||
fdt->magic = SWAP_UINT32(fdt->magic);
|
||||
fdt->totalsize = SWAP_UINT32(fdt->totalsize);
|
||||
fdt->off_dt_struct = SWAP_UINT32(fdt->off_dt_struct);
|
||||
fdt->off_dt_strings = SWAP_UINT32(fdt->off_dt_strings);
|
||||
fdt->off_mem_rsvmap = SWAP_UINT32(fdt->off_mem_rsvmap);
|
||||
fdt->version = SWAP_UINT32(fdt->version);
|
||||
fdt->last_comp_version = SWAP_UINT32(fdt->last_comp_version);
|
||||
fdt->boot_cpuid_phys = SWAP_UINT32(fdt->boot_cpuid_phys);
|
||||
fdt->size_dt_strings = SWAP_UINT32(fdt->size_dt_strings);
|
||||
fdt->size_dt_struct = SWAP_UINT32(fdt->size_dt_struct);
|
||||
size_t _strlen(const char* str) {
|
||||
size_t len = 0;
|
||||
while (str[len]) {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void parse_fdt(fdt_header* fdt) {
|
||||
const char* fdt_strings = (uint32_t)fdt + SWAP_UINT32(fdt->off_dt_strings);
|
||||
uint32_t* fdt_struct = (uint32_t)fdt + SWAP_UINT32(fdt->off_dt_struct);
|
||||
const uint32_t struct_size = SWAP_UINT32(fdt->size_dt_struct);
|
||||
|
||||
uint32_t* struct_ptr = fdt_struct;
|
||||
uint32_t name_length = 0;
|
||||
uint32_t prop_length = 0;
|
||||
uint32_t prop_name_off = 0;
|
||||
uint8_t tab_count = 0;
|
||||
uint8_t first_elem = 0;
|
||||
|
||||
while(struct_ptr < fdt_struct + struct_size) {
|
||||
// Read token
|
||||
const uint32_t token = SWAP_UINT32(*struct_ptr);
|
||||
switch(token) {
|
||||
// The beginning node is followed immediately by its name
|
||||
case FDT_BEGIN_NODE:
|
||||
// Advance pointer
|
||||
struct_ptr++;
|
||||
|
||||
// print tabs
|
||||
for(int i = 0; i < tab_count; ++i) uart_puts(" ");
|
||||
// increment tab count
|
||||
tab_count++;
|
||||
|
||||
// Calculate the size of the node name
|
||||
name_length = _strlen(struct_ptr);
|
||||
|
||||
// Print node name
|
||||
if(!name_length) {
|
||||
uart_puts("/:");
|
||||
} else {
|
||||
uart_puts(struct_ptr);
|
||||
uart_puts(":");
|
||||
}
|
||||
uart_putc('\n');
|
||||
|
||||
// Advance pointer by size of node name aligned to 4 bytes
|
||||
struct_ptr += name_length / 4;
|
||||
break;
|
||||
|
||||
// Property
|
||||
case FDT_PROP:
|
||||
// Advance pointer
|
||||
prop_length = *++struct_ptr;
|
||||
prop_name_off = *++struct_ptr;
|
||||
|
||||
// print tabs
|
||||
for(int i = 0; i < tab_count+1; ++i) uart_puts(" ");
|
||||
|
||||
// Print prop name and value
|
||||
uart_puts(fdt_strings + SWAP_UINT32(prop_name_off));
|
||||
// Value can be empty
|
||||
if(prop_length) {
|
||||
uart_puts(": ");
|
||||
// Dirty hack to see if the value is a string or a number(s)
|
||||
// If the first byte of the 4 byte chunk does not fall
|
||||
// under acceptable ASCII character values, print its
|
||||
// digits one by one, else just call puts on it since
|
||||
// it is ***probably*** a string.
|
||||
first_elem = (char*)(SWAP_UINT32(*(struct_ptr+1)));
|
||||
// It is probably a number or an array of numbers
|
||||
if(first_elem < 0x20 || first_elem > 0x7A) {
|
||||
// Divide length of the property by 4 to get
|
||||
// the amount of numbers and iterate over them
|
||||
for(int i = 0; i < SWAP_UINT32(prop_length)/4; ++i) {
|
||||
uint32_t hex = SWAP_UINT32(*(struct_ptr+1+i));
|
||||
// Put 0x before to denote it is a hexadecimal number
|
||||
uart_puts("0x");
|
||||
// Shift and mask number to get digits
|
||||
for(int shift = 28; shift >= 0; shift -= 4) {
|
||||
int digit = (hex >> shift) & 0xF;
|
||||
int digit_char = (digit<10)?('0'+digit):('A'+digit-10);
|
||||
uart_putc(digit_char);
|
||||
}
|
||||
// There might be more numbers coming so seperate them
|
||||
uart_puts(" ");
|
||||
}
|
||||
} else {
|
||||
// Its a good old string
|
||||
uart_puts(struct_ptr+1);
|
||||
}
|
||||
}
|
||||
uart_putc('\n');
|
||||
struct_ptr += SWAP_UINT32(prop_length) / 4;
|
||||
break;
|
||||
|
||||
// End is followed immediately by next token
|
||||
case FDT_END_NODE:
|
||||
--tab_count;
|
||||
case FDT_NOP:
|
||||
break;
|
||||
|
||||
// There can be only one FDT_END which marks the
|
||||
// end of FDT
|
||||
case FDT_END:
|
||||
return;
|
||||
}
|
||||
// Advance pointer
|
||||
struct_ptr++;
|
||||
}
|
||||
}
|
@ -19,23 +19,34 @@
|
||||
#ifndef _ASAGIRI_AARCH64_FDT
|
||||
#define _ASAGIRI_AARCH64_FDT
|
||||
|
||||
#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))
|
||||
#define SWAP_UINT32(x) (((x) >> 24) | \
|
||||
(((x) & 0x00FF0000) >> 8) | \
|
||||
(((x) & 0x0000FF00) << 8) | \
|
||||
((x) << 24))
|
||||
|
||||
#include "bits/alltypes.h"
|
||||
|
||||
typedef struct fdt_header {
|
||||
uint32_t magic;
|
||||
uint32_t totalsize;
|
||||
uint32_t off_dt_struct;
|
||||
uint32_t off_dt_strings;
|
||||
uint32_t off_mem_rsvmap;
|
||||
uint32_t version;
|
||||
uint32_t last_comp_version;
|
||||
uint32_t boot_cpuid_phys;
|
||||
uint32_t size_dt_strings;
|
||||
uint32_t size_dt_struct;
|
||||
uint32_t magic; // Magic value identifying FDT
|
||||
uint32_t totalsize; // Total size of FDT including the header
|
||||
uint32_t off_dt_struct; // Offset from beginning of the FDT to the structure block
|
||||
uint32_t off_dt_strings; // Offset from beginning of the FDT to the strings block
|
||||
uint32_t off_mem_rsvmap; // Offset from beginning of the FDT to the memory reservation map
|
||||
uint32_t version; // FDT version
|
||||
uint32_t last_comp_version; // Last compatible version
|
||||
uint32_t boot_cpuid_phys; // Boot CPU ID
|
||||
uint32_t size_dt_strings; // Size of the strings block
|
||||
uint32_t size_dt_struct; // Size of the structure block
|
||||
} fdt_header;
|
||||
|
||||
void fdt_init(fdt_header*);
|
||||
enum {
|
||||
FDT_BEGIN_NODE = 0x1,
|
||||
FDT_END_NODE = 0x2,
|
||||
FDT_PROP = 0x3,
|
||||
FDT_NOP = 0x4,
|
||||
FDT_END = 0x9,
|
||||
};
|
||||
|
||||
void parse_fdt();
|
||||
|
||||
#endif
|
@ -27,27 +27,16 @@
|
||||
void __attribute__((section (".text.boot"))) _start() {
|
||||
// Read FDT and convert to little endian
|
||||
fdt_header* fdt = (fdt_header*)(*(uint32_t*)0x1337);
|
||||
fdt_init(fdt);
|
||||
// init uart
|
||||
uart_init(3);
|
||||
uart_puts(
|
||||
"Esselamunaleykum ve rahmetullahi ve berakatu\n"
|
||||
"Allahin selami uzerine olsun canim kardesim.\n"
|
||||
"Simdi sana DTBdeki stringleri siraliyorum: \n\n - "
|
||||
"Simdi sana DTByi siraliyorum:\n\n"
|
||||
);
|
||||
// Print char array
|
||||
char* char_array = (char*)((uint32_t)fdt + fdt->off_dt_strings);
|
||||
for(int i = 0; i < fdt->size_dt_strings; ++i) {
|
||||
char c = char_array[i];
|
||||
switch(c) {
|
||||
case '\n':
|
||||
case '\0':
|
||||
uart_puts("\r\n - ");
|
||||
break;
|
||||
default:
|
||||
uart_putc(c);
|
||||
}
|
||||
}
|
||||
|
||||
parse_fdt(fdt);
|
||||
|
||||
// Test to see if fdt address is correct
|
||||
asm(
|
||||
"mov x0, %0\n"
|
||||
|
Loading…
Reference in New Issue
Block a user