/* * Open device and perform command */ int main(int argc, char **argv) { struct k8048 k; char *execdup, *execname; /* Initialise to NULL/0 */ memset(&k, 0, sizeof(k)); /* Get exec name */ execdup = (char *)strdup(argv[0]); if (execdup == NULL) { printf("%s: fatal error: strdup failed\n", __func__); io_exit(&k, EX_OSERR); /* Panic */ } execname = basename(execdup); if (execname == NULL) { printf("%s: fatal error: basename failed\n", __func__); io_exit(&k, EX_OSERR); /* Panic */ } /* Get configuration */ getconf(&k); /* Command: k8048 */ if (strcmp(execname, "k8048") == 0) { resetuid(&k); usage_k8048(&k); } #ifdef TTY /* Command: kload */ if (strcmp(execname, "kload") == 0) { resetuid(&k); if (argc < 3) usage_kload(&k, "Missing arg"); if (argc > 5) usage_kload(&k, "Too many args"); int prog_mode = tolower((int)argv[1][0]); if (prog_mode != 'p' && prog_mode != 'v') usage_kload(&k, "Invalid mode"); if (argv[2][0] == '/' && strstr(argv[2], "/dev/tty") != argv[2]) usage_kload(&k, "Invalid tty"); char file[STRLEN]; strcpy(file, "-"); if (argc >= 4) strncpy(file, argv[3], STRMAX); int target = 'n'; if (argc == 5) { target = tolower((int)argv[4][0]); if (target != 'a') usage_kload(&k, "Invalid target"); } io_signal_on(k); // !SIGPIPE stk500v2_load(&k, prog_mode, argv[2], file, target); io_exit(&k, EX_OK); } #endif /* Open device */ if (io_open(&k) < 0) { #ifdef KTEST if (strcmp(execname, "ktest") == 0) usage_ktest(&k, io_error(&k)); #endif usage(&k, execname, io_error(&k)); } /* Raise priority */ setpriority(PRIO_PROCESS, 0, -20); /* Reset user */ resetuid(&k); #ifdef KCTRL /* Command: kctrl */ if (strcmp(execname, "kctrl") == 0) { if (argc < 2) usage_kctrl(&k, "Missing arg"); if (argc > 2) usage_kctrl(&k, "Too many args"); if (strcasecmp(argv[1], "RUN") == 0) { io_close(&k, HIGH); printf("RUN\n"); } else if (strcasecmp(argv[1], "STOP") == 0) { io_close(&k, LOW); printf("STOP\n"); } else if (strcasecmp(argv[1], "RESTORE") == 0) { io_set_vpp(&k, LOW); io_usleep(&k, 10); io_close(&k, HIGH); printf("RESTORE\n"); } io_exit(&k, EX_OK); } #endif #ifdef KTEST /* Command: ktest */ if (strcmp(execname, "ktest") == 0) { if (argc < 3) usage_ktest(&k, "Missing args"); if (argc > 3) usage_ktest(&k, "Too many args"); int32_t testarg = strtol(argv[2], NULL, 0); if (testarg < 0) usage_ktest(&k, "Invalid arg"); if (strcasecmp(argv[1], "VPP") == 0) io_test0(&k, 0, testarg); else if (strcasecmp(argv[1], "PGC") == 0) io_test0(&k, 1, testarg); else if (strcasecmp(argv[1], "PGD") == 0) io_test0(&k, 2, testarg); else if (strcasecmp(argv[1], "PGM") == 0) io_test0(&k, 3, testarg); else if (argv[1][0] >= '0' && argv[1][0] <= '9') { int32_t test = strtol(argv[1], NULL, 0); switch (test) { #ifdef RPI case 0: gpio_test(&k, testarg);break; #endif case 1: io_test1(&k, testarg); break; case 2: io_test2(&k, testarg); break; case 3: io_test3(&k, testarg); break; case 4: io_test4(&k, testarg); break; #if defined(KTEST) && defined(KIO) case 5: io_test5(&k, testarg); break; #endif default:usage_ktest(&k, "Invalid arg");break; } } else { usage_ktest(&k, "Invalid arg"); } io_exit(&k, EX_OK); } #endif /* Determine arch: k12 | k14 | k16 | k24 | k32 */ if (pic_arch(&k, execname) == 0) usage_k8048(&k); if (argc < 2) usage(&k, execname, "Missing arg(s)"); /* Device selection */ int argv1 = tolower((int)argv[1][0]); if (argv1 == 's') { /* Select device */ if (argc < 3) { pic_selector(&k); io_exit(&k, EX_OK); } if (mystrcasestr(argv[2], "dspic") == argv[2]) { strncpy(k.devicename, argv[2], STRLEN); } else if (mystrcasestr(argv[2], "pic") == argv[2]) { strncpy(k.devicename, argv[2], STRLEN); } else { int32_t temp = strtol(argv[2], NULL, 0); if (temp < 10 || temp > 33) { usage(&k, execname, "Invalid arg [select]"); } if (temp == 30 || temp == 33) { strcpy(k.devicename, "dspic"); strncpy(&k.devicename[5], argv[2], STRLEN - 5); } else { strcpy(k.devicename, "pic"); strncpy(&k.devicename[3], argv[2], STRLEN - 3); } } argc -= 2; argv += 2; if (argc < 2) usage(&k, execname, "Missing arg(s)"); } else if (k.pic->arch == ARCH12BIT) { usage(&k, execname, "Missing select"); } /* Key entry */ argv1 = tolower((int)argv[1][0]); if (argv1 == 'l') { /* LVP 32-bit key entry */ if (k.pic->arch == ARCH12BIT) { usage(&k, execname, "Invalid arg [lvp]"); } /* ARCH14BIT || ARCH16BIT || ARCH24BIT || ARCH32BIT */ k.key = LVPKEY; argc -= 1; argv += 1; if (argc < 2) usage(&k, execname, "Missing arg(s)"); } else if (argv1 == 'h') { /* HVP 32-bit key entry */ if (k.pic->arch == ARCH12BIT || k.pic->arch == ARCH14BIT || k.pic->arch == ARCH32BIT) { usage(&k, execname, "Invalid arg [hvp]"); } /* ARCH16BIT || ARCH24BIT */ k.key = HVPKEY; argc -= 1; argv += 1; if (argc < 2) usage(&k, execname, "Missing arg(s)"); } else if (k.pic->arch == ARCH32BIT) { /* LVP 32-bit key entry */ /* ARCH32BIT */ k.key = LVPKEY; } else { /* No key entry */ /* ARCH12BIT || ARCH14BIT || ARCH16BIT || ARCH24BIT */ k.key = NOKEY; } /* Command */ argv1 = tolower((int)argv[1][0]); int argv11 = tolower((int)argv[1][1]); switch (argv1) { case 'b': if (argv11 == 'o') { /* BOOT */ uint32_t addr = UINT32_MAX, words = UINT32_MAX; if (argc > 4) usage(&k, execname, "Too many args [boot]"); if (argc >= 3) { words = strtoul(argv[2], NULL, 0); if (words == 0) usage(&k, execname, "Invalid arg [boot]"); } if (argc == 4) { addr = strtoul(argv[3], NULL, 0); } pic_dumpboot(&k, addr, words); } else { /* BLANK */ if (argc > 2) usage(&k, execname, "Too many args [blank]"); if (areyousure("Blank device")) pic_blank(&k); } break; case 'c': if (argc > 3) usage(&k, execname, "Too many args [config]"); if (argc == 2) pic_dumpconfig(&k); else pic_writebandgap(&k, strtoul(argv[2], NULL, 0)); break; case 'd': if (argv11 == 'a') { /* DATA */ if (argc > 2) usage(&k, execname, "Too many args [data]"); pic_dumpdata(&k); } else if (argv11 == 'e') { /* DEBUG */ printf("Hello world!\n"); } else { /* DUMP */ if (argc > 2) usage(&k, execname, "Too many args [dump]"); pic_dumpdevice(&k); } break; case 'e': if (argv11 == 'r') { /* ERASE FLASH | ID | ROW[NROWS] */ uint32_t row = 0, nrows = 1; char prompt[STRLEN] = {0}, *endptr = NULL; if (argc < 3) usage(&k, execname, "Missing arg [erase]"); if (argc > 4) usage(&k, execname, "Too many args [erase]"); int argv2 = tolower((int)argv[2][0]); switch (argv2) { case 'i': /* IDLOCATION */ case 'u': /* USERID/CONFIG */ row = PIC_ERASE_ID; strncpy(prompt, "Erase id", STRLEN); break; case 'c': /* CONFIG */ row = PIC_ERASE_CONFIG; strncpy(prompt, "Erase config", STRLEN); break; case 'e': /* EEPROM */ row = PIC_ERASE_EEPROM; strncpy(prompt, "Erase EEPROM", STRLEN); break; case 'f': /* FLASH */ nrows = UINT32_MAX; strncpy(prompt, "Erase program flash", STRLEN); break; default: /* FLASH ROW */ row = strtoul(argv[2], &endptr, 0); if (endptr == argv[2]) usage(&k, execname, "Invalid arg [erase]"); if (argc == 4) { nrows = strtoul(argv[3], NULL, 0); if (nrows == 0) usage(&k, execname, "Invalid arg [erase]"); } snprintf(prompt, STRLEN, "Erase %u row(s) at row %u", nrows, row); break; } if (areyousure(prompt)) pic_erase(&k, row, nrows); } else if (argv11 == 'x') { /* EXECUTIVE */ uint32_t addr = UINT32_MAX, words = UINT32_MAX; if (argc > 4) usage(&k, execname, "Too many args [executive]"); if (argc >= 3) { words = strtoul(argv[2], NULL, 0); if (words == 0) usage(&k, execname, "Invalid arg [executive]"); } if (argc == 4) { addr = strtoul(argv[3], NULL, 0); } pic_dumpexec(&k, addr, words); } else { /* EEPROM */ if (argc > 2) usage(&k, execname, "Too many args [eeprom]"); pic_dumpdata(&k); } break; case 'f': { uint32_t words = UINT32_MAX, addr = UINT32_MAX; if (argc > 4) usage(&k, execname, "Too many args [program flash]"); if (argc >= 3) { words = strtoul(argv[2], NULL, 0); if (words == 0) usage(&k, execname, "Invalid arg [program flash]"); } if (argc == 4) { addr = strtoul(argv[3], NULL, 0); } pic_dumpprogram(&k, addr, words); } break; case 'i': if (argc > 2) usage(&k, execname, "Too many args [id]"); pic_dumpdeviceid(&k); break; case 'o': if (argc > 3) usage(&k, execname, "Too many args [osccal]"); if (argc == 2) pic_dumposccal(&k); else pic_writeosccal(&k, strtoul(argv[2], NULL, 0)); break; case 'p': { int blank = 1; if (argc > 4) usage(&k, execname, "Too many args [program]"); if (argc == 4) switch (argv[3][0]) { case 'n': case 'N': case '0': blank = 0; break; case 'y': case 'Y': case '1': blank = 1; break; default:usage(&k, execname, "Invalid arg [program]"); break; } if (argc < 3) pic_program(&k, "-", 1); else pic_program(&k, argv[2], blank); } break; case 'v': if (argv11 == 'i') { /* VIEW */ if (argc > 3) usage(&k, execname, "Too many args [view]"); if (argc < 3) pic_view(&k, "-"); else pic_view(&k, argv[2]); } else { /* VERIFY */ if (argc > 3) usage(&k, execname, "Too many args [verify]"); if (argc < 3) pic_verify(&k, "-"); else pic_verify(&k, argv[2]); } break; #ifdef TTY case '/': if (strstr(argv[1], "/dev/tty") != argv[1]) { usage(&k, execname, "Invalid device [TTY]"); } if (strstr(argv[1], k.device) != NULL) { usage(&k, execname, "Device in use [TTY]"); } stk500v2_listen(&k, argv[1], 0); break; case '8': stk500v2_listen(&k, "0.0.0.0", 8048); break; #endif default: usage(&k, execname, "Unknown operation"); break; } free(execdup); io_exit(&k, EX_OK); }
/* * Open device and perform command */ int main(int argc, char **argv) { char *execdup, *execname; int rc = EX_OK; /* Get exec name */ execdup = (char *)strdup(argv[0]); if (execdup == NULL) { printf("%s: fatal error: strdup failed\n", __func__); io_exit(EX_OSERR); /* Panic */ } execname = basename(execdup); if (execname == NULL) { printf("%s: fatal error: basename failed\n", __func__); io_exit(EX_OSERR); /* Panic */ } /* Get configuration */ getconf(); /* Open device */ if (io_open() < 0) { usage(execname, io_error()); } /* Raise priority */ setpriority(PRIO_PROCESS, 0, -20); /* Reset uid */ if (getuid() != geteuid()) { if (setuid(getuid()) < 0) { printf("%s: fatal error: setuid failed\n", __func__); io_exit(EX_OSERR); /* Panic */ } } /* Determine arch: 12 | 14 | 16 | 24 | 32 */ if (pic_arch(execname) == 0) usage_pickle(); /* Perform operation */ if (argc < 2) usage(execname, "Missing arg(s)"); /* Device selection */ int argv1 = tolower((int)argv[1][0]); if (argv1 == 's') { /* Select device */ if (argc < 3) { pic_selector(); io_exit(EX_OK); } if (mystrcasestr(argv[2], "dspic") == argv[2]) { strncpy(p.devicename, argv[2], STRLEN); } else if (mystrcasestr(argv[2], "pic") == argv[2]) { strncpy(p.devicename, argv[2], STRLEN); } else { int32_t temp = strtol(argv[2], NULL, 0); if (temp < 10 || temp > 33) { usage(execname, "Invalid arg [select]"); } if (temp == 30 || temp == 33) { strcpy(p.devicename, "dspic"); strncpy(&p.devicename[5], argv[2], STRLEN - 5); } else { strcpy(p.devicename, "pic"); strncpy(&p.devicename[3], argv[2], STRLEN - 3); } } argc -= 2; argv += 2; if (argc < 2) usage(execname, "Missing arg(s)"); } else if (p.pic->arch == ARCH12BIT) { usage(execname, "Missing select"); } /* Key entry */ argv1 = tolower((int)argv[1][0]); if (argv1 == 'l') { /* LVP 32-bit key entry */ if (p.pic->arch == ARCH12BIT) { usage(execname, "Invalid arg [lvp]"); } /* ARCH14BIT || ARCH16BIT || ARCH24BIT || ARCH32BIT */ p.key = LVPKEY; argc -= 1; argv += 1; if (argc < 2) usage(execname, "Missing arg(s)"); } else if (argv1 == 'h') { /* HVP 32-bit key entry */ if (p.pic->arch == ARCH12BIT || p.pic->arch == ARCH14BIT || p.pic->arch == ARCH32BIT) { usage(execname, "Invalid arg [hvp]"); } /* ARCH16BIT || ARCH24BIT */ p.key = HVPKEY; argc -= 1; argv += 1; if (argc < 2) usage(execname, "Missing arg(s)"); } else if (p.pic->arch == ARCH32BIT) { /* LVP 32-bit key entry */ /* ARCH32BIT */ p.key = LVPKEY; } else { /* No key entry */ /* ARCH12BIT || ARCH14BIT || ARCH16BIT || ARCH24BIT */ p.key = NOKEY; } /* Command */ argv1 = tolower((int)argv[1][0]); int argv11 = tolower((int)argv[1][1]); switch (argv1) { case 'b': if (argv11 == 'o') { /* BOOT */ uint32_t addr = UINT32_MAX, words = UINT32_MAX; if (argc > 4) usage(execname, "Too many args [boot]"); if (argc >= 3) { words = strtoul(argv[2], NULL, 0); if (words == 0) usage(execname, "Invalid arg [boot]"); } if (argc == 4) { addr = strtoul(argv[3], NULL, 0); } pic_dumpboot(addr, words); } else { /* BLANK */ int config = 1; if (argc > 3) usage(execname, "Too many args [blank]"); if (argc == 3) switch (argv[2][0]) { case 'n': case 'N': case '0': config = 0; break; case 'y': case 'Y': case '1': config = 1; break; default:usage(execname, "invalid arg [blank]"); break; } if (areyousure("Blank device")) { pic_blank(config); } } break; case 'c': if (argc > 3) usage(execname, "Too many args [config]"); if (argc == 2) pic_dumpconfig(); else pic_writebandgap(strtoul(argv[2], NULL, 0)); break; case 'd': if (argv11 == 'a') { /* DATA */ if (argc > 2) usage(execname, "Too many args [data]"); pic_dumpdata(); } else if (argv11 == 'e') { /* DEBUG */ pic_debug(); } else { /* DUMP */ if (argc > 2) usage(execname, "Too many args [dump]"); pic_dumpdevice(); } break; case 'e': if (argv11 == 'r') { /* ERASE FLASH | ID | ROW[NROWS] */ uint32_t row = 0, nrows = 1; char prompt[STRLEN] = {0}, *endptr = NULL; if (argc < 3) usage(execname, "Missing arg [erase]"); if (argc > 4) usage(execname, "Too many args [erase]"); int argv2 = tolower((int)argv[2][0]); switch (argv2) { case 'i': /* IDLOCATION */ case 'u': /* USERID/CONFIG */ row = PIC_ERASE_ID; strncpy(prompt, "Erase id", STRLEN); break; case 'c': /* CONFIG */ row = PIC_ERASE_CONFIG; strncpy(prompt, "Erase config", STRLEN); break; case 'e': /* EEPROM */ row = PIC_ERASE_EEPROM; strncpy(prompt, "Erase EEPROM", STRLEN); break; case 'f': /* FLASH */ nrows = UINT32_MAX; strncpy(prompt, "Erase program flash", STRLEN); break; default: /* FLASH ROW */ row = strtoul(argv[2], &endptr, 0); if (endptr == argv[2]) usage(execname, "Invalid arg [erase]"); if (argc == 4) { nrows = strtoul(argv[3], NULL, 0); if (nrows == 0) usage(execname, "Invalid arg [erase]"); } snprintf(prompt, STRLEN, "Erase %u row(s) at row %u", nrows, row); break; } if (areyousure(prompt)) pic_erase(row, nrows); } else if (argv11 == 'x') { /* EXECUTIVE */ uint32_t addr = UINT32_MAX, words = UINT32_MAX; if (argc > 4) usage(execname, "Too many args [executive]"); if (argc >= 3) { words = strtoul(argv[2], NULL, 0); if (words == 0) usage(execname, "Invalid arg [executive]"); } if (argc == 4) { addr = strtoul(argv[3], NULL, 0); } pic_dumpexec(addr, words); } else { /* EEPROM */ if (argc > 2) usage(execname, "Too many args [eeprom]"); pic_dumpdata(); } break; case 'f': { uint32_t words = UINT32_MAX, addr = UINT32_MAX; if (argc > 4) usage(execname, "Too many args [program flash]"); if (argc >= 3) { words = strtoul(argv[2], NULL, 0); if (words == 0) usage(execname, "Invalid arg [program flash]"); } if (argc == 4) { addr = strtoul(argv[3], NULL, 0); } pic_dumpprogram(addr, words); } break; case 'i': if (argc > 2) usage(execname, "Too many args [id]"); pic_dumpdeviceid(); break; case 'o': if (argc > 3) usage(execname, "Too many args [osccal]"); if (argc == 2) pic_dumposccal(); else pic_writeosccal(strtoul(argv[2], NULL, 0)); break; case 'p': { int blank = 1; if (argc > 4) usage(execname, "Too many args [program]"); if (argc == 4) switch (argv[3][0]) { case 'n': case 'N': case '0': blank = 0; break; case 'y': case 'Y': case '1': blank = 1; break; default:usage(execname, "invalid arg [program]"); break; } if (argc < 3) pic_program("-", 1); else pic_program(argv[2], blank); } break; case 'v': if (argv11 == 'i') { /* VIEW */ int raw = 0; if (argc > 4) usage(execname, "Too many args [view]"); if (argc == 4) switch (argv[3][0]) { case 'r': case 'R': raw = 1; break; default:usage(execname, "invalid arg [view]"); break; } if (argc < 3) pic_view("-", 0); else pic_view(argv[2], raw); } else { /* VERIFY */ if (argc > 3) usage(execname, "Too many args [verify]"); if (argc < 3) rc = 0 - pic_verify("-"); else rc = 0 - pic_verify(argv[2]); } break; #ifdef TTY case '/': if (strstr(argv[1], "/dev/tty") != argv[1]) { usage(execname, "Invalid device [TTY]"); } if (strstr(argv[1], p.device) != NULL) { usage(execname, "Device in use [TTY]"); } stk500v2_listen(argv[1], 0); break; case '8': stk500v2_listen("0.0.0.0", 8048); break; #endif default: usage(execname, "Unknown operation"); break; } free(execdup); io_exit(rc); }