All of lore.kernel.org
 help / color / mirror / Atom feed
* [Patch][0/2][BIOS] Support BCV table
@ 2009-03-26 13:40 Akio Takebe
  2009-03-26 13:42 ` Akio Takebe
  2009-03-26 13:43 ` [Patch][2/2][BIOS] " Akio Takebe
  0 siblings, 2 replies; 14+ messages in thread
From: Akio Takebe @ 2009-03-26 13:40 UTC (permalink / raw)
  To: xen-devel

Hi,

The patches support BCV table/priority in rombios.
The motivation is we want to:
- select bootable device because loading optionROM take a long time.
- retry other devices if we fail to boot wiht the first device.

BCV priority is a order of installing int 0x13 handler.
In my patch, the priorty is decided with BDF number.
ATA emulation disk is the highest priority,
and lower BDF number of passthrough devices is higher priority.

The patch adds two syntax in configuration file.
1. boot option of pci
   e.g. pci = [ '01:00.0@6,boot=1' ]
2. p option of boot
   e.g. boot = "pcd"

In the above example, hvmloader will load optionROM of 01:00.0 pass-through device.
Then rombios will try to boot from pass-through device.
If it fail, rombios will try CD boot, and ATA disk boot.

I use hvm_info table for passing BDF numbers which we want to load their optionROMs.
If still possible, please apply the patch.

Best Regards,

Akio Takebe

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

* Re: [Patch][0/2][BIOS] Support BCV table
  2009-03-26 13:40 [Patch][0/2][BIOS] Support BCV table Akio Takebe
