V10/lsys/md/machmfair.c

/*
 * machine-specific hardware routines,
 * these for MicroVAX III
 */

#include "sys/param.h"
#include "sys/pte.h"
#include "sys/mtpr.h"
#include "sys/vm.h"
#include "sys/qbio.h"
#include "sys/clock.h"

#define	CADR	37		/* first-level cache control */
#define	IORESET	55		/* reset all IO connections */
#define	CEN	020		/* cacr: cache enable */
#define	CAEN	0360		/* CADR: enable both halves, both I and D */

/*
 * bits in console mailbox
 */

#define	HALTACT	03	/* halt action */
#define	HMRBOOT	0	/* halt: restart, then boot (if halts disabled!) */
#define	HMRST	01	/* halt: restart regardless (but never boot) */
#define	HMBOOT	02	/* halt: boot */
#define	BOOTIH	04	/* boot inhibit */
#define	RSTIH	010	/* restart inhibit */

char *iospace;
int delayfact = 3;		/* factor for DELAY macro */

/*
 * adjust physical top of memory to useful top of memory:
 * preserve memory bitmap (one bit per 512-byte page)
 * and Q-bus map, which steals memory as well
 * the console is meant to have left it all at the top
 * but we may not have found the top, if intermediate bits are broken
 */
machmem(hi)
register int hi;
{
	register int qm;

	qm = *(int *)0x20080010;	/* addr of Q-bus map in mem */
	qm -= qm/(NBPG*NBBY);		/* bitmap */
	if (hi < qm)			/* in case memory has holes */
		return (hi);
	return (qm);
}

/*
 * miscellaneous machine-dependent initialization
 * called just after mapping turned on
 *
 * - make instruction emulation code accessible from user space
 * - reset and enable IO
 * - enable caches
 *
 * eventually some of the init stuff moves to machreset
 */
machinit()
{
	register int *p;		/* pun; really struct pte */
	register char *e;
	register struct iomfair *q;
	register int i;
	extern char _emulbeg, _emulend;

	e = &_emulbeg;
	p = (int *)&Sysmap[btop((int)e & ~KSTART)];
	do {
		*p = (*p &~ PG_PROT) | PG_URKR;
		p++;
		e += NBPG;
	} while (e < &_emulend);
	mtpr(IORESET, 0);
	q = (struct iomfair *)iospace;
	for (i = 0; i < CACHESIZE; i++)
		q->d.cd[i] = 0;		/* flush second-level cache */
	q->d.cacr |= CEN;	/* and enable it */
	mtpr(CADR, mfpr(CADR)|CAEN);
	machreset();
	mcrinit();
}

/*
 * stray interrupt handling:
 * just decrypt it and return
 */
strayintr(v)
int v;
{
	if (v < 0x200)
		printf("stray interrupt at 0x%x\n", v);
	else
		printf("stray Q-bus interrupt at 0%o\n", v-0x200);
}

/*
 * how big is io space?
 */

mchiopsize()
{
	return (sizeof(struct iomfair));
}

/*
 * set up the page tables for iospace
 * called while the system page table is being assembled;
 * memory mapping is off
 * pt is the first page table of an area
 * mapping what mchiopsize returned
 */

mchiopinit(pt)
struct pte *pt;
{
	register long *p;	/* pun, for efficiency */
	register long b;
	register int i;

	p = (long *)pt;
	*p++ = PG_V|PG_KW|btop(0x20080000);	/* cpu regs */
	*p++ = PG_V|PG_KW|btop(0x20140400);	/* NVRAM */
	*p++ = PG_V|PG_KW|btop(0x20084000);	/* cache register */
	b = btop(0x10000000);			/* cache diagnostic space */
	for (i = 0; i < btop(CACHESIZE*sizeof(long)); i++)
		*p++ = PG_V|PG_KW|b++;
	b = btop(0x20088000);			/* Q-bus map */
	for (i = 0; i < btop(NQMREG*sizeof(long)); i++)
		*p++ = PG_V|PG_KW|b++;
	b = btop(0x20000000);			/* Q-bus io regs */
	for (i = 0; i < btop(8192); i++)
		*p++ = PG_V|PG_KW|b++;
}

/*
 * return the IO regs for a Q-bus adapter
 * (there's really only one, but only this code knows that)
 */

caddr_t
qbaaddr(u)
int u;
{
	if (u != 0)
		return (0);
	return ((caddr_t)&((struct iomfair *)iospace)->u[u]);
}

/*
 * arrange for a restart on halt
 * -- it would be slightly preferable
 * to fall back to a boot if the restart fails;
 * alas, to do that on MicroVAX II or III,
 * you must disable console halts
 */

setrestart()
{
	register short *p;

	p = &((struct iomfair *)iospace)->w.cpmbx;
	*p &=~ (BOOTIH|RSTIH|HALTACT);
	*p |= HMRST;		/* always just restart */
}

/*
 * arrange for a boot, now or on next halt
 * -- sometimes called with mapping disabled
 */

setboot()
{
	register short *p;

	if (mfpr(MAPEN))
		p = &((struct iomfair *)iospace)->w.cpmbx;
	else
		p = (short *)0x20140400;
	*p &=~ (BOOTIH|RSTIH|HALTACT);
	*p |= HMBOOT;		/* halt mode `boot' */
}

/*
 * fetch/set time-of-year clock
 */

gettodr()
{
	return (mfpr(TODR));
}

settodr(t)
long t;
{
	mtpr(TODR, t);
}