U-Boot: PPC: properly enumerate CPUs
* Code comes almost verbatim from OF platform. * Only bus frequency needs to be read from the /plb node instead.
This commit is contained in:
@@ -19,9 +19,12 @@
|
|||||||
#include <arch/ppc/arch_cpu.h>
|
#include <arch/ppc/arch_cpu.h>
|
||||||
#include <arch_kernel.h>
|
#include <arch_kernel.h>
|
||||||
#include <arch_system_info.h>
|
#include <arch_system_info.h>
|
||||||
|
#include <platform/openfirmware/devices.h>
|
||||||
|
#include <platform/openfirmware/openfirmware.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
// TODO: try to move remaining FDT code to OF calls
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <fdt.h>
|
#include <fdt.h>
|
||||||
#include <libfdt.h>
|
#include <libfdt.h>
|
||||||
@@ -38,13 +41,112 @@ extern void *gFDT;
|
|||||||
# define TRACE(x) ;
|
# define TRACE(x) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//uint32 gTimeConversionFactor;
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
static void
|
enumerate_cpus(void)
|
||||||
calculate_cpu_conversion_factor()
|
|
||||||
{
|
{
|
||||||
#warning U-Boot:TODO!
|
// iterate through the "/cpus" node to find all CPUs
|
||||||
|
int cpus = of_finddevice("/cpus");
|
||||||
|
if (cpus == OF_FAILED) {
|
||||||
|
printf("enumerate_cpus(): Failed to open \"/cpus\"!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
char cpuPath[256];
|
||||||
|
int cookie = 0;
|
||||||
|
int cpuCount = 0;
|
||||||
|
while (of_get_next_device(&cookie, cpus, "cpu", cpuPath,
|
||||||
|
sizeof(cpuPath)) == B_OK) {
|
||||||
|
TRACE(("found CPU: %s\n", cpuPath));
|
||||||
|
|
||||||
|
// For the first CPU get the frequencies of CPU, bus, and time base.
|
||||||
|
// We assume they are the same for all CPUs.
|
||||||
|
if (cpuCount == 0) {
|
||||||
|
int cpu = of_finddevice(cpuPath);
|
||||||
|
if (cpu == OF_FAILED) {
|
||||||
|
printf("enumerate_cpus: Failed get CPU device node!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Does encode-int really encode quadlet (32 bit numbers)
|
||||||
|
// only?
|
||||||
|
int32 clockFrequency;
|
||||||
|
if (of_getprop(cpu, "clock-frequency", &clockFrequency, 4)
|
||||||
|
== OF_FAILED) {
|
||||||
|
printf("enumerate_cpus: Failed to get CPU clock "
|
||||||
|
"frequency!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
int32 busFrequency = 0;
|
||||||
|
if (of_getprop(cpu, "bus-frequency", &busFrequency, 4)
|
||||||
|
== OF_FAILED) {
|
||||||
|
//printf("enumerate_cpus: Failed to get bus clock "
|
||||||
|
// "frequency!\n");
|
||||||
|
//return B_ERROR;
|
||||||
|
}
|
||||||
|
int32 timeBaseFrequency;
|
||||||
|
if (of_getprop(cpu, "timebase-frequency", &timeBaseFrequency, 4)
|
||||||
|
== OF_FAILED) {
|
||||||
|
printf("enumerate_cpus: Failed to get time base "
|
||||||
|
"frequency!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
gKernelArgs.arch_args.cpu_frequency = clockFrequency;
|
||||||
|
gKernelArgs.arch_args.bus_frequency = busFrequency;
|
||||||
|
gKernelArgs.arch_args.time_base_frequency = timeBaseFrequency;
|
||||||
|
|
||||||
|
TRACE((" CPU clock frequency: %ld\n", clockFrequency));
|
||||||
|
//TRACE((" bus clock frequency: %ld\n", busFrequency));
|
||||||
|
TRACE((" time base frequency: %ld\n", timeBaseFrequency));
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpuCount == 0) {
|
||||||
|
printf("enumerate_cpus(): Found no CPUs!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
gKernelArgs.num_cpus = cpuCount;
|
||||||
|
|
||||||
|
// FDT doesn't list bus frequency on the cpu node but on the plb node
|
||||||
|
if (gKernelArgs.arch_args.bus_frequency == 0) {
|
||||||
|
int plb = of_finddevice("/plb");
|
||||||
|
|
||||||
|
int32 busFrequency = 0;
|
||||||
|
if (of_getprop(plb, "clock-frequency", &busFrequency, 4)
|
||||||
|
== OF_FAILED) {
|
||||||
|
printf("enumerate_cpus: Failed to get bus clock "
|
||||||
|
"frequency!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
gKernelArgs.arch_args.bus_frequency = busFrequency;
|
||||||
|
}
|
||||||
|
TRACE((" bus clock frequency: %ld\n", gKernelArgs.arch_args.bus_frequency));
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
//XXX:Classic
|
||||||
|
// allocate the kernel stacks (the memory stuff is already initialized
|
||||||
|
// at this point)
|
||||||
|
addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000,
|
||||||
|
cpuCount * (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE),
|
||||||
|
B_READ_AREA | B_WRITE_AREA, false);
|
||||||
|
if (!stack) {
|
||||||
|
printf("enumerate_cpus(): Failed to allocate kernel stack(s)!\n");
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < cpuCount; i++) {
|
||||||
|
gKernelArgs.cpu_kstack[i].start = stack;
|
||||||
|
gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE
|
||||||
|
+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
|
stack += KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -155,6 +257,8 @@ arch_spin(bigtime_t microseconds)
|
|||||||
extern "C" status_t
|
extern "C" status_t
|
||||||
boot_arch_cpu_init(void)
|
boot_arch_cpu_init(void)
|
||||||
{
|
{
|
||||||
|
// first check some features
|
||||||
|
// including some necessary for dprintf()...
|
||||||
status_t err = check_cpu_features();
|
status_t err = check_cpu_features();
|
||||||
|
|
||||||
if (err != B_OK) {
|
if (err != B_OK) {
|
||||||
@@ -162,11 +266,8 @@ boot_arch_cpu_init(void)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
calculate_cpu_conversion_factor();
|
// now enumerate correctly all CPUs and get system frequencies
|
||||||
|
enumerate_cpus();
|
||||||
gKernelArgs.num_cpus = 1;
|
|
||||||
// this will eventually be corrected later on
|
|
||||||
// TODO:iterate on /cpus/*
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user