bios_emulator: Add some VESA interface debugging

Allow the supported modes to be listed when in debug mode.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2014-12-29 19:32:26 -07:00
parent e78dd86998
commit 222f25f855
2 changed files with 150 additions and 24 deletions

View File

@ -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;
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);
memcpy(mode_info->mode_info_block, buffer,
sizeof(struct vbe_mode_info));
mode_info->valid = true;
if (regs->e.eax != 0x4f) {
debug("VESA_GET_MODE_INFO: error %x\n", regs->e.eax);
return -ENOSYS;
}
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);
memcpy(mode_info->mode_info_block, buffer,
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");
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);
}

View File

@ -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);