Summarize the device tree
This commit is contained in:
23
kernel.s
23
kernel.s
@@ -30,11 +30,30 @@ kernel_main:
|
|||||||
la t0, kernel_entry
|
la t0, kernel_entry
|
||||||
csrw stvec, t0
|
csrw stvec, t0
|
||||||
|
|
||||||
# unimp
|
|
||||||
|
|
||||||
mv a0, a1
|
mv a0, a1
|
||||||
call device_tree
|
call device_tree
|
||||||
|
|
||||||
|
# Prepare the kernel root memory table.
|
||||||
|
la a0, __free_ram
|
||||||
|
li a1, 8
|
||||||
|
call write_x
|
||||||
|
|
||||||
|
la t0, __free_ram
|
||||||
|
srli t0, t0, 10
|
||||||
|
li t1, 0xf0000000
|
||||||
|
or t0, t0, t1
|
||||||
|
|
||||||
|
la t1, __free_ram
|
||||||
|
sw t0, (t1)
|
||||||
|
|
||||||
|
la t0, __free_ram
|
||||||
|
ori t0, t0, 1
|
||||||
|
|
||||||
|
csrw satp, t0
|
||||||
|
sfence.vma zero, zero
|
||||||
|
|
||||||
|
|
||||||
|
# Do nothing in a loop.
|
||||||
.Lkernel_main:
|
.Lkernel_main:
|
||||||
j .Lkernel_main
|
j .Lkernel_main
|
||||||
|
|
||||||
|
182
source.elna
182
source.elna
@@ -82,7 +82,7 @@ begin
|
|||||||
return written
|
return written
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc write_x(value: Word, padding: Word) -> Word;
|
proc write_x*(value: Word, padding: Word) -> Word;
|
||||||
return print_x(value, padding, write_c)
|
return print_x(value, padding, write_c)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -149,48 +149,142 @@ begin
|
|||||||
write_c('\n')
|
write_c('\n')
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc skip_node(stream: ^Char) -> ^Char;
|
proc strlen(input: ^Char) -> Word;
|
||||||
|
var
|
||||||
|
length: Word;
|
||||||
|
begin
|
||||||
|
length := 0u;
|
||||||
|
while cast(input^: Word) <> 0u do
|
||||||
|
length := length + 1u;
|
||||||
|
input := input + 1
|
||||||
|
end;
|
||||||
|
|
||||||
|
return length
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc memory_node(stream: ^Char, strings: ^Char);
|
||||||
|
var
|
||||||
|
property: fdt_property_header;
|
||||||
|
token: Word;
|
||||||
|
name_data: ^Char;
|
||||||
|
name: String;
|
||||||
|
property_position: Word;
|
||||||
|
element: Word;
|
||||||
|
begin
|
||||||
|
write_s("memory\n");
|
||||||
|
token := network_order(stream);
|
||||||
|
|
||||||
|
while token = FDT_PROP do
|
||||||
|
property := parse_property_header(stream);
|
||||||
|
stream := stream + 12;
|
||||||
|
|
||||||
|
name_data := strings + property.nameoff;
|
||||||
|
name := String(name_data, strlen(name_data));
|
||||||
|
|
||||||
|
write_s(" ");
|
||||||
|
write_s(name);
|
||||||
|
|
||||||
|
if name = "reg" then
|
||||||
|
property_position := 0u;
|
||||||
|
|
||||||
|
while property_position < property.len do
|
||||||
|
element := network_order(stream);
|
||||||
|
write_c(' ');
|
||||||
|
write_x(element, 8u);
|
||||||
|
|
||||||
|
property_position := property_position + 4u;
|
||||||
|
stream := stream + 4
|
||||||
|
end
|
||||||
|
else
|
||||||
|
write_c(' ');
|
||||||
|
stream := stream + property.len;
|
||||||
|
write_i(cast(property.len: Int))
|
||||||
|
end;
|
||||||
|
write_c('\n');
|
||||||
|
|
||||||
|
align_stream(@stream);
|
||||||
|
token := network_order(stream)
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc parse_property_header(stream: ^Char) -> fdt_property_header;
|
||||||
|
var
|
||||||
|
property: fdt_property_header;
|
||||||
|
begin
|
||||||
|
stream := stream + 4;
|
||||||
|
property.len := network_order(stream);
|
||||||
|
|
||||||
|
stream := stream + 4;
|
||||||
|
property.nameoff := network_order(stream);
|
||||||
|
|
||||||
|
return property
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc memcmp(lhs: Pointer, rhs: Pointer, n: Word) -> Int;
|
||||||
|
var
|
||||||
|
i: Word;
|
||||||
|
lhs_char: ^Char;
|
||||||
|
rhs_char: ^Char;
|
||||||
|
result: Int;
|
||||||
|
begin
|
||||||
|
lhs_char := cast(lhs: ^Char);
|
||||||
|
rhs_char := cast(lhs: ^Char);
|
||||||
|
result := 0;
|
||||||
|
|
||||||
|
while i < n & result = 0 do
|
||||||
|
result := lhs_char - rhs_char;
|
||||||
|
lhs_char := lhs_char + 1;
|
||||||
|
rhs_char := rhs_char + 1;
|
||||||
|
i := i + 1u
|
||||||
|
end;
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc skip_node(stream: ^Char, strings: ^Char) -> ^Char;
|
||||||
var
|
var
|
||||||
token: Word;
|
token: Word;
|
||||||
property: fdt_property_header;
|
property: fdt_property_header;
|
||||||
|
name_data: [31]Char;
|
||||||
|
name_length: Word;
|
||||||
|
name: String;
|
||||||
begin
|
begin
|
||||||
(* The first token should be FDT_BEGIN_NODE. *)
|
(* The first token should be FDT_BEGIN_NODE. *)
|
||||||
token := network_order(stream);
|
token := network_order(stream);
|
||||||
stream := stream + 4;
|
stream := stream + 4;
|
||||||
|
|
||||||
(* Read the token name. *)
|
(* Read the token name. *)
|
||||||
|
name_length := 0u;
|
||||||
|
while cast(stream^: Word) <> 0u & stream^ <> '@' do
|
||||||
|
name_length := name_length + 1u;
|
||||||
|
name_data[name_length] := stream^;
|
||||||
|
stream := stream + 1
|
||||||
|
end;
|
||||||
|
name := String(name_data.ptr, name_length);
|
||||||
|
|
||||||
while cast(stream^: Word) <> 0u do
|
while cast(stream^: Word) <> 0u do
|
||||||
write_c(stream^);
|
|
||||||
stream := stream + 1
|
stream := stream + 1
|
||||||
end;
|
end;
|
||||||
stream := stream + 1; (* Skip the trailing \0 encounted in the previous step. *)
|
stream := stream + 1; (* Skip the trailing \0 encounted in the previous step. *)
|
||||||
write_c('\n');
|
align_stream(@stream);
|
||||||
|
|
||||||
while cast(stream: Word) % 4u <> 0u do
|
if name = "memory" then
|
||||||
stream := stream + 1
|
memory_node(stream, strings)
|
||||||
|
elsif name = "reserved_memory" then
|
||||||
|
write_s("reserved_memory\n")
|
||||||
end;
|
end;
|
||||||
|
|
||||||
(* Property token. *)
|
(* Property token. *)
|
||||||
token := network_order(stream);
|
token := network_order(stream);
|
||||||
|
|
||||||
while token = FDT_PROP do
|
while token = FDT_PROP do
|
||||||
stream := stream + 4;
|
property := parse_property_header(stream);
|
||||||
|
stream := stream + 12 + property.len;
|
||||||
property.len := network_order(stream);
|
|
||||||
stream := stream + 4;
|
|
||||||
|
|
||||||
property.nameoff := network_order(stream);
|
|
||||||
stream := stream + 4;
|
|
||||||
|
|
||||||
stream := stream + property.len;
|
|
||||||
while cast(stream: Word) % 4u <> 0u do
|
|
||||||
stream := stream + 1
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
align_stream(@stream);
|
||||||
token := network_order(stream)
|
token := network_order(stream)
|
||||||
end;
|
end;
|
||||||
while token = FDT_BEGIN_NODE do
|
while token = FDT_BEGIN_NODE do
|
||||||
stream := skip_node(stream);
|
stream := skip_node(stream, strings);
|
||||||
token := network_order(stream)
|
token := network_order(stream)
|
||||||
end;
|
end;
|
||||||
(* Skip FDT_END_NODE. *)
|
(* Skip FDT_END_NODE. *)
|
||||||
@@ -199,16 +293,21 @@ begin
|
|||||||
return stream
|
return stream
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc find_memory(stream: ^Char, header: ^fdt_header);
|
proc align_stream(stream: ^^Char);
|
||||||
begin
|
begin
|
||||||
|
while cast(stream^: Word) % 4u <> 0u do
|
||||||
|
stream^ := stream^ + 1
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc find_memory(stream: ^Char, header: ^fdt_header);
|
||||||
|
var
|
||||||
|
strings: ^Char;
|
||||||
|
begin
|
||||||
|
strings := stream + header^.off_dt_strings;
|
||||||
stream := stream + header^.off_dt_struct;
|
stream := stream + header^.off_dt_struct;
|
||||||
|
|
||||||
skip_node(stream);
|
skip_node(stream, strings)
|
||||||
|
|
||||||
(* write_i(cast(stream^: Int));
|
|
||||||
write_i(cast(token: Int)); *)
|
|
||||||
|
|
||||||
write_c('\n')
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc parse_header(stream: ^Char, header: ^fdt_header) -> ^Char;
|
proc parse_header(stream: ^Char, header: ^fdt_header) -> ^Char;
|
||||||
@@ -246,6 +345,34 @@ begin
|
|||||||
return stream
|
return stream
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
proc reserve_memory(stream: ^Char, header: ^fdt_header);
|
||||||
|
var
|
||||||
|
component: Word;
|
||||||
|
begin
|
||||||
|
stream := stream + header^.off_mem_rsvmap;
|
||||||
|
write_s("Reserved memory map: ");
|
||||||
|
|
||||||
|
component := network_order(stream);
|
||||||
|
write_x(component, 8u);
|
||||||
|
stream := stream + 4;
|
||||||
|
write_c(' ');
|
||||||
|
|
||||||
|
component := network_order(stream);
|
||||||
|
write_x(component, 8u);
|
||||||
|
stream := stream + 4;
|
||||||
|
write_c(' ');
|
||||||
|
|
||||||
|
component := network_order(stream);
|
||||||
|
write_x(component, 8u);
|
||||||
|
stream := stream + 4;
|
||||||
|
write_c(' ');
|
||||||
|
|
||||||
|
component := network_order(stream);
|
||||||
|
write_x(component, 8u);
|
||||||
|
stream := stream + 4;
|
||||||
|
write_c('\n')
|
||||||
|
end;
|
||||||
|
|
||||||
proc device_tree*(raw: Pointer);
|
proc device_tree*(raw: Pointer);
|
||||||
var
|
var
|
||||||
raw_as_char: ^Char;
|
raw_as_char: ^Char;
|
||||||
@@ -257,7 +384,8 @@ begin
|
|||||||
print_header(@header);
|
print_header(@header);
|
||||||
|
|
||||||
write_c('\n');
|
write_c('\n');
|
||||||
find_memory(raw_as_char, @header)
|
find_memory(raw_as_char, @header);
|
||||||
|
reserve_memory(raw_as_char, @header)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
Reference in New Issue
Block a user