ref: 810aed76a5cffd3dbbcb190d53e71eb84335a587
parent: 6aff58df7502dfb8b8ab9f981ec89fecd0d7e358
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Apr 11 15:10:47 EDT 2019
bcm: move CONFADDR parsing into bootargs.c, simplify initcode start() args handling
--- /dev/null
+++ b/sys/src/9/bcm/bootargs.c
@@ -1,0 +1,169 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+
+#define BOOTARGS ((char*)CONFADDR)
+#define BOOTARGSLEN ((KZERO+REBOOTADDR)-CONFADDR)
+
+#define MAXCONF 64
+static char *confname[MAXCONF];
+static char *confval[MAXCONF];
+static int nconf;
+
+typedef struct Atag Atag;
+struct Atag {
+ u32int size; /* size of atag in words, including this header */
+ u32int tag; /* atag type */
+ union {
+ u32int data[1]; /* actually [size-2] */
+ /* AtagMem */
+ struct {
+ u32int size;
+ u32int base;
+ } mem;
+ /* AtagCmdLine */
+ char cmdline[1]; /* actually [4*(size-2)] */
+ };
+};
+
+enum {
+ AtagNone = 0x00000000,
+ AtagCore = 0x54410001,
+ AtagMem = 0x54410002,
+ AtagCmdline = 0x54410009,
+};
+
+static int
+findconf(char *k)
+{
+ int i;
+
+ for(i = 0; i < nconf; i++)
+ if(cistrcmp(confname[i], k) == 0)
+ return i;
+ return -1;
+}
+
+static void
+addconf(char *k, char *v)
+{
+ int i;
+
+ i = findconf(k);
+ if(i < 0){
+ if(nconf >= MAXCONF)
+ return;
+ i = nconf++;
+ confname[i] = k;
+ }
+ confval[i] = v;
+}
+
+static void
+plan9iniinit(char *s, int cmdline)
+{
+ char *toks[MAXCONF];
+ int i, c, n;
+ char *v;
+
+ if((c = *s) < ' ' || c >= 0x80)
+ return;
+ if(cmdline)
+ n = tokenize(s, toks, MAXCONF);
+ else
+ n = getfields(s, toks, MAXCONF, 1, "\n");
+ for(i = 0; i < n; i++){
+ if(toks[i][0] == '#')
+ continue;
+ v = strchr(toks[i], '=');
+ if(v == nil)
+ continue;
+ *v++ = '\0';
+ addconf(toks[i], v);
+ }
+}
+
+void
+bootargsinit(void)
+{
+ Atag *a;
+ int n;
+
+ a = (Atag*)BOOTARGS;
+ if(a->tag != AtagCore){
+ plan9iniinit((char*)a, 0);
+ return;
+ }
+ while(a->tag != AtagNone && a->size != 0){
+ switch(a->tag){
+ case AtagMem:
+ /* use only first bank */
+ if(conf.mem[0].limit == 0 && a->mem.size != 0){
+ memsize = a->mem.size;
+ conf.mem[0].base = a->mem.base;
+ conf.mem[0].limit = a->mem.base + memsize;
+ }
+ break;
+ case AtagCmdline:
+ n = (a->size * sizeof(u32int)) - offsetof(Atag, cmdline[0]);
+ if(a->cmdline + n < BOOTARGS + BOOTARGSLEN)
+ a->cmdline[n] = 0;
+ else
+ BOOTARGS[BOOTARGSLEN-1] = 0;
+ plan9iniinit(a->cmdline, 1);
+ break;
+ }
+ a = (Atag*)((u32int*)a + a->size);
+ }
+}
+
+char*
+getconf(char *name)
+{
+ int i;
+
+ if((i = findconf(name)) < 0)
+ return nil;
+ return confval[i];
+}
+
+void
+setconfenv(void)
+{
+ int i;
+
+ for(i = 0; i < nconf; i++){
+ if(confname[i][0] != '*')
+ ksetenv(confname[i], confval[i], 0);
+ ksetenv(confname[i], confval[i], 1);
+ }
+}
+
+void
+writeconf(void)
+{
+ char *p, *q;
+ int n;
+
+ p = getconfenv();
+ if(waserror()) {
+ free(p);
+ nexterror();
+ }
+
+ /* convert to name=value\n format */
+ for(q=p; *q; q++) {
+ q += strlen(q);
+ *q = '=';
+ q += strlen(q);
+ *q = '\n';
+ }
+ n = q - p + 1;
+ if(n >= BOOTARGSLEN)
+ error("kernel configuration too large");
+ memmove(BOOTARGS, p, n);
+ poperror();
+ free(p);
+}
--- a/sys/src/9/bcm/fns.h
+++ b/sys/src/9/bcm/fns.h
@@ -5,6 +5,7 @@
extern void archreboot(void);
extern void archreset(void);
extern void armtimerset(int);
+extern void bootargsinit(void);
extern void cachedwbinv(void);
extern void cachedwbse(void*, int);
extern void cachedwbinvse(void*, int);
@@ -77,6 +78,7 @@
extern void procsetup(Proc*);
extern void screeninit(void);
extern void setclkrate(int, ulong);
+extern void setconfenv(void);
extern void setpower(int, int);
extern void setr13(int, u32int*);
extern int startcpus(uint);
@@ -93,6 +95,7 @@
extern void vtable(void);
extern void wdogoff(void);
extern void wdogfeed(void);
+extern void writeconf(void);
extern void vtable(void);
extern int l2ap(int);
extern uint getcputemp(void);
--- a/sys/src/9/bcm/main.c
+++ b/sys/src/9/bcm/main.c
@@ -15,181 +15,12 @@
#define Minfirmrev 326770
#define Minfirmdate "22 Jul 2012"
-/*
- * Where configuration info is left for the loaded programme.
- */
-#define BOOTARGS ((char*)CONFADDR)
-#define BOOTARGSLEN (REBOOTADDR-PADDR(CONFADDR))
-#define MAXCONF 64
-#define MAXCONFLINE 160
-
uintptr kseg0 = KZERO;
Mach* machaddr[MAXMACH];
Conf conf;
ulong memsize = 128*1024*1024;
-/*
- * Option arguments from the command line.
- * oargv[0] is the boot file.
- */
-static int oargc;
-static char* oargv[20];
-static char oargb[128];
-static int oargblen;
-
-static uintptr sp; /* XXX - must go - user stack of init proc */
-
-/* store plan9.ini contents here at least until we stash them in #ec */
-static char confname[MAXCONF][KNAMELEN];
-static char confval[MAXCONF][MAXCONFLINE];
-static int nconf;
-
-typedef struct Atag Atag;
-struct Atag {
- u32int size; /* size of atag in words, including this header */
- u32int tag; /* atag type */
- union {
- u32int data[1]; /* actually [size-2] */
- /* AtagMem */
- struct {
- u32int size;
- u32int base;
- } mem;
- /* AtagCmdLine */
- char cmdline[1]; /* actually [4*(size-2)] */
- };
-};
-
-enum {
- AtagNone = 0x00000000,
- AtagCore = 0x54410001,
- AtagMem = 0x54410002,
- AtagCmdline = 0x54410009,
-};
-
-static int
-findconf(char *name)
-{
- int i;
-
- for(i = 0; i < nconf; i++)
- if(cistrcmp(confname[i], name) == 0)
- return i;
- return -1;
-}
-
-char*
-getconf(char *name)
-{
- int i;
-
- i = findconf(name);
- if(i >= 0)
- return confval[i];
- return nil;
-}
-
void
-addconf(char *name, char *val)
-{
- int i;
-
- i = findconf(name);
- if(i < 0){
- if(val == nil || nconf >= MAXCONF)
- return;
- i = nconf++;
- strecpy(confname[i], confname[i]+sizeof(confname[i]), name);
- }
- strecpy(confval[i], confval[i]+sizeof(confval[i]), val);
-}
-
-static void
-writeconf(void)
-{
- char *p, *q;
- int n;
-
- p = getconfenv();
-
- if(waserror()) {
- free(p);
- nexterror();
- }
-
- /* convert to name=value\n format */
- for(q=p; *q; q++) {
- q += strlen(q);
- *q = '=';
- q += strlen(q);
- *q = '\n';
- }
- n = q - p + 1;
- if(n >= BOOTARGSLEN)
- error("kernel configuration too large");
- memmove(BOOTARGS, p, n);
- memset(BOOTARGS + n, '\n', BOOTARGSLEN - n);
- poperror();
- free(p);
-}
-
-static void
-plan9iniinit(char *s, int cmdline)
-{
- char *toks[MAXCONF];
- int i, c, n;
- char *v;
-
- if((c = *s) < ' ' || c >= 0x80)
- return;
- if(cmdline)
- n = tokenize(s, toks, MAXCONF);
- else
- n = getfields(s, toks, MAXCONF, 1, "\n");
- for(i = 0; i < n; i++){
- if(toks[i][0] == '#')
- continue;
- v = strchr(toks[i], '=');
- if(v == nil)
- continue;
- *v++ = '\0';
- addconf(toks[i], v);
- }
-}
-
-static void
-ataginit(Atag *a)
-{
- int n;
-
- if(a->tag != AtagCore){
- plan9iniinit((char*)a, 0);
- return;
- }
- while(a->tag != AtagNone){
- switch(a->tag){
- case AtagMem:
- /* use only first bank */
- if(conf.mem[0].limit == 0 && a->mem.size != 0){
- memsize = a->mem.size;
- conf.mem[0].base = a->mem.base;
- conf.mem[0].limit = a->mem.base + memsize;
- }
- break;
- case AtagCmdline:
- n = (a->size * sizeof(u32int)) - offsetof(Atag, cmdline[0]);
- if(a->cmdline + n < BOOTARGS + BOOTARGSLEN)
- a->cmdline[n] = 0;
- else
- BOOTARGS[BOOTARGSLEN-1] = 0;
- plan9iniinit(a->cmdline, 1);
- break;
- }
- a = (Atag*)((u32int*)a + a->size);
- }
-}
-
-void
machinit(void)
{
Mach *m0;
@@ -245,16 +76,6 @@
print("only %d cpu%s started\n", mach, mach == 1? "" : "s");
}
-static void
-optionsinit(char* s)
-{
- strecpy(oargb, oargb+sizeof(oargb), s);
-
- oargblen = strlen(oargb);
- oargc = tokenize(oargb, oargv, nelem(oargv)-1);
- oargv[oargc] = nil;
-}
-
void
main(void)
{
@@ -264,11 +85,8 @@
m = (Mach*)MACHADDR;
memset(edata, 0, end - edata); /* clear bss */
mach0init();
-
- optionsinit("/boot/boot boot");
quotefmtinstall();
-
- ataginit((Atag*)BOOTARGS);
+ bootargsinit();
confinit(); /* figures out amount of memory */
xinit();
uartconsinit();
@@ -312,8 +130,7 @@
void
init0(void)
{
- int i;
- char buf[2*KNAMELEN];
+ char buf[2*KNAMELEN], **sp;
up->nerrlab = 0;
coherence();
@@ -342,48 +159,17 @@
ksetenv("etherargs", buf, 0);
/* convert plan9.ini variables to #e and #ec */
- for(i = 0; i < nconf; i++) {
- ksetenv(confname[i], confval[i], 0);
- ksetenv(confname[i], confval[i], 1);
- }
+ setconfenv();
poperror();
}
kproc("alarm", alarmkproc, 0);
- touser(sp);
- assert(0); /* shouldn't have returned */
-}
-static void
-bootargs(uintptr base)
-{
- int i;
- ulong ssize;
- char **av, *p;
+ sp = (char**)(USTKTOP - sizeof(Tos) - 8 - sizeof(sp[0])*4);
+ sp[3] = sp[2] = sp[1] = nil;
+ strcpy(sp[0] = (char*)&sp[4], "boot");
- /*
- * Push the boot args onto the stack.
- * The initial value of the user stack must be such
- * that the total used is larger than the maximum size
- * of the argument list checked in syscall.
- */
- i = oargblen+1;
- p = (void*)STACKALIGN(base + BY2PG - sizeof(Tos) - i);
- memmove(p, oargb, i);
-
- /*
- * Now push the argv pointers.
- * The code jumped to by touser in lproc.s expects arguments
- * main(char* argv0, ...)
- * and calls
- * startboot("/boot/boot", &argv0)
- * not the usual (int argc, char* argv[])
- */
- av = (char**)(p - (oargc+1)*sizeof(char*));
- ssize = base + BY2PG - (uintptr)av;
- for(i = 0; i < oargc; i++)
- *av++ = (oargv[i] - oargb) + (p - base) + (USTKTOP - BY2PG);
- *av = nil;
- sp = USTKTOP - ssize;
+ touser((uintptr)sp);
+ assert(0); /* shouldn't have returned */
}
/*
@@ -433,7 +219,7 @@
pg = newpage(1, 0, USTKTOP-BY2PG);
segpage(s, pg);
k = kmap(pg);
- bootargs(VA(k));
+ memset((void*)VA(k), 0, BY2PG);
kunmap(k);
/*
--- a/sys/src/9/bcm/mkfile
+++ b/sys/src/9/bcm/mkfile
@@ -45,6 +45,7 @@
lexception.$O\
lproc.$O\
arch.$O\
+ bootargs.$O\
clock.$O\
fpi.$O\
fpiarm.$O\