## diffname alphapc/main.c 1999/0415
## diff -e /dev/null /n/emeliedump/1999/0415/sys/src/brazil/alphapc/main.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "init.h"
#include "pool.h"
#include "/sys/src/boot/alphapc/conf.h"
#include "axp.h"
char argbuf[128]; /* arguments passed to initcode and /boot */
Hwrpb *hwrpb;
Bootconf *bootconf;
Conf conf;
FPsave initfp;
void
main(void)
{
hwrpb = (Hwrpb*)0x10000000;
hwrpb = (Hwrpb*)(KZERO|hwrpb->phys);
arginit();
machinit();
clockinit();
confinit();
archinit();
savefpregs(&initfp);
mmuinit();
xinit();
printinit();
if (arch->coreinit)
arch->coreinit();
trapinit();
/* console */
screeninit();
ns16552install();
ns16552special(0, 9600, 0, &printq, kbdcr2nl);
kbdinit();
cpuidprint();
if (arch->corehello)
arch->corehello();
#ifdef NEVER
percpu = hwrpb + (hwrpb[40]>>2);
// percpu[32] |= 2; /* restart capable */
percpu[32] &= ~1; /* boot in progress - not */
// percpu[32] |= (3<<16); /* warm boot requested */
// percpu[32] |= (2<<16); /* cold boot requested */
// percpu[32] |= (4<<16); /* stay halted */
percpu[32] |= (0<<16); /* default action */
#endif
pageinit();
procinit0();
initseg();
links();
chandevreset();
swapinit();
userinit();
schedinit();
}
/*
* initialize a processor's mach structure. each processor does this
* for itself.
*/
void
machinit(void)
{
int n;
icflush();
n = m->machno;
memset(m, 0, sizeof(Mach));
m->machno = n;
active.exiting = 0;
active.machs = 1;
}
void
init0(void)
{
char buf[2*NAMELEN];
spllo();
/*
* These are o.k. because rootinit is null.
* Then early kproc's will have a root and dot.
*/
up->slash = namec("#/", Atodir, 0, 0);
up->dot = cclone(up->slash, 0);
chandevinit();
if(!waserror()){
ksetenv("cputype", "alpha");
sprint(buf, "alpha %s axp", conffile);
ksetenv("terminal", buf);
ksetenv("sysname", sysname);
poperror();
}
kproc("alarm", alarmkproc, 0);
touser((uchar*)(USTKTOP - sizeof(argbuf)));
}
void
userinit(void)
{
Proc *p;
Segment *s;
KMap *k;
char **av;
Page *pg;
p = newproc();
p->pgrp = newpgrp();
p->egrp = smalloc(sizeof(Egrp));
p->egrp->ref = 1;
p->fgrp = dupfgrp(nil);
p->rgrp = newrgrp();
p->procmode = 0640;
strcpy(p->text, "*init*");
strcpy(p->user, eve);
p->fpstate = FPinit;
p->fpsave.fpstatus = initfp.fpstatus;
fpenab(0);
/*
* Kernel Stack
*/
p->sched.pc = (ulong)init0;
p->sched.sp = (ulong)p->kstack+KSTACK-(1+MAXSYSARG)*BY2WD;
/*
* User Stack, pass input arguments to boot process
*/
s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
p->seg[SSEG] = s;
pg = newpage(1, 0, USTKTOP-BY2PG);
segpage(s, pg);
k = kmap(pg);
for(av = (char**)argbuf; *av; av++)
*av += (USTKTOP - sizeof(argbuf)) - (ulong)argbuf;
memmove((uchar*)VA(k) + BY2PG - sizeof(argbuf), argbuf, sizeof argbuf);
kunmap(k);
/*
* Text
*/
s = newseg(SG_TEXT, UTZERO, 1);
s->flushme++;
p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
segpage(s, pg);
k = kmap(s->map[0]->pages[0]);
memmove((uchar*)VA(k), initcode, sizeof initcode);
kunmap(k);
ready(p);
}
void
exit(int)
{
canlock(&active);
active.machs &= ~(1<<m->machno);
active.exiting = 1;
unlock(&active);
spllo();
print("cpu %d exiting\n", m->machno);
do
delay(100);
while(consactive());
splhi();
delay(1000); /* give serial fifo time to finish flushing */
if (arch->coredetach)
arch->coredetach();
firmware();
}
void
confinit(void)
{
long mbytes;
int mul;
ulong ktop;
mbytes = 50; /* BUG FIXME */
/*
* This split of memory into 2 banks fools the allocator into
* allocating low memory pages from bank 0 for the ethernet since
* it has only a 24bit address counter.
* Note that the rom monitor has the bottom 2 megs
*/
conf.npage0 = (8*1024*1024)/BY2PG;
conf.base0 = 0;
conf.npage1 = (mbytes-8)*1024/8;
conf.base1 = 8*1024*1024;
conf.npage = conf.npage0+conf.npage1;
conf.upages = (conf.npage*70)/100;
ktop = PGROUND((ulong)end);
conf.ptebase = ktop;
ktop = PADDR(ktop);
ktop += ((mbytes+7)/8 + 2)*BY2PG; /* space for kernel ptes */
conf.npage0 -= ktop/BY2PG;
conf.base0 += ktop;
conf.mbytes = mbytes;
conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
mul = (mbytes+11)/12;
if(mul > 2)
mul = 2;
conf.nmach = 1;
conf.nproc = 20 + 50*mul;
conf.nswap = conf.nproc*80;
conf.nimage = 50;
conf.copymode = 0; /* copy on write */
if(cpuserver)
conf.nproc = 500;
/* else
conf.monitor = 1; /* BUG */
}
void
lights(int l)
{
USED(l);
}
char *sp;
char *
pusharg(char *p)
{
int n;
n = strlen(p)+1;
sp -= n;
memmove(sp, p, n);
return sp;
}
void
arginit(void)
{
char **av;
av = (char**)argbuf;
sp = argbuf + sizeof(argbuf);
*av++ = pusharg("boot");
*av = 0;
}
/*
* Q&D fake-out of plan9.ini until we resolve the booting issues
*/
char *confname[] =
{
"ether0",
"scsi0",
};
char *confval[] =
{
"type=21140",
"type=aic7xxx",
};
int nconf = nelem(confname);
char *
getconf(char *name)
{
int n;
for(n = 0; n < nconf; n++){
if(cistrcmp(confname[n], name) == 0)
return confval[n];
}
return 0;
}
int
isaconfig(char *class, int ctlrno, ISAConf *isa)
{
char cc[NAMELEN], *p, *q, *r;
int n;
sprint(cc, "%s%d", class, ctlrno);
for(n = 0; n < nconf; n++){
if(cistrncmp(confname[n], cc, NAMELEN))
continue;
isa->nopt = 0;
p = confval[n];
while(*p){
while(*p == ' ' || *p == '\t')
p++;
if(*p == '\0')
break;
if(cistrncmp(p, "type=", 5) == 0){
p += 5;
for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){
if(*p == '\0' || *p == ' ' || *p == '\t')
break;
*q = *p++;
}
*q = '\0';
}
else if(cistrncmp(p, "port=", 5) == 0)
isa->port = strtoul(p+5, &p, 0);
else if(cistrncmp(p, "irq=", 4) == 0)
isa->irq = strtoul(p+4, &p, 0);
else if(cistrncmp(p, "dma=", 4) == 0)
isa->dma = strtoul(p+4, &p, 0);
else if(cistrncmp(p, "mem=", 4) == 0)
isa->mem = strtoul(p+4, &p, 0);
else if(cistrncmp(p, "size=", 5) == 0)
isa->size = strtoul(p+5, &p, 0);
else if(cistrncmp(p, "freq=", 5) == 0)
isa->freq = strtoul(p+5, &p, 0);
else if(isa->nopt < NISAOPT){
r = isa->opt[isa->nopt];
while(*p && *p != ' ' && *p != '\t'){
*r++ = *p++;
if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1)
break;
}
*r = '\0';
isa->nopt++;
}
while(*p && *p != ' ' && *p != '\t')
p++;
}
return 1;
}
return 0;
}
int
cistrcmp(char *a, char *b)
{
int ac, bc;
for(;;){
ac = *a++;
bc = *b++;
if(ac >= 'A' && ac <= 'Z')
ac = 'a' + (ac - 'A');
if(bc >= 'A' && bc <= 'Z')
bc = 'a' + (bc - 'A');
ac -= bc;
if(ac)
return ac;
if(bc == 0)
break;
}
return 0;
}
int
cistrncmp(char *a, char *b, int n)
{
unsigned ac, bc;
while(n > 0){
ac = *a++;
bc = *b++;
n--;
if(ac >= 'A' && ac <= 'Z')
ac = 'a' + (ac - 'A');
if(bc >= 'A' && bc <= 'Z')
bc = 'a' + (bc - 'A');
ac -= bc;
if(ac)
return ac;
if(bc == 0)
break;
}
return 0;
}
.
## diffname alphapc/main.c 1999/0423
## diff -e /n/emeliedump/1999/0415/sys/src/brazil/alphapc/main.c /n/emeliedump/1999/0423/sys/src/brazil/alphapc/main.c
61a
pageinit();
.
57d
## diffname alphapc/main.c 1999/0504
## diff -e /n/emeliedump/1999/0423/sys/src/brazil/alphapc/main.c /n/emeliedump/1999/0504/sys/src/brazil/alphapc/main.c
283a
"type=sb16",
.
276a
"audio0",
.
## diffname alphapc/main.c 1999/0507
## diff -e /n/emeliedump/1999/0504/sys/src/brazil/alphapc/main.c /n/emeliedump/1999/0507/sys/src/brazil/alphapc/main.c
283,284c
"type=2114x",
"type=ata",
"type=ata",
"type=ata",
.
276a
"scsi1",
"scsi2",
.
## diffname alphapc/main.c 1999/0511
## diff -e /n/emeliedump/1999/0507/sys/src/brazil/alphapc/main.c /n/emeliedump/1999/0511/sys/src/brazil/alphapc/main.c
237,238c
conf.monitor = 1; /* BUG */
.
## diffname alphapc/main.c 1999/0514
## diff -e /n/emeliedump/1999/0511/sys/src/brazil/alphapc/main.c /n/emeliedump/1999/0514/sys/src/brazil/alphapc/main.c
288a
"type=2114x",
.
286,287d
279c
"ether1",
.
276,277d
29a
fpenab(0);
.
## diffname alphapc/main.c 1999/0515
## diff -e /n/emeliedump/1999/0514/sys/src/brazil/alphapc/main.c /n/emeliedump/1999/0515/sys/src/brazil/alphapc/main.c
170a
}
void
procsetup(Proc *p)
{
p->fpstate = FPinit;
fpenab(0);
}
void
procsave(Proc *p)
{
if(p->fpstate == FPactive){
if(p->state == Moribund)
fpenab(0);
else{
/*
* Fpsave() stores without handling pending
* unmasked exeptions. Postnote() can't be called
* here as sleep() already has up->rlock, so
* the handling of pending exceptions is delayed
* until the process runs again and generates an
* emulation fault to activate the FPU.
*/
savefpregs(&up->fpsave);
//print("PS=%lux+", up->fpsave.fpstatus);
}
p->fpstate = FPinactive;
}
/*
* Switch to the prototype page tables for this processor.
* While this processor is in the scheduler, the process could run
* on another processor and exit, returning the page tables to
* the free list where they could be reallocated and overwritten.
* When this processor eventually has to get an entry from the
* trashed page tables it will crash.
*/
.
134,136c
procsetup(p);
.
63a
savefpregs(&initfp);
initfp.fpstatus = 0x68028000;
.
50,51c
// percpu[32] |= 2; /* restart capable */
percpu[32] &= ~1; /* boot in progress - not */
.
29,30d
17a
uvlong initfpcr = 0x2800800000000000LL;
.
## diffname alphapc/main.c 2000/0108
## diff -e /n/emeliedump/1999/0515/sys/src/brazil/alphapc/main.c /n/emeliedump/2000/0108/sys/src/9/alphapc/main.c
38d
35a
screeninit();
screenputs("Hello Squidboy\n", 15);
{ static Lock l;
ilock(&l);
xxfirmware();
iunlock(&l);
}
printinit();
.
32d
## diffname alphapc/main.c 2000/0111
## diff -e /n/emeliedump/2000/0108/sys/src/9/alphapc/main.c /n/emeliedump/2000/0111/sys/src/9/alphapc/main.c
36,41d
## diffname alphapc/main.c 2000/0401
## diff -e /n/emeliedump/2000/0111/sys/src/9/alphapc/main.c /n/emeliedump/2000/0401/sys/src/9/alphapc/main.c
440a
}
int
getcfields(char* lp, char** fields, int n, char* sep)
{
int i;
for(i = 0; lp && *lp && i < n; i++){
while(*lp && strchr(sep, *lp) != 0)
*lp++ = 0;
if(*lp == 0)
break;
fields[i] = lp;
while(*lp && strchr(sep, *lp) == 0){
if(*lp == '\\' && *(lp+1) == '\n')
*lp++ = ' ';
lp++;
}
}
return i;
.
307,327d
282a
.
281c
Bank *b, *eb;
b = bootconf->bank;
eb = b+bootconf->nbank;
while(b < eb) {
if(b->min < (1LL<<32) && b->max < (1LL<<32))
xhole(b->min, b->max-b->min);
b++;
}
.
279c
memholes(void)
.
273,274c
if(cpuserver) {
if(userpcnt < 10)
userpcnt = 70;
kpages = conf.npage - (conf.npage*userpcnt)/100;
/*
* Hack for the big boys. Only good while physmem < 4GB.
* Give the kernel a max. of 16MB + enough to allocate the
* page pool.
* This is an overestimate as conf.upages < conf.npages.
* The patch of nimage is a band-aid, scanning the whole
* page list in imagereclaim just takes too long.
*/
if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){
kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;
conf.nimage = 2000;
kpages += (conf.nproc*KSTACK)/BY2PG;
}
} else {
if(userpcnt < 10) {
if(conf.npage*BY2PG < 16*MB)
userpcnt = 40;
else
userpcnt = 60;
}
kpages = conf.npage - (conf.npage*userpcnt)/100;
/*
* Make sure terminals with low memory get at least
* 4MB on the first Image chunk allocation.
*/
if(conf.npage*BY2PG < 16*MB)
imagmem->minarena = 4*1024*1024;
}
conf.upages = conf.npage - kpages;
conf.ialloc = (kpages/2)*BY2PG;
/*
* Guess how much is taken by the large permanent
* datastructures. Mntcache and Mntrpc are not accounted for
* (probably ~300KB).
*/
kpages *= BY2PG;
kpages -= conf.upages*sizeof(Page)
+ conf.nproc*sizeof(Proc)
+ conf.nimage*sizeof(Image)
+ conf.nswap
+ conf.nswppo*sizeof(Page);
mainmem->maxsize = kpages;
if(!cpuserver){
/*
* give terminals lots of image memory, too; the dynamic
* allocation will balance the load properly, hopefully.
* be careful with 32-bit overflow.
*/
imagmem->maxsize = kpages;
}
.
270c
conf.nswppo = 4096;
.
268c
conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
if(cpuserver)
conf.nproc *= 3;
if(conf.nproc > 2000)
conf.nproc = 2000;
conf.nimage = 200;
.
264,266c
/*
* Fix up the bank we found to be the remnant, below the kernel.
* This, and the other banks, will be passed to xhole() later.
* BUG: conf.upages needs to be adjusted, but how? In practice,
* we only have 1 bank, and the remnant is small.
*/
b->max = (uvlong)_main & ~(BY2PG-1);
.
261d
255,258d
249c
conf.npage1 = (b->max-8*1024*1024)/BY2PG;
.
245a
b = bootconf->bank;
eb = b+bootconf->nbank;
ktop = PGROUND((ulong)end);
ktop = PADDR(ktop);
while(b < eb) {
if(b->min < ktop && ktop < b->max)
break;
b++;
}
if(b == eb)
panic("confinit");
/*
* Split the bank of memory into 2 banks to fool the allocator into
* allocating low memory pages from bank 0 for any peripherals
* which only have a 24bit address counter.
*/
.
241,244c
* The console firmware divides memory into 1 or more banks.
* FInd the bank with the kernel in it.
.
238c
if(p = getconf("*kernelpercent"))
userpcnt = 100 - strtol(p, 0, 0);
else
userpcnt = 0;
.
234,236c
ulong ktop, kpages;
Bank *b, *eb;
extern void _main(void);
int userpcnt;
char *p;
.
226c
if(arch->coredetach)
.
107a
if(cpuserver)
ksetenv("service", "cpu");
else
ksetenv("service", "terminal");
for(i = 0; i < nconf; i++)
if(confname[i] && confname[i][0] != '*')
ksetenv(confname[i], confval[i]);
.
105c
sprint(buf, "alpha %s alphapc", conffile);
.
89a
int i;
.
44c
if(arch->corehello)
.
32c
memholes();
mmuinit();
if(arch->coreinit)
.
30d
26a
ioinit();
options();
.
19a
char bootargs[BOOTARGSLEN];
char *confname[MAXCONF];
char *confval[MAXCONF];
int nconf;
static void
options(void)
{
char *cp, *line[MAXCONF];
int i, n;
cp = bootconf->bootargs;
cp[BOOTARGSLEN-1] = 0;
strcpy(bootargs, cp);
n = getcfields(bootargs, line, MAXCONF, "\n");
for(i = 0; i < n; i++){
if(*line[i] == '#')
continue;
cp = strchr(line[i], '=');
if(cp == 0)
continue;
*cp++ = 0;
if(cp - line[i] >= NAMELEN+1)
*(line[i]+NAMELEN-1) = 0;
confname[nconf] = line[i];
confval[nconf] = cp;
nconf++;
}
}
.
## diffname alphapc/main.c 2000/0422
## diff -e /n/emeliedump/2000/0401/sys/src/9/alphapc/main.c /n/emeliedump/2000/0422/sys/src/9/alphapc/main.c
133a
cnameclose(up->slash->name);
up->slash->name = newcname("/");
.
## diffname alphapc/main.c 2000/0929
## diff -e /n/emeliedump/2000/0422/sys/src/9/alphapc/main.c /n/emeliedump/2000/0929/sys/src/9/alphapc/main.c
18c
/* setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPOVFL) */
uvlong initfpcr = (1LL<62)|(1LL<61)|(1LL<60)|(2LL<<58)|(1LL<48);
.
## diffname alphapc/main.c 2001/0727
## diff -e /n/emeliedump/2000/0929/sys/src/9/alphapc/main.c /n/emeliedump/2001/0727/sys/src/9/alphapc/main.c
492,503d
464,479c
isa->nopt = tokenize(confval[n], isa->opt, NISAOPT);
for(i = 0; i < isa->nopt; i++){
p = isa->opt[i];
if(cistrncmp(p, "type=", 5) == 0)
isa->type = p + 5;
.
462c
if(cistrcmp(confname[n], cc) != 0)
.
460c
snprint(cc, sizeof cc, "%s%d", class, ctlrno);
.
457,458c
char cc[32], *p;
int i, n;
.
401c
// conf.monitor = 1; /* BUG */
.
177,178c
kstrdup(&eve, "");
kstrdup(&p->text, "*init*");
kstrdup(&p->user, eve);
.
143,145c
sprint(tstr, "alpha %s alphapc", conffile);
ksetenv("terminal", tstr);
.
137c
up->dot = cclone(up->slash);
.
127a
up->nerrlab = 0;
.
126c
char tstr[32];
.
76a
i8250console();
print("\nPlan 9\n");
.
72,75d
60a
ioinit();
.
59d
43,45c
*cp++ = '\0';
.
41c
if(cp == nil)
.
36c
/*
* Strip out '\r', change '\t' -> ' '.
*/
p = cp;
for(q = cp; *q; q++){
if(*q == '\r')
continue;
if(*q == '\t')
*q = ' ';
*p++ = *q;
}
*p = 0;
n = getfields(cp, line, MAXCONF, 1, "\n");
.
29,30c
long i, n;
char *cp, *line[MAXCONF], *p, *q;
.
## diffname alphapc/main.c 2001/0728
## diff -e /n/emeliedump/2001/0727/sys/src/9/alphapc/main.c /n/emeliedump/2001/0728/sys/src/9/alphapc/main.c
128a
cpu = (Hwcpu*) ((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen);
cpu->state &= ~1; /* boot in progress - not */
/* cpu->state |= (4<<16); /* stay halted */
.
120a
Hwcpu *cpu;
.
91,100d
34d
32c
cp = bootargs;
strncpy(cp, bootconf->bootargs, BOOTARGSLEN);
.
## diffname alphapc/main.c 2001/0731
## diff -e /n/emeliedump/2001/0728/sys/src/9/alphapc/main.c /n/emeliedump/2001/0731/sys/src/9/alphapc/main.c
192c
p->sched.sp = (ulong)p->kstack+KSTACK-MAXSYSARG*BY2WD;
.
## diffname alphapc/main.c 2002/0109
## diff -e /n/emeliedump/2001/0731/sys/src/9/alphapc/main.c /n/emeliedump/2002/0109/sys/src/9/alphapc/main.c
259a
/* still too do */
void
reboot(void*, void*, ulong)
{
exit(0);
}
.
156,157c
if(confname[i])
ksetenv(confname[i], confval[i], 1);
.
154c
ksetenv("service", "terminal", 0);
.
152c
ksetenv("service", "cpu", 0);
.
150c
ksetenv("terminal", tstr, 0);
.
148c
ksetenv("cputype", "alpha", 0);
.
## diffname alphapc/main.c 2002/0112
## diff -e /n/emeliedump/2002/0109/sys/src/9/alphapc/main.c /n/emeliedump/2002/0112/sys/src/9/alphapc/main.c
267d
261c
/* still to do */
.
## diffname alphapc/main.c 2002/0116
## diff -e /n/emeliedump/2002/0112/sys/src/9/alphapc/main.c /n/emeliedump/2002/0116/sys/src/9/alphapc/main.c
258a
mmupark();
.
246,247d
236,244c
else
.
## diffname alphapc/main.c 2002/0217
## diff -e /n/emeliedump/2002/0116/sys/src/9/alphapc/main.c /n/emeliedump/2002/0217/sys/src/9/alphapc/main.c
84a
quotefmtinstall();
.
## diffname alphapc/main.c 2002/0323
## diff -e /n/emeliedump/2002/0217/sys/src/9/alphapc/main.c /n/emeliedump/2002/0323/sys/src/9/alphapc/main.c
158a
}
.
157c
if(confname[i]){
if(confname[i][0] != '*')
ksetenv(confname[i], confval[i], 0);
.
## diffname alphapc/main.c 2002/0410
## diff -e /n/emeliedump/2002/0323/sys/src/9/alphapc/main.c /n/emeliedump/2002/0410/sys/src/9/alphapc/main.c
93a
timersinit();
.
## diffname alphapc/main.c 2002/1130
## diff -e /n/emeliedump/2002/0410/sys/src/9/alphapc/main.c /n/emeliedump/2002/1130/sys/src/9/alphapc/main.c
504c
.
459c
}
.
456,457c
for(n = 0; n < nconf; n++)
if(cistrcmp(confname[n], name) == 0) {
.
417c
.
282c
setupboot(1); // set up to halt
for (; ; )
firmware();
// on PC is just:
if (0) {
shutdown(ispanic);
// arch->reset();
}
.
279a
if (getconf("*debug") != nil) {
USED(ispanic);
delay(60*1000); /* give us time to read the screen */
}
.
265c
exit(int ispanic)
.
260a
int n = 0; // cpu id of primary cpu, not just m->machno
Hwcpu *cpu = (Hwcpu*)((ulong)hwrpb + hwrpb->cpuoff + n*hwrpb->cpulen);
cpu->state &= ~(Cpucanrestart | Cpuhaltmask);
cpu->state |= (halt? Cpuhaltstayhalted: Cpuhaltwarmboot);
}
/* from ../pc */
static void
shutdown(int ispanic)
{
int ms, once;
lock(&active);
if(ispanic)
active.ispanic = ispanic;
else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
active.ispanic = 0;
once = active.machs & (1<<m->machno);
active.machs &= ~(1<<m->machno);
active.exiting = 1;
unlock(&active);
if(once)
print("cpu%d: exiting\n", m->machno);
spllo();
for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
delay(TK2MS(2));
if(active.machs == 0 && consactive() == 0)
break;
}
if(active.ispanic && m->machno == 0) {
if(cpuserver)
delay(10000);
else
for (;;)
continue;
} else
delay(1000);
}
/* from ../pc: */
void
reboot(void *entry, void *code, ulong size)
{
// writeconf(); // pass kernel environment to next kernel
shutdown(0);
/*
* should be the only processor running now
*/
print("shutting down...\n");
delay(200);
splhi();
/* turn off buffered serial console */
serialoq = nil;
/* shutdown devices */
chandevshutdown();
#ifdef FUTURE
{
ulong *pdb;
/*
* Modify the machine page table to directly map the low 4MB of memory
* This allows the reboot code to turn off the page mapping
*/
pdb = m->pdb;
pdb[PDX(0)] = pdb[PDX(KZERO)];
mmuflushtlb(PADDR(pdb));
}
/* setup reboot trampoline function */
{
void (*f)(ulong, ulong, ulong) = (void*)REBOOTADDR;
memmove(f, rebootcode, sizeof(rebootcode));
#else
USED(entry, code, size);
#endif
print("rebooting...\n");
#ifdef FUTURE
/* off we go - never to return */
(*f)(PADDR(entry), PADDR(code), size);
}
#endif
setupboot(0); // reboot, don't halt
.
259c
setupboot(int halt)
.
257d
151,152d
149a
snprint(buf, sizeof(buf), "alpha %s alphapc", conffile);
ksetenv("terminal", buf, 0);
.
132c
char buf[2*KNAMELEN];
.
124,125c
cpu->state &= ~Cpubootinprog;
if (0)
cpu->state |= Cpuhaltstayhalted;
.
104a
/* cpu->state bits */
enum {
Cpubootinprog = 1, /* boot in progress */
Cpucanrestart = 2, /* restart possible */
Cpuavail = 4, /* processor available */
Cpuexists = 8, /* processor present */
Cpuuserhalted = 0x10, /* user halted */
Cpuctxtokay = 0x20, /* context valid */
Cpupalokay = 0x40, /* PALcode valid */
Cpupalmemokay = 0x80, /* PALcode memory valid */
Cpupalloaded = 0x100, /* PALcode loaded */
Cpuhaltmask = 0xff0000, /* halt request mask */
Cpuhaltdflt = 0,
Cpuhaltsaveexit = 0x10000,
Cpuhaltcoldboot = 0x20000,
Cpuhaltwarmboot = 0x30000,
Cpuhaltstayhalted = 0x40000,
Cpumustbezero = 0xffffffffff000000, /* 24:63 -- must be zero */
};
.
82a
/* it's now safe to print */
/* dumpopts(); /* DEBUG */
.
62a
/* debugging only */
static void
dumpopts(void)
{
int i;
print("dumpopts: found /alpha/conf options at 0x%lux\n",
bootconf->bootargs);
for(i = 0; i < nconf; i++)
print("dumpopts: read %s=%s\n", confname[i], confval[i]);
}
.
34a
/* can't print in this routine, see below in main() */
.
|