[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:
Michael Brown
2025-06-24 13:17:19 +01:00
parent 6ea800ab54
commit d3e10ebd35
26 changed files with 100 additions and 80 deletions

View File

@@ -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 */
/** @} */

View File

@@ -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 ) { \