Uthreads handle FP save and restore
[akaros.git] / user / parlib / include / i686 / arch.h
1 #ifndef PARLIB_ARCH_H
2 #define PARLIB_ARCH_H
3
4 #include <ros/trapframe.h>
5 #include <ros/arch/mmu.h>
6 #include <ros/common.h>
7 #include <string.h>
8
9 #define internal_function   __attribute ((regparm (3), stdcall))
10
11 #define ARCH_CL_SIZE 64
12
13 /* Make sure you subtract off/save enough space at the top of the stack for
14  * whatever you compiler might want to use when calling a noreturn function or
15  * to handle a HW spill or whatever. */
16 static __inline void __attribute__((always_inline))
17 set_stack_pointer(void* sp)
18 {
19         asm volatile ("mov %0,%%esp" : : "r"(sp) : "memory","esp");
20 }
21
22 static __inline void
23 breakpoint(void)
24 {
25         __asm __volatile("int3");
26 }
27
28 static __inline uint64_t
29 read_tsc(void)
30 {
31         uint64_t tsc;
32         __asm __volatile("rdtsc" : "=A" (tsc));
33         return tsc;
34 }
35
36 /* non-core-id reporting style (it is in ecx) */
37 static __inline uint64_t
38 read_tscp(void)
39 {
40         uint64_t tsc;
41         __asm __volatile("rdtscp" : "=A" (tsc) : : "ecx");
42         return tsc;
43 }
44
45 static __inline void
46 cpuid(uint32_t info1, uint32_t info2, uint32_t *eaxp, uint32_t *ebxp,
47       uint32_t *ecxp, uint32_t *edxp)
48 {
49         uint32_t eax, ebx, ecx, edx;
50         /* Can select with both eax (info1) and ecx (info2) */
51         asm volatile("cpuid" 
52                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
53                 : "a" (info1), "c" (info2));
54         if (eaxp)
55                 *eaxp = eax;
56         if (ebxp)
57                 *ebxp = ebx;
58         if (ecxp)
59                 *ecxp = ecx;
60         if (edxp)
61                 *edxp = edx;
62 }
63
64 /* Check out k/a/i686/rdtsc_test.c for more info */
65 static __inline uint64_t 
66 read_tsc_serialized(void)
67 {
68         asm volatile("lfence"); /* mfence on amd */
69         return read_tsc();
70 }
71
72 static __inline void
73 cpu_relax(void)
74 {
75         asm volatile("pause" : : : "memory");
76 }
77
78 static __inline uint64_t                                                                             
79 read_pmc(uint32_t index)
80 {                                                                                                    
81     uint64_t pmc;
82
83     __asm __volatile("rdpmc" : "=A" (pmc) : "c" (index)); 
84     return pmc;                                                                                      
85 }
86
87 static inline void save_fp_state(struct ancillary_state *silly)
88 {
89         asm volatile("fxsave %0" : : "m"(*silly));
90 }
91
92 static inline void restore_fp_state(struct ancillary_state *silly)
93 {
94         asm volatile("fxrstor %0" : : "m"(*silly));
95 }
96
97 #endif /* PARLIB_ARCH_H */