U-Boot: PPC: Spice up CPU detection, trying both PVR and FDT
* Read the PVR register to determine the CPU type. * Also check the FDT /cpu/cpu@0 node for model string (we use the FDT calls directly since the OF wrapper isn't initialized yet). * Use this to enable the FPU APU hack for 440 (instead of #ifdef).
This commit is contained in:
@@ -6,6 +6,8 @@ UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ]
|
|||||||
[ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ;
|
[ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) board $(TARGET_BOOT_BOARD) ] ;
|
UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) board $(TARGET_BOOT_BOARD) ] ;
|
||||||
|
|
||||||
|
UseLibraryHeaders [ FDirName libfdt ] ;
|
||||||
|
|
||||||
SubDirC++Flags -fno-rtti ;
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
BootMergeObject boot_platform_u-boot_ppc.o :
|
BootMergeObject boot_platform_u-boot_ppc.o :
|
||||||
|
|||||||
@@ -22,8 +22,16 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <fdt.h>
|
||||||
|
#include <libfdt.h>
|
||||||
|
#include <libfdt_env.h>
|
||||||
|
};
|
||||||
|
|
||||||
//#define TRACE_CPU
|
|
||||||
|
extern void *gFDT;
|
||||||
|
|
||||||
|
#define TRACE_CPU
|
||||||
#ifdef TRACE_CPU
|
#ifdef TRACE_CPU
|
||||||
# define TRACE(x) dprintf x
|
# define TRACE(x) dprintf x
|
||||||
#else
|
#else
|
||||||
@@ -44,17 +52,67 @@ static status_t
|
|||||||
check_cpu_features()
|
check_cpu_features()
|
||||||
{
|
{
|
||||||
uint32 msr;
|
uint32 msr;
|
||||||
|
uint32 pvr;
|
||||||
|
bool is_440 = false;
|
||||||
|
bool is_460 = false;
|
||||||
|
bool pvr_unknown = false;
|
||||||
|
bool fdt_unknown = true;
|
||||||
|
const char *fdt_model = NULL;
|
||||||
|
|
||||||
#if BOARD_CPU_TYPE_PPC440
|
// attempt to detect processor version, either from PVR or FDT
|
||||||
// the FPU is implemented as an Auxiliary Processing Unit,
|
// TODO:someday we'll support other things than 440/460...
|
||||||
// so we must enable transfers by setting the DAPUIB bit to 0
|
|
||||||
asm volatile(
|
// read the Processor Version Register
|
||||||
"mfccr0 %%r3\n"
|
pvr = get_pvr();
|
||||||
"\tlis %%r4,~(1<<(20-16))\n"
|
uint16 version = (uint16)(pvr >> 16);
|
||||||
"\tand %%r3,%%r3,%%r4\n"
|
uint16 revision = (uint16)(pvr & 0xffff);
|
||||||
"\tmtccr0 %%r3"
|
|
||||||
: : : "r3", "r4");
|
switch (version) {
|
||||||
#endif
|
case AMCC440EP:
|
||||||
|
is_440 = true;
|
||||||
|
break;
|
||||||
|
case AMCC460EX:
|
||||||
|
is_460 = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pvr_unknown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have an FDT...
|
||||||
|
// XXX: use it only as fallback?
|
||||||
|
if (gFDT != NULL/* && pvr_unknown*/) {
|
||||||
|
// TODO: for MP support we must checn /chosen/cpu first
|
||||||
|
int node = fdt_path_offset(gFDT, "/cpus/cpu@0");
|
||||||
|
int len;
|
||||||
|
|
||||||
|
fdt_model = (const char *)fdt_getprop(gFDT, node, "model", &len);
|
||||||
|
// TODO: partial match ? "PowerPC,440" && isalpha(next char) ?
|
||||||
|
if (fdt_model) {
|
||||||
|
if (!strcmp(fdt_model, "PowerPC,440EP")) {
|
||||||
|
is_440 = true;
|
||||||
|
fdt_unknown = false;
|
||||||
|
} else if (!strcmp(fdt_model, "PowerPC,460EX")) {
|
||||||
|
is_460 = true;
|
||||||
|
fdt_unknown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_460)
|
||||||
|
is_440 = true;
|
||||||
|
|
||||||
|
// some cpu-dependent tweaking
|
||||||
|
|
||||||
|
if (is_440) {
|
||||||
|
// the FPU is implemented as an Auxiliary Processing Unit,
|
||||||
|
// so we must enable transfers by setting the DAPUIB bit to 0
|
||||||
|
asm volatile(
|
||||||
|
"mfccr0 %%r3\n"
|
||||||
|
"\tlis %%r4,~(1<<(20-16))\n"
|
||||||
|
"\tand %%r3,%%r3,%%r4\n"
|
||||||
|
"\tmtccr0 %%r3"
|
||||||
|
: : : "r3", "r4");
|
||||||
|
}
|
||||||
|
|
||||||
// we do need an FPU for vsnprintf to work
|
// we do need an FPU for vsnprintf to work
|
||||||
// on Sam460ex at least U-Boot doesn't enable the FPU for us
|
// on Sam460ex at least U-Boot doesn't enable the FPU for us
|
||||||
@@ -68,6 +126,11 @@ check_cpu_features()
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE(("CPU detection:\n"));
|
||||||
|
TRACE(("PVR revision %sknown: 0x%8lx\n", pvr_unknown ? "un" : "", pvr));
|
||||||
|
TRACE(("FDT model %sknown: %s\n", fdt_unknown ? "un" : "", fdt_model));
|
||||||
|
TRACE(("flags: %s440 %s460\n", is_440 ? "" : "!", is_460 ? "" : "!"));
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +166,7 @@ boot_arch_cpu_init(void)
|
|||||||
|
|
||||||
gKernelArgs.num_cpus = 1;
|
gKernelArgs.num_cpus = 1;
|
||||||
// this will eventually be corrected later on
|
// this will eventually be corrected later on
|
||||||
|
// TODO:iterate on /cpus/*
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user