]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/bcm64/main.c
bootrc: allow kbmap to be set via plan9.ini (thanks Aaron Bieber)
[plan9front.git] / sys / src / 9 / bcm64 / main.c
1 #include "u.h"
2 #include "tos.h"
3 #include "../port/lib.h"
4 #include "mem.h"
5 #include "dat.h"
6 #include "fns.h"
7 #include "../port/error.h"
8 #include "io.h"
9 #include "sysreg.h"
10 #include "rebootcode.i"
11
12 #include <pool.h>
13 #include <libsec.h>
14
15 Conf conf;
16
17 /*
18  *  starting place for first process
19  */
20 void
21 init0(void)
22 {
23         char buf[2*KNAMELEN], **sp;
24
25         chandevinit();
26
27         if(!waserror()){
28                 snprint(buf, sizeof(buf), "%s %s", "ARM64", conffile);
29                 ksetenv("terminal", buf, 0);
30                 ksetenv("cputype", "arm64", 0);
31                 if(cpuserver)
32                         ksetenv("service", "cpu", 0);
33                 else
34                         ksetenv("service", "terminal", 0);
35                 snprint(buf, sizeof(buf), "-a %s", getethermac());
36                 ksetenv("etherargs", buf, 0);
37
38                 /* convert plan9.ini variables to #e and #ec */
39                 setconfenv();
40                 poperror();
41         }
42         kproc("alarm", alarmkproc, 0);
43
44         sp = (char**)(USTKTOP-sizeof(Tos) - 8 - sizeof(sp[0])*4);
45         sp[3] = sp[2] = sp[1] = nil;
46         strcpy(sp[1] = (char*)&sp[4], "boot");
47         sp[0] = (void*)&sp[1];
48         touser((uintptr)sp);
49 }
50
51 void
52 confinit(void)
53 {
54         int userpcnt;
55         ulong kpages;
56         char *p;
57         int i;
58
59         if(p = getconf("service")){
60                 if(strcmp(p, "cpu") == 0)
61                         cpuserver = 1;
62                 else if(strcmp(p,"terminal") == 0)
63                         cpuserver = 0;
64         }
65
66         if(p = getconf("*kernelpercent"))
67                 userpcnt = 100 - strtol(p, 0, 0);
68         else
69                 userpcnt = 0;
70
71         if(userpcnt < 10)
72                 userpcnt = 60 + cpuserver*10;
73
74         conf.npage = 0;
75         for(i = 0; i < nelem(conf.mem); i++)
76                 conf.npage += conf.mem[i].npage;
77
78         kpages = conf.npage - (conf.npage*userpcnt)/100;
79
80         /*
81          * can't go past the end of virtual memory
82          * (uintptr)-KZERO is 2^32 - KZERO
83          */
84         if(kpages > ((uintptr)-KZERO)/BY2PG)
85                 kpages = ((uintptr)-KZERO)/BY2PG;
86
87         conf.upages = conf.npage - kpages;
88         conf.ialloc = (kpages/2)*BY2PG;
89
90         conf.nmach = getncpus();
91
92         /* set up other configuration parameters */
93         conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
94         if(cpuserver)
95                 conf.nproc *= 3;
96         if(conf.nproc > 2000)
97                 conf.nproc = 2000;
98         conf.nswap = conf.npage*3;
99         conf.nswppo = 4096;
100         conf.nimage = 200;
101
102         conf.copymode = conf.nmach > 1;
103
104         /*
105          * Guess how much is taken by the large permanent
106          * datastructures. Mntcache and Mntrpc are not accounted for.
107          */
108         kpages = conf.npage - conf.upages;
109         kpages *= BY2PG;
110         kpages -= conf.upages*sizeof(Page)
111                 + conf.nproc*sizeof(Proc)
112                 + conf.nimage*sizeof(Image)
113                 + conf.nswap
114                 + conf.nswppo*sizeof(Page*);
115         mainmem->maxsize = kpages;
116         if(!cpuserver)
117                 /*
118                  * give terminals lots of image memory, too; the dynamic
119                  * allocation will balance the load properly, hopefully.
120                  * be careful with 32-bit overflow.
121                  */
122                 imagmem->maxsize = kpages;
123 }
124
125 void
126 machinit(void)
127 {
128         m->ticks = 1;
129         m->perf.period = 1;
130         active.machs[m->machno] = 1;
131 }
132
133 void
134 mpinit(void)
135 {
136         extern void _start(void);
137         int i;
138
139         for(i = 1; i < conf.nmach; i++){
140                 MACHP(i)->machno = i;
141                 cachedwbinvse(MACHP(i), MACHSIZE);
142         }
143         for(i = 0; i < MAXMACH; i++)
144                 ((uintptr*)SPINTABLE)[i] = i < conf.nmach ? PADDR(_start) : 0;
145         cachedwbinvse((void*)SPINTABLE, MAXMACH*8);
146
147         sev();
148         delay(100);
149         sev();
150
151         synccycles();
152
153         for(i = 0; i < MAXMACH; i++)
154                 ((uintptr*)SPINTABLE)[i] = 0;
155 }
156
157 void
158 main(uintptr arg0)
159 {
160         machinit();
161         if(m->machno){
162                 trapinit();
163                 fpuinit();
164                 clockinit();
165                 cpuidprint();
166                 synccycles();
167                 timersinit();
168                 flushtlb();
169                 mmu1init();
170                 m->ticks = MACHP(0)->ticks;
171                 schedinit();
172                 return;
173         }
174         quotefmtinstall();
175         bootargsinit(arg0);
176         meminit();
177         confinit();
178         xinit();
179         printinit();
180         uartconsinit();
181         screeninit();
182         print("\nPlan 9\n");
183
184         /* set clock rate to arm_freq from config.txt */
185         setclkrate(ClkArm, 0);
186
187         trapinit();
188         fpuinit();
189         vgpinit();
190         clockinit();
191         cpuidprint();
192         timersinit();
193         pageinit();
194         procinit0();
195         initseg();
196         links();
197         chandevreset();
198         userinit();
199         mpinit();
200         mmu0clear((uintptr*)L1);
201         flushtlb();
202         mmu1init();
203         schedinit();
204 }
205
206 static void
207 rebootjump(void *entry, void *code, ulong size)
208 {
209         void (*f)(void*, void*, ulong);
210
211         intrcpushutdown();
212
213         /* redo identity map */
214         mmuidmap((uintptr*)L1);
215
216         /* setup reboot trampoline function */
217         f = (void*)REBOOTADDR;
218         memmove(f, rebootcode, sizeof(rebootcode));
219
220         cachedwbinvse(f, sizeof(rebootcode));
221         cacheiinvse(f, sizeof(rebootcode));
222
223         (*f)(entry, code, size);
224
225         for(;;);
226 }
227
228 void
229 exit(int)
230 {
231         cpushutdown();
232         splfhi();
233         if(m->machno == 0)
234                 archreboot();
235         rebootjump(0, 0, 0);
236 }
237
238 void
239 reboot(void *entry, void *code, ulong size)
240 {
241         writeconf();
242         while(m->machno != 0){
243                 procwired(up, 0);
244                 sched();
245         }
246
247         cpushutdown();
248         delay(2000);
249
250         splfhi();
251
252         /* turn off buffered serial console */
253         serialoq = nil;
254
255         /* shutdown devices */
256         chandevshutdown();
257
258         /* stop the clock (and watchdog if any) */
259         clockshutdown();
260         wdogoff();
261         intrsoff();
262
263         /* off we go - never to return */
264         rebootjump(entry, code, size);
265 }
266
267 /*
268  * stub for ../omap/devether.c
269  */
270 int
271 isaconfig(char *, int, ISAConf *)
272 {
273         return 0;
274 }