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