Patchwork [1/8] Support PCI based option rom loading

login
register
mail settings
Submitter Gerd Hoffmann
Date Dec. 18, 2009, 11:01 a.m.
Message ID <1261134074-11795-2-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/41382/
State New
Headers show

Comments

Gerd Hoffmann - Dec. 18, 2009, 11:01 a.m.
From: Anthony Liguori <aliguori@us.ibm.com>

Currently, we preload option roms into the option rom space in memory.  This
prevents DDIM from functioning correctly which severely limits the number
of roms we can support.

This patch introduces a pci_add_option_rom() which registers the
PCI_ROM_ADDRESS bar which points to our option rom.  It also converts over
the cirrus vga adapter, the rtl8139, virtio, and the e1000 to use this
new mechanism.

The result is that PXE boot functions even with three unique types of cards.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/cirrus_vga.c |    2 +-
 hw/e1000.c      |    2 +-
 hw/pci.c        |   35 +++++++++++++++++++++++++++++++++++
 hw/pci.h        |    5 +++++
 hw/rtl8139.c    |    2 +-
 hw/virtio-pci.c |    2 +-
 6 files changed, 44 insertions(+), 4 deletions(-)
Blue Swirl - Dec. 19, 2009, 10:57 a.m.
On Fri, Dec 18, 2009 at 11:01 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
> From: Anthony Liguori <aliguori@us.ibm.com>
>
> Currently, we preload option roms into the option rom space in memory.  This
> prevents DDIM from functioning correctly which severely limits the number
> of roms we can support.
>
> This patch introduces a pci_add_option_rom() which registers the
> PCI_ROM_ADDRESS bar which points to our option rom.  It also converts over
> the cirrus vga adapter, the rtl8139, virtio, and the e1000 to use this
> new mechanism.

This means that the VGA roms are now visible for all targets, not just
when rom_enable_driver_roms is true. I'm not opposing this, but it may
create regressions.
Anthony Liguori - Dec. 20, 2009, 3:34 p.m.
Blue Swirl wrote:
> On Fri, Dec 18, 2009 at 11:01 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
>   
>> From: Anthony Liguori <aliguori@us.ibm.com>
>>
>> Currently, we preload option roms into the option rom space in memory.  This
>> prevents DDIM from functioning correctly which severely limits the number
>> of roms we can support.
>>
>> This patch introduces a pci_add_option_rom() which registers the
>> PCI_ROM_ADDRESS bar which points to our option rom.  It also converts over
>> the cirrus vga adapter, the rtl8139, virtio, and the e1000 to use this
>> new mechanism.
>>     
>
> This means that the VGA roms are now visible for all targets, not just
> when rom_enable_driver_roms is true. I'm not opposing this, but it may
> create regressions.
>   

This is pretty normal on bare metal though, no?  I thought a lot of 
non-x86 systems actually use x86 emulators specifically to enable 
support for these roms.

Regards,

Anthony Liguori
Blue Swirl - Dec. 20, 2009, 5:02 p.m.
On Sun, Dec 20, 2009 at 3:34 PM, Anthony Liguori <anthony@codemonkey.ws> wrote:
> Blue Swirl wrote:
>>
>> On Fri, Dec 18, 2009 at 11:01 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
>>
>>>
>>> From: Anthony Liguori <aliguori@us.ibm.com>
>>>
>>> Currently, we preload option roms into the option rom space in memory.
>>>  This
>>> prevents DDIM from functioning correctly which severely limits the number
>>> of roms we can support.
>>>
>>> This patch introduces a pci_add_option_rom() which registers the
>>> PCI_ROM_ADDRESS bar which points to our option rom.  It also converts
>>> over
>>> the cirrus vga adapter, the rtl8139, virtio, and the e1000 to use this
>>> new mechanism.
>>>
>>
>> This means that the VGA roms are now visible for all targets, not just
>> when rom_enable_driver_roms is true. I'm not opposing this, but it may
>> create regressions.
>>
>
> This is pretty normal on bare metal though, no?  I thought a lot of non-x86
> systems actually use x86 emulators specifically to enable support for these
> roms.

I think so too, but ROM loading was first introduced with
rom_enable_driver_roms mechanism just for cases like this.

But if there are no regressions, rom_enable_driver_roms mechanism
could be removed.
Alexander Graf - Dec. 20, 2009, 5:18 p.m.
On 20.12.2009, at 18:02, Blue Swirl wrote:

