diff options
author | Noe Rubinstein <nrubinstein@avencall.com> | 2012-10-19 18:24:15 +0200 |
---|---|---|
committer | Noe Rubinstein <nrubinstein@avencall.com> | 2012-10-19 18:24:15 +0200 |
commit | 0900b73cfa02a55311c02a8e210871f33d62b28e (patch) | |
tree | 0df976c2ff0343d1d05bafae6f37f7eaa216193a /build_rom.c | |
parent | c4481f8d920fc9b42ad501221e9567ad59398228 (diff) |
add option to reflash the same data
Diffstat (limited to 'build_rom.c')
-rw-r--r-- | build_rom.c | 132 |
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; } |