ref: d09e6e509b73961bbed6bdde5b718acdbdecd13d
dir: /sys/src/9/mt7688/main.c/
#include "u.h"
#include "tos.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include <pool.h>
#include "../ip/ip.h"
#include <../port/error.h>
FPsave initfp;
/*
* software tlb simulation
*/
static Softtlb stlb[MAXMACH][STLBSIZE];
Conf conf;
Mach* machaddr[MAXMACH];
static void
checkclock0(void)
{
print("count=%luX compare=%luX %d\n", rdcount(), rdcompare(), m->speed);
delay(20);
}
static void
checkconf0(void)
{
iprint("frc0 check = %p\n", getfcr0);
// for debug stuff
}
static void
prcpuid(void)
{
ulong cpuid, cfg1;
char *cpu;
cpuid = prid();
if (((cpuid>>16) & MASK(8)) == 0) /* vendor */
cpu = "old mips";
else if (((cpuid>>16) & MASK(8)) == 1)
switch ((cpuid>>8) & MASK(8)) { /* processor */
case 0x93:
cpu = "mips 24k";
break;
case 0x96:
cpu = "mips 24KEc";
break;
default:
cpu = "mips";
break;
}
else
cpu = "other mips";
delay(20);
print("cpu%d: %ldMHz %s %s v%ld %ld rev %ld, ",
m->machno, m->hz / Mhz, cpu, getconfig() & (1<<15)? "b": "l",
(cpuid>>5) & MASK(3), (cpuid>>2) & MASK(3), cpuid & MASK(2));
delay(200);
cfg1 = getconfig1();
print("%s fpu\n", (cfg1 & 1? "has": "no"));
print("cpu%d: %ld tlb entries, using %dK pages\n", m->machno,
((cfg1>>25) & MASK(6)) + 1, BY2PG/1024);
delay(50);
print("cpu%d: l1 i cache: %d sets 4 ways 32 bytes/line\n", m->machno,
64 << ((cfg1>>22) & MASK(3)));
delay(50);
print("cpu%d: l1 d cache: %d sets 4 ways 32 bytes/line\n", m->machno,
64 << ((cfg1>>13) & MASK(3)));
delay(500);
/* i changed this if from 0 to 1 */
if (1)
print("cpu%d: cycle counter res = %ld\n",
m->machno, gethwreg3());
}
static void
fmtinit(void)
{
printinit();
}
static int
ckpagemask(ulong mask, ulong size)
{
int s;
ulong pm;
s = splhi();
setpagemask(mask);
pm = getpagemask();
splx(s);
if(pm != mask){
iprint("page size %ldK not supported on this cpu; "
"mask %#lux read back as %#lux\n", size/1024, mask, pm);
return -1;
}
return 0;
}
void
main(void)
{
uartconsinit();
quotefmtinstall();
confinit();
machinit(); /* calls clockinit */
active.exiting = 0;
active.machs[0] = 1;
kmapinit();
xinit();
timersinit();
plan9iniinit();
intrinit();
iprint("\nPlan 9 \n");
prcpuid();
delay(50);
checkclock0();
print("(m)status %lub\n", getstatus());
ckpagemask(PGSZ, BY2PG);
if (PTECACHED == PTENONCOHERWT)
print("caches configured as write-through\n");
tlbinit();
pageinit();
delay(50);
printinit(); /* what does this do? */
procinit0();
initseg();
links();
chandevreset();
userinit();
schedinit();
}
/*
* initialize a processor's mach structure. each processor does this
* for itself.
*/
void
machinit(void)
{
extern void gevector(void); /* l.s */
extern void utlbmiss(void);
extern void vector0(void);
extern void vector180(void);
void **sbp = (void*)SPBADDR;
MACHP(0) = (Mach*)MACHADDR;
memset(m, 0, sizeof(Mach));
m->machno = 0;
machaddr[m->machno] = m;
/*
* set up CPU's mach structure
* cpu0's was zeroed in l.s and our stack is in Mach, so don't zero it.
*/
m->speed = 580; /* initial guess at MHz */
m->hz = m->speed * Mhz;
conf.nmach = 1;
m->stb = stlb[m->machno];
m->ticks = 1;
m->perf.period = 1;
/* install exception handlers */
sbp[0x18/4] = utlbmiss;
sbp[0x14/4] = gevector;
/* we could install our own vectors directly, but we'll try to play nice */
if(1){
memmove((void*)(KSEG0+0x0), (void*)vector0, 0x80);
memmove((void*)(KSEG0+0x180), (void*)vector180, 0x80);
icflush((void*)(KSEG0+0x0), 0x80);
icflush((void*)(KSEG0+0x180), 0x80);
}
setstatus(getstatus() & ~BEV);
up = nil;
/* Ensure CU1 is off */
clrfpintr();
clockinit();
}
void
init0(void)
{
char buf[128], **sp;
chandevinit();
if(!waserror()){
ksetenv("cputype", "spim", 0);
snprint(buf, sizeof buf, "mips %s", conffile);
ksetenv("terminal", buf, 0);
if(cpuserver)
ksetenv("service", "cpu", 0);
else
ksetenv("service", "terminal", 0);
setconfenv();
poperror();
}
checkconf0();
kproc("alarm", alarmkproc, 0);
sp = (char**)(USTKTOP-sizeof(Tos) - 8 - sizeof(sp[0])*4);
sp[3] = sp[2] = sp[1] = nil;
strcpy(sp[0] = (char*)&sp[4], "boot");
touser(sp);
}
void
exit(int)
{
cpushutdown();
splhi();
if(m->machno == 0){
/* clear secrets */
zeroprivatepages();
poolreset(secrmem);
}
for(;;);
}
void
reboot(void *, void *, ulong)
{
}
void
confinit(void)
{
ulong kpages, ktop;
/*
* divide memory twixt user pages and kernel.
*/
conf.mem[0].base = ktop = PADDR(PGROUND((ulong)end));
/* fixed memory on routerboard */
conf.mem[0].npage = MEMSIZE/BY2PG - ktop/BY2PG;
conf.npage = conf.mem[0].npage;
kpages = conf.npage - (conf.npage*80)/100;
if(kpages > (64*MB + conf.npage*sizeof(Page))/BY2PG){
kpages = (64*MB + conf.npage*sizeof(Page))/BY2PG;
kpages += (conf.nproc*KSTACK)/BY2PG;
}
conf.upages = conf.npage - kpages;
conf.ialloc = (kpages/2)*BY2PG;
kpages *= BY2PG;
kpages -= conf.upages*sizeof(Page)
+ conf.nproc*sizeof(Proc)
+ conf.nimage*sizeof(Image)
+ conf.nswap
+ conf.nswppo*sizeof(Page);
mainmem->maxsize = kpages;
// mainmem->flags |= POOL_PARANOIA;
/* set up other configuration parameters */
conf.nproc = 2000;
conf.nswap = 262144;
conf.nswppo = 4096;
conf.nimage = 200;
conf.copymode = 0; /* copy on write */
}
void
setupwatchpts(Proc *, Watchpt *, int n)
{
if(n > 0)
error("no watchpoints");
}
int
isaconfig(char *, int, ISAConf*)
{
return 0;
}