Commit 1a88e745 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

shell: handling init configuration script stored in FMC EEPROM

parent cad7d202
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* is that it starts with 0xdeadbeef pattern. The structure of SFP section is: * is that it starts with 0xdeadbeef pattern. The structure of SFP section is:
* *
* -------------- * --------------
* | count (4B) | * | count (1B) |
* -------------------------------------------------------------------------------------------- * --------------------------------------------------------------------------------------------
* | SFP(1) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) | chksum(1B) | * | SFP(1) part number (16B) | alpha (4B) | deltaTx (4B) | deltaRx (4B) | chksum(1B) |
* -------------------------------------------------------------------------------------------- * --------------------------------------------------------------------------------------------
...@@ -30,6 +30,19 @@ ...@@ -30,6 +30,19 @@
* *
*/ */
/*
* The init script area consist of 2-byte size field and a set of shell commands
* separated with '\n' character.
*
* -------------------
* | bytes used (2B) |
* ------------------------------------------------
* | shell commands separated with '\n'..... |
* | |
* | |
* ------------------------------------------------
*/
int eeprom_read(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size) int eeprom_read(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size)
{ {
...@@ -127,7 +140,7 @@ int32_t eeprom_get_sfp(uint8_t i2cif, uint8_t i2c_addr, struct s_sfpinfo* sfp, u ...@@ -127,7 +140,7 @@ int32_t eeprom_get_sfp(uint8_t i2cif, uint8_t i2c_addr, struct s_sfpinfo* sfp, u
for(i=0; i<sizeof(struct s_sfpinfo)-1; ++i) //'-1' because we do not include chksum in computation for(i=0; i<sizeof(struct s_sfpinfo)-1; ++i) //'-1' because we do not include chksum in computation
chksum = (uint8_t) ((uint16_t)chksum + *(ptr++)) & 0xff; chksum = (uint8_t) ((uint16_t)chksum + *(ptr++)) & 0xff;
if(chksum != sfp->chksum) if(chksum != sfp->chksum)
EE_RET_CHKSUM; EE_RET_CORRPT;
} }
else else
{ {
...@@ -173,3 +186,117 @@ int8_t eeprom_match_sfp(uint8_t i2cif, uint8_t i2c_addr, struct s_sfpinfo* sfp) ...@@ -173,3 +186,117 @@ int8_t eeprom_match_sfp(uint8_t i2cif, uint8_t i2c_addr, struct s_sfpinfo* sfp)
return 0; return 0;
} }
int8_t eeprom_init_erase(uint8_t i2cif, uint8_t i2c_addr)
{
uint16_t used = 0;
if( eeprom_write(i2cif, i2c_addr, EE_BASE_INIT, &used, sizeof(used)) != sizeof(used))
return EE_RET_I2CERR;
else
return used;
}
int8_t eeprom_init_purge(uint8_t i2cif, uint8_t i2c_addr)
{
uint16_t used = 0xffff, i;
uint16_t pattern = 0xff;
eeprom_read(i2cif, i2c_addr, EE_BASE_INIT, &used, sizeof(used));
if(used==0xffff) used=0;
for(i=0; i<used; ++i)
eeprom_write(i2cif, i2c_addr, EE_BASE_INIT+sizeof(used)+i, &pattern, 1);
used = 0xffff;
eeprom_write(i2cif, i2c_addr, EE_BASE_INIT, &used, 2);
return used;
}
/*
* Appends a new shell command at the end of boot script
*/
int8_t eeprom_init_add(uint8_t i2cif, uint8_t i2c_addr, const char *args[])
{
uint8_t i=1;
char separator = ' ';
uint16_t used, readback;
if( eeprom_read(i2cif, i2c_addr, EE_BASE_INIT, &used, sizeof(used)) != sizeof(used) )
return EE_RET_I2CERR;
if( used==0xffff ) used=0; //this means the memory is blank
while(args[i]!='\0')
{
if( eeprom_write(i2cif, i2c_addr, EE_BASE_INIT+sizeof(used)+used, args[i], strlen(args[i])) != strlen(args[i]))
return EE_RET_I2CERR;
used += strlen(args[i]);
if( eeprom_write(i2cif, i2c_addr, EE_BASE_INIT+sizeof(used)+used, &separator, sizeof(separator)) != sizeof(separator) )
return EE_RET_I2CERR;
++used;
++i;
}
//the end of the command, replace last separator with '\n'
separator = '\n';
if( eeprom_write(i2cif, i2c_addr, EE_BASE_INIT+sizeof(used)+used-1, &separator, sizeof(separator)) != sizeof(separator) )
return EE_RET_I2CERR;
//and finally update the size of the script
if( eeprom_write(i2cif, i2c_addr, EE_BASE_INIT, &used, sizeof(used)) != sizeof(used) )
return EE_RET_I2CERR;
if( eeprom_read(i2cif, i2c_addr, EE_BASE_INIT, &readback, sizeof(readback)) != sizeof(readback) )
return EE_RET_I2CERR;
return 0;
}
int32_t eeprom_init_show(uint8_t i2cif, uint8_t i2c_addr)
{
uint16_t used, i;
char byte;
if( eeprom_read(i2cif, i2c_addr, EE_BASE_INIT, &used, sizeof(used)) != sizeof(used) )
return EE_RET_I2CERR;
if(used==0 || used==0xffff)
{
used = 0; //this means the memory is blank
mprintf("Empty init script...\n");
}
//just read and print to the screen char after char
for(i=0; i<used; ++i)
{
if( eeprom_read(i2cif, i2c_addr, EE_BASE_INIT+sizeof(used)+i, &byte, sizeof(byte)) != sizeof(byte) )
return EE_RET_I2CERR;
mprintf("%c", byte);
}
return 0;
}
int8_t eeprom_init_readcmd(uint8_t i2cif, uint8_t i2c_addr, char* buf, uint8_t bufsize, uint8_t next)
{
static uint16_t ptr;
static uint16_t used = 0;
uint8_t i=0;
if(next == 0)
{
if( eeprom_read(i2cif, i2c_addr, EE_BASE_INIT, &used, sizeof(used)) != sizeof(used) )
return EE_RET_I2CERR;
ptr = sizeof(used);
}
if(ptr-sizeof(used) >= used)
return 0;
do
{
if(ptr-sizeof(used) > bufsize) return EE_RET_CORRPT;
if( eeprom_read(i2cif, i2c_addr, EE_BASE_INIT+(ptr++), &buf[i], sizeof(char)) != sizeof(char) )
return EE_RET_I2CERR;
}while(buf[i++]!='\n');
return i;
}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#define EE_RET_I2CERR -1 #define EE_RET_I2CERR -1
#define EE_RET_DBFULL -2 #define EE_RET_DBFULL -2
#define EE_RET_CHKSUM -3 #define EE_RET_CORRPT -3
#define EE_RET_POSERR -4 #define EE_RET_POSERR -4
extern int32_t sfp_alpha; extern int32_t sfp_alpha;
...@@ -28,9 +28,13 @@ struct s_sfpinfo ...@@ -28,9 +28,13 @@ struct s_sfpinfo
int eeprom_read(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size); int eeprom_read(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size);
int eeprom_write(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size); int eeprom_write(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset, uint8_t *buf, size_t size);
int32_t eeprom_sfpdb_erase(uint8_t i2cif, uint8_t i2c_addr); int32_t eeprom_sfpdb_erase(uint8_t i2cif, uint8_t i2c_addr);
int32_t eeprom_sfp_section(uint8_t i2cif, uint8_t i2c_addr, size_t size, uint16_t *section_sz); int32_t eeprom_sfp_section(uint8_t i2cif, uint8_t i2c_addr, size_t size, uint16_t *section_sz);
int8_t eeprom_match_sfp(uint8_t i2cif, uint8_t i2c_addr, struct s_sfpinfo* sfp); int8_t eeprom_match_sfp(uint8_t i2cif, uint8_t i2c_addr, struct s_sfpinfo* sfp);
int8_t eeprom_init_erase(uint8_t i2cif, uint8_t i2c_addr);
int8_t eeprom_init_add(uint8_t i2cif, uint8_t i2c_addr, const char *args[]);
int32_t eeprom_init_show(uint8_t i2cif, uint8_t i2c_addr);
int8_t eeprom_init_readcmd(uint8_t i2cif, uint8_t i2c_addr, char* buf, uint8_t bufsize, uint8_t next);
#endif #endif
...@@ -23,6 +23,8 @@ int cmd_time(const char *args[]); ...@@ -23,6 +23,8 @@ int cmd_time(const char *args[]);
int cmd_ip(const char *args[]); int cmd_ip(const char *args[]);
int cmd_sdb(const char *args[]); int cmd_sdb(const char *args[]);
int cmd_mac(const char *args[]); int cmd_mac(const char *args[]);
int cmd_init(const char *args[]);
int cmd_env(const char *args[]); int cmd_env(const char *args[]);
int cmd_saveenv(const char *args[]); int cmd_saveenv(const char *args[]);
...@@ -35,5 +37,7 @@ void env_init(); ...@@ -35,5 +37,7 @@ void env_init();
int shell_exec(const char *buf); int shell_exec(const char *buf);
void shell_interactive(); void shell_interactive();
int shell_boot_script(void);
#endif #endif
#include "shell.h"
#include "eeprom.h"
#include "syscon.h"
int cmd_init(const char *args[])
{
if( !mi2c_devprobe(WRPC_FMC_I2C, FMC_EEPROM_ADR) )
{
mprintf("EEPROM not found..\n");
return -1;
}
if(args[0] && !strcasecmp(args[0], "erase"))
{
if( eeprom_init_erase(WRPC_FMC_I2C, FMC_EEPROM_ADR) < 0 )
mprintf("Could not erase init script\n");
}
else if(args[0] && !strcasecmp(args[0], "purge"))
{
eeprom_init_purge(WRPC_FMC_I2C, FMC_EEPROM_ADR);
}
else if(args[1] && !strcasecmp(args[0], "add"))
{
if( eeprom_init_add(WRPC_FMC_I2C, FMC_EEPROM_ADR, args) < 0 )
mprintf("Could not add the command\n");
else
mprintf("OK.\n");
}
else if(args[0] && !strcasecmp(args[0], "show"))
{
eeprom_init_show(WRPC_FMC_I2C, FMC_EEPROM_ADR);
}
else if(args[0] && !strcasecmp(args[0], "boot"))
{
shell_boot_script();
}
return 0;
}
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "util.h" #include "util.h"
#include "uart.h" #include "uart.h"
#include "syscon.h"
#include "shell.h" #include "shell.h"
#define SH_MAX_LINE_LEN 80 #define SH_MAX_LINE_LEN 80
...@@ -45,6 +46,7 @@ static const struct shell_cmd cmds_list[] = { ...@@ -45,6 +46,7 @@ static const struct shell_cmd cmds_list[] = {
{ "saveenv", cmd_saveenv }, { "saveenv", cmd_saveenv },
{ "time", cmd_time }, { "time", cmd_time },
{ "sfp", cmd_sfp }, { "sfp", cmd_sfp },
{ "init", cmd_init },
#if WITH_ETHERBONE #if WITH_ETHERBONE
{ "ip", cmd_ip }, { "ip", cmd_ip },
#endif #endif
...@@ -266,3 +268,30 @@ const char* fromdec(const char* dec, int* v) { ...@@ -266,3 +268,30 @@ const char* fromdec(const char* dec, int* v) {
*v = o; *v = o;
return dec; return dec;
} }
int shell_boot_script(void)
{
uint8_t next=0;
//first check if EEPROM is really there
if( !mi2c_devprobe(WRPC_FMC_I2C, FMC_EEPROM_ADR) )
if( !mi2c_devprobe(WRPC_FMC_I2C, FMC_EEPROM_ADR) )
return -1;
while(1)
{
cmd_len = eeprom_init_readcmd(WRPC_FMC_I2C, FMC_EEPROM_ADR, cmd_buf, SH_MAX_LINE_LEN, next);
if(cmd_len <= 0)
{
if(next==0) mprintf("Empty init script...\n");
break;
}
cmd_buf[cmd_len] = 0;
mprintf("executing: %s", cmd_buf);
_shell_exec();
next = 1;
}
return 0;
}
...@@ -10,7 +10,8 @@ OBJS_SHELL = shell/shell.o \ ...@@ -10,7 +10,8 @@ OBJS_SHELL = shell/shell.o \
shell/cmd_time.o \ shell/cmd_time.o \
shell/cmd_gui.o \ shell/cmd_gui.o \
shell/cmd_sdb.o \ shell/cmd_sdb.o \
shell/cmd_mac.o shell/cmd_mac.o \
shell/cmd_init.o
ifneq ($(WITH_ETHERBONE), 0) ifneq ($(WITH_ETHERBONE), 0)
OBJS_SHELL += shell/cmd_ip.o OBJS_SHELL += shell/cmd_ip.o
......
...@@ -71,6 +71,9 @@ void wrc_initialize() ...@@ -71,6 +71,9 @@ void wrc_initialize()
ipv4_init("wru1"); ipv4_init("wru1");
arp_init("wru1"); arp_init("wru1");
#endif #endif
//try to read and execute init script from EEPROM
shell_boot_script();
} }
#define LINK_WENT_UP 1 #define LINK_WENT_UP 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment