1 /* 2 * Copyright 2012, Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ithamar R. Adema <ithamar@upgrade-android.com> 7 */ 8 9 #include "cpu.h" 10 11 #include <OS.h> 12 #include <boot/platform.h> 13 #include <boot/stdio.h> 14 #include <boot/kernel_args.h> 15 #include <boot/stage2.h> 16 #include <arch/cpu.h> 17 #include <arch_kernel.h> 18 #include <arch_system_info.h> 19 #include <arch_cpu.h> 20 #include <string.h> 21 22 #define TRACE_CPU 23 #ifdef TRACE_CPU 24 # define TRACE(x) dprintf x 25 #else 26 # define TRACE(x) ; 27 #endif 28 29 /*! check_cpu_features 30 * 31 * Please note the fact that ARM7 and ARMv7 are two different things ;) 32 * ARMx is a specific ARM CPU core instance, while ARMvX refers to the 33 * ARM architecture specification version.... 34 * 35 * Most of the architecture versions we're detecting here we will probably 36 * never run on, just included for completeness sake... ARMv5 and up are 37 * the likely ones for us to support (as they all have some kind of MMU). 38 */ 39 40 static status_t 41 check_cpu_features() 42 { 43 uint32 result = 0; 44 int arch, variant = 0, part = 0, revision = 0, implementor = 0; 45 46 asm volatile("MRC p15, 0, %[c1out], c0, c0, 0":[c1out] "=r" (result)); 47 48 implementor = (result >> 24) & 0xff; 49 50 if (!(result & (1 << 19))) { 51 switch((result >> 12) & 0xf) { 52 case 0: /* early ARMv3 or even older */ 53 arch = ARCH_ARM_PRE_ARM7; 54 break; 55 56 case 7: /* ARM7 processor */ 57 arch = (result & (1 << 23)) ? ARCH_ARM_v4T : ARCH_ARM_v3; 58 variant = (result >> 16) & 0x7f; 59 part = (result >> 4) & 0xfff; 60 revision = result & 0xf; 61 break; 62 63 default: 64 revision = result & 0xf; 65 part = (result >> 4) & 0xfff; 66 switch((result >> 16) & 0xf) { 67 case 1: arch = ARCH_ARM_v4; break; 68 case 2: arch = ARCH_ARM_v4T; break; 69 case 3: arch = ARCH_ARM_v5; break; 70 case 4: arch = ARCH_ARM_v5T; break; 71 case 5: arch = ARCH_ARM_v5TE; break; 72 case 6: arch = ARCH_ARM_v5TEJ; break; 73 case 7: arch = ARCH_ARM_v6; break; 74 case 0xf: /* XXX TODO ARMv7 */; break; 75 } 76 variant = (result >> 20) & 0xf; 77 break; 78 } 79 } 80 81 TRACE(("%s: implementor=0x%x('%c'), arch=%d, variant=0x%x, part=0x%x, revision=0x%x\n", 82 __func__, implementor, implementor, arch, variant, part, revision)); 83 84 return B_OK; 85 } 86 87 // #pragma mark - 88 89 extern "C" void 90 arch_spin(bigtime_t microseconds) 91 { 92 panic("No timing support in bootloader yet!"); 93 } 94 95 96 extern "C" status_t 97 boot_arch_cpu_init(void) 98 { 99 status_t err = check_cpu_features(); 100 if (err != B_OK) { 101 panic("Retire your old Acorn and get something modern to boot!\n"); 102 return err; 103 } 104 105 gKernelArgs.num_cpus = 1; 106 // this will eventually be corrected later on 107 108 return B_OK; 109 } 110