@ 2009-03-26 13:42 ` Akio Takebe
  2009-03-26 13:46   ` [Patch][1/2][BIOS] " Akio Takebe
  2009-03-26 13:43 ` [Patch][2/2][BIOS] " Akio Takebe
  1 sibling, 1 reply; 14+ messages in thread
From: Akio Takebe @ 2009-03-26 13:42 UTC (permalink / raw)
  To: xen-devel

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

Hi,

this patch is tools parts.

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

Best Regards,

Akio Takebe

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

diff -r 0477f9061c8a tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c	Fri Mar 20 17:42:46 2009 +0000
+++ b/tools/firmware/hvmloader/hvmloader.c	Thu Mar 26 22:20:23 2009 +0900
@@ -477,10 +477,14 @@
 {
     uint32_t option_rom_addr, rom_phys_addr = rom_base_addr;
     uint16_t vendor_id, device_id;
-    uint8_t devfn, class;
+    uint8_t devfn, class, i;
 
-    for ( devfn = 0; devfn < 128; devfn++ )
-    {
+    for (i=0; i < MAX_PCI_BOOT; i++){
+        devfn = hvm_info->pci_sbdf[i];
+        if ( devfn ==0 )
+            continue;
+        printf("%s:devfn=%x \n",__func__, 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);
diff -r 0477f9061c8a tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c	Fri Mar 20 17:42:46 2009 +0000
+++ b/tools/firmware/rombios/rombios.c	Thu Mar 26 22:20:23 2009 +0900
@@ -187,18 +187,33 @@
 #define EBDA_SIZE          1              // In KiB
 #define BASE_MEM_IN_K   (640 - EBDA_SIZE)
 
-/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */
+/* 256 bytes at 0x9ff00 -- 0x9ffaf is used for the IPL boot table. */
 #define IPL_TABLE_OFFSET     0x0300  /* offset from EBDA */
 #define IPL_TABLE_ENTRIES    8
 #define IPL_COUNT_OFFSET     0x0380  /* u16: number of valid table entries */
 #define IPL_SEQUENCE_OFFSET  0x0382  /* u16: next boot device */
 #define IPL_BOOTFIRST_OFFSET 0x0384  /* u16: user selected device */
-#define IPL_SIZE             0xff
+#define IPL_SIZE             0xaf
 #define IPL_TYPE_FLOPPY      0x01
 #define IPL_TYPE_HARDDISK    0x02
 #define IPL_TYPE_CDROM       0x03
 #define IPL_TYPE_BEV         0x80
 
+#define IPL_TYPE_BCV         IPL_TYPE_HARDDISK
+
+/* 256 bytes at 0x9ffb0 -- 0x9ffff is used for the BCV boot table. */
+#define BCV_TABLE_OFFSET     0x03b0  /* offset from EBDA */
+#define BCV_TABLE_ENTRIES    4
+#define BCV_COUNT_OFFSET     0x03f0  /* u16: number of valid table entries */
+#define BCV_SEQUENCE_OFFSET  0x03f2  /* u16: next boot device */
+#define BCV_BOOTFIRST_OFFSET 0x03f4  /* u16: user selected device */
+#define BCV_SIZE             0x4f
+
+#define BOOTDEV_FDD 0x1
+#define BOOTDEV_HDD 0x2
+#define BOOTDEV_CD  0x3
+#define BOOTDEV_NET 0x4
+#define BOOTDEV_BCV 0x5
 
   // Sanity Checks
 #if BX_USE_ATADRV && BX_CPU<3
@@ -2064,14 +2079,65 @@
 
 static char drivetypes[][10]={"", "Floppy","Hard Disk","CD-Rom", "Network"};
 
+/* initialize BCV talbe. BCV and IPL table are the same structure. */
 static void
-init_boot_vectors()
+init_boot_connection_vector()
 {
   ipl_entry_t e;
   Bit16u count = 0;
   Bit16u ss = get_SS();
   Bit16u ebda_seg = read_word(0x0040, 0x000E);
 
+  /* Clear out the BCV table. */
+  memsetb(ebda_seg, BCV_TABLE_OFFSET, 0, BCV_SIZE);
+
+  /* User selected device not set */
+  write_word(ebda_seg, BCV_BOOTFIRST_OFFSET, 0xFFFF);
+
+  /* First HDD */
+//  e.type = IPL_TYPE_HARDDISK; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
+//  memcpyb(ebda_seg, BCV_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
+//  count++;
+
+  /* Remember how many devices we have */
+  write_word(ebda_seg, BCV_COUNT_OFFSET, count);
+  /* Not tried booting anything yet */
+  write_word(ebda_seg, BCV_SEQUENCE_OFFSET, 0xFFFF);
+}
+
+static Bit16u
+get_bcv_count()
+{
+  Bit16u count;
+  Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
+  count = read_word(ebda_seg, BCV_COUNT_OFFSET);
+  return count;
+}
+
+static Bit8u
+get_bcv_entry(i, e)
+Bit16u i; ipl_entry_t *e;
+{
+  Bit16u count;
+  Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
+  /* Get the count of boot devices, and refuse to overrun the array */
+  count = read_word(ebda_seg, BCV_COUNT_OFFSET);
+  if (i > count) return 0;
+  /* OK to read this device */
+  memcpyb(ss, e, ebda_seg, BCV_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));
+  return 1;
+}
+
+static void
+init_boot_vectors()
+{
+  ipl_entry_t e;
+  Bit16u count = 0;
+  Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
+
   /* Clear out the IPL table. */
   memsetb(ebda_seg, IPL_TABLE_OFFSET, 0, IPL_SIZE);
 
@@ -2106,13 +2172,23 @@
 Bit16u i; ipl_entry_t *e;
 {
   Bit16u count;
+  Bit16u j = i;
   Bit16u ss = get_SS();
   Bit16u ebda_seg = read_word(0x0040, 0x000E);
+
+  /* BCV device also use IPL_TYPE_HARDDISK. */
+  if(i == BOOTDEV_BCV)
+    j = BOOTDEV_HDD;
+
   /* Get the count of boot devices, and refuse to overrun the array */
   count = read_word(ebda_seg, IPL_COUNT_OFFSET);
-  if (i >= count) return 0;
+  if (j >= count) return 0;
+
+  /* Translate from CMOS runes to an IPL table offset by subtracting 1 */
+  j--;
+
   /* OK to read this device */
-  memcpyb(ss, e, ebda_seg, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));
+  memcpyb(ss, e, ebda_seg, IPL_TABLE_OFFSET + j * sizeof (*e), sizeof (*e));
   return 1;
 }
 
@@ -2204,7 +2280,7 @@
   type = e->type;
   /* NIC appears as type 0x80 */
   if (type == IPL_TYPE_BEV) type = 0x4;
-  if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n");
+  if (type == 0 || type > 0x5) BX_PANIC("Bad drive type(%d)\n", type);
   printf("Booting from %s", drivetypes[type]);
   /* print product string if BEV */
   if (type == 4 && e->description != 0) {
@@ -2217,6 +2293,22 @@
   printf("...\n");
 }
 
+void
+print_bcv_device(bcv, bootdrv)
+  ipl_entry_t *bcv;
+  Bit8u  bootdrv;
+{
+  char description[33];
+  Bit16u ss = get_SS();
+
+  if (bcv->description != 0)
+  {
+    memcpyb(ss, &description, (Bit16u)(bcv->description >> 16), (Bit16u)(bcv->description & 0xffff), 32);
+    description[32] = 0;
+    printf(" [%S]", ss, description);
+  }
+  printf(" bootdrv[0x%x]\n", bootdrv);
+}
 //--------------------------------------------------------------------------
 // print_boot_failure
 //   displays the reason why boot failed
@@ -8207,8 +8299,12 @@
   Bit16u bootip;
   Bit16u status;
   Bit16u bootfirst;
+  Bit16u bcv_count;
+  Bit16u retry_count;
+  Bit16u hdcount, ata_hdcount;
 
   ipl_entry_t e;
+  ipl_entry_t bcv;
 
   // if BX_ELTORITO_BOOT is not defined, old behavior
   //   check bit 5 in CMOS reg 0x2d.  load either 0x00 or 0x80 into DL
@@ -8245,8 +8341,6 @@
     write_word(ebda_seg, IPL_SEQUENCE_OFFSET, 0xFFFF);
   } else if (bootdev == 0) BX_PANIC("No bootable device.\n");
 
-  /* Translate from CMOS runes to an IPL table offset by subtracting 1 */
-  bootdev -= 1;
 #else
   if (seq_nr ==2) BX_PANIC("No more boot devices.");
   if (!!(inb_cmos(0x2d) & 0x20) ^ (seq_nr == 1))
@@ -8255,11 +8349,10 @@
   else
     bootdev = 0x01;
 #endif
-
   /* Read the boot device from the IPL table */
-  if (get_boot_vector(bootdev, &e) == 0) {
-    BX_INFO("Invalid boot device (0x%x)\n", bootdev);
-    return;
+  if (get_boot_vector(bootdev, &e) == 0 ){
+      BX_INFO("Invalid boot device (0x%x)\n", bootdev);
+      return;
   }
 
   /* Do the loading, and set up vector as a far pointer to the boot
@@ -8269,8 +8362,37 @@
   switch(e.type) {
   case IPL_TYPE_FLOPPY: /* FDD */
   case IPL_TYPE_HARDDISK: /* HDD */
-
-    bootdrv = (e.type == IPL_TYPE_HARDDISK) ? 0x80 : 0x00;
+    ata_hdcount = read_byte(ebda_seg, &EbdaData->ata.hdcount);
+    hdcount     = read_byte(0x40,0x75);
+    bcv_count   = hdcount - ata_hdcount;
+    if ( bcv_count != get_bcv_count() || bcv_count < 0 )
+        BX_PANIC("Invaild hdcount(%d) ata_hdcount=%d bcv_count=%d\n",
+                  hdcount, ata_hdcount, get_bcv_count());
+
+    BX_INFO("hdcount(%d) ata_hdcount=%d bcv_count=%d\n",
+            hdcount, ata_hdcount, get_bcv_count());
+    if ( bootdev == BOOTDEV_BCV ) {
+      retry_count = bcv_count;
+      bootdrv = (0x80 + ata_hdcount);
+    } else {
+      if ( ata_hdcount == 0 && e.type == IPL_TYPE_HARDDISK) {
+          print_boot_failure(e.type, 1);
+          return;
+      }
+      retry_count = 1;
+      bootdrv = (e.type == IPL_TYPE_HARDDISK) ? 0x80 : 0x00;
+    }
+retry_type_hdd:
+    if ( retry_count == 0 ) {
+      return; /* boot fail with all bcv devices */
+    } else {
+      if ( bootdev == BOOTDEV_BCV ) {
+        bootdrv = bootdrv + (bcv_count - retry_count);
+        get_bcv_entry(bcv_count - retry_count, &bcv);
+        print_bcv_device(&bcv, bootdrv);
+      } 
+    }
+
     bootseg = 0x07c0;
     status = 0;
 
@@ -8306,7 +8428,8 @@
 
     if (status != 0) {
       print_boot_failure(e.type, 1);
-      return;
+      retry_count--;
+      goto retry_type_hdd;
     }
 
     /* Always check the signature on a HDD boot sector; on FDD, only do
@@ -8314,7 +8437,8 @@
     if ((e.type != IPL_TYPE_FLOPPY) || !((inb_cmos(0x38) & 0x01))) {
       if (read_word(bootseg,0x1fe) != 0xaa55) {
         print_boot_failure(e.type, 0);
-        return;
+        retry_count--;
+        goto retry_type_hdd;
       }
     }
 
@@ -8326,6 +8450,7 @@
     /* Canonicalize bootseg:bootip */
     bootip = (bootseg & 0x0fff) << 4;
     bootseg &= 0xf000;
+    printf("boot from [%x:%x]\n", bootseg, bootip);
   break;
 
 #if BX_ELTORITO_BOOT
@@ -10585,7 +10710,31 @@
   cli           ;; In case expansion ROM BIOS turns IF on
   add  sp, #2   ;; Pop offset value
   pop  cx       ;; Pop seg value (restore CX)
-  jmp   no_bev
+
+  ;; Found BCV device. Recode it in BCV table.
+  mov  bx, 0x001a   ;; 0x1A is the offset into ROM header that contains...
+  mov  di, 0x10[bx]            ;; Pointer to the product name string or zero if none
+
+  xor  bx, bx
+  mov  ds, bx
+  mov  bx, word ptr [0x40E]    ;; EBDA segment
+  mov  ds, bx                  ;; Go to the segment where the BCV table lives
+  mov  bx, BCV_COUNT_OFFSET    ;; Read the number of entries so far
+  cmp  bx, #BCV_TABLE_ENTRIES
+  je   no_bev                  ;; Get out if the table is full
+  shl  bx, #0x4                ;; Turn count into offset (entries are 16 bytes)
+  mov  BCV_TABLE_OFFSET+0[bx], #IPL_TYPE_BCV ;; This entry is a BCV device
+  mov  BCV_TABLE_OFFSET+6[bx], cx            ;; Build a far pointer from the segment...
+  mov  BCV_TABLE_OFFSET+4[bx], ax            ;; and the offset
+  cmp  di, #0x0000
+  je   no_prod_str1
+  mov  BCV_TABLE_OFFSET+0xA[bx], cx          ;; segment to descritption
+  mov  BCV_TABLE_OFFSET+0x8[bx], di          ;; pointer to descritption
+no_prod_str1:
+  shr  bx, #0x4                ;; Turn the offset back into a count
+  inc  bx                      ;; We have one more entry now
+  mov  BCV_COUNT_OFFSET, bx    ;; Remember that.
+  jmp  no_bev
 
 no_bcv:
   mov  ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of...
@@ -10606,10 +10755,10 @@
   mov  IPL_TABLE_OFFSET+6[bx], cx            ;; Build a far pointer from the segment...
   mov  IPL_TABLE_OFFSET+4[bx], ax            ;; and the offset
   cmp  di, #0x0000
-  je   no_prod_str
+  je   no_prod_str2
   mov  0xA[bx], cx             ;; Build a far pointer from the segment...
   mov  8[bx], di               ;; and the offset
-no_prod_str:
+no_prod_str2:
   shr  bx, #0x4                ;; Turn the offset back into a count
   inc  bx                      ;; We have one more entry now
   mov  IPL_COUNT_OFFSET, bx    ;; Remember that.
@@ -11041,6 +11190,7 @@
 #endif
 
   call _init_boot_vectors
+  call _init_boot_connection_vector
 
   mov  cx, #(OPTIONROM_PHYSICAL_ADDRESS >> 4)  ;; init option roms
   mov  ax, #(OPTIONROM_PHYSICAL_END >> 4)
diff -r 0477f9061c8a tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py	Fri Mar 20 17:42:46 2009 +0000
+++ b/tools/python/xen/xm/create.py	Thu Mar 26 22:20:23 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,12 @@
           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.
+          If boot option is set, the devices are handled as bootable devices.
+          boot option can add only 4 pci devices.
+          If boot is set, guest BIOS can 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 +709,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 0477f9061c8a xen/include/public/hvm/hvm_info_table.h
--- a/xen/include/public/hvm/hvm_info_table.h	Fri Mar 20 17:42:46 2009 +0000
+++ b/xen/include/public/hvm/hvm_info_table.h	Thu Mar 26 22:20:23 2009 +0900
@@ -28,6 +28,8 @@
 #define HVM_INFO_PFN         0x09F
 #define HVM_INFO_OFFSET      0x800
 #define HVM_INFO_PADDR       ((HVM_INFO_PFN << 12) + HVM_INFO_OFFSET)
+
+#define MAX_PCI_BOOT 4
 
 struct hvm_info_table {
     char        signature[8]; /* "HVM INFO" */
@@ -64,6 +66,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_sbdf[MAX_PCI_BOOT];
 };
 
 #endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */

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

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

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

* [Patch][2/2][BIOS] Support BCV table
  2009-03-26 13:40 [Patch][0/2][BIOS] Support BCV table Akio Takebe
  2009-03-26 13:42 ` Akio Takebe
@ 2009-03-26 13:43 ` Akio Takebe
  2009-03-26 14:36   ` Keir Fraser
  1 sibling, 1 reply; 14+ messages in thread
From: Akio Takebe @ 2009-03-26 13:43 UTC (permalink / raw)
  To: xen-devel

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

Hi,

This patch is qemu parts.

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

Best Regards,

Akio Takebe

[-- Attachment #2: bcv.qemu.patch --]
[-- Type: text/x-diff, Size: 5756 bytes --]

diff --git a/hw/pass-through.c b/hw/pass-through.c
index f23bdbb..43a5e20 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -27,6 +27,8 @@
 #include "pci/pci.h"
 #include "pt-msi.h"
 #include "qemu-xen.h"
+#include "xen/hvm/hvm_info_table.h"
+#include <sys/mman.h>
 #include <unistd.h>
 
 struct php_dev {
@@ -3634,6 +3636,60 @@ static int pt_pmcsr_reg_restore(struct pt_dev *ptdev,
     return 0;
 }
 
+static int
+pt_register_bootable_device(uint32_t e_devfn, int pci_boot)
+{
+    uint8_t *hvm_info_page;
+    struct hvm_info_table *hvm_info;
+    int i;
+    uint8_t sum;
+    uint32_t devfn; 
+    int rc = -1;
+
+    if (pci_boot <= 0 ) {
+        PT_LOG("Error: pci_boot=%d\n", pci_boot);
+        goto out;
+    }
+
+    hvm_info_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
+                                            PROT_READ|PROT_WRITE, HVM_INFO_PFN);
+    if (hvm_info_page == NULL){
+        PT_LOG("Error: xc_map_foreign_rage(HVM_INFO_PFN) error %d\n", errno);
+        goto out;
+    }
+    hvm_info = (struct hvm_info_table *)(hvm_info_page+HVM_INFO_OFFSET);
+
+    if ( strncmp(hvm_info->signature, "HVM INFO", 8) ) {
+        PT_LOG("Error: Bad hvm info signature(%s)\n", hvm_info->signature);
+        goto free;
+    }
+
+    for ( i = 0; i < MAX_PCI_BOOT; i++ ) { 
+        if ( hvm_info->pci_sbdf[i] == 0 ) {
+            hvm_info->pci_sbdf[i] = e_devfn;
+            break;
+        } else {
+            if ( i == MAX_PCI_BOOT ){
+                PT_LOG("Error: cannot enable bootable option (devfn=%x:%x)\n",
+                        (e_devfn>>3)&&0x1f, e_devfn&&0x7);
+                goto free;
+            }
+        }
+    }
+
+    hvm_info->checksum = 0;
+    for ( i = 0, sum = 0; i < hvm_info->length; i++ )
+        sum += ((uint8_t *)hvm_info)[i];
+    hvm_info->checksum = -sum;
+    rc = 0;
+
+free:
+    munmap(hvm_info_page, XC_PAGE_SIZE);
+out:
+    return rc;
+}
+
+
 struct pt_dev * register_real_device(PCIBus *e_bus,
         const char *e_dev_name, int e_devfn, uint8_t r_bus, uint8_t r_dev,
         uint8_t r_func, uint32_t machine_irq, struct pci_access *pci_access,
@@ -3647,6 +3703,7 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
     int free_slot = -1;
     char *key, *val;
     int msi_translate, power_mgmt;
+    int pci_boot = 0;
 
     PT_LOG("Assigning real physical device %02x:%02x.%x ...\n",
         r_bus, r_dev, r_func);
@@ -3716,6 +3773,19 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
             else
                 PT_LOG("Error: unrecognized value for power_mgmt=\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);
 
@@ -3810,6 +3880,12 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
             *(uint16_t *)(&assigned_device->dev.config[0x04]));
     }
 
+    if (pci_boot){
+        rc = pt_register_bootable_device(e_devfn, pci_boot);
+        if ( rc < 0 )
+            return NULL;
+    }
+
 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/pc.c b/hw/pc.c
index 878069d..bd376a0 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -215,6 +215,8 @@ static int boot_device2nibble(char boot_device)
         return 0x03; /* CD-ROM boot */
     case 'n':
         return 0x04; /* Network boot */
+    case 'p':
+        return 0x05; /* Pass-trough device */
     }
     return 0;
 }
diff --git a/vl.c b/vl.c
index 5801e42..9476218 100644
--- a/vl.c
+++ b/vl.c
@@ -3944,7 +3944,9 @@ static void help(int exitcode)
            "-mtdblock file  use 'file' as on-board Flash memory image\n"
            "-sd file        use 'file' as SecureDigital card image\n"
            "-pflash file    use 'file' as a parallel flash image\n"
-           "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
+           "-boot [a|c|d|n|p]\n"
+           "                boot on floppy (a), hard disk (c), CD-ROM (d), network (n)\n"
+           "                or PCI pass-through(p)\n"
            "-snapshot       write to temporary files instead of disk image files\n"
            "-m megs         set virtual RAM size to megs MB [default=%d]\n"
 #ifndef _WIN32
@@ -4982,7 +4984,8 @@ int main(int argc, char **argv, char **envp)
                          * a b     : floppy disk drives
                          * c ... f : IDE disk drives
                          * g ... m : machine implementation dependant drives
-                         * n ... p : network devices
+                         * n ... o : network devices
+                         * p       : PCI pass-through devices
                          * It's up to each machine implementation to check
                          * if the given boot devices match the actual hardware
                          * implementation and firmware features.
@@ -5525,7 +5528,7 @@ int main(int argc, char **argv, char **envp)
         kqemu_allowed = 0;
 #endif
     linux_boot = (kernel_filename != NULL);
-    net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
+    net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0x2;
 
     if (!linux_boot && net_boot == 0 &&
         !machine->nodisk_ok && nb_drives_opt == 0)

