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 bool 25 fdt_valid(void* fdt, uint32* size) 26 { 27 if (fdt == NULL) 28 return false; 29 uint32* words = (uint32*)fdt; 30 if (B_BENDIAN_TO_HOST_INT32(words[0]) != 0xd00dfeed) 31 return false; 32 *size = B_BENDIAN_TO_HOST_INT32(words[1]); 33 if (size == 0) 34 return false; 35 36 return true; 37 } 38 39 40 void 41 dtb_init() 42 { 43 efi_configuration_table *table = kSystemTable->ConfigurationTable; 44 size_t entries = kSystemTable->NumberOfTableEntries; 45 46 INFO("Probing for device trees from UEFI...\n"); 47 48 // Try to find an FDT 49 for (uint32 i = 0; i < entries; i++) { 50 if (!table[i].VendorGuid.equals(DEVICE_TREE_GUID)) 51 continue; 52 53 void* dtbPtr = (void*)(table[i].VendorTable); 54 55 uint32 fdtSize = 0; 56 if (!fdt_valid(dtbPtr, &fdtSize)) { 57 ERROR("Invalid FDT from UEFI table %d\n", i); 58 break; 59 } 60 61 INFO("Valid FDT from UEFI table %d (%d)\n", i, fdtSize); 62 63 // pack into proper location if the architecture cares 64 #ifdef __ARM__ 65 gKernelArgs.arch_args.fdt = kernel_args_malloc(fdtSize); 66 if (gKernelArgs.arch_args.fdt != NULL) { 67 memcpy(gKernelArgs.arch_args.fdt, dtbPtr, fdtSize); 68 } else 69 ERROR("unable to malloc for fdt!\n"); 70 #endif 71 } 72 } 73