All of lore.kernel.org
 help / color / mirror / Atom feed
* [Patch][RFC] BIOS: configure bootable pass-through device
@ 2009-03-12 10:11 Akio Takebe
  2009-03-12 10:38 ` Keir Fraser
  0 siblings, 1 reply; 3+ messages in thread
From: Akio Takebe @ 2009-03-12 10:11 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 917 bytes --]

Hi,

These patches allow users to configure bootable device in guest configration file.
The shadow memory, which mean memory area loading option ROM, is small.
So if we specified many pass-through device, hvmloader cannot load all of option ROM.
We want to select a device which we want to load the option ROM.
After applying these patches, we need to specify pci option of bootable device like below.

pci = [ '01:00.0,boot=1' ]

boot=1 means bootable, boot=0 and no boot option mean non-bootable.

BTW, if we don't specify the boot=1 option, we can boot from emulation disks
and we can boot faster because option ROM is not initialized.

These patches use cmos(0x60) as a place retaining the devfn of bootable device.
Bochs BIOS doesn't seems to use the offset 0x60.
What do you think of using cmos(0x60)?
Do you have some ideas?

Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com>

Best Regards,

Akio Takebe

[-- Attachment #2: select_bootable_pt_dev.patch --]
[-- Type: text/x-diff, Size: 3994 bytes --]

diff -r a4274d1e85a3 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c	Wed Mar 11 13:11:21 2009 +0000
+++ b/tools/firmware/hvmloader/hvmloader.c	Thu Mar 12 18:50:26 2009 +0900
@@ -479,37 +479,38 @@
     uint16_t vendor_id, device_id;
     uint8_t devfn, class;
 
-    for ( devfn = 0; devfn < 128; devfn++ )
-    {
-        class     = pci_readb(devfn, PCI_CLASS_DEVICE + 1);
-        vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
-        device_id = pci_readw(devfn, PCI_DEVICE_ID);
+    devfn = cmos_inb(0x60);
+    printf("devfn=%x \n", devfn);
 
-        if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
-            continue;
+    class     = pci_readb(devfn, PCI_CLASS_DEVICE + 1);
+    vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
+    device_id = pci_readw(devfn, PCI_DEVICE_ID);
 
-        /*
-         * Currently only scan options from mass storage devices and serial
-         * bus controller (Fibre Channel included).
-         */
-        if ( (class != 0x1) && (class != 0xc) )
-            continue;
+    if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
+        goto out;
 
-        option_rom_addr = pci_readl(devfn, PCI_ROM_ADDRESS);
-        if ( !option_rom_addr )
-            continue;
+    /*
+     * Currently only scan options from mass storage devices and serial
+     * bus controller (Fibre Channel included).
+     */
+    if ( (class != 0x1) && (class != 0xc) )
+        goto out;
 
-        /* Ensure Expansion Bar is enabled before copying */
-        pci_writel(devfn, PCI_ROM_ADDRESS, option_rom_addr | 0x1);
+    option_rom_addr = pci_readl(devfn, PCI_ROM_ADDRESS);
+    if ( !option_rom_addr )
+        goto out;
 
-        rom_phys_addr += scan_option_rom(
-            devfn, vendor_id, device_id,
-            (void *)(option_rom_addr & ~2047), rom_phys_addr);
+    /* Ensure Expansion Bar is enabled before copying */
+    pci_writel(devfn, PCI_ROM_ADDRESS, option_rom_addr | 0x1);
 
-        /* Restore the default original value of Expansion Bar */
-        pci_writel(devfn, PCI_ROM_ADDRESS, option_rom_addr);
-    }
+    rom_phys_addr += scan_option_rom(
+        devfn, vendor_id, device_id,
+        (void *)(option_rom_addr & ~2047), rom_phys_addr);
 
+    /* Restore the default original value of Expansion Bar */
+    pci_writel(devfn, PCI_ROM_ADDRESS, option_rom_addr);
+
+out:
     return rom_phys_addr - rom_base_addr;
 }
 
diff -r a4274d1e85a3 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py	Wed Mar 11 13:11:21 2009 +0000
+++ b/tools/python/xen/xm/create.py	Thu Mar 12 18:50:26 2009 +0900
@@ -322,7 +322,7 @@
           backend driver domain to use for the disk.
           The option may be repeated to add more than one disk.""")
 
-gopts.var('pci', val='BUS:DEV.FUNC[,msitranslate=0|1][,power_mgmt=0|1]',
+gopts.var('pci', val='BUS:DEV.FUNC[,msitranslate=0|1][,power_mgmt=0|1][,boot=0|1]',
           fn=append_value, default=[],
           use="""Add a PCI device to a domain, using given params (in hex).
           For example 'pci=c0:02.1'.
@@ -331,7 +331,10 @@
           translated from physical MSI, HVM only. Default is 1.
           The option may be repeated to add more than one pci device.
           If power_mgmt is set, the guest OS will be able to program the power
-          states D0-D3hot of the device, HVM only. Default=0.""")
+          states D0-D3hot of the device, HVM only. Default=0.
+          The option can add only one pci device.
+          If boot is set, guest BIOS boot OS from the pass-through devices.
+          The option is used by SAN/SAS boot.""")
 
 gopts.var('vscsi', val='PDEV,VDEV[,DOM]',
           fn=append_value, default=[],
@@ -697,7 +700,7 @@
         d = comma_sep_kv_to_dict(opts)
 
         def f(k):
-            if k not in ['msitranslate', 'power_mgmt']:
+            if k not in ['msitranslate', 'power_mgmt', 'boot']:
                 err('Invalid pci option: ' + k)
 
             config_pci_opts.append([k, d[k]])

[-- Attachment #3: select_bootable_pt_dev.qemu.patch --]
[-- Type: text/x-diff, Size: 3232 bytes --]

diff --git a/hw/pass-through.c b/hw/pass-through.c
index 4a86309..7a6e8a8 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -3565,6 +3565,7 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
     int free_pci_slot = -1;
     char *key, *val;
     int msi_translate;
+    int pci_boot;
 
     PT_LOG("Assigning real physical device %02x:%02x.%x ...\n",
         r_bus, r_dev, r_func);
@@ -3597,6 +3598,7 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
     }
 
     msi_translate = direct_pci_msitranslate;
+    pci_boot = 0;
     while (opt) {
         if (get_next_keyval(&opt, &key, &val)) {
             PT_LOG("Error: unrecognized PCI assignment option \"%s\"\n", opt);
@@ -3618,6 +3620,19 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
             else
                 PT_LOG("Error: unrecognized value for msitranslate=\n");
         }
+        else if (strcmp(key, "boot") == 0)
+            if (strcmp(val, "0") == 0 || strcmp(val, "no") == 0)
+            {
+                PT_LOG("Disable boot option\n");
+                pci_boot = 0;
+            }
+            else if (strcmp(val, "1") == 0 || strcmp(val, "yes") == 0)
+            {
+                PT_LOG("Enable boot option\n");
+                pci_boot = 1;
+            }
+            else
+                PT_LOG("Error: unrecognized value for boot=\n");
         else
             PT_LOG("Error: unrecognized PCI assignment option \"%s=%s\"\n", key, val);
 
@@ -3710,6 +3725,9 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
             *(uint16_t *)(&assigned_device->dev.config[0x04]));
     }
 
+    if (pci_boot)
+        pt_register_bootable_device(e_devfn);
+
 out:
     PT_LOG("Real physical device %02x:%02x.%x registered successfuly!\n"
            "IRQ type = %s\n", r_bus, r_dev, r_func,
diff --git a/hw/pass-through.h b/hw/pass-through.h
index e86d311..cb5d3f4 100644
--- a/hw/pass-through.h
+++ b/hw/pass-through.h
@@ -384,5 +384,7 @@ static inline pciaddr_t pt_pci_base_addr(pciaddr_t base)
     return base & PCI_ADDR_MEM_MASK;
 }
 
+void pt_register_bootable_device(int e_devfn);
+
 #endif /* __PASSTHROUGH_H__ */
 
diff --git a/hw/pc.c b/hw/pc.c
index f0492c8..ca4995a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -237,6 +237,14 @@ static int pc_boot_set(void *opaque, const char *boot_device)
     return(0);
 }
 
+#ifdef CONFIG_PASSTHROUGH
+void pt_register_bootable_device(int e_devfn)
+{
+    RTCState *s = rtc_state;
+    rtc_set_memory(s, 0x60, e_devfn);
+}
+#endif
+
 /* hd_table must contain 4 block drivers */
 static void cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
                       const char *boot_device, BlockDriverState **hd_table)
@@ -981,6 +989,8 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
         }
     }
 
+    rtc_state = rtc_init(0x70, i8259[8]);
+
 #ifdef CONFIG_PASSTHROUGH
     /* Pass-through Initialization
      * init libpci even direct_pci is null, as can hotplug a dev runtime
@@ -996,8 +1006,6 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
     }
 #endif
 
-    rtc_state = rtc_init(0x70, i8259[8]);
-
     qemu_register_boot_set(pc_boot_set, rtc_state);
 
     register_ioport_read(0x92, 1, 1, ioport92_read, NULL);

[-- Attachment #4: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-03-12 11:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-12 10:11 [Patch][RFC] BIOS: configure bootable pass-through device Akio Takebe
2009-03-12 10:38 ` Keir Fraser
2009-03-12 11:10   ` Akio Takebe

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.