Esempio n. 1
0
/*
 * caller must zero or otherwise initialise *rp,
 * other than ax, bx, dx, si & ds.
 */
static int
biosdiskcall(Ureg *up, uchar op, ulong bx, ulong dx, ulong si)
{
	int s;
	uchar err;

	s = splhi();		/* don't let the bios call be interrupted */

	up->ax = op << 8;
	up->bx = bx;
	up->dx = dx;		/* often drive id */
	/*
	 * ensure that dap addr fits in a short.
	 */
	if((si & 0xffff0000) != 0)
		print("biosdiskcall: dap address %#lux not a short\n", si);

	/* assume si is in first 64K */
	if((si & 0xffff0000) != ((si + 512 - 1) & 0xffff0000))
		print("biosdiskcall: dap address %#lux too near segment boundary\n",
			si);
	up->si = si;		/* ds:si forms data access packet addr */
	up->ds = 0;
	up->di = 0;

	/*
	 * *up is copied into low memory (realmoderegs) and thence into
	 * the machine registers before the BIOS call, and the registers are
	 * copied into realmoderegs and thence into *up after.
	 *
	 * realmode loads these registers: di, si, ax, bx, cx, dx, ds, es.
	 */
	realmode(0x13, up);

	splx(s);

	if (up->flags & CF) {
		if (Debug && dx == Baseid) {
			err = up->ax >> 8;
			print("\nbiosdiskcall: int 0x13 op %#ux drive %#lux "
				"failed, ah error code %#ux (%s)\n",
				op, dx, err, strerr(err));
		}
		return -1;
	}
Esempio n. 2
0
File: proc.c Progetto: npe9/harvey
Proc*
runproc(void)
{
	Mach *m = machp();
	Schedq *rq;
	Proc *p;
	uint32_t start, now;

	if(nosmp)
		return singlerunproc();

	//NIX modeset cannot work without halt every cpu at boot
	//if(sys->nmach <= AMPmincores)
	else
		return smprunproc();

	start = perfticks();
	run.preempts++;
	rq = nil;
	if(m->machno != 0){
		do{
			spllo();
			while(m->proc == nil)
				idlehands();
			now = perfticks();
			m->perf.inidle += now-start;
			start = now;
			splhi();
			p = m->proc;
		}while(p == nil);
		p->state = Scheding;
		p->mp = sys->machptr[m->machno];
	
		if(edflock(p)){
			edfrun(p, rq == &run.runq[PriEdf]);	/* start deadline timer and do admin */
			edfunlock();
		}
		if(p->trace)
			proctrace(p, SRun, 0);
		return p;
	}

	mach0sched();
	return nil;	/* not reached */
}
Esempio n. 3
0
File: devcons.c Progetto: 8l/inferno
int
iprint(char *fmt, ...)
{
	int n, s;
	va_list arg;
	char buf[PRINTSIZE];

	s = splhi();
	va_start(arg, fmt);
	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
	va_end(arg);
	if(screenputs != nil && iprintscreenputs)
		screenputs(buf, n);
	uartputs(buf, n);
	splx(s);

	return n;
}
Esempio n. 4
0
/*
 * Tval is supposed to be in fastticks units.
 * One fasttick unit is 1/Basetickfreq seconds.
 */
void
timerset(Tval next)
{
	int x;
	long period;

	if(next == 0)
		return;
	x = splhi();			/* don't let us get scheduled */
	period = next - fastticks(nil);
	if(period > m->maxperiod - m->minperiod)
		period = m->maxperiod;
	else if(period < m->minperiod)
		period = m->minperiod;
	wrcompare(rdcount()+period);
	silencewdog();
	splx(x);
}
Esempio n. 5
0
File: proc.c Progetto: 8l/inferno
int
wakeup(Rendez *r)
{
	Proc *p;
	int s;

	s = splhi();
	lock(r);
	p = r->p;
	if(p){
		r->p = nil;
		if(p->state != Wakeme)
			panic("wakeup: state");
		ready(p);
	}
	unlock(r);
	splx(s);
	return p != nil;
}
Esempio n. 6
0
void
flushmmu(void)
{
	int s, i;
	ulong p;
	ulong *l1;

	l1 = KADDR(L1PT);
	s = splhi();
	for(i = 0; i < nelem(up->l1); i++){
		p = l1[i];
		if(p & Small)
			free(KADDR(ROUNDDN(p, BY2PG)));
	}
	memset(up->l1, 0, sizeof up->l1);
	memset(l1, 0, sizeof up->l1);
	flushtlb();
	splx(s);
}
Esempio n. 7
0
File: proc.c Progetto: 8l/inferno
void
sched(void)
{
	if(up) {
		splhi();
		procsave(up);
		if(setlabel(&up->sched)) {
			/* procrestore(up); */
			spllo();
			return;
		}
		gotolabel(&m->sched);
	}
	up = runproc();
	up->state = Running;
	up->mach = MACHP(m->machno);	/* m might be a fixed address; use MACHP */
	m->proc = up;
	gotolabel(&up->sched);
}
Esempio n. 8
0
/* estimate instructions/s. */
static int
guessmips(long (*loop)(void), char *)
{
	int s;
	long cyc;

	do {
		s = splhi();
		cyc = loop();
		splx(s);
		if (cyc < 0)
			iprint("again...");
	} while (cyc < 0);
	/*
	 * Instrs instructions took cyc cycles @ Basetickfreq Hz.
	 * round the result.
	 */
	return (((vlong)Basetickfreq * Instrs) / cyc + Mhz/2) / Mhz;
}
Esempio n. 9
0
void
swcursorclock(void)
{
	int x;
	if(!swenabled)
		return;
	if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers)
		return;

	x = splhi();
	if(swenabled)
	if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers)
	if(canqlock(&drawlock)){
		swcursorhide();
		swcursordraw();
		qunlock(&drawlock);
	}
	splx(x);
}
Esempio n. 10
0
vm_offset_t
himem_convert(
	vm_offset_t	phys_addr,
	vm_size_t	length,
	int		io_op,
	hil_t		*hil)
{
	hil_t		h;
	spl_t		ipl;
	vm_offset_t	offset = phys_addr & (I386_PGBYTES - 1);

	assert (offset + length <= I386_PGBYTES);

	ipl = splhi();
	simple_lock(&hil_lock);
	while (!(h = hil_head)) { 
		printf("WARNING: out of HIMEM pages\n");
		thread_sleep_simple_lock((event_t)&hil_head,
					simple_lock_addr(hil_lock), FALSE);
		simple_lock (&hil_lock);
	}
	hil_head = hil_head->next;
	simple_unlock(&hil_lock);
	splx(ipl);
	
	h->high_addr = phys_addr;

	if (io_op == D_WRITE) {
	  bcopy((char *)phystokv(phys_addr), (char *)phystokv(h->low_page + offset),
		length);
	  h->length = 0;
	} else {
	  h->length = length;
	}
	h->offset = offset;

	assert(!*hil || (*hil)->high_addr);

	h->next = *hil;
	*hil = h;
	return(h->low_page + offset);
}
Esempio n. 11
0
File: mmu.c Progetto: 8l/inferno
/*
 * map a physical addresses at pa to va, with the given attributes.
 * the virtual address must not be mapped already.
 * if va is nil, map it at pa in virtual space.
 */
