static int do_vbexport_test_diskinfo_flags(uint32_t flags)
{
	int ret = 0;
	VbDiskInfo *info;
	uint32_t count, i;

	ret = VbExDiskGetInfo(&info, &count, flags);
	if (ret)
		return ret;

	if (count == 0) {
		VbExDebug("No disk found!\n");
	} else {
		VbExDebug("handle    byte/lba  lba_count  f  name\n");
		for (i = 0; i < count; i++) {
			VbExDebug("%08lx  %-9llu %-10llu %-2lu %s",
					info[i].handle,
					info[i].bytes_per_lba,
					info[i].lba_count,
					info[i].flags,
					info[i].name);

			if ((flags & info[i].flags) != flags) {
				VbExDebug("    INCORRECT: flag mismatched\n");
				ret = 1;
			} else
				VbExDebug("\n");
		}
	}

	return VbExDiskFreeInfo(info, NULL) || ret;
}
static int do_vbexport_test_malloc_size(uint32_t size)
{
	char *mem = VbExMalloc(size);
	int i, line_size;

#if CONFIG_ARM
	line_size = dcache_get_line_size();
#elif defined CACHE_LINE_SIZE
	line_size = CACHE_LINE_SIZE;
#else
	line_size = __BIGGEST_ALIGNMENT__;
#endif

	VbExDebug("Trying to malloc a memory block for %lu bytes...", size);
	if ((uintptr_t)mem % line_size != 0) {
		VbExDebug("\nMemory not algined with a cache line!\n");
		VbExFree(mem);
		return 1;
	}
	for (i = 0; i < size; i++) {
		mem[i] = i % 0x100;
	}
	for (i = 0; i < size; i++) {
		if (mem[i] != i % 0x100) {
			VbExDebug("\nMemory verification failed!\n");
			VbExFree(mem);
			return 1;
		}
	}
	VbExFree(mem);
	VbExDebug(" - SUCCESS\n");
	return 0;
}
Esempio n. 3
0
static void vboot_wrapper(void *arg)
{
	VbError_t res;
	struct vboot_context *context;

	context = arg;
	gcontext = context;

	VbExDebug("Calling VbInit()\n");
	res = VbInit(context->cparams, &context->handoff->init_params);
	VbExDebug("VbInit() returned 0x%08x\n", res);

	if (res != VBERROR_SUCCESS) {
		if(res == VBERROR_TPM_REBOOT_REQUIRED) {
			VbExDebug("TPM Reboot Required. Proceeding reboot.\n");
			gcontext->reset();
		}
		return;
	}

	VbExDebug("Calling VbSelectFirmware()\n");
	res = VbSelectFirmware(context->cparams, context->fparams);
	VbExDebug("VbSelectFirmware() returned 0x%08x\n", res);

	if (res != VBERROR_SUCCESS)
		return;
}
static int do_vbexport_test_display(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	int ret = 0;
	uint32_t width, height;
	GoogleBinaryBlockHeader *gbbh;
	BmpBlockHeader *bmph;
	int screen = -1;
	int local = 0;

	if (argc > 1) {
		screen = simple_strtoul(argv[1], NULL, 10);
		if (argc > 2)
			local = simple_strtoul(argv[2], NULL, 10);
	}

	if (VbExDisplayInit(&width, &height)) {
		VbExDebug("Failed to init display.\n");
		return 1;
	}

	VbExDebug("The screen dimensions is %ldx%ld.\n", width, height);

	VbExDebug("Showing screens for localisation %d...\n", local);
	mdelay(500);
	if (screen == -1) {
		ret |= show_screen_and_delay(VB_SCREEN_BLANK);
		ret |= show_screen_and_delay(VB_SCREEN_DEVELOPER_WARNING);
		ret |= show_screen_and_delay(VB_SCREEN_DEVELOPER_EGG);
		ret |= show_screen_and_delay(VB_SCREEN_RECOVERY_REMOVE);
		ret |= show_screen_and_delay(VB_SCREEN_RECOVERY_INSERT);
		ret |= show_screen_and_delay(VB_SCREEN_RECOVERY_NO_GOOD);
		ret |= show_screen_and_delay(VB_SCREEN_WAIT);
	}

	gbbh = (GoogleBinaryBlockHeader *)read_gbb_from_firmware();
	if (gbbh) {
		bmph = (BmpBlockHeader *)((uint8_t *)gbbh + gbbh->bmpfv_offset);

		VbExDebug("Showing images...\n");
		if (screen != -1) {
			ret |= show_images_and_delay(bmph, local, screen);
		} else {
			for (screen = 0; screen < MAX_VALID_SCREEN_INDEX;
					screen++)
				ret |= show_images_and_delay(bmph, local,
							     screen);
		}
	} else {
		ret = 1;
	}

	VbExDebug("Showing debug info...\n");
	ret |= VbExDisplayDebugInfo("Hello!\n"
			"This is a debug message.\n"
			"Bye Bye!\n");

	return ret;
}
static int do_vbexport_test_diskinfo(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	int ret = 0;

	VbExDebug("Detecting all fixed disks...\n");
	ret |= do_vbexport_test_diskinfo_flags(VB_DISK_FLAG_FIXED);

	VbExDebug("\nDetecting all removable disks...\n");
	ret |= do_vbexport_test_diskinfo_flags(VB_DISK_FLAG_REMOVABLE);

	return ret;
}
static int do_vbexport_test_key(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	int ret = 0;
	uint32_t c = 0;

	VbExDebug("Press any key for test. Press Ctrl-C to exit...\n");
	while (c != KEY_CTRL_C) {
		c = VbExKeyboardRead();
		if (c)
			VbExDebug("Key pressed: 0x%02x\n", c);
	}

	return ret;
}
/**
 * need comment here
 */
