8 #include <boot/coreboot_tables.h>
9 #include <console/console.h>
10 #include <device/device.h>
11 #include <device/pci.h>
12 #include <device/pci_ids.h>
13 #include <device/pci_ops.h>
15 #include <pc80/vga_io.h>
17 /* VGA init. We use the Bochs VESA VBE extensions */
18 #define VBE_DISPI_IOPORT_INDEX 0x01CE
19 #define VBE_DISPI_IOPORT_DATA 0x01CF
21 #define VBE_DISPI_INDEX_ID 0x0
22 #define VBE_DISPI_INDEX_XRES 0x1
23 #define VBE_DISPI_INDEX_YRES 0x2
24 #define VBE_DISPI_INDEX_BPP 0x3
25 #define VBE_DISPI_INDEX_ENABLE 0x4
26 #define VBE_DISPI_INDEX_BANK 0x5
27 #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
28 #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
29 #define VBE_DISPI_INDEX_X_OFFSET 0x8
30 #define VBE_DISPI_INDEX_Y_OFFSET 0x9
31 #define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa
33 #define VBE_DISPI_ID0 0xB0C0
34 #define VBE_DISPI_ID1 0xB0C1
35 #define VBE_DISPI_ID2 0xB0C2
36 #define VBE_DISPI_ID4 0xB0C4
37 #define VBE_DISPI_ID5 0xB0C5
39 #define VBE_DISPI_DISABLED 0x00
40 #define VBE_DISPI_ENABLED 0x01
41 #define VBE_DISPI_LFB_ENABLED 0x40
42 #define VBE_DISPI_NOCLEARMEM 0x80
44 #if IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)
45 static int width
= CONFIG_DRIVERS_EMULATION_QEMU_BOCHS_XRES
;
46 static int height
= CONFIG_DRIVERS_EMULATION_QEMU_BOCHS_YRES
;
48 static void bochs_write(int index
, int val
)
50 outw(index
, VBE_DISPI_IOPORT_INDEX
);
51 outw(val
, VBE_DISPI_IOPORT_DATA
);
54 static int bochs_read(int index
)
56 outw(index
, VBE_DISPI_IOPORT_INDEX
);
57 return inw(VBE_DISPI_IOPORT_DATA
);
61 static void bochs_init(device_t dev
)
63 #if IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)
68 /* bochs dispi detection */
69 id
= bochs_read(VBE_DISPI_INDEX_ID
);
70 if ((id
& 0xfff0) != VBE_DISPI_ID0
) {
71 printk(BIOS_DEBUG
, "QEMU VGA: bochs dispi: ID mismatch.\n");
74 mem
= bochs_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K
) * 64 * 1024;
76 /* find lfb pci bar */
77 addr
= pci_read_config32(dev
, PCI_BASE_ADDRESS_0
);
78 if ((addr
& PCI_BASE_ADDRESS_SPACE
) == PCI_BASE_ADDRESS_SPACE_MEMORY
) {
79 /* qemu -vga {std,qxl} */
82 /* qemu -vga vmware */
83 addr
= pci_read_config32(dev
, PCI_BASE_ADDRESS_1
);
86 addr
&= ~PCI_BASE_ADDRESS_MEM_ATTR_MASK
;
91 printk(BIOS_DEBUG
, "QEMU VGA: bochs dispi interface found, "
92 "%d MiB video memory\n", mem
/ ( 1024 * 1024));
93 printk(BIOS_DEBUG
, "QEMU VGA: framebuffer @ %x (pci bar %d)\n",
96 /* setup video mode */
97 bochs_write(VBE_DISPI_INDEX_ENABLE
, 0);
98 bochs_write(VBE_DISPI_INDEX_BANK
, 0);
99 bochs_write(VBE_DISPI_INDEX_BPP
, 32);
100 bochs_write(VBE_DISPI_INDEX_XRES
, width
);
101 bochs_write(VBE_DISPI_INDEX_YRES
, height
);
102 bochs_write(VBE_DISPI_INDEX_VIRT_WIDTH
, width
);
103 bochs_write(VBE_DISPI_INDEX_VIRT_HEIGHT
, height
);
104 bochs_write(VBE_DISPI_INDEX_X_OFFSET
, 0);
105 bochs_write(VBE_DISPI_INDEX_Y_OFFSET
, 0);
106 bochs_write(VBE_DISPI_INDEX_ENABLE
,
107 VBE_DISPI_ENABLED
| VBE_DISPI_LFB_ENABLED
);
109 outb(0x20, 0x3c0); /* disable blanking */
111 /* setup coreboot framebuffer */
114 edid
.x_resolution
= width
;
115 edid
.y_resolution
= height
;
116 edid
.bytes_per_line
= width
* 4;
118 set_vbe_mode_info_valid(&edid
, addr
);
125 static struct device_operations qemu_graph_ops
= {
126 .read_resources
= pci_dev_read_resources
,
127 .set_resources
= pci_dev_set_resources
,
128 .enable_resources
= pci_dev_enable_resources
,
133 static const struct pci_driver qemu_stdvga_driver __pci_driver
= {
134 .ops
= &qemu_graph_ops
,
139 static const struct pci_driver qemu_vmware_driver __pci_driver
= {
140 .ops
= &qemu_graph_ops
,
144 static const struct pci_driver qemu_qxl_driver __pci_driver
= {
145 .ops
= &qemu_graph_ops
,