mirror of
https://github.com/gwenhael-le-moine/x49gp.git
synced 2024-12-26 21:58:41 +01:00
[3298] Add command-line options to rebuild the flash or reboot
This commit is contained in:
parent
df33a5ac5b
commit
0a148f61e3
3 changed files with 118 additions and 23 deletions
34
flash.c
34
flash.c
|
@ -512,7 +512,11 @@ flash_load(x49gp_module_t *module, GKeyFile *key)
|
||||||
|
|
||||||
if (flash->size > st.st_size) {
|
if (flash->size > st.st_size) {
|
||||||
fprintf(stderr, "Flash too small, rebuilding\n");
|
fprintf(stderr, "Flash too small, rebuilding\n");
|
||||||
|
x49gp->startup_reinit = X49GP_REINIT_FLASH_FULL;
|
||||||
|
}
|
||||||
|
if (x49gp->startup_reinit >= X49GP_REINIT_FLASH) {
|
||||||
|
|
||||||
|
if (x49gp->startup_reinit == X49GP_REINIT_FLASH_FULL)
|
||||||
memset(phys_ram_base + flash->offset, 0xff,
|
memset(phys_ram_base + flash->offset, 0xff,
|
||||||
flash->size - st.st_size);
|
flash->size - st.st_size);
|
||||||
|
|
||||||
|
@ -547,22 +551,29 @@ flash_load(x49gp_module_t *module, GKeyFile *key)
|
||||||
close(bootfd);
|
close(bootfd);
|
||||||
g_free(bootfile);
|
g_free(bootfile);
|
||||||
|
|
||||||
/* The stock firmware expects special markers in certain spots
|
if (x49gp->startup_reinit == X49GP_REINIT_FLASH_FULL) {
|
||||||
across the flash. Without these, the user banks act up and
|
/* The stock firmware expects special markers in certain
|
||||||
are not usable, and PINIT apparently won't fix it.
|
spots across the flash. Without these, the user banks
|
||||||
Let's help it out; custom firmware will have to deal with
|
act up and are not usable, and PINIT apparently won't
|
||||||
remnants of the user banks on real calculators anyway,
|
fix it. Let's help it out; custom firmware will have
|
||||||
so if they break here, they will too on actual hardware
|
to deal with remnants of the user banks on real
|
||||||
because that always comes with the stock firmware and
|
calculators anyway, so if they break here, they will
|
||||||
its user banks marked properly. */
|
too on actual hardware because that always comes with
|
||||||
|
the stock firmware and its user banks marked
|
||||||
|
properly. */
|
||||||
for (i=2;i<14;i++) {
|
for (i=2;i<14;i++) {
|
||||||
bank_marker[1] = i;
|
bank_marker[1] = i;
|
||||||
memcpy(phys_ram_base + flash->offset + 0x40100 +
|
memcpy(phys_ram_base + flash->offset + 0x40100 +
|
||||||
0x20000 * i, bank_marker, 5);
|
0x20000 * i, bank_marker, 5);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
filename = NULL;
|
filename = NULL;
|
||||||
|
if (x49gp->firmware != NULL) {
|
||||||
|
filename = g_strdup(x49gp->firmware);
|
||||||
|
} else {
|
||||||
x49gp_ui_open_firmware(x49gp, &filename);
|
x49gp_ui_open_firmware(x49gp, &filename);
|
||||||
|
}
|
||||||
if (filename != NULL) {
|
if (filename != NULL) {
|
||||||
fwfd = open(filename, O_RDONLY);
|
fwfd = open(filename, O_RDONLY);
|
||||||
if (fwfd < 0) {
|
if (fwfd < 0) {
|
||||||
|
@ -572,6 +583,9 @@ flash_load(x49gp_module_t *module, GKeyFile *key)
|
||||||
fprintf(stderr, "Warning: Could not open "
|
fprintf(stderr, "Warning: Could not open "
|
||||||
"selected firmware, falling back to "
|
"selected firmware, falling back to "
|
||||||
"bootloader recovery tools\n");
|
"bootloader recovery tools\n");
|
||||||
|
/* Mark firmware as invalid if there is one */
|
||||||
|
memset(phys_ram_base + flash->offset +
|
||||||
|
BOOT_SIZE, 0, 16);
|
||||||
} else {
|
} else {
|
||||||
/* The firmware may be shorter than
|
/* The firmware may be shorter than
|
||||||
SST29VF160_SIZE - BOOT_SIZE, but if so,
|
SST29VF160_SIZE - BOOT_SIZE, but if so,
|
||||||
|
@ -588,6 +602,10 @@ flash_load(x49gp_module_t *module, GKeyFile *key)
|
||||||
"read selected firmware, "
|
"read selected firmware, "
|
||||||
"falling back to bootloader "
|
"falling back to bootloader "
|
||||||
"recovery tools\n");
|
"recovery tools\n");
|
||||||
|
/* Mark firmware as invalid
|
||||||
|
if there is one */
|
||||||
|
memset(phys_ram_base + flash->offset +
|
||||||
|
BOOT_SIZE, 0, 16);
|
||||||
} else {
|
} else {
|
||||||
/* Mark the firmware as valid in the
|
/* Mark the firmware as valid in the
|
||||||
same way the bootloader does */
|
same way the bootloader does */
|
||||||
|
|
|
@ -54,6 +54,12 @@ struct __x49gp_module_s__ {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
X49GP_REINIT_NONE = 0,
|
||||||
|
X49GP_REINIT_REBOOT_ONLY,
|
||||||
|
X49GP_REINIT_FLASH,
|
||||||
|
X49GP_REINIT_FLASH_FULL
|
||||||
|
} x49gp_reinit_t;
|
||||||
|
|
||||||
struct __x49gp_s__ {
|
struct __x49gp_s__ {
|
||||||
CPUARMState *env;
|
CPUARMState *env;
|
||||||
|
@ -97,6 +103,8 @@ struct __x49gp_s__ {
|
||||||
const char *progpath;
|
const char *progpath;
|
||||||
const char *basename;
|
const char *basename;
|
||||||
int debug_port;
|
int debug_port;
|
||||||
|
x49gp_reinit_t startup_reinit;
|
||||||
|
char *firmware;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void x49gp_set_idle(x49gp_t *, x49gp_arm_idle_t idle);
|
extern void x49gp_set_idle(x49gp_t *, x49gp_arm_idle_t idle);
|
||||||
|
|
73
main.c
73
main.c
|
@ -254,6 +254,8 @@ struct options {
|
||||||
char *config;
|
char *config;
|
||||||
int debug_port;
|
int debug_port;
|
||||||
int start_debugger;
|
int start_debugger;
|
||||||
|
char *firmware;
|
||||||
|
x49gp_reinit_t reinit;
|
||||||
|
|
||||||
int more_options;
|
int more_options;
|
||||||
};
|
};
|
||||||
|
@ -275,6 +277,13 @@ static int action_debuglater(struct options *opt, struct option_def *match,
|
||||||
char *this_opt, char *param, char *progname);
|
char *this_opt, char *param, char *progname);
|
||||||
static int action_debug(struct options *opt, struct option_def *match,
|
static int action_debug(struct options *opt, struct option_def *match,
|
||||||
char *this_opt, char *param, char *progname);
|
char *this_opt, char *param, char *progname);
|
||||||
|
static int action_reinit_flash(struct options *opt, struct option_def *match,
|
||||||
|
char *this_opt, char *param, char *progname);
|
||||||
|
static int action_reinit_flash_full(struct options *opt,
|
||||||
|
struct option_def *match, char *this_opt,
|
||||||
|
char *param, char *progname);
|
||||||
|
static int action_reboot(struct options *opt, struct option_def *match,
|
||||||
|
char *this_opt, char *param, char *progname);
|
||||||
|
|
||||||
static int action_unknown_with_param(struct options *opt,
|
static int action_unknown_with_param(struct options *opt,
|
||||||
struct option_def *match, char *this_opt,
|
struct option_def *match, char *this_opt,
|
||||||
|
@ -288,6 +297,9 @@ struct option_def option_defs[] = {
|
||||||
{ action_help, "help", 'h' },
|
{ action_help, "help", 'h' },
|
||||||
{ action_debuglater, "enable-debug", 'D' },
|
{ action_debuglater, "enable-debug", 'D' },
|
||||||
{ action_debug, "debug", 'd' },
|
{ action_debug, "debug", 'd' },
|
||||||
|
{ action_reinit_flash, "reflash", 'f' },
|
||||||
|
{ action_reinit_flash_full, "reflash-full", 'F' },
|
||||||
|
{ action_reboot, "reboot", 'r' },
|
||||||
|
|
||||||
{ action_longopt, NULL, '-' },
|
{ action_longopt, NULL, '-' },
|
||||||
{ action_unknown_with_param, NULL, '=' },
|
{ action_unknown_with_param, NULL, '=' },
|
||||||
|
@ -319,6 +331,20 @@ action_help(struct options *opt, struct option_def *match, char *this_opt,
|
||||||
" (default port: %u)\n"
|
" (default port: %u)\n"
|
||||||
" -d, --debug[=<port>] like -D, but also start the"
|
" -d, --debug[=<port>] like -D, but also start the"
|
||||||
" debugger immediately\n"
|
" debugger immediately\n"
|
||||||
|
" -f, --reflash[=firmware] rebuild the flash using the"
|
||||||
|
" supplied firmware\n"
|
||||||
|
" (default: select one"
|
||||||
|
" interactively)\n"
|
||||||
|
" (implies -r for safety"
|
||||||
|
" reasons)\n"
|
||||||
|
" -F, --reflash-full[=firmware] like -f, but don't preserve the"
|
||||||
|
" flash contents\n"
|
||||||
|
" in the area beyond the"
|
||||||
|
" firmware\n"
|
||||||
|
" -r, --reboot reboot on startup instead of"
|
||||||
|
" continuing from the\n"
|
||||||
|
" saved state in the config"
|
||||||
|
" file\n"
|
||||||
" -h, --help print this message and exit\n"
|
" -h, --help print this message and exit\n"
|
||||||
"The config file is formatted as INI file and contains the"
|
"The config file is formatted as INI file and contains the"
|
||||||
" settings for which\n"
|
" settings for which\n"
|
||||||
|
@ -366,6 +392,45 @@ action_debug(struct options *opt, struct option_def *match, char *this_opt,
|
||||||
return action_debuglater(opt, match, this_opt, param, progname);
|
return action_debuglater(opt, match, this_opt, param, progname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
action_reinit_flash(struct options *opt, struct option_def *match,
|
||||||
|
char *this_opt, char *param, char *progname)
|
||||||
|
{
|
||||||
|
if (opt->reinit < X49GP_REINIT_FLASH)
|
||||||
|
opt->reinit = X49GP_REINIT_FLASH;
|
||||||
|
|
||||||
|
if (param == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (opt->firmware != NULL)
|
||||||
|
fprintf(stderr, "Additional firmware file \"%s\" specified,"
|
||||||
|
" overriding\n", param);
|
||||||
|
opt->firmware = param;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
action_reinit_flash_full(struct options *opt,
|
||||||
|
struct option_def *match, char *this_opt,
|
||||||
|
char *param, char *progname)
|
||||||
|
{
|
||||||
|
int result = action_reinit_flash(opt, match, this_opt, param, progname);
|
||||||
|
opt->reinit = X49GP_REINIT_FLASH_FULL;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
action_reboot(struct options *opt, struct option_def *match, char *this_opt,
|
||||||
|
char *param, char *progname)
|
||||||
|
{
|
||||||
|
if (param != NULL)
|
||||||
|
warn_unneeded_param(match, this_opt);
|
||||||
|
|
||||||
|
if (opt->reinit < X49GP_REINIT_REBOOT_ONLY)
|
||||||
|
opt->reinit = X49GP_REINIT_REBOOT_ONLY;
|
||||||
|
return param != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
action_longopt(struct options *opt, struct option_def *match, char *this_opt,
|
action_longopt(struct options *opt, struct option_def *match, char *this_opt,
|
||||||
char *param, char *progname)
|
char *param, char *progname)
|
||||||
|
@ -530,6 +595,8 @@ main(int argc, char **argv)
|
||||||
opt.config = NULL;
|
opt.config = NULL;
|
||||||
opt.debug_port = 0;
|
opt.debug_port = 0;
|
||||||
opt.start_debugger = FALSE;
|
opt.start_debugger = FALSE;
|
||||||
|
opt.reinit = X49GP_REINIT_NONE;
|
||||||
|
opt.firmware = NULL;
|
||||||
parse_options(&opt, argc, argv, progname);
|
parse_options(&opt, argc, argv, progname);
|
||||||
|
|
||||||
x49gp = malloc(sizeof(x49gp_t));
|
x49gp = malloc(sizeof(x49gp_t));
|
||||||
|
@ -595,10 +662,12 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
x49gp->basename = g_path_get_dirname(opt.config);
|
x49gp->basename = g_path_get_dirname(opt.config);
|
||||||
x49gp->debug_port = opt.debug_port;
|
x49gp->debug_port = opt.debug_port;
|
||||||
|
x49gp->startup_reinit = opt.reinit;
|
||||||
|
x49gp->firmware = opt.firmware;
|
||||||
|
|
||||||
error = x49gp_modules_load(x49gp, opt.config);
|
error = x49gp_modules_load(x49gp, opt.config);
|
||||||
if (error) {
|
if (error || opt.reinit >= X49GP_REINIT_REBOOT_ONLY) {
|
||||||
if (error != -EAGAIN) {
|
if (error && error != -EAGAIN) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
x49gp_modules_reset(x49gp, X49GP_RESET_POWER_ON);
|
x49gp_modules_reset(x49gp, X49GP_RESET_POWER_ON);
|
||||||
|
|
Loading…
Reference in a new issue