mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 10:26:10 +01:00 
			
		
		
		
	efi_selftest: BitBlt test
The BitBlt test leaves the serial console output in disarray.
* Call ClearScreen() where needed.
* Test CheckEvent() for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey
  via adding navigation keys
* Correct timer comment
For testing on the sandbox:
    CONFIG_CMD_BOOTEFI_SELFTEST=y
    CONFIG_CONSOLE_TRUETYPE=n
    $ ./u-boot -T -l
    => setenv efi_selftest block image transfer
    => bootefi selftest
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
			
			
This commit is contained in:
		| @@ -14,6 +14,12 @@ | |||||||
| #define HEIGHT	120 | #define HEIGHT	120 | ||||||
| #define DEPTH	 60 | #define DEPTH	 60 | ||||||
|  |  | ||||||
|  | struct pos { | ||||||
|  | 	efi_uintn_t x; | ||||||
|  | 	efi_uintn_t y; | ||||||
|  | 	int redrawn; | ||||||
|  | }; | ||||||
|  |  | ||||||
| static const struct efi_gop_pixel BLACK =	{  0,   0,   0, 0}; | static const struct efi_gop_pixel BLACK =	{  0,   0,   0, 0}; | ||||||
| static const struct efi_gop_pixel RED =		{  0,   0, 255, 0}; | static const struct efi_gop_pixel RED =		{  0,   0, 255, 0}; | ||||||
| static const struct efi_gop_pixel ORANGE =	{  0, 128, 255, 0}; | static const struct efi_gop_pixel ORANGE =	{  0, 128, 255, 0}; | ||||||
| @@ -27,7 +33,7 @@ static efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; | |||||||
| static struct efi_gop *gop; | static struct efi_gop *gop; | ||||||
| static struct efi_gop_pixel *bitmap; | static struct efi_gop_pixel *bitmap; | ||||||
| static struct efi_event *event; | static struct efi_event *event; | ||||||
| static efi_uintn_t xpos; | static struct pos pos; | ||||||
|  |  | ||||||
| static void ellipse(efi_uintn_t x, efi_uintn_t y, | static void ellipse(efi_uintn_t x, efi_uintn_t y, | ||||||
| 		    efi_uintn_t x0, efi_uintn_t y0, | 		    efi_uintn_t x0, efi_uintn_t y0, | ||||||
| @@ -62,31 +68,33 @@ static void rectangle(efi_uintn_t x, efi_uintn_t y, | |||||||
|  */ |  */ | ||||||
| static void EFIAPI notify(struct efi_event *event, void *context) | static void EFIAPI notify(struct efi_event *event, void *context) | ||||||
| { | { | ||||||
| 	efi_uintn_t *pos = context; | 	struct pos *pos = context; | ||||||
| 	efi_uintn_t dx, sx, width; | 	efi_uintn_t dx, sx, width; | ||||||
|  |  | ||||||
| 	if (!pos) | 	if (!pos) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	/* Increment position */ | 	/* Increment position */ | ||||||
| 	*pos += 5; | 	pos->x += 5; | ||||||
| 	if (*pos >= WIDTH + gop->mode->info->width) | 	if (pos->x >= WIDTH + gop->mode->info->width) | ||||||
| 		*pos = 0; | 		pos->x = 0; | ||||||
|  |  | ||||||
| 	width = WIDTH; | 	width = WIDTH; | ||||||
| 	dx = *pos - WIDTH; | 	dx = pos->x - WIDTH; | ||||||
| 	sx = 0; | 	sx = 0; | ||||||
| 	if (*pos >= gop->mode->info->width) { | 	if (pos->x >= gop->mode->info->width) { | ||||||
| 		width = WIDTH +  gop->mode->info->width - *pos; | 		width = WIDTH +  gop->mode->info->width - pos->x; | ||||||
| 	} else if (*pos < WIDTH) { | 	} else if (pos->x < WIDTH) { | ||||||
| 		dx = 0; | 		dx = 0; | ||||||
| 		sx = WIDTH - *pos; | 		sx = WIDTH - pos->x; | ||||||
| 		width = *pos; | 		width = pos->x; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* Copy image to video */ | 	/* Copy image to video */ | ||||||
| 	gop->blt(gop, bitmap, EFI_BLT_BUFFER_TO_VIDEO, sx, 0, dx, DEPTH, | 	gop->blt(gop, bitmap, EFI_BLT_BUFFER_TO_VIDEO, sx, 0, dx, pos->y, | ||||||
| 		 width, HEIGHT, WIDTH * sizeof(struct efi_gop_pixel)); | 		 width, HEIGHT, WIDTH * sizeof(struct efi_gop_pixel)); | ||||||
|  |  | ||||||
|  | 	pos->redrawn = 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -107,7 +115,7 @@ static int setup(const efi_handle_t handle, | |||||||
|  |  | ||||||
| 	/* Create event */ | 	/* Create event */ | ||||||
| 	ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, | 	ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, | ||||||
| 				     TPL_CALLBACK, notify, (void *)&xpos, | 				     TPL_CALLBACK, notify, (void *)&pos, | ||||||
| 				     &event); | 				     &event); | ||||||
| 	if (ret != EFI_SUCCESS) { | 	if (ret != EFI_SUCCESS) { | ||||||
| 		efi_st_error("could not create event\n"); | 		efi_st_error("could not create event\n"); | ||||||
| @@ -247,6 +255,9 @@ static int execute(void) | |||||||
| 		return EFI_ST_FAILURE; | 		return EFI_ST_FAILURE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	con_out->set_attribute(con_out, EFI_WHITE | EFI_BACKGROUND_BLUE); | ||||||
|  | 	con_out->clear_screen(con_out); | ||||||
|  |  | ||||||
| 	/* Fill background */ | 	/* Fill background */ | ||||||
| 	ret = gop->blt(gop, bitmap, EFI_BLT_VIDEO_FILL, 0, 0, 0, 0, | 	ret = gop->blt(gop, bitmap, EFI_BLT_VIDEO_FILL, 0, 0, 0, 0, | ||||||
| 		       info->width, info->height, 0); | 		       info->width, info->height, 0); | ||||||
| @@ -281,21 +292,53 @@ static int execute(void) | |||||||
| 		return EFI_ST_FAILURE; | 		return EFI_ST_FAILURE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* Set 250ms timer */ | 	/* Set 25ms timer */ | ||||||
| 	xpos = WIDTH; | 	pos.x = WIDTH; | ||||||
|  | 	pos.y = DEPTH; | ||||||
| 	ret = boottime->set_timer(event, EFI_TIMER_PERIODIC, 250000); | 	ret = boottime->set_timer(event, EFI_TIMER_PERIODIC, 250000); | ||||||
| 	if (ret != EFI_SUCCESS) { | 	if (ret != EFI_SUCCESS) { | ||||||
| 		efi_st_error("Could not set timer\n"); | 		efi_st_error("Could not set timer\n"); | ||||||
| 		return EFI_ST_FAILURE; | 		return EFI_ST_FAILURE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	con_out->set_cursor_position(con_out, 0, 0); |  | ||||||
| 	con_out->set_attribute(con_out, EFI_WHITE | EFI_BACKGROUND_BLUE); |  | ||||||
| 	efi_st_printf("The submarine should have three yellow port holes.\n"); | 	efi_st_printf("The submarine should have three yellow port holes.\n"); | ||||||
| 	efi_st_printf("Press any key to continue"); | 	efi_st_printf("UP, DOWN to navigate, any other key to quit"); | ||||||
| 	efi_st_get_key(); | 	for (;;) { | ||||||
|  | 		struct efi_input_key input_key; | ||||||
|  |  | ||||||
|  | 		ret = boottime->check_event(con_in->wait_for_key); | ||||||
|  | 		if (ret == EFI_NOT_READY) | ||||||
|  | 			continue; | ||||||
|  | 		if (ret != EFI_SUCCESS) { | ||||||
|  | 			efi_st_error("CheckEvent failed %x\n", | ||||||
|  | 				     (unsigned int)ret); | ||||||
|  | 			return EFI_ST_FAILURE; | ||||||
|  | 		} | ||||||
|  | 		ret = con_in->read_key_stroke(con_in, &input_key); | ||||||
|  | 		if (ret != EFI_SUCCESS) { | ||||||
|  | 			efi_st_error("Key not available %x\n", | ||||||
|  | 				     (unsigned int)ret); | ||||||
|  | 			return EFI_ST_FAILURE; | ||||||
|  | 		} | ||||||
|  | 		switch (input_key.scan_code) { | ||||||
|  | 		case 0x01: /* UP */ | ||||||
|  | 			if (pos.redrawn && pos.y >= 5) { | ||||||
|  | 				pos.y -= 5; | ||||||
|  | 				pos.redrawn = 0; | ||||||
|  | 			} | ||||||
|  | 			continue; | ||||||
|  | 		case 0x02: /* DOWN */ | ||||||
|  | 			if (pos.redrawn && | ||||||
|  | 			    pos.y + HEIGHT + 5 < gop->mode->info->height) { | ||||||
|  | 				pos.y += 5; | ||||||
|  | 				pos.redrawn = 0; | ||||||
|  | 			} | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
| 	con_out->set_attribute(con_out, EFI_LIGHTGRAY); | 	con_out->set_attribute(con_out, EFI_LIGHTGRAY); | ||||||
| 	efi_st_printf("\n"); | 	con_out->clear_screen(con_out); | ||||||
|  |  | ||||||
| 	return EFI_ST_SUCCESS; | 	return EFI_ST_SUCCESS; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user