> On Sun, Dec 20, 2009 at 3:34 PM, Anthony Liguori <anthony@codemonkey.ws> wrote:
>> Blue Swirl wrote:
>>> 
>>> On Fri, Dec 18, 2009 at 11:01 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
>>> 
>>>> 
>>>> From: Anthony Liguori <aliguori@us.ibm.com>
>>>> 
>>>> Currently, we preload option roms into the option rom space in memory.
>>>>  This
>>>> prevents DDIM from functioning correctly which severely limits the number
>>>> of roms we can support.
>>>> 
>>>> This patch introduces a pci_add_option_rom() which registers the
>>>> PCI_ROM_ADDRESS bar which points to our option rom.  It also converts
>>>> over
>>>> the cirrus vga adapter, the rtl8139, virtio, and the e1000 to use this
>>>> new mechanism.
>>>> 
>>> 
>>> This means that the VGA roms are now visible for all targets, not just
>>> when rom_enable_driver_roms is true. I'm not opposing this, but it may
>>> create regressions.
>>> 
>> 
>> This is pretty normal on bare metal though, no?  I thought a lot of non-x86
>> systems actually use x86 emulators specifically to enable support for these
>> roms.
> 
> I think so too, but ROM loading was first introduced with
> rom_enable_driver_roms mechanism just for cases like this.
> 
> But if there are no regressions, rom_enable_driver_roms mechanism
> could be removed.

Don't macs usually have a powerpc vgabios?

I don't think we'd introduce regressions, just something you wouldn't find in a real machine. But then again the mac target isn't exactly that close to real hw anyways ...

Alex
Anthony Liguori - Dec. 20, 2009, 5:55 p.m.
Alexander Graf wrote:
> Don't macs usually have a powerpc vgabios?
>   
I'm not certain, but this is what x86emu is for in X11.

VGA is a PC concept and just about nothing about it really make sense on 
a different architecture.  The interface is an extension of the PC BIOS 
(software interrupts) and the dictated memory layouts are specific to 
the x86.  I think most non-x86 systems have to use native drivers for 
whatever graphics cards they support from the start.

Regards,

Anthony Liguori
Alexander Graf - Dec. 20, 2009, 6:01 p.m.
On 20.12.2009, at 18:55, Anthony Liguori wrote:

> Alexander Graf wrote:
>> Don't macs usually have a powerpc vgabios?
>>  
> I'm not certain, but this is what x86emu is for in X11.
> 
> VGA is a PC concept and just about nothing about it really make sense on a different architecture.  The interface is an extension of the PC BIOS (software interrupts) and the dictated memory layouts are specific to the x86.  I think most non-x86 systems have to use native drivers for whatever graphics cards they support from the start.

Yes. The Alpha for example used stock VGABIOSes. IIRC Sparc has its own graphics anyways and I don't know about the others, but I suspect they either use x86 VGABIOSes or no VGABIOSes.

Macs are different though. IIRC they have a normal VGA interface in ppc logic, but I might be wrong. Maybe it's also some OpenFirmware stuff. They definitely don't have an x86 VGABIOS in the graphics card's rom slot, but something different.

Since we're using the Cirrus on Macs, I guess we'd need a Cirrus PPC VGABIOS - phew.

Other PPCs on the other hand, such as the Powerstation, use x86 roms.

