Example #1
0
long
rtctime(void)
{
	int i;
	long t, ot;

	ilock(&rtclock);

	/* loop till we get two reads in a row the same */
	t = _rtctime();
	for(i = 0; i < 100; i++){
		ot = t;
		t = _rtctime();
		if(ot == t)
			break;
	}
	if(i == 100) print("we are boofheads\n");

	iunlock(&rtclock);

	return t;
}
Example #2
0
static void
ks8695_modemctl(Uart* uart, int on)
{
	Ctlr *ctlr;

	ctlr = uart->regs;
	ilock(&uart->tlock);
	if(on){
		INTRREG->en |= 1<<IRQums;	/* TO DO */
		uart->modem = 1;
		uart->cts = csr8r(ctlr, Msr) & Cts;
	}
	else{
		INTRREG->en &= ~(1<<IRQums);
		uart->modem = 0;
		uart->cts = 1;
	}
	iunlock(&uart->tlock);

	/* modem needs fifo */
	(*uart->phys->fifo)(uart, on);
}
Example #3
0
Timer*
addclock0link(void (*f)(void), int ms)
{
	Timer *nt;
	uvlong when;

	/* Synchronize to hztimer if ms is 0 */
	nt = malloc(sizeof(Timer));
	if(ms == 0)
		ms = 1000/HZ;
	nt->tns = (vlong)ms*1000000LL;
	nt->tmode = Tperiodic;
	nt->tt = nil;
	nt->tf = (void (*)(Ureg*, Timer*))f;

	ilock(&timers[0]);
	when = tadd(&timers[0], nt);
	if(when)
		timerset(when);
	iunlock(&timers[0]);
	return nt;
}
Example #4
0
// Look up and return the inode for a path name.
// If parent != 0, return the inode for the parent and copy the final
// path element into name, which must have room for DIRSIZ bytes.
static struct inode *
namex (char *path, int nameiparent, char *name)
{
    struct inode *ip, *next;

    if (*path == '/')
        ip = iget (ROOTDEV, ROOTINO);
    else
        ip = idup (proc->cwd);

    while ((path = skipelem (path, name)) != 0)
    {
        ilock (ip);
        if (ip->type != T_DIR)
        {
            iunlockput (ip);
            return 0;
        }
        if (nameiparent && *path == '\0')
        {
            // Stop one level early.
            iunlock (ip);
            return ip;
        }
        if ((next = dirlookup (ip, name, 0)) == 0)
        {
            iunlockput (ip);
            return 0;
        }
        iunlockput (ip);
        ip = next;
    }
    if (nameiparent)
    {
        iput (ip);
        return 0;
    }
    return ip;
}
Example #5
0
void
dp8390getea(Ether* ether, uchar* ea)
{
	Dp8390 *ctlr;
	uchar cr;
	int i;

	ctlr = ether->ctlr;

	/*
	 * Get the ethernet address from the chip.
	 * Take care to restore the command register
	 * afterwards.
	 */
	ilock(ctlr);
	cr = regr(ctlr, Cr) & ~Txp;
	regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
	for(i = 0; i < Eaddrlen; i++)
		ea[i] = regr(ctlr, Par0+i);
	regw(ctlr, Cr, cr);
	iunlock(ctlr);
}
Example #6
0
void
intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name)
{
	Vctl **pv, *v;
	int vno;

	if(arch->intrvecno == nil || (tbdf != BUSUNKNOWN && (irq == 0xff || irq == 0))){
		/*
		 * on APIC machine, irq is pretty meaningless
		 * and disabling a the vector is not implemented.
		 * however, we still want to remove the matching
		 * Vctl entry to prevent calling Vctl.f() with a
		 * stale Vctl.a pointer.
		 */
		irq = -1;
		vno = VectorPIC;
	} else {
		vno = arch->intrvecno(irq);
	}
	ilock(&vctllock);
	do {
		for(pv = &vctl[vno]; (v = *pv) != nil; pv = &v->next){
			if(v->isintr && (v->irq == irq || irq == -1)
			&& v->tbdf == tbdf && v->f == f && v->a == a
			&& strcmp(v->name, name) == 0)
				break;
		}
		if(v != nil){
			*pv = v->next;
			xfree(v);

			if(irq != -1 && vctl[vno] == nil && arch->intrdisable != nil)
				arch->intrdisable(irq);
			break;
		}
	} while(irq == -1 && ++vno <= MaxVectorAPIC);
	iunlock(&vctllock);
}
Example #7
0
static void
oxfifo(Uart *uart, int level)
{
	Ctlr *ctlr;
	Port *port;

	port = uart->regs;
	ctlr = port->ctlr;

	/*
	 * 950 Mode FIFOs have a depth of 128 bytes; devuart only
	 * cares about setting RHR trigger levels.  THR trigger
	 * levels are not supported.
	 */
	ilock(ctlr);
	if(level == 0)
		port->mem[Fcr] = 0;		/* Disable FIFO */
	else{
		port->mem[Fcr] = 1<<0;		/* Enable FIFO */
		switch(level){
		default:
			level = 112;
		case 112:
			port->mem[Fcr] = 0x03<<6|1<<0;	/* RHR Trigger Level */
			break;
		case 64:
			port->mem[Fcr] = 0x02<<6|1<<0;
			break;
		case 32:
			port->mem[Fcr] = 0x01<<6|1<<0;
			break;
		case 16:
			break;
		}
	}
	port->level = level;
	iunlock(ctlr);
}
Example #8
0
Block*
iallocb(int size)
{
	Block *b;
	static int m1, m2, mp;

	if(ialloc.bytes > conf.ialloc){
		if((m1++%10000)==0){
			if(mp++ > 1000){
				active.exiting = 1;
				exit(0);
			}
			iprint("iallocb: limited %lud/%lud\n",
				ialloc.bytes, conf.ialloc);
		}
		return nil;
	}

	if((b = _allocb(size)) == nil){
		if((m2++%10000)==0){
			if(mp++ > 1000){
				active.exiting = 1;
				exit(0);
			}
			iprint("iallocb: no memory %lud/%lud\n",
				ialloc.bytes, conf.ialloc);
		}
		return nil;
	}
	setmalloctag(b, getcallerpc(&size));
	b->flag = BINTR;

	ilock(&ialloc);
	ialloc.bytes += b->lim - b->base;
	iunlock(&ialloc);

	return b;
}
Example #9
0
long
w_ctl(Ether* ether, void* buf, long n)
{
	Ctlr *ctlr;

	if((ctlr = ether->ctlr) == nil)
		error(Enonexist);
	if((ctlr->state & Attached) == 0)
		error(Eshutdown);

	ilock(ctlr);
	if(w_option(ctlr, buf, n)){
		iunlock(ctlr);
		error(Ebadctl);
	}
	if(ctlr->txbusy)
		w_txdone(ctlr, WTxErrEv);
	w_enable(ether);
	w_txstart(ether);
	iunlock(ctlr);

	return n;
}
Example #10
0
void
w_attach(Ether* ether)
{
	Ctlr* ctlr;
	char name[64];
	int rc;

	if(ether->ctlr == 0)
		return;

	snprint(name, sizeof(name), "#l%dtimer", ether->ctlrno);
	ctlr = (Ctlr*) ether->ctlr;
	if((ctlr->state & Attached) == 0){
		ilock(ctlr);
		rc = w_enable(ether);
		iunlock(ctlr);
		if(rc == 0){
			ctlr->state |= Attached;
			kproc(name, w_timer, ether);
		} else
			print("#l%d: enable failed\n",ether->ctlrno);
	}
}
Example #11
0
void
powerenable(void (*f)(int))
{
	Power *p, *l;

	p = malloc(sizeof(*p));
	p->f = f;
	p->prev = nil;
	p->next = nil;
	ilock(&power);
	for(l = power.list.next; l != &power.list; l = l->next)
		if(l->f == f){
			iunlock(&power);
			free(p);
			return;
		}
	l = &power.list;
	p->prev = l->prev;
	l->prev = p;
	p->next = l;
	p->prev->next = p;
	iunlock(&power);
}
Example #12
0
int
i8259disable(int irq)
{
	int irqbit;

	/*
	 * Given an IRQ, disable the corresponding interrupt
	 * in the 8259.
	 */
	if(irq < 0 || irq > MaxIrqPIC){
		print("i8259disable: irq %d out of range\n", irq);
		return -1;
	}
	irqbit = 1<<irq;

	ilock(&i8259lock);
	if(!(i8259mask & irqbit)){
		i8259mask |= irqbit;
		if(irq < 8)
			outb(Int0aux, i8259mask & 0xFF);
		else
			outb(Int1aux, (i8259mask>>8) & 0xFF);
	}
Example #13
0
/*
 *  wait for the queue to be non-empty or closed.
 *  called with q ilocked.
 */
static int
qwait(Queue *q)
{
	/* wait for data */
	for(;;){
		if(q->bfirst != nil)
			break;

		if(q->state & Qclosed){
			if(++q->eof > 3)
				return -1;
			if(*q->err && strcmp(q->err, Ehungup) != 0)
				return -1;
			return 0;
		}

		q->state |= Qstarve;	/* flag requesting producer to wake me */
		iunlock(q);
		sleep(&q->rr, notempty, q);
		ilock(q);
	}
	return 1;
}
Example #14
0
File: clock.c Project: CoryXie/NxM
uvlong
fastticks(uvlong *hz)
{
	Counter now, sclnow;

	if(hz)
		*hz = m->cpuhz;
	ilock(&clklck);
	if (m->ticks > HZ/10 && m->fastclock == 0)
		panic("fastticks: zero m->fastclock; ticks %lud fastclock %#llux",
			m->ticks, m->fastclock);

	now.uvl = m->fastclock;
	now.low = rdcycles();
	if(now.uvl < m->fastclock)	/* low bits must have wrapped */
		now.high++;
	m->fastclock = now.uvl;
	coherence();

	sclnow.uvl = now.uvl;
	iunlock(&clklck);
	return sclnow.uvl;
}
Example #15
0
/*
 *  Put character, possibly a rune, into read queue at interrupt time.
 *  Called at interrupt time to process a character.
 */
int
kbdputc(Queue *q, int ch)
{
	int n;
	Rune r;
	char buf[UTFmax];
	
	r = ch;
	n = runetochar(buf, &r);
	echo(buf, n);
	return 0;

#if 0 // Plan 9 VX
	int i, n;
	char buf[3];
	Rune r;
	char *next;

	if(kbd.ir == nil)
		return 0;		/* in case we're not inited yet */
	
	ilock(&kbd.lockputc);		/* just a mutex */
	r = ch;
	n = runetochar(buf, &r);
	for(i = 0; i < n; i++){
		next = kbd.iw+1;
		if(next >= kbd.ie)
			next = kbd.istage;
		if(next == kbd.ir)
			break;
		*kbd.iw = buf[i];
		kbd.iw = next;
	}
	iunlock(&kbd.lockputc);
	return 0;
#endif
}
Example #16
0
static int load_proc(char *path, struct proc *p)
{
	int i;
	struct proc np;
	//an inode describes a single unnamed file
	struct inode *ip;
	begin_op();
	if ((ip = namei(path)) == 0) {
		end_op();
		return -1;
	}
	ilock(ip);
	if((np.pgdir = setupkvm()) == 0)
		return -1;
	if((np.sz = allocuvm(np.pgdir, 0, p->sz)) == 0)
		return -1;
	for(i = 0; i < p->sz; i+=PGSIZE) {
		if(loaduvm(np.pgdir, (void *)i, ip, sizeof(struct proc) + i,PGSIZE) < 0)	
	return -1;
	}
	iunlockput(ip);
	end_op();
	ip = 0;
	
	np.tf->eax = proc->pid;
	np.tf->eip = p->tf->eip;
	np.tf->esp = p->tf->esp;
	np.tf->ebp = p->tf->ebp;
	
	proc->pgdir = np.pgdir;
	proc->sz = PGROUNDUP(np.sz);
	*proc->tf = *np.tf;
	
	switchuvm(proc);
	
	return 0;
}
Example #17
0
int
i8259enable(Vctl* v)
{
	int irq, irqbit;

	/*
	 * Given an IRQ, enable the corresponding interrupt in the i8259
	 * and return the vector to be used. The i8259 is set to use a fixed
	 * range of vectors starting at VectorPIC.
	 */
	irq = v->irq;
	if(irq < 0 || irq > MaxIrqPIC){
		print("i8259enable: irq %d out of range\n", irq);
		return -1;
	}
	irqbit = 1<<irq;

	ilock(&i8259lock);
	if(!(i8259mask & irqbit) && !(i8259elcr & irqbit)){
		print("i8259enable: irq %d shared but not level\n", irq);
		iunlock(&i8259lock);
		return -1;
	}
	i8259mask &= ~irqbit;
	if(irq < 8)
		outb(Int0aux, i8259mask & 0xFF);
	else
		outb(Int1aux, (i8259mask>>8) & 0xFF);

	if(i8259elcr & irqbit)
		v->eoi = i8259isr;
	else
		v->isr = i8259isr;
	iunlock(&i8259lock);

	return VectorPIC+irq;
}
Example #18
0
static char*
startxfer(I2Cdev *d, int op, void (*xfer)(Ctlr*), Block *b, int n, ulong offset)
{
    IICregs *iic;
    Ctlr *ctlr;
    int i, cntl, p, s;

    ctlr = iicctlr;
    if(up) {
        qlock(&ctlr->io);
        if(waserror()) {
            qunlock(&ctlr->io);
            nexterror();
        }
    }
    ilock(ctlr);
    if(!idlectlr(ctlr)) {
        iunlock(ctlr);
        if(up)
            error("bus confused");
        return "bus confused";
    }
    if(ctlr->phase >= Busy)
        panic("iic: ctlr busy");
    cntl = op | Pt;
    if(d->tenbit)
        cntl |= Amd10;
    ctlr->cntl = cntl;
    ctlr->b = b;
    ctlr->rdcount = n;
    ctlr->phase = Busy;
    iic = ctlr->regs;
    if(d->tenbit) {
        iic->hmadr = 0xF0 | (d->addr>>7);	/* 2 higher bits of address, LSB don't care */
        iic->lmadr = d->addr;
    } else {
Example #19
0
void
w_detach(Ether* ether)
{
	Ctlr* ctlr;
	char name[64];

	if(ether->ctlr == nil)
		return;

	snprint(name, sizeof(name), "#l%dtimer", ether->ctlrno);
	ctlr = (Ctlr*) ether->ctlr;
	if(ctlr->state & Attached){
		ilock(ctlr);
		w_intdis(ctlr);
		if(ctlr->timerproc){
			if(!postnote(ctlr->timerproc, 1, "kill", NExit))
				print("timerproc note not posted\n");
			print("w_detach, killing 0x%p\n", ctlr->timerproc);
		}
		ctlr->state &= ~Attached;
		iunlock(ctlr);
	}
	ether->ctlr = nil;
}
Example #20
0
void
dp8390setea(Ether* ether)
{
	int i;
	uchar cr;
	Dp8390 *ctlr;

	ctlr = ether->ctlr;

	/*
	 * Set the ethernet address into the chip.
	 * Take care to restore the command register
	 * afterwards. Don't care about multicast
	 * addresses as multicast is never enabled
	 * (currently).
	 */
	ilock(ctlr);
	cr = regr(ctlr, Cr) & ~Txp;
	regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr));
	for(i = 0; i < Eaddrlen; i++)
		regw(ctlr, Par0+i, ether->ea[i]);
	regw(ctlr, Cr, cr);
	iunlock(ctlr);
}
Example #21
0
File: tod.c Project: 99years/plan9
/*
 *  called regularly to avoid calculation overflows
 */
static void
todfix(void)
{
	vlong ticks, diff;
	uvlong x;

	ticks = fastticks(nil);

	diff = ticks - tod.last;
	if(diff > tod.hz){
		ilock(&tod);

		/* convert to epoch */
		mul64fract(&x, diff, tod.multiplier);
if(x > 30000000000ULL) iprint("todfix %llud\n", x);
		x += tod.off;

		/* protect against overflows */
		tod.last = ticks;
		tod.off = x;

		iunlock(&tod);
	}
}
Example #22
0
static void
i8250modemctl(Uart* uart, int on)
{
	Ctlr *ctlr;

	ctlr = uart->regs;
	ilock(&uart->tlock);
	if(on){
		ctlr->sticky[Ier] |= Ems;
		csr8w(ctlr, Ier, 0);
		uart->modem = 1;
		uart->cts = csr8r(ctlr, Msr) & Cts;
	}
	else{
		ctlr->sticky[Ier] &= ~Ems;
		csr8w(ctlr, Ier, 0);
		uart->modem = 0;
		uart->cts = 1;
	}
	iunlock(&uart->tlock);

	/* modem needs fifo */
	(*uart->phys->fifo)(uart, on);
}
Example #23
0
static void
uartclose(Chan *c)
{
	Proc *up = externup();
	Uart *p;

	if(c->qid.type & QTDIR)
		return;
	if((c->flag & COPEN) == 0)
		return;
	switch(UARTTYPE(c->qid.path)){
	case Qdata:
	case Qctl:
		p = uart[UARTID(c->qid.path)];
		qlock(&p->ql);
		if(--(p->opens) == 0){
			qclose(p->iq);
			ilock(&p->rlock);
			p->ir = p->iw = p->istage;
			iunlock(&p->rlock);

			/*
			 */
			qhangup(p->oq, nil);
			if(!waserror()){
				uartdrainoutput(p);
				poperror();
			}
			qclose(p->oq);
			uartdisable(p);
			p->dcd = p->dsr = p->dohup = 0;
		}
		qunlock(&p->ql);
		break;
	}
}
Example #24
0
static void
x86wdenable(void)
{
	Wd *wd;
	vlong r, t;
	int i, model;
	u32int evntsel;

	wd = &x86wd;
	ilock(wd);
	if(wd->inuse){
		iunlock(wd);
		error(Einuse);
	}
	iunlock(wd);

	/*
	 * keep this process on cpu 0 so we always see the same timers
	 * and so that this will work even if all other cpus are shut down.
	 */
	runoncpu(0);

	/*
	 * Check the processor is capable of doing performance
	 * monitoring and that it has TSC, RDMSR/WRMSR and a local APIC.
	 */
	model = -1;
	if(strncmp(m->cpuidid, "AuthenticAMD", 12) == 0){
		if(X86FAMILY(m->cpuidax) == 0x06)
			model = K6;
		else if(X86FAMILY(m->cpuidax) == 0x0F)
			model = K8;
	}
	else if(strncmp(m->cpuidid, "GenuineIntel", 12) == 0){
		if(X86FAMILY(m->cpuidax) == 0x06)
			model = P6;
		else if(X86FAMILY(m->cpuidax) == 0x0F)
			model = P4;
	}
	if(model == -1 ||
	    (m->cpuiddx & (Cpuapic|Cpumsr|Tsc)) != (Cpuapic|Cpumsr|Tsc))
		error(Enodev);

	ilock(wd);
	if(wd->inuse){
		iunlock(wd);
		error(Einuse);
	}
	wd->model = model;
	wd->inuse = 1;
	wd->ticks = 0;

	/*
	 * See the IA-32 Intel Architecture Software
	 * Developer's Manual Volume 3: System Programming Guide,
	 * Chapter 15 and the AMD equivalent for what all this
	 * bit-whacking means.
	 */
	t = interval();
	switch(model){
	case P6:
		wrmsr(0x186, 0);			/* evntsel */
		wrmsr(0x187, 0);
		wrmsr(0xC1, 0);				/* perfctr */
		wrmsr(0xC2, 0);

		lapicnmienable();
	
		evntsel = 0x00130000|0x79;
		wrmsr(0xC1, -t);
		wrmsr(0x186, 0x00400000|evntsel);
		break;
	case P4:
		rdmsr(0x1A0, &r);
		if(!(r & 0x0000000000000080LL))
			return;
	
		for(i = 0; i < 18; i++)
			wrmsr(0x300+i, 0);		/* perfctr */
		for(i = 0; i < 18; i++)
			wrmsr(0x360+i, 0);		/* ccr */
	
		for(i = 0; i < 31; i++)
			wrmsr(0x3A0+i, 0);		/* escr */
		for(i = 0; i < 6; i++)
			wrmsr(0x3C0+i, 0);		/* escr */
		for(i = 0; i < 6; i++)
			wrmsr(0x3C8+i, 0);		/* escr */
		for(i = 0; i < 2; i++)
			wrmsr(0x3E0+i, 0);		/* escr */
	
		if(!(r & 0x0000000000001000LL)){
			for(i = 0; i < 2; i++)
				wrmsr(0x3F1+i, 0);	/* pebs */
		}
	
		lapicnmienable();
	
		wrmsr(0x3B8, 0x000000007E00000CLL);	/* escr0 */
		r = 0x0000000004FF8000ULL;
		wrmsr(0x36C, r);			/* cccr0 */
		wrmsr(0x30C, -t);
		wrmsr(0x36C, 0x0000000000001000LL|r);
		break;
	case K6:
	case K8:
		/*
		 * PerfEvtSel 0-3, PerfCtr 0-4.
		 */
		for(i = 0; i < 8; i++)
			wrmsr(0xC0010000+i, 0);
	
		lapicnmienable();
	
		evntsel = 0x00130000|0x76;
		wrmsr(0xC0010004, -t);
		wrmsr(0xC0010000, 0x00400000|evntsel);
		break;
	}
	iunlock(wd);
}
Example #25
0
File: exec.c Project: 5kg/xv6
int
exec(char *path, char **argv)
{
  char *s, *last;
  int i, off;
  uint argc, sz, sp, ustack[3+MAXARG+1];
  struct elfhdr elf;
  struct inode *ip;
  struct proghdr ph;
  pde_t *pgdir, *oldpgdir;

  begin_op();
  if((ip = namei(path)) == 0){
    end_op();
    return -1;
  }
  ilock(ip);
  pgdir = 0;

  // Check ELF header
  if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf))
    goto bad;
  if(elf.magic != ELF_MAGIC)
    goto bad;

  if((pgdir = setupkvm()) == 0)
    goto bad;

  // Load program into memory.
  sz = 0;
  for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){
    if(readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))
      goto bad;
    if(ph.type != ELF_PROG_LOAD)
      continue;
    if(ph.memsz < ph.filesz)
      goto bad;
    if((sz = allocuvm(pgdir, sz, ph.vaddr + ph.memsz)) == 0)
      goto bad;
    if(loaduvm(pgdir, (char*)ph.vaddr, ip, ph.off, ph.filesz) < 0)
      goto bad;
  }
  iunlockput(ip);
  end_op();
  ip = 0;

  // Allocate two pages at the next page boundary.
  // Make the first inaccessible.  Use the second as the user stack.
  sz = PGROUNDUP(sz);
  if((sz = allocuvm(pgdir, sz, sz + 2*PGSIZE)) == 0)
    goto bad;
  clearpteu(pgdir, (char*)(sz - 2*PGSIZE));
  sp = sz;

  // Push argument strings, prepare rest of stack in ustack.
  for(argc = 0; argv[argc]; argc++) {
    if(argc >= MAXARG)
      goto bad;
    sp = (sp - (strlen(argv[argc]) + 1)) & ~3;
    if(copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0)
      goto bad;
    ustack[3+argc] = sp;
  }
  ustack[3+argc] = 0;

  ustack[0] = 0xffffffff;  // fake return PC
  ustack[1] = argc;
  ustack[2] = sp - (argc+1)*4;  // argv pointer

  sp -= (3+argc+1) * 4;
  if(copyout(pgdir, sp, ustack, (3+argc+1)*4) < 0)
    goto bad;

  // Save program name for debugging.
  for(last=s=path; *s; s++)
    if(*s == '/')
      last = s+1;
  safestrcpy(proc->name, last, sizeof(proc->name));

  // Commit to the user image.
  oldpgdir = proc->pgdir;
  proc->pgdir = pgdir;
  proc->sz = sz;
  proc->tf->eip = elf.entry;  // main
  proc->tf->esp = sp;
  switchuvm(proc);
  freevm(oldpgdir);
  return 0;

 bad:
  if(pgdir)
    freevm(pgdir);
  if(ip){
    iunlockput(ip);
    end_op();
  }
  return -1;
}
Example #26
0
static void
igbeinterrupt(Ureg*, void* arg)
{
	Block *bp;
	Ctlr *ctlr;
	Ether *edev;
	Rdesc *rdesc;
	int icr, im, rdh, txdw = 0;

	edev = arg;
	ctlr = edev->ctlr;

	ilock(&ctlr->imlock);
	csr32w(ctlr, Imc, ~0);
	im = ctlr->im;

	if((icr = csr32r(ctlr, Icr)) & ctlr->im){
		/*
		 * Link status changed.
		 */
		if(icr & (Rxseq|Lsc)){
			/*
			 * More here...
			 */
		}

		/*
		 * Process any received packets.
		 */
		rdh = ctlr->rdh;
		for(;;){
			rdesc = &ctlr->rdba[rdh];
			if(!(rdesc->status & Rdd))
				break;
			if ((rdesc->status & Reop) && rdesc->errors == 0) {
				bp = ctlr->rb[rdh];
				ctlr->rb[rdh] = nil;
				/*
				 * it appears that the original 82543 needed
				 * to have the Ethernet CRC excluded, but that
				 * the newer chips do not?
				 */
				bp->wp += rdesc->length /* -4 */;
				toringbuf(edev, bp);
				freeb(bp);
			} else if ((rdesc->status & Reop) && rdesc->errors)
				print("igbe: input packet error 0x%ux\n",
					rdesc->errors);
			rdesc->status = 0;
			rdh = NEXT(rdh, Nrdesc);
		}
		ctlr->rdh = rdh;

		if(icr & Rxdmt0)
			igbereplenish(ctlr);
		if(icr & Txdw){
			im &= ~Txdw;
			txdw++;
		}
	}

	ctlr->im = im;
	csr32w(ctlr, Ims, im);
	iunlock(&ctlr->imlock);

	if(txdw)
		igbetransmit(edev);
}
Example #27
0
int
exec(char *path, char **argv)
{
  char *s, *last;
  int i, off;
  uint argc, sz,s_sz, sp, ustack[3+MAXARG+1];
  struct elfhdr elf;
  struct inode *ip;
  struct proghdr ph;
  pde_t *pgdir, *oldpgdir;

  if((ip = namei(path)) == 0)
    return -1;
  ilock(ip);
  pgdir = 0;

  // Check ELF header
  if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf))
    goto bad;
  if(elf.magic != ELF_MAGIC)
    goto bad;

  if((pgdir = setupkvm()) == 0)
    goto bad;

  // Load program into memory.
  sz = PGSIZE;
  for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){
    if(readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))
      goto bad;
    if(ph.type != ELF_PROG_LOAD)
      continue;
    if(ph.memsz < ph.filesz)
      goto bad;
    if((sz = allocuvm(pgdir, sz, ph.va + ph.memsz)) == 0)
      goto bad;
    if(loaduvm(pgdir, (char*)ph.va, ip, ph.offset, ph.filesz) < 0)
      goto bad;
  }
  iunlockput(ip);
  ip = 0;

  // Allocate a one-page stack one page away from USERTOP (at bottom
  // grow upwards)
  s_sz = (USERTOP - PGSIZE);
  if((s_sz = allocuvm(pgdir, s_sz, s_sz + PGSIZE)) == 0)
    goto bad;

  // Push argument strings, prepare rest of stack in ustack.
  sp = s_sz;
  for(argc = 0; argv[argc]; argc++) {
    if(argc >= MAXARG)
      goto bad;
    sp -= strlen(argv[argc]) + 1;
    sp &= ~3;
    if(copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0)
      goto bad;
    ustack[3+argc] = sp;
  }
  ustack[3+argc] = 0;

  ustack[0] = 0xffffffff;  // fake return PC
  ustack[1] = argc;
  ustack[2] = sp - (argc+1)*4;  // argv pointer

  sp -= (3+argc+1) * 4;
  if(copyout(pgdir, sp, ustack, (3+argc+1)*4) < 0)
    goto bad;

  // Save program name for debugging.
  for(last=s=path; *s; s++)
    if(*s == '/')
      last = s+1;
  safestrcpy(proc->name, last, sizeof(proc->name));

  s_sz = USERTOP - PGSIZE;

  // Commit to the user image.
  oldpgdir = proc->pgdir;
  proc->pgdir = pgdir;
  proc->sz = sz;
  proc->s_sz =s_sz;
  proc->tf->eip = elf.entry;  // main
  proc->tf->esp = sp;
  switchuvm(proc);
  freevm(oldpgdir);

 // cprintf("finish exec%d\t%d\n",sz,s_sz);

  return 0;

 bad:
  if(pgdir)
    freevm(pgdir);
  if(ip)
    iunlockput(ip);
  return -1;
}
Example #28
0
static long
loopbackwrite(Chan *c, void *va, long n, vlong off)
{
	Loop *lb;
	Link *link;
	Cmdbuf *volatile cb;
	Block *volatile bp;
	vlong d0, d0ns;
	long dn, dnns;

	switch(TYPE(c->qid.path)){
	case Qdata:
		bp = allocb(n);
		if(waserror()){
			freeb(bp);
			nexterror();
		}
		memmove(bp->wp, va, n);
		poperror();
		bp->wp += n;
		return loopbackbwrite(c, bp, off);
	case Qctl:
		lb = c->aux;
		link = &lb->link[ID(c->qid.path)];
		cb = parsecmd(va, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		if(cb->nf < 1)
			error("short control request");
		if(strcmp(cb->f[0], "delay") == 0){
			if(cb->nf != 3)
				error("usage: delay latency bytedelay");
			d0ns = strtoll(cb->f[1], nil, 10);
			dnns = strtol(cb->f[2], nil, 10);

			/*
			 * it takes about 20000 cycles on a pentium ii
			 * to run pushlink; perhaps this should be accounted.
			 */

			ilock(link);
			link->delay0ns = d0ns;
			link->delaynns = dnns;
			iunlock(link);
		}else if(strcmp(cb->f[0], "indrop") == 0){
			if(cb->nf != 2)
				error("usage: indrop [01]");
			ilock(link);
			link->indrop = strtol(cb->f[1], nil, 0) != 0;
			iunlock(link);
		}else if(strcmp(cb->f[0], "droprate") == 0){
			if(cb->nf != 2)
				error("usage: droprate ofn");
			ilock(link);
			link->droprate = strtol(cb->f[1], nil, 0);
			iunlock(link);
		}else if(strcmp(cb->f[0], "limit") == 0){
			if(cb->nf != 2)
				error("usage: limit maxqsize");
			ilock(link);
			link->limit = strtol(cb->f[1], nil, 0);
			qsetlimit(link->oq, link->limit);
			qsetlimit(link->iq, link->limit);
			iunlock(link);
		}else if(strcmp(cb->f[0], "reset") == 0){
			if(cb->nf != 1)
				error("usage: reset");
			ilock(link);
			link->packets = 0;
			link->bytes = 0;
			link->indrop = 0;
			link->soverflows = 0;
			link->drops = 0;
			iunlock(link);
		}else
			error("unknown control request");
		poperror();
		free(cb);
		break;
	default:
		error(Eperm);
	}

	return n;
}
Example #29
0
/*
 * move blocks between queues if they are ready.
 * schedule an interrupt for the next interesting time.
 *
 * must be called with the link ilocked.
 */
static void
pushlink(Link *link, vlong now)
{
	Block *bp;
	vlong tout, tin;

	/*
	 * put another block in the link queue
	 */
	ilock(link);
	if(link->iq == nil || link->oq == nil){
		iunlock(link);
		return;

	}
	timerdel(&link->ci);

	/*
	 * put more blocks into the xmit queue
	 * use the time the last packet was supposed to go out
	 * as the start time for the next packet, rather than
	 * the current time.  this more closely models a network
	 * device which can queue multiple output packets.
	 */
	tout = link->tout;
	if(!tout)
		tout = now;
	while(tout <= now){
		bp = qget(link->oq);
		if(bp == nil){
			tout = 0;
			break;
		}

		/*
		 * can't send the packet before it gets queued
		 */
		tin = gtime(bp->rp);
		if(tin > tout)
			tout = tin;
		tout = tout + (BLEN(bp) - Tmsize) * link->delayn;

		/*
		 * drop packets
		 */
		if(link->droprate && nrand(link->droprate) == 0)
			link->drops++;
		else{
			ptime(bp->rp, tout + link->delay0ns);
			if(link->tq == nil)
				link->tq = bp;
			else
				link->tqtail->next = bp;
			link->tqtail = bp;
		}
	}

	/*
	 * record the next time a packet can be sent,
	 * but don't schedule an interrupt if none is waiting
	 */
	link->tout = tout;
	if(!qcanread(link->oq))
		tout = 0;

	/*
	 * put more blocks into the receive queue
	 */
	tin = 0;
	while(bp = link->tq){
		tin = gtime(bp->rp);
		if(tin > now)
			break;
		bp->rp += Tmsize;
		link->tq = bp->next;
		bp->next = nil;
		if(!link->indrop)
			qpassnolim(link->iq, bp);
		else if(qpass(link->iq, bp) < 0)
			link->soverflows++;
		tin = 0;
	}
	if(bp == nil && qisclosed(link->oq) && !qcanread(link->oq) && !qisclosed(link->iq))
		qhangup(link->iq, nil);
	link->tin = tin;
	if(!tin || tin > tout && tout)
		tin = tout;

	link->ci.ns = tin - now;
	if(tin){
		if(tin < now)
			panic("loopback unfinished business");
		timeradd(&link->ci);
	}
	iunlock(link);
}
Example #30
0
File: clock.c Project: CoryXie/NxM
void
clockinit(void)
{
	int i, s;
	Timerregs *tn;

	clockshutdown();

	/* turn cycle counter on */
	cpwrsc(0, CpCLD, CpCLDena, CpCLDenacyc, 1<<31);

	/* turn all counters on and clear the cycle counter */
	cpwrsc(0, CpCLD, CpCLDena, CpCLDenapmnc, 1<<2 | 1);

	/* let users read the cycle counter directly */
	cpwrsc(0, CpCLD, CpCLDena, CpCLDenapmnc, 1);

	ilock(&clklck);
	m->fastclock = 1;
	m->ticks = ticks = 0;

	/*
	 * T0 is a freerunning timer (cycle counter); it wraps,
	 * automatically reloads, and does not dispatch interrupts.
	 */
	tn = (Timerregs *)Tn0;
	tn->tcrr = Freebase;			/* count up to 0 */
	tn->tldr = Freebase;
	coherence();
	tn->tclr = Ar | St;
	iunlock(&clklck);

	/*
	 * T1 is the interrupting timer and does not participate
	 * in measuring time.  It is initially set to HZ.
	 */
	tn = (Timerregs *)Tn1;
	irqenable(Tn0irq+1, clockintr, tn, "clock");
	ilock(&clklck);
	tn->tcrr = -Tcycles;			/* approx.; count up to 0 */
	tn->tldr = -Tcycles;
	coherence();
	tn->tclr = Ar | St;
	coherence();
	tn->tier = Ovf_it;
	coherence();
	iunlock(&clklck);

	/*
	 * verify sanity of timer1
	 */
	s = spllo();			/* risky */
	for (i = 0; i < 5 && ticks == 0; i++) {
		delay(10);
		cachedwbinvse(&ticks, sizeof ticks);
	}
	splx(s);
	if (ticks == 0) {
		if (tn->tcrr == 0)
			panic("clock not interrupting");
		else if (tn->tcrr == tn->tldr)
			panic("clock not ticking at all");
#ifdef PARANOID
		else
			panic("clock running very slowly");
#endif
	}

	guessmips(issue1loop, "single");
	if (Debug)
		iprint(", ");
	guessmips(issue2loop, "dual");
	if (Debug)
		iprint("\n");

	/*
	 * m->delayloop should be the number of delay loop iterations
	 * needed to consume 1 ms.  2 is min. instructions in the delay loop.
	 */
	m->delayloop = m->cpuhz / (1000 * 2);
//	iprint("m->delayloop = %lud\n", m->delayloop);

	/*
	 *  desynchronize the processor clocks so that they all don't
	 *  try to resched at the same time.
	 */
	delay(m->machno*2);
}