2003-04-22 21:02:15 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2008-11-30 15:52:46 +01:00
|
|
|
#include <unistd.h>
|
2003-04-22 21:02:15 +02:00
|
|
|
#include <ctype.h>
|
2004-03-11 16:01:31 +01:00
|
|
|
#include <errno.h>
|
2008-12-02 13:26:17 +01:00
|
|
|
#include <libgen.h>
|
2003-04-22 21:02:15 +02:00
|
|
|
#include "../../src/include/pc80/mc146818rtc.h"
|
2008-01-18 17:16:45 +01:00
|
|
|
#include "../../src/include/boot/coreboot_tables.h"
|
2003-04-22 21:02:15 +02:00
|
|
|
|
2009-04-22 11:03:08 +02:00
|
|
|
#define CMOS_IMAGE_BUFFER_SIZE 256
|
2003-04-22 21:02:15 +02:00
|
|
|
#define INPUT_LINE_MAX 256
|
|
|
|
#define MAX_VALUE_BYTE_LENGTH 64
|
|
|
|
|
2008-12-02 13:26:17 +01:00
|
|
|
#define TMPFILE_LEN 256
|
|
|
|
#define TMPFILE_TEMPLATE "/build_opt_tbl_XXXXXX"
|
2003-04-22 21:02:15 +02:00
|
|
|
|
|
|
|
static unsigned char cmos_table[4096];
|
|
|
|
|
|
|
|
/* This routine loops through the entried and tests if any of the fields overlap
|
|
|
|
input entry_start = the memory pointer to the start of the entries.
|
|
|
|
entry_end = the byte past the entries.
|
|
|
|
output none
|
|
|
|
if there is an overlap, the routine exits, other wise it returns.
|
|
|
|
*/
|
CMOS: Add set_option and rework get_option.
To ease some of my debugging pain on the unichrome, i decided i needed to
move FB size selection into cmos, so i could test a size and then reset it
to the default after loading this value so that the next reboot uses the
(working) default again. This meant implementing set_option in parallel to
get_option.
get_option was then found to have inversed argument ordering (like outb) and
passing char * and then depending on the cmos layout length, which made me
feel quite uncomfortable. Since we either have reserved space (which we
shouldn't do anything with in these two functions), an enum or a
hexadecimal value, unsigned int seemed like the way to go. So all users of
get_option now have their arguments inversed and switched from using ints
to unsigned ints now.
The way get_cmos_value was implemented forced us to not overlap byte and to
have multibyte values be byte aligned. This logic is now adapted to do a
full uint32_t read (when needed) at any offset and any length up to 32, and
the shifting all happens inside an uint32_t as well. set_cmos_value was
implemented similarly. Both routines have been extensively tested in a
quick separate little program as it is not easy to get this stuff right.
build_opt_tbl.c was altered to function correctly within these new
parameters. The enum value retrieval has been changed strol(..., NULL, 10)
to stroul(..., NULL, 0), so that we not only are able to use unsigned ints
now but so that we also interprete hex values correctly. The 32bit limit
gets imposed on all entries not marked reserved, an unused "user_data" field
that appeared in a lot of cmos.layouts has been changed to reserved as well.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4332 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-06-03 12:47:19 +02:00
|
|
|
|
2003-10-11 08:20:25 +02:00
|
|
|
void test_for_entry_overlaps(void *entry_start, void *entry_end)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
2003-10-11 08:20:25 +02:00
|
|
|
char *cptr;
|
CMOS: Add set_option and rework get_option.
To ease some of my debugging pain on the unichrome, i decided i needed to
move FB size selection into cmos, so i could test a size and then reset it
to the default after loading this value so that the next reboot uses the
(working) default again. This meant implementing set_option in parallel to
get_option.
get_option was then found to have inversed argument ordering (like outb) and
passing char * and then depending on the cmos layout length, which made me
feel quite uncomfortable. Since we either have reserved space (which we
shouldn't do anything with in these two functions), an enum or a
hexadecimal value, unsigned int seemed like the way to go. So all users of
get_option now have their arguments inversed and switched from using ints
to unsigned ints now.
The way get_cmos_value was implemented forced us to not overlap byte and to
have multibyte values be byte aligned. This logic is now adapted to do a
full uint32_t read (when needed) at any offset and any length up to 32, and
the shifting all happens inside an uint32_t as well. set_cmos_value was
implemented similarly. Both routines have been extensively tested in a
quick separate little program as it is not easy to get this stuff right.
build_opt_tbl.c was altered to function correctly within these new
parameters. The enum value retrieval has been changed strol(..., NULL, 10)
to stroul(..., NULL, 0), so that we not only are able to use unsigned ints
now but so that we also interprete hex values correctly. The 32bit limit
gets imposed on all entries not marked reserved, an unused "user_data" field
that appeared in a lot of cmos.layouts has been changed to reserved as well.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4332 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-06-03 12:47:19 +02:00
|
|
|
struct cmos_entries *ce = NULL;
|
2003-04-22 21:02:15 +02:00
|
|
|
unsigned char test[CMOS_IMAGE_BUFFER_SIZE];
|
CMOS: Add set_option and rework get_option.
To ease some of my debugging pain on the unichrome, i decided i needed to
move FB size selection into cmos, so i could test a size and then reset it
to the default after loading this value so that the next reboot uses the
(working) default again. This meant implementing set_option in parallel to
get_option.
get_option was then found to have inversed argument ordering (like outb) and
passing char * and then depending on the cmos layout length, which made me
feel quite uncomfortable. Since we either have reserved space (which we
shouldn't do anything with in these two functions), an enum or a
hexadecimal value, unsigned int seemed like the way to go. So all users of
get_option now have their arguments inversed and switched from using ints
to unsigned ints now.
The way get_cmos_value was implemented forced us to not overlap byte and to
have multibyte values be byte aligned. This logic is now adapted to do a
full uint32_t read (when needed) at any offset and any length up to 32, and
the shifting all happens inside an uint32_t as well. set_cmos_value was
implemented similarly. Both routines have been extensively tested in a
quick separate little program as it is not easy to get this stuff right.
build_opt_tbl.c was altered to function correctly within these new
parameters. The enum value retrieval has been changed strol(..., NULL, 10)
to stroul(..., NULL, 0), so that we not only are able to use unsigned ints
now but so that we also interprete hex values correctly. The 32bit limit
gets imposed on all entries not marked reserved, an unused "user_data" field
that appeared in a lot of cmos.layouts has been changed to reserved as well.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4332 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-06-03 12:47:19 +02:00
|
|
|
int i;
|
|
|
|
|
|
|
|
memset(test, 0, CMOS_IMAGE_BUFFER_SIZE);
|
|
|
|
|
|
|
|
for (cptr = entry_start; cptr < (char *)entry_end; cptr += ce->size) {
|
|
|
|
ce = (struct cmos_entries *)cptr;
|
2003-04-22 21:02:15 +02:00
|
|
|
|
CMOS: Add set_option and rework get_option.
To ease some of my debugging pain on the unichrome, i decided i needed to
move FB size selection into cmos, so i could test a size and then reset it
to the default after loading this value so that the next reboot uses the
(working) default again. This meant implementing set_option in parallel to
get_option.
get_option was then found to have inversed argument ordering (like outb) and
passing char * and then depending on the cmos layout length, which made me
feel quite uncomfortable. Since we either have reserved space (which we
shouldn't do anything with in these two functions), an enum or a
hexadecimal value, unsigned int seemed like the way to go. So all users of
get_option now have their arguments inversed and switched from using ints
to unsigned ints now.
The way get_cmos_value was implemented forced us to not overlap byte and to
have multibyte values be byte aligned. This logic is now adapted to do a
full uint32_t read (when needed) at any offset and any length up to 32, and
the shifting all happens inside an uint32_t as well. set_cmos_value was
implemented similarly. Both routines have been extensively tested in a
quick separate little program as it is not easy to get this stuff right.
build_opt_tbl.c was altered to function correctly within these new
parameters. The enum value retrieval has been changed strol(..., NULL, 10)
to stroul(..., NULL, 0), so that we not only are able to use unsigned ints
now but so that we also interprete hex values correctly. The 32bit limit
gets imposed on all entries not marked reserved, an unused "user_data" field
that appeared in a lot of cmos.layouts has been changed to reserved as well.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4332 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-06-03 12:47:19 +02:00
|
|
|
/* Only reserved space can be larger than 32bits */
|
|
|
|
if ((ce->length > 32) && (ce->config != 'r')) {
|
|
|
|
fprintf(stderr, "Error: Entry %s is longer than"
|
|
|
|
" 32bits.\n", ce->name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2003-10-11 08:20:25 +02:00
|
|
|
|
2003-04-22 21:02:15 +02:00
|
|
|
/* test if entry goes past the end of the buffer */
|
CMOS: Add set_option and rework get_option.
To ease some of my debugging pain on the unichrome, i decided i needed to
move FB size selection into cmos, so i could test a size and then reset it
to the default after loading this value so that the next reboot uses the
(working) default again. This meant implementing set_option in parallel to
get_option.
get_option was then found to have inversed argument ordering (like outb) and
passing char * and then depending on the cmos layout length, which made me
feel quite uncomfortable. Since we either have reserved space (which we
shouldn't do anything with in these two functions), an enum or a
hexadecimal value, unsigned int seemed like the way to go. So all users of
get_option now have their arguments inversed and switched from using ints
to unsigned ints now.
The way get_cmos_value was implemented forced us to not overlap byte and to
have multibyte values be byte aligned. This logic is now adapted to do a
full uint32_t read (when needed) at any offset and any length up to 32, and
the shifting all happens inside an uint32_t as well. set_cmos_value was
implemented similarly. Both routines have been extensively tested in a
quick separate little program as it is not easy to get this stuff right.
build_opt_tbl.c was altered to function correctly within these new
parameters. The enum value retrieval has been changed strol(..., NULL, 10)
to stroul(..., NULL, 0), so that we not only are able to use unsigned ints
now but so that we also interprete hex values correctly. The 32bit limit
gets imposed on all entries not marked reserved, an unused "user_data" field
that appeared in a lot of cmos.layouts has been changed to reserved as well.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4332 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-06-03 12:47:19 +02:00
|
|
|
if ((ce->bit + ce->length) > (CMOS_IMAGE_BUFFER_SIZE * 8)) {
|
|
|
|
fprintf(stderr, "Error: Entry %s exceeds CMOS"
|
|
|
|
" space.\n", ce->name);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
CMOS: Add set_option and rework get_option.
To ease some of my debugging pain on the unichrome, i decided i needed to
move FB size selection into cmos, so i could test a size and then reset it
to the default after loading this value so that the next reboot uses the
(working) default again. This meant implementing set_option in parallel to
get_option.
get_option was then found to have inversed argument ordering (like outb) and
passing char * and then depending on the cmos layout length, which made me
feel quite uncomfortable. Since we either have reserved space (which we
shouldn't do anything with in these two functions), an enum or a
hexadecimal value, unsigned int seemed like the way to go. So all users of
get_option now have their arguments inversed and switched from using ints
to unsigned ints now.
The way get_cmos_value was implemented forced us to not overlap byte and to
have multibyte values be byte aligned. This logic is now adapted to do a
full uint32_t read (when needed) at any offset and any length up to 32, and
the shifting all happens inside an uint32_t as well. set_cmos_value was
implemented similarly. Both routines have been extensively tested in a
quick separate little program as it is not easy to get this stuff right.
build_opt_tbl.c was altered to function correctly within these new
parameters. The enum value retrieval has been changed strol(..., NULL, 10)
to stroul(..., NULL, 0), so that we not only are able to use unsigned ints
now but so that we also interprete hex values correctly. The 32bit limit
gets imposed on all entries not marked reserved, an unused "user_data" field
that appeared in a lot of cmos.layouts has been changed to reserved as well.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4332 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-06-03 12:47:19 +02:00
|
|
|
|
|
|
|
/* see whether our bits were marked before */
|
|
|
|
for (i = ce->bit; i < (ce->bit + ce->length); i++)
|
|
|
|
if (test[i / 8] & (0x01 << (i % 8))) {
|
|
|
|
printf("Error: Entry %s overlaps at bit %d.\n",
|
|
|
|
ce->name, i);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
CMOS: Add set_option and rework get_option.
To ease some of my debugging pain on the unichrome, i decided i needed to
move FB size selection into cmos, so i could test a size and then reset it
to the default after loading this value so that the next reboot uses the
(working) default again. This meant implementing set_option in parallel to
get_option.
get_option was then found to have inversed argument ordering (like outb) and
passing char * and then depending on the cmos layout length, which made me
feel quite uncomfortable. Since we either have reserved space (which we
shouldn't do anything with in these two functions), an enum or a
hexadecimal value, unsigned int seemed like the way to go. So all users of
get_option now have their arguments inversed and switched from using ints
to unsigned ints now.
The way get_cmos_value was implemented forced us to not overlap byte and to
have multibyte values be byte aligned. This logic is now adapted to do a
full uint32_t read (when needed) at any offset and any length up to 32, and
the shifting all happens inside an uint32_t as well. set_cmos_value was
implemented similarly. Both routines have been extensively tested in a
quick separate little program as it is not easy to get this stuff right.
build_opt_tbl.c was altered to function correctly within these new
parameters. The enum value retrieval has been changed strol(..., NULL, 10)
to stroul(..., NULL, 0), so that we not only are able to use unsigned ints
now but so that we also interprete hex values correctly. The 32bit limit
gets imposed on all entries not marked reserved, an unused "user_data" field
that appeared in a lot of cmos.layouts has been changed to reserved as well.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4332 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-06-03 12:47:19 +02:00
|
|
|
|
|
|
|
/* now mark our bits */
|
|
|
|
for (i = ce->bit; i < (ce->bit + ce->length); i++)
|
|
|
|
test[i / 8] |= 0x01 << (i % 8);
|
|
|
|
|
2003-04-22 21:02:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This routine displays the usage options */
|
2008-11-30 15:52:46 +01:00
|
|
|
void display_usage(char *name)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
2008-11-30 15:52:46 +01:00
|
|
|
printf("Usage: %s [--config filename]\n", name);
|
|
|
|
printf(" [--option filename]\n");
|
|
|
|
printf(" [--header filename]\n\n");
|
|
|
|
printf("--config = Build the definitions table from the given file.\n");
|
|
|
|
printf("--option = Output a C source file with the definitions.\n");
|
|
|
|
printf("--header = Ouput a C header file with the definitions.\n");
|
|
|
|
exit(1);
|
2003-04-22 21:02:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void skip_spaces(char *line, char **ptr)
|
|
|
|
{
|
|
|
|
if (!isspace(**ptr)) {
|
|
|
|
printf("Error missing whitespace in line\n%s\n", line);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
while(isspace(**ptr)) {
|
|
|
|
(*ptr)++;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
static unsigned long get_number(char *line, char **ptr, int base)
|
|
|
|
{
|
|
|
|
unsigned long value;
|
|
|
|
char *ptr2;
|
|
|
|
value = strtoul(*ptr, &ptr2, base);
|
|
|
|
if (ptr2 == *ptr) {
|
|
|
|
printf("Error missing digits at: \n%s\n in line:\n%s\n",
|
|
|
|
*ptr, line);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
*ptr = ptr2;
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2004-03-11 16:01:31 +01:00
|
|
|
static int is_ident_nondigit(int c)
|
|
|
|
{
|
CMOS: Add set_option and rework get_option.
To ease some of my debugging pain on the unichrome, i decided i needed to
move FB size selection into cmos, so i could test a size and then reset it
to the default after loading this value so that the next reboot uses the
(working) default again. This meant implementing set_option in parallel to
get_option.
get_option was then found to have inversed argument ordering (like outb) and
passing char * and then depending on the cmos layout length, which made me
feel quite uncomfortable. Since we either have reserved space (which we
shouldn't do anything with in these two functions), an enum or a
hexadecimal value, unsigned int seemed like the way to go. So all users of
get_option now have their arguments inversed and switched from using ints
to unsigned ints now.
The way get_cmos_value was implemented forced us to not overlap byte and to
have multibyte values be byte aligned. This logic is now adapted to do a
full uint32_t read (when needed) at any offset and any length up to 32, and
the shifting all happens inside an uint32_t as well. set_cmos_value was
implemented similarly. Both routines have been extensively tested in a
quick separate little program as it is not easy to get this stuff right.
build_opt_tbl.c was altered to function correctly within these new
parameters. The enum value retrieval has been changed strol(..., NULL, 10)
to stroul(..., NULL, 0), so that we not only are able to use unsigned ints
now but so that we also interprete hex values correctly. The 32bit limit
gets imposed on all entries not marked reserved, an unused "user_data" field
that appeared in a lot of cmos.layouts has been changed to reserved as well.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4332 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-06-03 12:47:19 +02:00
|
|
|
if (((c >= 'A') && (c <='Z')) ||
|
|
|
|
((c >= 'a') && (c <='z')) ||
|
|
|
|
(c == '_'))
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
2004-03-11 16:01:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int is_ident(char *str)
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
int ch;
|
|
|
|
ch = *str;
|
|
|
|
result = 0;
|
|
|
|
if (is_ident_nondigit(ch)) {
|
|
|
|
do {
|
|
|
|
str++;
|
|
|
|
ch = *str;
|
CMOS: Add set_option and rework get_option.
To ease some of my debugging pain on the unichrome, i decided i needed to
move FB size selection into cmos, so i could test a size and then reset it
to the default after loading this value so that the next reboot uses the
(working) default again. This meant implementing set_option in parallel to
get_option.
get_option was then found to have inversed argument ordering (like outb) and
passing char * and then depending on the cmos layout length, which made me
feel quite uncomfortable. Since we either have reserved space (which we
shouldn't do anything with in these two functions), an enum or a
hexadecimal value, unsigned int seemed like the way to go. So all users of
get_option now have their arguments inversed and switched from using ints
to unsigned ints now.
The way get_cmos_value was implemented forced us to not overlap byte and to
have multibyte values be byte aligned. This logic is now adapted to do a
full uint32_t read (when needed) at any offset and any length up to 32, and
the shifting all happens inside an uint32_t as well. set_cmos_value was
implemented similarly. Both routines have been extensively tested in a
quick separate little program as it is not easy to get this stuff right.
build_opt_tbl.c was altered to function correctly within these new
parameters. The enum value retrieval has been changed strol(..., NULL, 10)
to stroul(..., NULL, 0), so that we not only are able to use unsigned ints
now but so that we also interprete hex values correctly. The 32bit limit
gets imposed on all entries not marked reserved, an unused "user_data" field
that appeared in a lot of cmos.layouts has been changed to reserved as well.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4332 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-06-03 12:47:19 +02:00
|
|
|
} while(ch && (is_ident_nondigit(ch) || isdigit(ch)));
|
2004-03-11 16:01:31 +01:00
|
|
|
result = (ch == '\0');
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-04-22 21:02:15 +02:00
|
|
|
/* This routine builds the cmos definition table from the cmos layout file
|
|
|
|
input The input comes from the configuration file which contains two parts
|
|
|
|
entries and enumerations. Each section is started with the key words
|
|
|
|
entries and enumerations. Records then follow in their respective
|
|
|
|
formats.
|
|
|
|
output The output of this program is the cmos definitions table. It is stored
|
|
|
|
in the cmos_table array. If this module is called, and the global
|
|
|
|
table_file has been implimented by the user, the table is also written
|
|
|
|
to the specified file.
|
|
|
|
This program exits on and error. It returns a 1 on successful
|
|
|
|
completion
|
|
|
|
*/
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
char *config=0;
|
|
|
|
char *option=0;
|
2004-03-11 16:01:31 +01:00
|
|
|
char *header=0;
|
2003-04-22 21:02:15 +02:00
|
|
|
FILE *fp;
|
2008-11-30 15:52:46 +01:00
|
|
|
int tmpfile;
|
2008-12-02 13:26:17 +01:00
|
|
|
char tmpfilename[TMPFILE_LEN];
|
2003-04-22 21:02:15 +02:00
|
|
|
struct cmos_option_table *ct;
|
|
|
|
struct cmos_entries *ce;
|
|
|
|
struct cmos_enums *c_enums, *c_enums_start;
|
|
|
|
struct cmos_checksum *cs;
|
2007-10-24 13:12:15 +02:00
|
|
|
char line[INPUT_LINE_MAX];
|
2003-04-22 21:02:15 +02:00
|
|
|
unsigned char uc;
|
|
|
|
int entry_mode=0;
|
|
|
|
int enum_mode=0;
|
|
|
|
int checksum_mode=0;
|
2003-09-26 11:47:41 +02:00
|
|
|
long ptr;
|
|
|
|
int cnt;
|
2003-04-22 21:02:15 +02:00
|
|
|
char *cptr;
|
2003-10-11 08:20:25 +02:00
|
|
|
void *entry_start, *entry_end;
|
2003-04-22 21:02:15 +02:00
|
|
|
int entries_length;
|
|
|
|
int enum_length;
|
|
|
|
int len;
|
2007-10-24 13:12:15 +02:00
|
|
|
char buf[16];
|
2003-04-22 21:02:15 +02:00
|
|
|
|
|
|
|
for(i=1;i<argc;i++) {
|
|
|
|
if(argv[i][0]!='-') {
|
2008-11-30 15:52:46 +01:00
|
|
|
display_usage(argv[0]);
|
2003-04-22 21:02:15 +02:00
|
|
|
}
|
|
|
|
switch(argv[i][1]) {
|
|
|
|
case '-': /* data is requested from a file */
|
|
|
|
switch(argv[i][2]) {
|
|
|
|
case 'c': /* use a configuration file */
|
|
|
|
if(strcmp(&argv[i][2],"config")) {
|
2008-11-30 15:52:46 +01:00
|
|
|
display_usage(argv[0]);
|
2003-04-22 21:02:15 +02:00
|
|
|
}
|
|
|
|
config=argv[++i];
|
|
|
|
break;
|
|
|
|
case 'o': /* use a cmos definitions table file */
|
|
|
|
if(strcmp(&argv[i][2],"option")) {
|
2008-11-30 15:52:46 +01:00
|
|
|
display_usage(argv[0]);
|
2003-04-22 21:02:15 +02:00
|
|
|
}
|
|
|
|
option=argv[++i];
|
|
|
|
break;
|
2004-03-11 16:01:31 +01:00
|
|
|
case 'h': /* Output a header file */
|
|
|
|
if (strcmp(&argv[i][2], "header") != 0) {
|
2008-11-30 15:52:46 +01:00
|
|
|
display_usage(argv[0]);
|
2004-03-11 16:01:31 +01:00
|
|
|
}
|
|
|
|
header=argv[++i];
|
|
|
|
break;
|
2003-04-22 21:02:15 +02:00
|
|
|
default:
|
2008-11-30 15:52:46 +01:00
|
|
|
display_usage(argv[0]);
|
2003-04-22 21:02:15 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2004-03-11 16:01:31 +01:00
|
|
|
|
2003-04-22 21:02:15 +02:00
|
|
|
default:
|
2008-11-30 15:52:46 +01:00
|
|
|
display_usage(argv[0]);
|
2003-04-22 21:02:15 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Has the user specified a configuration file */
|
|
|
|
if(config) { /* if yes, open it */
|
|
|
|
if((fp=fopen(config,"r"))==NULL){
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - Can not open config file %s\n",config);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1); /* exit if it can not be opened */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else { /* no configuration file specified, so try the default */
|
|
|
|
if((fp=fopen("cmos.layout","r"))==NULL){
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - Can not open cmos.layout\n");
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1); /* end of no configuration file is found */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* type cast a pointer, so we can us the structure */
|
|
|
|
ct=(struct cmos_option_table*)cmos_table;
|
|
|
|
/* start the table with the type signature */
|
|
|
|
ct->tag = LB_TAG_CMOS_OPTION_TABLE;
|
|
|
|
/* put in the header length */
|
|
|
|
ct->header_length=sizeof(*ct);
|
|
|
|
|
|
|
|
/* Get the entry records */
|
|
|
|
ce=(struct cmos_entries*)(cmos_table+(ct->header_length));
|
|
|
|
cptr = (char*)ce;
|
|
|
|
for(;;){ /* this section loops through the entry records */
|
|
|
|
if(fgets(line,INPUT_LINE_MAX,fp)==NULL)
|
|
|
|
break; /* end if no more input */
|
|
|
|
if(!entry_mode) { /* skip input until the entries key word */
|
|
|
|
if (strstr(line,"entries") != 0) {
|
|
|
|
entry_mode=1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{ /* Test if we are done with entries and starting enumerations */
|
|
|
|
if (strstr(line,"enumerations") != 0){
|
|
|
|
entry_mode=0;
|
|
|
|
enum_mode=1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strstr(line, "checksums") != 0) {
|
|
|
|
enum_mode=0;
|
|
|
|
checksum_mode=1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* skip commented and blank lines */
|
|
|
|
if(line[0]=='#') continue;
|
|
|
|
if(line[strspn(line," ")]=='\n') continue;
|
|
|
|
/* scan in the input data */
|
|
|
|
sscanf(line,"%d %d %c %d %s",
|
|
|
|
&ce->bit,&ce->length,&uc,&ce->config_id,&ce->name[0]);
|
|
|
|
ce->config=(int)uc;
|
|
|
|
/* check bit and length ranges */
|
|
|
|
if(ce->bit>(CMOS_IMAGE_BUFFER_SIZE*8)) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - bit is to big in line \n%s\n",line);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if((ce->length>(MAX_VALUE_BYTE_LENGTH*8))&&(uc!='r')) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - Length is to long in line \n%s\n",line);
|
|
|
|
exit(1);
|
|
|
|
}
|
2007-10-24 13:12:15 +02:00
|
|
|
if (!is_ident((char *)ce->name)) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr,
|
|
|
|
"Error - Name %s is an invalid identifier in line\n %s\n",
|
|
|
|
ce->name, line);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
/* put in the record type */
|
|
|
|
ce->tag=LB_TAG_OPTION;
|
|
|
|
/* calculate and save the record length */
|
2007-10-24 13:12:15 +02:00
|
|
|
len=strlen((char *)ce->name)+1;
|
2003-04-22 21:02:15 +02:00
|
|
|
/* make the record int aligned */
|
|
|
|
if(len%4)
|
|
|
|
len+=(4-(len%4));
|
|
|
|
ce->size=sizeof(struct cmos_entries)-32+len;
|
|
|
|
cptr = (char*)ce;
|
2003-10-11 08:20:25 +02:00
|
|
|
cptr += ce->size; /* increment to the next table position */
|
2003-04-22 21:02:15 +02:00
|
|
|
ce = (struct cmos_entries*) cptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* put the length of the entries into the header section */
|
2003-10-11 08:20:25 +02:00
|
|
|
entries_length = (cptr - (char *)&cmos_table) - ct->header_length;
|
2003-04-22 21:02:15 +02:00
|
|
|
|
|
|
|
/* compute the start of the enumerations section */
|
2003-10-11 08:20:25 +02:00
|
|
|
entry_start = ((char*)&cmos_table) + ct->header_length;
|
|
|
|
entry_end = ((char *)entry_start) + entries_length;
|
|
|
|
c_enums_start = c_enums = (struct cmos_enums*)entry_end;
|
2003-04-22 21:02:15 +02:00
|
|
|
/* test for overlaps in the entry records */
|
2003-10-11 08:20:25 +02:00
|
|
|
test_for_entry_overlaps(entry_start, entry_end);
|
2003-04-22 21:02:15 +02:00
|
|
|
|
|
|
|
for(;enum_mode;){ /* loop to build the enumerations section */
|
|
|
|
if(fgets(line,INPUT_LINE_MAX,fp)==NULL)
|
|
|
|
break; /* go till end of input */
|
|
|
|
|
|
|
|
if (strstr(line, "checksums") != 0) {
|
|
|
|
enum_mode=0;
|
|
|
|
checksum_mode=1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* skip commented and blank lines */
|
|
|
|
if(line[0]=='#') continue;
|
|
|
|
if(line[strspn(line," ")]=='\n') continue;
|
|
|
|
|
|
|
|
/* scan in the data */
|
|
|
|
for(ptr=0;(line[ptr]==' ')||(line[ptr]=='\t');ptr++);
|
|
|
|
c_enums->config_id=strtol(&line[ptr],(char**)NULL,10);
|
|
|
|
for(;(line[ptr]!=' ')&&(line[ptr]!='\t');ptr++);
|
|
|
|
for(;(line[ptr]==' ')||(line[ptr]=='\t');ptr++);
|
CMOS: Add set_option and rework get_option.
To ease some of my debugging pain on the unichrome, i decided i needed to
move FB size selection into cmos, so i could test a size and then reset it
to the default after loading this value so that the next reboot uses the
(working) default again. This meant implementing set_option in parallel to
get_option.
get_option was then found to have inversed argument ordering (like outb) and
passing char * and then depending on the cmos layout length, which made me
feel quite uncomfortable. Since we either have reserved space (which we
shouldn't do anything with in these two functions), an enum or a
hexadecimal value, unsigned int seemed like the way to go. So all users of
get_option now have their arguments inversed and switched from using ints
to unsigned ints now.
The way get_cmos_value was implemented forced us to not overlap byte and to
have multibyte values be byte aligned. This logic is now adapted to do a
full uint32_t read (when needed) at any offset and any length up to 32, and
the shifting all happens inside an uint32_t as well. set_cmos_value was
implemented similarly. Both routines have been extensively tested in a
quick separate little program as it is not easy to get this stuff right.
build_opt_tbl.c was altered to function correctly within these new
parameters. The enum value retrieval has been changed strol(..., NULL, 10)
to stroul(..., NULL, 0), so that we not only are able to use unsigned ints
now but so that we also interprete hex values correctly. The 32bit limit
gets imposed on all entries not marked reserved, an unused "user_data" field
that appeared in a lot of cmos.layouts has been changed to reserved as well.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4332 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-06-03 12:47:19 +02:00
|
|
|
c_enums->value = strtoul(&line[ptr],(char**)NULL,0);
|
2003-04-22 21:02:15 +02:00
|
|
|
for(;(line[ptr]!=' ')&&(line[ptr]!='\t');ptr++);
|
|
|
|
for(;(line[ptr]==' ')||(line[ptr]=='\t');ptr++);
|
|
|
|
for(cnt=0;(line[ptr]!='\n')&&(cnt<31);ptr++,cnt++)
|
|
|
|
c_enums->text[cnt]=line[ptr];
|
|
|
|
c_enums->text[cnt]=0;
|
|
|
|
|
|
|
|
/* make the record int aligned */
|
|
|
|
cnt++;
|
|
|
|
if(cnt%4)
|
|
|
|
cnt+=4-(cnt%4);
|
|
|
|
/* store the record length */
|
2003-10-11 08:20:25 +02:00
|
|
|
c_enums->size=((char *)&c_enums->text[cnt]) - (char *)c_enums;
|
2003-04-22 21:02:15 +02:00
|
|
|
/* store the record type */
|
|
|
|
c_enums->tag=LB_TAG_OPTION_ENUM;
|
|
|
|
/* increment to the next record */
|
|
|
|
c_enums=(struct cmos_enums*)&c_enums->text[cnt];
|
|
|
|
}
|
|
|
|
/* save the enumerations length */
|
2003-10-11 08:20:25 +02:00
|
|
|
enum_length= (char *)c_enums - (char *)c_enums_start;
|
2003-04-22 21:02:15 +02:00
|
|
|
ct->size=ct->header_length+enum_length+entries_length;
|
|
|
|
|
|
|
|
/* Get the checksum records */
|
|
|
|
cs=(struct cmos_checksum *)(cmos_table+(ct->size));
|
|
|
|
cptr = (char*)cs;
|
|
|
|
for(;checksum_mode;) { /* This section finds the checksums */
|
|
|
|
char *ptr;
|
|
|
|
if(fgets(line, INPUT_LINE_MAX,fp)==NULL)
|
|
|
|
break; /* end if no more input */
|
|
|
|
|
|
|
|
/* skip commented and blank lines */
|
|
|
|
if (line[0]=='#') continue;
|
|
|
|
if (line[strspn(line, " ")]=='\n') continue;
|
|
|
|
if (memcmp(line, "checksum", 8) != 0) continue;
|
|
|
|
|
|
|
|
/* get the information */
|
|
|
|
ptr = line + 8;
|
|
|
|
skip_spaces(line, &ptr);
|
|
|
|
cs->range_start = get_number(line, &ptr, 10);
|
|
|
|
|
|
|
|
skip_spaces(line, &ptr);
|
|
|
|
cs->range_end = get_number(line, &ptr, 10);
|
|
|
|
|
|
|
|
skip_spaces(line, &ptr);
|
|
|
|
cs->location = get_number(line, &ptr, 10);
|
|
|
|
|
|
|
|
/* Make certain there are spaces until the end of the line */
|
|
|
|
skip_spaces(line, &ptr);
|
|
|
|
|
|
|
|
if ((cs->range_start%8) != 0) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - range start is not byte aligned in line\n%s\n", line);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (cs->range_start >= (CMOS_IMAGE_BUFFER_SIZE*8)) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - range start is to big in line\n%s\n", line);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if ((cs->range_end%8) != 7) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - range end is not byte aligned in line\n%s\n", line);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if ((cs->range_end) >= (CMOS_IMAGE_BUFFER_SIZE*8)) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - range end is to long in line\n%s\n", line);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if ((cs->location%8) != 0) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - location is not byte aligned in line\n%s\n", line);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if ((cs->location >= (CMOS_IMAGE_BUFFER_SIZE*8)) ||
|
|
|
|
((cs->location + 16) > (CMOS_IMAGE_BUFFER_SIZE*8)))
|
|
|
|
{
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - location is to big in line\n%s\n", line);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
/* And since we are not ready to be fully general purpose yet.. */
|
|
|
|
if ((cs->range_start/8) != LB_CKS_RANGE_START) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - Range start(%d) does not match define(%d) in line\n%s\n",
|
2003-04-22 21:02:15 +02:00
|
|
|
cs->range_start/8, LB_CKS_RANGE_START, line);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if ((cs->range_end/8) != LB_CKS_RANGE_END) {
|
2007-04-06 14:14:51 +02:00
|
|
|
fprintf(stderr, "Error - Range end (%d) does not match define (%d) in line\n%s\n",
|
|
|
|
(cs->range_end/8), LB_CKS_RANGE_END, line);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if ((cs->location/8) != LB_CKS_LOC) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Error - Location does not match define in line\n%s\n", line);
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
cs->tag = LB_TAG_OPTION_CHECKSUM;
|
|
|
|
cs->size = sizeof(*cs);
|
|
|
|
cs->type = CHECKSUM_PCBIOS;
|
|
|
|
cptr = (char *)cs;
|
|
|
|
cptr += cs->size;
|
|
|
|
cs = (struct cmos_checksum *)cptr;
|
|
|
|
|
|
|
|
}
|
|
|
|
ct->size += (cptr - (char *)(cmos_table + ct->size));
|
|
|
|
fclose(fp);
|
|
|
|
|
2008-11-30 15:52:46 +01:00
|
|
|
/* See if we want to output a C source file */
|
2003-04-22 21:02:15 +02:00
|
|
|
if(option) {
|
2009-05-01 00:45:41 +02:00
|
|
|
int err=0;
|
2008-12-02 13:26:17 +01:00
|
|
|
strncpy(tmpfilename, dirname(option), TMPFILE_LEN);
|
|
|
|
strncat(tmpfilename, TMPFILE_TEMPLATE, TMPFILE_LEN);
|
2008-11-30 15:52:46 +01:00
|
|
|
tmpfile = mkstemp(tmpfilename);
|
|
|
|
if(tmpfile == -1) {
|
|
|
|
perror("Error - Could not create temporary file");
|
2003-04-22 21:02:15 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
2008-11-30 15:52:46 +01:00
|
|
|
|
|
|
|
if((fp=fdopen(tmpfile,"w"))==NULL){
|
|
|
|
perror("Error - Could not open temporary file");
|
|
|
|
unlink(tmpfilename);
|
|
|
|
exit(1);
|
2003-04-22 21:02:15 +02:00
|
|
|
}
|
|
|
|
|
2008-11-30 15:52:46 +01:00
|
|
|
/* write the header */
|
|
|
|
if(!fwrite("unsigned char option_table[] = {",1,32,fp)) {
|
|
|
|
perror("Error - Could not write image file");
|
|
|
|
fclose(fp);
|
|
|
|
unlink(tmpfilename);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
/* write the array values */
|
|
|
|
for(i=0;i<(ct->size-1);i++) {
|
I would have liked to get an ack, but the error this corrects is pretty
critical, since unless it is fixed this tool creates empty tables that cause
coreboot to (in some cases, e.g. on qemu) triple fault and die.
For the record, an empty option_table is not allowed. The table must,
at least, have 3 32-bit entries in this order:
type -- should be 200, 0r 0xc8, i.e. 0xc8, 0, 0, 0
size of table in LE order, 4 bytes
size of header in LE order, which is always 12,0,0,0
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4264 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-05-09 19:14:58 +02:00
|
|
|
if(!(i%10) && !err) err=!fwrite("\n\t",1,2,fp);
|
2008-11-30 15:52:46 +01:00
|
|
|
sprintf(buf,"0x%02x,",cmos_table[i]);
|
I would have liked to get an ack, but the error this corrects is pretty
critical, since unless it is fixed this tool creates empty tables that cause
coreboot to (in some cases, e.g. on qemu) triple fault and die.
For the record, an empty option_table is not allowed. The table must,
at least, have 3 32-bit entries in this order:
type -- should be 200, 0r 0xc8, i.e. 0xc8, 0, 0, 0
size of table in LE order, 4 bytes
size of header in LE order, which is always 12,0,0,0
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4264 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-05-09 19:14:58 +02:00
|
|
|
if(!err) err=!fwrite(buf,1,5,fp);
|
2008-11-30 15:52:46 +01:00
|
|
|
}
|
|
|
|
/* write the end */
|
|
|
|
sprintf(buf,"0x%02x\n",cmos_table[i]);
|
I would have liked to get an ack, but the error this corrects is pretty
critical, since unless it is fixed this tool creates empty tables that cause
coreboot to (in some cases, e.g. on qemu) triple fault and die.
For the record, an empty option_table is not allowed. The table must,
at least, have 3 32-bit entries in this order:
type -- should be 200, 0r 0xc8, i.e. 0xc8, 0, 0, 0
size of table in LE order, 4 bytes
size of header in LE order, which is always 12,0,0,0
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4264 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-05-09 19:14:58 +02:00
|
|
|
if(!err) err=!fwrite(buf,1,4,fp);
|
2008-11-30 15:52:46 +01:00
|
|
|
if(!fwrite("};\n",1,3,fp)) {
|
|
|
|
perror("Error - Could not write image file");
|
|
|
|
fclose(fp);
|
|
|
|
unlink(tmpfilename);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
if (rename(tmpfilename, option)) {
|
|
|
|
fprintf(stderr, "Error - Could not write %s: ", option);
|
|
|
|
perror(NULL);
|
|
|
|
unlink(tmpfilename);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
2004-03-11 16:01:31 +01:00
|
|
|
|
|
|
|
/* See if we also want to output a C header file */
|
|
|
|
if (header) {
|
|
|
|
struct cmos_option_table *hdr;
|
|
|
|
struct lb_record *ptr, *end;
|
2008-11-30 15:52:46 +01:00
|
|
|
|
2008-12-02 13:26:17 +01:00
|
|
|
strncpy(tmpfilename, dirname(option), TMPFILE_LEN);
|
|
|
|
strncat(tmpfilename, TMPFILE_TEMPLATE, TMPFILE_LEN);
|
2008-11-30 15:52:46 +01:00
|
|
|
tmpfile = mkstemp(tmpfilename);
|
|
|
|
if(tmpfile == -1) {
|
|
|
|
perror("Error - Could not create temporary file");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fp = fdopen(tmpfile, "w");
|
2004-03-11 16:01:31 +01:00
|
|
|
if (!fp) {
|
2008-11-30 15:52:46 +01:00
|
|
|
perror("Error - Could not open temporary file");
|
|
|
|
unlink(tmpfilename);
|
2004-03-11 16:01:31 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
2008-11-30 15:52:46 +01:00
|
|
|
|
2004-03-11 16:01:31 +01:00
|
|
|
/* Get the cmos table header */
|
|
|
|
hdr = (struct cmos_option_table *)cmos_table;
|
|
|
|
/* Walk through the entry records */
|
|
|
|
ptr = (struct lb_record *)(cmos_table + hdr->header_length);
|
|
|
|
end = (struct lb_record *)(cmos_table + hdr->size);
|
|
|
|
for(;ptr < end; ptr = (struct lb_record *)(((char *)ptr) + ptr->size)) {
|
|
|
|
if (ptr->tag != LB_TAG_OPTION) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ce = (struct cmos_entries *)ptr;
|
2009-04-22 11:03:08 +02:00
|
|
|
|
2007-10-24 13:12:15 +02:00
|
|
|
if (!is_ident((char *)ce->name)) {
|
2004-03-11 16:01:31 +01:00
|
|
|
fprintf(stderr, "Invalid identifier: %s\n",
|
|
|
|
ce->name);
|
2008-11-30 15:52:46 +01:00
|
|
|
fclose(fp);
|
|
|
|
unlink(tmpfilename);
|
2004-03-11 16:01:31 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
fprintf(fp, "#define CMOS_VSTART_%s %d\n",
|
|
|
|
ce->name, ce->bit);
|
|
|
|
fprintf(fp, "#define CMOS_VLEN_%s %d\n",
|
|
|
|
ce->name, ce->length);
|
|
|
|
}
|
|
|
|
fclose(fp);
|
2008-11-30 15:52:46 +01:00
|
|
|
|
|
|
|
if (rename(tmpfilename, header)) {
|
|
|
|
fprintf(stderr, "Error - Could not write %s: ", header);
|
|
|
|
perror(NULL);
|
|
|
|
unlink(tmpfilename);
|
|
|
|
exit(1);
|
|
|
|
}
|
2004-03-11 16:01:31 +01:00
|
|
|
}
|
2003-04-22 21:02:15 +02:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|