WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [Patch][2/2][BIOS] Support BCV table

To: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>, xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: Re: [Xen-devel] [Patch][2/2][BIOS] Support BCV table
From: Akio Takebe <takebe_akio@xxxxxxxxxxxxxx>
Date: Mon, 30 Mar 2009 15:50:31 +0900
Cc:
Delivery-date: Sun, 29 Mar 2009 23:51:02 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <8DC9AEC72C5177takebe_akio@xxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <C5F24622.50E9%keir.fraser@xxxxxxxxxxxxx> <8CC9AEC60A1E3Ctakebe_akio@xxxxxxxxxxxxxx> <8DC9AEC72C5177takebe_akio@xxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 2.0.0.21 (X11/20090320)
Hi,

Akio Takebe wrote:
>>> On 27/03/2009 00:48, "Akio Takebe" <takebe_akio@xxxxxxxxxxxxxx> wrote:
>>>
>>>>> You want qemu mucking about with the hvm_info_table? I don't think so.
>>>>> You'll have to consider an approach which doesn't touch qemu - you have 
>>>>> some
>>>>> time anyway since this is not going in for 3.4.
>>>> I didn't want to modify qemu, but virtual slot is decided in qemu.
>>>> Most of my patch modify hw/pass-through.c
>>>> Because hw/pass-though.c is used by only xen,
>>>> I though it was accectable to modify it.
>>>> So I modified qemu involuntarily. I'm sorry.
>>>> If we don't modify qemu, we need to see xenstore and so on
>>>> from hvmloader. Do you have any idea?
>>> I may be missing some of the motivation and higher-level design, which you
>>> may have to describe. I'm not really sure what the whole patchset was
>>> actually for and why we'd want it.
>>>
>> I have two problems.
>> 1. We cannot load many optionROM
>>  In the case of a native PnP BIOS, it load a optionROM and
>>  try to initialize their device, then it can free unnecessary ROM 
>>  memory. So a native BIOS can load many optionROM.
>>  But in the case of xen, optionROMs are loaded in hvmloader.
>>  So we cannot free unnecessary memory.
>>  Current hvmloader try to load all of optionROM, But if shadow memory
>>  doesn't have enough space, it stop loading optionROM.
>>  So I wanted to load some necessary optionROM for booting.
>>  As the side effect, the patch make booting faster if you don't want to
>>  boot from pass-through device.
>>  I think it is not important problem.
>>  We can configure bootable devices with early number of vslot.
>>  
>> 2. We cannot retry the next drive of HDD type.
>>  rombios try to boot from only 0x80 drive.
>>  So rombios cannot retry to boot with other drives.
>>  I want to boot from other drive.
>>  It is useful when the first drive(0x80) broke.
>>  Also if acceptable, I want to implement interactive boot key
>>  for pass-through device.
>>
>>> But, for example, why not specify the vendor:dev identifier via
>>> hvm_info_table, rather than specifying the vslot?
>> Oh, I didn't have the idea. I'll try it.
>>
> I don't try the idea of vendor:dev id, but I made a patch(bcv.v2.patch)
> adding the feature of retrying to boot with the next drives.
> What do you think about this patch?
> This patch doesn't add any new syntax, just add the retry feature.
> 
> Also I made another patch(support_interactive_boot_for_bcv.patch).
> It allows user to select a bootable pass-through device with F12.
> support_interactive_boot_for_bcv.patch depends on bcv.v2.patch.
> 
Just RFC. I made a patch which we can select bootable devices with 
vendor_id:device_id.
It depends on previous 2 patches(bcv.v2.patch, 
support_interactive_boot_for_bcv.patch).
If acceptable, I will remake, cleanup and post them after xen-3.5.

Best Regards,

Akio Takebe
diff -r b6cf416223e3 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Fri Mar 27 19:44:05 2009 +0900
+++ b/tools/firmware/hvmloader/hvmloader.c      Mon Mar 30 15:42:08 2009 +0900
@@ -478,6 +478,8 @@
     uint32_t option_rom_addr, rom_phys_addr = rom_base_addr;
     uint16_t vendor_id, device_id;
     uint8_t devfn, class;
