]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ux/cpu-ux.cpp
update
[l4.git] / kernel / fiasco / src / kern / ux / cpu-ux.cpp
1 /*
2  * Fiasco-UX
3  * Architecture specific cpu init code
4  */
5
6 INTERFACE[ux]:
7
8 class Tss;
9
10 EXTENSION class Cpu
11 {
12 public:
13   static Mword kern_ds() { return _kern_ds; }
14   static Mword kern_es() { return _kern_es; }
15 private:
16   static Tss *tss asm ("CPU_TSS");
17   static int msr_dev;
18   static unsigned long _gs asm ("CPU_GS");
19   static unsigned long _fs asm ("CPU_FS");
20   static Mword _kern_ds asm ("KERN_DS");
21   static Mword _kern_es asm ("KERN_ES");
22
23   Cpu_phys_id _tid;
24 };
25
26 // -----------------------------------------------------------------------
27 IMPLEMENTATION[ux]:
28
29 #include <cerrno>
30 #include <cstdio>
31 #include <unistd.h>
32 #include <fcntl.h>
33
34 #include "div32.h"
35 #include "emulation.h"
36 #include "gdt.h"
37 #include "initcalls.h"
38 #include "processor.h"
39 #include "regdefs.h"
40 #include "tss.h"
41
42 Proc::Status volatile Proc::virtual_processor_state = 0;
43 Tss *Cpu::tss;
44 int Cpu::msr_dev = -1;
45 unsigned long Cpu::_gs; // for mp: percpu
46 unsigned long Cpu::_fs; // for mp: percpu
47 unsigned long Cpu::_kern_ds;
48 unsigned long Cpu::_kern_es;
49
50 IMPLEMENT FIASCO_INIT_CPU
51 void
52 Cpu::init()
53 {
54   identify();
55
56   // Get original es and ds to be used for RESET_KERNEL_SEGMENTS_FORCE_DS_ES
57   _kern_ds = get_ds();
58   _kern_es = get_es();
59
60   // No Sysenter Support for Fiasco-UX
61   _features &= ~FEAT_SEP;
62
63   // Determine CPU frequency
64   FILE *fp;
65   if ((fp = fopen ("/proc/cpuinfo", "r")) != NULL)
66     {
67       char buffer[128];
68       float val;
69
70       while (fgets (buffer, sizeof (buffer), fp))
71         if (sscanf (buffer, "cpu MHz%*[^:]: %f", &val) == 1)
72           {
73             _frequency    = (Unsigned64)(val * 1000) * 1000;
74             scaler_tsc_to_ns = muldiv (1 << 27, 1000000000,    _frequency);
75             scaler_tsc_to_us = muldiv (1 << 27, 32 * 1000000,  _frequency);
76             scaler_ns_to_tsc = muldiv (1 << 27, _frequency, 1000000000);
77             break;
78           }
79
80       fclose (fp);
81     }
82
83   if (this == _boot_cpu)
84     {
85       // XXX hardcoded
86       msr_dev = open("/dev/msr", O_RDWR);
87       if (msr_dev == -1)
88         msr_dev = open("/dev/cpu/0/msr", O_RDWR);
89     }
90
91   _tid = phys_id_direct();
92 }
93
94 PUBLIC
95 void
96 Cpu::print() const
97 {
98   printf ("CPU[%u:%u]: %s (%X:%X:%X:%X) Model: %s at %llu MHz\n\n",
99           cxx::int_value<Cpu_number>(id()),
100           cxx::int_value<Cpu_phys_id>(phys_id()),
101           vendor_str(), family(), model(), stepping(), brand(), model_str(),
102           div32(frequency(), 1000000));
103 }
104
105 PUBLIC inline
106 Cpu_phys_id
107 Cpu::phys_id() const
108 { return _tid; }
109
110 PUBLIC static inline
111 void
112 Cpu::set_fast_entry (void (*)(void))
113 {}
114
115 PUBLIC static FIASCO_INIT
116 void
117 Cpu::init_tss (Address tss_mem)
118 {
119   tss = reinterpret_cast<Tss*>(tss_mem);
120   tss->_ss0 = Gdt::gdt_data_kernel;
121 }
122
123 PUBLIC static inline
124 Tss*
125 Cpu::get_tss ()
126 { return tss; }
127
128 PUBLIC static inline
129 void
130 Cpu::enable_rdpmc()
131 {
132 }
133
134 IMPLEMENT inline
135 int
136 Cpu::can_wrmsr() const
137 {
138   return msr_dev != -1;
139 }
140
141 PUBLIC static
142 Unsigned64
143 Cpu::rdmsr (Unsigned32 reg)
144 {
145   Unsigned64 msr;
146
147   if (lseek(msr_dev, reg, SEEK_SET) >= 0)
148     read(msr_dev, &msr, sizeof(msr));
149
150   return msr;
151 }
152
153 PUBLIC static inline
154 Unsigned64
155 Cpu::rdpmc (Unsigned32, Unsigned32 reg)
156 {
157   return rdmsr(reg);
158 }
159
160 PUBLIC static
161 void
162 Cpu::wrmsr (Unsigned64 msr, Unsigned32 reg)
163 {
164   if (lseek(msr_dev, reg, SEEK_SET) >= 0)
165     write(msr_dev, &msr, sizeof(msr));
166 }
167
168 PUBLIC static inline
169 void
170 Cpu::wrmsr (Unsigned32 low, Unsigned32 high, Unsigned32 reg)
171 {
172   Unsigned64 msr = ((Unsigned64)high << 32) | low;
173   wrmsr(msr, reg);
174 }
175
176 PUBLIC static inline
177 void
178 Cpu::debugctl_enable()
179 {}
180
181 PUBLIC static inline
182 void
183 Cpu::debugctl_disable()
184 {}
185
186 PUBLIC static inline
187 void
188 Cpu::set_fs(Unsigned32 val)
189 { _fs = val; }
190
191 PUBLIC static inline
192 void
193 Cpu::set_gs(Unsigned32 val)
194 { _gs = val; }
195
196 PUBLIC static inline
197 Unsigned32
198 Cpu::get_fs()
199 { return _fs; }
200
201 PUBLIC static inline
202 Unsigned32
203 Cpu::get_gs()
204 { return _gs; }
205
206 // ------------------------------------------------------------------------
207 IMPLEMENTATION[ux && !mp]:
208
209 PUBLIC static inline
210 Cpu_phys_id
211 Cpu::phys_id_direct()
212 { return Cpu_phys_id(0); }
213
214 // ------------------------------------------------------------------------
215 IMPLEMENTATION[ux && mp]:
216
217 PUBLIC static inline NEEDS["emulation.h"]
218 Cpu_phys_id
219 Cpu::phys_id_direct()
220 { return Cpu_phys_id(Emulation::gettid()); }
221