diff options
| author | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-11-26 21:43:54 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-11-26 21:43:54 +0100 |
| commit | 87d1a2597ceedd03a7d4005db1bf82b72b423a18 (patch) | |
| tree | e53bf20d06016b37fde0067526ed7abd95b848e8 /lib | |
| parent | eec442be4d2dd0a1630a820ee43220e635450aa7 (diff) | |
| download | fbos-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.c | 50 |
1 files changed, 50 insertions, 0 deletions
@@ -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"); |
