xref: /xv6-public/x86.h (revision 9e9bcaf1)
1 static __inline uchar
2 inb(int port)
3 {
4   uchar data;
5   __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
6   return data;
7 }
8 
9 static __inline void
10 insl(int port, void *addr, int cnt)
11 {
12   __asm __volatile("cld\n\trepne\n\tinsl"     :
13                    "=D" (addr), "=c" (cnt)    :
14                    "d" (port), "0" (addr), "1" (cnt)  :
15                    "memory", "cc");
16 }
17 
18 static __inline void
19 outb(int port, uchar data)
20 {
21   __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
22 }
23 
24 static __inline void
25 outw(int port, ushort data)
26 {
27   __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
28 }
29 
30 static __inline void
31 outsl(int port, const void *addr, int cnt)
32 {
33   __asm __volatile("cld\n\trepne\n\toutsl"    :
34                    "=S" (addr), "=c" (cnt)    :
35                    "d" (port), "0" (addr), "1" (cnt)  :
36                    "cc");
37 }
38 
39 struct segdesc;
40 
41 static __inline void
42 lgdt(struct segdesc *p, int size)
43 {
44   volatile ushort pd[3];
45 
46   pd[0] = size-1;
47   pd[1] = (uint)p;
48   pd[2] = (uint)p >> 16;
49 
50   asm volatile("lgdt (%0)" : : "g" (pd));
51 }
52 
53 struct gatedesc;
54 
55 static __inline void
56 lidt(struct gatedesc *p, int size)
57 {
58   volatile ushort pd[3];
59 
60   pd[0] = size-1;
61   pd[1] = (uint)p;
62   pd[2] = (uint)p >> 16;
63 
64   asm volatile("lidt (%0)" : : "g" (pd));
65 }
66 
67 static __inline void
68 ltr(ushort sel)
69 {
70   __asm __volatile("ltr %0" : : "r" (sel));
71 }
72 
73 static __inline uint
74 read_eflags(void)
75 {
76   uint eflags;
77   __asm __volatile("pushfl; popl %0" : "=r" (eflags));
78   return eflags;
79 }
80 
81 static __inline void
82 write_eflags(uint eflags)
83 {
84   __asm __volatile("pushl %0; popfl" : : "r" (eflags));
85 }
86 
87 static __inline void
88 cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp)
89 {
90   uint eax, ebx, ecx, edx;
91   asm volatile("cpuid" :
92                "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) :
93                "a" (info));
94   if(eaxp)
95     *eaxp = eax;
96   if(ebxp)
97     *ebxp = ebx;
98   if(ecxp)
99     *ecxp = ecx;
100   if(edxp)
101     *edxp = edx;
102 }
103 
104 static __inline uint
105 cmpxchg(uint oldval, uint newval, volatile uint* lock_addr)
106 {
107   uint result;
108   __asm__ __volatile__("lock; cmpxchgl %2, %0" :
109                        "+m" (*lock_addr), "=a" (result) :
110                        "r"(newval), "1"(oldval) :
111                        "cc");
112   return result;
113 }
114 
115 static __inline void
116 cli(void)
117 {
118   __asm__ volatile("cli");
119 }
120 
121 static __inline void
122 sti(void)
123 {
124   __asm__ volatile("sti");
125 }
126 
127 struct trapframe {
128   /* registers as pushed by pusha */
129   uint edi;
130   uint esi;
131   uint ebp;
132   uint oesp;      /* Useless */
133   uint ebx;
134   uint edx;
135   uint ecx;
136   uint eax;
137   /* rest of trap frame */
138   ushort es;
139   ushort padding1;
140   ushort ds;
141   ushort padding2;
142   uint trapno;
143   /* below here defined by x86 hardware */
144   uint err;
145   uint eip;
146   ushort cs;
147   ushort padding3;
148   uint eflags;
149   /* below here only when crossing rings, such as from user to kernel */
150   uint esp;
151   ushort ss;
152   ushort padding4;
153 };
154