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 | | |
| 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 | |