+    uint32_t i, found;
+    uint32_t vendev;
 
     for ( devfn = 0; devfn < 128; devfn++ )
     {
@@ -487,6 +489,22 @@
 
         if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
             continue;
+
+        found = 0;
+        for ( i = 0; i < 4 ; i++ ) {
+            vendev = hvm_info->pci_vd[i];
+            if ( vendev == 0 )
+                continue;
+            if ( (vendor_id == (vendev>>16&0xffff)) && (device_id == 
(vendev&0xffff)) ){
+                found = 1;
+                break;
+            }
+        }
+   
+        if ( found == 0 )
+            continue;
+        else 
+            printf("vendor=%x device=%x \n", ((vendev>>16)&0xffff), 
vendev&0xffff);
 
         /*
          * Currently only scan options from mass storage devices and serial
diff -r b6cf416223e3 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Fri Mar 27 19:44:05 2009 +0900
+++ b/tools/libxc/xc_hvm_build.c        Mon Mar 30 15:42:08 2009 +0900
@@ -30,12 +30,37 @@
 #define NR_SPECIAL_PAGES     5
 #define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x))
 
-static void build_hvm_info(void *hvm_info_page, uint64_t mem_size)
+static int token_value(char *token)
+{
+    token = strchr(token, 'x') + 1;
+    return strtol(token, NULL, 16);
+}
+
+static int next_vd(char **str, int *vendor, int *device)
+{
+    char *token;
+
+    if ( !(*str) || !strchr(*str, ',') )
+        return 0;
+
+    token = *str;
+    *vendor  = token_value(token);
+    token = strchr(token, ',') + 1;
+    *device  = token_value(token);
+    token = strchr(token, ',');
+    *str = token ? token + 1 : NULL;
+
+    return 1;
+}
+
+static void build_hvm_info(void *hvm_info_page, uint64_t mem_size, char 
*pci_str)
 {
     struct hvm_info_table *hvm_info = (struct hvm_info_table *)
         (((unsigned char *)hvm_info_page) + HVM_INFO_OFFSET);
     uint64_t lowmem_end = mem_size, highmem_end = 0;
     uint8_t sum;
+    uint32_t vd = 0;
+    int vendor, device;
     int i;
 
     if ( lowmem_end > HVM_BELOW_4G_RAM_END )
@@ -60,10 +85,24 @@
     hvm_info->high_mem_pgend = highmem_end >> PAGE_SHIFT;
     hvm_info->reserved_mem_pgstart = special_pfn(0);
 
+    /* bootable pass-through devices */
+    i = 0;
+    while ( next_vd(&pci_str, &vendor, &device) )
+    {
+        vd |= (vendor & 0xffff) << 16;
+        vd |= (device & 0xffff) ;
+       hvm_info->pci_vd[i] = vd;
+        vd = 0;
+       i++;
+        if ( i == 4 )
+               break;
+    }
+
     /* Finish with the checksum. */
     for ( i = 0, sum = 0; i < hvm_info->length; i++ )
         sum += ((uint8_t *)hvm_info)[i];
     hvm_info->checksum = -sum;
+
 }
 
 static int loadelfimage(
@@ -102,7 +141,8 @@
 
 static int setup_guest(int xc_handle,
                        uint32_t dom, int memsize, int target,
-                       char *image, unsigned long image_size)
+                       char *image, unsigned long image_size,
+                       char *pci)
 {
     xen_pfn_t *page_array = NULL;
     unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
@@ -132,6 +172,8 @@
     elf_parse_binary(&elf);
     v_start = 0;
     v_end = (unsigned long long)memsize << 20;
+
+    PERROR("%s: BBB pci=%s\n",__func__, pci);
 
     if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 )
     {
@@ -248,7 +290,7 @@
               xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
               HVM_INFO_PFN)) == NULL )
         goto error_out;
-    build_hvm_info(hvm_info_page, v_end);
+    build_hvm_info(hvm_info_page, v_end, pci);
     munmap(hvm_info_page, PAGE_SIZE);
 
     /* Map and initialise shared_info page. */
