meta-facebook/meta-galaxy100/recipes-utils/mkeeprom/files/mkeeprom.c (283 lines of code) (raw):
/*
* Copyright 2014-present Facebook. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include <fcntl.h>
#include <inttypes.h>
#include <getopt.h>
#include "mkeeprom.h"
struct wedge_eeprom_st *eeprom;
bool set_fbw_local_mac = 0;
void dump_eeprom(struct wedge_eeprom_st *eeprom) {
printf("dump_eeprom\n");
printf("eeprom->fbw_product_name = 0x%x\n",eeprom->fbw_magic);
printf("eeprom->fbw_version = 0x%x\n",eeprom->fbw_version);
printf("eeprom->fbw_product_name = %s\n",eeprom->fbw_product_name);
printf("eeprom->fbw_product_number = %s\n",eeprom->fbw_product_number);
printf("eeprom->fbw_assembly_number = %s\n",eeprom->fbw_assembly_number);
printf("eeprom->fbw_facebook_pcba_number = %s\n",eeprom->fbw_facebook_pcba_number);
printf("eeprom->fbw_facebook_pcb_number = %s\n",eeprom->fbw_facebook_pcb_number);
printf("eeprom->fbw_odm_pcb_number = %s\n",eeprom->fbw_odm_pcb_number);
printf("eeprom->fbw_odm_pcb_serial = %s\n",eeprom->fbw_odm_pcb_serial);
printf("eeprom->fbw_production_state = 0%x\n",eeprom->fbw_production_state);
printf("eeprom->fbw_product_version = 0x%x\n",eeprom->fbw_product_version);
printf("eeprom->fbw_product_subversion = 0x%x\n",eeprom->fbw_product_subversion);
printf("eeprom->fbw_product_serial = %s\n",eeprom->fbw_product_serial);
printf("eeprom->fbw_product_asset = %s\n",eeprom->fbw_product_asset);
printf("eeprom->fbw_system_manufacturer = %s\n",eeprom->fbw_system_manufacturer);
//printf("eeprom->fbw_system_manufacturing_date = 0x%x\n",eeprom->fbw_system_manufacturing_date);
printf("eeprom->fbw_system_manufacturing_date = %d-%d-%d\n",eeprom->fbw_system_manufacturing_year,eeprom->fbw_system_manufacturing_month,eeprom->fbw_system_manufacturing_day);
printf("eeprom->fbw_pcb_manufacturer = %s\n",eeprom->fbw_pcb_manufacturer);
printf("eeprom->fbw_assembled = %s\n",eeprom->fbw_assembled);
printf("eeprom->fbw_local_mac = %s\n",eeprom->fbw_local_mac);
printf("eeprom->fbw_mac_base = %s\n",eeprom->fbw_mac_base);
printf("eeprom->fbw_mac_size = 0x%x\n",eeprom->fbw_mac_size);
printf("eeprom->fbw_location = %s\n",eeprom->fbw_location);
}
void remove_all_chars(char* str, char c) {
char *pr = str, *pw = str;
while (*pr) {
*pw = *pr++;
pw += (*pw != c);
}
*pw = '\0';
}
void parse_command(char* cmd, char* c) {
char temp[100];
printf("cmd = %s,c=%s\n",cmd,c);
memset(temp,0,sizeof(temp));
if (strcmp(cmd, "magic_word")==0) {
sscanf(c, "%s %hx",cmd, &eeprom->fbw_magic);
printf("eeprom->fbw_product_name = 0x%x\n",eeprom->fbw_magic);
}
if (strcmp(cmd, "format_version")==0) {
//fbw_version
sscanf(c, "%s %hhu",cmd, &eeprom->fbw_version);
printf("eeprom->fbw_version = 0x%x\n",eeprom->fbw_version);
}
if (strcmp(cmd, "product_name")==0) {
sscanf(c, "%s %s",cmd, eeprom->fbw_product_name);
printf("eeprom->fbw_product_name = %s\n",eeprom->fbw_product_name);
}
if (strcmp(cmd, "product_number")==0) {
//sscanf(c, "%s \"%9[^-"]\"",cmd, eeprom->fbw_product_number);
sscanf(c, "%s %s", cmd, temp);
/* Product Part #: 8 byte data shown as XX-XXXXXXX */
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_product_number,temp,FBW_EEPROM_F_PRODUCT_NUMBER);
printf("eeprom->fbw_product_number = %s\n",eeprom->fbw_product_number);
}
if (strcmp(cmd, "assembly_number")==0) {
sscanf(c, "%s %s", cmd, temp);
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_assembly_number,temp,FBW_EEPROM_F_ASSEMBLY_NUMBER);
printf("eeprom->fbw_assembly_number = %s\n",eeprom->fbw_assembly_number);
}
if (strcmp(cmd, "pcba_number")==0) {
sscanf(c, "%s %s", cmd, temp);
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_facebook_pcba_number,temp,FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER);
printf("eeprom->fbw_facebook_pcba_number = %s\n",eeprom->fbw_facebook_pcba_number);
}
if (strcmp(cmd, "pcb_number")==0) {
sscanf(c, "%s %s", cmd, temp);
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_facebook_pcb_number,temp,FBW_EEPROM_F_FACEBOOK_PCB_NUMBER);
printf("eeprom->fbw_facebook_pcb_number = %s\n",eeprom->fbw_facebook_pcb_number);
}
if (strcmp(cmd, "odm_pcb_number")==0) {
sscanf(c, "%s %s", cmd, temp);
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_odm_pcb_number,temp,FBW_EEPROM_F_ODM_PCB_NUMBER);
printf("eeprom->fbw_odm_pcb_number = %s\n",eeprom->fbw_odm_pcb_number);
}
if (strcmp(cmd, "odm_pcb_serial")==0) {
sscanf(c, "%s %s", cmd, temp);
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_odm_pcb_serial,temp,FBW_EEPROM_F_ODM_PCB_SERIAL);
printf("eeprom->fbw_odm_pcb_serial = %s\n",eeprom->fbw_odm_pcb_serial);
}
if (strcmp(cmd, "production_state")==0) {
sscanf(c, "%s %hhu",cmd, &eeprom->fbw_production_state);
printf("eeprom->fbw_production_state = 0%x\n",eeprom->fbw_production_state);
}
if (strcmp(cmd, "product_version")==0) {
sscanf(c, "%s %hhu",cmd, &eeprom->fbw_product_version);
printf("eeprom->fbw_product_version = 0x%x\n",eeprom->fbw_product_version);
}
if (strcmp(cmd, "product_subversion")==0) {
sscanf(c, "%s %hhu",cmd, &eeprom->fbw_product_subversion);
printf("eeprom->fbw_product_subversion = 0x%x\n",eeprom->fbw_product_subversion);
}
if (strcmp(cmd, "product_serial_number")==0) {
sscanf(c, "%s %s", cmd, temp);
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_product_serial,temp,FBW_EEPROM_F_PRODUCT_SERIAL);
printf("eeprom->fbw_product_serial = %s\n",eeprom->fbw_product_serial);
}
if (strcmp(cmd, "product_asset_tag")==0) {
sscanf(c, "%s %s", cmd, temp);
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_product_asset,temp,FBW_EEPROM_F_PRODUCT_ASSET);
printf("eeprom->fbw_product_asset = %s\n",eeprom->fbw_product_asset);
}
if (strcmp(cmd, "system_manufacturer")==0) {
sscanf(c, "%s %s",cmd, eeprom->fbw_system_manufacturer);
printf("eeprom->fbw_system_manufacturer = %s\n",eeprom->fbw_system_manufacturer);
}
if (strcmp(cmd, "system_manufacturing_date")==0) {
sscanf(c, "%s %d-%d-%d",cmd, &eeprom->fbw_system_manufacturing_year,&eeprom->fbw_system_manufacturing_month,&eeprom->fbw_system_manufacturing_day);
printf("eeprom->fbw_system_manufacturing_date = %d-%d-%d\n",eeprom->fbw_system_manufacturing_year,eeprom->fbw_system_manufacturing_month,eeprom->fbw_system_manufacturing_day);
}
if (strcmp(cmd, "pcb_manufacturer")==0) {
sscanf(c, "%s %s",cmd, eeprom->fbw_pcb_manufacturer);
printf("eeprom->fbw_pcb_manufacturer = %s\n",eeprom->fbw_pcb_manufacturer);
}
if (strcmp(cmd, "assembled_location")==0) {
sscanf(c, "%s %s",cmd, eeprom->fbw_assembled);
printf("eeprom->fbw_assembled = %s\n",eeprom->fbw_assembled);
}
if ((strcmp(cmd, "local_mac_address")==0) && (set_fbw_local_mac != 1)){
sscanf(c, "%s %s", cmd, temp);
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_local_mac,temp,FBW_EEPROM_F_LOCAL_MAC);
printf("eeprom->fbw_local_mac = %s\n",eeprom->fbw_local_mac);
}
if (strcmp(cmd, "extended_mac_base")==0) {
sscanf(c, "%s %s", cmd, temp);
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_mac_base,temp,FBW_EEPROM_F_EXT_MAC_BASE);
printf("eeprom->fbw_mac_base = %s\n",eeprom->fbw_mac_base);
}
if (strcmp(cmd, "extended_mac_size")==0) {
sscanf(c, "%s %d",cmd, &eeprom->fbw_mac_size);
printf("eeprom->fbw_mac_size = 0x%x\n",eeprom->fbw_mac_size);
}
if (strcmp(cmd, "location_on_fabric")==0) {
sscanf(c, "%s %s",cmd, eeprom->fbw_location);
printf("eeprom->fbw_location = %s\n",eeprom->fbw_location);
}
}
int read_text(char* in) {
FILE * fp;
char * line = NULL;
char * c = NULL;
size_t len = 0;
ssize_t read;
char *comment = NULL;
int atomct = 2;
int linect = 0;
char * command = (char*) malloc (101);
int i;
printf("Opening file %s for read\n", in);
fp = fopen(in, "r");
if (fp == NULL) {
printf("Error opening input file\n");
return -1;
}
while ((read = getline(&line, &len, fp)) != -1) {
linect++;
c = line;
for (i=0; i<read; i++) if (c[i]=='#') c[i]='\0';
while (isspace(*c)) ++c;
if (*c=='\0' || *c=='\n' || *c=='\r') {
//empty line, do nothing
} else if (isalnum (*c)) {
sscanf(c, "%100s", command);
#ifdef DEBUG
printf("Processing line %u: %s", linect, c);
if ((*(c+strlen(c)-1))!='\n') printf("\n");
#endif
parse_command(command, c);
} else printf("Can't parse line %u: %s", linect, c);
}
printf("Done reading\n");
#if 1 //def DEBUG
printf("Done reading to dump_eeprom\n");
dump_eeprom(eeprom);
#endif
return 0;
}
/*
* The eeprom size is 8K, we only use 157 bytes for v1 format.
* Read 256 for now.
*/
#define FBW_EEPROM_SIZE 256
int write_binary(char* out) {
FILE *fp;
int i, offset;
short crc;
unsigned char *pack;
uint8_t raw[FBW_EEPROM_SIZE];
fp=fopen(out, "wb");
if (!fp) {
printf("Error writing file %s\n", out);
return -1;
}
//fwrite(&header, sizeof(header), 1, fp);
offset = 0;
//fwrite(eeprom, sizeof(struct wedge_eeprom_st), 1, fp);
//fwrite(eeprom, FBW_EEPROM_SIZE, 1, fp);
memset(raw,0xff,FBW_EEPROM_SIZE);
memcpy(raw,eeprom,sizeof(struct wedge_eeprom_st));
//dump_eeprom(eeprom);
#ifdef DEBUG
offset = 0;
if (offset % 16 != 0) {
printf("\n%08X :", (offset/16)*16);
for (i = 0; i < (offset % 16); i++) {
printf(" ");
}
}
for(i = 0; i < FBW_EEPROM_SIZE; i++)
{
if ((offset + i) % 16 == 0) {
printf("\n%08X :", offset + i);
}
printf(" %02X", raw[i]);
}
printf("\n");
#endif
fwrite(raw, FBW_EEPROM_SIZE, 1, fp);
fflush(fp);
fclose(fp);
return 0;
}
int main(int argc, char **argv) {
char *infile, *outfile;
char temp[100];
/* supported cmdline options */
int c, length, max_size, result;
char options[] = "efghvri:lm:ws:c:o:";
int ret;
int i, custom_o=0;
infile = outfile = NULL;
//allocating memory and setting up required atoms
eeprom = (struct wedge_eeprom_st *) malloc(sizeof(struct wedge_eeprom_st));
memset(eeprom, "\0", sizeof(*eeprom));
eeprom->fbw_crc8 = 0;
printf("sizeof(struct wedge_eeprom_st)=%d\n",(int)sizeof(struct wedge_eeprom_st));
while((c = getopt(argc, argv, options)) != -1) {
switch(c) {
case 'm':
//result = sscanf(optarg, "%d", &max_size);
result = sscanf(optarg, "%s", temp);
remove_all_chars(temp,'-');
memcpy(eeprom->fbw_local_mac,temp,FBW_EEPROM_F_LOCAL_MAC);
set_fbw_local_mac = 1;
if (result == 0 || result == EOF) {
fprintf(stderr, "\nError! Invalid maximum file size (-s %s)\n\n",
optarg);
return -1;
}
break;
case 'i':
infile = optarg;
break;
case 'o':
outfile = optarg;
break;
case 'v':
return 0;
default:
return -1;
}
}
ret = read_text(infile);
if (ret) {
printf("Error reading and parsing input, aborting\n");
return 0;
}
ret = write_binary(outfile);
if (ret) {
printf("Error writing output\n");
return 0;
}
printf("Done.\n");
return 0;
}