revert between 56095 -> 55830 in arch
[AROS.git] / arch / i386-all / include / asm / cpu.h
blob92d7681e4eab30bf2a092c9a80c61af8752ffcad
1 #ifndef ASM_I386_CPU_H
2 #define ASM_I386_CPU_H
4 /*
5 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
6 $Id$
8 Desc: assembler-level specific definitions for x86 CPU
9 Lang: english
12 #include <inttypes.h>
14 /* This file is very very incomplete :) */
16 #define HALT asm volatile("hlt")
18 /* Selector used for lgdt and lidt commands */
19 struct segment_selector
21 unsigned short size;
22 unsigned long base;
23 } __attribute__((packed));
25 struct int_gate_32bit {
26 uint16_t offset_low;
27 uint16_t selector;
28 unsigned ist:3, __pad0:5, type:5, dpl:2, p:1;
29 uint16_t offset_high;
30 } __attribute__((packed));
32 /* Segment descriptor in the GDT */
33 struct segment_desc
35 uint16_t limit_low;
36 uint16_t base_low;
37 uint8_t base_mid;
38 unsigned type:5, dpl:2, p:1;
39 unsigned limit_high:4, avl:1, l:1, d:1, g:1;
40 uint8_t base_high:8;
41 } __attribute__((packed));
44 * TaskStateStructure, defined only in matter of making life (setup)
45 * more human-readable
47 struct tss
49 unsigned int link, /* link to previous task */
50 ssp, /* Supervisor Stack Pointer */
51 ssp_seg, /* SSP descriptor */
52 t0,t1, /* Stack for CPL1 code */
53 t2,t3, /* Stack for CPL2 code */
54 cr3, /* used in paging */
55 eip, /* Instruction pointer */
56 eflags, /* Flags for given task */
57 r0,r1,r2,r3, /* 8 general purpouse registers */
58 r4,r5,r6,r7,
59 es,cs,ss,ds,fs,gs, /* segment descriptors */
60 ldt; /* LocalDescriptorTable */
61 unsigned short trap,iomap; /* trap flag and iomap pointer */
64 #define rdcr(reg) \
65 ({ long val; asm volatile("mov %%" #reg ",%0":"=r"(val)); val; })
67 #define wrcr(reg, val) \
68 do { asm volatile("mov %0,%%" #reg::"r"(val)); } while(0)
70 static inline void __attribute__((always_inline)) rdmsr(uint32_t msr_no, uint32_t *ret_lo, uint32_t *ret_hi)
72 uint32_t ret1, ret2;
74 asm volatile("rdmsr":"=a"(ret1),"=d"(ret2):"c"(msr_no));
75 *ret_lo=ret1;
76 *ret_hi=ret2;
79 static inline uint32_t __attribute__((always_inline)) rdmsri(uint32_t msr_no)
81 uint32_t ret;
83 asm volatile("rdmsr":"=a"(ret):"c"(msr_no));
84 return ret;
88 Compare value stored at "addr" with "expected". If they are equal, function returns 1 and stores "xchg" value
89 at "addr". If *addr != expected, function returns 0. Either "expected" or current value at *addr are stored back
90 at *found. The operation is atomic
92 static inline int compare_and_exchange_long(uint32_t *addr, uint32_t expected, uint32_t xchg, uint32_t *found)
94 char flag;
95 uint32_t ret;
96 asm volatile("lock cmpxchg %4, %0; setz %1":"+m"(*addr),"=q"(flag),"=a"(ret):"2"(expected),"r"(xchg):"memory","cc");
97 if (found)
98 *found = ret;
99 return flag;
102 static inline int compare_and_exchange_short(uint16_t *lock, uint16_t expected, uint16_t xchg, uint16_t *found)
104 char flag;
105 uint16_t ret;
106 asm volatile("lock cmpxchg %4, %0; setz %1":"+m"(*lock),"=q"(flag),"=a"(ret):"2"(expected),"r"(xchg):"memory","cc");
107 if (found)
108 *found = ret;
109 return flag;
112 static inline int compare_and_exchange_byte(uint8_t *lock, uint8_t expected, uint8_t xchg, uint8_t *found)
114 char flag;
115 uint16_t ret;
116 asm volatile("lock cmpxchg %4, %0; setz %1":"+m"(*lock),"=q"(flag),"=a"(ret):"2"(expected),"q"(xchg):"memory","cc");
117 if (found)
118 *found = ret;
119 return flag;
122 static inline int bit_test_and_set_long(uint32_t *addr, int32_t bit)
124 char retval = 0;
125 asm volatile("lock btsl %2, %0; setc %1":"+m"(*addr),"=q"(retval):"Ir"(bit):"memory");
126 return retval;
129 static inline int bit_test_and_set_short(uint16_t *addr, int32_t bit)
131 char retval = 0;
132 asm volatile("lock btsw %2, %0; setc %1":"+m"(*addr),"=q"(retval):"Ir"(bit):"memory");
133 return retval;
136 static inline int bit_test_and_clear_long(uint32_t *addr, int32_t bit)
138 char retval = 0;
139 asm volatile("lock btrl %2, %0; setc %1":"+m"(*addr),"=q"(retval):"Ir"(bit):"memory");
140 return retval;
143 static inline int bit_test_and_clear_short(uint16_t *addr, int32_t bit)
145 char retval = 0;
146 asm volatile("lock btrw %2, %0; setc %1":"+m"(*addr),"=q"(retval):"Ir"(bit):"memory");
147 return retval;
150 static inline int bit_test_and_complement_long(uint32_t *addr, int32_t bit)
152 char retval = 0;
153 asm volatile("lock btcl %2, %0; setc %1":"+m"(*addr),"=q"(retval):"Ir"(bit):"memory");
154 return retval;
157 static inline int bit_test_and_complement_short(uint16_t *addr, int32_t bit)
159 char retval = 0;
160 asm volatile("lock btcw %2, %0; setc %1":"+m"(*addr),"=q"(retval):"Ir"(bit):"memory");
161 return retval;
164 #endif