summaryrefslogtreecommitdiff
path: root/build_rom.c
diff options
context:
space:
mode:
authorNoe Rubinstein <nrubinstein@avencall.com>2012-10-19 18:24:15 +0200
committerNoe Rubinstein <nrubinstein@avencall.com>2012-10-19 18:24:15 +0200
commit0900b73cfa02a55311c02a8e210871f33d62b28e (patch)
tree0df976c2ff0343d1d05bafae6f37f7eaa216193a /build_rom.c
parentc4481f8d920fc9b42ad501221e9567ad59398228 (diff)
add option to reflash the same data
Diffstat (limited to 'build_rom.c')
-rw-r--r--build_rom.c132
1 files changed, 101 insertions, 31 deletions
diff --git a/build_rom.c b/build_rom.c
index 6ed43b5..c898af7 100644
--- a/build_rom.c
+++ b/build_rom.c
@@ -58,11 +58,12 @@ void choose_macs(mac from, mac to, struct xioh_data *xioh_data);
void print_mac_le(FILE* h, mac mac);
void print_mac_be(FILE* h, mac mac);
void reverse(uint8_t *t, int n);
-void write_serial(struct serial *serial);
-void dump_xioh_data(struct xioh_data *xioh_data);
-void write_xioh_data(const char *fname, struct xioh_data *xioh_data);
-void write_standalone(const char *fname, struct xioh_data *xioh_data);
+void write_serial(struct serial *serial, int serial_number);
+void dump_xioh_data(const struct xioh_data *xioh_data);
+void write_xioh_data(const char *fname, const struct xioh_data *xioh_data);
+void write_standalone(const char *fname, const struct xioh_data *xioh_data);
uint8_t cksum(const uint8_t* addr, size_t sz);
+const struct xioh_data* get_xioh_data(char *fname, int serial);
int rand_range(int max) { return (int)(rand()/(double)RAND_MAX*max); }
unsigned date(void) { return time(NULL) / 86400; }
@@ -89,23 +90,27 @@ static void print_usage(char *name)
"\t-f MAC\tUse random MAC addresses (start of range)\n"
"\t-t MAC\tUse random MAC addresses (end of range)\n"
"\t-n NUM\tUse this number for the serial\n"
+ "\t-r NUM\tInstead of building a new ROM, reflash the one with this number\n"
, name);
}
int main(int argc, char *argv[])
{
- int i;
struct xioh_data xioh_data;
+ const struct xioh_data *xioh_data_p = &xioh_data;
+
+ int i;
char *fname = "coreboot.rom";
char *standalone = NULL;
mac from, to;
bool hasfrom = false, hasto = false;
- enum { MODE_UNSET, RANDOM, CONTINUOUS } mode = MODE_UNSET;
+ int serial_number = -1;
+ enum { MODE_UNSET, RANDOM, CONTINUOUS, REFLASH } mode = MODE_UNSET;
srand(time(NULL)+getpid());
while (true) {
- int c = getopt(argc, argv, "s:m:f:t:n:c:d:S:");
+ int c = getopt(argc, argv, "s:m:f:t:n:c:d:S:r:");
if (c == -1) break;
@@ -136,16 +141,17 @@ int main(int argc, char *argv[])
hasto = true;
parse_mac(optarg, &to);
break;
+ case 'r':
+ mode = REFLASH;
+ /* intentional fallthrough */
case 'n':
{
char *endptr;
- int next = strtol(optarg, &endptr, 0);
- if (!*optarg || *endptr || next < 0) {
- fprintf(stderr, "-n requires a positive number\n");
+ serial_number = strtol(optarg, &endptr, 0);
+ if (!*optarg || *endptr || serial_number < 0) {
+ fprintf(stderr, "-%c requires a positive number\n", c);
exit(1);
}
-
- set_next_serial(next);
}
break;
default:
@@ -167,30 +173,37 @@ int main(int argc, char *argv[])
}
choose_macs(from, to, &xioh_data);
break;
+ case REFLASH:
+ xioh_data_p = get_xioh_data(db, serial_number);
+ break;
case MODE_UNSET:
print_usage(argv[0]);
exit(1);
}
- memcpy(xioh_data.magic, xioh_data_magic, sizeof(xioh_data.magic));
- xioh_data.version = XIOH_DATA_VERSION;
- write_serial(&xioh_data.serial);
+ if (mode != REFLASH) {
+ memcpy(xioh_data.magic, xioh_data_magic, sizeof(xioh_data.magic));
+ xioh_data.version = XIOH_DATA_VERSION;
+ write_serial(&xioh_data.serial, serial_number);
- for (i = 0; i < MAC_NUM; i++)
- reverse(xioh_data.addr[i].b, 6);
+ for (i = 0; i < MAC_NUM; i++)
+ reverse(xioh_data.addr[i].b, 6);
+
+ xioh_data.reserved = 0;
+ xioh_data.cksum = 0;
+ xioh_data.cksum = cksum((uint8_t*)&xioh_data, sizeof(xioh_data));
- xioh_data.reserved = 0;
- xioh_data.cksum = 0;
- xioh_data.cksum = cksum((uint8_t*)&xioh_data, sizeof(xioh_data));
+ }
- dump_xioh_data(&xioh_data);
+ dump_xioh_data(xioh_data_p);
if (standalone)
- write_standalone(standalone, &xioh_data);
+ write_standalone(standalone, xioh_data_p);
else
- write_xioh_data(fname, &xioh_data);
+ write_xioh_data(fname, xioh_data_p);
- record_use(db, &xioh_data);
+ if (mode != REFLASH)
+ record_use(db, &xioh_data);
return 0;
}
@@ -203,7 +216,7 @@ uint8_t cksum(const uint8_t* addr, size_t sz)
return r;
}
-void write_standalone(const char *fname, struct xioh_data *xioh_data)
+void write_standalone(const char *fname, const struct xioh_data *xioh_data)
{
FILE *f = fopen(fname, "w");
if (!f) {
@@ -215,7 +228,7 @@ void write_standalone(const char *fname, struct xioh_data *xioh_data)
fclose(f);
}
-void write_xioh_data(const char *fname, struct xioh_data *xioh_data)
+void write_xioh_data(const char *fname, const struct xioh_data *xioh_data)
{
FILE *rom = fopen(fname, "r+");
if (!rom) {
@@ -232,7 +245,7 @@ void write_xioh_data(const char *fname, struct xioh_data *xioh_data)
fclose(rom);
}
-void dump_xioh_data(struct xioh_data *xioh_data)
+void dump_xioh_data(const struct xioh_data *xioh_data)
{
int i;
time_t time = xioh_data->serial.date * 86400;
@@ -276,11 +289,18 @@ retry: xioh_data->addr[i] = mac_between(from, to);
}
}
-void write_serial(struct serial *serial)
+void write_serial(struct serial *serial, int serial_number)
{
serial->date = date();
serial->version = XIOH_HARDWARE_VERSION;
- serial->number = get_next_serial();
+ if (serial_number < 0) {
+ serial->number = get_next_serial();
+ } else if (serial_used(db, serial_number)) {
+ fprintf(stderr, "Serial number %d already used!\n", serial_number);
+ exit(2);
+ } else {
+ serial->number = serial_number;
+ }
}
void set_next_serial(unsigned serial)
@@ -303,14 +323,65 @@ unsigned get_next_serial(void)
fclose(f);
}
- while (serial_used(db, cur))
+ while (serial_used(db, cur)) {
+ fprintf(stderr, "Serial number %d already used! Trying %d.\n", cur, cur+1);
cur++;
+ }
set_next_serial(cur+1);
return cur;
}
+const struct xioh_data* get_xioh_data(char *fname, int serial) {
+ sqlite3 *db;
+ sqlite3_stmt *stmt;
+ int rc;
+ const struct xioh_data* res = NULL;
+
+ rc = sqlite3_open(fname, &db);
+ if (SQLITE_OK != rc) {
+ fprintf(stderr, "could not open sqlite database \"%s\" "
+ "(error %d)\n", fname, rc);
+ sqlite3_close(db);
+ goto opened;
+ }
+
+ rc = sqlite3_prepare_v2(db, "SELECT xioh_data FROM xioh_data "
+ "WHERE serial_number == ?", -1, &stmt, NULL);
+ if (SQLITE_OK != rc) {
+ fprintf(stderr, "could not compile statement (error %d)\n", rc);
+ sqlite3_close(db);
+ goto prepared;
+ }
+
+ sqlite3_bind_int(stmt, 1, serial);
+
+ rc = sqlite3_step(stmt);
+
+ switch (rc) {
+ case SQLITE_ROW:
+ res = sqlite3_column_blob(stmt, 0);
+ break;
+ case SQLITE_DONE:
+ fprintf(stderr, "No data for serial number %d\n", serial);
+ break;
+ default:
+ fprintf(stderr, "could not execute statement (error %d)\n", rc);
+ break;
+ }
+
+prepared: \
+ sqlite3_finalize(stmt); \
+opened: \
+ sqlite3_close(db); \
+
+ if (res)
+ return res;
+ else
+ exit(1);
+}
+
#ifndef OLD_DB_FORMAT
# define TEST_IN_SQLITE3(cond, bind) \
sqlite3 *db; \
@@ -410,7 +481,6 @@ bool serial_used(const char *fname, int serial)
while (0 < fread(&xioh_data, sizeof(xioh_data), 1, f)) {
if (xioh_data.serial.number == serial) {
- fprintf(stderr, "Serial number %d already used! Trying %d.\n", serial, serial+1);
fclose(f);
return true;
}