xref: /haiku/headers/private/kernel/arch/arm/arch_cpu.h (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
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 
18 #define set_ac()
19 #define clear_ac()
20 
21 
22 #ifndef _ASSEMBLER
23 
24 #include <arch/arm/arch_thread_types.h>
25 #include <kernel.h>
26 
27 /**! Values for arch_cpu_info.arch */
28 enum {
29 	ARCH_ARM_PRE_ARM7,
30 	ARCH_ARM_v3,
31 	ARCH_ARM_v4,
32 	ARCH_ARM_v4T,
33 	ARCH_ARM_v5,
34 	ARCH_ARM_v5T,
35 	ARCH_ARM_v5TE,
36 	ARCH_ARM_v5TEJ,
37 	ARCH_ARM_v6,
38 	ARCH_ARM_v7
39 };
40 
41 typedef struct arch_cpu_info {
42 	/* For a detailed interpretation of these values,
43 	   see "The System Control coprocessor",
44 	   "Main ID register" in your ARM ARM */
45 	int implementor;
46 	int part_number;
47 	int revision;
48 	int variant;
49 	int arch;
50 } arch_cpu_info;
51 
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55 
56 
57 #define DEFINE_ARM_GET_REG(name, cp, opc1, crn, crm, opc2) \
58 	static inline uint32 \
59 	arm_get_##name(void) \
60 	{ \
61 		uint32 res; \
62 		asm volatile ("mrc " #cp ", " #opc1 ", %0, " #crn ", " #crm ", " #opc2 : "=r" (res)); \
63 		return res; \
64 	}
65 
66 
67 #define DEFINE_ARM_SET_REG(name, cp, opc1, crn, crm, opc2) \
68 	static inline void \
69 	arm_set_##name(uint32 val) \
70 	{ \
71 		asm volatile ("mcr " #cp ", " #opc1 ", %0, " #crn ", " #crm ", " #opc2 :: "r" (val)); \
72 	}
73 
74 
75 /* CP15 c1, System Control Register */
76 DEFINE_ARM_GET_REG(sctlr, p15, 0, c1, c0, 0)
77 DEFINE_ARM_SET_REG(sctlr, p15, 0, c1, c0, 0)
78 
79 /* CP15 c2, Translation table support registers */
80 DEFINE_ARM_GET_REG(ttbr0, p15, 0, c2, c0, 0)
81 DEFINE_ARM_SET_REG(ttbr0, p15, 0, c2, c0, 0)
82 DEFINE_ARM_GET_REG(ttbr1, p15, 0, c2, c0, 1)
83 DEFINE_ARM_SET_REG(ttbr1, p15, 0, c2, c0, 1)
84 DEFINE_ARM_GET_REG(ttbcr, p15, 0, c2, c0, 2)
85 DEFINE_ARM_SET_REG(ttbcr, p15, 0, c2, c0, 2)
86 
87 /* CP15 c5 and c6, Memory system fault registers */
88 DEFINE_ARM_GET_REG(dfsr, p15, 0, c5, c0, 0)
89 DEFINE_ARM_GET_REG(ifsr, p15, 0, c5, c0, 1)
90 DEFINE_ARM_GET_REG(dfar, p15, 0, c6, c0, 0)
91 DEFINE_ARM_GET_REG(ifar, p15, 0, c6, c0, 2)
92 
93 /* CP15 c13, Process, context and thread ID registers */
94 DEFINE_ARM_GET_REG(tpidruro, p15, 0, c13, c0, 3)
95 DEFINE_ARM_SET_REG(tpidruro, p15, 0, c13, c0, 3)
96 DEFINE_ARM_GET_REG(tpidrprw, p15, 0, c13, c0, 4)
97 DEFINE_ARM_SET_REG(tpidrprw, p15, 0, c13, c0, 4)
98 
99 
100 #undef DEFINE_ARM_GET_REG
101 #undef DEFINE_ARM_SET_REG
102 
103 
104 static inline addr_t
105 arm_get_fp(void)
106 {
107 	uint32 res;
108 	asm volatile ("mov %0, fp": "=r" (res));
109 	return res;
110 }
111 
112 
113 void arch_cpu_invalidate_TLB_page(addr_t page);
114 
115 static inline void
116 arch_cpu_pause(void)
117 {
118 	// TODO: ARM Priority pause call
119 }
120 
121 
122 static inline void
123 arch_cpu_idle(void)
124 {
125 	uint32 Rd = 0;
126 	asm volatile("mcr p15, 0, %[c7format], c7, c0, 4"
127 		: : [c7format] "r" (Rd) );
128 }
129 
130 
131 #ifdef __cplusplus
132 };
133 #endif
134 
135 #endif	// !_ASSEMBLER
136 
137 #endif	/* _KERNEL_ARCH_ARM_CPU_H */
138