void*
kmapphys(void *va, ulong pa, ulong nb, ulong attr, ulong le)
{
	int s, i;
	ulong size;

	if(va == nil)
		va = (void*)pa;	/* simplest is to use a 1-1 map */
	size = 1024;
	for(i = 0; i < 8 && size < nb; i++)
		size <<= 2;
	if(i >= 8)
		return nil;
	s = splhi();
	tlbwelo(tlbx, pa | TLBZONE(0) | attr);
	tlbwehi(tlbx, (ulong)va | (i<<7) | TLBVALID | le);
	tlbx++;
	splx(s);
	return va;
}
Esempio n. 12
0
uint_t
read_rtc(struct rtc_t *rtc)
{
	int s;
	uint_t rtc_readable = 0;

	s = splhi();
	/*
	 * If UIP bit is not set we have at least 274us
	 * to read the values. Otherwise we have up to
	 * 336us to wait before we can read it
	 */
	if (!(RTC_GET8(RTC_A) & RTC_UIP)) {
		rtc_readable = 1;

		rtc->rtc_sec = RTC_GET8(RTC_SEC);
		rtc->rtc_asec = RTC_GET8(RTC_ASEC);
		rtc->rtc_min = RTC_GET8(RTC_MIN);
		rtc->rtc_amin = RTC_GET8(RTC_AMIN);

		rtc->rtc_hrs = RTC_GET8(RTC_HRS);
		rtc->rtc_ahrs = RTC_GET8(RTC_AHRS);
		rtc->rtc_dow = RTC_GET8(RTC_DOW);
		rtc->rtc_dom = RTC_GET8(RTC_DOM);
		rtc->rtc_adom = RTC_GET8(RTC_D) & 0x3f;

		rtc->rtc_mon = RTC_GET8(RTC_MON);
		rtc->rtc_year = RTC_GET8(RTC_YEAR);
		rtc->rtc_century = RTC_GET8(RTC_CENTURY);
		rtc->rtc_amon = 0;

		/* Clear wakeup data */
		rtc->apc_wdwr = 0;
		rtc->apc_wdmr = 0;
		rtc->apc_wmr = 0;
		rtc->apc_wyr = 0;
		rtc->apc_wcr = 0;
	}
	splx(s);
	return (rtc_readable);
}
Esempio n. 13
0
/*
 *  called splhi() by notify().  See comment in notify for the
 *  reasoning.
 */