Oh well, let's just export the x86 one for now but use video.x for video output. Looks like there'd be quite a lot of work involved in getting it aligned to real world mac hw :-(.

Alex

PS: Ben, please correct me if I'm wrong.
Andreas Färber - Dec. 20, 2009, 6:24 p.m.
Am 20.12.2009 um 19:01 schrieb Alexander Graf:

>
> On 20.12.2009, at 18:55, Anthony Liguori wrote:
>
>> Alexander Graf wrote:
>>> Don't macs usually have a powerpc vgabios?
>>>
>> I'm not certain, but this is what x86emu is for in X11.
>>
>> VGA is a PC concept and just about nothing about it really make  
>> sense on a different architecture.  The interface is an extension  
>> of the PC BIOS (software interrupts) and the dictated memory  
>> layouts are specific to the x86.  I think most non-x86 systems have  
>> to use native drivers for whatever graphics cards they support from  
>> the start.
>
> Yes. The Alpha for example used stock VGABIOSes. IIRC Sparc has its  
> own graphics anyways and I don't know about the others, but I  
> suspect they either use x86 VGABIOSes or no VGABIOSes.
>
> Macs are different though. IIRC they have a normal VGA interface in  
> ppc logic, but I might be wrong. Maybe it's also some OpenFirmware  
> stuff. They definitely don't have an x86 VGABIOS in the graphics  
> card's rom slot, but something different.
>
> Since we're using the Cirrus on Macs, I guess we'd need a Cirrus PPC  
> VGABIOS - phew.

ATI used to sell special "Mac Edition" graphics cards. That would seem  
to back up the possibility of a ppc VGABIOS on Mac.

Never tried putting such a card into a PC though or vice versa. Maybe  
we'd get the same sick-coloured penguins then...? ;)

Andreas

> Other PPCs on the other hand, such as the Powerstation, use x86 roms.
>
> Oh well, let's just export the x86 one for now but use video.x for  
> video output. Looks like there'd be quite a lot of work involved in  
> getting it aligned to real world mac hw :-(.
>
> Alex
>
> PS: Ben, please correct me if I'm wrong.
>
Blue Swirl - Dec. 20, 2009, 6:53 p.m.
On Sun, Dec 20, 2009 at 6:24 PM, Andreas Färber <andreas.faerber@web.de> wrote:
>
> Am 20.12.2009 um 19:01 schrieb Alexander Graf:
>
>>
>> On 20.12.2009, at 18:55, Anthony Liguori wrote:
>>
>>> Alexander Graf wrote:
>>>>
>>>> Don't macs usually have a powerpc vgabios?
>>>>
>>> I'm not certain, but this is what x86emu is for in X11.
>>>
>>> VGA is a PC concept and just about nothing about it really make sense on
>>> a different architecture.  The interface is an extension of the PC BIOS
>>> (software interrupts) and the dictated memory layouts are specific to the
>>> x86.  I think most non-x86 systems have to use native drivers for whatever
>>> graphics cards they support from the start.
>>
>> Yes. The Alpha for example used stock VGABIOSes. IIRC Sparc has its own
>> graphics anyways and I don't know about the others, but I suspect they
>> either use x86 VGABIOSes or no VGABIOSes.
>>
>> Macs are different though. IIRC they have a normal VGA interface in ppc
>> logic, but I might be wrong. Maybe it's also some OpenFirmware stuff. They
>> definitely don't have an x86 VGABIOS in the graphics card's rom slot, but
>> something different.
>>
>> Since we're using the Cirrus on Macs, I guess we'd need a Cirrus PPC
>> VGABIOS - phew.
>
> ATI used to sell special "Mac Edition" graphics cards. That would seem to
> back up the possibility of a ppc VGABIOS on Mac.

Some Sun machines also had "ATY,Rage XL" cards but I don't know if
they had special roms.
Benjamin Herrenschmidt - Dec. 20, 2009, 9:23 p.m.
On Sun, 2009-12-20 at 19:01 +0100, Alexander Graf wrote:
> 
> Yes. The Alpha for example used stock VGABIOSes. IIRC Sparc has its
> own graphics anyways and I don't know about the others, but I suspect
> they either use x86 VGABIOSes or no VGABIOSes.
> 
> Macs are different though. IIRC they have a normal VGA interface in
> ppc logic, but I might be wrong. Maybe it's also some OpenFirmware
> stuff. They definitely don't have an x86 VGABIOS in the graphics
> card's rom slot, but something different.
> 
> Since we're using the Cirrus on Macs, I guess we'd need a Cirrus PPC
> VGABIOS - phew.
> 
> Other PPCs on the other hand, such as the Powerstation, use x86 roms.
> 
> Oh well, let's just export the x86 one for now but use video.x for
> video output. Looks like there'd be quite a lot of work involved in
> getting it aligned to real world mac hw :-(.

Hrm, I missed the beginning of the story :-) But basically here's what
things look like vs. option ROMs on powerpc:

 - Most Open Firmware based machines (pSeries and Macs) can load some
f-code firmware from there (tokenized forth). The f-code is platform
agnostic (in theory, Apple did play games in that area) and so in theory
the same f-code would work on, for example, an x86 with Open Firmware
(if you had a slot on the OLPC you could try :-)

 - That f-code firmware is used for whatever initializations the card
need (for example, video cards generally need specific inits before
being usable at all by the OS, at least older ones do). It can create
additional properties in the device-tree as well.

 - On Macs specifically, they have a trick consisting of putting a
powerpc MacOS video driver in there, in the form of one big property
(AAPL,NDRV iirc). This is a MacOS 7/8/9 style PEF driver but generally
compiled and linked to work in a very limited environment for which OS X
provides a sandbox, and which provides basic monitor detection and mode
settings. video.x is such a driver (I wrote it :-) though I don't
remember precisely whether the video.x file is the raw NDRV or the
packaged f-code which contains the ndrv).

 - Some powerpc machines (Pegasos, Efika, PowerStation, ... ) also have
an x86emu variant in their firmware that can load a VGA ROM and use it
to setup some kind of boot display for the firmware.

 - An option ROM can contain multiple images :-) IE. It can contain
-both- the x86 style ROM and the Open Firmware style f-code...

Now, in the light of the above, what is interesting to do on qemu ?

It all depends how "close" we consider OpenBIOS to be from qemu. If
"close" then we don't need any of the f-code stuff. OpenBIOS could use
some private calls to inside qemu and be done with it, including for
sucking the video.x MacOS driver if the machine "profile" is a Mac (see
the discussions on using the device-tree to define machines inside qemu,
I believe that would be a great improvement).

