1/* 2 * Copyright 2019-2021 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#include <arch_cpu_defs.h> 10#include <arch_dtb.h> 11#include <arch_smp.h> 12#include <boot/platform.h> 13#include <boot/stage2.h> 14 15extern "C" { 16#include <libfdt.h> 17} 18 19#include "dtb.h" 20 21/* TODO: Code taken from ARM port just for building purposes */ 22 23/* The potential interrupt controoller would be present in the dts as: 24 * compatible = "arm,gic-v3"; 25 */ 26const struct supported_interrupt_controllers { 27 const char* dtb_compat; 28 const char* kind; 29} kSupportedInterruptControllers[] = { 30 { "arm,cortex-a9-gic", INTC_KIND_GICV1 }, 31 { "arm,cortex-a15-gic", INTC_KIND_GICV2 }, 32 { "ti,omap3-intc", INTC_KIND_OMAP3 }, 33 { "marvell,pxa-intc", INTC_KIND_PXA }, 34}; 35 36 37void 38arch_handle_fdt(const void* fdt, int node) 39{ 40 const char* deviceType = (const char*)fdt_getprop(fdt, node, 41 "device_type", NULL); 42 43 if (deviceType != NULL) { 44 if (strcmp(deviceType, "cpu") == 0) { 45 platform_cpu_info* info = NULL; 46 arch_smp_register_cpu(&info); 47 if (info == NULL) 48 return; 49 info->id = fdt32_to_cpu(*(uint32*)fdt_getprop(fdt, node, 50 "reg", NULL)); 51 dprintf("cpu\n"); 52 dprintf(" id: %" B_PRIu32 "\n", info->id); 53 54 } 55 } 56 57 int compatibleLen; 58 const char* compatible = (const char*)fdt_getprop(fdt, node, 59 "compatible", &compatibleLen); 60 61 if (compatible == NULL) 62 return; 63 64 intc_info &interrupt_controller = gKernelArgs.arch_args.interrupt_controller; 65 if (interrupt_controller.kind[0] == 0) { 66 for (uint32 i = 0; i < B_COUNT_OF(kSupportedInterruptControllers); i++) { 67 if (dtb_has_fdt_string(compatible, compatibleLen, 68 kSupportedInterruptControllers[i].dtb_compat)) { 69 70 memcpy(interrupt_controller.kind, kSupportedInterruptControllers[i].kind, 71 sizeof(interrupt_controller.kind)); 72 73 dtb_get_reg(fdt, node, 0, interrupt_controller.regs1); 74 dtb_get_reg(fdt, node, 1, interrupt_controller.regs2); 75 } 76 } 77 } 78} 79 80 81void 82arch_dtb_set_kernel_args(void) 83{ 84 intc_info &interrupt_controller = gKernelArgs.arch_args.interrupt_controller; 85 dprintf("Chosen interrupt controller:\n"); 86 if (interrupt_controller.kind[0] == 0) { 87 dprintf("kind: None!\n"); 88 } else { 89 dprintf(" kind: %s\n", interrupt_controller.kind); 90 dprintf(" regs: %#" B_PRIx64 ", %#" B_PRIx64 "\n", 91 interrupt_controller.regs1.start, 92 interrupt_controller.regs1.size); 93 dprintf(" %#" B_PRIx64 ", %#" B_PRIx64 "\n", 94 interrupt_controller.regs2.start, 95 interrupt_controller.regs2.size); 96 } 97} 98