[SeaBIOS] [PATCH 6/9] Add functions for boot device path parsing.
Gleb Natapov
gleb at redhat.com
Thu Dec 23 10:29:40 CET 2010
Add functions that find boot device path for pci/ata/floppy/rom devices.
Signed-off-by: Gleb Natapov <gleb at redhat.com>
---
src/boot.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/boot.h | 5 ++
2 files changed, 161 insertions(+), 0 deletions(-)
diff --git a/src/boot.c b/src/boot.c
index 9c37023..aeacf08 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -13,6 +13,7 @@
#include "boot.h" // struct ipl_s
#include "cmos.h" // inb_cmos
#include "paravirt.h"
+#include "pci.h" //pci_bdf_to_*
struct ipl_s IPL;
@@ -574,3 +575,158 @@ 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 rest 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);
+ if (!node) {
+ warn_noalloc();
+ return NULL;
+ }
+ 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 + 1, unit_address);
+}
+
+static int match_next_node_address(const char *path, const char *addr,
+ const char **rest)
+{
+ char *node = dev_path_get_node(path, rest);
+
+ if (!node)
+ return 0;
+
+ int r = match_unit_address(node, addr);
+ free(node);
+
+ return r;
+}
+
+static int match_pci_node(const char *path, int bdf, const char **rest)
+{
+ char pci[7];
+ int dev = pci_bdf_to_dev(bdf), fn = pci_bdf_to_fn(bdf);
+
+ if (!fn)
+ snprintf(pci, sizeof(pci), "%x", dev);
+ else
+ snprintf(pci, sizeof(pci), "%x,%x", dev, fn);
+
+ return match_next_node_address(path, pci, rest);
+}
+
+#define FW_PCI_DOMAIN "/pci at i0cf8"
+
+static u8 find_pci_device(int bdf, u8 start_idx, const char **rest)
+{
+ u8 i;
+
+ for (i = start_idx; i < IPL.fw_bootorder_count; i++) {
+ const char *path = IPL.fw_bootorder[i];
+
+ /* is pci domain? */
+ if (memcmp(path, FW_PCI_DOMAIN, strlen(FW_PCI_DOMAIN)))
+ continue;
+
+ if (match_pci_node(path + strlen(FW_PCI_DOMAIN), bdf, rest))
+ return i;
+ }
+
+ return MAX_BOOT_PRIO;
+}
+
+u8 bootprio_find_pci_device(int bdf)
+{
+ const char *rest;
+
+ return find_pci_device(bdf, 0, &rest);
+}
+
+u8 bootprio_find_ata_device(int bdf, int chanid, int slave)
+{
+ const char *rest;
+ u8 idx = 0;
+
+ if (bdf == -1)
+ return MAX_BOOT_PRIO; /* support only pci machine for now */
+
+ while((idx = find_pci_device(bdf, idx, &rest)) != MAX_BOOT_PRIO) {
+ if (match_next_node_address(rest, chanid ? "1" : "0", &rest) &&
+ match_next_node_address(rest, slave ? "1" : "0", &rest))
+ break;
+ idx++;
+ }
+
+ return idx;
+}
+
+
+u8 bootprio_find_fdc_device(int bdf, int port, int fdid)
+{
+ const char *rest;
+ u8 idx = 0;
+ char addr[5];
+
+ if (bdf == -1)
+ return MAX_BOOT_PRIO; /* support only pci machine for now */
+
+ snprintf(addr, sizeof addr, "%04x", port);
+
+ while((idx = find_pci_device(bdf, idx, &rest)) != MAX_BOOT_PRIO) {
+ if (match_next_node_address(rest, addr, &rest) &&
+ match_next_node_address(rest, fdid ? "1" : "0", &rest))
+ break;
+ idx++;
+ }
+
+ return idx;
+}
+
+u8 bootprio_find_named_rom(const char *name)
+{
+ u8 i;
+
+ for (i = 0; i < IPL.fw_bootorder_count; i++) {
+ const char *path = IPL.fw_bootorder[i];
+
+ /* is this rom file? */
+ if (memcmp(path, "/rom@", strlen("/rom@")))
+ continue;
+
+ if (strcmp(path + strlen("/rom@"), name))
+ return i;
+ }
+
+ return MAX_BOOT_PRIO;
+}
diff --git a/src/boot.h b/src/boot.h
index 778aebd..0dfb135 100644
--- a/src/boot.h
+++ b/src/boot.h
@@ -33,6 +33,7 @@ struct ipl_s {
#define BCV_TYPE_EXTERNAL 0x80
#define BCV_TYPE_INTERNAL 0x02
+#define MAX_BOOT_PRIO 255
/****************************************************************
* Function defs
@@ -48,5 +49,9 @@ void add_bcv_internal(struct drive_s *drive_g);
void add_baid_cdrom(struct drive_s *drive_g);
void boot_prep(void);
+u8 bootprio_find_pci_device(int bdf);
+u8 bootprio_find_ata_device(int bdf, int chanid, int slave);
+u8 bootprio_find_fdc_device(int bfd, int port, int fdid);
+u8 bootprio_find_named_rom(const char *name);
#endif // __BOOT_H
--
1.7.2.3
More information about the SeaBIOS
mailing list