aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2024-11-26 21:43:54 +0100
committerMiquel Sabaté Solà <mikisabate@gmail.com>2024-11-26 21:43:54 +0100
commit87d1a2597ceedd03a7d4005db1bf82b72b423a18 (patch)
treee53bf20d06016b37fde0067526ed7abd95b848e8 /lib
parenteec442be4d2dd0a1630a820ee43220e635450aa7 (diff)
downloadfbos-87d1a2597ceedd03a7d4005db1bf82b72b423a18.tar.gz
fbos-87d1a2597ceedd03a7d4005db1bf82b72b423a18.zip
Show the detected machine model
Originally I was planning to detect the machine model just in case we needed to do workaround for special cases. But since apparently even VisionFive2 brings its own CPU frequency base on DT, this is not even needed. Hence, fetching the model is now a cool message being shown on boot. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/dt.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/dt.c b/lib/dt.c
index ddf01f3..f5eed92 100644
--- a/lib/dt.c
+++ b/lib/dt.c
@@ -96,6 +96,54 @@ __kernel int32_t find_dt_node(uint32_t *dtb, struct fdt_header *header, const ch
return (int32_t)idx;
}
+// Returns the index in the 'dtb' of the first proper node.
+__kernel uint32_t first_dt_node(uint32_t *dtb, struct fdt_header *header)
+{
+ uint32_t idx;
+
+ for (idx = header->off_dt_struct; idx < header->size_dt_struct; idx++) {
+ if (dtb[idx] == FDT_BEGIN_NODE_LE) {
+ return idx;
+ }
+ }
+
+ return 0;
+}
+
+// Set the 'model' buffer from 'info' if available on the 'dtb' blob.
+__kernel void set_dt_model(uint32_t *dtb, struct dt_info *info, struct fdt_header *header)
+{
+ uint32_t len, nameoff;
+ uint32_t idx = first_dt_node(dtb, header);
+ char *base_dt_string = ((char *)dtb) + header->off_dt_string;
+
+ while (idx < header->size_dt_struct) {
+ len = __bswap_constant_32(dtb[idx + 1]);
+ nameoff = __bswap_constant_32(dtb[idx + 2]);
+ idx += 3;
+
+ if (strcmp(&base_dt_string[nameoff], "model") == 0) {
+ // In the (very unlikely) case that the model string is huge, don't
+ // even try.
+ if (len >= DT_MODEL_MAX) {
+ printk("WARNING: The model string is too large!\n");
+ break;
+ }
+
+ // And copy the string. Since we know the length of it, we can
+ // simply use 'memcpy' which is already available on kernel code as
+ // well.
+ memcpy(info->model, (char *)&dtb[idx], len);
+ info->model[len] = '\0';
+ break;
+ }
+
+ // Skip until the beginning of the next node.
+ for (; dtb[idx] != FDT_PROP_LE && idx < header->size_dt_struct; idx++)
+ ;
+ }
+}
+
// Set the 'cpu_freq' field of 'info' if available on the 'dtb' blob.
__kernel void set_cpu_freq(uint32_t *dtb, struct dt_info *info, struct fdt_header *header)
{
@@ -151,6 +199,8 @@ __kernel void get_dt_info(uint32_t *dtb, struct dt_info *info)
.size_dt_struct = __bswap_constant_32(dtb[9]) / sizeof(uint32_t),
};
+ set_dt_model(dtb, info, &header);
+
set_initrd_addr(dtb, info, &header);
if (!info->initrd_start || !info->initrd_end) {
die("Could not fetch the addresses for the initramfs\n");