xref: /haiku/src/system/boot/platform/efi/arch/arm64/arch_dtb.cpp (revision 6f80a9801fedbe7355c4360bd204ba746ec3ec2d)
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 
15 extern "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  */
26 const 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 
37 void
38 arch_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 
81 void
82 arch_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