Permalink
Browse files

ARM: Add ARM architecture detection to generic bootloader ARM code.

This detects everything up to ARMv6 right now. Need to check more
recent ARM ARMs for ARMv7 detection.

The detected details get passed on to the kernel, which can use
the pre-detected info for selecting right pagetable format and such.

Copyright removal of Axel done after agreement with Axel @ BeGeistert
that for files that were copy/pasted from x86 arch and then fully
replaced the implementation, removal of original copyright holder is
allowed, since their actual code is gone ;)
  • Loading branch information...
1 parent 959e760 commit 1df5784a22ff1783bb42fbcb63cb86b9965237a1 @Ithamar Ithamar committed Nov 13, 2012
Showing with 77 additions and 37 deletions.
  1. +21 −6 headers/private/kernel/arch/arm/arch_cpu.h
  2. +56 −31 src/system/boot/arch/arm/arch_cpu.cpp
View
27 headers/private/kernel/arch/arm/arch_cpu.h
@@ -33,15 +33,30 @@ struct iframe {
uint32 pc;
} _PACKED;
+/**! 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
+};
+
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;
-extern int arch_cpu_type;
-extern int arch_fpu_type;
-extern int arch_mmu_type;
-extern int arch_platform;
-extern int arch_machine;
-
#ifdef __cplusplus
extern "C" {
#endif
View
87 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 <ithamar@upgrade-android.com>
*/
-
#include "cpu.h"
#include <OS.h>
@@ -17,68 +16,94 @@
#include <arch/cpu.h>
#include <arch_kernel.h>
#include <arch_system_info.h>
-
+#include <arch_cpu.h>
#include <string.h>
-
-//#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<microseconds;i=i+1)
- {
- /*
- asm volatile ("mov r0,r0");
- asm volatile ("mov r0,r0");
- */
- }
- #warning U-Boot:ARM:TODO!!
+ panic("No timing support in bootloader yet!");
}
extern "C" status_t
boot_arch_cpu_init(void)
{
status_t err = check_cpu_features();
-
if (err != B_OK) {
panic("Retire your old Acorn and get something modern to boot!\n");
return err;
}
- calculate_cpu_conversion_factor();
-
gKernelArgs.num_cpus = 1;
// this will eventually be corrected later on
return B_OK;
}
-

0 comments on commit 1df5784

Please sign in to comment.