shithub: riscv

Download patch

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\