changelog shortlog tags branches changeset files file revisions raw help

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