Esempio n. 1
0
static int stm32x_protect_check(struct flash_bank *bank)
{
	struct target *target = bank->target;
	struct stm32x_flash_bank *stm32x_info = bank->driver_priv;

	uint32_t protection;
	int i, s;
	int num_bits;
	int set;

	if (target->state != TARGET_HALTED)
	{
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	int retval = stm32x_check_operation_supported(bank);
	if (ERROR_OK != retval)
		return retval;

	/* medium density - each bit refers to a 4bank protection
	 * high density - each bit refers to a 2bank protection */
	retval = target_read_u32(target, STM32_FLASH_WRPR, &protection);
	if (retval != ERROR_OK)
		return retval;

	/* medium density - each protection bit is for 4 * 1K pages
	 * high density - each protection bit is for 2 * 2K pages */
	num_bits = (bank->num_sectors / stm32x_info->ppage_size);

	if (stm32x_info->ppage_size == 2)
	{
		/* high density flash/connectivity line protection */

		set = 1;

		if (protection & (1 << 31))
			set = 0;

		/* bit 31 controls sector 62 - 255 protection for high density
		 * bit 31 controls sector 62 - 127 protection for connectivity line */
		for (s = 62; s < bank->num_sectors; s++)
		{
			bank->sectors[s].is_protected = set;
		}

		if (bank->num_sectors > 61)
			num_bits = 31;

		for (i = 0; i < num_bits; i++)
		{
			set = 1;

			if (protection & (1 << i))
				set = 0;

			for (s = 0; s < stm32x_info->ppage_size; s++)
				bank->sectors[(i * stm32x_info->ppage_size) + s].is_protected = set;
		}
	}
	else
	{
		/* low/medium density flash protection */
		for (i = 0; i < num_bits; i++)
		{
			set = 1;

			if (protection & (1 << i))
				set = 0;

			for (s = 0; s < stm32x_info->ppage_size; s++)
				bank->sectors[(i * stm32x_info->ppage_size) + s].is_protected = set;
		}
	}

	return ERROR_OK;
}
Esempio n. 2
0
static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
{
	struct stm32x_flash_bank *stm32x_info = NULL;
	struct target *target = bank->target;
	uint16_t prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
	int i, reg, bit;
	int status;
	uint32_t protection;

	stm32x_info = bank->driver_priv;

	if (target->state != TARGET_HALTED)
	{
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	int retval = stm32x_check_operation_supported(bank);
	if (ERROR_OK != retval)
		return retval;

	if ((first % stm32x_info->ppage_size) != 0)
	{
		LOG_WARNING("aligned start protect sector to a %d sector boundary",
				stm32x_info->ppage_size);
		first = first - (first % stm32x_info->ppage_size);
	}
	if (((last + 1) % stm32x_info->ppage_size) != 0)
	{
		LOG_WARNING("aligned end protect sector to a %d sector boundary",
				stm32x_info->ppage_size);
		last++;
		last = last - (last % stm32x_info->ppage_size);
		last--;
	}

	/* medium density - each bit refers to a 4bank protection
	 * high density - each bit refers to a 2bank protection */
	retval = target_read_u32(target, STM32_FLASH_WRPR, &protection);
	if (retval != ERROR_OK)
		return retval;

	prot_reg[0] = (uint16_t)protection;
	prot_reg[1] = (uint16_t)(protection >> 8);
	prot_reg[2] = (uint16_t)(protection >> 16);
	prot_reg[3] = (uint16_t)(protection >> 24);

	if (stm32x_info->ppage_size == 2)
	{
		/* high density flash */

		/* bit 7 controls sector 62 - 255 protection */
		if (last > 61)
		{
			if (set)
				prot_reg[3] &= ~(1 << 7);
			else
				prot_reg[3] |= (1 << 7);
		}

		if (first > 61)
			first = 62;
		if (last > 61)
			last = 61;

		for (i = first; i <= last; i++)
		{
			reg = (i / stm32x_info->ppage_size) / 8;
			bit = (i / stm32x_info->ppage_size) - (reg * 8);

			if (set)
				prot_reg[reg] &= ~(1 << bit);
			else
				prot_reg[reg] |= (1 << bit);
		}
	}
	else
	{
		/* medium density flash */
		for (i = first; i <= last; i++)
		{
			reg = (i / stm32x_info->ppage_size) / 8;
			bit = (i / stm32x_info->ppage_size) - (reg * 8);

			if (set)
				prot_reg[reg] &= ~(1 << bit);
			else
				prot_reg[reg] |= (1 << bit);
		}
	}

	if ((status = stm32x_erase_options(bank)) != ERROR_OK)
		return status;

	stm32x_info->option_bytes.protection[0] = prot_reg[0];
	stm32x_info->option_bytes.protection[1] = prot_reg[1];
	stm32x_info->option_bytes.protection[2] = prot_reg[2];
	stm32x_info->option_bytes.protection[3] = prot_reg[3];

	return stm32x_write_options(bank);
}
Esempio n. 3
0
/////////////////////////////////////////////////////////////////////////////
// Here begins the standard command set. These commands will be the main
//  interface to the part and are the heart of the flash driver. There will be
//  an entry for each of these in the flash_driver structure at the end of
//  this file. Reference:
// http://openocd.berlios.de/doc/doxygen/html/structflash__driver.html#aa4fda4f0ea001af0b75d7b9ca879b0d0
//
// It is required that these functions (described in the flash_driver structure)
//  exist and be entered int the flash_driver structure. Weird segmentation faults
//  may result otherwise (guess how I know).
//
// protect_check is the first of these functions, although they can be defined
//  in any order. protect_check checks each protection region in a specified bank
//  to see if it is protected in hardware. An appropriate entry is made in the 
//  sectors array in the bank structure.
// The algorithm for checking protection is specific to each device and
//  must be custom. That's why it's in the flash_driver!. Indeed, some devices
//  might not have this sort of protection at all. As mentioned above, the function
//  still must exist, even if it just returns.
static int stm32x_protect_check(struct flash_bank *bank)
{
	// Note the method of obtaining the target name from the bank structure.
	//  the target name is used in calls that read and write specific registers.
	struct target *target = bank->target;

	// This is the standard method of obtaining the pointer to the private
	//  data structure so that the private data can be accessed.
	struct stm32x_flash_bank *stm32x_info = bank->driver_priv;

	uint32_t protection;
	int i, s;
	int num_bits;
	int set;

	if (target->state != TARGET_HALTED)
	{
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	// stm32x specific function call
	int retval = stm32x_check_operation_supported(bank);
	if (ERROR_OK != retval)
		return retval;

	// The target_read_u32 is very commonly used to read specific registers
	//  for a device. The error code should always be checked.
	/* medium density - each bit refers to a 4bank protection
	 * high density - each bit refers to a 2bank protection */
	retval = target_read_u32(target, STM32_FLASH_WRPR, &protection);
	if (retval != ERROR_OK)
		return retval;

	/* medium density - each protection bit is for 4 * 1K pages
	 * high density - each protection bit is for 2 * 2K pages */
	num_bits = (bank->num_sectors / stm32x_info->ppage_size);

	if (stm32x_info->ppage_size == 2)
	{
		/* high density flash/connectivity line protection */

		set = 1;

		if (protection & (1 << 31))
			set = 0;

		/* bit 31 controls sector 62 - 255 protection for high density
		 * bit 31 controls sector 62 - 127 protection for connectivity line */
		for (s = 62; s < bank->num_sectors; s++)
		{
			bank->sectors[s].is_protected = set;
		}

		if (bank->num_sectors > 61)
			num_bits = 31;

		for (i = 0; i < num_bits; i++)
		{
			set = 1;

			if (protection & (1 << i))
				set = 0;

			for (s = 0; s < stm32x_info->ppage_size; s++)
				bank->sectors[(i * stm32x_info->ppage_size) + s].is_protected = set;
		}
	}
	else
	{
		/* low/medium density flash protection */
		for (i = 0; i < num_bits; i++)
		{
			set = 1;

			if (protection & (1 << i))
				set = 0;

			for (s = 0; s < stm32x_info->ppage_size; s++)
				bank->sectors[(i * stm32x_info->ppage_size) + s].is_protected = set;
		}
	}

	return ERROR_OK;
}