@@ -325,21 +367,25 @@
     free(page_array);
     return -1;
 }
+extern FILE *xc_dom_logfile;
+extern void xc_dom_loginit(void);
 
 static int xc_hvm_build_internal(int xc_handle,
                                  uint32_t domid,
                                  int memsize,
                                  int target,
                                  char *image,
-                                 unsigned long image_size)
+                                 unsigned long image_size,
+                                 char *pci)
 {
+    xc_dom_loginit();
     if ( (image == NULL) || (image_size == 0) )
     {
         ERROR("Image required");
         return -1;
     }
 
-    return setup_guest(xc_handle, domid, memsize, target, image, image_size);
+    return setup_guest(xc_handle, domid, memsize, target, image, image_size, 
pci);
 }
 
 static inline int is_loadable_phdr(Elf32_Phdr *phdr)
@@ -364,7 +410,7 @@
          ((image = xc_read_image(image_name, &image_size)) == NULL) )
         return -1;
 
-    sts = xc_hvm_build_internal(xc_handle, domid, memsize, memsize, image, 
image_size);
+    sts = xc_hvm_build_internal(xc_handle, domid, memsize, memsize, image, 
image_size, NULL);
 
     free(image);
 
@@ -381,7 +427,8 @@
                            uint32_t domid,
                            int memsize,
                            int target,
-                           const char *image_name)
+                           const char *image_name,
+                           char *pci)
 {
     char *image;
     int  sts;
@@ -391,7 +438,7 @@
          ((image = xc_read_image(image_name, &image_size)) == NULL) )
         return -1;
 
-    sts = xc_hvm_build_internal(xc_handle, domid, memsize, target, image, 
image_size);
+    sts = xc_hvm_build_internal(xc_handle, domid, memsize, target, image, 
image_size, pci);
 
     free(image);
 
@@ -427,7 +474,7 @@
     }
 
     sts = xc_hvm_build_internal(xc_handle, domid, memsize, memsize,
-                                img, img_len);
+                                img, img_len, NULL);
 
     /* xc_inflate_buffer may return the original buffer pointer (for
        for already inflated buffers), so exercise some care in freeing */
diff -r b6cf416223e3 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Fri Mar 27 19:44:05 2009 +0900
+++ b/tools/libxc/xenguest.h    Mon Mar 30 15:42:08 2009 +0900
@@ -134,7 +134,8 @@
                             uint32_t domid,
                             int memsize,
                             int target,
-                            const char *image_name);
+                            const char *image_name,
+                            char *pci);
 
 int xc_hvm_build_mem(int xc_handle,
                      uint32_t domid,
diff -r b6cf416223e3 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Mar 27 19:44:05 2009 +0900
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon Mar 30 15:42:08 2009 +0900
@@ -891,20 +891,21 @@
 #endif
     char *image;
     int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1;
+    char *pci;
 
     static char *kwd_list[] = { "domid",
                                 "memsize", "image", "target", "vcpus", "acpi",
-                                "apic", NULL };
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiii", kwd_list,
+                                "apic", "pci", NULL };
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiiis", kwd_list,
                                       &dom, &memsize, &image, &target, &vcpus,
-                                      &acpi, &apic) )
+                                      &acpi, &apic, &pci) )
         return NULL;
 
     if ( target == -1 )
         target = memsize;
 
     if ( xc_hvm_build_target_mem(self->xc_handle, dom, memsize,
-                                 target, image) != 0 )
+                                 target, image, pci) != 0 )
         return pyxc_error_to_exception();
 
 #if !defined(__ia64__)
diff -r b6cf416223e3 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Fri Mar 27 19:44:05 2009 +0900
+++ b/tools/python/xen/xend/image.py    Mon Mar 30 15:42:08 2009 +0900
@@ -41,6 +41,7 @@
 from xen.xend import XendOptions
 from xen.util import oshelp
 from xen.util import utils
+from xen.util import pci as PciUtil
 from xen.xend import osdep
 
 xc = xen.lowlevel.xc.xc()
@@ -49,6 +50,34 @@
 
 sentinel_path_prefix = '/var/run/xend/dm-'
 sentinel_fifos_inuse = { }
