36716a6ce452210a375ff8f76216863b29576c72
[akaros.git] / user / parlib / include / i686 / arch.h
1 #ifndef PARLIB_ARCH_H
2 #define PARLIB_ARCH_H
3
4 #include <ros/arch/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 static __inline uint64_t
65 read_tsc_serialized(void)
66 {
67         uint64_t tsc;
68         cpuid(0x0, 0x0, 0, 0, 0, 0);
69         tsc = read_tsc();
70         return tsc;
71 }
72
73 static __inline void
74 cpu_relax(void)
75 {
76         asm volatile("pause" : : : "memory");
77 }
78
79 static __inline uint64_t                                                                             
80 read_pmc(uint32_t index)
81 {                                                                                                    
82     uint64_t pmc;
83
84     __asm __volatile("rdpmc" : "=A" (pmc) : "c" (index)); 
85     return pmc;                                                                                      
86 }
87
88
89 #endif /* PARLIB_ARCH_H */