bcm: move CONFADDR parsing into bootargs.c, simplify initcode start() args handling

This commit is contained in:
cinap_lenrek 2019-04-11 19:10:47 +02:00
parent 6aff58df75
commit 810aed76a5
4 changed files with 183 additions and 224 deletions

169
sys/src/9/bcm/bootargs.c Normal file
View file

@ -0,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);
}

View file

@ -5,6 +5,7 @@ Dirtab* addarchfile(char*, int, long(*)(Chan*, void*, long, vlong),
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 procfork(Proc*);
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 vgpset(uint, int);
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);

View file

@ -15,180 +15,11 @@
#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)
{
@ -245,16 +76,6 @@ launchinit(void)
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 @@ main(void)
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 @@ main(void)
void
init0(void)
{
int i;
char buf[2*KNAMELEN];
char buf[2*KNAMELEN], **sp;
up->nerrlab = 0;
coherence();
@ -342,50 +159,19 @@ init0(void)
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);
sp = (char**)(USTKTOP - sizeof(Tos) - 8 - sizeof(sp[0])*4);
sp[3] = sp[2] = sp[1] = nil;
strcpy(sp[0] = (char*)&sp[4], "boot");
touser((uintptr)sp);
assert(0); /* shouldn't have returned */
}
static void
bootargs(uintptr base)
{
int i;
ulong ssize;
char **av, *p;
/*
* 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;
}
/*
* create the first process
*/
@ -433,7 +219,7 @@ userinit(void)
pg = newpage(1, 0, USTKTOP-BY2PG);
segpage(s, pg);
k = kmap(pg);
bootargs(VA(k));
memset((void*)VA(k), 0, BY2PG);
kunmap(k);
/*

View file

@ -45,6 +45,7 @@ OBJ=\
lexception.$O\
lproc.$O\
arch.$O\
bootargs.$O\
clock.$O\
fpi.$O\
fpiarm.$O\