+
+def comma_sep_kv_to_dict(c):
+    """Convert comma-separated, equals-separated key-value pairs into a
+    dictionary.
+    """
+    d = {}
+    c = c.strip()
+    if len(c) > 0:
+        a = c.split(',')
+        for b in a:
+            if b.find('=') == -1:
+                err("%s should be a pair, separated by an equals sign." % b)
+            (k, v) = b.split('=', 1)
+            k = k.strip()
+            v = v.strip()
+            d[k] = v
+    log.debug("AAA: d = %s " % d.keys())
+    return d
+
+def parse_hex(val):
+    try:
+        if isinstance(val, types.StringTypes):
+            return int(val, 16)
+        else:
+            return val
+    except ValueError:
+        return None
+
 
 def cleanup_stale_sentinel_fifos():
     for path in glob.glob(sentinel_path_prefix + '*.fifo'):
@@ -741,6 +770,7 @@
         self.apic = int(vmConfig['platform'].get('apic', 0))
         self.acpi = int(vmConfig['platform'].get('acpi', 0))
         self.guest_os_type = vmConfig['platform'].get('guest_os_type')
+       self.pci  = vmConfig['platform'].get('pci')
 
 
     # Return a list of cmd line args to the device models based on the
@@ -839,6 +869,8 @@
 
         memmax_mb = self.getRequiredMaximumReservation() / 1024
         mem_mb = self.getRequiredInitialReservation() / 1024
+        pci_str = ""
+        PciUtil.create_lspci_info()
 
         log.debug("domid          = %d", self.vm.getDomid())
         log.debug("image          = %s", self.loader)
@@ -848,6 +880,15 @@
         log.debug("vcpus          = %d", self.vm.getVCpuCount())
         log.debug("acpi           = %d", self.acpi)
         log.debug("apic           = %d", self.apic)
+        log.debug(self.pci)
+        for (d, b, s, f, vslot, opts) in self.pci:
+            dic = comma_sep_kv_to_dict(opts)
+            if 'boot' in dic.keys():
+                if int(dic['boot'],10) > 0:
+                    pci_dev = PciUtil.PciDevice(int(d, 16), int(b, 16), int(s, 
16), int(f, 16))
+                    pci_str += "%s,%s" % (hex(pci_dev.vendor), 
hex(pci_dev.device))
+
+        log.debug("pci_str        = %s", pci_str)
 
         rc = xc.hvm_build(domid          = self.vm.getDomid(),
                           image          = self.loader,
@@ -855,7 +896,9 @@
                           target         = mem_mb,
                           vcpus          = self.vm.getVCpuCount(),
                           acpi           = self.acpi,
-                          apic           = self.apic)
+                          apic           = self.apic,
+                          pci            = pci_str)
+
         rc['notes'] = { 'SUSPEND_CANCEL': 1 }
 
         rc['store_mfn'] = xc.hvm_get_param(self.vm.getDomid(),
diff -r b6cf416223e3 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Fri Mar 27 19:44:05 2009 +0900
+++ b/tools/python/xen/xm/create.py     Mon Mar 30 15:42:08 2009 +0900
@@ -323,7 +323,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[@VSLOT][,msitranslate=0|1][,power_mgmt=0|1]',
+gopts.var('pci', 
val='BUS:DEV.FUNC[@VSLOT][,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'.
@@ -334,7 +334,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=[],
@@ -704,7 +707,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]])
diff -r b6cf416223e3 xen/include/public/hvm/hvm_info_table.h
--- a/xen/include/public/hvm/hvm_info_table.h   Fri Mar 27 19:44:05 2009 +0900
+++ b/xen/include/public/hvm/hvm_info_table.h   Mon Mar 30 15:42:08 2009 +0900
@@ -64,6 +64,11 @@
      *    RAM above 4GB
      */
     uint32_t    high_mem_pgend;
+    /*
+     * SBDF of bootable pass-through devices
+     * It is used by hvmloader for loading option ROM.
+     */
+    uint32_t   pci_vd[4];
 };
 
 #endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel