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
arm_get_fp(void)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
arch_cpu_pause(void)117 arch_cpu_pause(void)
118 {
119 // TODO: ARM Priority pause call
120 }
121
122
123 static inline void
arch_cpu_idle(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