mirror of
https://github.com/ipxe/ipxe
synced 2026-02-12 09:59:51 +03:00
Use the magic of common symbols to allow struct dev to effectively grow at
link time to accommodate whatever bus objects are included.
This commit is contained in:
@@ -144,7 +144,10 @@ static int initialized;
|
|||||||
|
|
||||||
|
|
||||||
/* Global instance of the current boot device */
|
/* 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
|
* 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
|
#if 0
|
||||||
|
|
||||||
static int main_loop(int state)
|
static int main_loop(int state)
|
||||||
|
|||||||
@@ -13,6 +13,14 @@
|
|||||||
#define DBG(...)
|
#define DBG(...)
|
||||||
#endif
|
#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
|
* Fill in parameters for an EISA device based on slot number
|
||||||
*
|
*
|
||||||
@@ -52,15 +60,14 @@ static int fill_eisa_device ( struct eisa_device *eisa ) {
|
|||||||
* Obtain a struct eisa * from a struct dev *
|
* Obtain a struct eisa * from a struct dev *
|
||||||
*
|
*
|
||||||
* If dev has not previously been used for an EISA device scan, blank
|
* 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_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 ) );
|
memset ( eisa, 0, sizeof ( *eisa ) );
|
||||||
dev->devid.bus_type = EISA_BUS_TYPE;
|
eisa->magic = eisa_magic;
|
||||||
eisa->slot = EISA_MIN_SLOT;
|
|
||||||
}
|
}
|
||||||
eisa->dev = dev;
|
eisa->dev = dev;
|
||||||
return eisa;
|
return eisa;
|
||||||
@@ -74,8 +81,13 @@ int find_eisa_device ( struct eisa_device *eisa, struct eisa_driver *driver ) {
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Iterate through all possible EISA slots, starting where we
|
/* 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++ ) {
|
for ( ; eisa->slot <= EISA_MAX_SLOT ; eisa->slot++ ) {
|
||||||
/* If we've already used this device, skip it */
|
/* If we've already used this device, skip it */
|
||||||
if ( eisa->already_tried ) {
|
if ( eisa->already_tried ) {
|
||||||
@@ -101,6 +113,8 @@ int find_eisa_device ( struct eisa_device *eisa, struct eisa_driver *driver ) {
|
|||||||
eisa->prod_id ) );
|
eisa->prod_id ) );
|
||||||
if ( eisa->dev ) {
|
if ( eisa->dev ) {
|
||||||
eisa->dev->name = driver->name;
|
eisa->dev->name = driver->name;
|
||||||
|
eisa->dev->devid.bus_type
|
||||||
|
= ISA_BUS_TYPE;
|
||||||
eisa->dev->devid.vendor_id
|
eisa->dev->devid.vendor_id
|
||||||
= eisa->mfg_id;
|
= eisa->mfg_id;
|
||||||
eisa->dev->devid.device_id
|
eisa->dev->devid.device_id
|
||||||
|
|||||||
@@ -19,6 +19,14 @@
|
|||||||
#define DBG(...)
|
#define DBG(...)
|
||||||
#endif
|
#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
|
* 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 *
|
* Obtain a struct mca * from a struct dev *
|
||||||
*
|
*
|
||||||
* If dev has not previously been used for an MCA device scan, blank
|
* 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_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 ) );
|
memset ( mca, 0, sizeof ( *mca ) );
|
||||||
dev->devid.bus_type = MCA_BUS_TYPE;
|
mca->magic = mca_magic;
|
||||||
}
|
}
|
||||||
mca->dev = dev;
|
mca->dev = dev;
|
||||||
return mca;
|
return mca;
|
||||||
@@ -97,8 +105,10 @@ int find_mca_device ( struct mca_device *mca, struct mca_driver *driver ) {
|
|||||||
id->name, driver->name, id->id );
|
id->name, driver->name, id->id );
|
||||||
if ( mca->dev ) {
|
if ( mca->dev ) {
|
||||||
mca->dev->name = driver->name;
|
mca->dev->name = driver->name;
|
||||||
mca->dev->devid.vendor_id =
|
mca->dev->devid.bus_type
|
||||||
GENERIC_MCA_VENDOR;
|
= MCA_BUS_TYPE;
|
||||||
|
mca->dev->devid.vendor_id
|
||||||
|
= GENERIC_MCA_VENDOR;
|
||||||
mca->dev->devid.device_id = id->id;
|
mca->dev->devid.device_id = id->id;
|
||||||
}
|
}
|
||||||
mca->already_tried = 1;
|
mca->already_tried = 1;
|
||||||
|
|||||||
@@ -9,6 +9,14 @@
|
|||||||
#define DBG(...)
|
#define DBG(...)
|
||||||
#endif
|
#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
|
* Fill in parameters (vendor & device ids, class, membase etc.) for a
|
||||||
* PCI device based on bus & devfn.
|
* PCI device based on bus & devfn.
|
||||||
@@ -112,19 +120,33 @@ void adjust_pci_device ( struct pci_device *pci ) {
|
|||||||
* Obtain a struct pci * from a struct dev *
|
* Obtain a struct pci * from a struct dev *
|
||||||
*
|
*
|
||||||
* If dev has not previously been used for a PCI device scan, blank
|
* 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_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 ) );
|
memset ( pci, 0, sizeof ( *pci ) );
|
||||||
dev->devid.bus_type = PCI_BUS_TYPE;
|
pci->magic = pci_magic;
|
||||||
}
|
}
|
||||||
pci->dev = dev;
|
pci->dev = dev;
|
||||||
return pci;
|
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
|
* 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 */
|
/* Fill in dev structure, if present */
|
||||||
if ( pci->dev ) {
|
if ( pci->dev ) {
|
||||||
pci->dev->name = driver->name;
|
pci->dev->name = driver->name;
|
||||||
|
pci->dev->devid.bus_type = PCI_BUS_TYPE;
|
||||||
pci->dev->devid.vendor_id = pci->vendor;
|
pci->dev->devid.vendor_id = pci->vendor;
|
||||||
pci->dev->devid.device_id = pci->dev_id;
|
pci->dev->devid.device_id = pci->dev_id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,6 @@
|
|||||||
|
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
/* Bus types */
|
|
||||||
#include "pci.h"
|
|
||||||
#include "eisa.h"
|
|
||||||
#include "mca.h"
|
|
||||||
|
|
||||||
/* Device types */
|
/* Device types */
|
||||||
#include "nic.h"
|
#include "nic.h"
|
||||||
|
|
||||||
@@ -18,8 +13,7 @@ struct dev_id {
|
|||||||
uint8_t bus_type;
|
uint8_t bus_type;
|
||||||
#define PCI_BUS_TYPE 1
|
#define PCI_BUS_TYPE 1
|
||||||
#define ISA_BUS_TYPE 2
|
#define ISA_BUS_TYPE 2
|
||||||
#define EISA_BUS_TYPE 3
|
#define MCA_BUS_TYPE 3
|
||||||
#define MCA_BUS_TYPE 4
|
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/* Dont use sizeof, that will include the padding */
|
/* Dont use sizeof, that will include the padding */
|
||||||
@@ -29,18 +23,25 @@ struct dev {
|
|||||||
struct dev_operations *dev_op;
|
struct dev_operations *dev_op;
|
||||||
const char *name;
|
const char *name;
|
||||||
struct dev_id devid; /* device ID string (sent to DHCP server) */
|
struct dev_id devid; /* device ID string (sent to DHCP server) */
|
||||||
/* All possible bus types */
|
/* Pointer to bus information for device. Whatever sets up
|
||||||
union {
|
* the struct dev must make sure that this points to a buffer
|
||||||
struct pci_device pci;
|
* large enough for the required struct <bus>_device.
|
||||||
struct eisa_device eisa;
|
*/
|
||||||
struct mca_device mca;
|
void *bus;
|
||||||
};
|
|
||||||
/* All possible device types */
|
/* All possible device types */
|
||||||
union {
|
union {
|
||||||
struct nic nic;
|
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 {
|
struct dev_operations {
|
||||||
void ( *disable ) ( struct dev * );
|
void ( *disable ) ( struct dev * );
|
||||||
void ( *print_info ) ( struct dev * );
|
void ( *print_info ) ( struct dev * );
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
struct dev;
|
struct dev;
|
||||||
struct eisa_device {
|
struct eisa_device {
|
||||||
|
char *magic; /* must be first */
|
||||||
struct dev *dev;
|
struct dev *dev;
|
||||||
unsigned int slot;
|
unsigned int slot;
|
||||||
uint16_t ioaddr;
|
uint16_t ioaddr;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
*/
|
*/
|
||||||
struct dev;
|
struct dev;
|
||||||
struct mca_device {
|
struct mca_device {
|
||||||
|
char *magic; /* must be first */
|
||||||
struct dev *dev;
|
struct dev *dev;
|
||||||
unsigned int slot;
|
unsigned int slot;
|
||||||
unsigned char pos[8];
|
unsigned char pos[8];
|
||||||
|
|||||||
@@ -232,13 +232,13 @@
|
|||||||
#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
|
#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_32 8 /* 16 bits of data for 32-bit devices */
|
||||||
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
|
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A physical PCI device
|
* A physical PCI device
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct dev;
|
struct dev;
|
||||||
struct pci_device {
|
struct pci_device {
|
||||||
|
char * magic; /* must be first */
|
||||||
struct dev * dev;
|
struct dev * dev;
|
||||||
uint32_t membase; /* BAR 1 */
|
uint32_t membase; /* BAR 1 */
|
||||||
uint32_t ioaddr; /* first IO BAR */
|
uint32_t ioaddr; /* first IO BAR */
|
||||||
|
|||||||
Reference in New Issue
Block a user