]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/drivers/amd64/processor-amd64.cpp
3ea94dc6b4b0b7d5c088f1672c855643ac5c7922
[l4.git] / kernel / fiasco / src / drivers / amd64 / processor-amd64.cpp
1 INTERFACE[amd64]:
2
3 EXTENSION class Proc
4 {
5 public:
6   enum Efer_bits
7   {
8     Efer_sce_flag  = 0x00000001,      // Syscall Enable Flag
9     Efer_lme_flag  = 0x00000100,      // Long Mode Enable Flag
10     Efer_nxe_flag  = 0x00000800,      // Not-executable      
11     Efer_svme_flag = 0x00001000,      // Enable SVM
12   };
13 };
14
15 IMPLEMENTATION[amd64]:
16
17 #include "types.h"
18 #include "std_macros.h"
19
20 IMPLEMENT static inline
21 Mword Proc::stack_pointer()
22 {
23   Mword sp;
24   asm volatile ("mov %%rsp, %0 \n" : "=r"(sp) );
25   return sp;
26 }
27
28 IMPLEMENT static inline
29 void Proc::stack_pointer(Mword sp)
30 {
31   asm volatile ("mov %0, %%rsp \n" : : "r"(sp) );
32 }
33
34 IMPLEMENT static inline
35 Mword Proc::program_counter ()
36 {
37   Mword pc;
38   asm volatile ("call 1f ; 1: pop %0" : "=r"(pc));
39   return pc;
40 }
41
42 IMPLEMENT static inline
43 void Proc::pause()
44 {
45   asm volatile (" .byte 0xf3, 0x90 #pause \n" ); 
46 }
47
48 /*
49  * The following simple ASM statements need the clobbering to work around
50  * a bug in (at least) gcc-3.2.x up to x == 1. The bug was fixed on
51  * Jan 9th 2003 (see gcc-bugs #9242 and #8832), so a released gcc-3.2.2
52  * won't have it. It's safe to take the clobber statements out after
53  * some time (e.g. when gcc-3.3 is used as a standard compiler).
54  */
55
56 IMPLEMENT static inline
57 void Proc::halt()
58 {
59   asm volatile ("hlt" : : : "memory");
60 }
61
62 IMPLEMENT static inline
63 void Proc::cli()
64 {
65   asm volatile ("cli" : : : "memory");
66 }
67
68 IMPLEMENT static inline
69 void Proc::sti()
70 {
71   asm volatile ("sti" : : : "memory");
72 }
73
74 IMPLEMENT static inline
75 Proc::Status Proc::cli_save()
76 {
77   Status ret;
78   asm volatile ("pushfq \n\t"
79                 "popq %0        \n\t"
80                 "cli            \n\t"
81                 : "=g"(ret) : /* no input */ : "memory");
82   return ret;
83 }
84
85 IMPLEMENT static inline
86 void Proc::sti_restore(Status st)
87 {
88   if (st & 0x0200)
89     asm volatile ("sti" : : : "memory");
90 }
91
92 IMPLEMENT static inline
93 Proc::Status Proc::interrupts()
94 {
95   Status ret;
96   asm volatile ("pushfq         \n"
97                 "popq %0        \n"
98                 : "=g"(ret) : /* no input */ : "memory");
99   return ret & 0x0200;
100 }
101
102 IMPLEMENT static inline
103 void Proc::irq_chance()
104 {
105   asm volatile ("nop; nop;" : : : "memory");
106 }
107
108
109 PUBLIC static inline
110 Unsigned64
111 Proc::rdmsr(Unsigned32 msr)
112 {
113   Unsigned32 h,l;
114
115   asm volatile ("rdmsr" : "=a" (l), "=d" (h) : "c" (msr));
116   return (((Mword)h) << 32) | l;
117 }
118
119 PUBLIC static inline
120 void
121 Proc::wrmsr(Unsigned32 msr, Unsigned64 value)
122 {
123   asm volatile ("wrmsr" : : 
124       "a" ((Unsigned32)value),
125       "d" ((Unsigned32)(value >> 32)),
126       "c" (msr)); 
127 }
128
129 PUBLIC static inline
130 Mword
131 Proc::efer()
132 { return rdmsr(0xc0000080); }
133
134 PUBLIC static inline
135 void
136 Proc::efer(Mword value)
137 { wrmsr(0xc0000080, value); }
138
139