[-- Attachment #3: 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] 14+ messages in thread

* [Patch][1/2][BIOS] Support BCV table
  2009-03-26 13:42 ` Akio Takebe
@ 2009-03-26 13:46   ` Akio Takebe
  0 siblings, 0 replies; 14+ messages in thread
From: Akio Takebe @ 2009-03-26 13:46 UTC (permalink / raw)
  To: xen-devel

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

Hi,

# Oops, the subject of the previous mail is wrong.:)
# I send again with correct subject. Sorry.

this patch is tools parts.

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

Best Regards,

Akio Takebe

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

diff -r 0477f9061c8a tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c	Fri Mar 20 17:42:46 2009 +0000
+++ b/tools/firmware/hvmloader/hvmloader.c	Thu Mar 26 22:20:23 2009 +0900
@@ -477,10 +477,14 @@
 {
     uint32_t option_rom_addr, rom_phys_addr = rom_base_addr;
     uint16_t vendor_id, device_id;
-    uint8_t devfn, class;
+    uint8_t devfn, class, i;
 
-    for ( devfn = 0; devfn < 128; devfn++ )
-    {
+    for (i=0; i < MAX_PCI_BOOT; i++){
+        devfn = hvm_info->pci_sbdf[i];
+        if ( devfn ==0 )
+            continue;
+        printf("%s:devfn=%x \n",__func__, 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);
diff -r 0477f9061c8a tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c	Fri Mar 20 17:42:46 2009 +0000
+++ b/tools/firmware/rombios/rombios.c	Thu Mar 26 22:20:23 2009 +0900
@@ -187,18 +187,33 @@
 #define EBDA_SIZE          1              // In KiB
 #define BASE_MEM_IN_K   (640 - EBDA_SIZE)
 
-/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */
+/* 256 bytes at 0x9ff00 -- 0x9ffaf is used for the IPL boot table. */
 #define IPL_TABLE_OFFSET     0x0300  /* offset from EBDA */
 #define IPL_TABLE_ENTRIES    8
 #define IPL_COUNT_OFFSET     0x0380  /* u16: number of valid table entries */
 #define IPL_SEQUENCE_OFFSET  0x0382  /* u16: next boot device */
 #define IPL_BOOTFIRST_OFFSET 0x0384  /* u16: user selected device */
-#define IPL_SIZE             0xff
+#define IPL_SIZE             0xaf
 #define IPL_TYPE_FLOPPY      0x01
 #define IPL_TYPE_HARDDISK    0x02
 #define IPL_TYPE_CDROM       0x03
 #define IPL_TYPE_BEV         0x80
 
+#define IPL_TYPE_BCV         IPL_TYPE_HARDDISK
+
+/* 256 bytes at 0x9ffb0 -- 0x9ffff is used for the BCV boot table. */
+#define BCV_TABLE_OFFSET     0x03b0  /* offset from EBDA */
+#define BCV_TABLE_ENTRIES    4
+#define BCV_COUNT_OFFSET     0x03f0  /* u16: number of valid table entries */
+#define BCV_SEQUENCE_OFFSET  0x03f2  /* u16: next boot device */
+#define BCV_BOOTFIRST_OFFSET 0x03f4  /* u16: user selected device */
+#define BCV_SIZE             0x4f
+
+#define BOOTDEV_FDD 0x1
+#define BOOTDEV_HDD 0x2
+#define BOOTDEV_CD  0x3
+#define BOOTDEV_NET 0x4
+#define BOOTDEV_BCV 0x5
 
   // Sanity Checks
 #if BX_USE_ATADRV && BX_CPU<3
@@ -2064,14 +2079,65 @@
 
 static char drivetypes[][10]={"", "Floppy","Hard Disk","CD-Rom", "Network"};
 
+/* initialize BCV talbe. BCV and IPL table are the same structure. */
 static void
-init_boot_vectors()
+init_boot_connection_vector()
 {
   ipl_entry_t e;
   Bit16u count = 0;
   Bit16u ss = get_SS();
   Bit16u ebda_seg = read_word(0x0040, 0x000E);
 
+  /* Clear out the BCV table. */
+  memsetb(ebda_seg, BCV_TABLE_OFFSET, 0, BCV_SIZE);
+
+  /* User selected device not set */
+  write_word(ebda_seg, BCV_BOOTFIRST_OFFSET, 0xFFFF);
+
+  /* First HDD */
+//  e.type = IPL_TYPE_HARDDISK; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
+//  memcpyb(ebda_seg, BCV_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
+//  count++;
+
+  /* Remember how many devices we have */
+  write_word(ebda_seg, BCV_COUNT_OFFSET, count);
+  /* Not tried booting anything yet */
+  write_word(ebda_seg, BCV_SEQUENCE_OFFSET, 0xFFFF);
+}
+
+static Bit16u
+get_bcv_count()
+{
+  Bit16u count;
+  Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
+  count = read_word(ebda_seg, BCV_COUNT_OFFSET);
+  return count;
+}
+
+static Bit8u
+get_bcv_entry(i, e)
+Bit16u i; ipl_entry_t *e;
+{
+  Bit16u count;
+  Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
+  /* Get the count of boot devices, and refuse to overrun the array */
+  count = read_word(ebda_seg, BCV_COUNT_OFFSET);
+  if (i > count) return 0;
+  /* OK to read this device */
+  memcpyb(ss, e, ebda_seg, BCV_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));
+  return 1;
+}
+
+static void
+init_boot_vectors()
+{
+  ipl_entry_t e;
+  Bit16u count = 0;
+  Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
+
   /* Clear out the IPL table. */
   memsetb(ebda_seg, IPL_TABLE_OFFSET, 0, IPL_SIZE);
 
@@ -2106,13 +2172,23 @@
 Bit16u i; ipl_entry_t *e;
 {
   Bit16u count;
+  Bit16u j = i;
   Bit16u ss = get_SS();
   Bit16u ebda_seg = read_word(0x0040, 0x000E);
+
+  /* BCV device also use IPL_TYPE_HARDDISK. */
+  if(i == BOOTDEV_BCV)
+    j = BOOTDEV_HDD;
+
   /* Get the count of boot devices, and refuse to overrun the array */
   count = read_word(ebda_seg, IPL_COUNT_OFFSET);
-  if (i >= count) return 0;
+  if (j >= count) return 0;
+
+  /* Translate from CMOS runes to an IPL table offset by subtracting 1 */
+  j--;
+
   /* OK to read this device */
-  memcpyb(ss, e, ebda_seg, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));
+  memcpyb(ss, e, ebda_seg, IPL_TABLE_OFFSET + j * sizeof (*e), sizeof (*e));
   return 1;
 }
 
@@ -2204,7 +2280,7 @@
   type = e->type;
   /* NIC appears as type 0x80 */
   if (type == IPL_TYPE_BEV) type = 0x4;
-  if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n");
+  if (type == 0 || type > 0x5) BX_PANIC("Bad drive type(%d)\n", type);
   printf("Booting from %s", drivetypes[type]);
   /* print product string if BEV */
   if (type == 4 && e->description != 0) {
@@ -2217,6 +2293,22 @@
   printf("...\n");
 }
 
+void
+print_bcv_device(bcv, bootdrv)
+  ipl_entry_t *bcv;
+  Bit8u  bootdrv;
+{
+  char description[33];
+  Bit16u ss = get_SS();
+
+  if (bcv->description != 0)
+  {
+    memcpyb(ss, &description, (Bit16u)(bcv->description >> 16), (Bit16u)(bcv->description & 0xffff), 32);
+    description[32] = 0;
+    printf(" [%S]", ss, description);
+  }
+  printf(" bootdrv[0x%x]\n", bootdrv);
+}
 //--------------------------------------------------------------------------
 // print_boot_failure
 //   displays the reason why boot failed
@@ -8207,8 +8299,12 @@
   Bit16u bootip;
   Bit16u status;
   Bit16u bootfirst;
+  Bit16u bcv_count;
+  Bit16u retry_count;
+  Bit16u hdcount, ata_hdcount;
 
   ipl_entry_t e;
+  ipl_entry_t bcv;
 
   // if BX_ELTORITO_BOOT is not defined, old behavior
   //   check bit 5 in CMOS reg 0x2d.  load either 0x00 or 0x80 into DL
@@ -8245,8 +8341,6 @@
     write_word(ebda_seg, IPL_SEQUENCE_OFFSET, 0xFFFF);
   } else if (bootdev == 0) BX_PANIC("No bootable device.\n");
 
-  /* Translate from CMOS runes to an IPL table offset by subtracting 1 */
-  bootdev -= 1;
 #else
   if (seq_nr ==2) BX_PANIC("No more boot devices.");
   if (!!(inb_cmos(0x2d) & 0x20) ^ (seq_nr == 1))
@@ -8255,11 +8349,10 @@
   else
     bootdev = 0x01;
 #endif
-
   /* Read the boot device from the IPL table */
-  if (get_boot_vector(bootdev, &e) == 0) {
-    BX_INFO("Invalid boot device (0x%x)\n", bootdev);
-    return;
+  if (get_boot_vector(bootdev, &e) == 0 ){
+      BX_INFO("Invalid boot device (0x%x)\n", bootdev);
+      return;
   }
 
   /* Do the loading, and set up vector as a far pointer to the boot
@@ -8269,8 +8362,37 @@
   switch(e.type) {
   case IPL_TYPE_FLOPPY: /* FDD */
   case IPL_TYPE_HARDDISK: /* HDD */
-
-    bootdrv = (e.type == IPL_TYPE_HARDDISK) ? 0x80 : 0x00;
+    ata_hdcount = read_byte(ebda_seg, &EbdaData->ata.hdcount);
+    hdcount     = read_byte(0x40,0x75);
+    bcv_count   = hdcount - ata_hdcount;
+    if ( bcv_count != get_bcv_count() || bcv_count < 0 )
+        BX_PANIC("Invaild hdcount(%d) ata_hdcount=%d bcv_count=%d\n",
+                  hdcount, ata_hdcount, get_bcv_count());
+
+    BX_INFO("hdcount(%d) ata_hdcount=%d bcv_count=%d\n",
+            hdcount, ata_hdcount, get_bcv_count());
+    if ( bootdev == BOOTDEV_BCV ) {
+      retry_count = bcv_count;
+      bootdrv = (0x80 + ata_hdcount);
+    } else {
+      if ( ata_hdcount == 0 && e.type == IPL_TYPE_HARDDISK) {
+          print_boot_failure(e.type, 1);
+          return;
+      }
+      retry_count = 1;
+      bootdrv = (e.type == IPL_TYPE_HARDDISK) ? 0x80 : 0x00;
+    }
+retry_type_hdd:
+    if ( retry_count == 0 ) {
+      return; /* boot fail with all bcv devices */
+    } else {
+      if ( bootdev == BOOTDEV_BCV ) {
+        bootdrv = bootdrv + (bcv_count - retry_count);
+        get_bcv_entry(bcv_count - retry_count, &bcv);
+        print_bcv_device(&bcv, bootdrv);
+      } 
+    }
+
     bootseg = 0x07c0;
     status = 0;
 
@@ -8306,7 +8428,8 @@
 
     if (status != 0) {
       print_boot_failure(e.type, 1);
-      return;
+      retry_count--;
+      goto retry_type_hdd;
     }
 
     /* Always check the signature on a HDD boot sector; on FDD, only do
@@ -8314,7 +8437,8 @@
     if ((e.type != IPL_TYPE_FLOPPY) || !((inb_cmos(0x38) & 0x01))) {
       if (read_word(bootseg,0x1fe) != 0xaa55) {
         print_boot_failure(e.type, 0);
-        return;
+        retry_count--;
+        goto retry_type_hdd;
       }
     }
 
@@ -8326,6 +8450,7 @@
     /* Canonicalize bootseg:bootip */
     bootip = (bootseg & 0x0fff) << 4;
     bootseg &= 0xf000;
+    printf("boot from [%x:%x]\n", bootseg, bootip);
   break;
 
 #if BX_ELTORITO_BOOT
@@ -10585,7 +10710,31 @@
   cli           ;; In case expansion ROM BIOS turns IF on
   add  sp, #2   ;; Pop offset value
   pop  cx       ;; Pop seg value (restore CX)
-  jmp   no_bev
+
+  ;; Found BCV device. Recode it in BCV table.
+  mov  bx, 0x001a   ;; 0x1A is the offset into ROM header that contains...
+  mov  di, 0x10[bx]            ;; Pointer to the product name string or zero if none
+
+  xor  bx, bx
+  mov  ds, bx
+  mov  bx, word ptr [0x40E]    ;; EBDA segment
+  mov  ds, bx                  ;; Go to the segment where the BCV table lives
+  mov  bx, BCV_COUNT_OFFSET    ;; Read the number of entries so far
+  cmp  bx, #BCV_TABLE_ENTRIES
+  je   no_bev                  ;; Get out if the table is full
+  shl  bx, #0x4                ;; Turn count into offset (entries are 16 bytes)
+  mov  BCV_TABLE_OFFSET+0[bx], #IPL_TYPE_BCV ;; This entry is a BCV device
+  mov  BCV_TABLE_OFFSET+6[bx], cx            ;; Build a far pointer from the segment...
+  mov  BCV_TABLE_OFFSET+4[bx], ax            ;; and the offset
+  cmp  di, #0x0000
+  je   no_prod_str1
+  mov  BCV_TABLE_OFFSET+0xA[bx], cx          ;; segment to descritption
+  mov  BCV_TABLE_OFFSET+0x8[bx], di          ;; pointer to descritption
+no_prod_str1:
+  shr  bx, #0x4                ;; Turn the offset back into a count
+  inc  bx                      ;; We have one more entry now
+  mov  BCV_COUNT_OFFSET, bx    ;; Remember that.
+  jmp  no_bev
 
 no_bcv:
   mov  ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of...
@@ -10606,10 +10755,10 @@
   mov  IPL_TABLE_OFFSET+6[bx], cx            ;; Build a far pointer from the segment...
   mov  IPL_TABLE_OFFSET+4[bx], ax            ;; and the offset
   cmp  di, #0x0000
-  je   no_prod_str
+  je   no_prod_str2
   mov  0xA[bx], cx             ;; Build a far pointer from the segment...
   mov  8[bx], di               ;; and the offset
-no_prod_str:
+no_prod_str2:
   shr  bx, #0x4                ;; Turn the offset back into a count
   inc  bx                      ;; We have one more entry now
   mov  IPL_COUNT_OFFSET, bx    ;; Remember that.
@@ -11041,6 +11190,7 @@
 #endif
 
   call _init_boot_vectors
+  call _init_boot_connection_vector
 
   mov  cx, #(OPTIONROM_PHYSICAL_ADDRESS >> 4)  ;; init option roms
   mov  ax, #(OPTIONROM_PHYSICAL_END >> 4)
diff -r 0477f9061c8a tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py	Fri Mar 20 17:42:46 2009 +0000
+++ b/tools/python/xen/xm/create.py	Thu Mar 26 22:20:23 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,12 @@
           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.
+          If boot option is set, the devices are handled as bootable devices.
+          boot option can add only 4 pci devices.
+          If boot is set, guest BIOS can 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 +709,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 0477f9061c8a xen/include/public/hvm/hvm_info_table.h
--- a/xen/include/public/hvm/hvm_info_table.h	Fri Mar 20 17:42:46 2009 +0000
+++ b/xen/include/public/hvm/hvm_info_table.h	Thu Mar 26 22:20:23 2009 +0900
@@ -28,6 +28,8 @@
 #define HVM_INFO_PFN         0x09F
 #define HVM_INFO_OFFSET      0x800
 #define HVM_INFO_PADDR       ((HVM_INFO_PFN << 12) + HVM_INFO_OFFSET)
+
+#define MAX_PCI_BOOT 4
 
 struct hvm_info_table {
     char        signature[8]; /* "HVM INFO" */
@@ -64,6 +66,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_sbdf[MAX_PCI_BOOT];
 };
 
 #endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */

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

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

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

* Re: [Patch][2/2][BIOS] Support BCV table
  2009-03-26 13:43 ` [Patch][2/2][BIOS] " Akio Takebe
@ 2009-03-26 14:36   ` Keir Fraser
  2009-03-27  0:48     ` Akio Takebe
  0 siblings, 1 reply; 14+ messages in thread
From: Keir Fraser @ 2009-03-26 14:36 UTC (permalink / raw)
  To: Akio Takebe, xen-devel

On 26/03/2009 13:43, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:

> Hi,
> 
> This patch is qemu parts.
> 
> Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com>

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.

 -- Keir

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

* Re: [Patch][2/2][BIOS] Support BCV table
  2009-03-26 14:36   ` Keir Fraser
@ 2009-03-27  0:48     ` Akio Takebe
  2009-03-27  4:44       ` Akio Takebe
  2009-03-27  9:00       ` Keir Fraser
  0 siblings, 2 replies; 14+ messages in thread
From: Akio Takebe @ 2009-03-27  0:48 UTC (permalink / raw)
  To: Keir Fraser, xen-devel; +Cc: Akio Takebe

Hi,

>On 26/03/2009 13:43, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:
>
>> Hi,
>> 
>> This patch is qemu parts.
>> 
>> Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com>
>
>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?

Best Regards,

Akio Takebe

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

* Re: [Patch][2/2][BIOS] Support BCV table
  2009-03-27  0:48     ` Akio Takebe
@ 2009-03-27  4:44       ` Akio Takebe
  2009-03-27  9:02         ` Keir Fraser
  2009-03-27  9:00       ` Keir Fraser
  1 sibling, 1 reply; 14+ messages in thread
From: Akio Takebe @ 2009-03-27  4:44 UTC (permalink / raw)
  To: Keir Fraser, xen-devel; +Cc: Akio Takebe

Hi, Keir

>Hi,
>
>>On 26/03/2009 13:43, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:
>>
>>> Hi,
>>> 
>>> This patch is qemu parts.
>>> 
>>> Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com>
>>
>>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?
>
After some consideration, I abandon a feature of selecting bootable 
device. If I abandon it, I don't need to modify qemu. As the result, we 
need to configure a bootable device as vslot 6 or 7. I think it is 
reasonable. How about you?

Best Regards,

Akio Takebe

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

* Re: [Patch][2/2][BIOS] Support BCV table
  2009-03-27  0:48     ` Akio Takebe
  2009-03-27  4:44       ` Akio Takebe
@ 2009-03-27  9:00       ` Keir Fraser
  2009-03-27 10:23         ` Akio Takebe
  1 sibling, 1 reply; 14+ messages in thread
From: Keir Fraser @ 2009-03-27  9:00 UTC (permalink / raw)
  To: Akio Takebe, xen-devel

On 27/03/2009 00:48, "Akio Takebe" <takebe_akio@jp.fujitsu.com> 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.

But, for example, why not specify the vendor:dev identifier via
hvm_info_table, rather than specifying the vslot?

Or, if you feel you must do this via qemu, hack extra info into the PCI
config space of each device, or expose via the xen-platform device I/O
ports? Something which qemu already controls (unlike hvm_info_table).

 -- Keir

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

* Re: [Patch][2/2][BIOS] Support BCV table
  2009-03-27  4:44       ` Akio Takebe
@ 2009-03-27  9:02         ` Keir Fraser
  0 siblings, 0 replies; 14+ messages in thread
From: Keir Fraser @ 2009-03-27  9:02 UTC (permalink / raw)
  To: Akio Takebe, xen-devel

On 27/03/2009 04:44, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:

>> 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?
>> 
> After some consideration, I abandon a feature of selecting bootable
> device. If I abandon it, I don't need to modify qemu. As the result, we
> need to configure a bootable device as vslot 6 or 7. I think it is
> reasonable. How about you?

Errrr. You'll have to gove me some more hints about exactly what problem all
your work so far is trying to solve. :-)

 -- Keir

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

* Re: [Patch][2/2][BIOS] Support BCV table
  2009-03-27  9:00       ` Keir Fraser
@ 2009-03-27 10:23         ` Akio Takebe
  2009-03-27 10:31           ` Akio Takebe
  0 siblings, 1 reply; 14+ messages in thread
From: Akio Takebe @ 2009-03-27 10:23 UTC (permalink / raw)
  To: Keir Fraser, xen-devel; +Cc: Akio Takebe

>On 27/03/2009 00:48, "Akio Takebe" <takebe_akio@jp.fujitsu.com> 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.

>Or, if you feel you must do this via qemu, hack extra info into the PCI
>config space of each device, or expose via the xen-platform device I/O
>ports? Something which qemu already controls (unlike hvm_info_table).


Best Regards,

Akio Takebe

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

* Re: [Patch][2/2][BIOS] Support BCV table
  2009-03-27 10:23         ` Akio Takebe
@ 2009-03-27 10:31           ` Akio Takebe
  2009-03-27 13:49             ` Keir Fraser
  2009-03-30  6:50             ` Akio Takebe
  0 siblings, 2 replies; 14+ messages in thread
From: Akio Takebe @ 2009-03-27 10:31 UTC (permalink / raw)
  To: Keir Fraser, xen-devel; +Cc: Akio Takebe

[-- Attachment #1: Mail message body --]
[-- Type: text/plain, Size: 2551 bytes --]

>>On 27/03/2009 00:48, "Akio Takebe" <takebe_akio@jp.fujitsu.com> 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.

Best Regards,

Akio Takebe

[-- Attachment #2: bcv.v2.patch --]
[-- Type: application/octet-stream, Size: 9943 bytes --]

diff -r 0477f9061c8a tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c	Fri Mar 20 17:42:46 2009 +0000
+++ b/tools/firmware/rombios/rombios.c	Fri Mar 27 13:56:30 2009 +0900
@@ -187,18 +187,27 @@
 #define EBDA_SIZE          1              // In KiB
 #define BASE_MEM_IN_K   (640 - EBDA_SIZE)
 
-/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */
+/* 176 bytes at 0x9ff00 -- 0x9ffaf is used for the IPL boot table. */
 #define IPL_TABLE_OFFSET     0x0300  /* offset from EBDA */
 #define IPL_TABLE_ENTRIES    8
 #define IPL_COUNT_OFFSET     0x0380  /* u16: number of valid table entries */
 #define IPL_SEQUENCE_OFFSET  0x0382  /* u16: next boot device */
 #define IPL_BOOTFIRST_OFFSET 0x0384  /* u16: user selected device */
-#define IPL_SIZE             0xff
+#define IPL_SIZE             0xaf
 #define IPL_TYPE_FLOPPY      0x01
 #define IPL_TYPE_HARDDISK    0x02
 #define IPL_TYPE_CDROM       0x03
 #define IPL_TYPE_BEV         0x80
 
+#define IPL_TYPE_BCV         IPL_TYPE_HARDDISK
+
+/* 80 bytes at 0x9ffb0 -- 0x9ffff is used for the BCV boot table. */
+#define BCV_TABLE_OFFSET     0x03b0  /* offset from EBDA */
+#define BCV_TABLE_ENTRIES    4
+#define BCV_COUNT_OFFSET     0x03f0  /* u16: number of valid table entries */
+#define BCV_SEQUENCE_OFFSET  0x03f2  /* u16: next boot device */
+#define BCV_BOOTFIRST_OFFSET 0x03f4  /* u16: user selected device */
+#define BCV_SIZE             0x4f
 
   // Sanity Checks
 #if BX_USE_ATADRV && BX_CPU<3
@@ -2064,14 +2073,65 @@
 
 static char drivetypes[][10]={"", "Floppy","Hard Disk","CD-Rom", "Network"};
 
+/* initialize BCV talbe. BCV and IPL table are the same structure. */
 static void
-init_boot_vectors()
+init_boot_connection_vector()
 {
   ipl_entry_t e;
   Bit16u count = 0;
   Bit16u ss = get_SS();
   Bit16u ebda_seg = read_word(0x0040, 0x000E);
 
+  /* Clear out the BCV table. */
+  memsetb(ebda_seg, BCV_TABLE_OFFSET, 0, BCV_SIZE);
+
+  /* User selected device not set */
+  write_word(ebda_seg, BCV_BOOTFIRST_OFFSET, 0xFFFF);
+
+  /* First HDD */
+//  e.type = IPL_TYPE_HARDDISK; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
+//  memcpyb(ebda_seg, BCV_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
+//  count++;
+
+  /* Remember how many devices we have */
+  write_word(ebda_seg, BCV_COUNT_OFFSET, count);
+  /* Not tried booting anything yet */
+  write_word(ebda_seg, BCV_SEQUENCE_OFFSET, 0xFFFF);
+}
+
+static Bit16u
+get_bcv_count()
+{
+  Bit16u count;
+  Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
+  count = read_word(ebda_seg, BCV_COUNT_OFFSET);
+  return count;
+}
+
+static Bit8u
+get_bcv_entry(i, e)
+Bit16u i; ipl_entry_t *e;
+{
+  Bit16u count;
+  Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
+  /* Get the count of boot devices, and refuse to overrun the array */
+  count = read_word(ebda_seg, BCV_COUNT_OFFSET);
+  if (i > count) return 0;
+  /* OK to read this device */
+  memcpyb(ss, e, ebda_seg, BCV_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));
+  return 1;
+}
+
+static void
+init_boot_vectors()
+{
+  ipl_entry_t e;
+  Bit16u count = 0;
+  Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
+
   /* Clear out the IPL table. */
   memsetb(ebda_seg, IPL_TABLE_OFFSET, 0, IPL_SIZE);
 
@@ -2106,13 +2166,19 @@
 Bit16u i; ipl_entry_t *e;
 {
   Bit16u count;
+  Bit16u j = i;
   Bit16u ss = get_SS();
   Bit16u ebda_seg = read_word(0x0040, 0x000E);
+
   /* Get the count of boot devices, and refuse to overrun the array */
   count = read_word(ebda_seg, IPL_COUNT_OFFSET);
-  if (i >= count) return 0;
+  if (j >= count) return 0;
+
+  /* Translate from CMOS runes to an IPL table offset by subtracting 1 */
+  j--;
+
   /* OK to read this device */
-  memcpyb(ss, e, ebda_seg, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));
+  memcpyb(ss, e, ebda_seg, IPL_TABLE_OFFSET + j * sizeof (*e), sizeof (*e));
   return 1;
 }
 
@@ -2204,7 +2270,7 @@
   type = e->type;
   /* NIC appears as type 0x80 */
   if (type == IPL_TYPE_BEV) type = 0x4;
-  if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n");
+  if (type == 0 || type > 0x4) BX_PANIC("Bad drive type(%d)\n", type);
   printf("Booting from %s", drivetypes[type]);
   /* print product string if BEV */
   if (type == 4 && e->description != 0) {
@@ -2217,6 +2283,22 @@
   printf("...\n");
 }
 
+void
+print_bcv_device(bcv, bootdrv)
+  ipl_entry_t *bcv;
+  Bit8u  bootdrv;
+{
+  char description[33];
+  Bit16u ss = get_SS();
+
+  if (bcv->description != 0)
+  {
+    memcpyb(ss, &description, (Bit16u)(bcv->description >> 16), (Bit16u)(bcv->description & 0xffff), 32);
+    description[32] = 0;
+    printf(" [%S]", ss, description);
+  }
+  printf(" bootdrv[0x%x]\n", bootdrv);
+}
 //--------------------------------------------------------------------------
 // print_boot_failure
 //   displays the reason why boot failed
@@ -8207,8 +8289,12 @@
   Bit16u bootip;
   Bit16u status;
   Bit16u bootfirst;
+  Bit16u bcv_count;
+  Bit16u retry_count;
+  Bit16u hdcount, ata_hdcount;
 
   ipl_entry_t e;
+  ipl_entry_t bcv;
 
   // if BX_ELTORITO_BOOT is not defined, old behavior
   //   check bit 5 in CMOS reg 0x2d.  load either 0x00 or 0x80 into DL
@@ -8245,8 +8331,6 @@
     write_word(ebda_seg, IPL_SEQUENCE_OFFSET, 0xFFFF);
   } else if (bootdev == 0) BX_PANIC("No bootable device.\n");
 
-  /* Translate from CMOS runes to an IPL table offset by subtracting 1 */
-  bootdev -= 1;
 #else
   if (seq_nr ==2) BX_PANIC("No more boot devices.");
   if (!!(inb_cmos(0x2d) & 0x20) ^ (seq_nr == 1))
@@ -8255,7 +8339,6 @@
   else
     bootdev = 0x01;
 #endif
-
   /* Read the boot device from the IPL table */
   if (get_boot_vector(bootdev, &e) == 0) {
     BX_INFO("Invalid boot device (0x%x)\n", bootdev);
@@ -8269,8 +8352,32 @@
   switch(e.type) {
   case IPL_TYPE_FLOPPY: /* FDD */
   case IPL_TYPE_HARDDISK: /* HDD */
-
+    ata_hdcount = read_byte(ebda_seg, &EbdaData->ata.hdcount);
+    hdcount     = read_byte(0x40,0x75);
+    bcv_count   = hdcount - ata_hdcount;
+    if ( bcv_count != get_bcv_count() || bcv_count < 0 )
+        BX_PANIC("Invaild hdcount(%d) ata_hdcount=%d bcv_count=%d\n",
+                  hdcount, ata_hdcount, get_bcv_count());
+
+    BX_INFO("hdcount(%d) ata_hdcount=%d bcv_count=%d\n",
+            hdcount, ata_hdcount, get_bcv_count());
+    if ( hdcount == 0 && e.type == IPL_TYPE_HARDDISK) {
+      print_boot_failure(e.type, 1);
+      return;
+    }
+    retry_count = hdcount;
     bootdrv = (e.type == IPL_TYPE_HARDDISK) ? 0x80 : 0x00;
+retry_type_hdd:
+    if ( retry_count == 0 ) {
+      return; /* boot fail with all bcv devices */
+    } else {
+      bootdrv = bootdrv + hdcount - retry_count;
+      if ( ata_hdcount == 0 || bootdrv > 0x80 ) {
+        get_bcv_entry(bcv_count - retry_count, &bcv);
+        print_bcv_device(&bcv, bootdrv);
+      }
+    }
+
     bootseg = 0x07c0;
     status = 0;
 
@@ -8306,7 +8413,8 @@
 
     if (status != 0) {
       print_boot_failure(e.type, 1);
-      return;
+      retry_count--;
+      goto retry_type_hdd;
     }
 
     /* Always check the signature on a HDD boot sector; on FDD, only do
@@ -8314,7 +8422,8 @@
     if ((e.type != IPL_TYPE_FLOPPY) || !((inb_cmos(0x38) & 0x01))) {
       if (read_word(bootseg,0x1fe) != 0xaa55) {
         print_boot_failure(e.type, 0);
-        return;
+        retry_count--;
+        goto retry_type_hdd;
       }
     }
 
@@ -8326,6 +8435,7 @@
     /* Canonicalize bootseg:bootip */
     bootip = (bootseg & 0x0fff) << 4;
     bootseg &= 0xf000;
+    printf("boot from [%x:%x]\n", bootseg, bootip);
   break;
 
 #if BX_ELTORITO_BOOT
@@ -10585,7 +10695,31 @@
   cli           ;; In case expansion ROM BIOS turns IF on
   add  sp, #2   ;; Pop offset value
   pop  cx       ;; Pop seg value (restore CX)
-  jmp   no_bev
+
+  ;; Found BCV device. Recode it in BCV table.
+  mov  bx, 0x001a   ;; 0x1A is the offset into ROM header that contains...
+  mov  di, 0x10[bx]            ;; Pointer to the product name string or zero if none
+
+  xor  bx, bx
+  mov  ds, bx
+  mov  bx, word ptr [0x40E]    ;; EBDA segment
+  mov  ds, bx                  ;; Go to the segment where the BCV table lives
+  mov  bx, BCV_COUNT_OFFSET    ;; Read the number of entries so far
+  cmp  bx, #BCV_TABLE_ENTRIES
+  je   no_bev                  ;; Get out if the table is full
+  shl  bx, #0x4                ;; Turn count into offset (entries are 16 bytes)
+  mov  BCV_TABLE_OFFSET+0[bx], #IPL_TYPE_BCV ;; This entry is a BCV device
+  mov  BCV_TABLE_OFFSET+6[bx], cx            ;; Build a far pointer from the segment...
+  mov  BCV_TABLE_OFFSET+4[bx], ax            ;; and the offset
+  cmp  di, #0x0000
+  je   no_prod_str1
+  mov  BCV_TABLE_OFFSET+0xA[bx], cx          ;; segment to descritption
+  mov  BCV_TABLE_OFFSET+0x8[bx], di          ;; pointer to descritption
+no_prod_str1:
+  shr  bx, #0x4                ;; Turn the offset back into a count
+  inc  bx                      ;; We have one more entry now
+  mov  BCV_COUNT_OFFSET, bx    ;; Remember that.
+  jmp  no_bev
 
 no_bcv:
   mov  ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of...
@@ -10606,10 +10740,10 @@
   mov  IPL_TABLE_OFFSET+6[bx], cx            ;; Build a far pointer from the segment...
   mov  IPL_TABLE_OFFSET+4[bx], ax            ;; and the offset
   cmp  di, #0x0000
-  je   no_prod_str
+  je   no_prod_str2
   mov  0xA[bx], cx             ;; Build a far pointer from the segment...
   mov  8[bx], di               ;; and the offset
-no_prod_str:
+no_prod_str2:
   shr  bx, #0x4                ;; Turn the offset back into a count
   inc  bx                      ;; We have one more entry now
   mov  IPL_COUNT_OFFSET, bx    ;; Remember that.
@@ -11041,6 +11175,7 @@
 #endif
 
   call _init_boot_vectors
+  call _init_boot_connection_vector
 
   mov  cx, #(OPTIONROM_PHYSICAL_ADDRESS >> 4)  ;; init option roms
   mov  ax, #(OPTIONROM_PHYSICAL_END >> 4)

[-- Attachment #3: support_interactive_boot_for_bcv.patch --]
[-- Type: application/octet-stream, Size: 4559 bytes --]

diff -r 910b54a7202d tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c	Fri Mar 27 13:58:04 2009 +0900
+++ b/tools/firmware/rombios/rombios.c	Fri Mar 27 17:55:37 2009 +0900
@@ -942,6 +942,7 @@ static void           interactive_bootke
 static void           interactive_bootkey();
 static void           print_bios_banner();
 static void           print_boot_device();
+static void           print_bcv_device();
 static void           print_boot_failure();
 static void           print_cdromboot_failure();
 
@@ -2187,10 +2188,15 @@ interactive_bootkey()
 interactive_bootkey()
 {
   ipl_entry_t e;
+  ipl_entry_t bcv;
   Bit16u count;
   char description[33];
   Bit8u scan_code;
   Bit8u i;
+  Bit16u bootdrv;
+  Bit16u bcv_count;
+  Bit16u retry_count;
+  Bit16u hdcount, ata_hdcount;
   Bit16u ss = get_SS();
   Bit16u valid_choice = 0;
   Bit16u ebda_seg = read_word(0x0040, 0x000E);
@@ -2216,8 +2222,8 @@ interactive_bootkey()
       switch(e.type)
       {
         case IPL_TYPE_FLOPPY:
+        case IPL_TYPE_CDROM:
         case IPL_TYPE_HARDDISK:
-        case IPL_TYPE_CDROM:
           printf("%s\n", drivetypes[e.type]);
           break;
         case IPL_TYPE_BEV:
@@ -2233,6 +2239,18 @@ interactive_bootkey()
       }
     }
 
+    ata_hdcount = read_byte(ebda_seg, &EbdaData->ata.hdcount);
+    hdcount     = read_byte(0x40,0x75);
+    bcv_count   = hdcount - ata_hdcount;
+    for (i = 0; i < bcv_count; i++){
+      bootdrv = 0x80 + i + ata_hdcount;
+      get_bcv_entry(i, &bcv);
+      printf("%d. ", i+count+1);
+      printf("Attached PCI device:");
+      print_bcv_device(&bcv, bootdrv);
+      
+    }
+
     count++;
     while (!valid_choice) {
       scan_code = get_keystroke();
@@ -2240,12 +2258,19 @@ interactive_bootkey()
       {
         valid_choice = 1;
       }
-      else if (scan_code <= count)
+      else if (scan_code <= count + bcv_count)
       {
         valid_choice = 1;
         scan_code -= 1;
-        /* Set user selected device */
-        write_word(ebda_seg, IPL_BOOTFIRST_OFFSET, scan_code);
+        if (scan_code < count)
+        {
+          /* Set user selected device */
+          write_word(ebda_seg, IPL_BOOTFIRST_OFFSET, scan_code);
+        } else {
+          /* Set user selected device */
+          write_word(ebda_seg, IPL_BOOTFIRST_OFFSET, scan_code);
+          write_word(ebda_seg, BCV_BOOTFIRST_OFFSET, scan_code - count);
+        }
       }
     }
 
@@ -8288,7 +8313,9 @@ Bit16u seq_nr;
   Bit16u bootseg;
   Bit16u bootip;
   Bit16u status;
-  Bit16u bootfirst;
+  Bit16u ipl_bootfirst;
+  Bit16u ipl_count;
+  Bit16u bcv_bootfirst;
   Bit16u bcv_count;
   Bit16u retry_count;
   Bit16u hdcount, ata_hdcount;
@@ -8322,11 +8349,18 @@ Bit16u seq_nr;
   bootdev &= 0xf;
 
   /* Read user selected device */
-  bootfirst = read_word(ebda_seg, IPL_BOOTFIRST_OFFSET);
-  if (bootfirst != 0xFFFF) {
-    bootdev = bootfirst;
+  ipl_bootfirst = read_word(ebda_seg, IPL_BOOTFIRST_OFFSET);
+  bcv_bootfirst = read_word(ebda_seg, BCV_BOOTFIRST_OFFSET);
+  if (ipl_bootfirst != 0xFFFF) {
+    ipl_count = read_word(ebda_seg, IPL_COUNT_OFFSET);
+    if ( ipl_bootfirst > ipl_count ) {
+      bootdev = 2; /* It's a attached PCI. convert to HDD type*/
+    } else {
+      bootdev = ipl_bootfirst;
+    }
     /* User selected device not set */
     write_word(ebda_seg, IPL_BOOTFIRST_OFFSET, 0xFFFF);
+    write_word(ebda_seg, BCV_BOOTFIRST_OFFSET, 0xFFFF);
     /* Reset boot sequence */
     write_word(ebda_seg, IPL_SEQUENCE_OFFSET, 0xFFFF);
   } else if (bootdev == 0) BX_PANIC("No bootable device.\n");
@@ -8367,15 +8401,27 @@ Bit16u seq_nr;
     }
     retry_count = hdcount;
     bootdrv = (e.type == IPL_TYPE_HARDDISK) ? 0x80 : 0x00;
+
 retry_type_hdd:
-    if ( retry_count == 0 ) {
+    if ( retry_count == 0 ) 
       return; /* boot fail with all bcv devices */
-    } else {
+
+    if (ipl_bootfirst != 0xFFFF ) {
+      retry_count = 1;
+      if (bcv_bootfirst != 0xFFFF ) {
+        bootdrv = 0x80 + bcv_bootfirst + ata_hdcount;
+      } else {
+        if ( ata_hdcount == 0) {
+          print_boot_failure(e.type, 1);
+          return;
+        }
+      }
+    } else
       bootdrv = bootdrv + hdcount - retry_count;
-      if ( ata_hdcount == 0 || bootdrv > 0x80 ) {
-        get_bcv_entry(bcv_count - retry_count, &bcv);
-        print_bcv_device(&bcv, bootdrv);
-      }
+
+    if ( ata_hdcount == 0 || bootdrv > 0x80 ) {
+      get_bcv_entry(bcv_count - retry_count, &bcv);
+      print_bcv_device(&bcv, bootdrv);
     }
 
     bootseg = 0x07c0;

[-- 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	[flat|nested] 14+ messages in thread

* Re: [Patch][2/2][BIOS] Support BCV table
  2009-03-27 10:31           ` Akio Takebe
@ 2009-03-27 13:49             ` Keir Fraser
  2009-03-27 14:22               ` Akio Takebe
  2009-03-30  6:50             ` Akio Takebe
  1 sibling, 1 reply; 14+ messages in thread
From: Keir Fraser @ 2009-03-27 13:49 UTC (permalink / raw)
  To: Akio Takebe, xen-devel

On 27/03/2009 10:31, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:

> 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.

Both are plausible. Looking at your previous email, I get the impression
that the limitations are in rombios, and/or its integration with hvmloader.
Would the right fix really to make rombios be a bit smarter: being able to
load and discard option ROMs into 0xc0000-0xe0000 range, for example? Also,
I have the view that parts of rombios's POST routines could get moved into
hvmloader, even if we keep rombios for its real-mode BIOS service routines,
after POST. Actually I'd be happy to see hvmloader get a bit fatter at
rombios's expense! Perhaps this is a possibility for the Xen 3.5 development
cycle.

 -- Keir

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

* Re: [Patch][2/2][BIOS] Support BCV table
  2009-03-27 13:49             ` Keir Fraser
@ 2009-03-27 14:22               ` Akio Takebe
  0 siblings, 0 replies; 14+ messages in thread
From: Akio Takebe @ 2009-03-27 14:22 UTC (permalink / raw)
  To: Keir Fraser, xen-devel; +Cc: Akio Takebe

>On 27/03/2009 10:31, "Akio Takebe" <takebe_akio@jp.fujitsu.com> wrote:
>
>> 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.
>
>Both are plausible. Looking at your previous email, I get the impression
>that the limitations are in rombios, and/or its integration with hvmloader.
>Would the right fix really to make rombios be a bit smarter: being able to
>load and discard option ROMs into 0xc0000-0xe0000 range, for example? Also,
Thanks. Yes, you are right.

>I have the view that parts of rombios's POST routines could get moved into
>hvmloader, even if we keep rombios for its real-mode BIOS service routines,
>after POST. Actually I'd be happy to see hvmloader get a bit fatter at
>rombios's expense! Perhaps this is a possibility for the Xen 3.5 development
>cycle.
OK, I will also improve my patch with your idea of vendor:dev id
for Xen-3.5.

Best Regards,

Akio Takebe

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

* Re: [Patch][2/2][BIOS] Support BCV table
  2009-03-27 10:31           ` Akio Takebe
  2009-03-27 13:49             ` Keir Fraser
@ 2009-03-30  6:50             ` Akio Takebe
  1 sibling, 0 replies; 14+ messages in thread
From: Akio Takebe @ 2009-03-30  6:50 UTC (permalink / raw)
  To: Keir Fraser, xen-devel

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

Hi,

Akio Takebe wrote:
>>> On 27/03/2009 00:48, "Akio Takebe" <takebe_akio@jp.fujitsu.com> 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

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

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__ */

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

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

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

end of thread, other threads:[~2009-03-30  6:50 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-26 13:40 [Patch][0/2][BIOS] Support BCV table Akio Takebe
2009-03-26 13:42 ` Akio Takebe
2009-03-26 13:46   ` [Patch][1/2][BIOS] " Akio Takebe
2009-03-26 13:43 ` [Patch][2/2][BIOS] " Akio Takebe
2009-03-26 14:36   ` Keir Fraser
2009-03-27  0:48     ` Akio Takebe
2009-03-27  4:44       ` Akio Takebe
2009-03-27  9:02         ` Keir Fraser
2009-03-27  9:00       ` Keir Fraser
2009-03-27 10:23         ` Akio Takebe
2009-03-27 10:31           ` Akio Takebe
2009-03-27 13:49             ` Keir Fraser
2009-03-27 14:22               ` Akio Takebe
2009-03-30  6:50             ` 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.