clean up stale error checks and panics
delete unused functions a few comments
This commit is contained in:
parent
b52151e032
commit
2b19190c13
44
Notes
44
Notes
|
@ -95,49 +95,15 @@ inode->count counts in-memory pointers to the struct
|
||||||
blocks and inodes have ad-hoc sleep-locks
|
blocks and inodes have ad-hoc sleep-locks
|
||||||
provide a single mechanism?
|
provide a single mechanism?
|
||||||
|
|
||||||
test 14-character file names
|
|
||||||
and file arguments longer than 14
|
|
||||||
|
|
||||||
kalloc() can return 0; do callers handle this right?
|
kalloc() can return 0; do callers handle this right?
|
||||||
|
|
||||||
OH! recursive interrupts will use up any amount of cpu[].stack!
|
|
||||||
underflow and wrecks *previous* cpu's struct
|
|
||||||
|
|
||||||
disk scheduling
|
|
||||||
mkdir
|
|
||||||
sh arguments
|
|
||||||
sh redirection
|
|
||||||
indirect blocks
|
|
||||||
is there a create/create race for same file name?
|
|
||||||
resulting in two entries w/ same name in directory?
|
|
||||||
why does shell often ignore first line of input?
|
|
||||||
|
|
||||||
test: one process unlinks a file while another links to it
|
test: one process unlinks a file while another links to it
|
||||||
test: one process opens a file while another deletes it
|
test: one process opens a file while another deletes it
|
||||||
test: mkdir. deadlock d/.. vs ../d, two processes.
|
test: deadlock d/.. vs ../d, two processes.
|
||||||
test: dup() shared fd->off
|
test: dup() shared fd->off
|
||||||
test: sbrk
|
test: sbrk
|
||||||
test: does echo foo > x truncate x?
|
test: does echo foo > x truncate x?
|
||||||
|
|
||||||
make proc[0] runnable
|
|
||||||
cpu early tss and gdt
|
|
||||||
how do we get cpu0 scheduler() to use mpstack, not proc[0].kstack?
|
|
||||||
when iget() first sleeps, where does it longjmp to?
|
|
||||||
maybe set up proc[0] to be runnable, with entry proc0main(), then
|
|
||||||
have main() call scheduler()?
|
|
||||||
perhaps so proc[0] uses right kstack?
|
|
||||||
and scheduler() uses mpstack?
|
|
||||||
ltr sets the busy bit in the TSS, faults if already set
|
|
||||||
so gdt and TSS per cpu?
|
|
||||||
we don't want to be using some random process's gdt when it changes it.
|
|
||||||
maybe get rid of per-proc gdt and ts
|
|
||||||
one per cpu
|
|
||||||
refresh it when needed
|
|
||||||
setupsegs(proc *)
|
|
||||||
|
|
||||||
why do we get 0 characters from keyboard?
|
|
||||||
are the locks in the right place in keyboardintr?
|
|
||||||
|
|
||||||
sh: support pipes? leave it for the class?
|
sh: support pipes? leave it for the class?
|
||||||
sh: dynamic memory allocation?
|
sh: dynamic memory allocation?
|
||||||
sh: should sh support ; () & --- need malloc
|
sh: should sh support ; () & --- need malloc
|
||||||
|
@ -146,3 +112,11 @@ sh: stop stdin on ctrl-d (for cat > y)
|
||||||
really should have bdwrite() for file content
|
really should have bdwrite() for file content
|
||||||
and make some inode updates async
|
and make some inode updates async
|
||||||
so soft updates make sense
|
so soft updates make sense
|
||||||
|
|
||||||
|
disk scheduling
|
||||||
|
echo foo > bar should truncate bar
|
||||||
|
so O_CREATE should not truncate
|
||||||
|
but O_TRUNC should
|
||||||
|
|
||||||
|
make it work on one cpu
|
||||||
|
make it work on amsterdam
|
||||||
|
|
|
@ -9,10 +9,6 @@ struct spinlock console_lock;
|
||||||
int panicked = 0;
|
int panicked = 0;
|
||||||
int use_console_lock = 0;
|
int use_console_lock = 0;
|
||||||
|
|
||||||
// per-cpu copy of output to help panic/lock debugging
|
|
||||||
char obuf[NCPU][1024];
|
|
||||||
uint obufi[NCPU];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* copy console output to parallel port, which you can tell
|
* copy console output to parallel port, which you can tell
|
||||||
* .bochsrc to copy to the stdout:
|
* .bochsrc to copy to the stdout:
|
||||||
|
@ -37,10 +33,6 @@ cons_putc(int c)
|
||||||
ushort *crt = (ushort *) 0xB8000; // base of CGA memory
|
ushort *crt = (ushort *) 0xB8000; // base of CGA memory
|
||||||
int ind;
|
int ind;
|
||||||
|
|
||||||
obuf[rcr4()][obufi[rcr4()]++] = c;
|
|
||||||
if(obufi[rcr4()] >= 1024)
|
|
||||||
obufi[rcr4()] = 0;
|
|
||||||
|
|
||||||
if(panicked){
|
if(panicked){
|
||||||
cli();
|
cli();
|
||||||
for(;;)
|
for(;;)
|
||||||
|
|
2
defs.h
2
defs.h
|
@ -16,7 +16,7 @@ struct jmpbuf;
|
||||||
void setupsegs(struct proc *);
|
void setupsegs(struct proc *);
|
||||||
struct proc * copyproc(struct proc*);
|
struct proc * copyproc(struct proc*);
|
||||||
struct spinlock;
|
struct spinlock;
|
||||||
char *growproc(int);
|
int growproc(int);
|
||||||
void sleep(void *, struct spinlock *);
|
void sleep(void *, struct spinlock *);
|
||||||
void wakeup(void *);
|
void wakeup(void *);
|
||||||
void scheduler(void);
|
void scheduler(void);
|
||||||
|
|
4
main.c
4
main.c
|
@ -25,8 +25,6 @@ main0(void)
|
||||||
int i;
|
int i;
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
|
||||||
lcr4(0); // xxx copy of cpu #
|
|
||||||
|
|
||||||
// clear BSS
|
// clear BSS
|
||||||
memset(edata, 0, end - edata);
|
memset(edata, 0, end - edata);
|
||||||
|
|
||||||
|
@ -97,8 +95,6 @@ main0(void)
|
||||||
void
|
void
|
||||||
mpmain(void)
|
mpmain(void)
|
||||||
{
|
{
|
||||||
lcr4(1); // xxx copy of cpu #
|
|
||||||
|
|
||||||
cprintf("cpu%d: starting\n", cpu());
|
cprintf("cpu%d: starting\n", cpu());
|
||||||
idtinit(); // CPU's idt
|
idtinit(); // CPU's idt
|
||||||
if(cpu() == 0)
|
if(cpu() == 0)
|
||||||
|
|
20
param.h
20
param.h
|
@ -1,10 +1,10 @@
|
||||||
#define NPROC 64
|
#define NPROC 64 // maximum number of processes
|
||||||
#define PAGE 4096
|
#define PAGE 4096 // granularity of user-space memory allocation
|
||||||
#define KSTACKSIZE PAGE
|
#define KSTACKSIZE PAGE // size of per-process kernel stack
|
||||||
#define NCPU 8
|
#define NCPU 8 // maximum number of CPUs
|
||||||
#define NOFILE 16 // file descriptors per process
|
#define NOFILE 16 // file descriptors per process
|
||||||
#define NFD 100 // file descriptors per system
|
#define NFD 100 // file descriptors per system
|
||||||
#define NREQUEST 100 // outstanding disk requests
|
#define NREQUEST 100 // outstanding disk requests
|
||||||
#define NBUF 10
|
#define NBUF 10 // size of disk block cache
|
||||||
#define NINODE 100
|
#define NINODE 100 // maximum number of active i-nodes
|
||||||
#define NDEV 10
|
#define NDEV 10 // maximum major device number
|
||||||
|
|
8
proc.c
8
proc.c
|
@ -138,22 +138,22 @@ copyproc(struct proc* p)
|
||||||
return np;
|
return np;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
int
|
||||||
growproc(int n)
|
growproc(int n)
|
||||||
{
|
{
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
char *newmem, *oldmem;
|
char *newmem, *oldmem;
|
||||||
|
|
||||||
newmem = kalloc(cp->sz + n);
|
newmem = kalloc(cp->sz + n);
|
||||||
if(newmem == 0) return (char *) -1;
|
if(newmem == 0)
|
||||||
|
return -1;
|
||||||
memmove(newmem, cp->mem, cp->sz);
|
memmove(newmem, cp->mem, cp->sz);
|
||||||
memset(newmem + cp->sz, 0, n);
|
memset(newmem + cp->sz, 0, n);
|
||||||
oldmem = cp->mem;
|
oldmem = cp->mem;
|
||||||
cp->mem = newmem;
|
cp->mem = newmem;
|
||||||
kfree(oldmem, cp->sz);
|
kfree(oldmem, cp->sz);
|
||||||
cprintf("growproc: added %d bytes to %d bytes\n", n, cp->sz);
|
|
||||||
cp->sz += n;
|
cp->sz += n;
|
||||||
return cp->sz - n;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per-CPU process scheduler.
|
// Per-CPU process scheduler.
|
||||||
|
|
43
spinlock.c
43
spinlock.c
|
@ -6,18 +6,11 @@
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
#include "spinlock.h"
|
#include "spinlock.h"
|
||||||
|
|
||||||
// Can't call cprintf from inside these routines,
|
|
||||||
// because cprintf uses them itself.
|
|
||||||
//#define cprintf dont_use_cprintf
|
|
||||||
|
|
||||||
#define LOCKMAGIC 0x6673ffea
|
|
||||||
|
|
||||||
extern int use_console_lock;
|
extern int use_console_lock;
|
||||||
|
|
||||||
void
|
void
|
||||||
initlock(struct spinlock *lock, char *name)
|
initlock(struct spinlock *lock, char *name)
|
||||||
{
|
{
|
||||||
lock->magic = LOCKMAGIC;
|
|
||||||
lock->name = name;
|
lock->name = name;
|
||||||
lock->locked = 0;
|
lock->locked = 0;
|
||||||
lock->cpu = 0xffffffff;
|
lock->cpu = 0xffffffff;
|
||||||
|
@ -38,8 +31,6 @@ getcallerpcs(void *v, uint pcs[])
|
||||||
void
|
void
|
||||||
acquire(struct spinlock * lock)
|
acquire(struct spinlock * lock)
|
||||||
{
|
{
|
||||||
if(lock->magic != LOCKMAGIC)
|
|
||||||
panic("weird lock magic");
|
|
||||||
if(holding(lock))
|
if(holding(lock))
|
||||||
panic("acquire");
|
panic("acquire");
|
||||||
|
|
||||||
|
@ -47,34 +38,32 @@ acquire(struct spinlock * lock)
|
||||||
cli();
|
cli();
|
||||||
cpus[cpu()].nlock++;
|
cpus[cpu()].nlock++;
|
||||||
|
|
||||||
while(cmpxchg(0, 1, &lock->locked) == 1)
|
while(cmpxchg(0, 1, &lock->locked) == 1)
|
||||||
;
|
;
|
||||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||||
getcallerpcs(&lock, lock->pcs);
|
getcallerpcs(&lock, lock->pcs);
|
||||||
lock->cpu = cpu() + 10;
|
lock->cpu = cpu() + 10;
|
||||||
cpus[cpu()].lastacquire = lock;
|
cpus[cpu()].lastacquire = lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
release(struct spinlock * lock)
|
release(struct spinlock * lock)
|
||||||
{
|
{
|
||||||
if(lock->magic != LOCKMAGIC)
|
|
||||||
panic("weird lock magic");
|
|
||||||
|
|
||||||
if(!holding(lock))
|
if(!holding(lock))
|
||||||
panic("release");
|
panic("release");
|
||||||
|
|
||||||
cpus[cpu()].lastrelease = lock;
|
cpus[cpu()].lastrelease = lock;
|
||||||
lock->pcs[0] = 0;
|
lock->pcs[0] = 0;
|
||||||
lock->cpu = 0xffffffff;
|
lock->cpu = 0xffffffff;
|
||||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||||
lock->locked = 0;
|
lock->locked = 0;
|
||||||
if(--cpus[cpu()].nlock == 0)
|
if(--cpus[cpu()].nlock == 0)
|
||||||
sti();
|
sti();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
holding(struct spinlock *lock)
|
holding(struct spinlock *lock)
|
||||||
{
|
{
|
||||||
return lock->locked && lock->cpu == cpu() + 10;
|
return lock->locked && lock->cpu == cpu() + 10;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
struct spinlock {
|
struct spinlock {
|
||||||
uint magic;
|
|
||||||
char *name;
|
char *name;
|
||||||
uint locked;
|
uint locked;
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
|
@ -473,15 +473,15 @@ sys_getpid(void)
|
||||||
int
|
int
|
||||||
sys_sbrk(void)
|
sys_sbrk(void)
|
||||||
{
|
{
|
||||||
char *r;
|
|
||||||
int n;
|
int n;
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
|
|
||||||
if(fetcharg(0, &n) < 0)
|
if(fetcharg(0, &n) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
r = growproc(n);
|
if(growproc(n) != 0)
|
||||||
|
return -1;
|
||||||
setupsegs(cp);
|
setupsegs(cp);
|
||||||
return (int) r;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
45
trap.c
45
trap.c
|
@ -34,59 +34,19 @@ void
|
||||||
trap(struct trapframe *tf)
|
trap(struct trapframe *tf)
|
||||||
{
|
{
|
||||||
int v = tf->trapno;
|
int v = tf->trapno;
|
||||||
|
|
||||||
if(cpus[cpu()].nlock){
|
|
||||||
cprintf("trap v %d eip %x cpu %d nlock %d\n",
|
|
||||||
v, tf->eip, cpu(), cpus[cpu()].nlock);
|
|
||||||
panic("interrupt while holding a lock");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(curproc[cpu()] == 0){
|
|
||||||
if(&tf < cpus[cpu()].mpstack || &tf > cpus[cpu()].mpstack + MPSTACK){
|
|
||||||
cprintf("&tf %x mpstack %x\n", &tf, cpus[cpu()].mpstack);
|
|
||||||
panic("trap cpu stack");
|
|
||||||
}
|
|
||||||
} else if(curproc[cpu()]){
|
|
||||||
if(&tf < curproc[cpu()]->kstack){
|
|
||||||
panic("trap kstack");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(v == T_SYSCALL){
|
if(v == T_SYSCALL){
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
int num = cp->tf->eax;
|
int num = cp->tf->eax;
|
||||||
if((read_eflags() & FL_IF) == 0)
|
|
||||||
panic("syscall but interrupts now disabled");
|
|
||||||
if(cp == 0)
|
|
||||||
panic("syscall with no proc");
|
|
||||||
if(cp->killed)
|
if(cp->killed)
|
||||||
proc_exit();
|
proc_exit();
|
||||||
cp->tf = tf;
|
cp->tf = tf;
|
||||||
syscall();
|
syscall();
|
||||||
if(cp != curproc[cpu()])
|
|
||||||
panic("trap ret wrong curproc");
|
|
||||||
if(cp->state != RUNNING)
|
|
||||||
panic("trap ret but not RUNNING");
|
|
||||||
if(tf != cp->tf)
|
|
||||||
panic("trap ret wrong tf");
|
|
||||||
if(cpus[cpu()].nlock){
|
|
||||||
cprintf("num=%d\n", num);
|
|
||||||
panic("syscall returning locks held");
|
|
||||||
}
|
|
||||||
if((read_eflags() & FL_IF) == 0)
|
|
||||||
panic("syscall returning but FL_IF clear");
|
|
||||||
if(read_esp() < (uint)cp->kstack ||
|
|
||||||
read_esp() >= (uint)cp->kstack + KSTACKSIZE)
|
|
||||||
panic("trap ret esp wrong");
|
|
||||||
if(cp->killed)
|
if(cp->killed)
|
||||||
proc_exit();
|
proc_exit();
|
||||||
// XXX probably ought to lgdt on trap return
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if(read_eflags() & FL_IF)
|
|
||||||
//panic("interrupt but interrupts enabled");
|
|
||||||
|
|
||||||
if(v == (IRQ_OFFSET + IRQ_TIMER)){
|
if(v == (IRQ_OFFSET + IRQ_TIMER)){
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
lapic_timerintr();
|
lapic_timerintr();
|
||||||
|
@ -108,8 +68,6 @@ trap(struct trapframe *tf)
|
||||||
|
|
||||||
if(v == (IRQ_OFFSET + IRQ_IDE)){
|
if(v == (IRQ_OFFSET + IRQ_IDE)){
|
||||||
ide_intr();
|
ide_intr();
|
||||||
if(cpus[cpu()].nlock)
|
|
||||||
panic("ide_intr returned while holding a lock");
|
|
||||||
cli(); // prevent a waiting interrupt from overflowing stack
|
cli(); // prevent a waiting interrupt from overflowing stack
|
||||||
lapic_eoi();
|
lapic_eoi();
|
||||||
return;
|
return;
|
||||||
|
@ -117,9 +75,6 @@ trap(struct trapframe *tf)
|
||||||
|
|
||||||
if(v == (IRQ_OFFSET + IRQ_KBD)){
|
if(v == (IRQ_OFFSET + IRQ_KBD)){
|
||||||
kbd_intr();
|
kbd_intr();
|
||||||
if(cpus[cpu()].nlock){
|
|
||||||
panic("kbd_intr returned while holding a lock");
|
|
||||||
}
|
|
||||||
cli(); // prevent a waiting interrupt from overflowing stack
|
cli(); // prevent a waiting interrupt from overflowing stack
|
||||||
lapic_eoi();
|
lapic_eoi();
|
||||||
return;
|
return;
|
||||||
|
|
212
x86.h
212
x86.h
|
@ -1,45 +1,3 @@
|
||||||
static __inline void breakpoint(void) __attribute__((always_inline));
|
|
||||||
static __inline uchar inb(int port) __attribute__((always_inline));
|
|
||||||
static __inline void insb(int port, void *addr, int cnt) __attribute__((always_inline));
|
|
||||||
static __inline ushort inw(int port) __attribute__((always_inline));
|
|
||||||
static __inline void insw(int port, void *addr, int cnt) __attribute__((always_inline));
|
|
||||||
static __inline uint inl(int port) __attribute__((always_inline));
|
|
||||||
static __inline void insl(int port, void *addr, int cnt) __attribute__((always_inline));
|
|
||||||
static __inline void outb(int port, uchar data) __attribute__((always_inline));
|
|
||||||
static __inline void outsb(int port, const void *addr, int cnt) __attribute__((always_inline));
|
|
||||||
static __inline void outw(int port, ushort data) __attribute__((always_inline));
|
|
||||||
static __inline void outsw(int port, const void *addr, int cnt) __attribute__((always_inline));
|
|
||||||
static __inline void outsl(int port, const void *addr, int cnt) __attribute__((always_inline));
|
|
||||||
static __inline void outl(int port, uint data) __attribute__((always_inline));
|
|
||||||
static __inline void invlpg(void *addr) __attribute__((always_inline));
|
|
||||||
struct segdesc;
|
|
||||||
static __inline void lgdt(struct segdesc *p, int) __attribute__((always_inline));
|
|
||||||
struct gatedesc;
|
|
||||||
static __inline void lidt(struct gatedesc *p, int) __attribute__((always_inline));
|
|
||||||
static __inline void lldt(ushort sel) __attribute__((always_inline));
|
|
||||||
static __inline void ltr(ushort sel) __attribute__((always_inline));
|
|
||||||
static __inline void lcr0(uint val) __attribute__((always_inline));
|
|
||||||
static __inline uint rcr0(void) __attribute__((always_inline));
|
|
||||||
static __inline uint rcr2(void) __attribute__((always_inline));
|
|
||||||
static __inline void lcr3(uint val) __attribute__((always_inline));
|
|
||||||
static __inline uint rcr3(void) __attribute__((always_inline));
|
|
||||||
static __inline void lcr4(uint val) __attribute__((always_inline));
|
|
||||||
static __inline uint rcr4(void) __attribute__((always_inline));
|
|
||||||
static __inline void tlbflush(void) __attribute__((always_inline));
|
|
||||||
static __inline uint read_eflags(void) __attribute__((always_inline));
|
|
||||||
static __inline void write_eflags(uint eflags) __attribute__((always_inline));
|
|
||||||
static __inline uint read_ebp(void) __attribute__((always_inline));
|
|
||||||
static __inline uint read_esp(void) __attribute__((always_inline));
|
|
||||||
static __inline void cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp);
|
|
||||||
static __inline void cli(void) __attribute__((always_inline));
|
|
||||||
static __inline void sti(void) __attribute__((always_inline));
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
breakpoint(void)
|
|
||||||
{
|
|
||||||
__asm __volatile("int3");
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline uchar
|
static __inline uchar
|
||||||
inb(int port)
|
inb(int port)
|
||||||
{
|
{
|
||||||
|
@ -48,40 +6,6 @@ inb(int port)
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
|
||||||
insb(int port, void *addr, int cnt)
|
|
||||||
{
|
|
||||||
__asm __volatile("cld\n\trepne\n\tinsb" :
|
|
||||||
"=D" (addr), "=c" (cnt) :
|
|
||||||
"d" (port), "0" (addr), "1" (cnt) :
|
|
||||||
"memory", "cc");
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline ushort
|
|
||||||
inw(int port)
|
|
||||||
{
|
|
||||||
ushort data;
|
|
||||||
__asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
insw(int port, void *addr, int cnt)
|
|
||||||
{
|
|
||||||
__asm __volatile("cld\n\trepne\n\tinsw" :
|
|
||||||
"=D" (addr), "=c" (cnt) :
|
|
||||||
"d" (port), "0" (addr), "1" (cnt) :
|
|
||||||
"memory", "cc");
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline uint
|
|
||||||
inl(int port)
|
|
||||||
{
|
|
||||||
uint data;
|
|
||||||
__asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
insl(int port, void *addr, int cnt)
|
insl(int port, void *addr, int cnt)
|
||||||
{
|
{
|
||||||
|
@ -97,30 +21,12 @@ outb(int port, uchar data)
|
||||||
__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
|
__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
|
||||||
outsb(int port, const void *addr, int cnt)
|
|
||||||
{
|
|
||||||
__asm __volatile("cld\n\trepne\n\toutsb" :
|
|
||||||
"=S" (addr), "=c" (cnt) :
|
|
||||||
"d" (port), "0" (addr), "1" (cnt) :
|
|
||||||
"cc");
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
outw(int port, ushort data)
|
outw(int port, ushort data)
|
||||||
{
|
{
|
||||||
__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
|
__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
|
||||||
outsw(int port, const void *addr, int cnt)
|
|
||||||
{
|
|
||||||
__asm __volatile("cld\n\trepne\n\toutsw" :
|
|
||||||
"=S" (addr), "=c" (cnt) :
|
|
||||||
"d" (port), "0" (addr), "1" (cnt) :
|
|
||||||
"cc");
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
outsl(int port, const void *addr, int cnt)
|
outsl(int port, const void *addr, int cnt)
|
||||||
{
|
{
|
||||||
|
@ -130,17 +36,7 @@ outsl(int port, const void *addr, int cnt)
|
||||||
"cc");
|
"cc");
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
struct segdesc;
|
||||||
outl(int port, uint data)
|
|
||||||
{
|
|
||||||
__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
invlpg(void *addr)
|
|
||||||
{
|
|
||||||
__asm __volatile("invlpg (%0)" : : "r" (addr) : "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
lgdt(struct segdesc *p, int size)
|
lgdt(struct segdesc *p, int size)
|
||||||
|
@ -154,6 +50,8 @@ lgdt(struct segdesc *p, int size)
|
||||||
asm volatile("lgdt (%0)" : : "g" (pd));
|
asm volatile("lgdt (%0)" : : "g" (pd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct gatedesc;
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
lidt(struct gatedesc *p, int size)
|
lidt(struct gatedesc *p, int size)
|
||||||
{
|
{
|
||||||
|
@ -166,76 +64,12 @@ lidt(struct gatedesc *p, int size)
|
||||||
asm volatile("lidt (%0)" : : "g" (pd));
|
asm volatile("lidt (%0)" : : "g" (pd));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
|
||||||
lldt(ushort sel)
|
|
||||||
{
|
|
||||||
__asm __volatile("lldt %0" : : "r" (sel));
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
ltr(ushort sel)
|
ltr(ushort sel)
|
||||||
{
|
{
|
||||||
__asm __volatile("ltr %0" : : "r" (sel));
|
__asm __volatile("ltr %0" : : "r" (sel));
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
lcr4(uint val)
|
|
||||||
{
|
|
||||||
__asm __volatile("movl %0,%%cr4" : : "r" (val));
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline uint
|
|
||||||
rcr4(void)
|
|
||||||
{
|
|
||||||
uint cr4;
|
|
||||||
__asm __volatile("movl %%cr4,%0" : "=r" (cr4));
|
|
||||||
return cr4;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
tlbflush(void)
|
|
||||||
{
|
|
||||||
uint cr3;
|
|
||||||
__asm __volatile("movl %%cr3,%0" : "=r" (cr3));
|
|
||||||
__asm __volatile("movl %0,%%cr3" : : "r" (cr3));
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline uint
|
static __inline uint
|
||||||
read_eflags(void)
|
read_eflags(void)
|
||||||
{
|
{
|
||||||
|
@ -250,46 +84,6 @@ write_eflags(uint eflags)
|
||||||
__asm __volatile("pushl %0; popfl" : : "r" (eflags));
|
__asm __volatile("pushl %0; popfl" : : "r" (eflags));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline uint
|
|
||||||
read_ebp(void)
|
|
||||||
{
|
|
||||||
uint ebp;
|
|
||||||
__asm __volatile("movl %%ebp,%0" : "=r" (ebp));
|
|
||||||
return ebp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline uint
|
|
||||||
read_esp(void)
|
|
||||||
{
|
|
||||||
uint esp;
|
|
||||||
__asm __volatile("movl %%esp,%0" : "=r" (esp));
|
|
||||||
return esp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline uint
|
|
||||||
read_esi(void)
|
|
||||||
{
|
|
||||||
uint esi;
|
|
||||||
__asm __volatile("movl %%esi,%0" : "=r" (esi));
|
|
||||||
return esi;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline uint
|
|
||||||
read_edi(void)
|
|
||||||
{
|
|
||||||
uint edi;
|
|
||||||
__asm __volatile("movl %%edi,%0" : "=r" (edi));
|
|
||||||
return edi;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline uint
|
|
||||||
read_ebx(void)
|
|
||||||
{
|
|
||||||
uint ebx;
|
|
||||||
__asm __volatile("movl %%ebx,%0" : "=r" (ebx));
|
|
||||||
return ebx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp)
|
cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue