Пример #1
0
void system_disable_jump(void)
{
	disable_jump = 1;

#ifdef CONFIG_MPU
	if (system_is_locked()) {
		int ret;
		int enable_mpu = 0;
		enum system_image_copy_t copy;

		CPRINTS("MPU type: %08x", mpu_get_type());
		/*
		 * Protect RAM from code execution
		 */
		ret = mpu_protect_ram();
		if (ret == EC_SUCCESS) {
			enable_mpu = 1;
			CPRINTS("RAM locked. Exclusion %08x-%08x",
				&__iram_text_start, &__iram_text_end);
		} else {
			CPRINTS("Failed to lock RAM (%d)", ret);
		}

		/*
		 * Protect inactive image (ie. RO if running RW, vice versa)
		 * from code execution.
		 */
		switch (system_get_image_copy()) {
		case SYSTEM_IMAGE_RO:
			ret =  mpu_lock_rw_flash();
			copy = SYSTEM_IMAGE_RW;
			break;
		case SYSTEM_IMAGE_RW:
			ret =  mpu_lock_ro_flash();
			copy = SYSTEM_IMAGE_RO;
			break;
		default:
			copy = SYSTEM_IMAGE_UNKNOWN;
			ret = !EC_SUCCESS;
		}
		if (ret == EC_SUCCESS) {
			enable_mpu = 1;
			CPRINTS("%s image locked",
				system_image_copy_t_to_string(copy));
		} else {
			CPRINTS("Failed to lock %s image (%d)",
				system_image_copy_t_to_string(copy), ret);
		}

		if (enable_mpu)
			mpu_enable();
	} else {
		CPRINTS("System is unlocked. Skip MPU configuration");
	}
#endif
}
Пример #2
0
int system_run_image_copy(enum system_image_copy_t copy)
{
	uintptr_t base;
	uintptr_t init_addr;

	/* If system is already running the requested image, done */
	if (system_get_image_copy() == copy)
		return EC_SUCCESS;

	if (system_is_locked()) {
		/* System is locked, so disallow jumping between images unless
		 * this is the initial jump from RO to RW code. */

		/* Must currently be running the RO image */
		if (system_get_image_copy() != SYSTEM_IMAGE_RO)
			return EC_ERROR_ACCESS_DENIED;

		/* Target image must be RW image */
		if (copy != SYSTEM_IMAGE_RW)
			return EC_ERROR_ACCESS_DENIED;

		/* Jumping must still be enabled */
		if (disable_jump)
			return EC_ERROR_ACCESS_DENIED;
	}

	/* Load the appropriate reset vector */
	base = get_base(copy);
	if (base == 0xffffffff)
		return EC_ERROR_INVAL;

	/* TODO: (ML) jump to little FW for code ram architecture */
#ifdef CONFIG_CODERAM_ARCH
	init_addr = system_get_lfw_address(base);
#else
	/* Make sure the reset vector is inside the destination image */
	init_addr = *(uintptr_t *)(base + 4);
#ifndef EMU_BUILD
	if (init_addr < base || init_addr >= base + get_size(copy))
		return EC_ERROR_UNKNOWN;
#endif
#endif

	CPRINTS("Jumping to image %s", system_image_copy_t_to_string(copy));

	jump_to_image(init_addr);

	/* Should never get here */
	return EC_ERROR_UNKNOWN;
}
Пример #3
0
const char *system_get_image_copy_string(void)
{
	return system_image_copy_t_to_string(system_get_image_copy());
}
Пример #4
0
int system_run_image_copy(enum system_image_copy_t copy)
{
	uintptr_t base;
	uintptr_t init_addr;
#ifdef CONFIG_REPLACE_LOADER_WITH_BSS_SLOW
	uint8_t *buf;
	uint32_t offset;
	uint32_t bytes_to_load;
	int rv;
#endif /* defined(CONFIG_REPLACE_LOADER_WITH_BSS_SLOW) */

	/* If system is already running the requested image, done */
	if (system_get_image_copy() == copy)
		return EC_SUCCESS;

	if (system_is_locked()) {
		/* System is locked, so disallow jumping between images unless
		 * this is the initial jump from RO to RW code. */

		/* Must currently be running the RO image */
		if (system_get_image_copy() != SYSTEM_IMAGE_RO)
			return EC_ERROR_ACCESS_DENIED;

		/* Target image must be RW image */
		if (copy != SYSTEM_IMAGE_RW)
			return EC_ERROR_ACCESS_DENIED;

		/* Jumping must still be enabled */
		if (disable_jump)
			return EC_ERROR_ACCESS_DENIED;
	}

	/* Load the appropriate reset vector */
	base = get_program_memory_addr(copy);
	if (base == 0xffffffff)
		return EC_ERROR_INVAL;

#ifdef CONFIG_EXTERNAL_STORAGE
#ifdef CONFIG_REPLACE_LOADER_WITH_BSS_SLOW
	/*
	 * We've used the region in which the loader resided as data space for
	 * the .bss.slow section.  Therefore, we need to reload the loader from
	 * the external storage back into program memory so that we can load a
	 * different image.
	 */
	buf = (uint8_t *)(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_LOADER_MEM_OFF);
	bytes_to_load = CONFIG_LOADER_SIZE;
	offset = CONFIG_EC_PROTECTED_STORAGE_OFF + CONFIG_LOADER_STORAGE_OFF;

	rv = flash_read(offset, bytes_to_load, buf);
	if (rv)
		return rv;
#endif /* defined(CONFIG_REPLACE_LOADER_WITH_BSS_SLOW) */

	/* Jump to loader */
	init_addr = system_get_lfw_address();

	system_set_image_copy(copy);
#else
#ifdef CONFIG_FW_RESET_VECTOR
	/* Get reset vector */
	init_addr = system_get_fw_reset_vector(base);
#else
#if defined(CONFIG_RO_HEAD_ROOM)
	/* Skip any head room in the RO image */
	if (copy == SYSTEM_IMAGE_RO)
		/* Don't change base, though! */
		init_addr = *(uintptr_t *)(base + CONFIG_RO_HEAD_ROOM + 4);
	else
#endif
	init_addr = *(uintptr_t *)(base + 4);
#endif
#ifndef EMU_BUILD
	/* Make sure the reset vector is inside the destination image */
	if (init_addr < base || init_addr >= base + get_size(copy))
		return EC_ERROR_UNKNOWN;
#endif
#endif

	CPRINTS("Jumping to image %s", system_image_copy_t_to_string(copy));

	jump_to_image(init_addr);

	/* Should never get here */
	return EC_ERROR_UNKNOWN;
}