xref: /haiku/src/system/boot/platform/openfirmware/arch/ppc/cpu.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
1 /*
2  * Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 #include <boot/platform/openfirmware/platform_arch.h>
7 
8 #include <stdio.h>
9 
10 #include <KernelExport.h>
11 
12 #include <boot/kernel_args.h>
13 #include <boot/stage2.h>
14 #include <kernel.h>
15 #include <platform/openfirmware/devices.h>
16 #include <platform/openfirmware/openfirmware.h>
17 
18 #define TRACE_CPU
19 #ifdef TRACE_CPU
20 #	define TRACE(x) dprintf x
21 #else
22 #	define TRACE(x) ;
23 #endif
24 
25 
26 status_t
27 boot_arch_cpu_init(void)
28 {
29 	int32 busFrequency = 0;
30 
31 	int root = of_finddevice("/");
32 	if (root == OF_FAILED) {
33 		printf("boot_arch_cpu_init(): Failed to open \"/\"!\n");
34 		return B_ERROR;
35 	}
36 
37 	of_getprop(root, "clock-frequency", &busFrequency, 4);
38 		// we might find it in /cpus instead
39 
40 	// iterate through the "/cpus" node to find all CPUs
41 	int cpus = of_finddevice("/cpus");
42 	if (cpus == OF_FAILED) {
43 		printf("boot_arch_cpu_init(): Failed to open \"/cpus\"!\n");
44 		return B_ERROR;
45 	}
46 
47 	char cpuPath[256];
48 	int cookie = 0;
49 	int cpuCount = 0;
50 	while (of_get_next_device(&cookie, cpus, "cpu", cpuPath,
51 			sizeof(cpuPath)) == B_OK) {
52 		TRACE(("found CPU: %s\n", cpuPath));
53 
54 		// For the first CPU get the frequencies of CPU, bus, and time base.
55 		// We assume they are the same for all CPUs.
56 		if (cpuCount == 0) {
57 			int cpu = of_finddevice(cpuPath);
58 			if (cpu == OF_FAILED) {
59 				printf("boot_arch_cpu_init: Failed get CPU device node!\n");
60 				return B_ERROR;
61 			}
62 
63 			// TODO: Does encode-int really encode quadlet (32 bit numbers)
64 			// only?
65 			int32 clockFrequency;
66 			if (of_getprop(cpu, "clock-frequency", &clockFrequency, 4)
67 					== OF_FAILED) {
68 				printf("boot_arch_cpu_init: Failed to get CPU clock "
69 					"frequency!\n");
70 				return B_ERROR;
71 			}
72 			if (busFrequency == 0
73 				&& of_getprop(cpu, "bus-frequency", &busFrequency, 4)
74 					== OF_FAILED) {
75 				printf("boot_arch_cpu_init: Failed to get bus clock "
76 					"frequency!\n");
77 				return B_ERROR;
78 			}
79 			int32 timeBaseFrequency;
80 			if (of_getprop(cpu, "timebase-frequency", &timeBaseFrequency, 4)
81 					== OF_FAILED) {
82 				printf("boot_arch_cpu_init: Failed to get time base "
83 					"frequency!\n");
84 				return B_ERROR;
85 			}
86 
87 			gKernelArgs.arch_args.cpu_frequency = clockFrequency;
88 			gKernelArgs.arch_args.bus_frequency = busFrequency;
89 			gKernelArgs.arch_args.time_base_frequency = timeBaseFrequency;
90 
91 			TRACE(("  CPU clock frequency: %ld\n", clockFrequency));
92 			TRACE(("  bus clock frequency: %ld\n", busFrequency));
93 			TRACE(("  time base frequency: %ld\n", timeBaseFrequency));
94 		}
95 
96 		cpuCount++;
97 	}
98 
99 	if (cpuCount == 0) {
100 		printf("boot_arch_cpu_init(): Found no CPUs!\n");
101 		return B_ERROR;
102 	}
103 
104 	gKernelArgs.num_cpus = cpuCount;
105 
106 	// allocate the kernel stacks (the memory stuff is already initialized
107 	// at this point)
108 	addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000,
109 		cpuCount * (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE),
110 		B_READ_AREA | B_WRITE_AREA, false);
111 	if (!stack) {
112 		printf("boot_arch_cpu_init(): Failed to allocate kernel stack(s)!\n");
113 		return B_NO_MEMORY;
114 	}
115 
116 	for (int i = 0; i < cpuCount; i++) {
117 		gKernelArgs.cpu_kstack[i].start = stack;
118 		gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE
119 			+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
120 		stack += KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
121 	}
122 
123 	return B_OK;
124 }
125 
126