static int fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler, struct fcb_block *fcb, struct mtd_info *mtd) { fcb->FingerPrint = 0x20424346; fcb->Version = 0x01000000; fcb->PageDataSize = mtd->writesize; fcb->TotalPageSize = mtd->writesize + mtd->oobsize; fcb->SectorsPerBlock = mtd->erasesize / mtd->writesize; /* Divide ECC strength by two and save the value into FCB structure. */ fcb->EccBlock0EccType = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1; fcb->EccBlockNEccType = fcb->EccBlock0EccType; fcb->EccBlock0Size = 0x00000200; fcb->EccBlockNSize = 0x00000200; fcb->NumEccBlocksPerPage = mtd->writesize / fcb->EccBlock0Size - 1; /* DBBT search area starts at second page on first block */ fcb->DBBTSearchAreaStartAddress = 1; fcb->BadBlockMarkerByte = mxs_nand_mark_byte_offset(mtd); fcb->BadBlockMarkerStartBit = mxs_nand_mark_bit_offset(mtd); fcb->BBMarkerPhysicalOffset = mtd->writesize; imx_handler->fcb_create(imx_handler, fcb, mtd); fcb->Checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4); return 0; }
int main(int argc, char **argv) { FILE *fp; long size; uint32_t chksum; const char *desc = "Chinachip PMP firmware V1.0"; if (argc != 2 && argc != 3) { printf("Dingoo A320 hxf-file packer tool by unterwulf\n" "usage: %s <hxf-file>\n", argv[0]); return EXIT_SUCCESS; } fp = xfopen(argv[1], "w+"); xfseek(fp, HXF_HDR_SIZE, SEEK_SET); /* skip header */ process_filelist(fp); xfwritedw(0, fp); /* zero dword at the end of file */ size = ftell(fp); xfseek(fp, HXF_HDR_SIZE, SEEK_SET); /* skip header */ chksum = calc_chksum(fp); xfseek(fp, 0, SEEK_SET); write_header(fp, size, chksum, desc); fclose(fp); return EXIT_SUCCESS; }
// write the rboot config // preserves the contents of the rest of the sector, // so the rest of the sector can be used to store user data // updates checksum automatically (if enabled) bool ICACHE_FLASH_ATTR rboot_set_config(rboot_config *conf) { uint8 *buffer; buffer = (uint8*)os_malloc(SECTOR_SIZE); if (!buffer) { //os_printf("No ram!\r\n"); return false; } #ifdef BOOT_CONFIG_CHKSUM conf->chksum = calc_chksum((uint8*)conf, (uint8*)&conf->chksum); #endif spi_flash_read(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)((void*)buffer), SECTOR_SIZE); memcpy(buffer, conf, sizeof(rboot_config)); vPortEnterCritical(); spi_flash_erase_sector(BOOT_CONFIG_SECTOR); vPortExitCritical(); taskYIELD(); vPortEnterCritical(); //spi_flash_write(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)((void*)buffer), SECTOR_SIZE); spi_flash_write(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)((void*)buffer), SECTOR_SIZE); vPortExitCritical(); os_free(buffer); return true; }
//------------------------------------------------------------------------------------------------- unsigned Message::encode(f8String& to) const { char msg[MAX_MSG_LENGTH], hmsg[MAX_MSG_LENGTH]; size_t sz(0), hsz(0); #if defined CODECTIMING ostringstream gerr; gerr << "encode(" << _msgType << "):"; IntervalTimer itm; #endif if (!_header) throw MissingMessageComponent("header"); Fields::const_iterator fitr(_header->_fields.find(Common_MsgType)); static_cast<msg_type *>(fitr->second)->set(_msgType); _header->encode(msg, sz); MessageBase::encode(msg, sz); if (!_trailer) throw MissingMessageComponent("trailer"); _trailer->encode(msg, sz); const unsigned msgLen(sz); // checksummable msglength if ((fitr = _header->_fields.find(Common_BeginString)) == _header->_fields.end()) throw MissingMandatoryField(Common_BeginString); _header->_fp.clear(Common_BeginString, FieldTrait::suppress); fitr->second->encode(hmsg, hsz); #if defined MSGRECYCLING _header->_fp.set(Common_BeginString, FieldTrait::suppress); // in case we want to reuse #endif if ((fitr = _header->_fields.find(Common_BodyLength)) == _header->_fields.end()) throw MissingMandatoryField(Common_BodyLength); _header->_fp.clear(Common_BodyLength, FieldTrait::suppress); static_cast<body_length *>(fitr->second)->set(msgLen); fitr->second->encode(hmsg, hsz); #if defined MSGRECYCLING _header->_fp.set(Common_BodyLength, FieldTrait::suppress); // in case we want to reuse #endif ::memcpy(hmsg + hsz, msg, sz); hsz += sz; if ((fitr = _trailer->_fields.find(Common_CheckSum)) == _trailer->_fields.end()) throw MissingMandatoryField(Common_CheckSum); static_cast<check_sum *>(fitr->second)->set(fmt_chksum(calc_chksum(hmsg, hsz))); _trailer->_fp.clear(Common_CheckSum, FieldTrait::suppress); fitr->second->encode(hmsg, hsz); #if defined MSGRECYCLING _trailer->_fp.set(Common_CheckSum, FieldTrait::suppress); // in case we want to reuse #endif #if defined CODECTIMING gerr << itm.Calculate(); GlobalLogger::log(gerr.str()); #endif to.assign(hmsg, hsz); return to.size(); }
u16_t net_calc_chksum(struct net_pkt *pkt, u8_t proto) { u16_t upper_layer_len; u16_t sum; switch (net_pkt_family(pkt)) { #if defined(CONFIG_NET_IPV4) case AF_INET: upper_layer_len = (NET_IPV4_HDR(pkt)->len[0] << 8) + NET_IPV4_HDR(pkt)->len[1] - net_pkt_ipv6_ext_len(pkt) - net_pkt_ip_hdr_len(pkt); if (proto == IPPROTO_ICMP) { return htons(calc_chksum(0, net_pkt_ip_data(pkt) + net_pkt_ip_hdr_len(pkt), upper_layer_len)); } else { sum = calc_chksum(upper_layer_len + proto, (u8_t *)&NET_IPV4_HDR(pkt)->src, 2 * sizeof(struct in_addr)); } break; #endif #if defined(CONFIG_NET_IPV6) case AF_INET6: upper_layer_len = (NET_IPV6_HDR(pkt)->len[0] << 8) + NET_IPV6_HDR(pkt)->len[1] - net_pkt_ipv6_ext_len(pkt); sum = calc_chksum(upper_layer_len + proto, (u8_t *)&NET_IPV6_HDR(pkt)->src, 2 * sizeof(struct in6_addr)); break; #endif default: NET_DBG("Unknown protocol family %d", net_pkt_family(pkt)); return 0; } sum = calc_chksum_pkt(sum, pkt, upper_layer_len); sum = (sum == 0) ? 0xffff : htons(sum); return sum; }
//------------------------------------------------------------------------------------------------- /// Encode message with minimal copying size_t Message::encode(char **hmsg_store) const { char *moffs(*hmsg_store + HEADER_CALC_OFFSET), *msg(moffs); #if defined CODECTIMING IntervalTimer itm; #endif if (!_header) throw MissingMessageComponent("header"); Fields::const_iterator fitr(_header->_fields.find(Common_MsgType)); static_cast<msg_type *>(fitr->second)->set(_msgType); msg += _header->encode(msg); // start msg += MessageBase::encode(msg); if (!_trailer) throw MissingMessageComponent("trailer"); msg += _trailer->encode(msg); const size_t msgLen(msg - moffs); // checksummable msglength const size_t hlen(_ctx._preamble_sz + (msgLen < 10 ? 1 : msgLen < 100 ? 2 : msgLen < 1000 ? 3 : 4)); char *hmsg(moffs - hlen); *hmsg_store = hmsg; if ((fitr = _header->_fields.find(Common_BeginString)) == _header->_fields.end()) throw MissingMandatoryField(Common_BeginString); _header->_fp.clear(Common_BeginString, FieldTrait::suppress); hmsg += fitr->second->encode(hmsg); #if defined MSGRECYCLING _header->_fp.set(Common_BeginString, FieldTrait::suppress); // in case we want to reuse #endif if ((fitr = _header->_fields.find(Common_BodyLength)) == _header->_fields.end()) throw MissingMandatoryField(Common_BodyLength); _header->_fp.clear(Common_BodyLength, FieldTrait::suppress); static_cast<body_length *>(fitr->second)->set(msgLen); hmsg += fitr->second->encode(hmsg); #if defined MSGRECYCLING _header->_fp.set(Common_BodyLength, FieldTrait::suppress); // in case we want to reuse #endif if ((fitr = _trailer->_fields.find(Common_CheckSum)) == _trailer->_fields.end()) throw MissingMandatoryField(Common_CheckSum); static_cast<check_sum *>(fitr->second)->set(fmt_chksum(calc_chksum(moffs - hlen, msgLen + hlen))); _trailer->_fp.clear(Common_CheckSum, FieldTrait::suppress); msg += fitr->second->encode(msg); #if defined MSGRECYCLING _trailer->_fp.set(Common_CheckSum, FieldTrait::suppress); // in case we want to reuse #endif #if defined CODECTIMING _encode_timings._cpu_used += itm.Calculate().AsDouble(); ++_encode_timings._msg_count; #endif *msg = 0; return msg - *hmsg_store; }
u16_t net_calc_chksum_ipv4(struct net_pkt *pkt) { u16_t sum; sum = calc_chksum(0, (u8_t *)NET_IPV4_HDR(pkt), NET_IPV4H_LEN); sum = (sum == 0) ? 0xffff : htons(sum); return sum; }
void save_boot_cfg(espboot_cfg *cfg) { cfg->chksum = calc_chksum((uint8*)cfg, (uint8*)&cfg->chksum); if (SPIEraseSector(BOOT_CONFIG_SECTOR) != 0) { ERROR("Can not erase boot configuration sector\r\n"); } if (SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, cfg, sizeof(espboot_cfg)) != 0) { ERROR("Can not save boot configurations\r\n"); } }
//------------------------------------------------------------------------------------------------- Message *Message::factory(const F8MetaCntx& ctx, const f8String& from) { Message *msg(0); f8String len, mtype; if (extract_header(from, len, mtype)) { const unsigned mlen(fast_atoi<unsigned>(len.c_str())); const BaseMsgEntry *bme(ctx._bme.find_ptr(mtype)); if (!bme) throw InvalidMessage(mtype); msg = bme->_create(); #if defined PERMIT_CUSTOM_FIELDS if (ctx._ube) ctx._ube->post_msg_ctor(msg); #endif #if defined CODECTIMING ostringstream gerr; gerr << "decode(" << mtype << "):"; IntervalTimer itm; #endif msg->decode(from); #if defined CODECTIMING gerr << itm.Calculate(); GlobalLogger::log(gerr.str()); #endif static_cast<body_length *>(msg->_header->_fields.find(Common_BodyLength)->second)->set(mlen); Fields::const_iterator fitr(msg->_header->_fields.find(Common_MsgType)); static_cast<msg_type *>(fitr->second)->set(mtype); #if defined POPULATE_METADATA msg->check_set_rlm(fitr->second); #endif const char *pp(from.data() + from.size() - 7); if (*pp != '1' || *(pp + 1) != '0') // 10=XXX^A throw InvalidMessage(from); if (!ctx.has_flag(F8MetaCntx::noverifychksum)) // permit chksum calculation to be skipped { const f8String chksum(pp + 3, 3); static_cast<check_sum *>(msg->_trailer->_fields.find(Common_CheckSum)->second)->set(chksum); const unsigned chkval(fast_atoi<unsigned>(chksum.c_str())), mchkval(calc_chksum(from, 0, from.size() - 7)); if (chkval != mchkval) throw BadCheckSum(mchkval); } } else { //cerr << "Message::factory throwing" << endl; throw InvalidMessage(from); } return msg; }
//------------------------------------------------------------------------------------------------- Message *Message::factory(const F8MetaCntx& ctx, const f8String& from) { Message *msg(0); f8String len, mtype; if (extract_header(from, len, mtype)) { const unsigned mlen(fast_atoi<unsigned>(len.c_str())); const BaseMsgEntry *bme(ctx._bme.find_ptr(mtype)); if (!bme) throw InvalidMessage(mtype); msg = bme->_create(); #if defined PERMIT_CUSTOM_FIELDS if (ctx._ube) ctx._ube->post_msg_ctor(msg); #endif #if defined CODECTIMING ostringstream gerr; gerr << "decode(" << mtype << "):"; IntervalTimer itm; #endif msg->decode(from); #if defined CODECTIMING gerr << itm.Calculate(); GlobalLogger::log(gerr.str()); #endif Fields::const_iterator fitr(msg->_header->_fields.find(Common_BodyLength)); static_cast<body_length *>(fitr->second)->set(mlen); fitr = msg->_header->_fields.find(Common_MsgType); static_cast<msg_type *>(fitr->second)->set(mtype); #if defined POPULATE_METADATA msg->check_set_rlm(fitr->second); #endif f8String chksum; if (extract_trailer(from, chksum)) { Fields::const_iterator fitr(msg->_trailer->_fields.find(Common_CheckSum)); static_cast<check_sum *>(fitr->second)->set(chksum); const unsigned chkval(fast_atoi<unsigned>(chksum.c_str())), // chksum value mchkval(calc_chksum(from, 0)); // chksum pos if (chkval != mchkval) throw BadCheckSum(mchkval); } } else { //cerr << "Message::factory throwing" << endl; throw InvalidMessage(from); } return msg; }
static int check_fuses(jed_ctx *c) { uint16_t acc; if(0==c->fusechk) { fprintf(stderr,"Checksum is zero, not checking fuses\n"); return 0; } acc=calc_chksum(c); if(c->fusechk-acc) fprintf(stderr,"Fuse checksum fail. expect: %hx got: %hx\n",c->fusechk,acc); return c->fusechk-acc; }
//------------------------------------------------------------------------------------------------- Message *Message::factory(const F8MetaCntx& ctx, const f8String& from) { Message *msg(0); char mtype[MAX_MSGTYPE_FIELD_LEN] = {}, len[MAX_MSGTYPE_FIELD_LEN] = {}; if (extract_header(from, len, mtype)) { const unsigned mlen(fast_atoi<unsigned>(len)); const BaseMsgEntry *bme(ctx._bme.find_ptr(mtype)); if (!bme) throw InvalidMessage(mtype); msg = bme->_create(); #if defined CODECTIMING IntervalTimer itm; #endif msg->decode(from); #if defined CODECTIMING _decode_timings._cpu_used += itm.Calculate().AsDouble(); ++_decode_timings._msg_count; #endif static_cast<body_length *>(msg->_header->_fields.find(Common_BodyLength)->second)->set(mlen); Fields::const_iterator fitr(msg->_header->_fields.find(Common_MsgType)); static_cast<msg_type *>(fitr->second)->set(mtype); #if defined POPULATE_METADATA msg->check_set_rlm(fitr->second); #endif const char *pp(from.data() + from.size() - 7); if (*pp != '1' || *(pp + 1) != '0') // 10=XXX^A throw InvalidMessage(from); if (!ctx.has_flag(F8MetaCntx::noverifychksum)) // permit chksum calculation to be skipped { const f8String chksum(pp + 3, 3); static_cast<check_sum *>(msg->_trailer->_fields.find(Common_CheckSum)->second)->set(chksum); const unsigned chkval(fast_atoi<unsigned>(chksum.c_str())), mchkval(calc_chksum(from, 0, from.size() - 7)); if (chkval != mchkval) throw BadCheckSum(mchkval); } } else { //cerr << "Message::factory throwing" << endl; throw InvalidMessage(from); } return msg; }
void load_boot_cfg(espboot_cfg *cfg) { if (SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, cfg, sizeof(espboot_cfg)) != 0) { ERROR("Can not read boot configurations\r\n"); } INFO("ESPBOOT: Load"); if(cfg->magic != BOOT_CONFIG_MAGIC || cfg->chksum != calc_chksum((uint8*)cfg, (uint8*)&cfg->chksum)) { INFO(" default"); cfg->magic = BOOT_CONFIG_MAGIC; cfg->app_rom_addr = DEFAULT_APPROM_ADDR; cfg->backup_rom_addr = DEFAULT_BACKUPROM_ADDR; cfg->new_rom_addr = 0x200000; save_boot_cfg(cfg); } INFO(" boot settings\r\n"); }
static inline u16_t calc_chksum_pkt(u16_t sum, struct net_pkt *pkt, u16_t upper_layer_len) { struct net_buf *frag = pkt->frags; u16_t proto_len = net_pkt_ip_hdr_len(pkt) + net_pkt_ipv6_ext_len(pkt); s16_t len = frag->len - proto_len; u8_t *ptr = frag->data + proto_len; ARG_UNUSED(upper_layer_len); if (len < 0) { NET_DBG("1st fragment len %u < IP header len %u", frag->len, proto_len); return 0; } while (frag) { sum = calc_chksum(sum, ptr, len); frag = frag->frags; if (!frag) { break; } ptr = frag->data; /* Do we need to take first byte from next fragment */ if (len % 2) { u16_t tmp = *ptr; sum += tmp; if (sum < tmp) { sum++; } len = frag->len - 1; ptr++; } else { len = frag->len; } } return sum; }
bool ICACHE_FLASH_ATTR rboot_get_rtc_data(rboot_rtc_data *rtc) { if (system_rtc_mem_read(RBOOT_RTC_ADDR, rtc, sizeof(rboot_rtc_data))) { return (rtc->chksum == calc_chksum((uint8*)rtc, (uint8*)&rtc->chksum)); } return false; }
bool ICACHE_FLASH_ATTR rboot_set_rtc_data(rboot_rtc_data *rtc) { // calculate checksum rtc->chksum = calc_chksum((uint8*)rtc, (uint8*)&rtc->chksum); return system_rtc_mem_write(RBOOT_RTC_ADDR, rtc, sizeof(rboot_rtc_data)); }
/** Checks the boot config sector to see if there's a new image to write and if so, erases old and copies in new * @note Must be NOINLINE and not static to call from ASM without generating a stack which will be left in memory */ void NOINLINE copyNewImage(void) { BootloaderConfig config; SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, &config, sizeof(BootloaderConfig)); if (config.header != BOOT_CONFIG_HEADER) { ets_printf("No boot config header, %08x != %08x, skipping\r\n", config.header, BOOT_CONFIG_HEADER); return; } else if (calc_chksum((uint8*)&config, (uint8*)&config.chksum) != config.chksum) { ets_printf("ERROR: boot config has bad checksum, %02x, expecting %02x\r\n", config.chksum, calc_chksum((uint8*)&config, (uint8*)&config.chksum)); return; } else if (config.newImageStart == 0 || config.newImageSize == 0) { ets_printf("No new firmware, continuing\r\n"); return; } else { uint32 buffer[SECTOR_SIZE/4]; // Buffer to copy from one sector to another uint32 sector; SpiFlashOpResult rslt; ets_printf("Found new image: %x[%d]\r\n", config.newImageStart, config.newImageSize); ets_printf("\tErasing old firmware\r\n"); for (sector = FIRMWARE_START_SECTOR; sector < FIRMWARE_START_SECTOR + config.newImageSize; sector++) { rslt = SPIEraseSector(sector); if (rslt != SPI_FLASH_RESULT_OK) { ets_printf("\tError erasing sector %x: %d\r\n", sector, rslt); sector--; // Try this sector again } else { ets_printf("_"); } } ets_printf("\tCopying in new firmware\r\n"); for (sector = 0; sector < config.newImageSize; sector++) { rslt = SPIRead((sector + config.newImageStart)*SECTOR_SIZE + IMAGE_READ_OFFSET, buffer, SECTOR_SIZE); if (rslt != SPI_FLASH_RESULT_OK) { ets_printf("\tError reading sector %x: %d\r\n", sector + config.newImageStart, rslt); sector--; // Retry the same sector } else { rslt = SPIWrite((sector + FIRMWARE_START_SECTOR)*SECTOR_SIZE, buffer, SECTOR_SIZE); if (rslt != SPI_FLASH_RESULT_OK) { ets_printf("\tError writing sector %x: %d\r\n", sector + FIRMWARE_START_SECTOR, rslt); sector--; // Retry the same sector } else { ets_printf("."); } } } ets_printf("Done copying new image, %d sectors\r\n", sector); } }
// prevent this function being placed inline with main // to keep main's stack size as small as possible // don't mark as static or it'll be optimised out when // using the assembler stub uint32 NOINLINE find_image() { uint8 flag; uint32 runAddr; uint32 flashsize; int32 romToBoot; uint8 gpio_boot = FALSE; uint8 updateConfig = TRUE; uint8 buffer[SECTOR_SIZE]; rboot_config *romconf = (rboot_config*)buffer; rom_header *header = (rom_header*)buffer; // delay to slow boot (help see messages when debugging) //ets_delay_us(2000000); ets_printf("\r\nrBoot v1.2.0 - [email protected]\r\n"); // read rom header SPIRead(0, header, sizeof(rom_header)); // print and get flash size ets_printf("Flash Size: "); flag = header->flags2 >> 4; if (flag == 0) { ets_printf("4 Mbit\r\n"); flashsize = 0x80000; } else if (flag == 1) { ets_printf("2 Mbit\r\n"); flashsize = 0x40000; } else if (flag == 2) { ets_printf("8 Mbit\r\n"); flashsize = 0x100000; } else if (flag == 3) { ets_printf("16 Mbit\r\n"); #ifdef BOOT_BIG_FLASH flashsize = 0x200000; #else flashsize = 0x100000; // limit to 8Mbit #endif } else if (flag == 4) { ets_printf("32 Mbit\r\n"); #ifdef BOOT_BIG_FLASH flashsize = 0x400000; #else flashsize = 0x100000; // limit to 8Mbit #endif } else { ets_printf("unknown\r\n"); // assume at least 4mbit flashsize = 0x80000; } // print spi mode ets_printf("Flash Mode: "); if (header->flags1 == 0) { ets_printf("QIO\r\n"); } else if (header->flags1 == 1) { ets_printf("QOUT\r\n"); } else if (header->flags1 == 2) { ets_printf("DIO\r\n"); } else if (header->flags1 == 3) { ets_printf("DOUT\r\n"); } else { ets_printf("unknown\r\n"); } // print spi speed ets_printf("Flash Speed: "); flag = header->flags2 & 0x0f; if (flag == 0) ets_printf("40 MHz\r\n"); else if (flag == 1) ets_printf("26.7 MHz\r\n"); else if (flag == 2) ets_printf("20 MHz\r\n"); else if (flag == 0x0f) ets_printf("80 MHz\r\n"); else ets_printf("unknown\r\n"); // print enabled options #ifdef BOOT_BIG_FLASH ets_printf("rBoot Option: Big flash\r\n"); #endif #ifdef BOOT_CONFIG_CHKSUM ets_printf("rBoot Option: Config chksum\r\n"); #endif // read boot config SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE); // fresh install or old version? if (romconf->magic != BOOT_CONFIG_MAGIC || romconf->version != BOOT_CONFIG_VERSION #ifdef BOOT_CONFIG_CHKSUM || romconf->chksum != calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum) #endif ) { // create a default config for a standard 2 rom setup ets_printf("Writing default boot config.\r\n"); ets_memset(romconf, 0x00, sizeof(rboot_config)); romconf->magic = BOOT_CONFIG_MAGIC; romconf->version = BOOT_CONFIG_VERSION; romconf->count = 2; romconf->roms[0] = SECTOR_SIZE * 2; romconf->roms[1] = (flashsize / 2) + (SECTOR_SIZE * 2); #ifdef BOOT_CONFIG_CHKSUM romconf->chksum = calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum); #endif // write new config sector SPIEraseSector(BOOT_CONFIG_SECTOR); SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE); } // if gpio mode enabled check status of the gpio if ((romconf->mode & MODE_GPIO_ROM) && (get_gpio16() == 0)) { ets_printf("Booting GPIO-selected.\r\n"); romToBoot = romconf->gpio_rom; gpio_boot = TRUE; } else if (romconf->current_rom >= romconf->count) { // if invalid rom selected try rom 0 ets_printf("Invalid rom selected, defaulting.\r\n"); romToBoot = 0; romconf->current_rom = 0; updateConfig = TRUE; } else { // try rom selected in the config romToBoot = romconf->current_rom; } // try to find a good rom do { runAddr = check_image(romconf->roms[romToBoot]); if (runAddr == 0) { ets_printf("Rom %d is bad.\r\n", romToBoot); if (gpio_boot) { // don't switch to backup for gpio-selected rom ets_printf("GPIO boot failed.\r\n"); return 0; } else { // for normal mode try each previous rom // until we find a good one or run out updateConfig = TRUE; romToBoot--; if (romToBoot < 0) romToBoot = romconf->count - 1; if (romToBoot == romconf->current_rom) { // tried them all and all are bad! ets_printf("No good rom available.\r\n"); return 0; } } } } while (runAddr == 0); // re-write config, if required if (updateConfig) { romconf->current_rom = romToBoot; #ifdef BOOT_CONFIG_CHKSUM romconf->chksum = calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum); #endif SPIEraseSector(BOOT_CONFIG_SECTOR); SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE); } ets_printf("Booting rom %d.\r\n", romToBoot); // copy the loader to top of iram ets_memcpy((void*)_text_addr, _text_data, _text_len); // return address to load from return runAddr; }
int jed_write(char * fname,jed_ctx* ctx) { size_t i; ctx->f=fopen(fname,"wt"); if(NULL==ctx->f) { fprintf(stderr,"Failed to open %s for writing\n",fname); return 1; } fprintf(ctx->f,"%c\n",STX); fprintf(ctx->f,"GAL readout:*\n"); if(ctx->num_tvec) fprintf(ctx->f,"QV%d*\n",ctx->num_tvec); if(ctx->num_pins) fprintf(ctx->f,"QP%d*\n",ctx->num_pins); fprintf(ctx->f,"QF%d*\n",ctx->num_fuses); fprintf(ctx->f,"F0*\n"); fprintf(ctx->f,"G%d*\n",ctx->secfuse); for(i=0;i<(ctx->num_fuses+43)/44;i++) { size_t j; fprintf(ctx->f,"L%5.5d ",i*44); for(j=0;j<44;j++) { int b; if((i*44+j)<ctx->num_fuses) { get_bit(ctx->flist[(i*44+j)/8],b,(i*44+j)%8); fprintf(ctx->f,"%c",b?'1':'0'); } } fprintf(ctx->f,"*\n"); } ctx->fusechk=calc_chksum(ctx); fprintf(ctx->f,"C%4.4X*\n",ctx->fusechk); if(ctx->num_tvec) { fprintf(ctx->f,"X0*\n"); fprintf(ctx->f,"P "); i=0; while(ctx->pinseq && (i<ctx->num_pins) ) { fprintf(ctx->f,"%u ",((unsigned)ctx->pinseq[i])&0x0ff); i++; } fprintf(ctx->f,"*\n"); for(i=0;i<ctx->num_tvec;i++) { size_t j; if('V'!=ctx->testvec[(ctx->num_pins+1)*i]) printf("skipping unused vector\n"); else { fprintf(ctx->f,"V%4.4u ",i+1); for(j=0;j<ctx->num_pins;j++) { fprintf(ctx->f,"%c",ctx->testvec[(ctx->num_pins+1)*i+j+1]); } fprintf(ctx->f,"*\n"); } } } fprintf(ctx->f,"%c0000\n",ETX); fclose(ctx->f); ctx->f=NULL; return 0; }