void
procctl(void)
{
	char *state;
	ulong s;

	switch(up->procctl) {
	case Proc_exitbig:
		spllo();
		pprint("Killed: Insufficient physical memory\n");
		pexit("Killed: Insufficient physical memory", 1);

	case Proc_exitme:
		spllo();		/* pexit has locks in it */
		pexit("Killed", 1);

	case Proc_traceme:
		if(up->nnote == 0)
			return;
		/* No break */

	case Proc_stopme:
		up->procctl = 0;
		state = up->psstate;
		up->psstate = "Stopped";
		/* free a waiting debugger */
		s = spllo();
		qlock(&up->debug);
		if(up->pdbg != nil) {
			wakeup(&up->pdbg->sleep);
			up->pdbg = nil;
		}
		qunlock(&up->debug);
		splhi();
		up->state = Stopped;
		sched();
		up->psstate = state;
		splx(s);
		return;
	}
}
Esempio n. 14
0
File: mp.c Progetto: 8l/inferno
void
mpshutdown(void)
{
	/*
	 * To be done...
	 */
	if(!canlock(&mpshutdownlock)){
		/*
		 * If this processor received the CTRL-ALT-DEL from
		 * the keyboard, acknowledge it. Send an INIT to self.
		 */
#ifdef FIXTHIS
		if(lapicisr(VectorKBD))
			lapiceoi(VectorKBD);
#endif /* FIX THIS */
		idle();
	}

	print("apshutdown: active = 0x%2.2uX\n", active.machs);
	delay(1000);
	splhi();

	/*
	 * INIT all excluding self.
	 */
	lapicicrw(0, 0x000C0000|ApicINIT);

#ifdef notdef
	/*
	 * Often the BIOS hangs during restart if a conventional 8042
	 * warm-boot sequence is tried. The following is Intel specific and
	 * seems to perform a cold-boot, but at least it comes back.
	 */
	*(ushort*)KADDR(0x472) = 0x1234;	/* BIOS warm-boot flag */
	outb(0xCF9, 0x02);
	outb(0xCF9, 0x06);
#else
	pcireset();
	i8042reset();
#endif /* notdef */
}
Esempio n. 15
0
void
archreboot(void)
{
	Clkrst *clk = (Clkrst *)soc.clkrst;

	assert(m->machno == 0);
	iprint("archreboot: reset!\n");
	delay(20);

	clk->rstdevl |= Sysreset;
	coherence();
	delay(500);

	/* shouldn't get here */
	splhi();
	iprint("awaiting reset");
	for(;;) {
		delay(1000);
		print(".");
	}
}
Esempio n. 16
0
File: proc.c Progetto: npe9/harvey
int
canpage(Proc *p)
{
	int ok;
	Sched *sch;

	splhi();
	sch = procsched(p);
	lock(sch);
	/* Only reliable way to see if we are Running */
	if(p->mach == 0) {
		p->newtlb = 1;
		ok = 1;
	}
	else
		ok = 0;
	unlock(sch);
	spllo();

	return ok;
}
Esempio n. 17
0
File: qio.c Progetto: 8l/inferno
int
qbgetc(Queue *q)
{
	Block *b;
	int s, c;

	c = -1;
	s = splhi();
	while(c < 0 && (b = q->first) != nil){
		if(b->rp < b->wp){
			c = *b->rp++;
			q->len--;
		}
		if(b->rp >= b->wp){
			q->first = b->next;
			b->next = nil;
		}
	}
	splx(s);
	return c;
}
Esempio n. 18
0
uvlong
fastticks(uvlong *hz)
{
	Systimers *tn;
	ulong lo, hi;
	uvlong now;
	int s;

	if(hz)
		*hz = SystimerFreq;
	tn = (Systimers*)SYSTIMERS;
	s = splhi();
	do{
		hi = tn->chi;
		lo = tn->clo;
	}while(tn->chi != hi);
	now = (uvlong)hi<<32 | lo;
	m->fastclock = now;
	splx(s);
	return m->fastclock;
}
Esempio n. 19
0
File: clock.c Progetto: CoryXie/NxM
/* estimate instructions/s. using 32kHz clock */
static void
guessmips(long (*loop)(void), char *lab)
{
	int s;
	long tcks;

	do {
		s = splhi();
		tcks = loop();
		splx(s);
		if (tcks < 0)
			iprint("again...");
	} while (tcks < 0);
	/*
	 * Instrs instructions took tcks ticks @ Clockfreqbase Hz.
	 */
	s = ((vlong)Clockfreqbase * Instrs) / tcks / 1000000;
	if (Debug)
		iprint("%ud mips (%s-issue)", s, lab);
	USED(s);
}
Esempio n. 20
0
/*
 *  here at the end of non-clock interrupts to see if we should preempt the
 *  current process.  Returns 1 if preempted, 0 otherwise.
 */
int
preempted(void)
{
	if(up && up->state == Running)
	if(up->preempted == 0)
	if(anyhigher())
	if(!active.exiting){
		/*  Core 0 is dispatching all interrupts, so no core
		 *  actually running a user process is ever going call preempted, unless
		 *  we consider IPIs for preemption or we distribute interrupts.
		 *  But we are going to use SMP for machines with few cores.
		panic("preemted used");
		 */

		up->preempted = 1;
		sched();
		splhi();
		up->preempted = 0;
		return 1;
	}
	return 0;
}
Esempio n. 21
0
KMap*
kmap(Page *page)
{
	uintptr *pte, pa, va;
	int x;

	pa = page->pa;
	if(cankaddr(pa) != 0)
		return (KMap*)KADDR(pa);

	x = splhi();
	va = KMAP + ((uintptr)up->kmapindex << PGSHIFT);
	pte = mmuwalk(m->pml4, va, 0, 1);
	if(pte == 0 || *pte & PTEVALID)
		panic("kmap: pa=%#p va=%#p", pa, va);
	*pte = pa | PTEWRITE|PTEVALID;
 	up->kmapindex = (up->kmapindex + 1) % (1<<PTSHIFT);
	if(up->kmapindex == 0)
		mmuflushtlb();
	splx(x);
	return (KMap*)va;
}
Esempio n. 22
0
static void
schedready(Sched *sch, Proc *p, int locked)
{
	Mpl pl;
	int pri;
	Schedq *rq;

	pl = splhi();
	if(edfready(p)){
		splx(pl);
		return;
	}

	updatecpu(p);
	pri = reprioritize(p);
	p->priority = pri;
	rq = &sch->runq[pri];
	p->state = Ready;
	queueproc(sch, rq, p, locked);
	if(p->trace)
		proctrace(p, SReady, 0);
	splx(pl);
}
Esempio n. 23
0
Block*
allocb(int size)
{
	Block *b;

	/*
	 * Check in a process and wait until successful.
	 * Can still error out of here, though.
	 */
	if(up == nil)
		panic("allocb without up: %#p", getcallerpc(&size));
	if((b = _allocb(size)) == nil){
		splhi();
		xsummary();
		mallocsummary();
		delay(500);
		panic("allocb: no memory for %d bytes; caller %#p", size,
			getcallerpc(&size));
	}
	setmalloctag(b, getcallerpc(&size));

	return b;
}
Esempio n. 24
0
/*
 *  microseconds delay
 */
void
microdelay(int l)
{
	int s;
	ulong x, cyc, cnt, speed;

	speed = m->speed;
	if (speed == 0)
		speed = cpufreq / Mhz;
	cyc = (ulong)l * (speed / Cyccntres);
	s = splhi();
	cnt = rdcount();
	x = cnt + cyc;
	if (x < cnt || x >= ~0ul - cpufreq/Cyccntres) {
		/* counter will wrap between now and x, or x is too near ~0 */
		wrcount(0);			/* somewhat drastic */
		wrcompare(rdcompare() - cnt);	/* match new count */
		x = cyc;
	}
	while(rdcount() < x)
		;
	splx(s);
}
Esempio n. 25
0
/*
 *  if the controller or a specific drive is in a confused state,
 *  reset it and get back to a kown state
 */
