]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/bootargs.c
kernel: cleanup the software mouse cursor mess
[plan9front.git] / sys / src / 9 / pc / bootargs.c
1 #include        "u.h"
2 #include        "../port/lib.h"
3 #include        "mem.h"
4 #include        "dat.h"
5 #include        "fns.h"
6
7 #define MAXCONF 64
8 static char *confname[MAXCONF];
9 static char *confval[MAXCONF];
10 static int nconf;
11
12 /* screen.c */
13 extern char* rgbmask2chan(char *buf, int depth, u32int rm, u32int gm, u32int bm);
14
15 /* vgavesa.c */
16 extern char* vesabootscreenconf(char*, char*, uchar*);
17
18 static void
19 multibootargs(void)
20 {
21         extern ulong multibootptr;
22         ulong *multiboot;
23         char *cp, *ep, *s;
24         ulong *m, l;
25         int i, n;
26
27         if(multibootptr == 0 || multibootptr >= MemMin)
28                 return;
29
30         multiboot = (ulong*)KADDR(multibootptr);
31
32         cp = BOOTARGS;
33         ep = cp + BOOTARGSLEN-1;
34
35         /* memory map */
36         if((multiboot[0] & (1<<6)) != 0 && (l = multiboot[11]) >= 24){
37                 cp = seprint(cp, ep, "*e820=");
38                 m = KADDR(multiboot[12]);
39                 while(m[0] >= 20 && m[0]+4 <= l){
40                         uvlong base, size;
41                         m++;
42                         base = ((uvlong)m[0] | (uvlong)m[1]<<32);
43                         size = ((uvlong)m[2] | (uvlong)m[3]<<32);
44                         cp = seprint(cp, ep, "%.1lux %.16llux %.16llux ",
45                                 m[4] & 0xF, base, base+size);
46                         l -= m[-1]+4;
47                         m = (ulong*)((uintptr)m + m[-1]);
48                 }
49                 cp[-1] = '\n';
50         }
51
52         if((multiboot[0] & (1<<12)) != 0 && multiboot[22] != 0){        /* framebuffer */
53                 uchar *p = (uchar*)multiboot + 112;
54                 int depth = multiboot[27] & 0xFF;
55                 char chan[32];
56
57                 switch((multiboot[27]>>8) & 0xFF){
58                 case 0:
59                         snprint(chan, sizeof chan, "m%d", depth);
60                         if(0){
61                 case 1:
62                         rgbmask2chan(chan, depth,
63                                 (1UL<<p[1])-1 << p[0],
64                                 (1UL<<p[3])-1 << p[2],
65                                 (1UL<<p[5])-1 << p[4]);
66                         }
67                         cp = seprint(cp, ep, "*bootscreen=%dx%dx%d %s %#lux\n",
68                                 (int)multiboot[24]*8 / depth,
69                                 (int)multiboot[26],
70                                 depth,
71                                 chan,
72                                 multiboot[22]);
73                 }
74         } else
75         if((multiboot[0] & (1<<11)) != 0 && multiboot[19] != 0)         /* vbe mode info */
76                 cp = vesabootscreenconf(cp, ep, KADDR(multiboot[19]));
77
78         /* plan9.ini passed as the first module */
79         if((multiboot[0] & (1<<3)) != 0 && multiboot[5] > 0 && multiboot[6] != 0){
80                 m = KADDR(multiboot[6]);
81                 s = (char*)KADDR(m[0]);
82                 if(m[1] > m[0]){
83                         n = utfnlen(s, m[1] - m[0]);
84                         if(n > 0)
85                                 cp = seprint(cp, ep, "%.*s\n", n, s);
86                 }
87         }
88
89         /* command line */
90         if((multiboot[0] & (1<<2)) != 0 && multiboot[4] != 0){
91                 n = tokenize(KADDR(multiboot[4]), confval, MAXCONF);
92                 for(i=0; i<n; i++)
93                         cp = seprint(cp, ep, "%s\n", confval[i]);
94         }
95
96         *cp = 0;
97 }
98
99 void
100 bootargsinit(void)
101 {
102         int i, j, n;
103         char *cp, *line[MAXCONF], *p, *q;
104
105         multibootargs();
106
107         /*
108          *  parse configuration args from dos file plan9.ini
109          */
110         cp = BOOTARGS;  /* where b.com leaves its config */
111         cp[BOOTARGSLEN-1] = 0;
112
113         /*
114          * Strip out '\r', change '\t' -> ' '.
115          */
116         p = cp;
117         for(q = cp; *q; q++){
118                 if(*q == '\r')
119                         continue;
120                 if(*q == '\t')
121                         *q = ' ';
122                 *p++ = *q;
123         }
124         *p = 0;
125
126         n = getfields(cp, line, MAXCONF, 1, "\n");
127         for(i = 0; i < n; i++){
128                 if(*line[i] == '#')
129                         continue;
130                 cp = strchr(line[i], '=');
131                 if(cp == nil)
132                         continue;
133                 *cp++ = '\0';
134                 for(j = 0; j < nconf; j++){
135                         if(cistrcmp(confname[j], line[i]) == 0)
136                                 break;
137                 }
138                 confname[j] = line[i];
139                 confval[j] = cp;
140                 if(j == nconf)
141                         nconf++;
142         }
143 }
144
145 char*
146 getconf(char *name)
147 {
148         int i;
149
150         for(i = 0; i < nconf; i++)
151                 if(cistrcmp(confname[i], name) == 0)
152                         return confval[i];
153         return 0;
154 }
155
156 void
157 setconfenv(void)
158 {
159         int i;
160
161         for(i = 0; i < nconf; i++){
162                 if(confname[i][0] != '*')
163                         ksetenv(confname[i], confval[i], 0);
164                 ksetenv(confname[i], confval[i], 1);
165         }
166 }
167
168 void
169 writeconf(void)
170 {
171         char *p, *q;
172         int n;
173
174         p = getconfenv();
175         if(waserror()) {
176                 free(p);
177                 nexterror();
178         }
179
180         /* convert to name=value\n format */
181         for(q=p; *q; q++) {
182                 q += strlen(q);
183                 *q = '=';
184                 q += strlen(q);
185                 *q = '\n';
186         }
187         n = q - p + 1;
188         if(n >= BOOTARGSLEN)
189                 error("kernel configuration too large");
190         memmove(BOOTARGS, p, n);
191         memset(BOOTLINE, 0, BOOTLINELEN);
192         poperror();
193         free(p);
194 }