diff --git a/headers/private/kernel/arch/arm/arch_cpu.h b/headers/private/kernel/arch/arm/arch_cpu.h index 34364a8004..a70398aa64 100644 --- a/headers/private/kernel/arch/arm/arch_cpu.h +++ b/headers/private/kernel/arch/arm/arch_cpu.h @@ -33,14 +33,29 @@ struct iframe { uint32 pc; } _PACKED; -typedef struct arch_cpu_info { -} arch_cpu_info; +/**! Values for arch_cpu_info.arch */ +enum { + ARCH_ARM_PRE_ARM7, + ARCH_ARM_v3, + ARCH_ARM_v4, + ARCH_ARM_v4T, + ARCH_ARM_v5, + ARCH_ARM_v5T, + ARCH_ARM_v5TE, + ARCH_ARM_v5TEJ, + ARCH_ARM_v6 +}; -extern int arch_cpu_type; -extern int arch_fpu_type; -extern int arch_mmu_type; -extern int arch_platform; -extern int arch_machine; +typedef struct arch_cpu_info { + /* For a detailed interpretation of these values, + see "The System Control coprocessor", + "Main ID register" in your ARM ARM */ + int implementor; + int part_number; + int revision; + int variant; + int arch; +} arch_cpu_info; #ifdef __cplusplus extern "C" { diff --git a/src/system/boot/arch/arm/arch_cpu.cpp b/src/system/boot/arch/arm/arch_cpu.cpp index 028146b9b5..2decd55ab3 100644 --- a/src/system/boot/arch/arm/arch_cpu.cpp +++ b/src/system/boot/arch/arm/arch_cpu.cpp @@ -1,12 +1,11 @@ /* - * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2012, Haiku, Inc. * Distributed under the terms of the MIT License. * - * calculate_cpu_conversion_factor() was written by Travis Geiselbrecht and - * licensed under the NewOS license. + * Authors: + * Ithamar R. Adema */ - #include "cpu.h" #include @@ -17,50 +16,80 @@ #include #include #include - +#include #include - -//#define TRACE_CPU +#define TRACE_CPU #ifdef TRACE_CPU # define TRACE(x) dprintf x #else # define TRACE(x) ; #endif -//uint32 gTimeConversionFactor; - - -static void -calculate_cpu_conversion_factor() -{ - #warning U-Boot:TODO! -} - +/*! check_cpu_features + * + * Please note the fact that ARM7 and ARMv7 are two different things ;) + * ARMx is a specific ARM CPU core instance, while ARMvX refers to the + * ARM architecture specification version.... + * + * Most of the architecture versions we're detecting here we will probably + * never run on, just included for completeness sake... ARMv5 and up are + * the likely ones for us to support (as they all have some kind of MMU). + */ static status_t check_cpu_features() { + uint32 result = 0; + int arch, variant = 0, part = 0, revision = 0, implementor = 0; + + asm volatile("MRC p15, 0, %[c1out], c0, c0, 0":[c1out] "=r" (result)); + + 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; + + 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; + } + } + + 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)); - #warning U-Boot:TODO! return B_OK; } - // #pragma mark - - extern "C" void arch_spin(bigtime_t microseconds) { - for(bigtime_t i=0;i