xref: /haiku/src/system/boot/platform/openfirmware/arch/ppc/cpu.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
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 	// iterate through the "/cpus" node to find all CPUs
30 	int cpus = of_finddevice("/cpus");
31 	if (cpus == OF_FAILED) {
32 		printf("boot_arch_cpu_init(): Failed to open \"/cpus\"!\n");
33 		return B_ERROR;
34 	}
35 
36 	char cpuPath[256];
37 	int cookie = 0;
38 	int cpuCount = 0;
39 	while (of_get_next_device(&cookie, cpus, "cpu", cpuPath,
40 			sizeof(cpuPath)) == B_OK) {
41 		TRACE(("found CPU: %s\n", cpuPath));
42 
43 		// For the first CPU get the frequencies of CPU, bus, and time base.
44 		// We assume they are the same for all CPUs.
45 		if (cpuCount == 0) {
46 			int cpu = of_finddevice(cpuPath);
47 			if (cpu == OF_FAILED) {
48 				printf("boot_arch_cpu_init: Failed get CPU device node!\n");
49 				return B_ERROR;
50 			}
51 
52 			// TODO: Does encode-int really encode quadlet (32 bit numbers)
53 			// only?
54 			int32 clockFrequency;
55 			if (of_getprop(cpu, "clock-frequency", &clockFrequency, 4)
56 					== OF_FAILED) {
57 				printf("boot_arch_cpu_init: Failed to get CPU clock "
58 					"frequency!\n");
59 				return B_ERROR;
60 			}
61 			int32 busFrequency;
62 			if (of_getprop(cpu, "bus-frequency", &busFrequency, 4)
63 					== OF_FAILED) {
64 				printf("boot_arch_cpu_init: Failed to get bus clock "
65 					"frequency!\n");
66 				return B_ERROR;
67 			}
68 			int32 timeBaseFrequency;
69 			if (of_getprop(cpu, "timebase-frequency", &timeBaseFrequency, 4)
70 					== OF_FAILED) {
71 				printf("boot_arch_cpu_init: Failed to get time base "
72 					"frequency!\n");
73 				return B_ERROR;
74 			}
75 
76 			gKernelArgs.arch_args.cpu_frequency = clockFrequency;
77 			gKernelArgs.arch_args.bus_frequency = busFrequency;
78 			gKernelArgs.arch_args.time_base_frequency = timeBaseFrequency;
79 
80 			TRACE(("  CPU clock frequency: %ld\n", clockFrequency));
81 			TRACE(("  bus clock frequency: %ld\n", busFrequency));
82 			TRACE(("  time base frequency: %ld\n", timeBaseFrequency));
83 		}
84 
85 		cpuCount++;
86 	}
87 
88 	if (cpuCount == 0) {
89 		printf("boot_arch_cpu_init(): Found no CPUs!\n");
90 		return B_ERROR;
91 	}
92 
93 	gKernelArgs.num_cpus = cpuCount;
94 
95 	// allocate the kernel stacks (the memory stuff is already initialized
96 	// at this point)
97 	addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000,
98 		cpuCount * (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE),
99 		B_READ_AREA | B_WRITE_AREA, false);
100 	if (!stack) {
101 		printf("boot_arch_cpu_init(): Failed to allocate kernel stack(s)!\n");
102 		return B_NO_MEMORY;
103 	}
104 
105 	for (int i = 0; i < cpuCount; i++) {
106 		gKernelArgs.cpu_kstack[i].start = stack;
107 		gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE
108 			+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
109 		stack += KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
110 	}
111 
112 	return B_OK;
113 }
114 
115