clean up stale error checks and panics
delete unused functions a few comments
This commit is contained in:
parent
b52151e032
commit
2b19190c13
11 changed files with 46 additions and 347 deletions
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
|
||||
provide a single mechanism?
|
||||
|
||||
test 14-character file names
|
||||
and file arguments longer than 14
|
||||
|
||||
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 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: sbrk
|
||||
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: dynamic memory allocation?
|
||||
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
|
||||
and make some inode updates async
|
||||
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 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
|
||||
* .bochsrc to copy to the stdout:
|
||||
|
@ -37,10 +33,6 @@ cons_putc(int c)
|
|||
ushort *crt = (ushort *) 0xB8000; // base of CGA memory
|
||||
int ind;
|
||||
|
||||
obuf[rcr4()][obufi[rcr4()]++] = c;
|
||||
if(obufi[rcr4()] >= 1024)
|
||||
obufi[rcr4()] = 0;
|
||||
|
||||
if(panicked){
|
||||
cli();
|
||||
for(;;)
|
||||
|
|
2
defs.h
2
defs.h
|
@ -16,7 +16,7 @@ struct jmpbuf;
|
|||
void setupsegs(struct proc *);
|
||||
struct proc * copyproc(struct proc*);
|
||||
struct spinlock;
|
||||
char *growproc(int);
|
||||
int growproc(int);
|
||||
void sleep(void *, struct spinlock *);
|
||||
void wakeup(void *);
|
||||
void scheduler(void);
|
||||
|
|
4
main.c
4
main.c
|
@ -25,8 +25,6 @@ main0(void)
|
|||
int i;
|
||||
struct proc *p;
|
||||
|
||||
lcr4(0); // xxx copy of cpu #
|
||||
|
||||
// clear BSS
|
||||
memset(edata, 0, end - edata);
|
||||
|
||||
|
@ -97,8 +95,6 @@ main0(void)
|
|||
void
|
||||
mpmain(void)
|
||||
{
|
||||
lcr4(1); // xxx copy of cpu #
|
||||
|
||||
cprintf("cpu%d: starting\n", cpu());
|
||||
idtinit(); // CPU's idt
|
||||
if(cpu() == 0)
|
||||
|
|
20
param.h
20
param.h
|
@ -1,10 +1,10 @@
|
|||
#define NPROC 64
|
||||
#define PAGE 4096
|
||||
#define KSTACKSIZE PAGE
|
||||
#define NCPU 8
|
||||
#define NOFILE 16 // file descriptors per process
|
||||
#define NFD 100 // file descriptors per system
|
||||
#define NREQUEST 100 // outstanding disk requests
|
||||
#define NBUF 10
|
||||
#define NINODE 100
|
||||
#define NDEV 10
|
||||
#define NPROC 64 // maximum number of processes
|
||||
#define PAGE 4096 // granularity of user-space memory allocation
|
||||
#define KSTACKSIZE PAGE // size of per-process kernel stack
|
||||
#define NCPU 8 // maximum number of CPUs
|
||||
#define NOFILE 16 // file descriptors per process
|
||||
#define NFD 100 // file descriptors per system
|
||||
#define NREQUEST 100 // outstanding disk requests
|
||||
#define NBUF 10 // size of disk block cache
|
||||
#define NINODE 100 // maximum number of active i-nodes
|
||||
#define NDEV 10 // maximum major device number
|
||||
|
|
8
proc.c
8
proc.c
|
@ -138,22 +138,22 @@ copyproc(struct proc* p)
|
|||
return np;
|
||||
}
|
||||
|
||||
char *
|
||||
int
|
||||
growproc(int n)
|
||||
{
|
||||
struct proc *cp = curproc[cpu()];
|
||||
char *newmem, *oldmem;
|
||||
|
||||
newmem = kalloc(cp->sz + n);
|
||||
if(newmem == 0) return (char *) -1;
|
||||
if(newmem == 0)
|
||||
return -1;
|
||||
memmove(newmem, cp->mem, cp->sz);
|
||||
memset(newmem + cp->sz, 0, n);
|
||||
oldmem = cp->mem;
|
||||
cp->mem = newmem;
|
||||
kfree(oldmem, cp->sz);
|
||||
cprintf("growproc: added %d bytes to %d bytes\n", n, cp->sz);
|
||||
cp->sz += n;
|
||||
return cp->sz - n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Per-CPU process scheduler.
|
||||
|
|
43
spinlock.c
43
spinlock.c
|
@ -6,18 +6,11 @@
|
|||
#include "proc.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;
|
||||
|
||||
void
|
||||
initlock(struct spinlock *lock, char *name)
|
||||
{
|
||||
lock->magic = LOCKMAGIC;
|
||||
lock->name = name;
|
||||
lock->locked = 0;
|
||||
lock->cpu = 0xffffffff;
|
||||
|
@ -38,8 +31,6 @@ getcallerpcs(void *v, uint pcs[])
|
|||
void
|
||||
acquire(struct spinlock * lock)
|
||||
{
|
||||
if(lock->magic != LOCKMAGIC)
|
||||
panic("weird lock magic");
|
||||
if(holding(lock))
|
||||
panic("acquire");
|
||||
|
||||
|
@ -47,34 +38,32 @@ acquire(struct spinlock * lock)
|
|||
cli();
|
||||
cpus[cpu()].nlock++;
|
||||
|
||||
while(cmpxchg(0, 1, &lock->locked) == 1)
|
||||
;
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
getcallerpcs(&lock, lock->pcs);
|
||||
lock->cpu = cpu() + 10;
|
||||
cpus[cpu()].lastacquire = lock;
|
||||
while(cmpxchg(0, 1, &lock->locked) == 1)
|
||||
;
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
getcallerpcs(&lock, lock->pcs);
|
||||
lock->cpu = cpu() + 10;
|
||||
cpus[cpu()].lastacquire = lock;
|
||||
}
|
||||
|
||||
void
|
||||
release(struct spinlock * lock)
|
||||
{
|
||||
if(lock->magic != LOCKMAGIC)
|
||||
panic("weird lock magic");
|
||||
|
||||
if(!holding(lock))
|
||||
panic("release");
|
||||
if(!holding(lock))
|
||||
panic("release");
|
||||
|
||||
cpus[cpu()].lastrelease = lock;
|
||||
lock->pcs[0] = 0;
|
||||
lock->cpu = 0xffffffff;
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
lock->locked = 0;
|
||||
if(--cpus[cpu()].nlock == 0)
|
||||
sti();
|
||||
cpus[cpu()].lastrelease = lock;
|
||||
lock->pcs[0] = 0;
|
||||
lock->cpu = 0xffffffff;
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
lock->locked = 0;
|
||||
if(--cpus[cpu()].nlock == 0)
|
||||
sti();
|
||||
}
|
||||
|
||||
int
|
||||
holding(struct spinlock *lock)
|
||||
{
|
||||
return lock->locked && lock->cpu == cpu() + 10;
|
||||
return lock->locked && lock->cpu == cpu() + 10;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
struct spinlock {
|
||||
uint magic;
|
||||
char *name;
|
||||
uint locked;
|
||||
int cpu;
|
||||
|
|
|
@ -473,15 +473,15 @@ sys_getpid(void)
|
|||
int
|
||||
sys_sbrk(void)
|
||||
{
|
||||
char *r;
|
||||
int n;
|
||||
struct proc *cp = curproc[cpu()];
|
||||
|
||||
if(fetcharg(0, &n) < 0)
|
||||
return -1;
|
||||
r = growproc(n);
|
||||
if(growproc(n) != 0)
|
||||
return -1;
|
||||
setupsegs(cp);
|
||||
return (int) r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
45
trap.c
45
trap.c
|
@ -34,59 +34,19 @@ void
|
|||
trap(struct trapframe *tf)
|
||||
{
|
||||
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){
|
||||
struct proc *cp = curproc[cpu()];
|
||||
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)
|
||||
proc_exit();
|
||||
cp->tf = tf;
|
||||
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)
|
||||
proc_exit();
|
||||
// XXX probably ought to lgdt on trap return
|
||||
return;
|
||||
}
|
||||
|
||||
//if(read_eflags() & FL_IF)
|
||||
//panic("interrupt but interrupts enabled");
|
||||
|
||||
if(v == (IRQ_OFFSET + IRQ_TIMER)){
|
||||
struct proc *cp = curproc[cpu()];
|
||||
lapic_timerintr();
|
||||
|
@ -108,8 +68,6 @@ trap(struct trapframe *tf)
|
|||
|
||||
if(v == (IRQ_OFFSET + IRQ_IDE)){
|
||||
ide_intr();
|
||||
if(cpus[cpu()].nlock)
|
||||
panic("ide_intr returned while holding a lock");
|
||||
cli(); // prevent a waiting interrupt from overflowing stack
|
||||
lapic_eoi();
|
||||
return;
|
||||
|
@ -117,9 +75,6 @@ trap(struct trapframe *tf)
|
|||
|
||||
if(v == (IRQ_OFFSET + IRQ_KBD)){
|
||||
kbd_intr();
|
||||
if(cpus[cpu()].nlock){
|
||||
panic("kbd_intr returned while holding a lock");
|
||||
}
|
||||
cli(); // prevent a waiting interrupt from overflowing stack
|
||||
lapic_eoi();
|
||||
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
|
||||
inb(int port)
|
||||
{
|
||||
|
@ -48,40 +6,6 @@ inb(int port)
|
|||
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
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
outw(int port, ushort data)
|
||||
{
|
||||
__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
|
||||
outsl(int port, const void *addr, int cnt)
|
||||
{
|
||||
|
@ -130,17 +36,7 @@ outsl(int port, const void *addr, int cnt)
|
|||
"cc");
|
||||
}
|
||||
|
||||
static __inline void
|
||||
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");
|
||||
}
|
||||
struct segdesc;
|
||||
|
||||
static __inline void
|
||||
lgdt(struct segdesc *p, int size)
|
||||
|
@ -154,6 +50,8 @@ lgdt(struct segdesc *p, int size)
|
|||
asm volatile("lgdt (%0)" : : "g" (pd));
|
||||
}
|
||||
|
||||
struct gatedesc;
|
||||
|
||||
static __inline void
|
||||
lidt(struct gatedesc *p, int size)
|
||||
{
|
||||
|
@ -166,76 +64,12 @@ lidt(struct gatedesc *p, int size)
|
|||
asm volatile("lidt (%0)" : : "g" (pd));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
lldt(ushort sel)
|
||||
{
|
||||
__asm __volatile("lldt %0" : : "r" (sel));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ltr(ushort 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
|
||||
read_eflags(void)
|
||||
{
|
||||
|
@ -250,46 +84,6 @@ write_eflags(uint 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
|
||||
cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue