changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/9/bcm/bootargs.c

changeset 7234: fc141b91ed8a
parent: 66132ebbe687
child: 889b634159e5
author: cinap_lenrek@felloff.net
date: Mon, 13 May 2019 19:12:41 +0200
permissions: -rw-r--r--
description: bcm, bcm64: preserve memsize across reboots, avoid trashing atags while parsing cmdline

we override atag memory on reboot, so preserve
the memsize learned from atag as *maxmem plan9
variable. the global memsize variable is not
needed anymore.

avoid trashing the following atag when zero
terminating the cmdline string.

zero memory after plan9.ini variables.
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 
7 #define BOOTARGS ((char*)CONFADDR)
8 #define BOOTARGSLEN ((KZERO+REBOOTADDR)-CONFADDR)
9 
10 #define MAXCONF 64
11 static char *confname[MAXCONF];
12 static char *confval[MAXCONF];
13 static int nconf;
14 
15 typedef struct Atag Atag;
16 struct Atag {
17  u32int size; /* size of atag in words, including this header */
18  u32int tag; /* atag type */
19  union {
20  u32int data[1]; /* actually [size-2] */
21  /* AtagMem */
22  struct {
23  u32int size;
24  u32int base;
25  } mem;
26  /* AtagCmdLine */
27  char cmdline[1]; /* actually [4*(size-2)] */
28  };
29 };
30 
31 enum {
32  AtagNone = 0x00000000,
33  AtagCore = 0x54410001,
34  AtagMem = 0x54410002,
35  AtagCmdline = 0x54410009,
36 };
37 
38 static int
39 findconf(char *k)
40 {
41  int i;
42 
43  for(i = 0; i < nconf; i++)
44  if(cistrcmp(confname[i], k) == 0)
45  return i;
46  return -1;
47 }
48 
49 static void
50 addconf(char *k, char *v)
51 {
52  int i;
53 
54  i = findconf(k);
55  if(i < 0){
56  if(nconf >= MAXCONF)
57  return;
58  i = nconf++;
59  confname[i] = k;
60  }
61  confval[i] = v;
62 }
63 
64 static void
65 plan9iniinit(char *s, int cmdline)
66 {
67  char *toks[MAXCONF];
68  int i, c, n;
69  char *v;
70 
71  if((c = *s) < ' ' || c >= 0x80)
72  return;
73  if(cmdline)
74  n = tokenize(s, toks, MAXCONF);
75  else
76  n = getfields(s, toks, MAXCONF, 1, "\n");
77  for(i = 0; i < n; i++){
78  if(toks[i][0] == '#')
79  continue;
80  v = strchr(toks[i], '=');
81  if(v == nil)
82  continue;
83  *v++ = '\0';
84  addconf(toks[i], v);
85  }
86 }
87 
88 void
89 bootargsinit(void)
90 {
91  static char maxmem[11];
92  char x, *e;
93  Atag *a;
94 
95  e = BOOTARGS;
96  a = (Atag*)e;
97  if(a->tag != AtagCore){
98  plan9iniinit(e, 0);
99  return;
100  }
101  while(a->tag != AtagNone){
102  e += a->size * sizeof(u32int);
103  if(a->size < 2 || e < (char*)a || e > &BOOTARGS[BOOTARGSLEN])
104  break;
105  switch(a->tag){
106  case AtagMem:
107  if(findconf("*maxmem") < 0){
108  snprint(maxmem, sizeof(maxmem), "%ud", a->mem.base+a->mem.size);
109  addconf("*maxmem", maxmem);
110  }
111  break;
112  case AtagCmdline:
113  x = *e;
114  *e = 0;
115  plan9iniinit(a->cmdline, 1);
116  *e = x;
117  break;
118  }
119  if(e > &BOOTARGS[BOOTARGSLEN-8])
120  break;
121  a = (Atag*)e;
122  }
123 }
124 
125 char*
126 getconf(char *name)
127 {
128  int i;
129 
130  if((i = findconf(name)) < 0)
131  return nil;
132  return confval[i];
133 }
134 
135 void
136 setconfenv(void)
137 {
138  int i;
139 
140  for(i = 0; i < nconf; i++){
141  if(confname[i][0] != '*')
142  ksetenv(confname[i], confval[i], 0);
143  ksetenv(confname[i], confval[i], 1);
144  }
145 }
146 
147 void
148 writeconf(void)
149 {
150  char *p, *q;
151  int n;
152 
153  p = getconfenv();
154  if(waserror()) {
155  free(p);
156  nexterror();
157  }
158 
159  /* convert to name=value\n format */
160  for(q=p; *q; q++) {
161  q += strlen(q);
162  *q = '=';
163  q += strlen(q);
164  *q = '\n';
165  }
166  n = q - p + 1;
167  if(n >= BOOTARGSLEN)
168  error("kernel configuration too large");
169  memmove(BOOTARGS, p, n);
170  memset(BOOTARGS+n, 0, BOOTARGSLEN-n);
171  poperror();
172  free(p);
173 }