ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /os/cerf250/main.c/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "io.h"
#include "version.h"
#define MAXCONF 32
Mach *m = (Mach*)MACHADDR;
Proc *up = 0;
Vectorpage *page0 = (Vectorpage*)KZERO; /* doubly-mapped to AIVECADDR */
Conf conf;
extern ulong kerndate;
extern int cflag;
extern int main_pool_pcnt;
extern int heap_pool_pcnt;
extern int image_pool_pcnt;
ulong cpuidlecount;
char *confname[MAXCONF];
char *confval[MAXCONF];
int nconf;
void addconf(char *, char *);
void eepromscan(void);
char* getconf(char*);
void
doc(char *m)
{
USED(m);
print("%s...\n", m);
}
void
idoc(char *m)
{
uartputs(m, strlen(m)); //xdelay(1);
}
static void
poolsizeinit(void)
{
ulong nb;
nb = conf.npage*BY2PG;
poolsize(mainmem, (nb*main_pool_pcnt)/100, 0);
poolsize(heapmem, (nb*heap_pool_pcnt)/100, 0);
poolsize(imagmem, (nb*image_pool_pcnt)/100, 1);
}
static void
serialconsole(void)
{
char *p;
int port, baud;
p = getconf("console");
if(p == nil)
p = "0";
if(p != nil){
port = strtol(p, nil, 0);
baud = 38400;
p = getconf("baud");
if(p != nil){
baud = strtol(p, nil, 0);
if(baud < 38400)
baud = 38400;
}
uartspecial(port, baud, &kbdq, &printq, kbdcr2nl);
}
}
static char *hello = "Inferno\n";
void
main(void)
{
memset(edata, 0, end-edata); /* clear the BSS */
memset(m, 0, sizeof(Mach)); /* clear the mach struct */
conf.nmach = 1;
archreset();
idoc(hello);
if(0){
putcclkcfg(0); /* leave turbo mode */
COREREG->cccr = (COREREG->cccr & ~(7<<7)) | (4<<7); /* turbo mode multiplier=2 */
putcclkcfg(1); /* enter turbo mode */
}
quotefmtinstall();
idoc("confinit...\n");
confinit();
idoc("xinit...\n");
xinit();
idoc("mmuinit...\n");
mmuinit();
poolsizeinit();
poolinit();
idoc("trapinit...\n");
trapinit();
// dmareset();
idoc("printinit...\n");
printinit();
idoc("uartinstall...\n");
uartinstall();
eepromscan();
doc("clockinit");
clockinit();
doc("screeninit");
// screeninit();
doc("procinit");
procinit();
// cpuidprint();
doc("links");
links();
doc("chandevreset");
chandevreset();
eve = strdup("inferno");
serialconsole();
kbdinit();
print("%ld MHz id %8.8lux\n", (m->cpuhz+500000)/1000000, getcpuid());
print("\nInferno %s\n", VERSION);
print("Vita Nuova\n");
print("conf %s (%lud) jit %d\n\n",conffile, kerndate, cflag);
print("pmcr=%8.8lux pwer=%8.8lux prer=%8.8lux pfer=%8.8lux pedr=%8.8lux pcfr=%8.8lux rcsr=%8.8lux\n",
PMGRREG->pmcr, PMGRREG->pwer, PMGRREG->prer, PMGRREG->pfer, PMGRREG->pedr, PMGRREG->pcfr,
PMGRREG->rcsr);
print("cccr=%8.8lux cken=%8.8lux oscc=%8.8lux\n", COREREG->cccr, COREREG->cken, COREREG->oscc);
print("msc0=%8.8lux mcs1=%8.8lux mcs2=%8.8lux\n", MEMCFGREG->msc0, MEMCFGREG->msc1, MEMCFGREG->msc2);
print("clkcfg=%8.8lux\n", getcclkcfg());
userinit();
schedinit();
}
void
reboot(void)
{
exit(0);
}
void
halt(void)
{
spllo();
print("cpu halted\n");
for(;;){
/* nothing to do */
}
}
Conf conf;
void
addconf(char *name, char *val)
{
if(nconf >= MAXCONF)
return;
confname[nconf] = name;
confval[nconf] = val;
nconf++;
}
char*
getconf(char *name)
{
int i;
for(i = 0; i < nconf; i++)
if(cistrcmp(confname[i], name) == 0)
return confval[i];
return 0;
}
void
confinit(void)
{
ulong base;
archconfinit();
base = PGROUND((ulong)end);
conf.base0 = base;
conf.base1 = 0;
conf.npage1 = 0;
conf.npage0 = (conf.topofmem - base)/BY2PG;
conf.npage = conf.npage0 + conf.npage1;
conf.ialloc = (((conf.npage*(main_pool_pcnt))/100)/2)*BY2PG;
conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
conf.nmach = 1;
}
void
init0(void)
{
Osenv *o;
char buf[2*KNAMELEN];
up->nerrlab = 0;
spllo();
if(waserror())
panic("init0 %r");
/*
* These are o.k. because rootinit is null.
* Then early kproc's will have a root and dot.
*/
o = up->env;
o->pgrp->slash = namec("#/", Atodir, 0, 0);
cnameclose(o->pgrp->slash->name);
o->pgrp->slash->name = newcname("/");
o->pgrp->dot = cclone(o->pgrp->slash);
chandevinit();
if(!waserror()){
ksetenv("cputype", "arm", 0);
snprint(buf, sizeof(buf), "arm %s", conffile);
ksetenv("terminal", buf, 0);
poperror();
}
poperror();
disinit("/osinit.dis");
}
void
userinit(void)
{
Proc *p;
Osenv *o;
p = newproc();
o = p->env;
o->fgrp = newfgrp(nil);
o->pgrp = newpgrp();
o->egrp = newegrp();
kstrdup(&o->user, eve);
strcpy(p->text, "interp");
p->fpstate = FPINIT;
/*
* Kernel Stack
*
* N.B. The -12 for the stack pointer is important.
* 4 bytes for gotolabel's return PC
*/
p->sched.pc = (ulong)init0;
p->sched.sp = (ulong)p->kstack+KSTACK-8;
ready(p);
}
void
exit(int inpanic)
{
up = 0;
/* Shutdown running devices */
chandevshutdown();
if(inpanic && 0){
print("Hit the reset button\n");
for(;;)
clockpoll();
}
archreboot();
}
static void
linkproc(void)
{
spllo();
if (waserror())
print("error() underflow: %r\n");
else
(*up->kpfun)(up->arg);
pexit("end proc", 1);
}
void
kprocchild(Proc *p, void (*func)(void*), void *arg)
{
p->sched.pc = (ulong)linkproc;
p->sched.sp = (ulong)p->kstack+KSTACK-8;
p->kpfun = func;
p->arg = arg;
}
void
idlehands(void)
{
cpuidlecount++;
INTRREG->iccr = 1; /* only unmasked interrupts will stop idle mode */
idle();
}
/* stubs */
void
setfsr(ulong)
{
}
ulong
getfsr()
{
return 0;
}
void
setfcr(ulong)
{
}
ulong
getfcr()
{
return 0;
}
void
fpinit(void)
{
}
void
FPsave(void*)
{
}
void
FPrestore(void*)
{
}