static int show_images_and_delay(BmpBlockHeader *bmph, int local, int index)
{
	int i;
	ScreenLayout *screen;
	ImageInfo *image;

	screen = (ScreenLayout *)(bmph + 1);
	screen += local * bmph->number_of_screenlayouts;
	screen += index;

	for (i = 0;
	     i < MAX_IMAGE_IN_LAYOUT && screen->images[i].image_info_offset;
	     i++) {
		image = (ImageInfo *)((uint8_t *)bmph +
				screen->images[i].image_info_offset);
		if (show_image(image, screen->images[i].x,
				screen->images[i].y))
			goto bad;
	}

	VbExSleepMs(1000);
	return 0;

bad:
	VbExDebug("Failed to display image, screen=%lu, image=%d!\n", index, i);
	return 1;
}
static int do_vbexport_test_isshutdown(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	VbExDebug("Shutdown requested? %s\n",
			VbExIsShutdownRequested() ? "Yes" : "No");
	return 0;
}
static int do_vbexport_test_beep(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	int ret = 0;
	VbExDebug("Performing the beep tests...\n");
	ret |= do_vbexport_test_sleep_time(&beep_handler, 500);
	return ret;
}
static int show_screen_and_delay(uint32_t screen_type)
{
	if (VbExDisplayScreen(screen_type)) {
		VbExDebug("Failed to show a screen.\n");
		return 1;
	}

	VbExSleepMs(1000);
	return 0;
}
static uint8_t *read_gbb_from_firmware(void)
{
	void *fdt_ptr = (void *)gd->fdt_blob;
	firmware_storage_t file;
	struct twostop_fmap fmap;
	void *gbb;
	size_t gbb_size;

#ifndef CONFIG_HARDWARE_MAPPED_SPI
	gbb = cros_fdtdec_alloc_region(gd->fdt_blob,
			"google-binary-block", &gbb_size);
	if (!gbb) {
		VbExDebug("Failed to find gbb region!\n");
		return NULL;
	}
#endif

	if (cros_fdtdec_flashmap(fdt_ptr, &fmap)) {
		VbExDebug("Failed to load fmap config from fdt!\n");
		return NULL;
	}

	/* Open firmware storage device. */
	if (firmware_storage_open_spi(&file)) {
		VbExDebug("Failed to open firmware device!\n");
		return NULL;
	}

#ifdef CONFIG_HARDWARE_MAPPED_SPI
	{
		void *gbbp;

		if (gbb_init(&gbbp, &file, fmap.readonly.gbb.offset, 0)) {
			VbExDebug("Failed to read GBB!\n");
			return NULL;
		}
		gbb = gbbp;
		gbb_size = fmap.readonly.gbb.length;
	}
#else
	if (gbb_init(gbb, &file, fmap.readonly.gbb.offset, gbb_size)) {
		VbExDebug("Failed to read GBB!\n");
		return NULL;
	}
#endif

	if (gbb_read_bmp_block(gbb, &file, fmap.readonly.gbb.offset,
			       gbb_size)) {
		VbExDebug("Failed to load BMP Block in GBB!\n");
		return NULL;
	}

	if (file.close(&file)) {
		VbExDebug("Failed to close firmware device!\n");
	}

	return gbb;
}
Esempio n. 12
0
static void vboot_wrapper(void *arg)
{
	int i;
	VbError_t res;
	const struct components *components;
	struct vboot_context *context;

	context = arg;
	gcontext = context;

	VbExDebug("Calling VbInit()\n");
	res = VbInit(context->cparams, &context->handoff->init_params);
	VbExDebug("VbInit() returned 0x%08x\n", res);

	if (res != VBERROR_SUCCESS)
		return;

	VbExDebug("Calling VbSelectFirmware()\n");
	res = VbSelectFirmware(context->cparams, context->fparams);
	VbExDebug("VbSelectFirmware() returned 0x%08x\n", res);

	if (res != VBERROR_SUCCESS)
		return;

	/* Fix up the handoff structure. */
	context->handoff->selected_firmware =
		context->fparams->selected_firmware;

	/* Parse out the components for downstream consumption. */
	if (context->handoff->selected_firmware == VB_SELECT_FIRMWARE_A)
		components = (void *)context->fw_a;
	else if  (context->handoff->selected_firmware == VB_SELECT_FIRMWARE_B)
		components = (void *)context->fw_b;
	else
		return;

	for (i = 0; i < MAX_PARSED_FW_COMPONENTS; i++) {
		parse_component(components, i,
		                &context->handoff->components[i]);
	}
}
static int do_vbexport_test_nvclear(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	uint8_t zero_buf[VBNV_BLOCK_SIZE] = {0};

	if (VbExNvStorageWrite(zero_buf)) {
		VbExDebug("Failed to write nvstorage.\n");
		return 1;
	}

	return 0;
}
static int do_vbexport_test_nvrw(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	int ret = 0;
	uint8_t original_buf[VBNV_BLOCK_SIZE];
	uint8_t target_buf[VBNV_BLOCK_SIZE];
	uint8_t verify_buf[VBNV_BLOCK_SIZE];
	int i;

	for (i = 0; i < VBNV_BLOCK_SIZE; i++) {
		target_buf[i] = (0x27 + i) % 0x100;
	}

	if (VbExNvStorageRead(original_buf)) {
		VbExDebug("Failed to read nvstorage.\n");
		return 1;
	}

	if (VbExNvStorageWrite(target_buf)) {
		VbExDebug("Failed to write nvstorage.\n");
		ret = 1;
	} else {
		/* Read back and verify the data. */
		VbExNvStorageRead(verify_buf);
		if (memcmp(target_buf, verify_buf, VBNV_BLOCK_SIZE) != 0) {
			VbExDebug("Verify failed. The target data wrote "
				  "wrong.\n");
			ret = 1;
		}
	}

	/* Write the original data back. */
	VbExNvStorageWrite(original_buf);

	if (ret == 0)
		VbExDebug("Read and write nvstorage test SUCCESS.\n");

	return ret;
}
static int do_vbexport_test_sleep_time(sleep_handler_t handler, uint32_t msec)
{
	uint32_t start, end, delta, expected;
	VbExDebug("System is going to sleep for %lu ms...\n", msec);
	start = VbExGetTimer();
	(*handler)(msec);
	end = VbExGetTimer();
	delta = end - start;
	VbExDebug("From tick %lu to %lu (delta: %lu)", start, end, delta);

	expected = msec * CONFIG_SYS_HZ;
	/* The sleeping time should be accurate to within 10%. */
	if (delta > expected + expected / 10) {
		VbExDebug("\nSleep too long: expected %lu but actaully %lu!\n",
				expected, delta);
		return 1;
	} else if (delta < expected - expected / 10) {
		VbExDebug("\nSleep too short: expected %lu but actaully %lu!\n",
				expected, delta);
		return 1;
	}
	VbExDebug(" - SUCCESS\n");
	return 0;
}
static int do_vbexport_test_malloc(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	int ret = 0;
	VbExDebug("Performing the malloc/free tests...\n");
	ret |= do_vbexport_test_malloc_size(1);
	ret |= do_vbexport_test_malloc_size(2);
	ret |= do_vbexport_test_malloc_size(4);
	ret |= do_vbexport_test_malloc_size(8);
	ret |= do_vbexport_test_malloc_size(32);
	ret |= do_vbexport_test_malloc_size(1024);
	ret |= do_vbexport_test_malloc_size(4 * 1024);
	ret |= do_vbexport_test_malloc_size(32 * 1024);
	ret |= do_vbexport_test_malloc_size(1 * 1024 * 1024);
	ret |= do_vbexport_test_malloc_size(12345);
	ret |= do_vbexport_test_malloc_size(13579);
	return ret;
}
static int do_vbexport_test_all(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	int ret = 0;
	ret |= do_vbexport_test_debug(cmdtp, flag, argc, argv);
	ret |= do_vbexport_test_malloc(cmdtp, flag, argc, argv);
	ret |= do_vbexport_test_sleep(cmdtp, flag, argc, argv);
	ret |= do_vbexport_test_beep(cmdtp, flag, argc, argv);
	ret |= do_vbexport_test_diskinfo(cmdtp, flag, argc, argv);
	ret |= do_vbexport_test_diskrw(cmdtp, flag, argc, argv);
	ret |= do_vbexport_test_nvrw(cmdtp, flag, argc, argv);
	ret |= do_vbexport_test_key(cmdtp, flag, argc, argv);
	ret |= do_vbexport_test_display(cmdtp, flag, argc, argv);
	ret |= do_vbexport_test_isshutdown(cmdtp, flag, argc, argv);
	if (!ret)
		VbExDebug("All tests passed!\n");
	return ret;
}
Esempio n. 18
0
VbError_t VbExRegionRead(VbCommonParams *cparams,
                         enum vb_firmware_region region, uint32_t offset,
                         uint32_t size, void *buf)
{
	struct vboot_context *ctx;
	VbExDebug("VbExRegionRead: offset=%x size=%x, buf=%p\n",
	          offset, size, buf);
	ctx = cparams->caller_context;

	if (region == VB_REGION_GBB) {
		if (offset + size > cparams->gbb_size)
			return VBERROR_REGION_READ_INVALID;
		offset += ctx->gbb.offset_addr;
		if (ctx->get_region(offset, size, buf) == NULL)
			return VBERROR_REGION_READ_INVALID;
		return VBERROR_SUCCESS;
	}

	return VBERROR_UNSUPPORTED_REGION;
}
Esempio n. 19
0
void *VbExMalloc(size_t size)
{
	void *ptr;

	if (heap_current == NULL) {
		heap_current = &_heap[0];
		heap_size = &_eheap[0] - &_heap[0];
		VbExDebug("vboot heap: %p 0x%08x bytes\n",
		           heap_current, heap_size);
	}

	if (heap_size < size) {
		VbExError("vboot heap request cannot be fulfilled. "
		           "0x%08x available, 0x%08x requested\n",
		           heap_size, size);
	}

	ptr = heap_current;
	heap_size -= size;
	heap_current += size;

	return ptr;
}
static int do_vbexport_test_image(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	uint32_t width, height;
	GoogleBinaryBlockHeader *gbbh;
	BmpBlockHeader *bmph;
	ScreenLayout *screens;
	int snum, locale = 0;

	if (argc > 1)
		locale = simple_strtoul(argv[1], NULL, 10);

	if (VbExDisplayInit(&width, &height)) {
		VbExDebug("Failed to init display.\n");
		return 1;
	}

	gbbh = (GoogleBinaryBlockHeader *)read_gbb_from_firmware();
	if (!gbbh) {
		VbExDebug("Cannot read GBB\n");
		return 1;
	}

	bmph = (BmpBlockHeader *)((uint8_t *)gbbh + gbbh->bmpfv_offset);
	screens = (ScreenLayout *)(bmph + 1);

	VbExDebug("Total screen layouts: %d\n", bmph->number_of_screenlayouts);
	VbExDebug("Total localizations: %d\n", bmph->number_of_localizations);
	VbExDebug("Total images: %d\n", bmph->number_of_imageinfos);
	VbExDebug("bmpfv_offset=%#x, size=%#x\n", gbbh->bmpfv_offset,
		  gbbh->bmpfv_size);

	if (locale >= bmph->number_of_localizations) {
		VbExDebug("Selected localization is out of range\n");
		return 1;
	}

	/* Select the correct block */
	screens += locale * bmph->number_of_screenlayouts;

	for (snum = 0; snum < bmph->number_of_screenlayouts; snum++) {
		ScreenLayout *screen = &screens[snum];
		ImageInfo *image;
		int inum;

		VbExDebug("Screen: %d\n", snum);
		for (inum = 0; inum < MAX_IMAGE_IN_LAYOUT; inum++) {
			if (!screen->images[inum].image_info_offset)
				break;
			image = (ImageInfo *)((uint8_t *)bmph +
				screen->images[inum].image_info_offset);
			VbExDebug("   Image: %d at %d, %d: offset=%#x, "
				"size=%#x, end=%#x\n", inum,
				  screen->images[inum].x,
				  screen->images[inum].y,
				  gbbh->bmpfv_offset +
					screen->images[inum].image_info_offset,
				  image->compressed_size,
				  gbbh->bmpfv_offset +
				  screen->images[inum].image_info_offset +
					image->compressed_size);
			show_image(image, screen->images[inum].x,
				   screen->images[inum].y);
		}
		mdelay(500);
	}

	return 0;
}
static int do_vbexport_test_diskrw(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	int ret = 0;
	VbDiskInfo *disk_info;
	VbExDiskHandle_t handle;
	uint32_t disk_count, test_lba_count, buf_byte_count, i;
	uint8_t *original_buf, *target_buf, *verify_buf;
	uint64_t t0, t1;

	switch (argc) {
	case 1:  /* if no argument given, use the default lba count */
		test_lba_count = DEFAULT_TEST_LBA_COUNT;
		break;
	case 2:  /* use argument */
		test_lba_count = simple_strtoul(argv[1], NULL, 10);
		if (!test_lba_count) {
			VbExDebug("The first argument is not a number!\n");
			return cmd_usage(cmdtp);
		}
		break;
	default:
		return cmd_usage(cmdtp);
	}

	/* We perform read/write operations on the first internal disk. */
	if (VbExDiskGetInfo(&disk_info, &disk_count, VB_DISK_FLAG_FIXED) ||
			disk_count == 0) {
		VbExDebug("No internal disk found!\n");
		return 1;
	}
	handle = disk_info[0].handle;
	buf_byte_count = disk_info[0].bytes_per_lba * test_lba_count;
	VbExDiskFreeInfo(disk_info, handle);

	/* Allocate the buffer and fill the target test pattern. */
	original_buf = VbExMalloc(buf_byte_count);
	target_buf = VbExMalloc(buf_byte_count);
	verify_buf = VbExMalloc(buf_byte_count);

	/* Fill the target test pattern. */
	for (i = 0; i < buf_byte_count; i++)
		target_buf[i] = i & 0xff;

	t0 = VbExGetTimer();
	if (VbExDiskRead(handle, TEST_LBA_START, test_lba_count,
			original_buf)) {
		VbExDebug("Failed to read disk.\n");
		goto out;
	}
	t1 = VbExGetTimer();
	VbExDebug("test_diskrw: disk_read, lba_count: %u, time: %llu\n",
			test_lba_count, t1 - t0);

	t0 = VbExGetTimer();
	ret = VbExDiskWrite(handle, TEST_LBA_START, test_lba_count, target_buf);
	t1 = VbExGetTimer();
	VbExDebug("test_diskrw: disk_write, lba_count: %u, time: %llu\n",
			test_lba_count, t1 - t0);

	if (ret) {
		VbExDebug("Failed to write disk.\n");
		ret = 1;
	} else {
		/* Read back and verify the data. */
		VbExDiskRead(handle, TEST_LBA_START, test_lba_count,
				verify_buf);
		if (memcmp(target_buf, verify_buf, buf_byte_count) != 0) {
			VbExDebug("Verify failed. The target data wrote "
					"wrong.\n");
			ret = 1;
		}
	}

	/* Write the original data back. */
	if (VbExDiskWrite(handle, TEST_LBA_START, test_lba_count,
			original_buf)) {
		VbExDebug("Failed to write the original data back. The disk "
				"may now be corrupt.\n");
	}

out:
	VbExDiskFreeInfo(disk_info, NULL);

	VbExFree(original_buf);
	VbExFree(target_buf);
	VbExFree(verify_buf);

	if (ret == 0)
		VbExDebug("Read and write disk test SUCCESS.\n");

	return ret;
}
static int do_vbexport_test_debug(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	const char c = 'K';
	const char s[] = "Hello! It's \"Chrome OS\".";
	const int16_t hd = -22222;
	const uint16_t hu = 44444;
	const int32_t ld = -1111111111L;
	const uint32_t lu = 2222222222UL;
	const int64_t lld = -8888888888888888888LL;
	const uint64_t llu = 11111111111111111111ULL;
	VbExDebug("The \"Expect\" and \"Actual\" should be the same...\n");
	VbExDebug("Expect: K 75 Hello! It's \"Chrome OS\".\n");
	VbExDebug("Actual: %c %d %s\n", c, c, s);
	VbExDebug("Expect: -22222 0xa932\n");
	VbExDebug("Actual: %hd 0x%hx\n", hd, hd);
	VbExDebug("Expect: 44444 0xad9c\n");
	VbExDebug("Actual: %hu 0x%hx\n", hu, hu);
	VbExDebug("Expect: -1111111111 0xbdc5ca39\n");
	VbExDebug("Actual: %ld 0x%lx\n", ld, ld);
	VbExDebug("Expect: 2222222222 0x84746b8e\n");
	VbExDebug("Actual: %lu 0x%lx\n", lu, lu);
	VbExDebug("Expect: -8888888888888888888 0x84a452a6a1dc71c8\n");
	VbExDebug("Actual: %lld 0x%llx\n", lld, lld);
	VbExDebug("Expect: 11111111111111111111 0x9a3298afb5ac71c7\n");
	VbExDebug("Actual: %llu 0x%llx\n", llu, llu);
	return 0;
}
static uint32_t
twostop_main_firmware(struct twostop_fmap *fmap, void *gbb,
		      crossystem_data_t *cdata, void *vb_shared_data)
{
	VbError_t err;
	VbSelectAndLoadKernelParams kparams;
	VbCommonParams cparams;
	size_t size = 0;

#ifdef CONFIG_BOOTSTAGE_STASH
	bootstage_unstash((void *)CONFIG_BOOTSTAGE_STASH,
			CONFIG_BOOTSTAGE_STASH_SIZE);
#endif
	bootstage_mark_name(BOOTSTAGE_VBOOT_TWOSTOP_MAIN_FIRMWARE,
			"twostop_main_firmware");
	if (twostop_init_cparams(fmap, gbb, vb_shared_data, &cparams)) {
		VBDEBUG("failed to init cparams\n");
		return TWOSTOP_SELECT_ERROR;
	}

	/*
	 * Note that in case "kernel" is not found in the device tree, the
	 * "size" value is going to remain unchanged.
	 */
	kparams.kernel_buffer = cros_fdtdec_alloc_region(gd->fdt_blob,
		"kernel", &size);
	kparams.kernel_buffer_size = size;

	VBDEBUG("kparams:\n");
	VBDEBUG("- kernel_buffer:      : %p\n", kparams.kernel_buffer);
	VBDEBUG("- kernel_buffer_size: : %08x\n",
			kparams.kernel_buffer_size);

#ifdef CONFIG_EXYNOS_DISPLAYPORT
	/*
	 * Make sure the LCD is up before we load the kernel. Partly this
	 * is because VbSelectAndLoadKernel may do a software sync.
	 */
	exynos_lcd_check_next_stage(gd->fdt_blob, 1);
#endif

	if ((err = VbSelectAndLoadKernel(&cparams, &kparams))) {
		VBDEBUG("VbSelectAndLoadKernel: %d\n", err);
		switch (err) {
		case VBERROR_SHUTDOWN_REQUESTED:
			return TWOSTOP_SELECT_POWER_OFF;
		case VBERROR_BIOS_SHELL_REQUESTED:
			return TWOSTOP_SELECT_COMMAND_LINE;
		case VBERROR_EC_REBOOT_TO_RO_REQUIRED:
			request_ec_reboot_to_ro();
			return TWOSTOP_SELECT_POWER_OFF;
		}
		return TWOSTOP_SELECT_ERROR;
	}

	VBDEBUG("kparams:\n");
	VBDEBUG("- kernel_buffer:      : %p\n", kparams.kernel_buffer);
	VBDEBUG("- kernel_buffer_size: : %08x\n",
			kparams.kernel_buffer_size);
	VBDEBUG("- disk_handle:        : %p\n", kparams.disk_handle);
	VBDEBUG("- partition_number:   : %08x\n",
			kparams.partition_number);
	VBDEBUG("- bootloader_address: : %08llx\n",
			kparams.bootloader_address);
	VBDEBUG("- bootloader_size:    : %08x\n",
			kparams.bootloader_size);
	VBDEBUG("- partition_guid:     :");
#ifdef VBOOT_DEBUG
	int i;
	for (i = 0; i < 16; i++)
		VbExDebug(" %02x", kparams.partition_guid[i]);
	VbExDebug("\n");
#endif /* VBOOT_DEBUG */

	/* EC might jump between RO and RW during software sync. We need to
	 * update active EC copy in cdata. */
	set_active_ec_firmware(cdata);
	crossystem_data_dump(cdata);
#if defined(CONFIG_SANDBOX)
	return TWOSTOP_SELECT_COMMAND_LINE;
#else
	boot_kernel(&kparams, cdata);

	/* It is an error if boot_kenel returns */
	return TWOSTOP_SELECT_ERROR;
#endif
}