xv6-cs450/x86.h

238 lines
3.8 KiB
C
Raw Normal View History

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