blob: 44e91d28b6f93b2b414b6018c944b5679a32cdcf [file] [log] [blame]
efdesign98229f7cb2011-07-13 16:43:39 -07001/*
Edward O'Callaghan913e27e2014-11-01 05:35:18 +11002 * Copyright (c) 2011, Advanced Micro Devices, Inc. All rights reserved.
3 * Copyright (c) 2014, Edward O'Callaghan <eocallaghan@alterapraxis.com>
efdesign98229f7cb2011-07-13 16:43:39 -07004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
13 * its contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#if defined (__GNUC__)
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070030#include <stdint.h>
efdesign98229f7cb2011-07-13 16:43:39 -070031/* I/O intrin functions. */
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070032static __inline__ __attribute__((always_inline)) uint8_t __inbyte(uint16_t Port)
efdesign98229f7cb2011-07-13 16:43:39 -070033{
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070034 uint8_t value;
efdesign98229f7cb2011-07-13 16:43:39 -070035
36 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110037 "in %1, %0"
efdesign98229f7cb2011-07-13 16:43:39 -070038 : "=a" (value)
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110039 : "Nd" (Port)
efdesign98229f7cb2011-07-13 16:43:39 -070040 );
41
42 return value;
43}
44
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070045static __inline__ __attribute__((always_inline)) uint16_t __inword(uint16_t Port)
efdesign98229f7cb2011-07-13 16:43:39 -070046{
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070047 uint16_t value;
efdesign98229f7cb2011-07-13 16:43:39 -070048
49 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110050 "in %1, %0"
efdesign98229f7cb2011-07-13 16:43:39 -070051 : "=a" (value)
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110052 : "Nd" (Port)
efdesign98229f7cb2011-07-13 16:43:39 -070053 );
54
55 return value;
56}
57
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070058static __inline__ __attribute__((always_inline)) uint32_t __indword(uint16_t Port)
efdesign98229f7cb2011-07-13 16:43:39 -070059{
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070060 uint32_t value;
Edward O'Callaghane1845b32014-05-20 04:36:41 +100061
efdesign98229f7cb2011-07-13 16:43:39 -070062 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110063 "in %1, %0"
efdesign98229f7cb2011-07-13 16:43:39 -070064 : "=a" (value)
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110065 : "Nd" (Port)
efdesign98229f7cb2011-07-13 16:43:39 -070066 );
67 return value;
68
69}
70
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070071static __inline__ __attribute__((always_inline)) void __outbyte(uint16_t Port,uint8_t Data)
efdesign98229f7cb2011-07-13 16:43:39 -070072{
73 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110074 "out %0, %1"
efdesign98229f7cb2011-07-13 16:43:39 -070075 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110076 : "a" (Data), "Nd" (Port)
efdesign98229f7cb2011-07-13 16:43:39 -070077 );
78}
79
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070080static __inline__ __attribute__((always_inline)) void __outword(uint16_t Port,uint16_t Data)
efdesign98229f7cb2011-07-13 16:43:39 -070081{
82 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110083 "out %0, %1"
efdesign98229f7cb2011-07-13 16:43:39 -070084 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110085 : "a" (Data), "Nd" (Port)
efdesign98229f7cb2011-07-13 16:43:39 -070086 );
87}
88
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070089static __inline__ __attribute__((always_inline)) void __outdword(uint16_t Port,uint32_t Data)
efdesign98229f7cb2011-07-13 16:43:39 -070090{
91 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110092 "out %0, %1"
efdesign98229f7cb2011-07-13 16:43:39 -070093 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +110094 : "a" (Data), "Nd" (Port)
efdesign98229f7cb2011-07-13 16:43:39 -070095 );
96}
97
Stefan Reinauerd91ddc82015-07-30 11:17:40 -070098static __inline__ __attribute__((always_inline)) void __inbytestring(uint16_t Port,uint8_t *Buffer,unsigned long Count)
efdesign98229f7cb2011-07-13 16:43:39 -070099{
100 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100101 "rep ; insb"
102 : "+D" (Buffer), "+c" (Count)
103 : "d"(Port)
efdesign98229f7cb2011-07-13 16:43:39 -0700104 );
105}
106
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700107static __inline__ __attribute__((always_inline)) void __inwordstring(uint16_t Port,uint16_t *Buffer,unsigned long Count)
efdesign98229f7cb2011-07-13 16:43:39 -0700108{
109 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100110 "rep ; insw"
111 : "+D" (Buffer), "+c" (Count)
112 : "d"(Port)
efdesign98229f7cb2011-07-13 16:43:39 -0700113 );
114}
115
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700116static __inline__ __attribute__((always_inline)) void __indwordstring(uint16_t Port,unsigned long *Buffer,unsigned long Count)
efdesign98229f7cb2011-07-13 16:43:39 -0700117{
118 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100119 "rep ; insl"
120 : "+D" (Buffer), "+c" (Count)
121 : "d"(Port)
efdesign98229f7cb2011-07-13 16:43:39 -0700122 );
123}
124
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700125static __inline__ __attribute__((always_inline)) void __outbytestring(uint16_t Port,uint8_t *Buffer,unsigned long Count)
efdesign98229f7cb2011-07-13 16:43:39 -0700126{
127 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100128 "rep ; outsb"
129 : "+S" (Buffer), "+c" (Count)
130 : "d"(Port)
efdesign98229f7cb2011-07-13 16:43:39 -0700131 );
132}
133
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700134static __inline__ __attribute__((always_inline)) void __outwordstring(uint16_t Port,uint16_t *Buffer,unsigned long Count)
efdesign98229f7cb2011-07-13 16:43:39 -0700135{
136 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100137 "rep ; outsw"
138 : "+S" (Buffer), "+c" (Count)
139 : "d"(Port)
efdesign98229f7cb2011-07-13 16:43:39 -0700140 );
141}
142
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700143static __inline__ __attribute__((always_inline)) void __outdwordstring(uint16_t Port,unsigned long *Buffer,unsigned long Count)
efdesign98229f7cb2011-07-13 16:43:39 -0700144{
145 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100146 "rep ; outsl"
147 : "+S" (Buffer), "+c" (Count)
148 : "d"(Port)
efdesign98229f7cb2011-07-13 16:43:39 -0700149 );
150}
151
152static __inline__ __attribute__((always_inline)) unsigned long __readdr0(void)
153{
154 unsigned long value;
155 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000156 "mov %%dr0, %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100157 : [value] "=r" (value)
efdesign98229f7cb2011-07-13 16:43:39 -0700158 );
159 return value;
160}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000161
efdesign98229f7cb2011-07-13 16:43:39 -0700162static __inline__ __attribute__((always_inline)) unsigned long __readdr1(void)
163{
164 unsigned long value;
165 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000166 "mov %%dr1, %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100167 : [value] "=r" (value)
efdesign98229f7cb2011-07-13 16:43:39 -0700168 );
169 return value;
170}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000171
efdesign98229f7cb2011-07-13 16:43:39 -0700172static __inline__ __attribute__((always_inline)) unsigned long __readdr2(void)
173{
174 unsigned long value;
175 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000176 "mov %%dr2, %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100177 : [value] "=r" (value)
efdesign98229f7cb2011-07-13 16:43:39 -0700178 );
179 return value;
180}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000181
efdesign98229f7cb2011-07-13 16:43:39 -0700182static __inline__ __attribute__((always_inline)) unsigned long __readdr3(void)
183{
184 unsigned long value;
185 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000186 "mov %%dr3, %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100187 : [value] "=r" (value)
efdesign98229f7cb2011-07-13 16:43:39 -0700188 );
189 return value;
190}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000191
efdesign98229f7cb2011-07-13 16:43:39 -0700192static __inline__ __attribute__((always_inline)) unsigned long __readdr7(void)
193{
194 unsigned long value;
195 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000196 "mov %%dr7, %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100197 : [value] "=r" (value)
efdesign98229f7cb2011-07-13 16:43:39 -0700198 );
199 return value;
200}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000201
efdesign98229f7cb2011-07-13 16:43:39 -0700202static __inline__ __attribute__((always_inline)) unsigned long __readdr(unsigned long reg)
203{
204 switch (reg){
205 case 0:
206 return __readdr0 ();
207 break;
208
209 case 1:
210 return __readdr1 ();
211 break;
212
213 case 2:
214 return __readdr2 ();
215 break;
216
217 case 3:
218 return __readdr3 ();
219 break;
220
221 case 7:
222 return __readdr7 ();
223 break;
224
225 default:
226 return -1;
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000227 }
efdesign98229f7cb2011-07-13 16:43:39 -0700228}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000229
efdesign98229f7cb2011-07-13 16:43:39 -0700230static __inline__ __attribute__((always_inline)) void __writedr0(unsigned long Data)
231{
232 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100233 "mov %0, %%dr0"
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000234 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100235 : "r" (Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700236 );
237}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000238
efdesign98229f7cb2011-07-13 16:43:39 -0700239static __inline__ __attribute__((always_inline)) void __writedr1(unsigned long Data)
240{
241 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100242 "mov %0, %%dr1"
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000243 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100244 : "r" (Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700245 );
246}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000247
efdesign98229f7cb2011-07-13 16:43:39 -0700248static __inline__ __attribute__((always_inline)) void __writedr2(unsigned long Data)
249{
250 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100251 "mov %0, %%dr2"
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000252 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100253 : "r" (Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700254 );
255}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000256
efdesign98229f7cb2011-07-13 16:43:39 -0700257static __inline__ __attribute__((always_inline)) void __writedr3(unsigned long Data)
258{
259 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100260 "mov %0, %%dr3"
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000261 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100262 : "r" (Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700263 );
264}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000265
efdesign98229f7cb2011-07-13 16:43:39 -0700266static __inline__ __attribute__((always_inline)) void __writedr7(unsigned long Data)
267{
268 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100269 "mov %0, %%dr7"
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000270 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100271 : "r" (Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700272 );
273}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000274
efdesign98229f7cb2011-07-13 16:43:39 -0700275static __inline__ __attribute__((always_inline)) void __writedr(unsigned long reg, unsigned long Data)
276{
277 switch (reg){
278 case 0:
279 __writedr0 (Data);
280 break;
281
282 case 1:
283 __writedr1 (Data);
284 break;
285
286 case 2:
287 __writedr2 (Data);
288 break;
289
290 case 3:
291 __writedr3 (Data);
292 break;
293
294 case 7:
295 __writedr7 (Data);
296 break;
297
298 default:
299 ;
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000300 }
efdesign98229f7cb2011-07-13 16:43:39 -0700301}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000302
efdesign98229f7cb2011-07-13 16:43:39 -0700303static __inline__ __attribute__((always_inline)) unsigned long __readcr0(void)
304{
305 unsigned long value;
306 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000307 "mov %%cr0, %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100308 : [value] "=r" (value));
efdesign98229f7cb2011-07-13 16:43:39 -0700309 return value;
310}
311
312static __inline__ __attribute__((always_inline)) unsigned long __readcr2(void)
313{
314 unsigned long value;
315 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000316 "mov %%cr2, %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100317 : [value] "=r" (value));
efdesign98229f7cb2011-07-13 16:43:39 -0700318 return value;
319}
320
321static __inline__ __attribute__((always_inline)) unsigned long __readcr3(void)
322{
323 unsigned long value;
324 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000325 "mov %%cr3, %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100326 : [value] "=r" (value));
efdesign98229f7cb2011-07-13 16:43:39 -0700327 return value;
328}
329
330static __inline__ __attribute__((always_inline)) unsigned long __readcr4(void)
331{
332 unsigned long value;
333 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000334 "mov %%cr4, %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100335 : [value] "=r" (value));
efdesign98229f7cb2011-07-13 16:43:39 -0700336 return value;
337}
338
339static __inline__ __attribute__((always_inline)) unsigned long __readcr8(void)
340{
341 unsigned long value;
342 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000343 "mov %%cr8, %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100344 : [value] "=r" (value));
efdesign98229f7cb2011-07-13 16:43:39 -0700345 return value;
346}
347
348static __inline__ __attribute__((always_inline)) unsigned long __readcr(unsigned long reg)
349{
350 switch (reg){
351 case 0:
352 return __readcr0 ();
353 break;
354
355 case 2:
356 return __readcr2 ();
357 break;
358
359 case 3:
360 return __readcr3 ();
361 break;
362
363 case 4:
364 return __readcr4 ();
365 break;
366
367 case 8:
368 return __readcr8 ();
369 break;
370
371 default:
372 return -1;
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000373 }
efdesign98229f7cb2011-07-13 16:43:39 -0700374}
375
376static __inline__ __attribute__((always_inline)) void __writecr0(unsigned long Data)
377{
378 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100379 "mov %0, %%cr0"
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000380 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100381 : "r" (Data)
382 : "memory"
efdesign98229f7cb2011-07-13 16:43:39 -0700383 );
384}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000385
efdesign98229f7cb2011-07-13 16:43:39 -0700386static __inline__ __attribute__((always_inline)) void __writecr2(unsigned long Data)
387{
388 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100389 "mov %0, %%cr2"
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000390 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100391 : "r" (Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700392 );
393}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000394
efdesign98229f7cb2011-07-13 16:43:39 -0700395static __inline__ __attribute__((always_inline)) void __writecr3(unsigned long Data)
396{
397 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100398 "mov %0, %%cr3"
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000399 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100400 : "r" (Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700401 );
402}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000403
efdesign98229f7cb2011-07-13 16:43:39 -0700404static __inline__ __attribute__((always_inline)) void __writecr4(unsigned long Data)
405{
406 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100407 "mov %0, %%cr4"
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000408 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100409 : "r" (Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700410 );
411}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000412
efdesign98229f7cb2011-07-13 16:43:39 -0700413static __inline__ __attribute__((always_inline)) void __writecr8(unsigned long Data)
414{
415 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100416 "mov %0, %%cr8"
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000417 :
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100418 : "r" (Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700419 );
420}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000421
efdesign98229f7cb2011-07-13 16:43:39 -0700422static __inline__ __attribute__((always_inline)) void __writecr(unsigned long reg, unsigned long Data)
423{
424 switch (reg){
425 case 0:
426 __writecr0 (Data);
427 break;
428
429 case 2:
430 __writecr2 (Data);
431 break;
432
433 case 3:
434 __writecr3 (Data);
435 break;
436
437 case 4:
438 __writecr4 (Data);
439 break;
440
441 case 8:
442 __writecr8 (Data);
443 break;
444
445 default:
446 ;
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000447 }
efdesign98229f7cb2011-07-13 16:43:39 -0700448}
449
450static __inline__ __attribute__((always_inline)) UINT64 __readmsr(UINT32 msr)
451{
452 UINT64 retval;
453 __asm__ __volatile__(
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100454 "rdmsr"
efdesign98229f7cb2011-07-13 16:43:39 -0700455 : "=A" (retval)
456 : "c" (msr)
457 );
458 return retval;
459}
460
461static __inline__ __attribute__((always_inline)) void __writemsr (UINT32 msr, UINT64 Value)
462{
463 __asm__ __volatile__ (
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100464 "wrmsr"
efdesign98229f7cb2011-07-13 16:43:39 -0700465 :
466 : "c" (msr), "A" (Value)
467 );
468}
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000469
Stefan Reinauerc02b5e22017-06-25 03:39:18 +0200470#if !defined(__clang__)
efdesign98229f7cb2011-07-13 16:43:39 -0700471static __inline__ __attribute__((always_inline)) UINT64 __rdtsc(void)
472{
473 UINT64 retval;
474 __asm__ __volatile__ (
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000475 "rdtsc"
efdesign98229f7cb2011-07-13 16:43:39 -0700476 : "=A" (retval));
477 return retval;
478}
Stefan Reinauerc02b5e22017-06-25 03:39:18 +0200479#endif
efdesign98229f7cb2011-07-13 16:43:39 -0700480
481static __inline__ __attribute__((always_inline)) void __cpuid(int CPUInfo[], const int InfoType)
482{
483 __asm__ __volatile__(
Edward O'Callaghane1845b32014-05-20 04:36:41 +1000484 "cpuid"
485 :"=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
efdesign98229f7cb2011-07-13 16:43:39 -0700486 : "a" (InfoType)
487 );
488}
489
490
491static __inline__ __attribute__((always_inline)) void _disable(void)
492{
493 __asm__ __volatile__ ("cli");
494}
495
496
497static __inline__ __attribute__((always_inline)) void _enable(void)
498{
499 __asm__ __volatile__ ("sti");
500}
501
502
503static __inline__ __attribute__((always_inline)) void __halt(void)
504{
505 __asm__ __volatile__ ("hlt");
506}
507
508
509static __inline__ __attribute__((always_inline)) void __debugbreak(void)
510{
511 __asm__ __volatile__ ("int3");
512}
513
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100514static __inline__ __attribute__((always_inline)) void __invd(void)
515{
516 __asm__ __volatile__ ("invd");
517}
efdesign98229f7cb2011-07-13 16:43:39 -0700518
519static __inline__ __attribute__((always_inline)) void __wbinvd(void)
520{
521 __asm__ __volatile__ ("wbinvd");
522}
523
efdesign98229f7cb2011-07-13 16:43:39 -0700524static __inline__ __attribute__((always_inline)) void __lidt(void *Source)
525{
526 __asm__ __volatile__("lidt %0" : : "m"(*(short*)Source));
527}
528
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100529static __inline__ __attribute__((always_inline)) void
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700530__writefsbyte(const unsigned long Offset, const uint8_t Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700531{
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100532 __asm__ ("movb %[Data], %%fs:%a[Offset]"
533 :
534 : [Offset] "ir" (Offset), [Data] "iq" (Data));
efdesign98229f7cb2011-07-13 16:43:39 -0700535}
536
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100537static __inline__ __attribute__((always_inline)) void
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700538__writefsword(const unsigned long Offset, const uint16_t Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700539{
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100540 __asm__ ("movw %[Data], %%fs:%a[Offset]"
541 :
542 : [Offset] "ir" (Offset), [Data] "ir" (Data));
efdesign98229f7cb2011-07-13 16:43:39 -0700543}
544
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100545static __inline__ __attribute__((always_inline)) void
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700546__writefsdword(const unsigned long Offset, const uint32_t Data)
efdesign98229f7cb2011-07-13 16:43:39 -0700547{
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100548 __asm__ ("movl %[Data], %%fs:%a[Offset]"
549 :
550 : [Offset] "ir" (Offset), [Data] "ir" (Data));
efdesign98229f7cb2011-07-13 16:43:39 -0700551}
552
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700553static __inline__ __attribute__((always_inline)) uint8_t
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100554__readfsbyte(const unsigned long Offset)
efdesign98229f7cb2011-07-13 16:43:39 -0700555{
556 unsigned char value;
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100557 __asm__ ("movb %%fs:%a[Offset], %[value]"
558 : [value] "=q" (value)
559 : [Offset] "ir" (Offset));
efdesign98229f7cb2011-07-13 16:43:39 -0700560 return value;
561}
562
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700563static __inline__ __attribute__((always_inline)) uint16_t
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100564__readfsword(const unsigned long Offset)
efdesign98229f7cb2011-07-13 16:43:39 -0700565{
566 unsigned short value;
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100567 __asm__ ("movw %%fs:%a[Offset], %[value]"
568 : [value] "=q" (value)
569 : [Offset] "ir" (Offset));
efdesign98229f7cb2011-07-13 16:43:39 -0700570 return value;
571}
572
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700573static __inline__ __attribute__((always_inline)) uint32_t
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100574__readfsdword(unsigned long Offset)
efdesign98229f7cb2011-07-13 16:43:39 -0700575{
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100576 unsigned long value;
Stefan Reinauerd91ddc82015-07-30 11:17:40 -0700577 __asm__ ("mov %%fs:%a[Offset], %[value]"
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100578 : [value] "=r" (value)
579 : [Offset] "ir" (Offset));
efdesign98229f7cb2011-07-13 16:43:39 -0700580 return value;
581}
582
583#ifdef __SSE3__
Stefan Reinauer6a001132017-07-13 02:20:27 +0200584typedef long long __v2di __attribute__((__vector_size__ (16)));
585typedef long long __m128i __attribute__((__vector_size__ (16), __may_alias__));
efdesign98229f7cb2011-07-13 16:43:39 -0700586
587static __inline__ __attribute__((always_inline)) void _mm_stream_si128_fs2 (void *__A, __m128i __B)
588{
589 __asm__(".byte 0x64"); // fs prefix
Stefan Reinauerc02b5e22017-06-25 03:39:18 +0200590#if defined(__clang__)
591 __builtin_nontemporal_store((__v2di)__B, (__v2di *)__A);
592#else
efdesign98229f7cb2011-07-13 16:43:39 -0700593 __builtin_ia32_movntdq ((__v2di *)__A, (__v2di)__B);
Stefan Reinauerc02b5e22017-06-25 03:39:18 +0200594#endif
efdesign98229f7cb2011-07-13 16:43:39 -0700595}
596
597static __inline__ __attribute__((always_inline)) void _mm_stream_si128_fs (void *__A, void *__B)
598{
599 __m128i data;
600 data = (__m128i) __builtin_ia32_lddqu ((char const *)__B);
601 _mm_stream_si128_fs2 (__A, data);
602}
603
604static __inline__ __attribute__((always_inline)) void _mm_clflush_fs (void *__A)
605{
606 __asm__(".byte 0x64"); // fs prefix
607 __builtin_ia32_clflush (__A);
608}
609
Stefan Reinauerc02b5e22017-06-25 03:39:18 +0200610#if !defined(__clang__)
efdesign98229f7cb2011-07-13 16:43:39 -0700611static __inline __attribute__(( __always_inline__)) void _mm_mfence (void)
612{
613 __builtin_ia32_mfence ();
614}
Stefan Reinauerc02b5e22017-06-25 03:39:18 +0200615#else
616void _mm_mfence(void);
617#endif
efdesign98229f7cb2011-07-13 16:43:39 -0700618
Stefan Reinauerc02b5e22017-06-25 03:39:18 +0200619#if !defined(__clang__)
efdesign98229f7cb2011-07-13 16:43:39 -0700620static __inline __attribute__(( __always_inline__)) void _mm_sfence (void)
621{
622 __builtin_ia32_sfence ();
623}
Stefan Reinauerc02b5e22017-06-25 03:39:18 +0200624#else
625void _mm_sfence(void);
626#endif
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100627#endif /* __SSE3__ */
efdesign98229f7cb2011-07-13 16:43:39 -0700628
Edward O'Callaghan913e27e2014-11-01 05:35:18 +1100629#endif /* defined (__GNUC__) */