From: Gleb Natapov <gleb@redhat.com>
To: "Kevin O'Connor" <kevin@koconnor.net>
Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, seabios@seabios.org
Subject: Re: [PATCHv6 00/16] boot order specification
Date: Tue, 30 Nov 2010 16:01:00 +0200 [thread overview]
Message-ID: <20101130140100.GH2187@redhat.com> (raw)
In-Reply-To: <20101130013402.GB3488@morn.localdomain>
On Mon, Nov 29, 2010 at 08:34:03PM -0500, Kevin O'Connor wrote:
> On Sun, Nov 28, 2010 at 08:47:34PM +0200, Gleb Natapov wrote:
> > On Sun, Nov 28, 2010 at 12:15:44PM -0500, Kevin O'Connor wrote:
> > > It's unclear to me how SeaBIOS is supposed to do that.
> > >
> > Suppose we have "/pci@i0cf8/scsi@3/disk@0,0" with boot index 5 in
> > boot devices list and suppose pci device in slot 3 function 0 has
> > optionrom. When Seabios load the option rom from device to memory it looks
> > for string that matches "/pci@i0cf8/.*@3.*" if the string is found option
> > rom gets boot index from it. In our case "/pci@i0cf8/scsi@3/disk@0,0"
> > will match and optionrom will get boot index 5. In practice Seabios will
> > know that device is SCSI by reading device class so it will be able
> > to construct string "/pci@i0cf8/scsi@3" and use simple strstr to find
> > matching device path.
>
> I recognize that if we had a regex engine in seabios this would work,
> but I'm reluctant to add one. strstr doesn't work becuase "@3" could
> match some unrelated part of the path (eg, don't want to match
> "/pci@i0cf8/scsi@1/disk@3,0") - so, what you seem to want is
> "/pci@i0cf8/[^/]*@3(/|$)".
>
We do not need regex engine to part this very special and regular
string. The patch below reads boot order list from qemu and creates
rom2prio table for pci roms.
> [...]
> > > I'm still stuck on how seabios is supposed to know it's an ethernet
> > > card. Sure, seabios could hardcode translations from classid to
> > > strings, but that seems fragile. What happens when the user wants to
> > > boot from myranet, or fiberchannel, or whatnot?
> > This is not fragile since class to name translation is defined
> > by the spec. But even that is not required if Seabios will be a
> > little bit smarter and will implement fuzzy matching. i.e do not
> > match "/pci@i0cf8/ethernet@4/ethernet-phy@0" exactly but match
> > "/pci@i0cf8/.*@4.*" instead.
>
> I think we're agreeing here that we don't want to put class to name
> translation in seabios. :-)
We did? I think it is not needed but I don't not see why it would be
a problem.
>
> > > Maybe we can compromise here - if the user selects booting from a
> > > device, and qemu sees there is a rom for that device, then qemu can
> > > specify two boot options:
> > >
> > > /pci@i0cf8/ethernet@4/ethernet-phy@0
> > > /pci@i0cf8/rom@4
> > >
> > This patch series implement device paths as defined by Openfirmware
> > spec. /pci@i0cf8/rom@4 sould be out of spec. But I do not see why Seabios
> > can't build later from the former. Also I do not see why it would be
> > needed at all.
>
> The name isn't important to me - call it something else if you want.
> It's value is that SeaBIOS doesn't then need to do fuzzy matching or
> parsing of the device names. That is, we turn the list from boot
> devices to boot methods which makes life easier for the firmware.
>
> > > SeaBIOS will ignore the first entry, and act on the second entry. If
> > > at some later point seabios knows how to natively boot from the device
> > > (eg, scsi), then it will use the first entry and ignore the second.
> > >
> > If you let go to the idea of exact matching of string built by qemu in
> > Seabios it will be easy to see that /pci@i0cf8/ethernet@4/ethernet-phy@0
> > provides everything that Seabios needs to know and even more. If
> > you ignore all the noise it just says "boot from pci device slot 4 fn
> > 0". Seabios may have native support for the card in the slot or it can
> > use option rom on the card. Qemu does not care.
>
> I'm having a hard time letting go of string matching. I understand
> all the info is there if SeaBIOS parses the string. However, I think
> parsing out openbios device strings is overkill in an x86 bios that
> just wants to order the boot objects it knows about.
>
> Is there an issue with qemu generating two strings for devices with
> roms?
>
I just do not see how I can justify this addition to qemu maintainers
given that the parsing code below is very simple.
diff --git a/src/boot.c b/src/boot.c
index 021b8ac..c1ac9af 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -67,6 +67,47 @@ boot_setup(void)
if (!(inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1))
IPL.checkfloppysig = 1;
}
+
+ u32 file = romfile_find("bootorder");
+ if (!file)
+ return;
+
+ int filesize = romfile_size(file);
+ char *f = malloc_tmphigh(filesize);
+ dprintf(3, "bootorder file found (len %d)\n", filesize);
+
+ if (!f) {
+ dprintf(1, "can't allocate memory for bootorder file\n");
+ return;
+ }
+
+ romfile_copy(file, f, filesize);
+ int i;
+ IPL.fw_bootorder_count = 1;
+ while(f[i]) {
+ if (f[i] == '\n')
+ IPL.fw_bootorder_count++;
+ i++;
+ }
+ IPL.fw_bootorder = malloc_tmphigh(IPL.fw_bootorder_count*sizeof(char*));
+ if (!IPL.fw_bootorder) {
+ dprintf(1, "can't allocate memory for bootorder\n");
+ free(f);
+ return;
+ }
+
+ dprintf(3, "boot order:\n");
+ i = 0;
+ do {
+ IPL.fw_bootorder[i] = f;
+ f = strchr(f, '\n');
+ if (*f) {
+ *f = '\0';
+ f++;
+ dprintf(3, "%d: %s\n", i, IPL.fw_bootorder[i]);
+ i++;
+ }
+ } while(f);
}
// Add a BEV vector for a given pnp compatible option rom.
@@ -506,3 +547,78 @@ handle_19(void)
SET_EBDA(boot_sequence, 0);
do_boot(0);
}
+
+/*
+ * function returns string representing firts device path element in 'dp'
+ * and puts pointer to the reset of the device path into 'end'
+ */
+static char *dev_path_get_node(const char *dp, const char **end)
+{
+ int len;
+ char *node;
+
+ dp += 1; /* skip '/' */
+
+ *end = strchr(dp, '/');
+
+ if (*end == NULL) {
+ len = strlen(dp); /* last path element */
+ *end = dp + len;
+ }
+ else
+ len = *end - dp;
+
+ if (len == 0)
+ return NULL;
+
+ node = malloc_tmphigh(len + 1);
+ memcpy(node, dp, len);
+ node[len] = '\0';
+
+ return node;
+}
+
+static int match_unit_address(const char *pe, const char *unit_address)
+{
+ char *s = strchr(pe, '@');
+
+ if (s == NULL)
+ return 0;
+
+ return !strcmp(s, unit_address);
+}
+
+#define FW_PCI_DOMAIN "/pci@i0cf8"
+
+int bootprio_match_pci_device(int dev, int fn)
+{
+ int i, l;
+ char pci[7];
+
+ if (!fn)
+ l = snprintf(pci, sizeof(pci), "@%x", dev);
+ else
+ l = snprintf(pci, sizeof(pci), "@%x,%x", dev, fn);
+
+ for (i = 0; i < IPL.fw_bootorder_count; i++) {
+ char *node;
+ const char *next, *path = IPL.fw_bootorder[i];
+ int r;
+
+ /* is pci domain? */
+ if (memcmp(path, FW_PCI_DOMAIN, strlen(FW_PCI_DOMAIN)))
+ continue;
+
+ node = dev_path_get_node(path + strlen(FW_PCI_DOMAIN), &next);
+ if (node == NULL)
+ continue;
+
+ r = match_unit_address(node, pci);
+
+ free(node);
+ if (r)
+ return i;
+ }
+
+ return -1;
+}
diff --git a/src/boot.h b/src/boot.h
index db046e3..07467e6 100644
--- a/src/boot.h
+++ b/src/boot.h
@@ -20,6 +20,8 @@ struct ipl_s {
int bevcount, bcvcount;
u32 bootorder;
int checkfloppysig;
+ char **fw_bootorder;
+ int fw_bootorder_count;
};
#define IPL_TYPE_FLOPPY 0x01
@@ -44,5 +46,6 @@ void add_bcv(u16 seg, u16 ip, u16 desc);
struct drive_s;
void add_bcv_internal(struct drive_s *drive_g);
void boot_prep(void);
+int bootprio_match_pci_device(int dev, int fn);
#endif // __BOOT_H
diff --git a/src/optionroms.c b/src/optionroms.c
index 854c33f..5500c56 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -74,6 +74,13 @@ struct pnp_data {
// The end of the last deployed rom.
u32 RomEnd = BUILD_ROM_START;
+static struct rom_boot_prio {
+ u32 addr;
+ int prio;
+} rom2prio[92];
+
+static int rom2prio_index;
+
/****************************************************************
* Helper functions
@@ -342,7 +349,20 @@ init_pcirom(u16 bdf, int isvga)
if (! rom)
// No ROM present.
return -1;
- return init_optionrom(rom, bdf, isvga);
+
+ int r = init_optionrom(rom, bdf, isvga);
+
+ if (r || !is_valid_rom(rom))
+ return r;
+
+ rom2prio[rom2prio_index].addr = (u32)rom;
+ rom2prio[rom2prio_index].prio =
+ bootprio_match_pci_device(pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf));
+ dprintf(3, "pci rom at memory address %x has boot prio %d\n",
+ rom2prio[rom2prio_index].addr, rom2prio[rom2prio_index].prio);
+ rom2prio_index++;
+
+ return r;
}
diff --git a/src/util.c b/src/util.c
index 8e02d1e..cfb4add 100644
--- a/src/util.c
+++ b/src/util.c
@@ -253,6 +253,17 @@ strtcpy(char *dest, const char *src, size_t len)
return dest;
}
+// locate first occurance of character c in the string s
+char *
+strchr(const char *s, int c)
+{
+ int i = 0;
+
+ while(s[i] && s[i] != c)
+ i++;
+
+ return s[i] ? (char*)&s[i] : NULL;
+}
/****************************************************************
* Keyboard calls
diff --git a/src/util.h b/src/util.h
index 18ab814..cd46d9c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -208,6 +208,7 @@ void *memcpy(void *d1, const void *s1, size_t len);
void iomemcpy(void *d, const void *s, u32 len);
void *memmove(void *d, const void *s, size_t len);
char *strtcpy(char *dest, const char *src, size_t len);
+char *strchr(const char *s, int c);
int get_keystroke(int msec);
// stacks.c
--
Gleb.
next prev parent reply other threads:[~2010-11-30 14:01 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-17 16:43 [PATCHv6 00/16] boot order specification Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 01/16] Introduce fw_name field to DeviceInfo structure Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 02/16] Introduce new BusInfo callback get_fw_dev_path Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 03/16] Keep track of ISA ports ISA device is using in qdev Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 04/16] Add get_fw_dev_path callback to ISA bus " Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 05/16] Store IDE bus id in IDEBus structure for easy access Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 06/16] Add get_fw_dev_path callback to IDE bus Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 07/16] Add get_dev_path callback for system bus Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 08/16] Add get_fw_dev_path callback for pci bus Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 09/16] Record which USBDevice USBPort belongs too Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 10/16] Add get_dev_path callback for usb bus Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 11/16] Add get_dev_path callback to scsi bus Gleb Natapov
2010-11-17 16:43 ` [PATCHv6 12/16] Add bootindex parameter to net/block/fd device Gleb Natapov
2010-11-17 16:44 ` [PATCHv6 13/16] Change fw_cfg_add_file() to get full file path as a parameter Gleb Natapov
2010-11-17 16:44 ` [PATCHv6 14/16] Add bootindex for option roms Gleb Natapov
2010-11-17 16:44 ` [PATCHv6 15/16] Add notifier that will be called when machine is fully created Gleb Natapov
2010-11-17 16:44 ` [PATCHv6 16/16] Pass boot device list to firmware Gleb Natapov
2010-11-23 15:31 ` [PATCHv6 00/16] boot order specification Gleb Natapov
2010-11-23 16:12 ` Anthony Liguori
2010-11-23 19:30 ` Blue Swirl
2010-11-27 20:56 ` Avi Kivity
2010-11-28 7:54 ` Gleb Natapov
2010-11-28 9:38 ` Avi Kivity
2010-11-28 9:47 ` Gleb Natapov
2010-11-28 12:39 ` Blue Swirl
2010-11-28 13:03 ` Gleb Natapov
2010-11-28 13:13 ` Michael S. Tsirkin
2010-11-28 13:19 ` Gleb Natapov
2010-11-28 13:22 ` Blue Swirl
2010-11-28 17:02 ` Michael S. Tsirkin
2010-11-28 17:23 ` Michael S. Tsirkin
2010-11-28 18:54 ` Gleb Natapov
2010-11-28 19:09 ` Michael S. Tsirkin
2010-11-28 19:20 ` Gleb Natapov
2010-11-28 13:25 ` Gleb Natapov
2010-11-24 1:19 ` Kevin O'Connor
2010-11-24 10:03 ` Gleb Natapov
2010-11-27 15:41 ` Kevin O'Connor
2010-11-27 16:22 ` Gleb Natapov
2010-11-27 16:49 ` Kevin O'Connor
2010-11-27 17:06 ` Gleb Natapov
2010-11-27 17:47 ` Kevin O'Connor
2010-11-27 18:15 ` Gleb Natapov
2010-11-27 18:40 ` Kevin O'Connor
2010-11-27 19:04 ` Gleb Natapov
2010-11-27 21:07 ` Kevin O'Connor
2010-11-28 7:45 ` Gleb Natapov
2010-11-28 17:15 ` Kevin O'Connor
2010-11-28 18:47 ` Gleb Natapov
2010-11-28 19:11 ` [SeaBIOS] " Peter Stuge
2010-11-28 19:52 ` Gleb Natapov
2010-11-30 1:34 ` Kevin O'Connor
2010-11-30 14:01 ` Gleb Natapov [this message]
2010-12-01 2:53 ` Kevin O'Connor
2010-12-01 12:27 ` Gleb Natapov
2010-12-02 2:25 ` Kevin O'Connor
2010-12-02 12:30 ` Gleb Natapov
2010-12-02 15:07 ` [SeaBIOS] " Peter Stuge
2010-12-02 17:13 ` Gleb Natapov
2010-12-02 21:22 ` Sebastian Herbszt
2010-12-03 2:01 ` Kevin O'Connor
2010-12-03 5:55 ` Gleb Natapov
2010-11-29 10:50 ` Gerd Hoffmann
2010-11-30 1:55 ` Kevin O'Connor
2010-11-30 14:59 ` Gleb Natapov
2010-11-28 19:00 ` [SeaBIOS] " Peter Stuge
2010-11-28 19:16 ` Gleb Natapov
2010-11-29 10:19 ` Gerd Hoffmann
2010-11-29 12:07 ` Gleb Natapov
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=20101130140100.GH2187@redhat.com \
--to=gleb@redhat.com \
--cc=kevin@koconnor.net \
--cc=kvm@vger.kernel.org \
--cc=qemu-devel@nongnu.org \
--cc=seabios@seabios.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox