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