[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, &regs, vesa_mode, mode_info);
>   	if (vesa_mode != -1)
>   		atibios_set_vesa_mode(&regs, 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