1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "../port/lib.h"
3*74a4d8c2SCharles.Forsyth #include "mem.h"
4*74a4d8c2SCharles.Forsyth #include "dat.h"
5*74a4d8c2SCharles.Forsyth #include "fns.h"
6*74a4d8c2SCharles.Forsyth #include "../port/error.h"
7*74a4d8c2SCharles.Forsyth #include "io.h"
8*74a4d8c2SCharles.Forsyth #include "version.h"
9*74a4d8c2SCharles.Forsyth
10*74a4d8c2SCharles.Forsyth #define MAXCONF 32
11*74a4d8c2SCharles.Forsyth
12*74a4d8c2SCharles.Forsyth Mach *m = (Mach*)MACHADDR;
13*74a4d8c2SCharles.Forsyth Proc *up = 0;
14*74a4d8c2SCharles.Forsyth Vectorpage *page0 = (Vectorpage*)KZERO; /* doubly-mapped to AIVECADDR */
15*74a4d8c2SCharles.Forsyth Conf conf;
16*74a4d8c2SCharles.Forsyth
17*74a4d8c2SCharles.Forsyth extern ulong kerndate;
18*74a4d8c2SCharles.Forsyth extern int cflag;
19*74a4d8c2SCharles.Forsyth extern int main_pool_pcnt;
20*74a4d8c2SCharles.Forsyth extern int heap_pool_pcnt;
21*74a4d8c2SCharles.Forsyth extern int image_pool_pcnt;
22*74a4d8c2SCharles.Forsyth ulong cpuidlecount;
23*74a4d8c2SCharles.Forsyth
24*74a4d8c2SCharles.Forsyth char *confname[MAXCONF];
25*74a4d8c2SCharles.Forsyth char *confval[MAXCONF];
26*74a4d8c2SCharles.Forsyth int nconf;
27*74a4d8c2SCharles.Forsyth
28*74a4d8c2SCharles.Forsyth void addconf(char *, char *);
29*74a4d8c2SCharles.Forsyth void eepromscan(void);
30*74a4d8c2SCharles.Forsyth char* getconf(char*);
31*74a4d8c2SCharles.Forsyth
32*74a4d8c2SCharles.Forsyth void
doc(char * m)33*74a4d8c2SCharles.Forsyth doc(char *m)
34*74a4d8c2SCharles.Forsyth {
35*74a4d8c2SCharles.Forsyth USED(m);
36*74a4d8c2SCharles.Forsyth print("%s...\n", m);
37*74a4d8c2SCharles.Forsyth }
38*74a4d8c2SCharles.Forsyth
39*74a4d8c2SCharles.Forsyth void
idoc(char * m)40*74a4d8c2SCharles.Forsyth idoc(char *m)
41*74a4d8c2SCharles.Forsyth {
42*74a4d8c2SCharles.Forsyth uartputs(m, strlen(m)); //xdelay(1);
43*74a4d8c2SCharles.Forsyth }
44*74a4d8c2SCharles.Forsyth
45*74a4d8c2SCharles.Forsyth static void
poolsizeinit(void)46*74a4d8c2SCharles.Forsyth poolsizeinit(void)
47*74a4d8c2SCharles.Forsyth {
48*74a4d8c2SCharles.Forsyth ulong nb;
49*74a4d8c2SCharles.Forsyth
50*74a4d8c2SCharles.Forsyth nb = conf.npage*BY2PG;
51*74a4d8c2SCharles.Forsyth poolsize(mainmem, (nb*main_pool_pcnt)/100, 0);
52*74a4d8c2SCharles.Forsyth poolsize(heapmem, (nb*heap_pool_pcnt)/100, 0);
53*74a4d8c2SCharles.Forsyth poolsize(imagmem, (nb*image_pool_pcnt)/100, 1);
54*74a4d8c2SCharles.Forsyth }
55*74a4d8c2SCharles.Forsyth
56*74a4d8c2SCharles.Forsyth static void
serialconsole(void)57*74a4d8c2SCharles.Forsyth serialconsole(void)
58*74a4d8c2SCharles.Forsyth {
59*74a4d8c2SCharles.Forsyth char *p;
60*74a4d8c2SCharles.Forsyth int port, baud;
61*74a4d8c2SCharles.Forsyth
62*74a4d8c2SCharles.Forsyth p = getconf("console");
63*74a4d8c2SCharles.Forsyth if(p == nil)
64*74a4d8c2SCharles.Forsyth p = "0";
65*74a4d8c2SCharles.Forsyth if(p != nil){
66*74a4d8c2SCharles.Forsyth port = strtol(p, nil, 0);
67*74a4d8c2SCharles.Forsyth baud = 38400;
68*74a4d8c2SCharles.Forsyth p = getconf("baud");
69*74a4d8c2SCharles.Forsyth if(p != nil){
70*74a4d8c2SCharles.Forsyth baud = strtol(p, nil, 0);
71*74a4d8c2SCharles.Forsyth if(baud < 38400)
72*74a4d8c2SCharles.Forsyth baud = 38400;
73*74a4d8c2SCharles.Forsyth }
74*74a4d8c2SCharles.Forsyth uartspecial(port, baud, &kbdq, &printq, kbdcr2nl);
75*74a4d8c2SCharles.Forsyth }
76*74a4d8c2SCharles.Forsyth }
77*74a4d8c2SCharles.Forsyth
78*74a4d8c2SCharles.Forsyth static char *hello = "Inferno\n";
79*74a4d8c2SCharles.Forsyth
80*74a4d8c2SCharles.Forsyth void
main(void)81*74a4d8c2SCharles.Forsyth main(void)
82*74a4d8c2SCharles.Forsyth {
83*74a4d8c2SCharles.Forsyth memset(edata, 0, end-edata); /* clear the BSS */
84*74a4d8c2SCharles.Forsyth memset(m, 0, sizeof(Mach)); /* clear the mach struct */
85*74a4d8c2SCharles.Forsyth conf.nmach = 1;
86*74a4d8c2SCharles.Forsyth archreset();
87*74a4d8c2SCharles.Forsyth idoc(hello);
88*74a4d8c2SCharles.Forsyth if(0){
89*74a4d8c2SCharles.Forsyth putcclkcfg(0); /* leave turbo mode */
90*74a4d8c2SCharles.Forsyth COREREG->cccr = (COREREG->cccr & ~(7<<7)) | (4<<7); /* turbo mode multiplier=2 */
91*74a4d8c2SCharles.Forsyth putcclkcfg(1); /* enter turbo mode */
92*74a4d8c2SCharles.Forsyth }
93*74a4d8c2SCharles.Forsyth quotefmtinstall();
94*74a4d8c2SCharles.Forsyth idoc("confinit...\n");
95*74a4d8c2SCharles.Forsyth confinit();
96*74a4d8c2SCharles.Forsyth idoc("xinit...\n");
97*74a4d8c2SCharles.Forsyth xinit();
98*74a4d8c2SCharles.Forsyth idoc("mmuinit...\n");
99*74a4d8c2SCharles.Forsyth mmuinit();
100*74a4d8c2SCharles.Forsyth poolsizeinit();
101*74a4d8c2SCharles.Forsyth poolinit();
102*74a4d8c2SCharles.Forsyth idoc("trapinit...\n");
103*74a4d8c2SCharles.Forsyth trapinit();
104*74a4d8c2SCharles.Forsyth // dmareset();
105*74a4d8c2SCharles.Forsyth idoc("printinit...\n");
106*74a4d8c2SCharles.Forsyth printinit();
107*74a4d8c2SCharles.Forsyth idoc("uartinstall...\n");
108*74a4d8c2SCharles.Forsyth uartinstall();
109*74a4d8c2SCharles.Forsyth eepromscan();
110*74a4d8c2SCharles.Forsyth doc("clockinit");
111*74a4d8c2SCharles.Forsyth clockinit();
112*74a4d8c2SCharles.Forsyth doc("screeninit");
113*74a4d8c2SCharles.Forsyth // screeninit();
114*74a4d8c2SCharles.Forsyth doc("procinit");
115*74a4d8c2SCharles.Forsyth procinit();
116*74a4d8c2SCharles.Forsyth // cpuidprint();
117*74a4d8c2SCharles.Forsyth doc("links");
118*74a4d8c2SCharles.Forsyth links();
119*74a4d8c2SCharles.Forsyth doc("chandevreset");
120*74a4d8c2SCharles.Forsyth chandevreset();
121*74a4d8c2SCharles.Forsyth
122*74a4d8c2SCharles.Forsyth eve = strdup("inferno");
123*74a4d8c2SCharles.Forsyth
124*74a4d8c2SCharles.Forsyth serialconsole();
125*74a4d8c2SCharles.Forsyth kbdinit();
126*74a4d8c2SCharles.Forsyth
127*74a4d8c2SCharles.Forsyth print("%ld MHz id %8.8lux\n", (m->cpuhz+500000)/1000000, getcpuid());
128*74a4d8c2SCharles.Forsyth print("\nInferno %s\n", VERSION);
129*74a4d8c2SCharles.Forsyth print("Vita Nuova\n");
130*74a4d8c2SCharles.Forsyth print("conf %s (%lud) jit %d\n\n",conffile, kerndate, cflag);
131*74a4d8c2SCharles.Forsyth print("pmcr=%8.8lux pwer=%8.8lux prer=%8.8lux pfer=%8.8lux pedr=%8.8lux pcfr=%8.8lux rcsr=%8.8lux\n",
132*74a4d8c2SCharles.Forsyth PMGRREG->pmcr, PMGRREG->pwer, PMGRREG->prer, PMGRREG->pfer, PMGRREG->pedr, PMGRREG->pcfr,
133*74a4d8c2SCharles.Forsyth PMGRREG->rcsr);
134*74a4d8c2SCharles.Forsyth print("cccr=%8.8lux cken=%8.8lux oscc=%8.8lux\n", COREREG->cccr, COREREG->cken, COREREG->oscc);
135*74a4d8c2SCharles.Forsyth print("msc0=%8.8lux mcs1=%8.8lux mcs2=%8.8lux\n", MEMCFGREG->msc0, MEMCFGREG->msc1, MEMCFGREG->msc2);
136*74a4d8c2SCharles.Forsyth print("clkcfg=%8.8lux\n", getcclkcfg());
137*74a4d8c2SCharles.Forsyth
138*74a4d8c2SCharles.Forsyth userinit();
139*74a4d8c2SCharles.Forsyth schedinit();
140*74a4d8c2SCharles.Forsyth }
141*74a4d8c2SCharles.Forsyth
142*74a4d8c2SCharles.Forsyth void
reboot(void)143*74a4d8c2SCharles.Forsyth reboot(void)
144*74a4d8c2SCharles.Forsyth {
145*74a4d8c2SCharles.Forsyth exit(0);
146*74a4d8c2SCharles.Forsyth }
147*74a4d8c2SCharles.Forsyth
148*74a4d8c2SCharles.Forsyth void
halt(void)149*74a4d8c2SCharles.Forsyth halt(void)
150*74a4d8c2SCharles.Forsyth {
151*74a4d8c2SCharles.Forsyth spllo();
152*74a4d8c2SCharles.Forsyth print("cpu halted\n");
153*74a4d8c2SCharles.Forsyth for(;;){
154*74a4d8c2SCharles.Forsyth /* nothing to do */
155*74a4d8c2SCharles.Forsyth }
156*74a4d8c2SCharles.Forsyth }
157*74a4d8c2SCharles.Forsyth
158*74a4d8c2SCharles.Forsyth Conf conf;
159*74a4d8c2SCharles.Forsyth
160*74a4d8c2SCharles.Forsyth void
addconf(char * name,char * val)161*74a4d8c2SCharles.Forsyth addconf(char *name, char *val)
162*74a4d8c2SCharles.Forsyth {
163*74a4d8c2SCharles.Forsyth if(nconf >= MAXCONF)
164*74a4d8c2SCharles.Forsyth return;
165*74a4d8c2SCharles.Forsyth confname[nconf] = name;
166*74a4d8c2SCharles.Forsyth confval[nconf] = val;
167*74a4d8c2SCharles.Forsyth nconf++;
168*74a4d8c2SCharles.Forsyth }
169*74a4d8c2SCharles.Forsyth
170*74a4d8c2SCharles.Forsyth char*
getconf(char * name)171*74a4d8c2SCharles.Forsyth getconf(char *name)
172*74a4d8c2SCharles.Forsyth {
173*74a4d8c2SCharles.Forsyth int i;
174*74a4d8c2SCharles.Forsyth
175*74a4d8c2SCharles.Forsyth for(i = 0; i < nconf; i++)
176*74a4d8c2SCharles.Forsyth if(cistrcmp(confname[i], name) == 0)
177*74a4d8c2SCharles.Forsyth return confval[i];
178*74a4d8c2SCharles.Forsyth return 0;
179*74a4d8c2SCharles.Forsyth }
180*74a4d8c2SCharles.Forsyth
181*74a4d8c2SCharles.Forsyth void
confinit(void)182*74a4d8c2SCharles.Forsyth confinit(void)
183*74a4d8c2SCharles.Forsyth {
184*74a4d8c2SCharles.Forsyth ulong base;
185*74a4d8c2SCharles.Forsyth
186*74a4d8c2SCharles.Forsyth archconfinit();
187*74a4d8c2SCharles.Forsyth
188*74a4d8c2SCharles.Forsyth base = PGROUND((ulong)end);
189*74a4d8c2SCharles.Forsyth conf.base0 = base;
190*74a4d8c2SCharles.Forsyth
191*74a4d8c2SCharles.Forsyth conf.base1 = 0;
192*74a4d8c2SCharles.Forsyth conf.npage1 = 0;
193*74a4d8c2SCharles.Forsyth
194*74a4d8c2SCharles.Forsyth conf.npage0 = (conf.topofmem - base)/BY2PG;
195*74a4d8c2SCharles.Forsyth
196*74a4d8c2SCharles.Forsyth conf.npage = conf.npage0 + conf.npage1;
197*74a4d8c2SCharles.Forsyth conf.ialloc = (((conf.npage*(main_pool_pcnt))/100)/2)*BY2PG;
198*74a4d8c2SCharles.Forsyth
199*74a4d8c2SCharles.Forsyth conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
200*74a4d8c2SCharles.Forsyth conf.nmach = 1;
201*74a4d8c2SCharles.Forsyth
202*74a4d8c2SCharles.Forsyth }
203*74a4d8c2SCharles.Forsyth
204*74a4d8c2SCharles.Forsyth void
init0(void)205*74a4d8c2SCharles.Forsyth init0(void)
206*74a4d8c2SCharles.Forsyth {
207*74a4d8c2SCharles.Forsyth Osenv *o;
208*74a4d8c2SCharles.Forsyth char buf[2*KNAMELEN];
209*74a4d8c2SCharles.Forsyth
210*74a4d8c2SCharles.Forsyth up->nerrlab = 0;
211*74a4d8c2SCharles.Forsyth
212*74a4d8c2SCharles.Forsyth spllo();
213*74a4d8c2SCharles.Forsyth
214*74a4d8c2SCharles.Forsyth if(waserror())
215*74a4d8c2SCharles.Forsyth panic("init0 %r");
216*74a4d8c2SCharles.Forsyth /*
217*74a4d8c2SCharles.Forsyth * These are o.k. because rootinit is null.
218*74a4d8c2SCharles.Forsyth * Then early kproc's will have a root and dot.
219*74a4d8c2SCharles.Forsyth */
220*74a4d8c2SCharles.Forsyth o = up->env;
221*74a4d8c2SCharles.Forsyth o->pgrp->slash = namec("#/", Atodir, 0, 0);
222*74a4d8c2SCharles.Forsyth cnameclose(o->pgrp->slash->name);
223*74a4d8c2SCharles.Forsyth o->pgrp->slash->name = newcname("/");
224*74a4d8c2SCharles.Forsyth o->pgrp->dot = cclone(o->pgrp->slash);
225*74a4d8c2SCharles.Forsyth
226*74a4d8c2SCharles.Forsyth chandevinit();
227*74a4d8c2SCharles.Forsyth
228*74a4d8c2SCharles.Forsyth if(!waserror()){
229*74a4d8c2SCharles.Forsyth ksetenv("cputype", "arm", 0);
230*74a4d8c2SCharles.Forsyth snprint(buf, sizeof(buf), "arm %s", conffile);
231*74a4d8c2SCharles.Forsyth ksetenv("terminal", buf, 0);
232*74a4d8c2SCharles.Forsyth poperror();
233*74a4d8c2SCharles.Forsyth }
234*74a4d8c2SCharles.Forsyth
235*74a4d8c2SCharles.Forsyth poperror();
236*74a4d8c2SCharles.Forsyth
237*74a4d8c2SCharles.Forsyth disinit("/osinit.dis");
238*74a4d8c2SCharles.Forsyth }
239*74a4d8c2SCharles.Forsyth
240*74a4d8c2SCharles.Forsyth void
userinit(void)241*74a4d8c2SCharles.Forsyth userinit(void)
242*74a4d8c2SCharles.Forsyth {
243*74a4d8c2SCharles.Forsyth Proc *p;
244*74a4d8c2SCharles.Forsyth Osenv *o;
245*74a4d8c2SCharles.Forsyth
246*74a4d8c2SCharles.Forsyth p = newproc();
247*74a4d8c2SCharles.Forsyth o = p->env;
248*74a4d8c2SCharles.Forsyth
249*74a4d8c2SCharles.Forsyth o->fgrp = newfgrp(nil);
250*74a4d8c2SCharles.Forsyth o->pgrp = newpgrp();
251*74a4d8c2SCharles.Forsyth o->egrp = newegrp();
252*74a4d8c2SCharles.Forsyth kstrdup(&o->user, eve);
253*74a4d8c2SCharles.Forsyth
254*74a4d8c2SCharles.Forsyth strcpy(p->text, "interp");
255*74a4d8c2SCharles.Forsyth
256*74a4d8c2SCharles.Forsyth p->fpstate = FPINIT;
257*74a4d8c2SCharles.Forsyth
258*74a4d8c2SCharles.Forsyth /*
259*74a4d8c2SCharles.Forsyth * Kernel Stack
260*74a4d8c2SCharles.Forsyth *
261*74a4d8c2SCharles.Forsyth * N.B. The -12 for the stack pointer is important.
262*74a4d8c2SCharles.Forsyth * 4 bytes for gotolabel's return PC
263*74a4d8c2SCharles.Forsyth */
264*74a4d8c2SCharles.Forsyth p->sched.pc = (ulong)init0;
265*74a4d8c2SCharles.Forsyth p->sched.sp = (ulong)p->kstack+KSTACK-8;
266*74a4d8c2SCharles.Forsyth
267*74a4d8c2SCharles.Forsyth ready(p);
268*74a4d8c2SCharles.Forsyth }
269*74a4d8c2SCharles.Forsyth
270*74a4d8c2SCharles.Forsyth void
exit(int inpanic)271*74a4d8c2SCharles.Forsyth exit(int inpanic)
272*74a4d8c2SCharles.Forsyth {
273*74a4d8c2SCharles.Forsyth up = 0;
274*74a4d8c2SCharles.Forsyth
275*74a4d8c2SCharles.Forsyth /* Shutdown running devices */
276*74a4d8c2SCharles.Forsyth chandevshutdown();
277*74a4d8c2SCharles.Forsyth
278*74a4d8c2SCharles.Forsyth if(inpanic && 0){
279*74a4d8c2SCharles.Forsyth print("Hit the reset button\n");
280*74a4d8c2SCharles.Forsyth for(;;)
281*74a4d8c2SCharles.Forsyth clockpoll();
282*74a4d8c2SCharles.Forsyth }
283*74a4d8c2SCharles.Forsyth archreboot();
284*74a4d8c2SCharles.Forsyth }
285*74a4d8c2SCharles.Forsyth
286*74a4d8c2SCharles.Forsyth static void
linkproc(void)287*74a4d8c2SCharles.Forsyth linkproc(void)
288*74a4d8c2SCharles.Forsyth {
289*74a4d8c2SCharles.Forsyth spllo();
290*74a4d8c2SCharles.Forsyth if (waserror())
291*74a4d8c2SCharles.Forsyth print("error() underflow: %r\n");
292*74a4d8c2SCharles.Forsyth else
293*74a4d8c2SCharles.Forsyth (*up->kpfun)(up->arg);
294*74a4d8c2SCharles.Forsyth pexit("end proc", 1);
295*74a4d8c2SCharles.Forsyth }
296*74a4d8c2SCharles.Forsyth
297*74a4d8c2SCharles.Forsyth void
kprocchild(Proc * p,void (* func)(void *),void * arg)298*74a4d8c2SCharles.Forsyth kprocchild(Proc *p, void (*func)(void*), void *arg)
299*74a4d8c2SCharles.Forsyth {
300*74a4d8c2SCharles.Forsyth p->sched.pc = (ulong)linkproc;
301*74a4d8c2SCharles.Forsyth p->sched.sp = (ulong)p->kstack+KSTACK-8;
302*74a4d8c2SCharles.Forsyth
303*74a4d8c2SCharles.Forsyth p->kpfun = func;
304*74a4d8c2SCharles.Forsyth p->arg = arg;
305*74a4d8c2SCharles.Forsyth }
306*74a4d8c2SCharles.Forsyth
307*74a4d8c2SCharles.Forsyth void
idlehands(void)308*74a4d8c2SCharles.Forsyth idlehands(void)
309*74a4d8c2SCharles.Forsyth {
310*74a4d8c2SCharles.Forsyth cpuidlecount++;
311*74a4d8c2SCharles.Forsyth INTRREG->iccr = 1; /* only unmasked interrupts will stop idle mode */
312*74a4d8c2SCharles.Forsyth idle();
313*74a4d8c2SCharles.Forsyth }
314*74a4d8c2SCharles.Forsyth
315*74a4d8c2SCharles.Forsyth /* stubs */
316*74a4d8c2SCharles.Forsyth void
setfsr(ulong)317*74a4d8c2SCharles.Forsyth setfsr(ulong)
318*74a4d8c2SCharles.Forsyth {
319*74a4d8c2SCharles.Forsyth }
320*74a4d8c2SCharles.Forsyth
321*74a4d8c2SCharles.Forsyth ulong
getfsr()322*74a4d8c2SCharles.Forsyth getfsr()
323*74a4d8c2SCharles.Forsyth {
324*74a4d8c2SCharles.Forsyth return 0;
325*74a4d8c2SCharles.Forsyth }
326*74a4d8c2SCharles.Forsyth
327*74a4d8c2SCharles.Forsyth void
setfcr(ulong)328*74a4d8c2SCharles.Forsyth setfcr(ulong)
329*74a4d8c2SCharles.Forsyth {
330*74a4d8c2SCharles.Forsyth }
331*74a4d8c2SCharles.Forsyth
332*74a4d8c2SCharles.Forsyth ulong
getfcr()333*74a4d8c2SCharles.Forsyth getfcr()
334*74a4d8c2SCharles.Forsyth {
335*74a4d8c2SCharles.Forsyth return 0;
336*74a4d8c2SCharles.Forsyth }
337*74a4d8c2SCharles.Forsyth
338*74a4d8c2SCharles.Forsyth void
fpinit(void)339*74a4d8c2SCharles.Forsyth fpinit(void)
340*74a4d8c2SCharles.Forsyth {
341*74a4d8c2SCharles.Forsyth }
342*74a4d8c2SCharles.Forsyth
343*74a4d8c2SCharles.Forsyth void
FPsave(void *)344*74a4d8c2SCharles.Forsyth FPsave(void*)
345*74a4d8c2SCharles.Forsyth {
346*74a4d8c2SCharles.Forsyth }
347*74a4d8c2SCharles.Forsyth
348*74a4d8c2SCharles.Forsyth void
FPrestore(void *)349*74a4d8c2SCharles.Forsyth FPrestore(void*)
350*74a4d8c2SCharles.Forsyth {
351*74a4d8c2SCharles.Forsyth }
352