]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ppc32/cpu-ppc32.cpp
update
[l4.git] / kernel / fiasco / src / kern / ppc32 / cpu-ppc32.cpp
1 INTERFACE [ppc32]:
2
3 #include "per_cpu_data.h"
4 #include "types.h"
5
6 EXTENSION class Cpu
7 {
8 public:
9   void init(bool is_boot_cpu = false);
10   static void early_init();
11
12   static Per_cpu<Cpu> cpus;
13   static Cpu *boot_cpu() { return _boot_cpu; }
14
15   Cpu(Cpu_number cpu) { set_id(cpu); }
16
17 private:
18   static Cpu *_boot_cpu;
19   Cpu_phys_id _phys_id;
20   static unsigned long _ns_per_cycle;
21
22 };
23
24 namespace Segment
25 {
26   enum Attribs_enum
27   {
28     Ks = 1UL << 30,
29     Kp = 1UL << 29,
30     N  = 1UL << 28,
31     Default_attribs = Kp //Ks | Kp,
32   };
33 };
34 //------------------------------------------------------------------------------
35 IMPLEMENTATION [ppc32]:
36
37 #include "panic.h"
38 #include "boot_info.h"
39 #include "msr.h"
40
41 #include <cstdio>
42
43 DEFINE_PER_CPU Per_cpu<Cpu> Cpu::cpus(Per_cpu_data::Cpu_num);
44 Cpu *Cpu::_boot_cpu;
45 unsigned long Cpu::_ns_per_cycle;
46
47 PUBLIC static inline unsigned Cpu::phys_bits() { return 32; }
48
49 IMPLEMENT
50 void
51 Cpu::init(bool is_boot_cpu)
52 {
53   if (is_boot_cpu)
54     {
55       _boot_cpu = this;
56       set_present(1);
57       set_online(1);
58     }
59   _phys_id = Cpu_phys_id(0); //Proc::cpu_id();
60   _ns_per_cycle = 1000000000 / Boot_info::get_time_base();
61   printf("Timebase: %lu\n", Boot_info::get_time_base());
62 }
63
64 PUBLIC inline
65 Cpu_phys_id
66 Cpu::phys_id() const
67 { return _phys_id; }
68
69 IMPLEMENT
70 void
71 Cpu::early_init()
72 {
73   asm volatile( "mtmsr   %[msr]     \n" //set kernel msr (disables paging)
74                 "mtdbatu 0, %[zero] \n" //clear bat registers (good bye OF)
75                 "mtdbatu 1, %[zero] \n"
76                 "mtdbatu 2, %[zero] \n"
77                 "mtdbatu 3, %[zero] \n"
78                 "mtibatu 0, %[zero] \n"
79                 "mtibatu 1, %[zero] \n"
80                 "mtibatu 2, %[zero] \n"
81                 "mtibatu 3, %[zero] \n"
82                 : : [msr]"r" (Msr::Msr_kernel), [zero]"r" (0)
83                 );
84 }
85
86 PUBLIC static inline
87 Mword
88 Cpu::read_vsid(unsigned sr = 0)
89 {
90   Mword vsid;
91   asm volatile ("mfsrin %[vsid], %[sr] \n"
92                  : [vsid] "=r"(vsid)
93                  : [sr]"r" (sr << 28)
94                  );
95
96   return (vsid & 0xffffff);
97 }
98
99 /* set segment register 0-15 */
100 PUBLIC static inline //NEEDS["paging.h"]
101 void
102 Cpu::set_vsid(Mword vsid)
103 {
104   vsid |= Segment::Default_attribs;
105   Mword ret;
106
107   asm volatile ( " isync                           \n"
108                  " lis    %%r5, 0                  \n"
109                  " li     %%r5, 15                 \n"
110                  " mtctr  %%r5                     \n"
111                  " li     %%r5, 0                  \n"
112                  " mr     %%r6, %%r5               \n"
113                  " 1:                              \n"
114                  " mtsrin %[vsid], %%r5            \n" //set srX
115                  " addi   %[vsid], %[vsid], 1      \n" //inc vsid
116                  " addi   %%r6, %%r6, 1            \n"
117                  " rlwinm %%r5, %%r6, 28, 0, 3     \n" //extract sr index
118                  " bdnz  1b                        \n"
119 //               " isync                           \n" //rfi should be
120                                                        //sufficient
121                  : "=r" (ret)
122                  : [vsid]"r" (vsid)
123                  : "r5", "r6", "memory"
124                  );
125                 
126 }
127
128 PUBLIC static inline
129 Mword
130 Cpu::stack_align(Mword stack)
131 { return stack & ~0xf; }
132
133 PUBLIC static inline
134 bool
135 Cpu::have_superpages()
136 { return true; }
137
138 //------------------------------------------------------------------------------
139 /* Time functions */
140
141 /**
142  * Read time base registers 
143  */
144 PUBLIC static inline
145 Unsigned64
146 Cpu::rdtsc()
147 {
148   Unsigned32 tb_upper, tb_lower;
149   Unsigned64 tb;
150   asm volatile ( "1:                      \n"
151                  " mftbu %[upper]         \n"
152                  " mftb  %[lower]         \n"
153                  " mftbu %%r12            \n"
154                  " cmpw  %[upper], %%r12  \n"
155                  " bne 1b                 \n"
156                  : [upper]"=r" (tb_upper),
157                    [lower]"=r" (tb_lower)
158                  :
159                  : "r12"
160                 );
161   tb = tb_upper;
162   return (tb << 32) | tb_lower;
163 }
164
165 PUBLIC static inline
166 void
167 Cpu::busy_wait_ns(Unsigned64 ns)
168 {
169   Unsigned64 stop = rdtsc() + ns_to_tsc(ns);
170
171   while(rdtsc() <  stop) 
172     ;
173 }
174
175 PUBLIC static inline
176 Unsigned64
177 Cpu::ns_to_tsc(Unsigned64 ns)
178 {
179   return ns / _ns_per_cycle;
180 }
181
182 PUBLIC static inline
183 Unsigned64
184 Cpu::tsc_to_ns(Unsigned64 tsc)
185 {
186   return tsc * _ns_per_cycle;
187 }
188
189 PUBLIC static inline
190 Unsigned32
191 Cpu::get_scaler_tsc_to_ns()
192 { return 0; }
193
194 PUBLIC static inline
195 Unsigned32
196 Cpu::get_scaler_tsc_to_us() 
197 { return 0; }
198
199 PUBLIC static inline
200 Unsigned32 
201 Cpu::get_scaler_ns_to_tsc() 
202 { return 0; }
203
204 PUBLIC static inline
205 bool
206 Cpu::tsc()
207 { return 0; }
208
209 //------------------------------------------------------------------------------
210 /* Unimplemented */
211
212 PUBLIC static inline
213 void
214 Cpu::debugctl_enable()
215 {}
216
217 PUBLIC static inline
218 void
219 Cpu::debugctl_disable()
220 {}
221