Exemplo n.º 1
0
/*
 * Perform a rudimentary verification of header and return
 * size of image.
 */
static int verify_header(const uint8_t *buf)
{
	memcpy(&header, buf, sizeof(header));

	if (le32_to_cpu(header.validation) != VALIDATION_WORD)
		return -1;
	if (le16_to_cpu(header.checksum) != hdr_checksum(&header))
		return -1;

	return le16_to_cpu(header.length_u32) * 4;
}
Exemplo n.º 2
0
static void build_header(uint8_t *buf, uint8_t version, uint8_t flags,
			 uint16_t length_bytes)
{
	header.validation = cpu_to_le32(VALIDATION_WORD);
	header.version = version;
	header.flags = flags;
	header.length_u32 = cpu_to_le16(length_bytes/4);
	header.zero = 0;
	header.checksum = cpu_to_le16(hdr_checksum(&header));

	memcpy(buf, &header, sizeof(header));
}
Exemplo n.º 3
0
/* Dump a stage backup header */
afs_uint32
DumpStageHdr(XFILE * OX, backup_system_header * hdr)
{
    char buf[STAGE_HDRLEN];
    struct stage_header *bckhdr = (struct stage_header *)buf;
    afs_uint32 checksum;
    afs_uint32 r;

    memset(buf, 0, STAGE_HDRLEN);
    bckhdr->c_vers = hdr->version;
    bckhdr->c_fdate = htonl(hdr->from_date);
    bckhdr->c_tdate = htonl(hdr->to_date);
    bckhdr->c_filenum = htonl(hdr->filenum);
    bckhdr->c_time = htonl(hdr->dump_date);
    bckhdr->c_id = htonl(hdr->volid);
#ifdef NATIVE_INT64
    bckhdr->c_length = htonl((afs_uint32) hdr->dumplen);
#else
    bckhdr->c_length = htonl(hdr->dumplen.lo);
#endif
    bckhdr->c_level = htonl(hdr->level);
    bckhdr->c_magic = htonl(STAGE_MAGIC);
    bckhdr->c_flags = htonl(hdr->flags);

    strcpy(bckhdr->c_host, (char *)hdr->server);
    strcpy(bckhdr->c_disk, (char *)hdr->part);
    strcpy(bckhdr->c_name, (char *)hdr->volname);

    /* Now, compute the checksum */
    checksum = hdr_checksum(buf, STAGE_HDRLEN);
    bckhdr->c_checksum = htonl(STAGE_CHECKSUM - checksum);

    if ((r = xfwrite(OX, buf, STAGE_HDRLEN)))
	return r;
    return 0;
}
Exemplo n.º 4
0
u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart,
		u32 FileLength)
{
	u16 status = STATUS_SUCCESS;
	u32 state;
	u16 handshake;
	struct pseudo_hdr *pseudo_header;
	u16 pseudo_header_len;
	long word_length;
	u16 request;
	u16 temp;
	u16 tempword;

	struct dsp_file_hdr *file_hdr;
	struct dsp_image_info *dsp_img_info = NULL;
	long requested_version;
	bool correct_version;
	struct drv_msg *mailbox_data;
	u16 *data = NULL;
	u16 *s_file = NULL;
	u8 *c_file = NULL;
	u8 *boot_end = NULL, *code_end = NULL;
	int image;
	long loader_code_address, loader_code_size = 0;
	long run_address = 0, run_size = 0;

	u32 templong;
	u32 image_chksum = 0;

	u16 dpram = 0;
	u8 *pbuffer;
	struct prov_record *pprov_record;
	struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);

	DEBUG("Entered   scram_dnldr...\n");

	pft1000info->fcodeldr = 0;
	pft1000info->usbboot = 0;
	pft1000info->dspalive = 0xffff;

	//
	// Get version id of file, at first 4 bytes of file, for newer files.
	//

	state = STATE_START_DWNLD;

	file_hdr = (struct dsp_file_hdr *)pFileStart;

	ft1000_write_register(ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK);

	s_file = (u16 *) (pFileStart + file_hdr->loader_offset);
	c_file = (u8 *) (pFileStart + file_hdr->loader_offset);

	boot_end = (u8 *) (pFileStart + file_hdr->loader_code_end);

	loader_code_address = file_hdr->loader_code_address;
	loader_code_size = file_hdr->loader_code_size;
	correct_version = FALSE;

	while ((status == STATUS_SUCCESS) && (state != STATE_DONE_FILE)) {
		switch (state) {
		case STATE_START_DWNLD:
			DEBUG("FT1000:STATE_START_DWNLD\n");
			if (pft1000info->usbboot)
				handshake =
				    get_handshake_usb(ft1000dev,
						      HANDSHAKE_DSP_BL_READY);
			else
				handshake =
				    get_handshake(ft1000dev,
						  HANDSHAKE_DSP_BL_READY);

			if (handshake == HANDSHAKE_DSP_BL_READY) {
				DEBUG
				    ("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n");
				put_handshake(ft1000dev,
					      HANDSHAKE_DRIVER_READY);
			} else {
				DEBUG
				    ("FT1000:download:Download error: Handshake failed\n");
				status = STATUS_FAILURE;
			}

			state = STATE_BOOT_DWNLD;

			break;

		case STATE_BOOT_DWNLD:
			DEBUG("FT1000:STATE_BOOT_DWNLD\n");
			pft1000info->bootmode = 1;
			handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST);
			if (handshake == HANDSHAKE_REQUEST) {
				/*
				 * Get type associated with the request.
				 */
				request = get_request_type(ft1000dev);
				switch (request) {
				case REQUEST_RUN_ADDRESS:
					DEBUG("FT1000:REQUEST_RUN_ADDRESS\n");
					put_request_value(ft1000dev,
							  loader_code_address);
					break;
				case REQUEST_CODE_LENGTH:
					DEBUG("FT1000:REQUEST_CODE_LENGTH\n");
					put_request_value(ft1000dev,
							  loader_code_size);
					break;
				case REQUEST_DONE_BL:
					DEBUG("FT1000:REQUEST_DONE_BL\n");
					/* Reposition ptrs to beginning of code section */
					s_file = (u16 *) (boot_end);
					c_file = (u8 *) (boot_end);
					//DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file);
					//DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file);
					state = STATE_CODE_DWNLD;
					pft1000info->fcodeldr = 1;
					break;
				case REQUEST_CODE_SEGMENT:
					//DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");
					word_length =
					    get_request_value(ft1000dev);
					//DEBUG("FT1000:word_length = 0x%x\n", (int)word_length);
					//NdisMSleep (100);
					if (word_length > MAX_LENGTH) {
						DEBUG
						    ("FT1000:download:Download error: Max length exceeded\n");
						status = STATUS_FAILURE;
						break;
					}
					if ((word_length * 2 + c_file) >
					    boot_end) {
						/*
						 * Error, beyond boot code range.
						 */
						DEBUG
						    ("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n",
						     (int)word_length);
						status = STATUS_FAILURE;
						break;
					}
					/*
					 * Position ASIC DPRAM auto-increment pointer.
					 */
					dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
					if (word_length & 0x1)
						word_length++;
					word_length = word_length / 2;

					status =
					    write_blk(ft1000dev, &s_file,
						      &c_file, word_length);
					//DEBUG("write_blk returned %d\n", status);
					break;
				default:
					DEBUG
					    ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",
					     request);
					status = STATUS_FAILURE;
					break;
				}
				if (pft1000info->usbboot)
					put_handshake_usb(ft1000dev,
							  HANDSHAKE_RESPONSE);
				else
					put_handshake(ft1000dev,
						      HANDSHAKE_RESPONSE);
			} else {
				DEBUG
				    ("FT1000:download:Download error: Handshake failed\n");
				status = STATUS_FAILURE;
			}

			break;

		case STATE_CODE_DWNLD:
			//DEBUG("FT1000:STATE_CODE_DWNLD\n");
			pft1000info->bootmode = 0;
			if (pft1000info->usbboot)
				handshake =
				    get_handshake_usb(ft1000dev,
						      HANDSHAKE_REQUEST);
			else
				handshake =
				    get_handshake(ft1000dev, HANDSHAKE_REQUEST);
			if (handshake == HANDSHAKE_REQUEST) {
				/*
				 * Get type associated with the request.
				 */
				if (pft1000info->usbboot)
					request =
					    get_request_type_usb(ft1000dev);
				else
					request = get_request_type(ft1000dev);
				switch (request) {
				case REQUEST_FILE_CHECKSUM:
					DEBUG
					    ("FT1000:download:image_chksum = 0x%8x\n",
					     image_chksum);
					put_request_value(ft1000dev,
							  image_chksum);
					break;
				case REQUEST_RUN_ADDRESS:
					DEBUG
					    ("FT1000:download:  REQUEST_RUN_ADDRESS\n");
					if (correct_version) {
						DEBUG
						    ("FT1000:download:run_address = 0x%8x\n",
						     (int)run_address);
						put_request_value(ft1000dev,
								  run_address);
					} else {
						DEBUG
						    ("FT1000:download:Download error: Got Run address request before image offset request.\n");
						status = STATUS_FAILURE;
						break;
					}
					break;
				case REQUEST_CODE_LENGTH:
					DEBUG
					    ("FT1000:download:REQUEST_CODE_LENGTH\n");
					if (correct_version) {
						DEBUG
						    ("FT1000:download:run_size = 0x%8x\n",
						     (int)run_size);
						put_request_value(ft1000dev,
								  run_size);
					} else {
						DEBUG
						    ("FT1000:download:Download error: Got Size request before image offset request.\n");
						status = STATUS_FAILURE;
						break;
					}
					break;
				case REQUEST_DONE_CL:
					pft1000info->usbboot = 3;
					/* Reposition ptrs to beginning of provisioning section */
					s_file =
					    (u16 *) (pFileStart +
						     file_hdr->commands_offset);
					c_file =
					    (u8 *) (pFileStart +
						    file_hdr->commands_offset);
					state = STATE_DONE_DWNLD;
					break;
				case REQUEST_CODE_SEGMENT:
					//DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n");
					if (!correct_version) {
						DEBUG
						    ("FT1000:download:Download error: Got Code Segment request before image offset request.\n");
						status = STATUS_FAILURE;
						break;
					}

					word_length =
					    get_request_value(ft1000dev);
					//DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
					if (word_length > MAX_LENGTH) {
						DEBUG
						    ("FT1000:download:Download error: Max length exceeded\n");
						status = STATUS_FAILURE;
						break;
					}
					if ((word_length * 2 + c_file) >
					    code_end) {
						/*
						 * Error, beyond boot code range.
						 */
						DEBUG
						    ("FT1000:download:Download error: Requested len=%d exceeds DSP code boundary.\n",
						     (int)word_length);
						status = STATUS_FAILURE;
						break;
					}
					/*
					 * Position ASIC DPRAM auto-increment pointer.
					 */
					dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
					if (word_length & 0x1)
						word_length++;
					word_length = word_length / 2;

					write_blk_fifo(ft1000dev, &s_file,
						       &c_file, word_length);
					if (pft1000info->usbboot == 0)
						pft1000info->usbboot++;
					if (pft1000info->usbboot == 1) {
						tempword = 0;
						ft1000_write_dpram16(ft1000dev,
								     DWNLD_MAG1_PS_HDR_LOC,
								     tempword,
								     0);
					}

					break;

				case REQUEST_MAILBOX_DATA:
					DEBUG
					    ("FT1000:download: REQUEST_MAILBOX_DATA\n");
					// Convert length from byte count to word count. Make sure we round up.
					word_length =
					    (long)(pft1000info->DSPInfoBlklen +
						   1) / 2;
					put_request_value(ft1000dev,
							  word_length);
					mailbox_data =
					    (struct drv_msg *)&(pft1000info->
								DSPInfoBlk[0]);
					/*
					 * Position ASIC DPRAM auto-increment pointer.
					 */

					data = (u16 *) & mailbox_data->data[0];
					dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
					if (word_length & 0x1)
						word_length++;

					word_length = (word_length / 2);

					for (; word_length > 0; word_length--) {	/* In words */

						templong = *data++;
						templong |= (*data++ << 16);
						status =
						    fix_ft1000_write_dpram32
						    (ft1000dev, dpram++,
						     (u8 *) & templong);

					}
					break;

				case REQUEST_VERSION_INFO:
					DEBUG
					    ("FT1000:download:REQUEST_VERSION_INFO\n");
					word_length =
					    file_hdr->version_data_size;
					put_request_value(ft1000dev,
							  word_length);
					/*
					 * Position ASIC DPRAM auto-increment pointer.
					 */

					s_file =
					    (u16 *) (pFileStart +
						     file_hdr->
						     version_data_offset);

					dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
					if (word_length & 0x1)
						word_length++;

					word_length = (word_length / 2);

					for (; word_length > 0; word_length--) {	/* In words */

						templong = ntohs(*s_file++);
						temp = ntohs(*s_file++);
						templong |= (temp << 16);
						status =
						    fix_ft1000_write_dpram32
						    (ft1000dev, dpram++,
						     (u8 *) & templong);

					}
					break;

				case REQUEST_CODE_BY_VERSION:
					DEBUG
					    ("FT1000:download:REQUEST_CODE_BY_VERSION\n");
					correct_version = FALSE;
					requested_version =
					    get_request_value(ft1000dev);

					dsp_img_info =
					    (struct dsp_image_info *)(pFileStart
								      +
								      sizeof
								      (struct
								       dsp_file_hdr));

					for (image = 0;
					     image < file_hdr->nDspImages;
					     image++) {

						if (dsp_img_info->version ==
						    requested_version) {
							correct_version = TRUE;
							DEBUG
							    ("FT1000:download: correct_version is TRUE\n");
							s_file =
							    (u16 *) (pFileStart
								     +
								     dsp_img_info->
								     begin_offset);
							c_file =
							    (u8 *) (pFileStart +
								    dsp_img_info->
								    begin_offset);
							code_end =
							    (u8 *) (pFileStart +
								    dsp_img_info->
								    end_offset);
							run_address =
							    dsp_img_info->
							    run_address;
							run_size =
							    dsp_img_info->
							    image_size;
							image_chksum =
							    (u32) dsp_img_info->
							    checksum;
							break;
						}
						dsp_img_info++;

					}	//end of for

					if (!correct_version) {
						/*
						 * Error, beyond boot code range.
						 */
						DEBUG
						    ("FT1000:download:Download error: Bad Version Request = 0x%x.\n",
						     (int)requested_version);
						status = STATUS_FAILURE;
						break;
					}
					break;

				default:
					DEBUG
					    ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",
					     request);
					status = STATUS_FAILURE;
					break;
				}
				if (pft1000info->usbboot)
					put_handshake_usb(ft1000dev,
							  HANDSHAKE_RESPONSE);
				else
					put_handshake(ft1000dev,
						      HANDSHAKE_RESPONSE);
			} else {
				DEBUG
				    ("FT1000:download:Download error: Handshake failed\n");
				status = STATUS_FAILURE;
			}

			break;

		case STATE_DONE_DWNLD:
			DEBUG("FT1000:download:Code loader is done...\n");
			state = STATE_SECTION_PROV;
			break;

		case STATE_SECTION_PROV:
			DEBUG("FT1000:download:STATE_SECTION_PROV\n");
			pseudo_header = (struct pseudo_hdr *)c_file;

			if (pseudo_header->checksum ==
			    hdr_checksum(pseudo_header)) {
				if (pseudo_header->portdest !=
				    0x80 /* Dsp OAM */ ) {
					state = STATE_DONE_PROV;
					break;
				}
				pseudo_header_len = ntohs(pseudo_header->length);	/* Byte length for PROV records */

				// Get buffer for provisioning data
				pbuffer =
				    kmalloc((pseudo_header_len +
					     sizeof(struct pseudo_hdr)),
					    GFP_ATOMIC);
				if (pbuffer) {
					memcpy(pbuffer, (void *)c_file,
					       (u32) (pseudo_header_len +
						      sizeof(struct
							     pseudo_hdr)));
					// link provisioning data
					pprov_record =
					    kmalloc(sizeof(struct prov_record),
						    GFP_ATOMIC);
					if (pprov_record) {
						pprov_record->pprov_data =
						    pbuffer;
						list_add_tail(&pprov_record->
							      list,
							      &pft1000info->
							      prov_list);
						// Move to next entry if available
						c_file =
						    (u8 *) ((unsigned long)
							    c_file +
							    (u32) ((pseudo_header_len + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr));
						if ((unsigned long)(c_file) -
						    (unsigned long)(pFileStart)
						    >=
						    (unsigned long)FileLength) {
							state = STATE_DONE_FILE;
						}
					} else {
						kfree(pbuffer);
						status = STATUS_FAILURE;
					}
				} else {
					status = STATUS_FAILURE;
				}
			} else {
				/* Checksum did not compute */
				status = STATUS_FAILURE;
			}
			DEBUG
			    ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n",
			     state, status);
			break;

		case STATE_DONE_PROV:
			DEBUG("FT1000:download:STATE_DONE_PROV\n");
			state = STATE_DONE_FILE;
			break;

		default:
			status = STATUS_FAILURE;
			break;
		}		/* End Switch */

		if (status != STATUS_SUCCESS) {
			break;
		}

