1 /* 2 ** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 ** Distributed under the terms of the MIT License. 4 */ 5 #ifndef _KERNEL_ARCH_ARM_CPU_H 6 #define _KERNEL_ARCH_ARM_CPU_H 7 8 9 #define CPU_MAX_CACHE_LEVEL 8 10 #define CACHE_LINE_SIZE 64 11 // TODO: Could be 32-bits sometimes? 12 13 14 #define isb() __asm__ __volatile__("isb" : : : "memory") 15 #define dsb() __asm__ __volatile__("dsb" : : : "memory") 16 #define dmb() __asm__ __volatile__("dmb" : : : "memory") 17 #define wfi() __asm__ __volatile__("wfi" : : : "memory") 18 19 #define arch_cpu_enable_user_access() 20 #define arch_cpu_disable_user_access() 21 22 23 #ifndef _ASSEMBLER 24 25 #include <arch/arm/arch_thread_types.h> 26 #include <kernel.h> 27 28 /**! Values for arch_cpu_info.arch */ 29 enum { 30 ARCH_ARM_PRE_ARM7, 31 ARCH_ARM_v3, 32 ARCH_ARM_v4, 33 ARCH_ARM_v4T, 34 ARCH_ARM_v5, 35 ARCH_ARM_v5T, 36 ARCH_ARM_v5TE, 37 ARCH_ARM_v5TEJ, 38 ARCH_ARM_v6, 39 ARCH_ARM_v7 40 }; 41 42 typedef struct arch_cpu_info { 43 /* For a detailed interpretation of these values, 44 see "The System Control coprocessor", 45 "Main ID register" in your ARM ARM */ 46 int implementor; 47 int part_number; 48 int revision; 49 int variant; 50 int arch; 51 } arch_cpu_info; 52 53 #ifdef __cplusplus 54 extern "C" { 55 #endif 56 57 58 #define DEFINE_ARM_GET_REG(name, cp, opc1, crn, crm, opc2) \ 59 static inline uint32 \ 60 arm_get_##name(void) \ 61 { \ 62 uint32 res; \ 63 asm volatile ("mrc " #cp ", " #opc1 ", %0, " #crn ", " #crm ", " #opc2 : "=r" (res)); \ 64 return res; \ 65 } 66 67 68 #define DEFINE_ARM_SET_REG(name, cp, opc1, crn, crm, opc2) \ 69 static inline void \ 70 arm_set_##name(uint32 val) \ 71 { \ 72 asm volatile ("mcr " #cp ", " #opc1 ", %0, " #crn ", " #crm ", " #opc2 :: "r" (val)); \ 73 } 74 75 76 /* CP15 c1, System Control Register */ 77 DEFINE_ARM_GET_REG(sctlr, p15, 0, c1, c0, 0) 78 DEFINE_ARM_SET_REG(sctlr, p15, 0, c1, c0, 0) 79 80 /* CP15 c2, Translation table support registers */ 81 DEFINE_ARM_GET_REG(ttbr0, p15, 0, c2, c0, 0) 82 DEFINE_ARM_SET_REG(ttbr0, p15, 0, c2, c0, 0) 83 DEFINE_ARM_GET_REG(ttbr1, p15, 0, c2, c0, 1) 84 DEFINE_ARM_SET_REG(ttbr1, p15, 0, c2, c0, 1) 85 DEFINE_ARM_GET_REG(ttbcr, p15, 0, c2, c0, 2) 86 DEFINE_ARM_SET_REG(ttbcr, p15, 0, c2, c0, 2) 87 88 /* CP15 c5 and c6, Memory system fault registers */ 89 DEFINE_ARM_GET_REG(dfsr, p15, 0, c5, c0, 0) 90 DEFINE_ARM_GET_REG(ifsr, p15, 0, c5, c0, 1) 91 DEFINE_ARM_GET_REG(dfar, p15, 0, c6, c0, 0) 92 DEFINE_ARM_GET_REG(ifar, p15, 0, c6, c0, 2) 93 94 /* CP15 c13, Process, context and thread ID registers */ 95 DEFINE_ARM_GET_REG(tpidruro, p15, 0, c13, c0, 3) 96 DEFINE_ARM_SET_REG(tpidruro, p15, 0, c13, c0, 3) 97 DEFINE_ARM_GET_REG(tpidrprw, p15, 0, c13, c0, 4) 98 DEFINE_ARM_SET_REG(tpidrprw, p15, 0, c13, c0, 4) 99 100 101 #undef DEFINE_ARM_GET_REG 102 #undef DEFINE_ARM_SET_REG 103 104 105 static inline addr_t 106 arm_get_fp(void) 107 { 108 uint32 res; 109 asm volatile ("mov %0, fp": "=r" (res)); 110 return res; 111 } 112 113 114 void arch_cpu_invalidate_TLB_page(addr_t page); 115 116 static inline void 117 arch_cpu_pause(void) 118 { 119 // TODO: ARM Priority pause call 120 } 121 122 123 static inline void 124 arch_cpu_idle(void) 125 { 126 wfi(); 127 } 128 129 130 #ifdef __cplusplus 131 }; 132 #endif 133 134 #endif // !_ASSEMBLER 135 136 #endif /* _KERNEL_ARCH_ARM_CPU_H */ 137