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/*! Detect ARM core version and features. 30 Please note the fact that ARM7 and ARMv7 are two different things ;) 31 ARMx is a specific ARM CPU core instance, while ARMvX refers to the 32 ARM architecture specification version.... 33 34 Most of the architecture versions we're detecting here we will probably 35 never run on, just included for completeness sake... ARMv5 and up are 36 the likely ones for us to support (as they all have some kind of MMU). 37*/ 38static status_t 39check_cpu_features() 40{ 41 uint32 result = 0; 42 int arch; 43 int variant = 0; 44 int part = 0; 45 int revision = 0; 46 int implementor = 0; 47 48 asm volatile("MRC p15, 0, %[c1out], c0, c0, 0":[c1out] "=r" (result)); 49 50 implementor = (result >> 24) & 0xff; 51 52 if (!(result & (1 << 19))) { 53 switch ((result >> 12) & 0xf) { 54 case 0: /* early ARMv3 or even older */ 55 arch = ARCH_ARM_PRE_ARM7; 56 break; 57 58 case 7: /* ARM7 processor */ 59 arch = (result & (1 << 23)) ? ARCH_ARM_v4T : ARCH_ARM_v3; 60 variant = (result >> 16) & 0x7f; 61 part = (result >> 4) & 0xfff; 62 revision = result & 0xf; 63 break; 64 65 default: 66 revision = result & 0xf; 67 part = (result >> 4) & 0xfff; 68 switch((result >> 16) & 0xf) { 69 case 1: arch = ARCH_ARM_v4; break; 70 case 2: arch = ARCH_ARM_v4T; break; 71 case 3: arch = ARCH_ARM_v5; break; 72 case 4: arch = ARCH_ARM_v5T; break; 73 case 5: arch = ARCH_ARM_v5TE; break; 74 case 6: arch = ARCH_ARM_v5TEJ; break; 75 case 7: arch = ARCH_ARM_v6; break; 76 case 0xf: /* XXX TODO ARMv7 */; break; 77 } 78 variant = (result >> 20) & 0xf; 79 break; 80 } 81 } 82 83 TRACE(("%s: implementor=0x%x('%c'), arch=%d, variant=0x%x, part=0x%x, revision=0x%x\n", 84 __func__, implementor, implementor, arch, variant, part, revision)); 85 86 return B_OK; 87} 88 89 90void 91arch_cpu_memory_read_barrier(void) 92{ 93 asm volatile ("" : : : "memory"); 94} 95 96 97void 98arch_cpu_memory_write_barrier(void) 99{ 100 asm volatile ("" : : : "memory"); 101} 102 103 104extern "C" void 105arch_spin(bigtime_t microseconds) 106{ 107 panic("No timing support in bootloader yet!"); 108} 109 110 111extern "C" status_t 112boot_arch_cpu_init(void) 113{ 114 status_t err = check_cpu_features(); 115 if (err != B_OK) { 116 panic("Retire your old Acorn and get something modern to boot!\n"); 117 return err; 118 } 119 120 gKernelArgs.num_cpus = 1; 121 // this will eventually be corrected later on 122 123 return B_OK; 124} 125