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