2007-08-31 19:55:27 +00:00
|
|
|
// Routines to let C code use special x86 instructions.
|
2006-09-07 14:12:30 +00:00
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline uchar
|
2007-08-20 18:55:51 +00:00
|
|
|
inb(ushort port)
|
2006-06-12 15:22:12 +00:00
|
|
|
{
|
2006-09-06 17:04:06 +00:00
|
|
|
uchar data;
|
2007-08-27 12:48:20 +00:00
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
asm volatile("in %1,%0" : "=a" (data) : "d" (port));
|
2006-09-06 17:04:06 +00:00
|
|
|
return data;
|
2006-06-12 15:22:12 +00:00
|
|
|
}
|
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline void
|
2006-06-12 15:22:12 +00:00
|
|
|
insl(int port, void *addr, int cnt)
|
|
|
|
{
|
2009-03-08 21:27:57 +00:00
|
|
|
asm volatile("cld; rep insl" :
|
2009-03-08 20:56:38 +00:00
|
|
|
"=D" (addr), "=c" (cnt) :
|
|
|
|
"d" (port), "0" (addr), "1" (cnt) :
|
|
|
|
"memory", "cc");
|
2006-06-12 15:22:12 +00:00
|
|
|
}
|
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline void
|
2007-08-20 18:55:51 +00:00
|
|
|
outb(ushort port, uchar data)
|
2006-06-12 15:22:12 +00:00
|
|
|
{
|
2007-08-24 00:34:54 +00:00
|
|
|
asm volatile("out %0,%1" : : "a" (data), "d" (port));
|
2006-06-12 15:22:12 +00:00
|
|
|
}
|
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline void
|
2007-08-20 18:55:51 +00:00
|
|
|
outw(ushort port, ushort data)
|
2006-06-12 15:22:12 +00:00
|
|
|
{
|
2007-08-24 00:34:54 +00:00
|
|
|
asm volatile("out %0,%1" : : "a" (data), "d" (port));
|
2006-06-12 15:22:12 +00:00
|
|
|
}
|
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline void
|
2006-06-12 15:22:12 +00:00
|
|
|
outsl(int port, const void *addr, int cnt)
|
|
|
|
{
|
2009-03-08 21:27:57 +00:00
|
|
|
asm volatile("cld; rep outsl" :
|
2009-03-08 20:56:38 +00:00
|
|
|
"=S" (addr), "=c" (cnt) :
|
|
|
|
"d" (port), "0" (addr), "1" (cnt) :
|
|
|
|
"cc");
|
2006-06-12 15:22:12 +00:00
|
|
|
}
|
|
|
|
|
2009-03-08 21:27:57 +00:00
|
|
|
static inline void
|
|
|
|
stosb(void *addr, int data, int cnt)
|
|
|
|
{
|
|
|
|
asm volatile("cld; rep stosb" :
|
|
|
|
"=D" (addr), "=c" (cnt) :
|
|
|
|
"0" (addr), "1" (cnt), "a" (data) :
|
|
|
|
"memory", "cc");
|
|
|
|
}
|
|
|
|
|
2006-08-29 14:45:45 +00:00
|
|
|
struct segdesc;
|
2006-06-12 15:22:12 +00:00
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline void
|
2006-07-17 01:58:13 +00:00
|
|
|
lgdt(struct segdesc *p, int size)
|
2006-06-12 15:22:12 +00:00
|
|
|
{
|
2006-09-06 17:04:06 +00:00
|
|
|
volatile ushort pd[3];
|
2006-09-06 17:27:19 +00:00
|
|
|
|
2006-09-06 17:04:06 +00:00
|
|
|
pd[0] = size-1;
|
|
|
|
pd[1] = (uint)p;
|
|
|
|
pd[2] = (uint)p >> 16;
|
2006-07-16 16:55:52 +00:00
|
|
|
|
2007-08-24 00:02:03 +00:00
|
|
|
asm volatile("lgdt (%0)" : : "r" (pd));
|
2006-07-16 16:55:52 +00:00
|
|
|
}
|
|
|
|
|
2006-08-29 14:45:45 +00:00
|
|
|
struct gatedesc;
|
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline void
|
2006-07-17 01:58:13 +00:00
|
|
|
lidt(struct gatedesc *p, int size)
|
2006-07-16 16:55:52 +00:00
|
|
|
{
|
2006-09-06 17:04:06 +00:00
|
|
|
volatile ushort pd[3];
|
2006-09-06 17:27:19 +00:00
|
|
|
|
2006-09-06 17:04:06 +00:00
|
|
|
pd[0] = size-1;
|
|
|
|
pd[1] = (uint)p;
|
|
|
|
pd[2] = (uint)p >> 16;
|
2006-09-06 17:27:19 +00:00
|
|
|
|
2007-08-24 00:02:03 +00:00
|
|
|
asm volatile("lidt (%0)" : : "r" (pd));
|
2006-06-12 15:22:12 +00:00
|
|
|
}
|
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline void
|
2006-07-20 09:07:53 +00:00
|
|
|
ltr(ushort sel)
|
2006-06-12 15:22:12 +00:00
|
|
|
{
|
2007-08-24 00:34:54 +00:00
|
|
|
asm volatile("ltr %0" : : "r" (sel));
|
2006-06-12 15:22:12 +00:00
|
|
|
}
|
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline uint
|
2009-03-08 22:07:13 +00:00
|
|
|
readeflags(void)
|
2006-06-12 15:22:12 +00:00
|
|
|
{
|
2006-09-06 17:04:06 +00:00
|
|
|
uint eflags;
|
2007-08-24 00:34:54 +00:00
|
|
|
asm volatile("pushfl; popl %0" : "=r" (eflags));
|
2006-09-06 17:04:06 +00:00
|
|
|
return eflags;
|
2006-06-12 15:22:12 +00:00
|
|
|
}
|
|
|
|
|
2009-05-31 00:28:45 +00:00
|
|
|
static inline void
|
2009-09-02 17:09:34 +00:00
|
|
|
loadgs(ushort v)
|
2009-05-31 00:28:45 +00:00
|
|
|
{
|
2009-05-31 01:12:08 +00:00
|
|
|
asm volatile("movw %0, %%gs" : : "r" (v));
|
2009-05-31 00:28:45 +00:00
|
|
|
}
|
|
|
|
|
2011-07-29 11:31:27 +00:00
|
|
|
static inline void
|
|
|
|
loadfs(ushort v)
|
|
|
|
{
|
|
|
|
__asm volatile("movw %0, %%fs" : : "r" (v));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
loades(ushort v)
|
|
|
|
{
|
|
|
|
__asm volatile("movw %0, %%es" : : "r" (v));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
loadds(ushort v)
|
|
|
|
{
|
|
|
|
__asm volatile("movw %0, %%ds" : : "r" (v));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
loadss(ushort v)
|
|
|
|
{
|
|
|
|
__asm volatile("movw %0, %%ss" : : "r" (v));
|
|
|
|
}
|
|
|
|
|
2010-08-31 21:07:54 +00:00
|
|
|
static inline uint
|
|
|
|
rebp(void)
|
2010-08-31 20:42:05 +00:00
|
|
|
{
|
|
|
|
uint val;
|
|
|
|
asm volatile("movl %%ebp,%0" : "=r" (val));
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2010-08-31 21:07:54 +00:00
|
|
|
static inline uint
|
|
|
|
resp(void)
|
2010-08-31 20:42:05 +00:00
|
|
|
{
|
|
|
|
uint val;
|
|
|
|
asm volatile("movl %%esp,%0" : "=r" (val));
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline void
|
2006-07-16 01:15:28 +00:00
|
|
|
cli(void)
|
|
|
|
{
|
2007-08-24 00:34:54 +00:00
|
|
|
asm volatile("cli");
|
2006-07-16 01:15:28 +00:00
|
|
|
}
|
|
|
|
|
2007-08-24 00:34:54 +00:00
|
|
|
static inline void
|
2006-07-16 01:15:28 +00:00
|
|
|
sti(void)
|
|
|
|
{
|
2007-08-24 00:34:54 +00:00
|
|
|
asm volatile("sti");
|
2006-07-16 01:15:28 +00:00
|
|
|
}
|
|
|
|
|
2010-08-31 20:42:05 +00:00
|
|
|
static inline uint
|
|
|
|
xchg(volatile uint *addr, uint newval)
|
|
|
|
{
|
|
|
|
uint result;
|
|
|
|
|
|
|
|
// The + in "+m" denotes a read-modify-write operand.
|
|
|
|
asm volatile("lock; xchgl %0, %1" :
|
|
|
|
"+m" (*addr), "=a" (result) :
|
|
|
|
"1" (newval) :
|
|
|
|
"cc");
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-08-31 21:07:54 +00:00
|
|
|
//PAGEBREAK!
|
2010-08-31 20:43:41 +00:00
|
|
|
static inline void
|
|
|
|
lcr0(uint val)
|
2010-07-02 18:51:53 +00:00
|
|
|
{
|
|
|
|
asm volatile("movl %0,%%cr0" : : "r" (val));
|
|
|
|
}
|
|
|
|
|
2010-08-31 20:43:41 +00:00
|
|
|
static inline uint
|
|
|
|
rcr0(void)
|
2010-07-02 18:51:53 +00:00
|
|
|
{
|
|
|
|
uint val;
|
|
|
|
asm volatile("movl %%cr0,%0" : "=r" (val));
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2010-08-31 20:43:41 +00:00
|
|
|
static inline uint
|
|
|
|
rcr2(void)
|
2010-07-02 18:51:53 +00:00
|
|
|
{
|
|
|
|
uint val;
|
|
|
|
asm volatile("movl %%cr2,%0" : "=r" (val));
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2010-08-31 20:43:41 +00:00
|
|
|
static inline void
|
|
|
|
lcr3(uint val)
|
2010-07-02 18:51:53 +00:00
|
|
|
{
|
|
|
|
asm volatile("movl %0,%%cr3" : : "r" (val));
|
|
|
|
}
|
|
|
|
|
2010-08-31 20:43:41 +00:00
|
|
|
static inline uint
|
|
|
|
rcr3(void)
|
2010-07-02 18:51:53 +00:00
|
|
|
{
|
|
|
|
uint val;
|
|
|
|
asm volatile("movl %%cr3,%0" : "=r" (val));
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2009-08-08 08:07:30 +00:00
|
|
|
//PAGEBREAK: 36
|
2007-08-31 19:55:27 +00:00
|
|
|
// Layout of the trap frame built on the stack by the
|
|
|
|
// hardware and by trapasm.S, and passed to trap().
|
2006-07-17 01:58:13 +00:00
|
|
|
struct trapframe {
|
2006-09-06 17:50:20 +00:00
|
|
|
// registers as pushed by pusha
|
2006-09-06 17:04:06 +00:00
|
|
|
uint edi;
|
|
|
|
uint esi;
|
|
|
|
uint ebp;
|
2006-09-06 17:50:20 +00:00
|
|
|
uint oesp; // useless & ignored
|
2006-09-06 17:04:06 +00:00
|
|
|
uint ebx;
|
|
|
|
uint edx;
|
|
|
|
uint ecx;
|
|
|
|
uint eax;
|
2006-09-06 17:50:20 +00:00
|
|
|
|
|
|
|
// rest of trap frame
|
2008-09-24 01:48:31 +00:00
|
|
|
ushort gs;
|
2006-09-06 17:04:06 +00:00
|
|
|
ushort padding1;
|
2008-09-24 01:48:31 +00:00
|
|
|
ushort fs;
|
2006-09-06 17:04:06 +00:00
|
|
|
ushort padding2;
|
2008-09-24 01:48:31 +00:00
|
|
|
ushort es;
|
|
|
|
ushort padding3;
|
|
|
|
ushort ds;
|
|
|
|
ushort padding4;
|
2006-09-06 17:04:06 +00:00
|
|
|
uint trapno;
|
2006-09-06 17:50:20 +00:00
|
|
|
|
|
|
|
// below here defined by x86 hardware
|
2006-09-06 17:04:06 +00:00
|
|
|
uint err;
|
|
|
|
uint eip;
|
|
|
|
ushort cs;
|
2008-09-24 01:48:31 +00:00
|
|
|
ushort padding5;
|
2006-09-06 17:04:06 +00:00
|
|
|
uint eflags;
|
2006-09-06 17:50:20 +00:00
|
|
|
|
|
|
|
// below here only when crossing rings, such as from user to kernel
|
2006-09-06 17:04:06 +00:00
|
|
|
uint esp;
|
|
|
|
ushort ss;
|
2008-09-24 01:48:31 +00:00
|
|
|
ushort padding6;
|
2006-06-12 15:22:12 +00:00
|
|
|
};
|