--- tools/firmware/hvmloader/hvmloader.c.org 2010-03-15 11:59:29.517930657 +0100 +++ tools/firmware/hvmloader/hvmloader.c 2010-03-15 12:04:59.486764339 +0100 @@ -115,6 +115,9 @@ unsigned long pci_mem_end = PCI_MEM_END; static enum { VGA_none, VGA_std, VGA_cirrus, VGA_pt } virtual_vga = VGA_none; +/* virtual BDF of pass-throughed gfx */ +static uint8_t gfx_bdf; + static void init_hypercalls(void) { uint32_t eax, ebx, ecx, edx; @@ -217,6 +220,42 @@ static void pci_setup(void) virtual_vga = VGA_cirrus; else if ( virtual_vga == VGA_none ) virtual_vga = VGA_pt; + gfx_bdf = devfn; + + /* Make vBAR=pBAR */ + printf("Make vBAR = pBAR of assigned gfx\n"); + for ( bar = 0; bar < 7; bar++ ) + { + bar_reg = PCI_BASE_ADDRESS_0 + 4*bar; + if ( bar == 6 ) + bar_reg = PCI_ROM_ADDRESS; + /* When first time read, it will return physical address */ + bar_data = pci_readl(devfn, bar_reg); + pci_writel(devfn, bar_reg, bar_data); + + /* Now enable the memory or I/O mapping. */ + cmd = pci_readw(devfn, PCI_COMMAND); + if ( (bar_reg == PCI_ROM_ADDRESS) || + ((bar_data & PCI_BASE_ADDRESS_SPACE) == + PCI_BASE_ADDRESS_SPACE_MEMORY) ) + cmd |= PCI_COMMAND_MEMORY; + else + cmd |= PCI_COMMAND_IO; + cmd |= PCI_COMMAND_MASTER; + pci_writew(devfn, PCI_COMMAND, cmd); + } + + /* Map the interrupt. */ + pin = pci_readb(devfn, PCI_INTERRUPT_PIN); + if ( pin != 0 ) + { + /* This is the barber's pole mapping used by Xen. */ + link = ((pin - 1) + (devfn >> 3)) & 3; + isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link); + pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq); + } + continue; + break; case 0x0680: /* PIIX4 ACPI PM. Special device with special PCI config space. */ @@ -690,8 +729,10 @@ int main(void) break; case VGA_pt: printf("Loading VGABIOS of passthroughed gfx ...\n"); - vgabios_sz = - round_option_rom((*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, + vgabios_pt, sizeof(vgabios_pt)); + *(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS + sizeof(vgabios_pt)) = gfx_bdf; + vgabios_sz = round_option_rom(sizeof(vgabios_pt) + 1); break; default: printf("No emulated VGA adaptor ...\n");