mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-25 01:58:13 +01:00
Pull request efi-next-20230313
UEFI: * Improve graphics support in EFI app Others: * x86: Add a few more items to bdinfo * video: Remove duplicate cursor-positioning function * video: Clear the vidconsole rather than the video -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAmQPNQsACgkQxIHbvCwF GsTDcQ//V1UUQWmZGgWtref6cbG6RlVV4SZjvaVosfWazQY8fK3TC5LEV6dXjs2L gJZpHBAU8unCwsnQueYy2HumgEb/9ruyTVLCeO7s7Mqc7jBrHVEaFQf7E+FxAPOg ibQ5bx5MI36KaqcQ7fZmQtEIOvOIJXkxbdrlFPh/b3oE08GzVDnkryLXC9xykW2Z Y4HJxNhchz2labGuTInuGnst6qnhy3Oo8WHUSBdOJW04Dd0GVLyY11qjBsy4lttt uDmb48WouTfLBz6JquDZX9EY97KZA0ThVu6GDAr2BNqVmF/f0/Js5+5KdKYSBy44 jYR8MTG+BOQ2luIwy+YvLKcANOMYXB2HeN5pIemUOkrJA9cEAv4ru1yPR7fp4sse 2u+XZ7P9BosCyOpTErH4GMIdz4kYsT9lhiusVD2QyBgSco6vTD+7atRwH1pEptoS Hthqn5dnlQvGmMUlrlG4tCRGhu7tCEzPc6Z4MBzxUiOWkWxPvNg3nzjdK/OhSm62 zkznU8xOeoq2XwE6PA29vXAaXlVoPyfOVwTE7s1Zdq/tpZcIGeZqj5DtOqRYiufw YYWTb667rAcSEM0t/YfnzkuU1xA+rqSd2KrmjXhM6TfGRnyLWRnInr3e6FKaFcmE Q/bHfzdHHGl5WRfyBd6F0Bg5BIEuyDNew+pSfxXKPLoyJkvNJOg= =7BR5 -----END PGP SIGNATURE----- Merge tag 'efi-next-20230313' of https://source.denx.de/u-boot/custodians/u-boot-efi into next Pull request efi-next-20230313 UEFI: * Improve graphics support in EFI app Others: * x86: Add a few more items to bdinfo * video: Remove duplicate cursor-positioning function * video: Clear the vidconsole rather than the video
This commit is contained in:
commit
2684aad483
@ -27,6 +27,7 @@
|
|||||||
};
|
};
|
||||||
efi-fb {
|
efi-fb {
|
||||||
compatible = "efi-fb";
|
compatible = "efi-fb";
|
||||||
|
bootph-some-ram;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <efi.h>
|
#include <efi.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
#include <asm/cpu.h>
|
||||||
#include <asm/efi.h>
|
#include <asm/efi.h>
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
|
|
||||||
@ -16,6 +17,11 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||||||
void arch_print_bdinfo(void)
|
void arch_print_bdinfo(void)
|
||||||
{
|
{
|
||||||
bdinfo_print_num_l("prev table", gd->arch.table);
|
bdinfo_print_num_l("prev table", gd->arch.table);
|
||||||
|
bdinfo_print_num_l("clock_rate", gd->arch.clock_rate);
|
||||||
|
bdinfo_print_num_l("tsc_base", gd->arch.tsc_base);
|
||||||
|
bdinfo_print_num_l("vendor", gd->arch.x86_vendor);
|
||||||
|
bdinfo_print_str(" name", cpu_vendor_name(gd->arch.x86_vendor));
|
||||||
|
bdinfo_print_num_l("model", gd->arch.x86_model);
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_EFI_STUB))
|
if (IS_ENABLED(CONFIG_EFI_STUB))
|
||||||
efi_show_bdinfo();
|
efi_show_bdinfo();
|
||||||
|
|||||||
@ -106,7 +106,7 @@ static int fsp_video_probe(struct udevice *dev)
|
|||||||
vesa->phys_base_ptr = dm_pci_read_bar32(dev, 2);
|
vesa->phys_base_ptr = dm_pci_read_bar32(dev, 2);
|
||||||
gd->fb_base = vesa->phys_base_ptr;
|
gd->fb_base = vesa->phys_base_ptr;
|
||||||
|
|
||||||
ret = vesa_setup_video_priv(vesa, uc_priv, plat);
|
ret = vesa_setup_video_priv(vesa, vesa->phys_base_ptr, uc_priv, plat);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
|||||||
11
cmd/bdinfo.c
11
cmd/bdinfo.c
@ -26,6 +26,11 @@ void bdinfo_print_size(const char *name, uint64_t size)
|
|||||||
print_size(size, "\n");
|
print_size(size, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bdinfo_print_str(const char *name, const char *str)
|
||||||
|
{
|
||||||
|
printf("%-12s= %s\n", name, str);
|
||||||
|
}
|
||||||
|
|
||||||
void bdinfo_print_num_l(const char *name, ulong value)
|
void bdinfo_print_num_l(const char *name, ulong value)
|
||||||
{
|
{
|
||||||
printf("%-12s= 0x%0*lx\n", name, 2 * (int)sizeof(value), value);
|
printf("%-12s= 0x%0*lx\n", name, 2 * (int)sizeof(value), value);
|
||||||
@ -83,11 +88,15 @@ static void show_video_info(void)
|
|||||||
device_active(dev) ? "" : "in");
|
device_active(dev) ? "" : "in");
|
||||||
if (device_active(dev)) {
|
if (device_active(dev)) {
|
||||||
struct video_priv *upriv = dev_get_uclass_priv(dev);
|
struct video_priv *upriv = dev_get_uclass_priv(dev);
|
||||||
|
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
|
||||||
|
|
||||||
bdinfo_print_num_ll("FB base", (ulong)upriv->fb);
|
bdinfo_print_num_ll("FB base", (ulong)upriv->fb);
|
||||||
if (upriv->copy_fb)
|
if (upriv->copy_fb) {
|
||||||
bdinfo_print_num_ll("FB copy",
|
bdinfo_print_num_ll("FB copy",
|
||||||
(ulong)upriv->copy_fb);
|
(ulong)upriv->copy_fb);
|
||||||
|
bdinfo_print_num_l(" copy size",
|
||||||
|
plat->copy_size);
|
||||||
|
}
|
||||||
printf("%-12s= %dx%dx%d\n", "FB size", upriv->xsize,
|
printf("%-12s= %dx%dx%d\n", "FB size", upriv->xsize,
|
||||||
upriv->ysize, 1 << upriv->bpix);
|
upriv->ysize, 1 << upriv->bpix);
|
||||||
}
|
}
|
||||||
|
|||||||
20
cmd/cls.c
20
cmd/cls.c
@ -8,7 +8,7 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <video.h>
|
#include <video_console.h>
|
||||||
|
|
||||||
#define CSI "\x1b["
|
#define CSI "\x1b["
|
||||||
|
|
||||||
@ -17,14 +17,24 @@ static int do_video_clear(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||||||
{
|
{
|
||||||
__maybe_unused struct udevice *dev;
|
__maybe_unused struct udevice *dev;
|
||||||
|
|
||||||
/* Send clear screen and home */
|
/*
|
||||||
|
* Send clear screen and home
|
||||||
|
*
|
||||||
|
* FIXME(Heinrich Schuchardt <xypron.glpk@gmx.de>): This should go
|
||||||
|
* through an API and only be written to serial terminals, not video
|
||||||
|
* displays
|
||||||
|
*/
|
||||||
printf(CSI "2J" CSI "1;1H");
|
printf(CSI "2J" CSI "1;1H");
|
||||||
if (IS_ENABLED(CONFIG_VIDEO) && !IS_ENABLED(CONFIG_VIDEO_ANSI)) {
|
if (IS_ENABLED(CONFIG_VIDEO_ANSI))
|
||||||
if (uclass_first_device_err(UCLASS_VIDEO, &dev))
|
return 0;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_VIDEO)) {
|
||||||
|
if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev))
|
||||||
return CMD_RET_FAILURE;
|
return CMD_RET_FAILURE;
|
||||||
if (video_clear(dev))
|
if (vidconsole_clear_and_reset(dev))
|
||||||
return CMD_RET_FAILURE;
|
return CMD_RET_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMD_RET_SUCCESS;
|
return CMD_RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,7 @@ CONFIG_SYS_PBSIZE=532
|
|||||||
# CONFIG_CMD_BOOTM is not set
|
# CONFIG_CMD_BOOTM is not set
|
||||||
CONFIG_CMD_PART=y
|
CONFIG_CMD_PART=y
|
||||||
# CONFIG_CMD_NET is not set
|
# CONFIG_CMD_NET is not set
|
||||||
|
CONFIG_CMD_CACHE=y
|
||||||
CONFIG_CMD_TIME=y
|
CONFIG_CMD_TIME=y
|
||||||
CONFIG_CMD_EXT2=y
|
CONFIG_CMD_EXT2=y
|
||||||
CONFIG_CMD_EXT4=y
|
CONFIG_CMD_EXT4=y
|
||||||
@ -39,7 +40,9 @@ CONFIG_BOOTFILE="bzImage"
|
|||||||
CONFIG_USE_ROOTPATH=y
|
CONFIG_USE_ROOTPATH=y
|
||||||
CONFIG_REGMAP=y
|
CONFIG_REGMAP=y
|
||||||
CONFIG_SYSCON=y
|
CONFIG_SYSCON=y
|
||||||
|
CONFIG_CONSOLE_SCROLL_LINES=5
|
||||||
# CONFIG_REGEX is not set
|
# CONFIG_REGEX is not set
|
||||||
|
CONFIG_CMD_DHRYSTONE=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
CONFIG_EFI=y
|
CONFIG_EFI=y
|
||||||
CONFIG_EFI_APP_64BIT=y
|
CONFIG_EFI_APP_64BIT=y
|
||||||
|
|||||||
@ -325,7 +325,7 @@ err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vesa_setup_video_priv(struct vesa_mode_info *vesa,
|
int vesa_setup_video_priv(struct vesa_mode_info *vesa, u64 fb,
|
||||||
struct video_priv *uc_priv,
|
struct video_priv *uc_priv,
|
||||||
struct video_uc_plat *plat)
|
struct video_uc_plat *plat)
|
||||||
{
|
{
|
||||||
@ -348,9 +348,9 @@ int vesa_setup_video_priv(struct vesa_mode_info *vesa,
|
|||||||
|
|
||||||
/* Use double buffering if enabled */
|
/* Use double buffering if enabled */
|
||||||
if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->base)
|
if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->base)
|
||||||
plat->copy_base = vesa->phys_base_ptr;
|
plat->copy_base = fb;
|
||||||
else
|
else
|
||||||
plat->base = vesa->phys_base_ptr;
|
plat->base = fb;
|
||||||
log_debug("base = %lx, copy_base = %lx\n", plat->base, plat->copy_base);
|
log_debug("base = %lx, copy_base = %lx\n", plat->base, plat->copy_base);
|
||||||
plat->size = vesa->bytes_per_scanline * vesa->y_resolution;
|
plat->size = vesa->bytes_per_scanline * vesa->y_resolution;
|
||||||
|
|
||||||
@ -377,7 +377,9 @@ int vesa_setup_video(struct udevice *dev, int (*int15_handler)(void))
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = vesa_setup_video_priv(&mode_info.vesa, uc_priv, plat);
|
ret = vesa_setup_video_priv(&mode_info.vesa,
|
||||||
|
mode_info.vesa.phys_base_ptr, uc_priv,
|
||||||
|
plat);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret == -ENFILE) {
|
if (ret == -ENFILE) {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -404,6 +404,15 @@ static void tsc_timer_ensure_setup(bool early)
|
|||||||
if (!gd->arch.clock_rate) {
|
if (!gd->arch.clock_rate) {
|
||||||
unsigned long fast_calibrate;
|
unsigned long fast_calibrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There is no obvious way to obtain this information from EFI
|
||||||
|
* boot services. This value was measured on a Framework Laptop
|
||||||
|
* which has a 12th Gen Intel Core
|
||||||
|
*/
|
||||||
|
if (IS_ENABLED(CONFIG_EFI_APP)) {
|
||||||
|
fast_calibrate = 2750;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
fast_calibrate = native_calibrate_tsc();
|
fast_calibrate = native_calibrate_tsc();
|
||||||
if (fast_calibrate)
|
if (fast_calibrate)
|
||||||
goto done;
|
goto done;
|
||||||
|
|||||||
@ -57,7 +57,7 @@ static int coreboot_video_probe(struct udevice *dev)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = vesa_setup_video_priv(vesa, uc_priv, plat);
|
ret = vesa_setup_video_priv(vesa, vesa->phys_base_ptr, uc_priv, plat);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = log_msg_ret("setup", ret);
|
ret = log_msg_ret("setup", ret);
|
||||||
goto err;
|
goto err;
|
||||||
|
|||||||
@ -5,6 +5,8 @@
|
|||||||
* EFI framebuffer driver based on GOP
|
* EFI framebuffer driver based on GOP
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define LOG_CATEGORY LOGC_EFI
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <efi_api.h>
|
#include <efi_api.h>
|
||||||
@ -50,7 +52,19 @@ static void efi_find_pixel_bits(u32 mask, u8 *pos, u8 *size)
|
|||||||
*size = len;
|
*size = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_mode_info(struct vesa_mode_info *vesa)
|
/**
|
||||||
|
* get_mode_info() - Ask EFI for the mode information
|
||||||
|
*
|
||||||
|
* Gets info from the graphics-output protocol
|
||||||
|
*
|
||||||
|
* @vesa: Place to put the mode information
|
||||||
|
* @fbp: Returns the address of the frame buffer
|
||||||
|
* @infop: Returns a pointer to the mode info
|
||||||
|
* Returns: 0 if OK, -ENOSYS if boot services are not available, -ENOTSUPP if
|
||||||
|
* the protocol is not supported by EFI
|
||||||
|
*/
|
||||||
|
static int get_mode_info(struct vesa_mode_info *vesa, u64 *fbp,
|
||||||
|
struct efi_gop_mode_info **infop)
|
||||||
{
|
{
|
||||||
efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||||
struct efi_boot_services *boot = efi_get_boot();
|
struct efi_boot_services *boot = efi_get_boot();
|
||||||
@ -63,41 +77,70 @@ static int get_mode_info(struct vesa_mode_info *vesa)
|
|||||||
ret = boot->locate_protocol(&efi_gop_guid, NULL, (void **)&gop);
|
ret = boot->locate_protocol(&efi_gop_guid, NULL, (void **)&gop);
|
||||||
if (ret)
|
if (ret)
|
||||||
return log_msg_ret("prot", -ENOTSUPP);
|
return log_msg_ret("prot", -ENOTSUPP);
|
||||||
|
|
||||||
mode = gop->mode;
|
mode = gop->mode;
|
||||||
|
log_debug("maxmode %u, mode %u, info %p, size %lx, fb %lx, fb_size %lx\n",
|
||||||
|
mode->max_mode, mode->mode, mode->info, mode->info_size,
|
||||||
|
(ulong)mode->fb_base, (ulong)mode->fb_size);
|
||||||
|
|
||||||
vesa->phys_base_ptr = mode->fb_base;
|
vesa->phys_base_ptr = mode->fb_base;
|
||||||
|
*fbp = mode->fb_base;
|
||||||
vesa->x_resolution = mode->info->width;
|
vesa->x_resolution = mode->info->width;
|
||||||
vesa->y_resolution = mode->info->height;
|
vesa->y_resolution = mode->info->height;
|
||||||
|
*infop = mode->info;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int save_vesa_mode(struct vesa_mode_info *vesa)
|
/**
|
||||||
|
* get_mode_from_entry() - Obtain fb info from the EFIET_GOP_MODE payload entry
|
||||||
|
*
|
||||||
|
* This gets the mode information provided by the stub to the payload and puts
|
||||||
|
* it into a vesa structure. It also returns the mode information.
|
||||||
|
*
|
||||||
|
* @vesa: Place to put the mode information
|
||||||
|
* @fbp: Returns the address of the frame buffer
|
||||||
|
* @infop: Returns a pointer to the mode info
|
||||||
|
* Returns: 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
static int get_mode_from_entry(struct vesa_mode_info *vesa, u64 *fbp,
|
||||||
|
struct efi_gop_mode_info **infop)
|
||||||
{
|
{
|
||||||
struct efi_entry_gopmode *mode;
|
struct efi_gop_mode *mode;
|
||||||
const struct efi_framebuffer *fbinfo;
|
|
||||||
int size;
|
int size;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_EFI_APP)) {
|
ret = efi_info_get(EFIET_GOP_MODE, (void **)&mode, &size);
|
||||||
ret = get_mode_info(vesa);
|
if (ret) {
|
||||||
if (ret) {
|
printf("EFI graphics output entry not found\n");
|
||||||
printf("EFI graphics output protocol not found\n");
|
return ret;
|
||||||
return -ENXIO;
|
}
|
||||||
}
|
vesa->phys_base_ptr = mode->fb_base;
|
||||||
} else {
|
*fbp = mode->fb_base;
|
||||||
ret = efi_info_get(EFIET_GOP_MODE, (void **)&mode, &size);
|
vesa->x_resolution = mode->info->width;
|
||||||
if (ret == -ENOENT) {
|
vesa->y_resolution = mode->info->height;
|
||||||
printf("EFI graphics output protocol mode not found\n");
|
*infop = mode->info;
|
||||||
return -ENXIO;
|
|
||||||
}
|
return 0;
|
||||||
vesa->phys_base_ptr = mode->fb_base;
|
}
|
||||||
vesa->x_resolution = mode->info->width;
|
|
||||||
vesa->y_resolution = mode->info->height;
|
static int save_vesa_mode(struct vesa_mode_info *vesa, u64 *fbp)
|
||||||
|
{
|
||||||
|
const struct efi_framebuffer *fbinfo;
|
||||||
|
struct efi_gop_mode_info *info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_EFI_APP))
|
||||||
|
ret = get_mode_info(vesa, fbp, &info);
|
||||||
|
else
|
||||||
|
ret = get_mode_from_entry(vesa, fbp, &info);
|
||||||
|
if (ret) {
|
||||||
|
printf("EFI graphics output protocol not found (err=%dE)\n",
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode->info->pixel_format < EFI_GOT_BITMASK) {
|
if (info->pixel_format < EFI_GOT_BITMASK) {
|
||||||
fbinfo = &efi_framebuffer_format_map[mode->info->pixel_format];
|
fbinfo = &efi_framebuffer_format_map[info->pixel_format];
|
||||||
vesa->red_mask_size = fbinfo->red.size;
|
vesa->red_mask_size = fbinfo->red.size;
|
||||||
vesa->red_mask_pos = fbinfo->red.pos;
|
vesa->red_mask_pos = fbinfo->red.pos;
|
||||||
vesa->green_mask_size = fbinfo->green.size;
|
vesa->green_mask_size = fbinfo->green.size;
|
||||||
@ -108,29 +151,28 @@ static int save_vesa_mode(struct vesa_mode_info *vesa)
|
|||||||
vesa->reserved_mask_pos = fbinfo->rsvd.pos;
|
vesa->reserved_mask_pos = fbinfo->rsvd.pos;
|
||||||
|
|
||||||
vesa->bits_per_pixel = 32;
|
vesa->bits_per_pixel = 32;
|
||||||
vesa->bytes_per_scanline = mode->info->pixels_per_scanline * 4;
|
vesa->bytes_per_scanline = info->pixels_per_scanline * 4;
|
||||||
} else if (mode->info->pixel_format == EFI_GOT_BITMASK) {
|
} else if (info->pixel_format == EFI_GOT_BITMASK) {
|
||||||
efi_find_pixel_bits(mode->info->pixel_bitmask[0],
|
efi_find_pixel_bits(info->pixel_bitmask[0],
|
||||||
&vesa->red_mask_pos,
|
&vesa->red_mask_pos,
|
||||||
&vesa->red_mask_size);
|
&vesa->red_mask_size);
|
||||||
efi_find_pixel_bits(mode->info->pixel_bitmask[1],
|
efi_find_pixel_bits(info->pixel_bitmask[1],
|
||||||
&vesa->green_mask_pos,
|
&vesa->green_mask_pos,
|
||||||
&vesa->green_mask_size);
|
&vesa->green_mask_size);
|
||||||
efi_find_pixel_bits(mode->info->pixel_bitmask[2],
|
efi_find_pixel_bits(info->pixel_bitmask[2],
|
||||||
&vesa->blue_mask_pos,
|
&vesa->blue_mask_pos,
|
||||||
&vesa->blue_mask_size);
|
&vesa->blue_mask_size);
|
||||||
efi_find_pixel_bits(mode->info->pixel_bitmask[3],
|
efi_find_pixel_bits(info->pixel_bitmask[3],
|
||||||
&vesa->reserved_mask_pos,
|
&vesa->reserved_mask_pos,
|
||||||
&vesa->reserved_mask_size);
|
&vesa->reserved_mask_size);
|
||||||
vesa->bits_per_pixel = vesa->red_mask_size +
|
vesa->bits_per_pixel = vesa->red_mask_size +
|
||||||
vesa->green_mask_size +
|
vesa->green_mask_size +
|
||||||
vesa->blue_mask_size +
|
vesa->blue_mask_size +
|
||||||
vesa->reserved_mask_size;
|
vesa->reserved_mask_size;
|
||||||
vesa->bytes_per_scanline = (mode->info->pixels_per_scanline *
|
vesa->bytes_per_scanline = (info->pixels_per_scanline *
|
||||||
vesa->bits_per_pixel) / 8;
|
vesa->bits_per_pixel) / 8;
|
||||||
} else {
|
} else {
|
||||||
debug("efi set unknown framebuffer format: %d\n",
|
log_err("Unknown framebuffer format: %d\n", info->pixel_format);
|
||||||
mode->info->pixel_format);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,19 +184,20 @@ static int efi_video_probe(struct udevice *dev)
|
|||||||
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
|
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
|
||||||
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
|
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||||
struct vesa_mode_info *vesa = &mode_info.vesa;
|
struct vesa_mode_info *vesa = &mode_info.vesa;
|
||||||
|
u64 fb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Initialize vesa_mode_info structure */
|
/* Initialize vesa_mode_info structure */
|
||||||
ret = save_vesa_mode(vesa);
|
ret = save_vesa_mode(vesa, &fb);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ret = vesa_setup_video_priv(vesa, uc_priv, plat);
|
ret = vesa_setup_video_priv(vesa, fb, uc_priv, plat);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
printf("Video: %dx%dx%d\n", uc_priv->xsize, uc_priv->ysize,
|
printf("Video: %dx%dx%d @ %lx\n", uc_priv->xsize, uc_priv->ysize,
|
||||||
vesa->bits_per_pixel);
|
vesa->bits_per_pixel, (ulong)fb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -163,6 +206,30 @@ err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int efi_video_bind(struct udevice *dev)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_VIDEO_COPY)) {
|
||||||
|
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
|
||||||
|
struct vesa_mode_info vesa;
|
||||||
|
int ret;
|
||||||
|
u64 fb;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise vesa_mode_info structure so we can figure out the
|
||||||
|
* required framebuffer size. If something goes wrong, just do
|
||||||
|
* without a copy framebuffer
|
||||||
|
*/
|
||||||
|
ret = save_vesa_mode(&vesa, &fb);
|
||||||
|
if (!ret) {
|
||||||
|
/* this is not reached if the EFI call failed */
|
||||||
|
plat->copy_size = vesa.bytes_per_scanline *
|
||||||
|
vesa.y_resolution;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct udevice_id efi_video_ids[] = {
|
static const struct udevice_id efi_video_ids[] = {
|
||||||
{ .compatible = "efi-fb" },
|
{ .compatible = "efi-fb" },
|
||||||
{ }
|
{ }
|
||||||
@ -172,5 +239,6 @@ U_BOOT_DRIVER(efi_video) = {
|
|||||||
.name = "efi_video",
|
.name = "efi_video",
|
||||||
.id = UCLASS_VIDEO,
|
.id = UCLASS_VIDEO,
|
||||||
.of_match = efi_video_ids,
|
.of_match = efi_video_ids,
|
||||||
|
.bind = efi_video_bind,
|
||||||
.probe = efi_video_probe,
|
.probe = efi_video_probe,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -126,26 +126,14 @@ void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y)
|
|||||||
priv->ycur = y;
|
priv->ycur = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void vidconsole_position_cursor(struct udevice *dev, uint col, uint row)
|
||||||
* set_cursor_position() - set cursor position
|
|
||||||
*
|
|
||||||
* @priv: private data of the video console
|
|
||||||
* @row: new row
|
|
||||||
* @col: new column
|
|
||||||
*/
|
|
||||||
static void set_cursor_position(struct vidconsole_priv *priv, int row, int col)
|
|
||||||
{
|
{
|
||||||
/*
|
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
||||||
* Ensure we stay in the bounds of the screen.
|
short x, y;
|
||||||
*/
|
|
||||||
if (row >= priv->rows)
|
|
||||||
row = priv->rows - 1;
|
|
||||||
if (col >= priv->cols)
|
|
||||||
col = priv->cols - 1;
|
|
||||||
|
|
||||||
priv->ycur = row * priv->y_charsize;
|
x = min_t(short, col, priv->cols - 1) * priv->x_charsize;
|
||||||
priv->xcur_frac = priv->xstart_frac +
|
y = min_t(short, row, priv->rows - 1) * priv->y_charsize;
|
||||||
VID_TO_POS(col * priv->x_charsize);
|
vidconsole_set_cursor_pos(dev, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,7 +180,7 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)
|
|||||||
int row = priv->row_saved;
|
int row = priv->row_saved;
|
||||||
int col = priv->col_saved;
|
int col = priv->col_saved;
|
||||||
|
|
||||||
set_cursor_position(priv, row, col);
|
vidconsole_position_cursor(dev, col, row);
|
||||||
priv->escape = 0;
|
priv->escape = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -254,7 +242,7 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)
|
|||||||
if (row < 0)
|
if (row < 0)
|
||||||
row = 0;
|
row = 0;
|
||||||
/* Right and bottom overflows are handled in the callee. */
|
/* Right and bottom overflows are handled in the callee. */
|
||||||
set_cursor_position(priv, row, col);
|
vidconsole_position_cursor(dev, col, row);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'H':
|
case 'H':
|
||||||
@ -278,7 +266,7 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)
|
|||||||
if (col)
|
if (col)
|
||||||
--col;
|
--col;
|
||||||
|
|
||||||
set_cursor_position(priv, row, col);
|
vidconsole_position_cursor(dev, col, row);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -656,14 +644,14 @@ int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row)
|
int vidconsole_clear_and_reset(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
|
int ret;
|
||||||
struct udevice *vid_dev = dev->parent;
|
|
||||||
struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
|
|
||||||
short x, y;
|
|
||||||
|
|
||||||
x = min_t(short, col * priv->x_charsize, vid_priv->xsize - 1);
|
ret = video_clear(dev_get_parent(dev));
|
||||||
y = min_t(short, row * priv->y_charsize, vid_priv->ysize - 1);
|
if (ret)
|
||||||
vidconsole_set_cursor_pos(dev, x, y);
|
return ret;
|
||||||
|
vidconsole_position_cursor(dev, 0, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,24 +78,40 @@ void video_set_flush_dcache(struct udevice *dev, bool flush)
|
|||||||
priv->flush_dcache = flush;
|
priv->flush_dcache = flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ulong alloc_fb_(ulong align, ulong size, ulong *addrp)
|
||||||
|
{
|
||||||
|
ulong base;
|
||||||
|
|
||||||
|
align = align ? align : 1 << 20;
|
||||||
|
base = *addrp - size;
|
||||||
|
base &= ~(align - 1);
|
||||||
|
size = *addrp - base;
|
||||||
|
*addrp = base;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
static ulong alloc_fb(struct udevice *dev, ulong *addrp)
|
static ulong alloc_fb(struct udevice *dev, ulong *addrp)
|
||||||
{
|
{
|
||||||
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
|
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
|
||||||
ulong base, align, size;
|
ulong size;
|
||||||
|
|
||||||
|
if (!plat->size) {
|
||||||
|
if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_size) {
|
||||||
|
size = alloc_fb_(plat->align, plat->copy_size, addrp);
|
||||||
|
plat->copy_base = *addrp;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
if (!plat->size)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allow drivers to allocate the frame buffer themselves */
|
/* Allow drivers to allocate the frame buffer themselves */
|
||||||
if (plat->base)
|
if (plat->base)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
align = plat->align ? plat->align : 1 << 20;
|
size = alloc_fb_(plat->align, plat->size, addrp);
|
||||||
base = *addrp - plat->size;
|
plat->base = *addrp;
|
||||||
base &= ~(align - 1);
|
|
||||||
plat->base = base;
|
|
||||||
size = *addrp - base;
|
|
||||||
*addrp = base;
|
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -353,6 +353,9 @@ void relocate_code(ulong start_addr_sp, struct global_data *new_gd,
|
|||||||
void bdinfo_print_num_l(const char *name, ulong value);
|
void bdinfo_print_num_l(const char *name, ulong value);
|
||||||
void bdinfo_print_num_ll(const char *name, unsigned long long value);
|
void bdinfo_print_num_ll(const char *name, unsigned long long value);
|
||||||
|
|
||||||
|
/* Print a string value (for use in arch_print_bdinfo()) */
|
||||||
|
void bdinfo_print_str(const char *name, const char *str);
|
||||||
|
|
||||||
/* Print a clock speed in MHz */
|
/* Print a clock speed in MHz */
|
||||||
void bdinfo_print_mhz(const char *name, unsigned long hz);
|
void bdinfo_print_mhz(const char *name, unsigned long hz);
|
||||||
|
|
||||||
|
|||||||
@ -108,7 +108,21 @@ extern struct vesa_state mode_info;
|
|||||||
|
|
||||||
struct video_priv;
|
struct video_priv;
|
||||||
struct video_uc_plat;
|
struct video_uc_plat;
|
||||||
int vesa_setup_video_priv(struct vesa_mode_info *vesa,
|
|
||||||
|
/**
|
||||||
|
* vesa_setup_video_priv() - Set up a video device using VESA information
|
||||||
|
*
|
||||||
|
* The vesa struct is used by various x86 drivers, so this is a common function
|
||||||
|
* to use it to set up the video.
|
||||||
|
*
|
||||||
|
* @vesa: Vesa information to use (vesa->phys_base_ptr is ignored)
|
||||||
|
* @fb: Frame buffer address (since vesa->phys_base_ptr is only 32 bits)
|
||||||
|
* @uc_priv: Video device's uclass-private information
|
||||||
|
* @plat: Video devices's uclass-private platform data
|
||||||
|
* Returns: 0 if OK, -ENXIO if the x resolution is 0, -EEPROTONOSUPPORT if the
|
||||||
|
* pixel format is not supported
|
||||||
|
*/
|
||||||
|
int vesa_setup_video_priv(struct vesa_mode_info *vesa, u64 fb,
|
||||||
struct video_priv *uc_priv,
|
struct video_priv *uc_priv,
|
||||||
struct video_uc_plat *plat);
|
struct video_uc_plat *plat);
|
||||||
int vesa_setup_video(struct udevice *dev, int (*int15_handler)(void));
|
int vesa_setup_video(struct udevice *dev, int (*int15_handler)(void));
|
||||||
|
|||||||
@ -24,6 +24,7 @@ struct udevice;
|
|||||||
* @base: Base address of frame buffer, 0 if not yet known
|
* @base: Base address of frame buffer, 0 if not yet known
|
||||||
* @copy_base: Base address of a hardware copy of the frame buffer. See
|
* @copy_base: Base address of a hardware copy of the frame buffer. See
|
||||||
* CONFIG_VIDEO_COPY.
|
* CONFIG_VIDEO_COPY.
|
||||||
|
* @copy_size: Size of copy framebuffer, used if @size is 0
|
||||||
* @hide_logo: Hide the logo (used for testing)
|
* @hide_logo: Hide the logo (used for testing)
|
||||||
*/
|
*/
|
||||||
struct video_uc_plat {
|
struct video_uc_plat {
|
||||||
@ -31,6 +32,7 @@ struct video_uc_plat {
|
|||||||
uint size;
|
uint size;
|
||||||
ulong base;
|
ulong base;
|
||||||
ulong copy_base;
|
ulong copy_base;
|
||||||
|
ulong copy_size;
|
||||||
bool hide_logo;
|
bool hide_logo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -285,6 +285,15 @@ int vidconsole_put_string(struct udevice *dev, const char *str);
|
|||||||
void vidconsole_position_cursor(struct udevice *dev, unsigned col,
|
void vidconsole_position_cursor(struct udevice *dev, unsigned col,
|
||||||
unsigned row);
|
unsigned row);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vidconsole_clear_and_reset() - Clear the console and reset the cursor
|
||||||
|
*
|
||||||
|
* The cursor is placed at the start of the console
|
||||||
|
*
|
||||||
|
* @dev: vidconsole device to adjust
|
||||||
|
*/
|
||||||
|
int vidconsole_clear_and_reset(struct udevice *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vidconsole_set_cursor_pos() - set cursor position
|
* vidconsole_set_cursor_pos() - set cursor position
|
||||||
*
|
*
|
||||||
|
|||||||
@ -96,6 +96,8 @@ run_qemu() {
|
|||||||
fi
|
fi
|
||||||
if [[ -n "${serial}" ]]; then
|
if [[ -n "${serial}" ]]; then
|
||||||
extra="-display none -serial mon:stdio"
|
extra="-display none -serial mon:stdio"
|
||||||
|
else
|
||||||
|
extra="-serial mon:stdio"
|
||||||
fi
|
fi
|
||||||
echo "Running ${qemu}"
|
echo "Running ${qemu}"
|
||||||
# Use 512MB since U-Boot EFI likes to have 256MB to play with
|
# Use 512MB since U-Boot EFI likes to have 256MB to play with
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user