Example #1
0
char blackbox_read(blackbox_frame *frame, char *data)
{
    uchar type = 0;

    // The first byte must be a start byte
    if (flash_read_uchar(blackbox_offset) != BLACKBOX_FRAME_START)
        return -1;

    // Read and validate the type 
    type = flash_read_uchar(blackbox_offset + 1);
    if ((type != BLACKBOX_FRAME_TYPE_INFO)      &&
            (type != BLACKBOX_FRAME_TYPE_ERROR) &&
            (type != BLACKBOX_FRAME_TYPE_ADC))
        return -2;

    // Read tick
    uint32_t tick = flash_read_uint32(blackbox_offset + 2);

    // Read the data length
    uchar data_length = flash_read_uchar(blackbox_offset + 6);

    // The last byte must be an end byte
    if (flash_read_uchar(blackbox_offset + data_length + 7) != BLACKBOX_FRAME_END)
        return -3;

    // If we didn't fail yet, we are good to go
    frame->type = type;
    frame->tick = tick;
    frame->data_length = data_length;
    flash_read(data, data_length, blackbox_offset + 7);     // Read actual data
    blackbox_offset += data_length + 8;                     // Prepare for next read

    return 0;
}
/*
 * read jedec ids from device and set corresponding fields in info struct
 *
 * Note: assume cfi->vendor, cfi->portwidth and cfi->chipwidth are correct
 *
*/
static void amd_read_jedec_ids(struct flash_info *info)
{
	info->cmd_reset		= AMD_CMD_RESET;
	info->manufacturer_id = 0;
	info->device_id       = 0;
	info->device_id2      = 0;

	/* calculate command offsets as in the Linux driver */
	info->addr_unlock1 = 0x555;
	info->addr_unlock2 = 0x2AA;

	/*
	 * modify the unlock address if we are in compatibility mode
	 */
	if (	/* x8/x16 in x8 mode */
		((info->chipwidth == FLASH_CFI_BY8) &&
			(info->interface == FLASH_CFI_X8X16)) ||
		/* x16/x32 in x16 mode */
		((info->chipwidth == FLASH_CFI_BY16) &&
			(info->interface == FLASH_CFI_X16X32)))
	{
		info->addr_unlock1 = 0xaaa;
		info->addr_unlock2 = 0x555;
	}

	flash_write_cmd(info, 0, 0, info->cmd_reset);
	flash_unlock_seq(info);
	flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);
	udelay(1000); /* some flash are slow to respond */

	info->manufacturer_id = jedec_read_mfr(info);
	info->device_id = flash_read_uchar(info,
					FLASH_OFFSET_DEVICE_ID);
	if (info->device_id == 0x7E) {
		/* AMD 3-byte (expanded) device ids */
		info->device_id2 = flash_read_uchar(info,
					FLASH_OFFSET_DEVICE_ID2);
		info->device_id2 <<= 8;
		info->device_id2 |= flash_read_uchar(info,
					FLASH_OFFSET_DEVICE_ID3);
	}
	flash_write_cmd(info, 0, 0, info->cmd_reset);
}
/*
 * read jedec ids from device and set corresponding fields in info struct
 *
 * Note: assume cfi->vendor, cfi->portwidth and cfi->chipwidth are correct
 *
*/
static void amd_read_jedec_ids (struct flash_info *info)
{
	info->manufacturer_id = 0;
	info->device_id       = 0;
	info->device_id2      = 0;

	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
	flash_unlock_seq(info);
	flash_write_cmd(info, 0, AMD_ADDR_START, FLASH_CMD_READ_ID);
	udelay(1000); /* some flash are slow to respond */
	info->manufacturer_id = flash_read_uchar (info,
					FLASH_OFFSET_MANUFACTURER_ID);
	info->device_id = flash_read_uchar (info,
					FLASH_OFFSET_DEVICE_ID);
	if (info->device_id == 0x7E) {
		/* AMD 3-byte (expanded) device ids */
		info->device_id2 = flash_read_uchar (info,
					FLASH_OFFSET_DEVICE_ID2);
		info->device_id2 <<= 8;
		info->device_id2 |= flash_read_uchar (info,
					FLASH_OFFSET_DEVICE_ID3);
	}
	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
}
Example #4
0
/*
 * The following code cannot be run from FLASH!
 *
 */
static ulong flash_get_size(ulong base, int banknum)
{
	flash_info_t *info = &flash_info[banknum];
	int i, j;
	int sect_cnt;
	unsigned long sector;
	unsigned long tmp;
	int size_ratio = 0;
	uchar num_erase_regions;
	int erase_region_size;
	int erase_region_count;

	info->start[0] = base;
#if 0
	invalidate_dcache_range(base, base + 0x400);
#endif
	if (flash_detect_cfi(info)) {

		size_ratio = info->portwidth / info->chipwidth;
		num_erase_regions =
		    flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS);

		sect_cnt = 0;
		sector = base;
		for (i = 0; i < num_erase_regions; i++) {
			if (i > NUM_ERASE_REGIONS) {
				printf("%d erase regions found, only %d used\n",
				       num_erase_regions, NUM_ERASE_REGIONS);
				break;
			}
			tmp =
			    flash_read_long(info, 0,
					    FLASH_OFFSET_ERASE_REGIONS);
			erase_region_size =
			    (tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
			tmp >>= 16;
			erase_region_count = (tmp & 0xffff) + 1;
			for (j = 0; j < erase_region_count; j++) {
				info->start[sect_cnt] = sector;
				sector += (erase_region_size * size_ratio);
				info->protect[sect_cnt] =
				    flash_isset(info, sect_cnt,
						FLASH_OFFSET_PROTECT,
						FLASH_STATUS_PROTECT);
				sect_cnt++;
			}
		}

		info->sector_count = sect_cnt;
		/* multiply the size by the number of chips */
		info->size =
		    (1 << flash_read_uchar(info, FLASH_OFFSET_SIZE)) *
		    size_ratio;
		info->buffer_size =
		    (1 << flash_read_ushort(info, 0, FLASH_OFFSET_BUFFER_SIZE));
		tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_ETOUT);
		info->erase_blk_tout =
		    (tmp *
		     (1 << flash_read_uchar(info, FLASH_OFFSET_EMAX_TOUT)));
		tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WBTOUT);
		info->buffer_write_tout =
		    (tmp *
		     (1 << flash_read_uchar(info, FLASH_OFFSET_WBMAX_TOUT)));
		tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WTOUT);
		info->write_tout =
		    (tmp *
		     (1 << flash_read_uchar(info, FLASH_OFFSET_WMAX_TOUT))) /
		    1000;
		info->flash_id = FLASH_MAN_CFI;
	}

	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
#ifdef DEBUG_FLASH
	printf("portwidth=%d chipwidth=%d\n", info->portwidth, info->chipwidth);	/* test-only */
#endif
#ifdef DEBUG_FLASH
	printf("found %d erase regions\n", num_erase_regions);
#endif
#ifdef DEBUG_FLASH
	printf("size=%08x sectors=%08x \n", info->size, info->sector_count);
#endif
	return (info->size);
}