mirror of
https://github.com/ipxe/ipxe
synced 2025-12-15 00:12:19 +03:00
[legacy] Allocate legacy driver .bss-like segments at probe time
Some legacy drivers use large static allocations for transmit and receive buffers. To avoid bloating the .bss segment, we currently implement these as a single common symbol named "_shared_bss" (which is permissible since only one legacy driver may be active at any one time). Switch to dynamic allocation of these .bss-like segments, to avoid the requirement for using common symbols. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -623,28 +623,6 @@ char __debug_disable(OBJECT) = ( DBGLVL_MAX & ~DBGLVL_DFLT );
|
||||
*/
|
||||
#define inline inline __attribute__ (( no_instrument_function ))
|
||||
|
||||
/**
|
||||
* Shared data.
|
||||
*
|
||||
* To save space in the binary when multiple-driver images are
|
||||
* compiled, uninitialised data areas can be shared between drivers.
|
||||
* This will typically be used to share statically-allocated receive
|
||||
* and transmit buffers between drivers.
|
||||
*
|
||||
* Use as e.g.
|
||||
*
|
||||
* @code
|
||||
*
|
||||
* struct {
|
||||
* char rx_buf[NUM_RX_BUF][RX_BUF_SIZE];
|
||||
* char tx_buf[TX_BUF_SIZE];
|
||||
* } my_static_data __shared;
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
#define __shared __asm__ ( "_shared_bss" ) __aligned
|
||||
|
||||
#endif /* ASSEMBLY */
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -57,8 +57,14 @@ struct nic {
|
||||
unsigned int mbps;
|
||||
duplex_t duplex;
|
||||
void *priv_data; /* driver private data */
|
||||
void *fake_bss;
|
||||
size_t fake_bss_len;
|
||||
};
|
||||
|
||||
#define NIC_FAKE_BSS_PTR( type ) ( ( type * ) legacy_nic.fake_bss )
|
||||
#define NIC_FAKE_BSS( type ) ( * NIC_FAKE_BSS_PTR ( type ) )
|
||||
extern struct {} no_fake_bss;
|
||||
|
||||
struct nic_operations {
|
||||
int ( *connect ) ( struct nic * );
|
||||
int ( *poll ) ( struct nic *, int retrieve );
|
||||
@@ -90,7 +96,8 @@ extern int legacy_probe ( void *hwdev,
|
||||
void ( * set_drvdata ) ( void *hwdev, void *priv ),
|
||||
struct device *dev,
|
||||
int ( * probe ) ( struct nic *nic, void *hwdev ),
|
||||
void ( * disable ) ( struct nic *nic, void *hwdev ));
|
||||
void ( * disable ) ( struct nic *nic, void *hwdev ),
|
||||
size_t fake_bss_len );
|
||||
void legacy_remove ( void *hwdev,
|
||||
void * ( * get_drvdata ) ( void *hwdev ),
|
||||
void ( * disable ) ( struct nic *nic, void *hwdev ) );
|
||||
@@ -210,7 +217,8 @@ static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
|
||||
}
|
||||
|
||||
#undef DRIVER
|
||||
#define DRIVER(_name_text,_unused2,_unused3,_name,_probe,_disable) \
|
||||
#define DRIVER( _name_text, _unused2, _unused3, _name, _probe, _disable, \
|
||||
_fake_bss ) \
|
||||
static __attribute__ (( unused )) const char \
|
||||
_name ## _text[] = _name_text; \
|
||||
static inline int \
|
||||
@@ -225,7 +233,8 @@ static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
|
||||
_name ## _pci_legacy_probe ( struct pci_device *pci ) { \
|
||||
return legacy_probe ( pci, legacy_pci_set_drvdata, \
|
||||
&pci->dev, _name ## _probe, \
|
||||
_name ## _disable ); \
|
||||
_name ## _disable, \
|
||||
sizeof ( _fake_bss ) ); \
|
||||
} \
|
||||
static inline void \
|
||||
_name ## _pci_legacy_remove ( struct pci_device *pci ) { \
|
||||
@@ -237,7 +246,8 @@ static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
|
||||
const struct isapnp_device_id *id __unused ) { \
|
||||
return legacy_probe ( isapnp, legacy_isapnp_set_drvdata, \
|
||||
&isapnp->dev, _name ## _probe, \
|
||||
_name ## _disable ); \
|
||||
_name ## _disable, \
|
||||
sizeof ( _fake_bss ) ); \
|
||||
} \
|
||||
static inline void \
|
||||
_name ## _isapnp_legacy_remove ( struct isapnp_device *isapnp ) { \
|
||||
@@ -249,7 +259,8 @@ static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
|
||||
const struct eisa_device_id *id __unused ) { \
|
||||
return legacy_probe ( eisa, legacy_eisa_set_drvdata, \
|
||||
&eisa->dev, _name ## _probe, \
|
||||
_name ## _disable ); \
|
||||
_name ## _disable, \
|
||||
sizeof ( _fake_bss ) ); \
|
||||
} \
|
||||
static inline void \
|
||||
_name ## _eisa_legacy_remove ( struct eisa_device *eisa ) { \
|
||||
@@ -261,7 +272,8 @@ static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
|
||||
const struct mca_device_id *id __unused ) { \
|
||||
return legacy_probe ( mca, legacy_mca_set_drvdata, \
|
||||
&mca->dev, _name ## _probe, \
|
||||
_name ## _disable ); \
|
||||
_name ## _disable, \
|
||||
sizeof ( _fake_bss ) ); \
|
||||
} \
|
||||
static inline void \
|
||||
_name ## _mca_legacy_remove ( struct mca_device *mca ) { \
|
||||
@@ -272,7 +284,8 @@ static inline void * legacy_isa_get_drvdata ( void *hwdev ) {
|
||||
_name ## _isa_legacy_probe ( struct isa_device *isa ) { \
|
||||
return legacy_probe ( isa, legacy_isa_set_drvdata, \
|
||||
&isa->dev, _name ## _probe, \
|
||||
_name ## _disable ); \
|
||||
_name ## _disable, \
|
||||
sizeof ( _fake_bss ) ); \
|
||||
} \
|
||||
static inline void \
|
||||
_name ## _isa_legacy_remove ( struct isa_device *isa ) { \
|
||||
|
||||
Reference in New Issue
Block a user