changelog shortlog tags branches changeset files revisions annotate raw help

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

changeset 7159: 66132ebbe687
child: fc141b91ed8a
author: cinap_lenrek@felloff.net
date: Thu, 11 Apr 2019 19:10:47 +0200
permissions: -rw-r--r--
description: bcm: move CONFADDR parsing into bootargs.c, simplify initcode start() args handling
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  Atag *a;
92  int n;
93 
94  a = (Atag*)BOOTARGS;
95  if(a->tag != AtagCore){
96  plan9iniinit((char*)a, 0);
97  return;
98  }
99  while(a->tag != AtagNone && a->size != 0){
100  switch(a->tag){
101  case AtagMem:
102  /* use only first bank */
103  if(conf.mem[0].limit == 0 && a->mem.size != 0){
104  memsize = a->mem.size;
105  conf.mem[0].base = a->mem.base;
106  conf.mem[0].limit = a->mem.base + memsize;
107  }
108  break;
109  case AtagCmdline:
110  n = (a->size * sizeof(u32int)) - offsetof(Atag, cmdline[0]);
111  if(a->cmdline + n < BOOTARGS + BOOTARGSLEN)
112  a->cmdline[n] = 0;
113  else
114  BOOTARGS[BOOTARGSLEN-1] = 0;
115  plan9iniinit(a->cmdline, 1);
116  break;
117  }
118  a = (Atag*)((u32int*)a + a->size);
119  }
120 }
121 
122 char*
123 getconf(char *name)
124 {
125  int i;
126 
127  if((i = findconf(name)) < 0)
128  return nil;
129  return confval[i];
130 }
131 
132 void
133 setconfenv(void)
134 {
135  int i;
136 
137  for(i = 0; i < nconf; i++){
138  if(confname[i][0] != '*')
139  ksetenv(confname[i], confval[i], 0);
140  ksetenv(confname[i], confval[i], 1);
141  }
142 }
143 
144 void
145 writeconf(void)
146 {
147  char *p, *q;
148  int n;
149 
150  p = getconfenv();
151  if(waserror()) {
152  free(p);
153  nexterror();
154  }
155 
156  /* convert to name=value\n format */
157  for(q=p; *q; q++) {
158  q += strlen(q);
159  *q = '=';
160  q += strlen(q);
161  *q = '\n';
162  }
163  n = q - p + 1;
164  if(n >= BOOTARGSLEN)
165  error("kernel configuration too large");
166  memmove(BOOTARGS, p, n);
167  poperror();
168  free(p);
169 }