-
Notifications
You must be signed in to change notification settings - Fork 19
Device tree driver basics done #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
0604a8c
added polled uart
crusom a4c6b9d
Added v basic console handling
crusom d919c1c
added polled uart
crusom 02285ec
Added v basic console handling
crusom 7e80898
Added the device tree driver, not tested
Kamilosok 9d56f72
Fixed lib issues and example
Kamilosok 871d287
Fixed the basic functioncs of the DT
Kamilosok 30f16f6
Clang formatted and repaired whitespaces
Kamilosok fbb4056
Fixed incorrect merge issues and Cmake arguments
Kamilosok a24c6de
Addressed most problems that appeared in the main repo
Kamilosok b2d5f31
Added buffers to the best of my ability & improvements
Kamilosok 6934d43
Removed unnecessary console-related stuff
Kamilosok 89cc155
Implemented and fixed inconsistencies and remarks
Kamilosok 363eb7e
Improved encapsulation and logic
Kamilosok 056c33b
Properties are now fetched through buffers
Kamilosok 263055d
Naming schema conversions
Kamilosok File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| #ifndef DT_H | ||
| #define DT_H | ||
|
|
||
| #include <drivers/dt/dt_node.h> | ||
| #include <stdbigos/buffer.h> | ||
| #include <stdbigos/types.h> | ||
|
|
||
| // Initializes the device tree driver, the second argument specifies, whether the machine operates on big endian numbers | ||
| // natively | ||
| // TODO: Currently parses the entire FDT at init, maybe change to lazy parsing later | ||
| // Builds the actual tree structure handleable by the driver, 0 if success, <0 if error | ||
| int dt_init(const void* fdt, endianness_t machine_big_endian); | ||
|
|
||
| // Frees all memory used by the arena | ||
| void dt_cleanup(void); | ||
|
|
||
| // Find a node by full path in the tree, dt_node_t ptr if success, nullptr if error | ||
| dt_node_t* dt_node_find(const char* path); | ||
|
|
||
| // Get a node's name, const char ptr name if success, nullptr if error | ||
| const char* dt_node_get_name(const dt_node_t* node); | ||
|
|
||
| // Get node's child count, >=0 if success, <0 if error | ||
| int dt_node_child_count(const dt_node_t* node); | ||
|
|
||
| // Get a node's next sibling, dt_node_t ptr if success, nullptr if error or node is the last child | ||
| dt_node_t* dt_get_next_child(const dt_node_t* node); | ||
|
|
||
| // Returns the pointer to the root of the parsed device tree if success, nullptr if error | ||
| dt_node_t* dt_get_root(void); | ||
|
|
||
| void dt_reset_root(void); | ||
|
|
||
| #endif | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| #ifndef DT_NODE_H | ||
| #define DT_NODE_H | ||
|
|
||
| #include <stdbigos/types.h> | ||
|
|
||
| // Both prop and node structures are lists with outside pointers only to the first element | ||
| typedef struct dt_prop_t { | ||
| const char* name; | ||
| const void* value; | ||
| u32 data_length; | ||
| struct dt_prop_t* next_prop; | ||
| } dt_prop_t; | ||
|
|
||
| typedef struct dt_node_t { | ||
| const char* name; | ||
| u32 phandle; | ||
| struct dt_prop_t* props; | ||
| struct dt_node_t* parent; | ||
| struct dt_node_t* first_child; | ||
| struct dt_node_t* next_sibling; | ||
| } dt_node_t; | ||
|
|
||
| #endif |
|
qbojj marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| #ifndef DT_PROPS_H | ||
| #define DT_PROPS_H | ||
|
|
||
| #include <drivers/dt/dt_node.h> | ||
| #include <stdbigos/types.h> | ||
|
|
||
| // Can be used to check for bool-type props | ||
| // Find a property of node by a name, dt_prop_t ptr if success, nullptr if error | ||
| dt_prop_t* dt_find_prop(const dt_node_t* node, const char* name); | ||
|
|
||
| // Get a buffer of node's name value, the buffer's BUFFER_ERROR field will have any potential errors | ||
| buffer_t dt_prop_get_buffer(const dt_node_t* node, const char* name); | ||
|
|
||
| // Print the node's properties | ||
| void dt_print_props(const dt_node_t* node, u8 depth); | ||
|
|
||
| // Print the entire subtree with properties | ||
| void dt_print_tree(const dt_node_t* node, u8 depth); | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #ifndef _STDBIGOS_BITUTILS_H | ||
| #define _STDBIGOS_BITUTILS_H | ||
|
|
||
| #include <stdbigos/types.h> | ||
|
|
||
| u32 read_be32(const void* addr); | ||
|
|
||
| u64 read_be64(const void* addr); | ||
|
|
||
| u32 align_u32(u32 num, u32 align); | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| #ifndef _STDBIGOS_BUFFER_H | ||
| #define _STDBIGOS_BUFFER_H | ||
|
|
||
| #include <stdbigos/types.h> | ||
|
|
||
| // Error codes | ||
| typedef enum : u32 { | ||
| BUF_ERR_OK = 0, | ||
| BUF_ERR_OUT_OF_BOUNDS = 1, | ||
| BUF_ERR_FETCH = 2 | ||
| } buffer_error_t; | ||
|
|
||
| typedef struct buffer_t { | ||
| const void* data; | ||
| size_t size; | ||
| buffer_error_t error; | ||
| } buffer_t; | ||
|
|
||
| // Helpers to create buffers | ||
| static inline buffer_t make_buffer(const void* data, size_t size) { | ||
| buffer_t buf = {.data = data, .size = size, .error = BUF_ERR_OK}; | ||
| return buf; | ||
| } | ||
|
|
||
| static inline buffer_t make_buffer_err(const void* data, size_t size, buffer_error_t error) { | ||
| buffer_t buf = {.data = data, .size = size, .error = error}; | ||
| return buf; | ||
| } | ||
|
|
||
| // Read big-endian 32-bit from buffer at given offset | ||
| int buffer_read_u32_be(buffer_t buf, size_t offset, u32* out); | ||
|
|
||
| // Read big-endian 64-bit from buffer at given offset | ||
| int buffer_read_u64_be(buffer_t buf, size_t offset, u64* out); | ||
|
|
||
| // Read little-endian 32-bit from buffer at given offset | ||
| int buffer_read_u32_le(buffer_t buf, size_t offset, u32* out); | ||
|
|
||
| // Read little-endian 64-bit from buffer at given offset | ||
| int buffer_read_u64_le(buffer_t buf, size_t offset, u64* out); | ||
|
|
||
| // Read a zero-terminated C-string from buf at offset | ||
| int buffer_read_cstring(buffer_t buf, size_t offset, const char** out_str); | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| add_subdirectory(dt) | ||
|
|
||
| SETUP_LIBRARY(drivers) | ||
| target_link_libraries(drivers INTERFACE dt) | ||
|
|
||
| target_include_directories(drivers | ||
| INTERFACE | ||
| ${CMAKE_SOURCE_DIR}/include/drivers | ||
| ) |
|
Kamilosok marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| SETUP_LIBRARY(dt) | ||
|
|
||
| target_link_libraries(dt PRIVATE stdbigos) | ||
|
|
||
| if(CMAKE_BUILD_TYPE STREQUAL "Debug") | ||
| target_link_libraries(dt PRIVATE Debug) | ||
| endif() | ||
|
|
||
|
|
||
| target_include_directories(dt | ||
| PUBLIC | ||
| ${CMAKE_SOURCE_DIR}/include/drivers/dt | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| #include <debug/debug_stdio.h> | ||
| #include <drivers/dt/dt.h> | ||
| #include <drivers/dt/dt_node.h> | ||
| #include <drivers/dt/dt_props.h> | ||
| #include <stdbigos/bitutils.h> | ||
| #include <stdbigos/string.h> | ||
|
|
||
| #include "dt_alloc.h" | ||
| #include "dt_parser.h" | ||
|
|
||
| static dt_node_t* find_child_by_name_s(dt_node_t* parent, const char* name) { | ||
| for (dt_node_t* child = parent->first_child; child; child = child->next_sibling) { | ||
| if (strcmp(child->name, name) == 0) { | ||
| return child; | ||
| } | ||
| } | ||
| return nullptr; | ||
| } | ||
|
|
||
| dt_node_t* dt_node_find(const char* path) { | ||
| dt_node_t* root_node = dt_get_root(); | ||
|
|
||
| if (!path || path[0] != '/' || !root_node) | ||
| return nullptr; | ||
|
|
||
| if (strcmp(path, "/") == 0) | ||
| return root_node; | ||
|
|
||
| dt_node_t* current = root_node; | ||
| const char* p = path + 1; | ||
|
|
||
| while (*p) { | ||
| const char* slash = p; | ||
| while (*slash && *slash != '/') slash += 1; | ||
|
|
||
| uintptr_t len = slash - p; | ||
| if (len == 0) | ||
| break; | ||
|
|
||
| char segment[64]; | ||
| if (len >= (u32)sizeof(segment)) | ||
| return nullptr; | ||
|
|
||
| memcpy(segment, p, len); | ||
| segment[len] = '\0'; | ||
|
|
||
| current = find_child_by_name_s(current, segment); | ||
| if (!current) | ||
| return nullptr; | ||
|
|
||
| p = (*slash == '/') ? slash + 1 : slash; | ||
| } | ||
|
|
||
| return current; | ||
| } | ||
|
|
||
| const char* dt_node_get_name(const dt_node_t* node) { | ||
| if (!node) | ||
| return nullptr; | ||
|
|
||
| return node->name; | ||
| } | ||
|
|
||
| int dt_node_child_count(const dt_node_t* n) { | ||
| int c = 0; | ||
| for (dt_node_t* ch = n->first_child; ch; ch = ch->next_sibling) c++; | ||
| return c; | ||
| } | ||
|
|
||
| dt_node_t* dt_get_next_child(const dt_node_t* node) { | ||
| if (!node) | ||
| return nullptr; | ||
|
|
||
| // If there's no next sibling, it will automatically return a nullptr, as per documentation | ||
| return node->next_sibling; | ||
| } | ||
|
|
||
| dt_prop_t* dt_find_prop(const dt_node_t* node, const char* name) { | ||
| if (!node || !name) | ||
| return nullptr; | ||
|
|
||
| for (dt_prop_t* prop = node->props; prop; prop = prop->next_prop) { | ||
| if (strcmp(prop->name, name) == 0) { | ||
| return prop; | ||
| } | ||
| } | ||
|
|
||
| return nullptr; | ||
| } | ||
|
|
||
| buffer_t dt_prop_get_buffer(const dt_node_t* node, const char* name) { | ||
| buffer_t buffer = make_buffer_err(nullptr, 0, BUF_ERR_FETCH); | ||
|
|
||
| dt_prop_t* prop = dt_find_prop(node, name); | ||
| if (!prop || !prop->value) | ||
| return buffer; | ||
|
|
||
| buffer.data = prop->value; | ||
| buffer.size = prop->data_length; | ||
| buffer.error = BUF_ERR_OK; | ||
|
|
||
| return buffer; | ||
| } | ||
|
|
||
| #ifndef NDEBUG | ||
|
|
||
| // Use only in debug preset | ||
| void dt_print_props(const dt_node_t* node, [[maybe_unused]] u8 depth) { | ||
| dt_prop_t* next = node->props; | ||
| while (next) { | ||
| dputgap(depth); | ||
| dprintf("%s\n", next->name); | ||
| next = next->next_prop; | ||
| } | ||
| } | ||
|
|
||
| // Use only in debug preset | ||
| void dt_print_tree(const dt_node_t* node, [[maybe_unused]] u8 depth) { | ||
| dputgap(depth); | ||
| dprintf("NODE: %s\n", node->name); | ||
| dputgap(depth); | ||
|
|
||
| dprintf("PROPERTIES:\n"); | ||
| dt_print_props(node, depth + 1); | ||
| dputc('\n'); | ||
| dt_node_t* next = node->first_child; | ||
| while (next) { | ||
| dt_print_tree(next, depth + 1); | ||
| next = next->next_sibling; | ||
| } | ||
| } | ||
|
Kamilosok marked this conversation as resolved.
|
||
| #else | ||
| void dt_print_props(const dt_node_t* node, [[maybe_unused]] u8 depth); | ||
| void dt_print_tree(const dt_node_t* node, [[maybe_unused]] u8 depth); | ||
| #endif | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| #include "dt_alloc.h" | ||
|
|
||
| #include <stdbigos/bitutils.h> | ||
| #include <stdbigos/buffer.h> | ||
| #include <stdbigos/types.h> | ||
|
|
||
| // Arena proper | ||
| static u8 dt_arena_buffer[DT_ARENA_SIZE]; | ||
|
|
||
| static u32* arena_start = nullptr; | ||
|
|
||
| // Arena size in bytes | ||
| static u32 arena_size; | ||
|
|
||
| // Used area size in bytes | ||
| static u32 arena_offset; | ||
|
|
||
| u8* dt_get_arena_buffer(void) { | ||
| return dt_arena_buffer; | ||
| } | ||
|
|
||
| int dt_arena_init(void* start, u32 size) { | ||
| if (start == nullptr || size == 0) | ||
| return -1; | ||
|
|
||
| arena_start = (u32*)start; | ||
| arena_size = size; | ||
| arena_offset = 0; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| void* dt_alloc(u32 size) { | ||
| // May not be needed | ||
| if (size == 0) | ||
| return nullptr; | ||
|
|
||
| // Align to 4 bytes | ||
| u32 align = align_u32(size, 4); | ||
|
|
||
| if (arena_offset + align > arena_size) | ||
| return nullptr; | ||
|
|
||
| void* new_block = arena_start + arena_offset; | ||
| arena_offset += align; | ||
|
|
||
| return new_block; | ||
| } | ||
|
|
||
| // Invalidates previously allocated blocks by ignoring them | ||
| void dt_arena_reset(void) { | ||
| arena_offset = 0; | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.