A VGA ROM is not really useful past the firmware stage on ppc, as
generally X is built without Int10 and we cannot really do anything with
it appart from the FW initializing the card. This is not true of real
ATI or nVidia cards because their driver uses tables in the VGA ROM for
various things but that isn't necessarily very useful for qemu. But on
the other hand, it doesn't hurt to have it there.

We should also look formward to native flat device tree booting without
OpenBIOS in which case we probably don't care much (though again a VGA
ROM might prove useful if whatever we boot has an x86emu variant).

Cheers,
Ben.
Benjamin Herrenschmidt - Dec. 20, 2009, 9:24 p.m.
On Sun, 2009-12-20 at 18:53 +0000, Blue Swirl wrote:
> 
> Some Sun machines also had "ATY,Rage XL" cards but I don't know if
> they had special roms. 

They would have similar f-code to the mac ones (ie. Tokenized forth for
Open Firmware).

However, in the case of qemu, I don't see much point in doing so for the
sake of OpenBIOS :-)

Cheers
Ben.

Patch

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 24af81c..b08d2ae 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -3211,7 +3211,7 @@  static int pci_cirrus_vga_initfn(PCIDevice *dev)
      }
 
      /* ROM BIOS */
-     rom_add_vga(VGABIOS_CIRRUS_FILENAME);
+     pci_add_option_rom((PCIDevice *)d, VGABIOS_CIRRUS_FILENAME);
      return 0;
 }
 
diff --git a/hw/e1000.c b/hw/e1000.c
index 8566fe3..f795601 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1125,7 +1125,7 @@  static int pci_e1000_init(PCIDevice *pci_dev)
     if (!pci_dev->qdev.hotplugged) {
         static int loaded = 0;
         if (!loaded) {
-            rom_add_option("pxe-e1000.bin");
+            pci_add_option_rom(&d->dev, "pxe-e1000.bin");
             loaded = 1;
         }
     }
diff --git a/hw/pci.c b/hw/pci.c
index 404eead..dbdfdbf 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -26,6 +26,7 @@ 
 #include "monitor.h"
 #include "net.h"
 #include "sysemu.h"
+#include "loader.h"
 
 //#define DEBUG_PCI
 #ifdef DEBUG_PCI
@@ -1463,6 +1464,40 @@  static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
     return next;
 }
 
+static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, pcibus_t size, int type)
+{
+    cpu_register_physical_memory(addr, size, pdev->rom_offset);
+}
+
+/* Add an option rom for the device */
+int pci_add_option_rom(PCIDevice *pdev, const char *name)
+{
+    int size;
+    char *path;
+    void *ptr;
+
+    path = qemu_find_file(QEMU_FILE_TYPE_BIOS, name);
+    if (path == NULL) {
+        path = qemu_strdup(name);
+    }
+
+    size = get_image_size(path);
+    if (size & (size - 1)) {
+        size = 1 << qemu_fls(size);
+    }
+
+    pdev->rom_offset = qemu_ram_alloc(size);
+
+    ptr = qemu_get_ram_ptr(pdev->rom_offset);
+    load_image(path, ptr);
+    qemu_free(path);
+
+    pci_register_bar(pdev, PCI_ROM_SLOT, size,
+                     0, pci_map_option_rom);
+
+    return 0;
+}
+
 /* Reserve space and add capability to the linked list in pci config space */
 int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
 {
diff --git a/hw/pci.h b/hw/pci.h
index d279e3f..89b3f55 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -243,6 +243,9 @@  struct PCIDevice {
     uint32_t msix_bar_size;
     /* Version id needed for VMState */
     int32_t version_id;
+
+    /* Location of option rom */
+    ram_addr_t rom_offset;
 };
 
 PCIDevice *pci_register_device(PCIBus *bus, const char *name,
@@ -254,6 +257,8 @@  void pci_register_bar(PCIDevice *pci_dev, int region_num,
                             pcibus_t size, int type,
                             PCIMapIORegionFunc *map_func);
 
+int pci_add_option_rom(PCIDevice *pdev, const char *name);
+
 int pci_add_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size);
 
 void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size);
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 9fd05a8..2cee97b 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3357,7 +3357,7 @@  static int pci_rtl8139_init(PCIDevice *dev)
     if (!dev->qdev.hotplugged) {
         static int loaded = 0;
         if (!loaded) {
-            rom_add_option("pxe-rtl8139.bin");
+            pci_add_option_rom(&s->dev, "pxe-rtl8139.bin");
             loaded = 1;
         }
     }
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 4500130..85f14a2 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -522,7 +522,7 @@  static int virtio_net_init_pci(PCIDevice *pci_dev)
     if (!pci_dev->qdev.hotplugged) {
         static int loaded = 0;
         if (!loaded) {
-            rom_add_option("pxe-virtio.bin");
+            pci_add_option_rom(pci_dev, "pxe-virtio.bin");
             loaded = 1;
         }
     }