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