diff --git a/src/system/boot/platform/efi/dtb.cpp b/src/system/boot/platform/efi/dtb.cpp index fa49022e7a..55d9d8d6c1 100644 --- a/src/system/boot/platform/efi/dtb.cpp +++ b/src/system/boot/platform/efi/dtb.cpp @@ -460,8 +460,6 @@ dtb_handle_fdt(const void* fdt, int node) if (compatible == NULL) return; - // TODO: We should check for the "chosen" uart and prioritize that one - // check for a uart if we don't have one uart_info &uart = gKernelArgs.arch_args.uart; if (uart.kind[0] == 0) { @@ -487,6 +485,34 @@ dtb_handle_fdt(const void* fdt, int node) } +static void +dtb_handle_chosen_node(const void *fdt) +{ + int chosen = fdt_path_offset(fdt, "/chosen"); + if (chosen < 0) + return; + + int len; + const char *stdoutPath = (const char *)fdt_getprop(fdt, chosen, "stdout-path", &len); + if (stdoutPath == NULL) + return; + + // stdout-path can optionally contain a ":" separator character + // The part after the ":" character specifies the UART configuration + // We can ignore it here as the UART should be already initialized + // by the UEFI firmware (e.g. U-Boot or TianoCore) + + char *separator = strchr(stdoutPath, ':'); + int namelen = (separator == NULL) ? len - 1 : separator - stdoutPath; + + int stdoutNode = fdt_path_offset_namelen(fdt, stdoutPath, namelen); + if (stdoutNode < 0) + return; + + dtb_handle_fdt(fdt, stdoutNode); +} + + void dtb_init() { @@ -519,6 +545,8 @@ dtb_init() if (false) DumpFdt(sDtbTable); + dtb_handle_chosen_node(sDtbTable); + int node = -1; int depth = -1; while ((node = fdt_next_node(sDtbTable, node, &depth)) >= 0 && depth >= 0) {