Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #3
0
// 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;
}
Beispiel #4
0
//-------------------------------------------------------------------------------------------------
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();
}
Beispiel #5
0
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;
}
Beispiel #6
0
//-------------------------------------------------------------------------------------------------
/// 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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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");
	}
}
Beispiel #9
0
//-------------------------------------------------------------------------------------------------
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;
}
Beispiel #10
0
//-------------------------------------------------------------------------------------------------
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
//-------------------------------------------------------------------------------------------------
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;
}
Beispiel #13
0
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");
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
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));
}
Beispiel #17
0
/** 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);
  }
}
Beispiel #18
0
// 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;

}
Beispiel #19
0
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;
}