xref: /haiku/src/system/boot/platform/efi/dtb.cpp (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
1 /*
2  * Copyright 2019-2020 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *   Alexander von Gluck IV <kallisti5@unixzen.com>
7  */
8 
9 
10 #include <boot/addr_range.h>
11 #include <boot/platform.h>
12 #include <boot/stage2.h>
13 #include <kernel/kernel.h>
14 
15 #include <ByteOrder.h>
16 
17 #include "efi_platform.h"
18 
19 
20 #define INFO(x...) dprintf("efi/fdt: " x)
21 #define ERROR(x...) dprintf("efi/fdt: " x)
22 
23 
24 static void* sDtbTable = NULL;
25 static uint32 sDtbSize = 0;
26 
27 
28 static bool
29 fdt_valid(void* fdt, uint32* size)
30 {
31 	if (fdt == NULL)
32 		return false;
33 	uint32* words = (uint32*)fdt;
34 	if (B_BENDIAN_TO_HOST_INT32(words[0]) != 0xd00dfeed)
35 		return false;
36 	*size = B_BENDIAN_TO_HOST_INT32(words[1]);
37 	if (size == 0)
38 		return false;
39 
40 	return true;
41 }
42 
43 
44 void
45 dtb_init()
46 {
47 	efi_configuration_table *table = kSystemTable->ConfigurationTable;
48 	size_t entries = kSystemTable->NumberOfTableEntries;
49 
50 	INFO("Probing for device trees from UEFI...\n");
51 
52 	// Try to find an FDT
53 	for (uint32 i = 0; i < entries; i++) {
54 		if (!table[i].VendorGuid.equals(DEVICE_TREE_GUID))
55 			continue;
56 
57 		void* dtbPtr = (void*)(table[i].VendorTable);
58 
59 		uint32 fdtSize = 0;
60 		if (!fdt_valid(dtbPtr, &fdtSize)) {
61 			ERROR("Invalid FDT from UEFI table %d\n", i);
62 			break;
63 		} else {
64 			INFO("Valid FDT from UEFI table %d (%d)\n", i, fdtSize);
65 
66 			sDtbTable = dtbPtr;
67 			sDtbSize = fdtSize;
68 			break;
69 		}
70 	}
71 }
72 
73 
74 void
75 dtb_set_kernel_args()
76 {
77 	// pack into proper location if the architecture cares
78 	if (sDtbTable != NULL) {
79 		#ifdef __ARM__
80 		gKernelArgs.arch_args.fdt = kernel_args_malloc(sDtbSize);
81 		if (gKernelArgs.arch_args.fdt != NULL)
82 			memcpy(gKernelArgs.arch_args.fdt, sDtbTable, sDtbSize);
83 		else
84 			ERROR("unable to malloc for fdt!\n");
85 		#endif
86 	}
87 }
88