Let the bootloader know about ARMv7.

When an ARMv7 CPU is detected, immediately turn on the FPU. This allows
us to use vsnprintf in the TRACE call in that function, as our libc is
compiled with floating point support and will trigger a fault if the FPU
is not available.

This lets the boot go further, and crash in mmu_init. Next steps:
* Find why mmu_init is crashing
* Setup some fault handlers, otherwise we call uboot ones, and they are
not very helpful. They will also probably not work once the mmu is
enabledvery helpful. They will also probably not work once the mmu is
enabledvery helpful. They will also probably not work once the mmu is
enabled...
This commit is contained in:
PulkoMandy
2014-06-13 22:15:54 +02:00
parent afe56d3ab3
commit 4a2260f21a
2 changed files with 53 additions and 30 deletions
+2 -1
View File
@@ -50,7 +50,8 @@ enum {
ARCH_ARM_v5T,
ARCH_ARM_v5TE,
ARCH_ARM_v5TEJ,
ARCH_ARM_v6
ARCH_ARM_v6,
ARCH_ARM_v7
};
typedef struct arch_cpu_info {
+51 -29
View File
@@ -39,7 +39,7 @@ static status_t
check_cpu_features()
{
uint32 result = 0;
int arch;
int arch = 0;
int variant = 0;
int part = 0;
int revision = 0;
@@ -49,41 +49,63 @@ check_cpu_features()
implementor = (result >> 24) & 0xff;
if (!(result & (1 << 19))) {
switch ((result >> 12) & 0xf) {
case 0: /* early ARMv3 or even older */
arch = ARCH_ARM_PRE_ARM7;
break;
switch ((result >> 12) & 0xf) {
case 0: /* early ARMv3 or even older */
arch = ARCH_ARM_PRE_ARM7;
break;
case 7: /* ARM7 processor */
arch = (result & (1 << 23)) ? ARCH_ARM_v4T : ARCH_ARM_v3;
variant = (result >> 16) & 0x7f;
part = (result >> 4) & 0xfff;
revision = result & 0xf;
break;
case 7: /* ARM7 processor */
arch = (result & (1 << 23)) ? ARCH_ARM_v4T : ARCH_ARM_v3;
variant = (result >> 16) & 0x7f;
part = (result >> 4) & 0xfff;
revision = result & 0xf;
break;
default:
revision = result & 0xf;
part = (result >> 4) & 0xfff;
switch((result >> 16) & 0xf) {
case 1: arch = ARCH_ARM_v4; break;
case 2: arch = ARCH_ARM_v4T; break;
case 3: arch = ARCH_ARM_v5; break;
case 4: arch = ARCH_ARM_v5T; break;
case 5: arch = ARCH_ARM_v5TE; break;
case 6: arch = ARCH_ARM_v5TEJ; break;
case 7: arch = ARCH_ARM_v6; break;
case 0xf: /* XXX TODO ARMv7 */; break;
}
variant = (result >> 20) & 0xf;
break;
}
default:
revision = result & 0xf;
part = (result >> 4) & 0xfff;
switch((result >> 16) & 0xf) {
case 1: arch = ARCH_ARM_v4; break;
case 2: arch = ARCH_ARM_v4T; break;
case 3: arch = ARCH_ARM_v5; break;
case 4: arch = ARCH_ARM_v5T; break;
case 5: arch = ARCH_ARM_v5TE; break;
case 6: arch = ARCH_ARM_v5TEJ; break;
case 7: arch = ARCH_ARM_v6; break;
case 0xf:
arch = ARCH_ARM_v7;
// TODO ... or later. We apparently need to scan the
// CPUID registers to decide.
break;
}
variant = (result >> 20) & 0xf;
break;
}
// TODO actually check for VFP support, and maybe there is a better place
// to do this.
if (arch >= ARCH_ARM_v7)
{
// Enable VFP/NEON. We HAVE to do this before the trace call below,
// which is the first time we call vprintf. Otherwise, it will crash
// when trying to push floating point registers on the stack.
asm volatile(
" MRC p15, #0, r1, c1, c0, #2\n" // r1 = Access Control Register
" ORR r1, r1, #(0xf << 20)\n" // enable full access for p10,11
" MCR p15, #0, r1, c1, c0, #2\n" // Access Control Register = r1
" MOV r1, #0\n"
" MCR p15, #0, r1, c7, c5, #4\n" // flush prefetch buffer because of
// FMXR below and CP 10 & 11 were only just enabled
" MOV r0,#0x40000000 \n" // Enable VFP itself
" FMXR FPEXC, r0" //FPEXC = r0
:::"r0", "r1");
}
TRACE(("%s: implementor=0x%x('%c'), arch=%d, variant=0x%x, part=0x%x, revision=0x%x\n",
__func__, implementor, implementor, arch, variant, part, revision));
return B_OK;
return (arch < ARCH_ARM_v5) ? B_ERROR : B_OK;
}