Esempio n. 1
0
File: system.c Progetto: thehobn/ec
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;
}
Esempio n. 2
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;
}