Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / include / arch-x86_64 / processor.h
1 /*
2  * include/asm-x86_64/processor.h
3  *
4  * Copyright (C) 1994 Linus Torvalds
5  */
6
7 #ifndef _X86_64_PROCESSOR_H
8 #define _X86_64_PROCESSOR_H
9
10 #include <arch/segment.h>
11 #include <arch/page.h>
12 #include <arch/types.h>
13 #include <arch/sigcontext.h>
14 #include <arch/cpufeature.h>
15 /* #include <linux/threads.h> */
16 #include <arch/msr.h>
17 #include <arch/current.h>
18 #include <arch/system.h>
19 /* #include <arch/mmsegment.h> */
20 #include <arch/percpu.h>
21 /* #include <lwk/personality.h> */
22 #include <lwk/cpumask.h>
23 #include <lwk/cache.h>
24
25 #define TF_MASK         0x00000100
26 #define IF_MASK         0x00000200
27 #define IOPL_MASK       0x00003000
28 #define NT_MASK         0x00004000
29 #define VM_MASK         0x00020000
30 #define AC_MASK         0x00040000
31 #define VIF_MASK        0x00080000      /* virtual interrupt flag */
32 #define VIP_MASK        0x00100000      /* virtual interrupt pending */
33 #define ID_MASK         0x00200000
34
35 #define desc_empty(desc) \
36                (!((desc)->a | (desc)->b))
37
38 #define desc_equal(desc1, desc2) \
39                (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
40
41 /*
42  * Default implementation of macro that returns current
43  * instruction pointer ("program counter").
44  */
45 #define current_text_addr() ({ void *pc; asm volatile("leaq 1f(%%rip),%0\n1:":"=r"(pc)); pc; })
46
47 #define X86_VENDOR_INTEL 0
48 #define X86_VENDOR_CYRIX 1
49 #define X86_VENDOR_AMD 2
50 #define X86_VENDOR_UMC 3
51 #define X86_VENDOR_NEXGEN 4
52 #define X86_VENDOR_CENTAUR 5
53 #define X86_VENDOR_RISE 6
54 #define X86_VENDOR_TRANSMETA 7
55 #define X86_VENDOR_NUM 8
56 #define X86_VENDOR_UNKNOWN 0xff
57
58 extern char ignore_irq13;
59
60 extern void identify_cpu(void);
61
62 /*
63  * EFLAGS bits
64  */
65 #define X86_EFLAGS_CF   0x00000001 /* Carry Flag */
66 #define X86_EFLAGS_PF   0x00000004 /* Parity Flag */
67 #define X86_EFLAGS_AF   0x00000010 /* Auxillary carry Flag */
68 #define X86_EFLAGS_ZF   0x00000040 /* Zero Flag */
69 #define X86_EFLAGS_SF   0x00000080 /* Sign Flag */
70 #define X86_EFLAGS_TF   0x00000100 /* Trap Flag */
71 #define X86_EFLAGS_IF   0x00000200 /* Interrupt Flag */
72 #define X86_EFLAGS_DF   0x00000400 /* Direction Flag */
73 #define X86_EFLAGS_OF   0x00000800 /* Overflow Flag */
74 #define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */
75 #define X86_EFLAGS_NT   0x00004000 /* Nested Task */
76 #define X86_EFLAGS_RF   0x00010000 /* Resume Flag */
77 #define X86_EFLAGS_VM   0x00020000 /* Virtual Mode */
78 #define X86_EFLAGS_AC   0x00040000 /* Alignment Check */
79 #define X86_EFLAGS_VIF  0x00080000 /* Virtual Interrupt Flag */
80 #define X86_EFLAGS_VIP  0x00100000 /* Virtual Interrupt Pending */
81 #define X86_EFLAGS_ID   0x00200000 /* CPUID detection flag */
82
83 /*
84  * Intel CPU features in CR4
85  */
86 #define X86_CR4_VME             0x0001  /* enable vm86 extensions */
87 #define X86_CR4_PVI             0x0002  /* virtual interrupts flag enable */
88 #define X86_CR4_TSD             0x0004  /* disable time stamp at ipl 3 */
89 #define X86_CR4_DE              0x0008  /* enable debugging extensions */
90 #define X86_CR4_PSE             0x0010  /* enable page size extensions */
91 #define X86_CR4_PAE             0x0020  /* enable physical address extensions */
92 #define X86_CR4_MCE             0x0040  /* Machine check enable */
93 #define X86_CR4_PGE             0x0080  /* enable global pages */
94 #define X86_CR4_PCE             0x0100  /* enable performance counters at ipl 3 */
95 #define X86_CR4_OSFXSR          0x0200  /* enable fast FPU save and restore */
96 #define X86_CR4_OSXMMEXCPT      0x0400  /* enable unmasked SSE exceptions */
97
98 /*
99  * Save the cr4 feature set we're using (ie
100  * Pentium 4MB enable and PPro Global page
101  * enable), so that any CPU's that boot up
102  * after us can get the correct flags.
103  */
104 extern unsigned long mmu_cr4_features;
105
106 static inline void set_in_cr4 (unsigned long mask)
107 {
108         mmu_cr4_features |= mask;
109         __asm__("movq %%cr4,%%rax\n\t"
110                 "orq %0,%%rax\n\t"
111                 "movq %%rax,%%cr4\n"
112                 : : "irg" (mask)
113                 :"ax");
114 }
115
116 static inline void clear_in_cr4 (unsigned long mask)
117 {
118         mmu_cr4_features &= ~mask;
119         __asm__("movq %%cr4,%%rax\n\t"
120                 "andq %0,%%rax\n\t"
121                 "movq %%rax,%%cr4\n"
122                 : : "irg" (~mask)
123                 :"ax");
124 }
125
126
127 /*
128  * Size of io_bitmap.
129  */
130 #define IO_BITMAP_BITS  65536
131 #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
132 #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
133 #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
134 #define INVALID_IO_BITMAP_OFFSET 0x8000
135
136 struct i387_fxsave_struct {
137         u16     cwd;
138         u16     swd;
139         u16     twd;
140         u16     fop;
141         u64     rip;
142         u64     rdp; 
143         u32     mxcsr;
144         u32     mxcsr_mask;
145         u32     st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
146         u32     xmm_space[64];  /* 16*16 bytes for each XMM-reg = 256 bytes */
147         u32     padding[24];
148 } __attribute__ ((aligned (16)));
149
150 union i387_union {
151         struct i387_fxsave_struct       fxsave;
152 };
153
154 struct tss_struct {
155         u32 reserved1;
156         u64 rsp0;       
157         u64 rsp1;
158         u64 rsp2;
159         u64 reserved2;
160         u64 ist[7];
161         u32 reserved3;
162         u32 reserved4;
163         u16 reserved5;
164         u16 io_bitmap_base;
165         /*
166          * The extra 1 is there because the CPU will access an
167          * additional byte beyond the end of the IO permission
168          * bitmap. The extra byte must be all 1 bits, and must
169          * be within the limit. Thus we have:
170          *
171          * 128 bytes, the bitmap itself, for ports 0..0x3ff
172          * 8 bytes, for an extra "long" of ~0UL
173          */
174         unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
175 } __attribute__((packed)) ____cacheline_aligned;
176
177 DECLARE_PER_CPU(struct tss_struct,tss);
178
179 #ifdef CONFIG_X86_VSMP
180 #define ARCH_MIN_TASKALIGN      (1 << INTERNODE_CACHE_SHIFT)
181 #define ARCH_MIN_MMSTRUCT_ALIGN (1 << INTERNODE_CACHE_SHIFT)
182 #else
183 #define ARCH_MIN_TASKALIGN      16
184 #define ARCH_MIN_MMSTRUCT_ALIGN 0
185 #endif
186
187 struct thread_struct {
188         unsigned long   rsp0;
189         unsigned long   rsp;
190         unsigned long   userrsp;        /* Copy from PDA */ 
191         unsigned long   fs;
192         unsigned long   gs;
193         unsigned short  es, ds, fsindex, gsindex;       
194 /* Hardware debugging registers */
195         unsigned long   debugreg0;  
196         unsigned long   debugreg1;  
197         unsigned long   debugreg2;  
198         unsigned long   debugreg3;  
199         unsigned long   debugreg6;  
200         unsigned long   debugreg7;  
201 /* fault info */
202         unsigned long   cr2, trap_no, error_code;
203 /* floating point info */
204         union i387_union        i387  __attribute__((aligned(16)));
205 /* IO permissions. the bitmap could be moved into the GDT, that would make
206    switch faster for a limited number of ioperm using tasks. -AK */
207         int             ioperm;
208         unsigned long   *io_bitmap_ptr;
209         unsigned io_bitmap_max;
210 /* cached TLS descriptors. */
211         u64 tls_array[GDT_ENTRY_TLS_ENTRIES];
212 } __attribute__((aligned(16)));
213
214 #define BOOTSTRAP_THREAD  { \
215         .rsp0 = (unsigned long)&bootstrap_stack + sizeof(bootstrap_stack) \
216 }
217
218 #define BOOTSTRAP_TSS  { \
219         .rsp0 = (unsigned long)&bootstrap_stack + sizeof(bootstrap_stack) \
220 }
221
222 #define INIT_MMAP \
223 { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
224
225 #define start_thread(regs,new_rip,new_rsp) do { \
226         asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0));      \
227         load_gs_index(0);                                                       \
228         (regs)->rip = (new_rip);                                                 \
229         (regs)->rsp = (new_rsp);                                                 \
230         write_pda(oldrsp, (new_rsp));                                            \
231         (regs)->cs = __USER_CS;                                                  \
232         (regs)->ss = __USER_DS;                                                  \
233         (regs)->eflags = 0x200;                                                  \
234         set_fs(USER_DS);                                                         \
235 } while(0) 
236
237 #define get_debugreg(var, register)                             \
238                 __asm__("movq %%db" #register ", %0"            \
239                         :"=r" (var))
240 #define set_debugreg(value, register)                   \
241                 __asm__("movq %0,%%db" #register                \
242                         : /* no output */                       \
243                         :"r" (value))
244
245 struct mm_struct;
246
247 /* Free all resources held by a thread. */
248 extern void release_thread(struct task_struct *);
249
250 /* Prepare to copy thread state - unlazy all lazy status */
251 extern void prepare_to_copy(struct task_struct *tsk);
252
253 /*
254  * create a kernel thread without removing it from tasklists
255  */
256 extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
257
258 /*
259  * Return saved PC of a blocked thread.
260  * What is this good for? it will be always the scheduler or ret_from_fork.
261  */
262 #define thread_saved_pc(t) (*(unsigned long *)((t)->thread.rsp - 8))
263
264 extern unsigned long get_wchan(struct task_struct *p);
265 #define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.rsp0 - 1)
266 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->rip)
267 #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */
268
269
270 struct microcode_header {
271         unsigned int hdrver;
272         unsigned int rev;
273         unsigned int date;
274         unsigned int sig;
275         unsigned int cksum;
276         unsigned int ldrver;
277         unsigned int pf;
278         unsigned int datasize;
279         unsigned int totalsize;
280         unsigned int reserved[3];
281 };
282
283 struct microcode {
284         struct microcode_header hdr;
285         unsigned int bits[0];
286 };
287
288 typedef struct microcode microcode_t;
289 typedef struct microcode_header microcode_header_t;
290
291 /* microcode format is extended from prescott processors */
292 struct extended_signature {
293         unsigned int sig;
294         unsigned int pf;
295         unsigned int cksum;
296 };
297
298 struct extended_sigtable {
299         unsigned int count;
300         unsigned int cksum;
301         unsigned int reserved[3];
302         struct extended_signature sigs[0];
303 };
304
305
306 #define ASM_NOP1 K8_NOP1
307 #define ASM_NOP2 K8_NOP2
308 #define ASM_NOP3 K8_NOP3
309 #define ASM_NOP4 K8_NOP4
310 #define ASM_NOP5 K8_NOP5
311 #define ASM_NOP6 K8_NOP6
312 #define ASM_NOP7 K8_NOP7
313 #define ASM_NOP8 K8_NOP8
314
315 /* Opteron nops */
316 #define K8_NOP1 ".byte 0x90\n"
317 #define K8_NOP2 ".byte 0x66,0x90\n" 
318 #define K8_NOP3 ".byte 0x66,0x66,0x90\n" 
319 #define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" 
320 #define K8_NOP5 K8_NOP3 K8_NOP2 
321 #define K8_NOP6 K8_NOP3 K8_NOP3
322 #define K8_NOP7 K8_NOP4 K8_NOP3
323 #define K8_NOP8 K8_NOP4 K8_NOP4
324
325 #define ASM_NOP_MAX 8
326
327 /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
328 static inline void rep_nop(void)
329 {
330         __asm__ __volatile__("rep;nop": : :"memory");
331 }
332
333 /* Stop speculative execution */
334 static inline void sync_core(void)
335
336         int tmp;
337         asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
338
339
340 #define cpu_has_fpu 1
341
342 #define ARCH_HAS_PREFETCH
343 static inline void prefetch(void *x) 
344
345         asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x));
346
347
348 #define ARCH_HAS_PREFETCHW 1
349 static inline void prefetchw(void *x) 
350
351         asm volatile("prefetchtw %0" :: "m" (*(unsigned long *)x));
352
353
354 #define ARCH_HAS_SPINLOCK_PREFETCH 1
355
356 #define spin_lock_prefetch(x)  prefetchw(x)
357
358 #define cpu_relax()   rep_nop()
359
360 static inline void serialize_cpu(void)
361 {
362         __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
363 }
364
365 static inline void __monitor(const void *eax, unsigned long ecx,
366                 unsigned long edx)
367 {
368         /* "monitor %eax,%ecx,%edx;" */
369         asm volatile(
370                 ".byte 0x0f,0x01,0xc8;"
371                 : :"a" (eax), "c" (ecx), "d"(edx));
372 }
373
374 static inline void __mwait(unsigned long eax, unsigned long ecx)
375 {
376         /* "mwait %eax,%ecx;" */
377         asm volatile(
378                 ".byte 0x0f,0x01,0xc9;"
379                 : :"a" (eax), "c" (ecx));
380 }
381
382 #define stack_current() \
383 ({                                                              \
384         struct thread_info *ti;                                 \
385         asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK));  \
386         ti->task;                                       \
387 })
388
389 #define cache_line_size() (boot_cpu_data.x86_cache_alignment)
390
391 extern unsigned long boot_option_idle_override;
392 /* Boot loader type from the setup header */
393 extern int bootloader_type;
394
395 #define HAVE_ARCH_PICK_MMAP_LAYOUT 1
396
397 #endif /* _X86_64_PROCESSOR_H */