* [PATCH 0/2] device-assignment: option ROM support
@ 2009-05-06 15:48 Alex Williamson
2009-05-06 15:48 ` [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR Alex Williamson
2009-05-06 15:49 ` [PATCH 2/2] kvm: device-assignment: Add PCI option ROM support Alex Williamson
0 siblings, 2 replies; 4+ messages in thread
From: Alex Williamson @ 2009-05-06 15:48 UTC (permalink / raw)
To: kvm, sheng; +Cc: alex.williamson
This short series adds support for exposing PCI option ROMs on
pass-through devices. I'm hoping that someone with more BIOS-foo
can make use of this to dynamically load option ROMs from within
the BIOS such that we might be able to boot from a pass-through
device. I guess it's theoretically possible today, but the chance
of finding a server class device with a ROM small enough to
pre-load into the necessary address space is pretty slim.
---
Alex Williamson (2):
kvm: device-assignment: Add PCI option ROM support
kvm: bios: Use a different mask to size the option ROM BAR
hw/device-assignment.c | 59 ++++++++++++++++++++++++++++++++++++------------
hw/device-assignment.h | 5 +---
kvm/bios/rombios32.c | 8 ++++---
3 files changed, 50 insertions(+), 22 deletions(-)
--
Alex
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR
2009-05-06 15:48 [PATCH 0/2] device-assignment: option ROM support Alex Williamson
@ 2009-05-06 15:48 ` Alex Williamson
2009-05-07 12:10 ` Avi Kivity
2009-05-06 15:49 ` [PATCH 2/2] kvm: device-assignment: Add PCI option ROM support Alex Williamson
1 sibling, 1 reply; 4+ messages in thread
From: Alex Williamson @ 2009-05-06 15:48 UTC (permalink / raw)
To: kvm, sheng; +Cc: alex.williamson
Bit 0 is the enable bit, which we not only don't want to set, but
it will stick and make us think it's an I/O port resource.
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
---
kvm/bios/rombios32.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/kvm/bios/rombios32.c b/kvm/bios/rombios32.c
index 8684987..6502e63 100755
--- a/kvm/bios/rombios32.c
+++ b/kvm/bios/rombios32.c
@@ -958,11 +958,13 @@ static void pci_bios_init_device(PCIDevice *d)
int ofs;
uint32_t val, size ;
- if (i == PCI_ROM_SLOT)
+ if (i == PCI_ROM_SLOT) {
ofs = 0x30;
- else
+ pci_config_writel(d, ofs, 0xfffffffe);
+ } else {
ofs = 0x10 + i * 4;
- pci_config_writel(d, ofs, 0xffffffff);
+ pci_config_writel(d, ofs, 0xffffffff);
+ }
val = pci_config_readl(d, ofs);
if (val != 0) {
size = (~(val & ~0xf)) + 1;
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] kvm: device-assignment: Add PCI option ROM support
2009-05-06 15:48 [PATCH 0/2] device-assignment: option ROM support Alex Williamson
2009-05-06 15:48 ` [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR Alex Williamson
@ 2009-05-06 15:49 ` Alex Williamson
1 sibling, 0 replies; 4+ messages in thread
From: Alex Williamson @ 2009-05-06 15:49 UTC (permalink / raw)
To: kvm, sheng; +Cc: alex.williamson
The PCI code already knows about option ROMs, so we just need to
mmap some space for it, load it with a copy of the contents, and
complete the plubming to the generic code.
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
---
hw/device-assignment.c | 59 ++++++++++++++++++++++++++++++++++++------------
hw/device-assignment.h | 5 +---
2 files changed, 45 insertions(+), 19 deletions(-)
diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index 0a5f850..a7365c8 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -286,8 +286,8 @@ static void assigned_dev_pci_write_config(PCIDevice *d, uint32_t address,
/* Continue to program the card */
}
- if ((address >= 0x10 && address <= 0x24) || address == 0x34 ||
- address == 0x3c || address == 0x3d ||
+ if ((address >= 0x10 && address <= 0x24) || address == 0x30 ||
+ address == 0x34 || address == 0x3c || address == 0x3d ||
pci_access_cap_config(d, address, len)) {
/* used for update-mappings (BAR emulation) */
pci_default_write_config(d, address, val, len);
@@ -322,8 +322,8 @@ static uint32_t assigned_dev_pci_read_config(PCIDevice *d, uint32_t address,
AssignedDevice *pci_dev = container_of(d, AssignedDevice, dev);
if (address < 0x4 || (pci_dev->need_emulate_cmd && address == 0x4) ||
- (address >= 0x10 && address <= 0x24) || address == 0x34 ||
- address == 0x3c || address == 0x3d ||
+ (address >= 0x10 && address <= 0x24) || address == 0x30 ||
+ address == 0x34 || address == 0x3c || address == 0x3d ||
pci_access_cap_config(d, address, len)) {
val = pci_default_read_config(d, address, len);
DEBUG("(%x.%x): address=%04x val=0x%08x len=%d\n",
@@ -384,11 +384,20 @@ static int assigned_dev_register_regions(PCIRegion *io_regions,
/* map physical memory */
pci_dev->v_addrs[i].e_physbase = cur_region->base_addr;
- pci_dev->v_addrs[i].u.r_virtbase =
- mmap(NULL,
- (cur_region->size + 0xFFF) & 0xFFFFF000,
- PROT_WRITE | PROT_READ, MAP_SHARED,
- cur_region->resource_fd, (off_t) 0);
+ if (i == PCI_ROM_SLOT) {
+ pci_dev->v_addrs[i].u.r_virtbase =
+ mmap(NULL,
+ (cur_region->size + 0xFFF) & 0xFFFFF000,
+ PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE,
+ 0, (off_t) 0);
+
+ } else {
+ pci_dev->v_addrs[i].u.r_virtbase =
+ mmap(NULL,
+ (cur_region->size + 0xFFF) & 0xFFFFF000,
+ PROT_WRITE | PROT_READ, MAP_SHARED,
+ cur_region->resource_fd, (off_t) 0);
+ }
if (pci_dev->v_addrs[i].u.r_virtbase == MAP_FAILED) {
pci_dev->v_addrs[i].u.r_virtbase = NULL;
@@ -397,6 +406,14 @@ static int assigned_dev_register_regions(PCIRegion *io_regions,
(uint32_t) (cur_region->base_addr));
return -1;
}
+
+ if (i == PCI_ROM_SLOT) {
+ memset(pci_dev->v_addrs[i].u.r_virtbase, 0,
+ (cur_region->size + 0xFFF) & 0xFFFFF000);
+ mprotect(pci_dev->v_addrs[PCI_ROM_SLOT].u.r_virtbase,
+ (cur_region->size + 0xFFF) & 0xFFFFF000, PROT_READ);
+ }
+
pci_dev->v_addrs[i].r_size = cur_region->size;
pci_dev->v_addrs[i].e_size = 0;
@@ -468,7 +485,7 @@ again:
return 1;
}
- for (r = 0; r < MAX_IO_REGIONS; r++) {
+ for (r = 0; r < PCI_NUM_REGIONS; r++) {
if (fscanf(f, "%lli %lli %lli\n", &start, &end, &flags) != 3)
break;
@@ -480,11 +497,13 @@ again:
continue;
if (flags & IORESOURCE_MEM) {
flags &= ~IORESOURCE_IO;
- snprintf(name, sizeof(name), "%sresource%d", dir, r);
- fd = open(name, O_RDWR);
- if (fd == -1)
- continue; /* probably ROM */
- rp->resource_fd = fd;
+ if (r != PCI_ROM_SLOT) {
+ snprintf(name, sizeof(name), "%sresource%d", dir, r);
+ fd = open(name, O_RDWR);
+ if (fd == -1)
+ continue;
+ rp->resource_fd = fd;
+ }
} else
flags &= ~IORESOURCE_PREFETCH;
@@ -1391,6 +1410,16 @@ ram_addr_t assigned_dev_load_option_roms(ram_addr_t rom_base_offset)
continue;
}
+ if (adev->assigned_dev->v_addrs[PCI_ROM_SLOT].r_size >= size &&
+ adev->assigned_dev->v_addrs[PCI_ROM_SLOT].u.r_virtbase) {
+ mprotect(adev->assigned_dev->v_addrs[PCI_ROM_SLOT].u.r_virtbase,
+ size, PROT_READ | PROT_WRITE);
+ memcpy(adev->assigned_dev->v_addrs[PCI_ROM_SLOT].u.r_virtbase,
+ buf, size);
+ mprotect(adev->assigned_dev->v_addrs[PCI_ROM_SLOT].u.r_virtbase,
+ size, PROT_READ);
+ }
+
/* Scan the buffer for suitable ROMs and increase the offset */
offset += scan_option_rom(adev->assigned_dev->dev.devfn, buf, offset);
diff --git a/hw/device-assignment.h b/hw/device-assignment.h
index c691e11..713f9b7 100644
--- a/hw/device-assignment.h
+++ b/hw/device-assignment.h
@@ -36,9 +36,6 @@
/* From include/linux/pci.h in the kernel sources */
#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
-/* The number of BARs in the config space header */
-#define MAX_IO_REGIONS (6)
-
typedef struct {
int type; /* Memory or port I/O */
int valid;
@@ -53,7 +50,7 @@ typedef struct {
uint16_t region_number; /* number of active regions */
/* Port I/O or MMIO Regions */
- PCIRegion regions[MAX_IO_REGIONS];
+ PCIRegion regions[PCI_NUM_REGIONS];
int config_fd;
} PCIDevRegions;
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR
2009-05-06 15:48 ` [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR Alex Williamson
@ 2009-05-07 12:10 ` Avi Kivity
0 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2009-05-07 12:10 UTC (permalink / raw)
To: Alex Williamson; +Cc: kvm, sheng
Alex Williamson wrote:
> Bit 0 is the enable bit, which we not only don't want to set, but
> it will stick and make us think it's an I/O port resource.
>
> Signed-off-by: Alex Williamson <alex.williamson@hp.com>
> ---
>
> kvm/bios/rombios32.c | 8 +++++---
> 1 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/kvm/bios/rombios32.c b/kvm/bios/rombios32.c
> index 8684987..6502e63 100755
> --- a/kvm/bios/rombios32.c
> +++ b/kvm/bios/rombios32.c
> @@ -958,11 +958,13 @@ static void pci_bios_init_device(PCIDevice *d)
> int ofs;
> uint32_t val, size ;
>
> - if (i == PCI_ROM_SLOT)
> + if (i == PCI_ROM_SLOT) {
> ofs = 0x30;
> - else
> + pci_config_writel(d, ofs, 0xfffffffe);
> + } else {
> ofs = 0x10 + i * 4;
> - pci_config_writel(d, ofs, 0xffffffff);
> + pci_config_writel(d, ofs, 0xffffffff);
> + }
> val = pci_config_readl(d, ofs);
> if (val != 0) {
> size = (~(val & ~0xf)) + 1;
>
Looks good. I think it applies upstream (or even upstream's upstream)
though, in which case please send it qemu-devel.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-05-07 12:10 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-06 15:48 [PATCH 0/2] device-assignment: option ROM support Alex Williamson
2009-05-06 15:48 ` [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR Alex Williamson
2009-05-07 12:10 ` Avi Kivity
2009-05-06 15:49 ` [PATCH 2/2] kvm: device-assignment: Add PCI option ROM support Alex Williamson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.