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