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);
}