/****
      // Check if Card is present
      status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK);
      if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) {
          break;
      }

      status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID);
      if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) {
          break;
      }
****/

	}			/* End while */

	DEBUG("Download exiting with status = 0x%8x\n", status);
	ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX,
			      FT1000_REG_DOORBELL);

	return status;
}
Exemplo n.º 5
0
/* Parse a stage backup header.
 * If tag is non-NULL, *tag should contain the first byte (already read),
 * and will be filled in with the first byte after the header, if one exists.
 * On success, returns 0 and leaves us positioned after the header
 * On failure, returns an error and position is undefined
 * Iff there is no header, returns DSERR_MAGIC and leaves us
 * positioned where we started.
 */
afs_uint32
ParseStageHdr(XFILE * X, unsigned char *tag, backup_system_header * hdr)
{
    char buf[STAGE_HDRLEN];
    struct stage_header *bckhdr = (struct stage_header *)buf;
    u_int64 where;
    afs_int32 r;

    if ((r = xftell(X, &where)))
	return r;
    if (hdr)
	memset(hdr, 0, sizeof(*hdr));
    if (tag) {
	if (*tag != STAGE_VERSMIN)
	    return DSERR_MAGIC;
	buf[0] = *tag;
	r = xfread(X, buf + 1, STAGE_HDRLEN - 1);
    } else {
	r = xfread(X, buf, STAGE_HDRLEN);
    }

    if (r == ERROR_XFILE_EOF) {
	r = xfseek(X, &where);
	return r ? r : DSERR_MAGIC;
    } else if (r)
	return r;

    if (bckhdr->c_vers < STAGE_VERSMIN
	|| ntohl(bckhdr->c_magic) != STAGE_MAGIC
	|| hdr_checksum(buf, STAGE_HDRLEN) != STAGE_CHECKSUM) {
	r = xfseek(X, &where);
	return r ? r : DSERR_MAGIC;
    }

    if (hdr) {
	hdr->version = bckhdr->c_vers;
	hdr->from_date = ntohl(bckhdr->c_fdate);
	hdr->to_date = ntohl(bckhdr->c_tdate);
	hdr->dump_date = ntohl(bckhdr->c_time);
	hdr->filenum = ntohl(bckhdr->c_filenum);
	hdr->volid = ntohl(bckhdr->c_id);
#ifdef NATIVE_INT64
	hdr->dumplen = ntohl(bckhdr->c_length);
#else
        hdr->dumplen.hi = 0;
        hdr->dumplen.lo = ntohl(bckhdr->c_length);
#endif
	hdr->level = ntohl(bckhdr->c_level);
	hdr->magic = ntohl(bckhdr->c_magic);
	hdr->cksum = ntohl(bckhdr->c_checksum);
	hdr->flags = ntohl(bckhdr->c_flags);
	hdr->server = malloc(strlen(bckhdr->c_host) + 1);
	hdr->part = malloc(strlen(bckhdr->c_disk) + 1);
	hdr->volname = malloc(strlen(bckhdr->c_name) + 1);

	if (!hdr->server || !hdr->part || !hdr->volname) {
	    if (hdr->server)
		free(hdr->server);
	    if (hdr->part)
		free(hdr->part);
	    if (hdr->volname)
		free(hdr->volname);
	    return ENOMEM;
	}
	strcpy((char *)hdr->server, bckhdr->c_host);
	strcpy((char *)hdr->part, bckhdr->c_disk);
	strcpy((char *)hdr->volname, bckhdr->c_name);
    }

    if (tag)
	return ReadByte(X, tag);
    else
	return 0;
}