From: Akio Takebe <takebe_akio@jp.fujitsu.com>
To: Keir Fraser <keir.fraser@eu.citrix.com>,
xen-devel <xen-devel@lists.xensource.com>
Cc: Akio Takebe <takebe_akio@jp.fujitsu.com>
Subject: Re: [Patch][2/2][BIOS] Support BCV table
Date: Fri, 27 Mar 2009 19:31:22 +0900 [thread overview]
Message-ID: <8DC9AEC72C5177takebe_akio@jp.fujitsu.com> (raw)
In-Reply-To: <8CC9AEC60A1E3Ctakebe_akio@jp.fujitsu.com>
[-- 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
next prev parent reply other threads:[~2009-03-27 10:31 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
2009-03-27 13:49 ` Keir Fraser
2009-03-27 14:22 ` Akio Takebe
2009-03-30 6:50 ` Akio Takebe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8DC9AEC72C5177takebe_akio@jp.fujitsu.com \
--to=takebe_akio@jp.fujitsu.com \
--cc=keir.fraser@eu.citrix.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.