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 "io.h"
7*74a4d8c2SCharles.Forsyth #include "version.h"
8*74a4d8c2SCharles.Forsyth
9*74a4d8c2SCharles.Forsyth Mach *m = &mach0;
10*74a4d8c2SCharles.Forsyth Proc *up;
11*74a4d8c2SCharles.Forsyth int cflag;
12*74a4d8c2SCharles.Forsyth
13*74a4d8c2SCharles.Forsyth ulong cachetable[1024];
14*74a4d8c2SCharles.Forsyth
15*74a4d8c2SCharles.Forsyth Sysint *sysintr;
16*74a4d8c2SCharles.Forsyth struct {
17*74a4d8c2SCharles.Forsyth uchar format;
18*74a4d8c2SCharles.Forsyth uchar type;
19*74a4d8c2SCharles.Forsyth uchar ea[6];
20*74a4d8c2SCharles.Forsyth uchar pad[32-8];
21*74a4d8c2SCharles.Forsyth } idprom;
22*74a4d8c2SCharles.Forsyth
23*74a4d8c2SCharles.Forsyth int cpuserver;
24*74a4d8c2SCharles.Forsyth ulong bank[8];
25*74a4d8c2SCharles.Forsyth uchar mempres[64];
26*74a4d8c2SCharles.Forsyth char fbstr[32];
27*74a4d8c2SCharles.Forsyth ulong fbslot;
28*74a4d8c2SCharles.Forsyth int usecg6;
29*74a4d8c2SCharles.Forsyth Label catch;
30*74a4d8c2SCharles.Forsyth uchar *sp;
31*74a4d8c2SCharles.Forsyth
32*74a4d8c2SCharles.Forsyth int cold=1;
33*74a4d8c2SCharles.Forsyth
34*74a4d8c2SCharles.Forsyth typedef struct Sysparam Sysparam;
35*74a4d8c2SCharles.Forsyth struct Sysparam
36*74a4d8c2SCharles.Forsyth {
37*74a4d8c2SCharles.Forsyth int id; /* Model type from id prom */
38*74a4d8c2SCharles.Forsyth char *name; /* System name */
39*74a4d8c2SCharles.Forsyth char ss2; /* Is Sparcstation 2? */
40*74a4d8c2SCharles.Forsyth int vacsize; /* Cache size */
41*74a4d8c2SCharles.Forsyth int vacline; /* Cache line size */
42*74a4d8c2SCharles.Forsyth int ncontext; /* Number of MMU contexts */
43*74a4d8c2SCharles.Forsyth char cachebug; /* Machine needs cache bug work around */
44*74a4d8c2SCharles.Forsyth int nbank; /* Number of banks of memory */
45*74a4d8c2SCharles.Forsyth int banksize; /* Maximum Mbytes per bank */
46*74a4d8c2SCharles.Forsyth int pcnt; /* percent of mem for kernel? */
47*74a4d8c2SCharles.Forsyth }
48*74a4d8c2SCharles.Forsyth sysparam[] =
49*74a4d8c2SCharles.Forsyth {
50*74a4d8c2SCharles.Forsyth { 0xFF, "unknown Sun4M",0, 0, 0, 64, 0, 4, 32 ,0},
51*74a4d8c2SCharles.Forsyth { 0x80, "JavaStation uSparcII",0, 0, 0, 256, 0, 4, 32 ,2},
52*74a4d8c2SCharles.Forsyth { 0 }
53*74a4d8c2SCharles.Forsyth };
54*74a4d8c2SCharles.Forsyth Sysparam *sparam;
55*74a4d8c2SCharles.Forsyth
56*74a4d8c2SCharles.Forsyth void
doc(char * m)57*74a4d8c2SCharles.Forsyth doc(char *m)
58*74a4d8c2SCharles.Forsyth {
59*74a4d8c2SCharles.Forsyth print("%s\n", m);
60*74a4d8c2SCharles.Forsyth }
61*74a4d8c2SCharles.Forsyth
62*74a4d8c2SCharles.Forsyth static void poolsizeinit(void);
63*74a4d8c2SCharles.Forsyth
64*74a4d8c2SCharles.Forsyth void
main(void)65*74a4d8c2SCharles.Forsyth main(void)
66*74a4d8c2SCharles.Forsyth {
67*74a4d8c2SCharles.Forsyth
68*74a4d8c2SCharles.Forsyth
69*74a4d8c2SCharles.Forsyth machinit();
70*74a4d8c2SCharles.Forsyth trapinit();
71*74a4d8c2SCharles.Forsyth quotefmtinstall();
72*74a4d8c2SCharles.Forsyth confinit();
73*74a4d8c2SCharles.Forsyth xinit();
74*74a4d8c2SCharles.Forsyth mmuinit();
75*74a4d8c2SCharles.Forsyth intrinit();
76*74a4d8c2SCharles.Forsyth clockinit();
77*74a4d8c2SCharles.Forsyth printinit();
78*74a4d8c2SCharles.Forsyth screeninit();
79*74a4d8c2SCharles.Forsyth ioinit();
80*74a4d8c2SCharles.Forsyth doc("ioinit...");
81*74a4d8c2SCharles.Forsyth ns16552install();
82*74a4d8c2SCharles.Forsyth poolsizeinit();
83*74a4d8c2SCharles.Forsyth doc("ns16552install...");
84*74a4d8c2SCharles.Forsyth kbdinit();
85*74a4d8c2SCharles.Forsyth doc("kbdinit...");
86*74a4d8c2SCharles.Forsyth cacheinit();
87*74a4d8c2SCharles.Forsyth doc("cacheinit...");
88*74a4d8c2SCharles.Forsyth procinit();
89*74a4d8c2SCharles.Forsyth doc("procinit...");
90*74a4d8c2SCharles.Forsyth putphys(MID, 0x1F<<16); /* enable arbitration */
91*74a4d8c2SCharles.Forsyth links();
92*74a4d8c2SCharles.Forsyth doc("links");
93*74a4d8c2SCharles.Forsyth chandevreset();
94*74a4d8c2SCharles.Forsyth doc("chandevreset...");
95*74a4d8c2SCharles.Forsyth
96*74a4d8c2SCharles.Forsyth print("\nInferno Operating System\n");
97*74a4d8c2SCharles.Forsyth print("%s-%s \n\n",VERSION, conffile);
98*74a4d8c2SCharles.Forsyth print("JIT Compilation Mode = %d\n",cflag);
99*74a4d8c2SCharles.Forsyth
100*74a4d8c2SCharles.Forsyth userinit();
101*74a4d8c2SCharles.Forsyth doc("userinit...");
102*74a4d8c2SCharles.Forsyth
103*74a4d8c2SCharles.Forsyth /* clear pending processor interrupts */
104*74a4d8c2SCharles.Forsyth putphys(PROCINTCLR, (~0<<17)|(1<<15));
105*74a4d8c2SCharles.Forsyth print("berore schedinit\n");
106*74a4d8c2SCharles.Forsyth schedinit();
107*74a4d8c2SCharles.Forsyth }
108*74a4d8c2SCharles.Forsyth
109*74a4d8c2SCharles.Forsyth extern int main_pool_pcnt;
110*74a4d8c2SCharles.Forsyth extern int heap_pool_pcnt;
111*74a4d8c2SCharles.Forsyth extern int image_pool_pcnt;
112*74a4d8c2SCharles.Forsyth
113*74a4d8c2SCharles.Forsyth static void
poolsizeinit(void)114*74a4d8c2SCharles.Forsyth poolsizeinit(void)
115*74a4d8c2SCharles.Forsyth {
116*74a4d8c2SCharles.Forsyth ulong nb = conf.npage*BY2PG;
117*74a4d8c2SCharles.Forsyth
118*74a4d8c2SCharles.Forsyth print("Total memory available: %ld K\n",nb/1024);
119*74a4d8c2SCharles.Forsyth poolsize(mainmem, (nb*main_pool_pcnt)/100, 0);
120*74a4d8c2SCharles.Forsyth poolsize(heapmem, (nb*heap_pool_pcnt)/100, 0);
121*74a4d8c2SCharles.Forsyth poolsize(imagmem, (nb*image_pool_pcnt)/100, 1);
122*74a4d8c2SCharles.Forsyth }
123*74a4d8c2SCharles.Forsyth
124*74a4d8c2SCharles.Forsyth void
intrinit(void)125*74a4d8c2SCharles.Forsyth intrinit(void)
126*74a4d8c2SCharles.Forsyth {
127*74a4d8c2SCharles.Forsyth KMap *k;
128*74a4d8c2SCharles.Forsyth
129*74a4d8c2SCharles.Forsyth /* clear fault status */
130*74a4d8c2SCharles.Forsyth getphys(AFSR);
131*74a4d8c2SCharles.Forsyth
132*74a4d8c2SCharles.Forsyth k = kmappa(SYSINTR, PTEIO|PTENOCACHE);
133*74a4d8c2SCharles.Forsyth sysintr = (Sysint*)VA(k);
134*74a4d8c2SCharles.Forsyth
135*74a4d8c2SCharles.Forsyth /* mask all interrupts */
136*74a4d8c2SCharles.Forsyth sysintr->maskset = ~0;
137*74a4d8c2SCharles.Forsyth
138*74a4d8c2SCharles.Forsyth /* allow these */
139*74a4d8c2SCharles.Forsyth sysintr->maskclr=MaskAllIntr|MEIntr|MSIIntr|EMCIntr|EtherIntr|KbdIntr;
140*74a4d8c2SCharles.Forsyth
141*74a4d8c2SCharles.Forsyth /* clear pending processor interrupts */
142*74a4d8c2SCharles.Forsyth putphys(PROCINTCLR, (~0<<17)|(1<<15));
143*74a4d8c2SCharles.Forsyth
144*74a4d8c2SCharles.Forsyth }
145*74a4d8c2SCharles.Forsyth
146*74a4d8c2SCharles.Forsyth void
systemreset(void)147*74a4d8c2SCharles.Forsyth systemreset(void)
148*74a4d8c2SCharles.Forsyth {
149*74a4d8c2SCharles.Forsyth microdelay(200);
150*74a4d8c2SCharles.Forsyth putphys(SYSCTL, getphys(SYSCTL)|1); /* power on reset */
151*74a4d8c2SCharles.Forsyth }
152*74a4d8c2SCharles.Forsyth
153*74a4d8c2SCharles.Forsyth void
machinit(void)154*74a4d8c2SCharles.Forsyth machinit(void)
155*74a4d8c2SCharles.Forsyth {
156*74a4d8c2SCharles.Forsyth memset(m, 0, sizeof(Mach));
157*74a4d8c2SCharles.Forsyth }
158*74a4d8c2SCharles.Forsyth
159*74a4d8c2SCharles.Forsyth void
ioinit(void)160*74a4d8c2SCharles.Forsyth ioinit(void)
161*74a4d8c2SCharles.Forsyth {
162*74a4d8c2SCharles.Forsyth KMap *k;
163*74a4d8c2SCharles.Forsyth uchar *sindex; /* superio index */
164*74a4d8c2SCharles.Forsyth uchar *sdata; /* superio data */
165*74a4d8c2SCharles.Forsyth uchar *mkctl; /* superio mouse/kbd ctl register */
166*74a4d8c2SCharles.Forsyth uchar *mkdata; /* superio mouse/kbd data register */
167*74a4d8c2SCharles.Forsyth
168*74a4d8c2SCharles.Forsyth
169*74a4d8c2SCharles.Forsyth /* enable the uart's on the superio chip */
170*74a4d8c2SCharles.Forsyth k = kmappa(SUPERIO_PHYS_PAGE, PTEIO|PTENOCACHE);
171*74a4d8c2SCharles.Forsyth sindex = (uchar*)(VA(k)+SUPERIO_INDEX_OFFSET);
172*74a4d8c2SCharles.Forsyth sdata = (uchar*)(VA(k)+SUPERIO_DATA_OFFSET);
173*74a4d8c2SCharles.Forsyth mkdata = (uchar*)(VA(k)+SUPERIO_MOUSE_KBD_DATA_PORT);
174*74a4d8c2SCharles.Forsyth mkctl = (uchar*)(VA(k)+SUPERIO_MOUSE_KBD_CTL_PORT);
175*74a4d8c2SCharles.Forsyth
176*74a4d8c2SCharles.Forsyth superioinit(VA(k),sindex,sdata,mkctl,mkdata);
177*74a4d8c2SCharles.Forsyth doc("superioinit...");
178*74a4d8c2SCharles.Forsyth }
179*74a4d8c2SCharles.Forsyth
180*74a4d8c2SCharles.Forsyth void
init0(void)181*74a4d8c2SCharles.Forsyth init0(void)
182*74a4d8c2SCharles.Forsyth {
183*74a4d8c2SCharles.Forsyth Osenv *o;
184*74a4d8c2SCharles.Forsyth
185*74a4d8c2SCharles.Forsyth up->nerrlab = 0;
186*74a4d8c2SCharles.Forsyth
187*74a4d8c2SCharles.Forsyth print("before spllo");
188*74a4d8c2SCharles.Forsyth
189*74a4d8c2SCharles.Forsyth spllo();
190*74a4d8c2SCharles.Forsyth
191*74a4d8c2SCharles.Forsyth print("Sun Sparc %s\n", sparam->name);
192*74a4d8c2SCharles.Forsyth print("bank 0: %ldM 1: %ldM\n", bank[0], bank[1]);
193*74a4d8c2SCharles.Forsyth print("frame buffer id %lux slot %ld %s\n",conf.monitor,fbslot,fbstr);
194*74a4d8c2SCharles.Forsyth
195*74a4d8c2SCharles.Forsyth
196*74a4d8c2SCharles.Forsyth if(waserror())
197*74a4d8c2SCharles.Forsyth panic("init0");
198*74a4d8c2SCharles.Forsyth
199*74a4d8c2SCharles.Forsyth /*
200*74a4d8c2SCharles.Forsyth * These are o.k. because rootinit is null.
201*74a4d8c2SCharles.Forsyth * Then early kproc's will have a root and dot.
202*74a4d8c2SCharles.Forsyth */
203*74a4d8c2SCharles.Forsyth o = up->env;
204*74a4d8c2SCharles.Forsyth o->pgrp->slash = namec("#/", Atodir, 0, 0);
205*74a4d8c2SCharles.Forsyth cnameclose(o->pgrp->slash->name);
206*74a4d8c2SCharles.Forsyth o->pgrp->slash->name = newcname("/");
207*74a4d8c2SCharles.Forsyth o->pgrp->dot = cclone(o->pgrp->slash);
208*74a4d8c2SCharles.Forsyth
209*74a4d8c2SCharles.Forsyth chandevinit();
210*74a4d8c2SCharles.Forsyth poperror();
211*74a4d8c2SCharles.Forsyth disinit("/osinit.dis");
212*74a4d8c2SCharles.Forsyth }
213*74a4d8c2SCharles.Forsyth
214*74a4d8c2SCharles.Forsyth
215*74a4d8c2SCharles.Forsyth void
userinit(void)216*74a4d8c2SCharles.Forsyth userinit(void)
217*74a4d8c2SCharles.Forsyth {
218*74a4d8c2SCharles.Forsyth Proc *p;
219*74a4d8c2SCharles.Forsyth Osenv *o;
220*74a4d8c2SCharles.Forsyth
221*74a4d8c2SCharles.Forsyth p = newproc();
222*74a4d8c2SCharles.Forsyth o = p->env;
223*74a4d8c2SCharles.Forsyth
224*74a4d8c2SCharles.Forsyth o->fgrp = newfgrp(nil);
225*74a4d8c2SCharles.Forsyth o->pgrp = newpgrp();
226*74a4d8c2SCharles.Forsyth kstrdup(&o->user, eve);
227*74a4d8c2SCharles.Forsyth strcpy(p->text,"interp");
228*74a4d8c2SCharles.Forsyth
229*74a4d8c2SCharles.Forsyth p->fpstate = FPINIT;
230*74a4d8c2SCharles.Forsyth fpinit();
231*74a4d8c2SCharles.Forsyth
232*74a4d8c2SCharles.Forsyth /*
233*74a4d8c2SCharles.Forsyth * Kernel Stack
234*74a4d8c2SCharles.Forsyth */
235*74a4d8c2SCharles.Forsyth p->sched.pc = (ulong)init0;
236*74a4d8c2SCharles.Forsyth p->sched.sp = (ulong)p->kstack+KSTACK-8;
237*74a4d8c2SCharles.Forsyth p->sched.sp &= ~7; /* SP must be 8-byte aligned */
238*74a4d8c2SCharles.Forsyth
239*74a4d8c2SCharles.Forsyth ready(p);
240*74a4d8c2SCharles.Forsyth }
241*74a4d8c2SCharles.Forsyth
242*74a4d8c2SCharles.Forsyth uchar *
pusharg(char * p)243*74a4d8c2SCharles.Forsyth pusharg(char *p)
244*74a4d8c2SCharles.Forsyth {
245*74a4d8c2SCharles.Forsyth int n;
246*74a4d8c2SCharles.Forsyth
247*74a4d8c2SCharles.Forsyth n = strlen(p)+1;
248*74a4d8c2SCharles.Forsyth sp -= n;
249*74a4d8c2SCharles.Forsyth memmove(sp, p, n);
250*74a4d8c2SCharles.Forsyth return sp;
251*74a4d8c2SCharles.Forsyth }
252*74a4d8c2SCharles.Forsyth
253*74a4d8c2SCharles.Forsyth void
exit(int ispanic)254*74a4d8c2SCharles.Forsyth exit(int ispanic)
255*74a4d8c2SCharles.Forsyth {
256*74a4d8c2SCharles.Forsyth USED(ispanic);
257*74a4d8c2SCharles.Forsyth
258*74a4d8c2SCharles.Forsyth spllo();
259*74a4d8c2SCharles.Forsyth print("cpu exiting\n");
260*74a4d8c2SCharles.Forsyth
261*74a4d8c2SCharles.Forsyth /* Shutdown running devices */
262*74a4d8c2SCharles.Forsyth chandevshutdown();
263*74a4d8c2SCharles.Forsyth
264*74a4d8c2SCharles.Forsyth microdelay(500);
265*74a4d8c2SCharles.Forsyth systemreset();
266*74a4d8c2SCharles.Forsyth }
267*74a4d8c2SCharles.Forsyth
268*74a4d8c2SCharles.Forsyth void
reboot(void)269*74a4d8c2SCharles.Forsyth reboot(void)
270*74a4d8c2SCharles.Forsyth {
271*74a4d8c2SCharles.Forsyth exit(0);
272*74a4d8c2SCharles.Forsyth }
273*74a4d8c2SCharles.Forsyth
274*74a4d8c2SCharles.Forsyth void
halt(void)275*74a4d8c2SCharles.Forsyth halt(void)
276*74a4d8c2SCharles.Forsyth {
277*74a4d8c2SCharles.Forsyth spllo();
278*74a4d8c2SCharles.Forsyth print("cpu halted\n");
279*74a4d8c2SCharles.Forsyth microdelay(500);
280*74a4d8c2SCharles.Forsyth for(;;);
281*74a4d8c2SCharles.Forsyth }
282*74a4d8c2SCharles.Forsyth
283*74a4d8c2SCharles.Forsyth int
probemem(ulong addr)284*74a4d8c2SCharles.Forsyth probemem(ulong addr)
285*74a4d8c2SCharles.Forsyth {
286*74a4d8c2SCharles.Forsyth ulong pcr, save0;
287*74a4d8c2SCharles.Forsyth int works;
288*74a4d8c2SCharles.Forsyth
289*74a4d8c2SCharles.Forsyth save0 = getphys(0);
290*74a4d8c2SCharles.Forsyth pcr = getpcr()|NOFAULT;
291*74a4d8c2SCharles.Forsyth works = 0;
292*74a4d8c2SCharles.Forsyth setpcr(pcr & ~MEMPCHECK);
293*74a4d8c2SCharles.Forsyth putphys(addr, ~addr);
294*74a4d8c2SCharles.Forsyth if(addr)
295*74a4d8c2SCharles.Forsyth putphys(0, 0x89ABCDEF);
296*74a4d8c2SCharles.Forsyth if(getphys(addr) == ~addr){
297*74a4d8c2SCharles.Forsyth setpcr(pcr);
298*74a4d8c2SCharles.Forsyth putphys(addr, addr);
299*74a4d8c2SCharles.Forsyth if(addr)
300*74a4d8c2SCharles.Forsyth putphys(0, 0x89ABCDEF);
301*74a4d8c2SCharles.Forsyth if(getphys(addr) == addr)
302*74a4d8c2SCharles.Forsyth works = 1;
303*74a4d8c2SCharles.Forsyth }
304*74a4d8c2SCharles.Forsyth setpcr(pcr & ~NOFAULT);
305*74a4d8c2SCharles.Forsyth putphys(0, save0);
306*74a4d8c2SCharles.Forsyth getphys(AFSR); /* clear fault status */
307*74a4d8c2SCharles.Forsyth getrmmu(SFSR); /* clear fault status */
308*74a4d8c2SCharles.Forsyth return works;
309*74a4d8c2SCharles.Forsyth }
310*74a4d8c2SCharles.Forsyth
311*74a4d8c2SCharles.Forsyth /*
312*74a4d8c2SCharles.Forsyth * this assumes that if a bank is not empty,
313*74a4d8c2SCharles.Forsyth * its first slot is filled.
314*74a4d8c2SCharles.Forsyth *
315*74a4d8c2SCharles.Forsyth * ../port/alloc.c and ../port/page.c
316*74a4d8c2SCharles.Forsyth * need to be changed to support more than two banks.
317*74a4d8c2SCharles.Forsyth */
318*74a4d8c2SCharles.Forsyth void
scanbank(ulong base,uchar * mempres,int n)319*74a4d8c2SCharles.Forsyth scanbank(ulong base, uchar *mempres, int n)
320*74a4d8c2SCharles.Forsyth {
321*74a4d8c2SCharles.Forsyth int i;
322*74a4d8c2SCharles.Forsyth ulong addr, npg;
323*74a4d8c2SCharles.Forsyth
324*74a4d8c2SCharles.Forsyth npg = 0;
325*74a4d8c2SCharles.Forsyth for(i=0; i<n; i++){
326*74a4d8c2SCharles.Forsyth mempres[i] = 0;
327*74a4d8c2SCharles.Forsyth addr = base + i*MB;
328*74a4d8c2SCharles.Forsyth if(!probemem(addr))
329*74a4d8c2SCharles.Forsyth break;
330*74a4d8c2SCharles.Forsyth if(addr != base) {
331*74a4d8c2SCharles.Forsyth /* check for mirrors */
332*74a4d8c2SCharles.Forsyth putphys(addr, addr);
333*74a4d8c2SCharles.Forsyth if(getphys(base) == addr)
334*74a4d8c2SCharles.Forsyth break;
335*74a4d8c2SCharles.Forsyth }
336*74a4d8c2SCharles.Forsyth mempres[i] = 1;
337*74a4d8c2SCharles.Forsyth npg += MB/BY2PG;
338*74a4d8c2SCharles.Forsyth }
339*74a4d8c2SCharles.Forsyth if(npg){
340*74a4d8c2SCharles.Forsyth if(conf.npage0 == 0){
341*74a4d8c2SCharles.Forsyth conf.base0 = base;
342*74a4d8c2SCharles.Forsyth conf.npage0 = npg;
343*74a4d8c2SCharles.Forsyth }else if(conf.npage1 < npg){
344*74a4d8c2SCharles.Forsyth conf.base1 = base;
345*74a4d8c2SCharles.Forsyth conf.npage1 = npg;
346*74a4d8c2SCharles.Forsyth }
347*74a4d8c2SCharles.Forsyth }
348*74a4d8c2SCharles.Forsyth }
349*74a4d8c2SCharles.Forsyth
350*74a4d8c2SCharles.Forsyth void
physcopyin(void * d,ulong s,int n)351*74a4d8c2SCharles.Forsyth physcopyin(void *d, ulong s, int n)
352*74a4d8c2SCharles.Forsyth {
353*74a4d8c2SCharles.Forsyth int i, j;
354*74a4d8c2SCharles.Forsyth ulong w;
355*74a4d8c2SCharles.Forsyth
356*74a4d8c2SCharles.Forsyth for(i=0; i<n; i+=sizeof(ulong)) {
357*74a4d8c2SCharles.Forsyth w = getphys(s+i);
358*74a4d8c2SCharles.Forsyth j = n-i;
359*74a4d8c2SCharles.Forsyth if(j > sizeof(ulong))
360*74a4d8c2SCharles.Forsyth j = sizeof(ulong);
361*74a4d8c2SCharles.Forsyth memmove((uchar*)d+i, &w, j);
362*74a4d8c2SCharles.Forsyth }
363*74a4d8c2SCharles.Forsyth }
364*74a4d8c2SCharles.Forsyth
365*74a4d8c2SCharles.Forsyth Conf conf;
366*74a4d8c2SCharles.Forsyth
367*74a4d8c2SCharles.Forsyth void
confinit(void)368*74a4d8c2SCharles.Forsyth confinit(void)
369*74a4d8c2SCharles.Forsyth {
370*74a4d8c2SCharles.Forsyth ulong i;
371*74a4d8c2SCharles.Forsyth ulong ktop;
372*74a4d8c2SCharles.Forsyth
373*74a4d8c2SCharles.Forsyth conf.monitor = 0;
374*74a4d8c2SCharles.Forsyth
375*74a4d8c2SCharles.Forsyth conf.nmach = 1;
376*74a4d8c2SCharles.Forsyth if(conf.nmach > MAXMACH)
377*74a4d8c2SCharles.Forsyth panic("confinit");
378*74a4d8c2SCharles.Forsyth
379*74a4d8c2SCharles.Forsyth /* fetch ID prom */
380*74a4d8c2SCharles.Forsyth physcopyin(&idprom, NVR_PHYS+IDOFF, sizeof(idprom));
381*74a4d8c2SCharles.Forsyth if(idprom.format!=1 || (idprom.type&0xF0)!=0x80)
382*74a4d8c2SCharles.Forsyth *(ulong*)~0 = 0; /* not a new generation sparc; die! */
383*74a4d8c2SCharles.Forsyth
384*74a4d8c2SCharles.Forsyth for(sparam = sysparam; sparam->id; sparam++)
385*74a4d8c2SCharles.Forsyth if(sparam->id == idprom.type)
386*74a4d8c2SCharles.Forsyth break;
387*74a4d8c2SCharles.Forsyth
388*74a4d8c2SCharles.Forsyth /* First entry in the table is the default */
389*74a4d8c2SCharles.Forsyth if(sparam->id == 0)
390*74a4d8c2SCharles.Forsyth sparam = sysparam;
391*74a4d8c2SCharles.Forsyth
392*74a4d8c2SCharles.Forsyth conf.ss2 = sparam->ss2;
393*74a4d8c2SCharles.Forsyth conf.vacsize = sparam->vacsize;
394*74a4d8c2SCharles.Forsyth conf.vaclinesize = sparam->vacline;
395*74a4d8c2SCharles.Forsyth conf.ncontext = sparam->ncontext;
396*74a4d8c2SCharles.Forsyth conf.ss2cachebug = sparam->cachebug;
397*74a4d8c2SCharles.Forsyth
398*74a4d8c2SCharles.Forsyth for(i=0; i<sparam->nbank; i++)
399*74a4d8c2SCharles.Forsyth if(probemem(i*sparam->banksize*MB))
400*74a4d8c2SCharles.Forsyth scanbank(i*sparam->banksize*MB, mempres,
401*74a4d8c2SCharles.Forsyth sparam->banksize);
402*74a4d8c2SCharles.Forsyth
403*74a4d8c2SCharles.Forsyth bank[0] = conf.npage0*BY2PG/MB;
404*74a4d8c2SCharles.Forsyth bank[1] = conf.npage1*BY2PG/MB;
405*74a4d8c2SCharles.Forsyth
406*74a4d8c2SCharles.Forsyth if(bank[1] == 0){
407*74a4d8c2SCharles.Forsyth /*
408*74a4d8c2SCharles.Forsyth * This split of memory into 2 banks fools the allocator into
409*74a4d8c2SCharles.Forsyth * allocating low memory pages from bank 0 for the ethernet
410*74a4d8c2SCharles.Forsyth * since it has only a 24bit address *counter.
411*74a4d8c2SCharles.Forsyth * NB. Suns must have at LEAST 8Mbytes.
412*74a4d8c2SCharles.Forsyth */
413*74a4d8c2SCharles.Forsyth conf.npage1 = conf.npage0 - (8*MB)/BY2PG;
414*74a4d8c2SCharles.Forsyth conf.base1 = conf.base0 + 8*MB;
415*74a4d8c2SCharles.Forsyth conf.npage0 = (8*MB)/BY2PG;
416*74a4d8c2SCharles.Forsyth bank[1] = bank[0]-8;
417*74a4d8c2SCharles.Forsyth bank[0] = 8;
418*74a4d8c2SCharles.Forsyth }
419*74a4d8c2SCharles.Forsyth
420*74a4d8c2SCharles.Forsyth conf.npage = conf.npage0+conf.npage1;
421*74a4d8c2SCharles.Forsyth
422*74a4d8c2SCharles.Forsyth ktop = PGROUND((ulong)end);
423*74a4d8c2SCharles.Forsyth ktop = PADDR(ktop);
424*74a4d8c2SCharles.Forsyth conf.npage0 -= ktop/BY2PG;
425*74a4d8c2SCharles.Forsyth conf.base0 += ktop;
426*74a4d8c2SCharles.Forsyth
427*74a4d8c2SCharles.Forsyth conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
428*74a4d8c2SCharles.Forsyth conf.copymode = 0; /* copy on write */
429*74a4d8c2SCharles.Forsyth conf.arp = 32;
430*74a4d8c2SCharles.Forsyth conf.ialloc = (((conf.npage*(100-sparam->pcnt))/100)/2)*BY2PG;
431*74a4d8c2SCharles.Forsyth
432*74a4d8c2SCharles.Forsyth eve = strdup("inferno");
433*74a4d8c2SCharles.Forsyth
434*74a4d8c2SCharles.Forsyth #ifdef notdef
435*74a4d8c2SCharles.Forsyth /* XXX - Eric - Autoconfigure memory */
436*74a4d8c2SCharles.Forsyth /* XXX - Tad: 8 eigths, total... */
437*74a4d8c2SCharles.Forsyth mainmem->maxsize = (conf.npage*BY2PG)/8;
438*74a4d8c2SCharles.Forsyth heapmem->maxsize = ((conf.npage*BY2PG)*5)/8;
439*74a4d8c2SCharles.Forsyth imagmem->maxsize = ((conf.npage*BY2PG)*2)/8;
440*74a4d8c2SCharles.Forsyth #endif
441*74a4d8c2SCharles.Forsyth }
442*74a4d8c2SCharles.Forsyth
443*74a4d8c2SCharles.Forsyth /*
444*74a4d8c2SCharles.Forsyth * set up the lance
445*74a4d8c2SCharles.Forsyth */
446*74a4d8c2SCharles.Forsyth void
lancesetup(Lance * lp)447*74a4d8c2SCharles.Forsyth lancesetup(Lance *lp)
448*74a4d8c2SCharles.Forsyth {
449*74a4d8c2SCharles.Forsyth KMap *k;
450*74a4d8c2SCharles.Forsyth DMAdev *dma;
451*74a4d8c2SCharles.Forsyth ulong pa, va;
452*74a4d8c2SCharles.Forsyth int i;
453*74a4d8c2SCharles.Forsyth
454*74a4d8c2SCharles.Forsyth k = kmappa(ETHER, PTEIO|PTENOCACHE);
455*74a4d8c2SCharles.Forsyth lp->rdp = (void*)(VA(k)+0);
456*74a4d8c2SCharles.Forsyth lp->rap = (void*)(VA(k)+2);
457*74a4d8c2SCharles.Forsyth for(i=0; i<6; i++)
458*74a4d8c2SCharles.Forsyth lp->ea[i] = idprom.ea[i];
459*74a4d8c2SCharles.Forsyth
460*74a4d8c2SCharles.Forsyth lp->lognrrb = 7;
461*74a4d8c2SCharles.Forsyth lp->logntrb = 7;
462*74a4d8c2SCharles.Forsyth lp->nrrb = 1<<lp->lognrrb;
463*74a4d8c2SCharles.Forsyth lp->ntrb = 1<<lp->logntrb;
464*74a4d8c2SCharles.Forsyth lp->sep = 1;
465*74a4d8c2SCharles.Forsyth lp->busctl = BSWP | ACON | BCON;
466*74a4d8c2SCharles.Forsyth
467*74a4d8c2SCharles.Forsyth /*
468*74a4d8c2SCharles.Forsyth * Allocate area for lance init block and descriptor rings
469*74a4d8c2SCharles.Forsyth */
470*74a4d8c2SCharles.Forsyth pa = PADDR(xspanalloc(BY2PG, BY2PG, 0));
471*74a4d8c2SCharles.Forsyth
472*74a4d8c2SCharles.Forsyth /* map at LANCESEGM */
473*74a4d8c2SCharles.Forsyth va = kmapdma(pa, BY2PG);
474*74a4d8c2SCharles.Forsyth lp->lanceram = (ushort*)va;
475*74a4d8c2SCharles.Forsyth lp->lm = (Lancemem*)va;
476*74a4d8c2SCharles.Forsyth
477*74a4d8c2SCharles.Forsyth /*
478*74a4d8c2SCharles.Forsyth * Allocate space in host memory for the io buffers.
479*74a4d8c2SCharles.Forsyth */
480*74a4d8c2SCharles.Forsyth i = (lp->nrrb+lp->ntrb)*sizeof(Lancepkt);
481*74a4d8c2SCharles.Forsyth i = (i+(BY2PG-1))/BY2PG;
482*74a4d8c2SCharles.Forsyth pa = PADDR(xspanalloc(i*BY2PG, BY2PG, 0));
483*74a4d8c2SCharles.Forsyth va = kmapdma(pa, i*BY2PG);
484*74a4d8c2SCharles.Forsyth
485*74a4d8c2SCharles.Forsyth lp->lrp = (Lancepkt*)va;
486*74a4d8c2SCharles.Forsyth lp->rp = (Lancepkt*)va;
487*74a4d8c2SCharles.Forsyth lp->ltp = lp->lrp+lp->nrrb;
488*74a4d8c2SCharles.Forsyth lp->tp = lp->rp+lp->nrrb;
489*74a4d8c2SCharles.Forsyth
490*74a4d8c2SCharles.Forsyth k = kmappa(DMA, PTEIO|PTENOCACHE);
491*74a4d8c2SCharles.Forsyth dma = (DMAdev*)VA(k);
492*74a4d8c2SCharles.Forsyth dma->base = 0xff;
493*74a4d8c2SCharles.Forsyth
494*74a4d8c2SCharles.Forsyth /*
495*74a4d8c2SCharles.Forsyth * for now, let's assume the ROM has left the results of its
496*74a4d8c2SCharles.Forsyth * auto-sensing
497*74a4d8c2SCharles.Forsyth */
498*74a4d8c2SCharles.Forsyth #ifdef notdef
499*74a4d8c2SCharles.Forsyth if(dma->ecsr & E_TP_select)
500*74a4d8c2SCharles.Forsyth print("Twisted pair ethernet\n");
501*74a4d8c2SCharles.Forsyth else
502*74a4d8c2SCharles.Forsyth print("AUI ethernet\n");
503*74a4d8c2SCharles.Forsyth #endif
504*74a4d8c2SCharles.Forsyth microdelay(1);
505*74a4d8c2SCharles.Forsyth dma->ecsr |= E_Int_en|E_Invalidate|E_Dsbl_wr_inval|E_Dsbl_rd_drn;
506*74a4d8c2SCharles.Forsyth microdelay(1);
507*74a4d8c2SCharles.Forsyth }
508*74a4d8c2SCharles.Forsyth
509*74a4d8c2SCharles.Forsyth static void
linkproc(void)510*74a4d8c2SCharles.Forsyth linkproc(void)
511*74a4d8c2SCharles.Forsyth {
512*74a4d8c2SCharles.Forsyth spllo();
513*74a4d8c2SCharles.Forsyth (*up->kpfun)(up->arg);
514*74a4d8c2SCharles.Forsyth }
515*74a4d8c2SCharles.Forsyth
516*74a4d8c2SCharles.Forsyth void
kprocchild(Proc * p,void (* func)(void *),void * arg)517*74a4d8c2SCharles.Forsyth kprocchild(Proc *p, void (*func)(void*), void *arg)
518*74a4d8c2SCharles.Forsyth {
519*74a4d8c2SCharles.Forsyth p->sched.pc = (ulong)linkproc;
520*74a4d8c2SCharles.Forsyth p->sched.sp = (ulong)p->kstack+KSTACK-8;
521*74a4d8c2SCharles.Forsyth
522*74a4d8c2SCharles.Forsyth p->kpfun = func;
523*74a4d8c2SCharles.Forsyth p->arg = arg;
524*74a4d8c2SCharles.Forsyth }
525*74a4d8c2SCharles.Forsyth
526*74a4d8c2SCharles.Forsyth
527*74a4d8c2SCharles.Forsyth void
FPsave(void * f)528*74a4d8c2SCharles.Forsyth FPsave(void *f) /* f should be a FPenv */
529*74a4d8c2SCharles.Forsyth {
530*74a4d8c2SCharles.Forsyth savefsr(f);
531*74a4d8c2SCharles.Forsyth }
532*74a4d8c2SCharles.Forsyth
533*74a4d8c2SCharles.Forsyth void
FPrestore(void * f)534*74a4d8c2SCharles.Forsyth FPrestore(void *f) /* f should be a FPenv */
535*74a4d8c2SCharles.Forsyth {
536*74a4d8c2SCharles.Forsyth restfsr(f);
537*74a4d8c2SCharles.Forsyth }
538*74a4d8c2SCharles.Forsyth
539*74a4d8c2SCharles.Forsyth void
fpsave(FPU * f)540*74a4d8c2SCharles.Forsyth fpsave(FPU *f)
541*74a4d8c2SCharles.Forsyth {
542*74a4d8c2SCharles.Forsyth savefpregs( f );
543*74a4d8c2SCharles.Forsyth }
544*74a4d8c2SCharles.Forsyth
545*74a4d8c2SCharles.Forsyth void
fprestore(FPU * f)546*74a4d8c2SCharles.Forsyth fprestore(FPU *f)
547*74a4d8c2SCharles.Forsyth {
548*74a4d8c2SCharles.Forsyth restfpregs(f);
549*74a4d8c2SCharles.Forsyth }
550*74a4d8c2SCharles.Forsyth
551*74a4d8c2SCharles.Forsyth int
islo(void)552*74a4d8c2SCharles.Forsyth islo(void)
553*74a4d8c2SCharles.Forsyth {
554*74a4d8c2SCharles.Forsyth int val;
555*74a4d8c2SCharles.Forsyth val = (getpsr()&SPL(15)) == 0;
556*74a4d8c2SCharles.Forsyth
557*74a4d8c2SCharles.Forsyth return val;
558*74a4d8c2SCharles.Forsyth }
559*74a4d8c2SCharles.Forsyth
560*74a4d8c2SCharles.Forsyth void
setvec(void)561*74a4d8c2SCharles.Forsyth setvec(void)
562*74a4d8c2SCharles.Forsyth {
563*74a4d8c2SCharles.Forsyth /* XXX - Tad: eventually implement this */
564*74a4d8c2SCharles.Forsyth }
565