[U-Boot] [PATCH 05/10] bios_emulator: Add some VESA interface debugging
Heinrich Schuchardt
xypron.glpk at gmx.de
Tue Jul 30 20:52:25 UTC 2019
On 12/30/14 3:32 AM, Simon Glass wrote:
> Allow the supported modes to be listed when in debug mode.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> drivers/bios_emulator/atibios.c | 161 +++++++++++++++++++++++++++++++++++-----
> include/vbe.h | 9 ++-
> 2 files changed, 148 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c
> index 93b815c..7ea5fa6 100644
> --- a/drivers/bios_emulator/atibios.c
> +++ b/drivers/bios_emulator/atibios.c
> @@ -62,40 +62,158 @@ static u32 saveBaseAddress14;
> static u32 saveBaseAddress18;
> static u32 saveBaseAddress20;
>
> -static void atibios_set_vesa_mode(RMREGS *regs, int vesa_mode,
> - struct vbe_mode_info *mode_info)
> +/* Addres im memory of VBE region */
> +const int vbe_offset = 0x2000;
> +
> +static const void *bios_ptr(const void *buf, BE_VGAInfo *vga_info,
> + u32 x86_dword_ptr)
> +{
> + u32 seg_ofs, flat;
> +
> + seg_ofs = le32_to_cpu(x86_dword_ptr);
> + flat = ((seg_ofs & 0xffff0000) >> 12) | (seg_ofs & 0xffff);
> + if (flat >= 0xc0000)
> + return vga_info->BIOSImage + flat - 0xc0000;
> + else
> + return buf + (flat - vbe_offset);
> +}
> +
> +static int atibios_debug_mode(BE_VGAInfo *vga_info, RMREGS *regs,
> + int vesa_mode, struct vbe_mode_info *mode_info)
> +{
> + void *buffer = (void *)(M.mem_base + vbe_offset);
> + u16 buffer_seg = (((unsigned long)vbe_offset) >> 4) & 0xff00;
> + u16 buffer_adr = ((unsigned long)vbe_offset) & 0xffff;
> + struct vesa_mode_info *vm;
> + struct vbe_info *info;
> + const u16 *modes_bios, *ptr;
> + u16 *modes;
> + int size;
> +
> + debug("VBE: Getting information\n");
> + regs->e.eax = VESA_GET_INFO;
> + regs->e.esi = buffer_seg;
> + regs->e.edi = buffer_adr;
> + info = buffer;
> + memset(info, '\0', sizeof(*info));
> + strcpy(info->signature, "VBE2");
> + BE_int86(0x10, regs, regs);
> + if (regs->e.eax != 0x4f) {
> + debug("VESA_GET_INFO: error %x\n", regs->e.eax);
> + return -ENOSYS;
> + }
> + debug("version %x\n", le16_to_cpu(info->version));
> + debug("oem '%s'\n", (char *)bios_ptr(buffer, vga_info,
> + info->oem_string_ptr));
> + debug("vendor '%s'\n", (char *)bios_ptr(buffer, vga_info,
> + info->vendor_name_ptr));
> + debug("product '%s'\n", (char *)bios_ptr(buffer, vga_info,
> + info->product_name_ptr));
> + debug("rev '%s'\n", (char *)bios_ptr(buffer, vga_info,
> + info->product_rev_ptr));
> + modes_bios = bios_ptr(buffer, vga_info, info->modes_ptr);
> + debug("Modes: ");
> + for (ptr = modes_bios; *ptr != 0xffff; ptr++)
> + debug("%x ", le16_to_cpu(*ptr));
> + debug("\nmemory %dMB\n", le16_to_cpu(info->total_memory) >> 4);
> + size = (ptr - modes_bios) * sizeof(u16) + 2;
> + modes = malloc(size);
> + if (!modes)
> + return -ENOMEM;
> + memcpy(modes, modes_bios, size);
> +
> + regs->e.eax = VESA_GET_CUR_MODE;
> + BE_int86(0x10, regs, regs);
> + if (regs->e.eax != 0x4f) {
> + debug("VESA_GET_CUR_MODE: error %x\n", regs->e.eax);
> + return -ENOSYS;
> + }
> + debug("Current mode %x\n", regs->e.ebx);
> +
> + for (ptr = modes; *ptr != 0xffff; ptr++) {
> + int mode = le16_to_cpu(*ptr);
> + bool linear_ok;
> + int attr;
> +
> + break;
There is a lot of dead code following. Has this break been left over
from debugging? Or should the whole loop be eliminated?
Best regards
Heinrich
> + debug("Mode %x: ", mode);
> + memset(buffer, '\0', sizeof(struct vbe_mode_info));
> + regs->e.eax = VESA_GET_MODE_INFO;
> + regs->e.ebx = 0;
> + regs->e.ecx = mode;
> + regs->e.edx = 0;
> + regs->e.esi = buffer_seg;
> + regs->e.edi = buffer_adr;
> + BE_int86(0x10, regs, regs);
> + if (regs->e.eax != 0x4f) {
> + debug("VESA_GET_MODE_INFO: error %x\n", regs->e.eax);
> + continue;
> + }
> + memcpy(mode_info->mode_info_block, buffer,
> + sizeof(struct vesa_mode_info));
> + mode_info->valid = true;
> + vm = &mode_info->vesa;
> + attr = le16_to_cpu(vm->mode_attributes);
> + linear_ok = attr & 0x80;
> + debug("res %d x %d, %d bpp, mm %d, (Linear %s, attr %02x)\n",
> + le16_to_cpu(vm->x_resolution),
> + le16_to_cpu(vm->y_resolution),
> + vm->bits_per_pixel, vm->memory_model,
> + linear_ok ? "OK" : "not available",
> + attr);
> + debug("\tRGB pos=%d,%d,%d, size=%d,%d,%d\n",
> + vm->red_mask_pos, vm->green_mask_pos, vm->blue_mask_pos,
> + vm->red_mask_size, vm->green_mask_size,
> + vm->blue_mask_size);
> + }
> +
> + return 0;
> +}
> +
> +static int atibios_set_vesa_mode(RMREGS *regs, int vesa_mode,
> + struct vbe_mode_info *mode_info)
> {
> + void *buffer = (void *)(M.mem_base + vbe_offset);
> + u16 buffer_seg = (((unsigned long)vbe_offset) >> 4) & 0xff00;
> + u16 buffer_adr = ((unsigned long)vbe_offset) & 0xffff;
> + struct vesa_mode_info *vm;
> +
> debug("VBE: Setting VESA mode %#04x\n", vesa_mode);
> - /* request linear framebuffer mode */
> - vesa_mode |= (1 << 14);
> - /* request clearing of framebuffer */
> - vesa_mode &= ~(1 << 15);
> regs->e.eax = VESA_SET_MODE;
> regs->e.ebx = vesa_mode;
> + /* request linear framebuffer mode and don't clear display */
> + regs->e.ebx |= (1 << 14) | (1 << 15);
> BE_int86(0x10, regs, regs);
> + if (regs->e.eax != 0x4f) {
> + debug("VESA_SET_MODE: error %x\n", regs->e.eax);
> + return -ENOSYS;
> + }
>
> - int offset = 0x2000;
> - void *buffer = (void *)(M.mem_base + offset);
> -
> - u16 buffer_seg = (((unsigned long)offset) >> 4) & 0xff00;
> - u16 buffer_adr = ((unsigned long)offset) & 0xffff;
> + memset(buffer, '\0', sizeof(struct vbe_mode_info));
> + debug("VBE: Geting info for VESA mode %#04x\n", vesa_mode);
> regs->e.eax = VESA_GET_MODE_INFO;
> - regs->e.ebx = 0;
> regs->e.ecx = vesa_mode;
> - regs->e.edx = 0;
> regs->e.esi = buffer_seg;
> regs->e.edi = buffer_adr;
> BE_int86(0x10, regs, regs);
> + if (regs->e.eax != 0x4f) {
> + debug("VESA_GET_MODE_INFO: error %x\n", regs->e.eax);
> + return -ENOSYS;
> + }
> +
> memcpy(mode_info->mode_info_block, buffer,
> - sizeof(struct vbe_mode_info));
> + sizeof(struct vesa_mode_info));
> mode_info->valid = true;
> + mode_info->video_mode = vesa_mode;
> + vm = &mode_info->vesa;
> + vm->x_resolution = le16_to_cpu(vm->x_resolution);
> + vm->y_resolution = le16_to_cpu(vm->y_resolution);
> + vm->bytes_per_scanline = le16_to_cpu(vm->bytes_per_scanline);
> + vm->phys_base_ptr = le32_to_cpu(vm->phys_base_ptr);
> + vm->mode_attributes = le16_to_cpu(vm->mode_attributes);
> + debug("VBE: Init complete\n");
>
> - vesa_mode |= (1 << 14);
> - /* request clearing of framebuffer */
> - vesa_mode &= ~(1 << 15);
> - regs->e.eax = VESA_SET_MODE;
> - regs->e.ebx = vesa_mode;
> - BE_int86(0x10, regs, regs);
> + return 0;
> }
>
> /****************************************************************************
> @@ -132,6 +250,9 @@ static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo *vga_info,
> /*Cleanup and exit*/
> BE_getVGA(vga_info);
>
> + /* Useful for debugging */
> + if (0)
> + atibios_debug_mode(vga_info, ®s, vesa_mode, mode_info);
> if (vesa_mode != -1)
> atibios_set_vesa_mode(®s, vesa_mode, mode_info);
> }
> diff --git a/include/vbe.h b/include/vbe.h
> index d405691..c5deee9 100644
> --- a/include/vbe.h
> +++ b/include/vbe.h
> @@ -35,10 +35,14 @@ struct __packed screen_info_input {
> struct __packed vbe_info {
> char signature[4];
> u16 version;
> - u8 *oem_string_ptr;
> + u32 oem_string_ptr;
> u32 capabilities;
> - u16 video_mode_list[256];
> + u32 modes_ptr;
> u16 total_memory;
> + u16 oem_version;
> + u32 vendor_name_ptr;
> + u32 product_name_ptr;
> + u32 product_rev_ptr;
> };
>
> struct __packed vesa_mode_info {
> @@ -96,6 +100,7 @@ struct vbe_ddc_info {
> #define VESA_GET_INFO 0x4f00
> #define VESA_GET_MODE_INFO 0x4f01
> #define VESA_SET_MODE 0x4f02
> +#define VESA_GET_CUR_MODE 0x4f03
>
> struct graphic_device;
> int vbe_get_video_info(struct graphic_device *gdev);
>
More information about the U-Boot
mailing list