1a182bd6eSX512 /* 2a182bd6eSX512 * Copyright 2021, Haiku, Inc. 3a182bd6eSX512 * Distributed under the terms of the MIT License. 4a182bd6eSX512 */ 5a182bd6eSX512 6a182bd6eSX512 7a182bd6eSX512 #include "fdt.h" 8a182bd6eSX512 #include <SupportDefs.h> 9a182bd6eSX512 #include <ByteOrder.h> 10a182bd6eSX512 #include <KernelExport.h> 11a182bd6eSX512 #include <boot/stage2.h> 12a182bd6eSX512 13a182bd6eSX512 extern "C" { 14a182bd6eSX512 #include <libfdt.h> 15a182bd6eSX512 } 16a182bd6eSX512 17a182bd6eSX512 #include "mmu.h" 18a182bd6eSX512 #include "graphics.h" 19a182bd6eSX512 #include "virtio.h" 20a182bd6eSX512 21a182bd6eSX512 22a182bd6eSX512 void* gFdt = NULL; 23a182bd6eSX512 24a182bd6eSX512 25a182bd6eSX512 static void 26a182bd6eSX512 HandleFdt(const void* fdt, int node, uint32_t addressCells, uint32_t sizeCells, 27a182bd6eSX512 uint32_t interruptCells /* from parent node */) 28a182bd6eSX512 { 29a182bd6eSX512 // TODO: handle different field sizes 30a182bd6eSX512 31a182bd6eSX512 const char* device_type = (const char*)fdt_getprop(fdt, node, 32a182bd6eSX512 "device_type", NULL); 33a182bd6eSX512 if (device_type != NULL && strcmp(device_type, "memory") == 0) { 34a182bd6eSX512 gMemBase = (uint8*)fdt64_to_cpu(*((uint64_t*)fdt_getprop(fdt, node, 35a182bd6eSX512 "reg", NULL) + 0)); 36a182bd6eSX512 gTotalMem = fdt64_to_cpu(*((uint64_t*)fdt_getprop(fdt, node, 37a182bd6eSX512 "reg", NULL) + 1)); 38a182bd6eSX512 return; 39a182bd6eSX512 } 40a182bd6eSX512 const char* compatible = (const char*)fdt_getprop(fdt, node, 41a182bd6eSX512 "compatible", NULL); 42a182bd6eSX512 if (compatible == NULL) return; 43a182bd6eSX512 if (strcmp(compatible, "virtio,mmio") == 0) { 44a182bd6eSX512 virtio_register( 45a182bd6eSX512 fdt64_to_cpu(*((uint64_t*)fdt_getprop(fdt, node, "reg", NULL) + 0)), 46a182bd6eSX512 fdt64_to_cpu(*((uint64_t*)fdt_getprop(fdt, node, "reg", NULL) + 1)), 47a182bd6eSX512 fdt32_to_cpu(*((uint32_t*)fdt_getprop(fdt, node, 48a182bd6eSX512 "interrupts-extended", NULL) + 1)) 49a182bd6eSX512 ); 50a182bd6eSX512 } else if (strcmp(compatible, "simple-framebuffer") == 0) { 51a182bd6eSX512 gFramebuf.colors = (uint32_t*)fdt64_to_cpu( 52a182bd6eSX512 *(uint64_t*)fdt_getprop(fdt, node, "reg", NULL)); 53a182bd6eSX512 gFramebuf.stride = fdt32_to_cpu( 54a182bd6eSX512 *(uint32_t*)fdt_getprop(fdt, node, "stride", NULL)) / 4; 55a182bd6eSX512 gFramebuf.width = fdt32_to_cpu( 56a182bd6eSX512 *(uint32_t*)fdt_getprop(fdt, node, "width", NULL)); 57a182bd6eSX512 gFramebuf.height = fdt32_to_cpu( 58a182bd6eSX512 *(uint32_t*)fdt_getprop(fdt, node, "height", NULL)); 59a182bd6eSX512 } 60a182bd6eSX512 } 61a182bd6eSX512 62a182bd6eSX512 63a182bd6eSX512 void 64a182bd6eSX512 fdt_init(void* fdt) 65a182bd6eSX512 { 66a182bd6eSX512 dprintf("FDT: %p\n", fdt); 67a182bd6eSX512 gFdt = fdt; 68a182bd6eSX512 69a182bd6eSX512 int res = fdt_check_header(gFdt); 70a182bd6eSX512 if (res != 0) { 71a182bd6eSX512 panic("Invalid FDT: %s\n", fdt_strerror(res)); 72a182bd6eSX512 } 73a182bd6eSX512 74a182bd6eSX512 dprintf("FDT valid, size: %" B_PRIu32 "\n", fdt_totalsize(gFdt)); 75a182bd6eSX512 76a182bd6eSX512 int node = -1; 77a182bd6eSX512 int depth = 0; 78a182bd6eSX512 while ((node = fdt_next_node(gFdt, node, &depth)) >= 0) { 79a182bd6eSX512 HandleFdt(gFdt, node, 2, 2, 2); 80a182bd6eSX512 } 81a182bd6eSX512 } 82a182bd6eSX512 83a182bd6eSX512 84a182bd6eSX512 void 85a182bd6eSX512 fdt_set_kernel_args() 86a182bd6eSX512 { 87c9d6d52bSAlexander von Gluck IV uint32_t fdtSize = fdt_totalsize(gFdt); 88c9d6d52bSAlexander von Gluck IV 89*4b5c7fe7SAlexander von Gluck IV // libfdt requires 8-byte alignment 90*4b5c7fe7SAlexander von Gluck IV gKernelArgs.arch_args.fdt = (void*)(addr_t)kernel_args_malloc(fdtSize, 8); 91c9d6d52bSAlexander von Gluck IV 92a182bd6eSX512 if (gKernelArgs.arch_args.fdt != NULL) { 93c9d6d52bSAlexander von Gluck IV memcpy(gKernelArgs.arch_args.fdt, gFdt, fdtSize); 94a182bd6eSX512 } else 95a182bd6eSX512 panic("unable to malloc for FDT!\n"); 96c9d6d52bSAlexander von Gluck IV 97c9d6d52bSAlexander von Gluck IV dprintf("FDT getting passed to kernel @ %p\n", (void*)gKernelArgs.arch_args.fdt.Pointer()); 98a182bd6eSX512 } 99