From ff02f911cd6c198fcd892f2acdf3354682cb8447 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 6 Jul 2025 01:04:22 +0200 Subject: [PATCH] Summarize the device tree --- kernel.s | 23 ++++++- source.elna | 182 ++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 176 insertions(+), 29 deletions(-) diff --git a/kernel.s b/kernel.s index 65ca3c2..933d21e 100644 --- a/kernel.s +++ b/kernel.s @@ -30,11 +30,30 @@ kernel_main: la t0, kernel_entry csrw stvec, t0 - # unimp - mv a0, a1 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: j .Lkernel_main diff --git a/source.elna b/source.elna index 967d093..dcd78c9 100644 --- a/source.elna +++ b/source.elna @@ -82,7 +82,7 @@ begin return written end; -proc write_x(value: Word, padding: Word) -> Word; +proc write_x*(value: Word, padding: Word) -> Word; return print_x(value, padding, write_c) end; @@ -149,48 +149,142 @@ begin write_c('\n') 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 token: Word; property: fdt_property_header; + name_data: [31]Char; + name_length: Word; + name: String; begin (* The first token should be FDT_BEGIN_NODE. *) token := network_order(stream); stream := stream + 4; (* 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 - write_c(stream^); stream := stream + 1 end; 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 - stream := stream + 1 + if name = "memory" then + memory_node(stream, strings) + elsif name = "reserved_memory" then + write_s("reserved_memory\n") end; (* Property token. *) token := network_order(stream); while token = FDT_PROP do - stream := stream + 4; - - 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; + property := parse_property_header(stream); + stream := stream + 12 + property.len; + align_stream(@stream); token := network_order(stream) end; while token = FDT_BEGIN_NODE do - stream := skip_node(stream); + stream := skip_node(stream, strings); token := network_order(stream) end; (* Skip FDT_END_NODE. *) @@ -199,16 +293,21 @@ begin return stream end; -proc find_memory(stream: ^Char, header: ^fdt_header); +proc align_stream(stream: ^^Char); 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; - skip_node(stream); - - (* write_i(cast(stream^: Int)); - write_i(cast(token: Int)); *) - - write_c('\n') + skip_node(stream, strings) end; proc parse_header(stream: ^Char, header: ^fdt_header) -> ^Char; @@ -246,6 +345,34 @@ begin return stream 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); var raw_as_char: ^Char; @@ -257,7 +384,8 @@ begin print_header(@header); write_c('\n'); - find_memory(raw_as_char, @header) + find_memory(raw_as_char, @header); + reserve_memory(raw_as_char, @header) end; end.