]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/drivers/arm/processor-arm.cpp
update
[l4.git] / kernel / fiasco / src / drivers / arm / processor-arm.cpp
1 INTERFACE[arm]:
2
3 EXTENSION class Proc
4 {
5 private:
6   enum : unsigned
7   {
8     Status_FIQ_disabled        = 0x40,
9     Status_IRQ_disabled        = 0x80,
10   };
11
12 public:
13   enum : unsigned
14   {
15     Status_mode_user           = 0x10,
16     Status_mode_supervisor     = 0x13,
17     Status_mode_mask           = 0x1f,
18
19     Status_interrupts_disabled = Status_FIQ_disabled | Status_IRQ_disabled,
20     Status_thumb               = 0x20,
21   };
22
23   static Cpu_phys_id cpu_id();
24 };
25
26 INTERFACE[arm && !arm_em_tz]:
27
28 EXTENSION class Proc
29 {
30 public:
31   enum : unsigned
32     {
33       Cli_mask                = Status_interrupts_disabled,
34       Sti_mask                = Status_interrupts_disabled,
35       Status_preempt_disabled = Status_IRQ_disabled,
36       Status_interrupts_mask  = Status_interrupts_disabled,
37       Status_always_mask      = 0,
38     };
39 };
40
41 INTERFACE[arm && arm_em_tz]:
42
43 EXTENSION class Proc
44 {
45 public:
46   enum : unsigned
47     {
48       Cli_mask                = Status_FIQ_disabled,
49       Sti_mask                = Status_FIQ_disabled,
50       Status_preempt_disabled = Status_FIQ_disabled,
51       Status_interrupts_mask  = Status_FIQ_disabled,
52       Status_always_mask      = Status_IRQ_disabled,
53     };
54 };
55
56 IMPLEMENTATION[arm]:
57
58 #include "types.h"
59 #include "std_macros.h"
60
61 IMPLEMENT static inline
62 Mword Proc::stack_pointer()
63 {
64   Mword sp;
65   asm volatile ( "mov %0, sp \n" : "=r"(sp) );
66   return sp;
67 }
68
69 IMPLEMENT static inline
70 void Proc::stack_pointer(Mword sp)
71 {
72   asm volatile ( "mov sp, %0 \n" : : "r"(sp) );
73 }
74
75 IMPLEMENT static inline
76 Mword Proc::program_counter()
77 {
78   register Mword pc asm ("pc");
79   return pc;
80 }
81
82 IMPLEMENT static inline
83 void Proc::cli()
84 {
85   Mword v;
86   asm volatile("mrs %0, cpsr    \n"
87                "orr %0, %0, %1  \n"
88                "msr cpsr_c, %0  \n"
89                : "=r" (v)
90                : "I" (Cli_mask)
91                : "memory");
92 }
93
94 IMPLEMENT static inline
95 void Proc::sti()
96 {
97   Mword v;
98   asm volatile("mrs %0, cpsr    \n"
99                "bic %0, %0, %1  \n"
100                "msr cpsr_c, %0  \n"
101                : "=r" (v)
102                : "I" (Sti_mask)
103                : "memory");
104 }
105
106 IMPLEMENT static inline
107 Proc::Status Proc::cli_save()
108 {
109   Status ret;
110   Mword v;
111   asm volatile("mrs    %0, cpsr    \n"
112                "orr    %1, %0, %2  \n"
113                "msr    cpsr_c, %1  \n"
114                : "=r" (ret), "=r" (v)
115                : "I" (Cli_mask)
116                : "memory");
117   return ret;
118 }
119
120 IMPLEMENT static inline
121 Proc::Status Proc::interrupts()
122 {
123   Status ret;
124   asm volatile("mrs %0, cpsr" : "=r" (ret));
125   return !(ret & Sti_mask);
126 }
127
128 IMPLEMENT static inline
129 void Proc::sti_restore(Status st)
130 {
131   if (!(st & Sti_mask))
132     sti();
133 }
134
135 IMPLEMENT static inline
136 void Proc::irq_chance()
137 {
138   asm volatile ("nop; nop;" : : : "memory");
139 }
140
141
142 //----------------------------------------------------------------
143 IMPLEMENTATION[arm && !mp]:
144
145 IMPLEMENT static inline
146 Cpu_phys_id Proc::cpu_id()
147 { return Cpu_phys_id(0); }
148
149 //----------------------------------------------------------------
150 IMPLEMENTATION[arm && mp]:
151
152 IMPLEMENT static inline
153 Cpu_phys_id Proc::cpu_id()
154 {
155   unsigned mpidr;
156   __asm__("mrc p15, 0, %0, c0, c0, 5": "=r" (mpidr));
157   return Cpu_phys_id(mpidr & 0x7); // mind gic softirq
158 }
159
160 //----------------------------------------------------------------
161 IMPLEMENTATION[arm && (pxa || sa1100 || s3c2410)]:
162
163 IMPLEMENT static inline
164 void Proc::halt()
165 {}
166
167 IMPLEMENT static inline
168 void Proc::pause()
169 {}
170
171 //----------------------------------------------------------------
172 IMPLEMENTATION[arm && 926]:
173
174 IMPLEMENT static inline
175 void Proc::pause()
176 {
177 }
178
179 IMPLEMENT static inline
180 void Proc::halt()
181 {
182   Status f = cli_save();
183   asm volatile("mov     r0, #0                                              \n\t"
184                "mrc     p15, 0, r1, c1, c0, 0       @ Read control register \n\t"
185                "mcr     p15, 0, r0, c7, c10, 4      @ Drain write buffer    \n\t"
186                "bic     r2, r1, #1 << 12                                    \n\t"
187                "mcr     p15, 0, r2, c1, c0, 0       @ Disable I cache       \n\t"
188                "mcr     p15, 0, r0, c7, c0, 4       @ Wait for interrupt    \n\t"
189                "mcr     15, 0, r1, c1, c0, 0        @ Restore ICache enable \n\t"
190                :::"memory",
191                "r0", "r1", "r2", "r3", "r4", "r5",
192                "r6", "r7", "r8", "r9", "r10", "r11",
193                "r12", "r13", "r14", "r15"
194       );
195   sti_restore(f);
196 }
197
198 //----------------------------------------------------------------
199 IMPLEMENTATION[arm && arm1136]:
200
201 IMPLEMENT static inline
202 void Proc::pause()
203 {}
204
205 IMPLEMENT static inline
206 void Proc::halt()
207 {
208   Status f = cli_save();
209   asm volatile("mcr     p15, 0, r0, c7, c10, 4  @ DWB/DSB \n\t"
210                "mcr     p15, 0, r0, c7, c0, 4   @ WFI \n\t");
211   sti_restore(f);
212 }
213
214
215 //----------------------------------------------------------------
216 IMPLEMENTATION[arm && (arm1176 || mpcore)]:
217
218 IMPLEMENT static inline
219 void Proc::pause()
220 {}
221
222 IMPLEMENT static inline
223 void Proc::halt()
224 {
225   Status f = cli_save();
226   asm volatile("mcr     p15, 0, r0, c7, c10, 4  @ DWB/DSB \n\t"
227                "wfi \n\t");
228   sti_restore(f);
229 }
230
231 //----------------------------------------------------------------
232 IMPLEMENTATION[arm && (armca8 || armca9)]:
233
234 IMPLEMENT static inline
235 void Proc::pause()
236 {}
237
238 IMPLEMENT static inline
239 void Proc::halt()
240 {
241   Status f = cli_save();
242   asm volatile("dsb \n\t"
243                "wfi \n\t");
244   sti_restore(f);
245 }