summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2005-04-14 12:10:54 +0200
committerMichael Brown2005-04-14 12:10:54 +0200
commit75d864432cc41c45d46df9ea7d3afd7cccbc0148 (patch)
tree8b98bce9c01b2f99f16d5da9f93a4e147dfe1865 /src
parentStripped references to variables in C code. (diff)
downloadipxe-75d864432cc41c45d46df9ea7d3afd7cccbc0148.tar.gz
ipxe-75d864432cc41c45d46df9ea7d3afd7cccbc0148.tar.xz
ipxe-75d864432cc41c45d46df9ea7d3afd7cccbc0148.zip
Use the magic of common symbols to allow struct dev to effectively grow at
link time to accommodate whatever bus objects are included.
Diffstat (limited to 'src')
-rw-r--r--src/core/main.c23
-rw-r--r--src/drivers/bus/eisa.c26
-rw-r--r--src/drivers/bus/mca.c22
-rw-r--r--src/drivers/bus/pci.c31
-rw-r--r--src/include/dev.h27
-rw-r--r--src/include/eisa.h1
-rw-r--r--src/include/mca.h1
-rw-r--r--src/include/pci.h2
8 files changed, 84 insertions, 49 deletions
diff --git a/src/core/main.c b/src/core/main.c
index da1c58a6f..3cc777a8e 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -144,7 +144,10 @@ static int initialized;
/* Global instance of the current boot device */
-struct dev dev;
+DEV_BUS(struct {}, dev_bus);
+struct dev dev = {
+ .bus = &dev_bus,
+};
/**************************************************************************
* initialise() - perform any C-level initialisation
@@ -213,24 +216,6 @@ void exit(int status)
}
-/*
- * Set PCI device to use.
- *
- * This routine can be called by e.g. the ROM prefix to specify that
- * the first device to be tried should be the device on which the ROM
- * was physically located.
- *
- * Note that this is deliberately in main.c rather than pci.c, because
- * this function should generalise to other bus types (e.g. ISAPnP),
- * and we don't want to end up dragging in pci.o unnecessarily.
- */
-void set_pci_device ( uint16_t busdevfn ) {
- dev.devid.bus_type = PCI_BUS_TYPE;
- dev.pci.busdevfn = busdevfn;
- dev.pci.already_tried = 0;
-}
-
-
#if 0
static int main_loop(int state)
diff --git a/src/drivers/bus/eisa.c b/src/drivers/bus/eisa.c
index a294895d3..c80974a8a 100644
--- a/src/drivers/bus/eisa.c
+++ b/src/drivers/bus/eisa.c
@@ -14,6 +14,14 @@
#endif
/*
+ * Ensure that there is sufficient space in the shared dev_bus
+ * structure for a struct pci_device.
+ *
+ */
+DEV_BUS( struct eisa_device, eisa_dev );
+static char eisa_magic[0]; /* guaranteed unique symbol */
+
+/*
* Fill in parameters for an EISA device based on slot number
*
* Return 1 if device present, 0 otherwise
@@ -52,15 +60,14 @@ static int fill_eisa_device ( struct eisa_device *eisa ) {
* Obtain a struct eisa * from a struct dev *
*
* If dev has not previously been used for an EISA device scan, blank
- * out dev.eisa
+ * out struct eisa
*/
struct eisa_device * eisa_device ( struct dev *dev ) {
- struct eisa_device *eisa = &dev->eisa;
+ struct eisa_device *eisa = dev->bus;;
- if ( dev->devid.bus_type != EISA_BUS_TYPE ) {
+ if ( eisa->magic != eisa_magic ) {
memset ( eisa, 0, sizeof ( *eisa ) );
- dev->devid.bus_type = EISA_BUS_TYPE;
- eisa->slot = EISA_MIN_SLOT;
+ eisa->magic = eisa_magic;
}
eisa->dev = dev;
return eisa;
@@ -74,8 +81,13 @@ int find_eisa_device ( struct eisa_device *eisa, struct eisa_driver *driver ) {
unsigned int i;
/* Iterate through all possible EISA slots, starting where we
- * left off/
+ * left off. If eisa->slot is zero (which it will be if we
+ * have a zeroed structure), start from slot EISA_MIN_SLOT,
+ * since slot 0 doesn't exist.
*/
+ if ( ! eisa->slot ) {
+ eisa->slot = EISA_MIN_SLOT;
+ }
for ( ; eisa->slot <= EISA_MAX_SLOT ; eisa->slot++ ) {
/* If we've already used this device, skip it */
if ( eisa->already_tried ) {
@@ -101,6 +113,8 @@ int find_eisa_device ( struct eisa_device *eisa, struct eisa_driver *driver ) {
eisa->prod_id ) );
if ( eisa->dev ) {
eisa->dev->name = driver->name;
+ eisa->dev->devid.bus_type
+ = ISA_BUS_TYPE;
eisa->dev->devid.vendor_id
= eisa->mfg_id;
eisa->dev->devid.device_id
diff --git a/src/drivers/bus/mca.c b/src/drivers/bus/mca.c
index 28b99f77a..1715c5883 100644
--- a/src/drivers/bus/mca.c
+++ b/src/drivers/bus/mca.c
@@ -20,6 +20,14 @@
#endif
/*
+ * Ensure that there is sufficient space in the shared dev_bus
+ * structure for a struct pci_device.
+ *
+ */
+DEV_BUS( struct mca_device, mca_dev );
+static char mca_magic[0]; /* guaranteed unique symbol */
+
+/*
* Fill in parameters for an MCA device based on slot number
*
*/
@@ -53,14 +61,14 @@ static int fill_mca_device ( struct mca_device *mca ) {
* Obtain a struct mca * from a struct dev *
*
* If dev has not previously been used for an MCA device scan, blank
- * out dev.mca
+ * out struct mca
*/
struct mca_device * mca_device ( struct dev *dev ) {
- struct mca_device *mca = &dev->mca;
+ struct mca_device *mca = dev->bus;
- if ( dev->devid.bus_type != MCA_BUS_TYPE ) {
+ if ( mca->magic != mca_magic ) {
memset ( mca, 0, sizeof ( *mca ) );
- dev->devid.bus_type = MCA_BUS_TYPE;
+ mca->magic = mca_magic;
}
mca->dev = dev;
return mca;
@@ -97,8 +105,10 @@ int find_mca_device ( struct mca_device *mca, struct mca_driver *driver ) {
id->name, driver->name, id->id );
if ( mca->dev ) {
mca->dev->name = driver->name;
- mca->dev->devid.vendor_id =
- GENERIC_MCA_VENDOR;
+ mca->dev->devid.bus_type
+ = MCA_BUS_TYPE;
+ mca->dev->devid.vendor_id
+ = GENERIC_MCA_VENDOR;
mca->dev->devid.device_id = id->id;
}
mca->already_tried = 1;
diff --git a/src/drivers/bus/pci.c b/src/drivers/bus/pci.c
index 4b4e9a151..d23a647a8 100644
--- a/src/drivers/bus/pci.c
+++ b/src/drivers/bus/pci.c
@@ -10,6 +10,14 @@
#endif
/*
+ * Ensure that there is sufficient space in the shared dev_bus
+ * structure for a struct pci_device.
+ *
+ */
+DEV_BUS( struct pci_device, pci_dev );
+static char pci_magic[0]; /* guaranteed unique symbol */
+
+/*
* Fill in parameters (vendor & device ids, class, membase etc.) for a
* PCI device based on bus & devfn.
*
@@ -112,20 +120,34 @@ void adjust_pci_device ( struct pci_device *pci ) {
* Obtain a struct pci * from a struct dev *
*
* If dev has not previously been used for a PCI device scan, blank
- * out dev.pci
+ * out struct pci
*/
struct pci_device * pci_device ( struct dev *dev ) {
- struct pci_device *pci = &dev->pci;
+ struct pci_device *pci = dev->bus;
- if ( dev->devid.bus_type != PCI_BUS_TYPE ) {
+ if ( pci->magic != pci_magic ) {
memset ( pci, 0, sizeof ( *pci ) );
- dev->devid.bus_type = PCI_BUS_TYPE;
+ pci->magic = pci_magic;
}
pci->dev = dev;
return pci;
}
/*
+ * Set PCI device to use.
+ *
+ * This routine can be called by e.g. the ROM prefix to specify that
+ * the first device to be tried should be the device on which the ROM
+ * was physically located.
+ *
+ */
+void set_pci_device ( uint16_t busdevfn ) {
+ pci_dev.magic = pci_magic;
+ pci_dev.busdevfn = busdevfn;
+ pci_dev.already_tried = 0;
+}
+
+/*
* Find a PCI device matching the specified driver
*
*/
@@ -154,6 +176,7 @@ int find_pci_device ( struct pci_device *pci,
/* Fill in dev structure, if present */
if ( pci->dev ) {
pci->dev->name = driver->name;
+ pci->dev->devid.bus_type = PCI_BUS_TYPE;
pci->dev->devid.vendor_id = pci->vendor;
pci->dev->devid.device_id = pci->dev_id;
}
diff --git a/src/include/dev.h b/src/include/dev.h
index a9e2916b1..b5a2edda5 100644
--- a/src/include/dev.h
+++ b/src/include/dev.h
@@ -3,11 +3,6 @@
#include "stdint.h"
-/* Bus types */
-#include "pci.h"
-#include "eisa.h"
-#include "mca.h"
-
/* Device types */
#include "nic.h"
@@ -18,8 +13,7 @@ struct dev_id {
uint8_t bus_type;
#define PCI_BUS_TYPE 1
#define ISA_BUS_TYPE 2
-#define EISA_BUS_TYPE 3
-#define MCA_BUS_TYPE 4
+#define MCA_BUS_TYPE 3
} __attribute__ ((packed));
/* Dont use sizeof, that will include the padding */
@@ -29,18 +23,25 @@ struct dev {
struct dev_operations *dev_op;
const char *name;
struct dev_id devid; /* device ID string (sent to DHCP server) */
- /* All possible bus types */
- union {
- struct pci_device pci;
- struct eisa_device eisa;
- struct mca_device mca;
- };
+ /* Pointer to bus information for device. Whatever sets up
+ * the struct dev must make sure that this points to a buffer
+ * large enough for the required struct <bus>_device.
+ */
+ void *bus;
/* All possible device types */
union {
struct nic nic;
};
};
+/*
+ * Macro to help create a common symbol with enough space for any
+ * struct <bus>_device.
+ *
+ * Use as e.g. DEV_BUS(struct pci_device);
+ */
+#define DEV_BUS(datatype,symbol) datatype symbol __asm__ ( "_dev_bus" );
+
struct dev_operations {
void ( *disable ) ( struct dev * );
void ( *print_info ) ( struct dev * );
diff --git a/src/include/eisa.h b/src/include/eisa.h
index 4fe14fc69..ed0ccef35 100644
--- a/src/include/eisa.h
+++ b/src/include/eisa.h
@@ -27,6 +27,7 @@
*/
struct dev;
struct eisa_device {
+ char *magic; /* must be first */
struct dev *dev;
unsigned int slot;
uint16_t ioaddr;
diff --git a/src/include/mca.h b/src/include/mca.h
index e69b65601..c12b1cabe 100644
--- a/src/include/mca.h
+++ b/src/include/mca.h
@@ -28,6 +28,7 @@
*/
struct dev;
struct mca_device {
+ char *magic; /* must be first */
struct dev *dev;
unsigned int slot;
unsigned char pos[8];
diff --git a/src/include/pci.h b/src/include/pci.h
index 36edc0f58..988259a32 100644
--- a/src/include/pci.h
+++ b/src/include/pci.h
@@ -232,13 +232,13 @@
#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
-
/*
* A physical PCI device
*
*/
struct dev;
struct pci_device {
+ char * magic; /* must be first */
struct dev * dev;
uint32_t membase; /* BAR 1 */
uint32_t ioaddr; /* first IO BAR */