e820->nr_map = i;
}
+static void setup_vga_rom(struct kvm *kvm)
+{
+ u16 *mode;
+ void *p;
+
+ p = guest_flat_to_host(kvm, VGA_ROM_OEM_STRING);
+ memset(p, 0, VGA_ROM_OEM_STRING_SIZE);
+ strncpy(p, "KVM VESA", VGA_ROM_OEM_STRING_SIZE);
+
+ mode = guest_flat_to_host(kvm, VGA_ROM_MODES);
+ mode[0] = 0x0112;
+ mode[1] = 0xffff;
+}
+
/**
* setup_bios - inject BIOS into guest memory
* @kvm - guest system descriptor
/* E820 memory map must be present */
e820_setup(kvm);
+ /* VESA needs own tricks */
+ setup_vga_rom(kvm);
+
/*
* Setup a *fake* real mode vector table, it has only
* one real hadler which does just iret
#include "bios/memcpy.h"
-#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
-
-/* VESA General Information table */
-struct vesa_general_info {
- u32 signature; /* 0 Magic number = "VESA" */
- u16 version; /* 4 */
- void *vendor_string; /* 6 */
- u32 capabilities; /* 10 */
- void *video_mode_ptr; /* 14 */
- u16 total_memory; /* 18 */
- u16 modes[2]; /* 20 */
- char oem_string[11]; /* 24 */
-
- u8 reserved[223]; /* 35 */
-} __attribute__ ((packed));
-
-struct vminfo {
- u16 mode_attr; /* 0 */
- u8 win_attr[2]; /* 2 */
- u16 win_grain; /* 4 */
- u16 win_size; /* 6 */
- u16 win_seg[2]; /* 8 */
- u32 win_scheme; /* 12 */
- u16 logical_scan; /* 16 */
-
- u16 h_res; /* 18 */
- u16 v_res; /* 20 */
- u8 char_width; /* 22 */
- u8 char_height; /* 23 */
- u8 memory_planes; /* 24 */
- u8 bpp; /* 25 */
- u8 banks; /* 26 */
- u8 memory_layout; /* 27 */
- u8 bank_size; /* 28 */
- u8 image_planes; /* 29 */
- u8 page_function; /* 30 */
-
- u8 rmask; /* 31 */
- u8 rpos; /* 32 */
- u8 gmask; /* 33 */
- u8 gpos; /* 34 */
- u8 bmask; /* 35 */
- u8 bpos; /* 36 */
- u8 resv_mask; /* 37 */
- u8 resv_pos; /* 38 */
- u8 dcm_info; /* 39 */
-
- u32 lfb_ptr; /* 40 Linear frame buffer address */
- u32 offscreen_ptr; /* 44 Offscreen memory address */
- u16 offscreen_size; /* 48 */
-
- u8 reserved[206]; /* 50 */
-};
+#include <boot/vesa.h>
+
+static far_ptr gen_far_ptr(unsigned int pa)
+{
+ far_ptr ptr;
+
+ ptr.seg = (pa >> 4);
+ ptr.off = pa - (ptr.seg << 4);
+
+ return ptr;
+}
static inline void outb(unsigned short port, unsigned char val)
{
static void vbe_get_mode(struct biosregs *args)
{
- struct vminfo *info = (struct vminfo *) args->edi;
+ struct vesa_mode_info *info = (struct vesa_mode_info *) args->edi;
- *info = (struct vminfo) {
+ *info = (struct vesa_mode_info) {
.mode_attr = 0xd9, /* 11011011 */
.logical_scan = VESA_WIDTH*4,
.h_res = VESA_WIDTH,
info = (struct vesa_general_info) {
.signature = VESA_MAGIC,
.version = 0x102,
- .vendor_string = &infop->oem_string,
+ .vendor_string = gen_far_ptr(VGA_ROM_BEGIN),
.capabilities = 0x10,
- .video_mode_ptr = &infop->modes,
+ .video_mode_ptr = gen_far_ptr(VGA_ROM_MODES),
.total_memory = (4 * VESA_WIDTH * VESA_HEIGHT) / 0x10000,
- .oem_string = "KVM VESA",
- .modes = { 0x0112, 0xffff },
};
memcpy16(args->es, infop, args->ds, &info, sizeof(info));