static void
floppyrevive(void)
{
    FDrive *dp;

    /*
     *  reset the controller if it's confused
     */
    if(fl.confused) {
        DPRINT("floppyrevive in\n");
        fldump();

        /* reset controller and turn all motors off */
        splhi();
        fl.ncmd = 1;
        fl.cmd[0] = 0;
        outb(Pdor, 0);
        delay(10);
        outb(Pdor, Fintena|Fena);
        delay(10);
        spllo();
        fl.motor = 0;
        fl.confused = 0;
        floppywait(0);

        /* mark all drives in an unknown state */
        for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++)
            dp->confused = 1;

        /* set rate to a known value */
        outb(Pdsr, 0);
        fl.rate = 0;

        DPRINT("floppyrevive out\n");
        fldump();
    }
}
Esempio n. 26
0
File: mmu.c Progetto: qioixiy/harvey
void
mmuswitch(Proc* proc)
{
	Proc *up = externup();
	PTE *pte;
	Page *page;
	Mpl pl;

	pl = splhi();
	if(proc->newtlb){
		/*
 		 * NIX: We cannot clear our page tables if they are going to
		 * be used in the AC
		 */
		if(proc->ac == nil)
			mmuptpfree(proc, 1);
		proc->newtlb = 0;
	}

	if(machp()->pml4->daddr){
		memset(UINT2PTR(machp()->pml4->va), 0, machp()->pml4->daddr*sizeof(PTE));
		machp()->pml4->daddr = 0;
	}

	pte = UINT2PTR(machp()->pml4->va);
	for(page = proc->mmuptp[3]; page != nil; page = page->next){
		pte[page->daddr] = PPN(page->pa)|PteU|PteRW|PteP;
		if(page->daddr >= machp()->pml4->daddr)
			machp()->pml4->daddr = page->daddr+1;
		page->prev = machp()->pml4;
	}

	tssrsp0(machp(), STACKALIGN(PTR2UINT(proc->kstack+KSTACK)));
	cr3put(machp()->pml4->pa);
	splx(pl);
}
Esempio n. 27
0
File: mmu.c Progetto: qioixiy/harvey
int
mmuwalk(PTE* pml4, uintptr_t va, int level, PTE** ret,
	uint64_t (*alloc)(usize))
{
	Proc *up = externup();
	int l;
	uintmem pa;
	PTE *pte;

	Mpl pl;

	pl = splhi();
	if(DBGFLG > 1)
		DBG("mmuwalk%d: va %#p level %d\n", machp()->machno, va, level);
	pte = &pml4[PTLX(va, 3)];
	for(l = 3; l >= 0; l--){
		if(l == level)
			break;
		if(!(*pte & PteP)){
			if(alloc == nil)
				break;
			pa = alloc(PTSZ);
			if(pa == ~0)
				return -1;
			memset(UINT2PTR(KADDR(pa)), 0, PTSZ);
			*pte = pa|PteRW|PteP;
		}
		else if(*pte & PtePS)
			break;
		pte = UINT2PTR(KADDR(PPN(*pte)));
		pte += PTLX(va, l-1);
	}
	*ret = pte;
	splx(pl);
	return l;
}
Esempio n. 28
0
static void
i8250putc(Uart* uart, int c)
{
	int i;
	Ctlr *ctlr;

	if (!normalprint) {		/* too early; use brute force */
		int s = splhi();

		while (!(((ulong *)PHYSCONS)[Lsr] & Thre))
			;
		((ulong *)PHYSCONS)[Thr] = c;
		coherence();
		splx(s);
		return;
	}

	ctlr = uart->regs;
	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
		delay(1);
	csr8o(ctlr, Thr, (uchar)c);
	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
		delay(1);
}
Esempio n. 29
0
/*
 *  The rewriting of compare in this routine shouldn't be necessary.
 *  However, we lose clock interrupts if I don't, either a chip bug
 *  or one of ours -- presotto
 */
uvlong
fastticks(uvlong *hz)
{
	int x;
	ulong delta, count;

	if(hz)
		*hz = basetickfreq;

	/* avoid reentry on interrupt or trap, to prevent recursion */
	x = splhi();
	count = rdcount();
	if(rdcompare() - count > m->maxperiod)
		wrcompare(count+m->maxperiod);

	if (count < m->lastcount)		/* wrapped around? */
		delta = count + ((1ull<<32) - m->lastcount);
	else
		delta = count - m->lastcount;
	m->lastcount = count;
	m->fastticks += delta;
	splx(x);
	return m->fastticks;
}
Esempio n. 30
0
	outb(0xcf9, 0x06);

	for(;;)
		idle();
}

/*
 * 386 has no compare-and-swap instruction.
 * Run it with interrupts turned off instead.
 */
static int
cmpswap386(long *addr, long old, long new)
{
	int r, s;

	s = splhi();
	if(r = (*addr == old))
		*addr = new;
	splx(s);
	return r;
}

/*
 * On a uniprocessor, you'd think that coherence could be nop,
 * but it can't.  We still need a barrier when using coherence() in
 * device drivers.
 *
 * On VMware, it's safe (and a huge win) to set this to nop.
 * Aux/vmware does this via the #P/archctl file.
 */
void (*coherence)(void) = nop;