From 481f14d87fad24a9b6c99df702904cf4219c9c8c Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 1 Jul 2013 11:42:38 +0200 Subject: sysmobts: Cache the eeprom_Cfg_t for reading tx/rx calib data The current code has 26 fseek/fread. Only the minority really results in a call to read. Nevertheless the time for reading during the bootstrap can take up to 7.82 seconds. Caching the header (which is already done by fopen/fread) will result in one call to fseek/fread and only consumes 0.784 seconds. --- src/osmo-bts-sysmo/eeprom.c | 142 +++++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/osmo-bts-sysmo/eeprom.c b/src/osmo-bts-sysmo/eeprom.c index e3b94fc3..f0fdaabb 100644 --- a/src/osmo-bts-sysmo/eeprom.c +++ b/src/osmo-bts-sysmo/eeprom.c @@ -260,6 +260,7 @@ typedef struct static int eeprom_read( int addr, int size, char *pBuff ); static int eeprom_write( int addr, int size, const char *pBuff ); static uint16_t eeprom_crc( uint8_t *pu8Data, int len ); +static eeprom_Cfg_t *eeprom_cached_config(void); /**************************************************************************** @@ -649,29 +650,20 @@ eeprom_Error_t eeprom_WriteRfClockCal( const eeprom_RfClockCal_t *pRfClockCal ) eeprom_Error_t eeprom_ReadTxCal( int iBand, eeprom_TxCal_t *pTxCal ) { int i; - int err; int size; int nArfcn; - eeprom_Cfg_t ee; + eeprom_Cfg_t *ee = eeprom_cached_config(); eeprom_SID_t sId; eeprom_CfgTxCal_t *pCfgTxCal = NULL; // Get a copy of the EEPROM header - err = eeprom_read( EEPROM_CFG_START_ADDR, sizeof(ee.hdr), (char *)&ee.hdr ); - if ( err != sizeof(ee.hdr) ) + if (!ee) { - PERROR( "Error while reading the EEPROM content (%d)\n", err ); + PERROR( "Reading cached content failed.\n" ); return EEPROM_ERR_DEVICE; } - // Validate the header magic ID - if ( ee.hdr.u32MagicId != EEPROM_CFG_MAGIC_ID ) - { - PERROR( "Invalid EEPROM format\n" ); - return EEPROM_ERR_INVALID; - } - - switch ( ee.hdr.u16Version ) + switch ( ee->hdr.u16Version ) { case 1: { @@ -680,40 +672,32 @@ eeprom_Error_t eeprom_ReadTxCal( int iBand, eeprom_TxCal_t *pTxCal ) case 0: nArfcn = 124; sId = EEPROM_SID_GSM850_TXCAL; - pCfgTxCal = &ee.cfg.v1.gsm850TxCal; - size = sizeof(ee.cfg.v1.gsm850TxCal) + sizeof(ee.cfg.v1.__gsm850TxCalMem); + pCfgTxCal = &ee->cfg.v1.gsm850TxCal; + size = sizeof(ee->cfg.v1.gsm850TxCal) + sizeof(ee->cfg.v1.__gsm850TxCalMem); break; case 1: nArfcn = 194; sId = EEPROM_SID_GSM900_TXCAL; - pCfgTxCal = &ee.cfg.v1.gsm900TxCal; - size = sizeof(ee.cfg.v1.gsm900TxCal) + sizeof(ee.cfg.v1.__gsm900TxCalMem); + pCfgTxCal = &ee->cfg.v1.gsm900TxCal; + size = sizeof(ee->cfg.v1.gsm900TxCal) + sizeof(ee->cfg.v1.__gsm900TxCalMem); break; case 2: nArfcn = 374; sId = EEPROM_SID_DCS1800_TXCAL; - pCfgTxCal = &ee.cfg.v1.dcs1800TxCal; - size = sizeof(ee.cfg.v1.dcs1800TxCal) + sizeof(ee.cfg.v1.__dcs1800TxCalMem); + pCfgTxCal = &ee->cfg.v1.dcs1800TxCal; + size = sizeof(ee->cfg.v1.dcs1800TxCal) + sizeof(ee->cfg.v1.__dcs1800TxCalMem); break; case 3: nArfcn = 299; sId = EEPROM_SID_PCS1900_TXCAL; - pCfgTxCal = &ee.cfg.v1.pcs1900TxCal; - size = sizeof(ee.cfg.v1.pcs1900TxCal) + sizeof(ee.cfg.v1.__pcs1900TxCalMem); + pCfgTxCal = &ee->cfg.v1.pcs1900TxCal; + size = sizeof(ee->cfg.v1.pcs1900TxCal) + sizeof(ee->cfg.v1.__pcs1900TxCalMem); break; default: PERROR( "Invalid GSM band specified (%d)\n", iBand ); return EEPROM_ERR_INVALID; } - // Get a copy of the EEPROM section - err = eeprom_read( EEPROM_CFG_START_ADDR + ((uint32_t)pCfgTxCal - (uint32_t)&ee), size, (char *)pCfgTxCal ); - if ( err != size ) - { - PERROR( "Error while reading the EEPROM content (%d)\n", err ); - return EEPROM_ERR_DEVICE; - } - // Validate the ID if ( pCfgTxCal->u16SectionID != sId ) { @@ -920,29 +904,20 @@ eeprom_Error_t eeprom_WriteTxCal( int iBand, const eeprom_TxCal_t *pTxCal ) eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal ) { int i; - int err; int size; int nArfcn; - eeprom_Cfg_t ee; + eeprom_Cfg_t *ee = eeprom_cached_config(); eeprom_SID_t sId; eeprom_CfgRxCal_t *pCfgRxCal = NULL; - // Get a copy of the EEPROM header - err = eeprom_read( EEPROM_CFG_START_ADDR, sizeof(ee.hdr), (char *)&ee.hdr ); - if ( err != sizeof(ee.hdr) ) - { - PERROR( "Error while reading the EEPROM content (%d)\n", err ); - return EEPROM_ERR_DEVICE; - } - // Validate the header magic ID - if ( ee.hdr.u32MagicId != EEPROM_CFG_MAGIC_ID ) + if (!ee) { - PERROR( "Invalid EEPROM format\n" ); - return EEPROM_ERR_INVALID; + PERROR( "Reading cached content failed.\n" ); + return EEPROM_ERR_DEVICE; } - switch ( ee.hdr.u16Version ) + switch ( ee->hdr.u16Version ) { case 1: { @@ -953,14 +928,14 @@ eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal if ( iUplink ) { sId = EEPROM_SID_GSM850_RXUCAL; - pCfgRxCal = &ee.cfg.v1.gsm850RxuCal; - size = sizeof(ee.cfg.v1.gsm850RxuCal) + sizeof(ee.cfg.v1.__gsm850RxuCalMem); + pCfgRxCal = &ee->cfg.v1.gsm850RxuCal; + size = sizeof(ee->cfg.v1.gsm850RxuCal) + sizeof(ee->cfg.v1.__gsm850RxuCalMem); } else { sId = EEPROM_SID_GSM850_RXDCAL; - pCfgRxCal = &ee.cfg.v1.gsm850RxdCal; - size = sizeof(ee.cfg.v1.gsm850RxdCal) + sizeof(ee.cfg.v1.__gsm850RxdCalMem); + pCfgRxCal = &ee->cfg.v1.gsm850RxdCal; + size = sizeof(ee->cfg.v1.gsm850RxdCal) + sizeof(ee->cfg.v1.__gsm850RxdCalMem); } break; case 1: @@ -968,14 +943,14 @@ eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal if ( iUplink ) { sId = EEPROM_SID_GSM900_RXUCAL; - pCfgRxCal = &ee.cfg.v1.gsm900RxuCal; - size = sizeof(ee.cfg.v1.gsm900RxuCal) + sizeof(ee.cfg.v1.__gsm900RxuCalMem); + pCfgRxCal = &ee->cfg.v1.gsm900RxuCal; + size = sizeof(ee->cfg.v1.gsm900RxuCal) + sizeof(ee->cfg.v1.__gsm900RxuCalMem); } else { sId = EEPROM_SID_GSM900_RXDCAL; - pCfgRxCal = &ee.cfg.v1.gsm900RxdCal; - size = sizeof(ee.cfg.v1.gsm900RxdCal) + sizeof(ee.cfg.v1.__gsm900RxdCalMem); + pCfgRxCal = &ee->cfg.v1.gsm900RxdCal; + size = sizeof(ee->cfg.v1.gsm900RxdCal) + sizeof(ee->cfg.v1.__gsm900RxdCalMem); } break; case 2: @@ -983,14 +958,14 @@ eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal if ( iUplink ) { sId = EEPROM_SID_DCS1800_RXUCAL; - pCfgRxCal = &ee.cfg.v1.dcs1800RxuCal; - size = sizeof(ee.cfg.v1.dcs1800RxuCal) + sizeof(ee.cfg.v1.__dcs1800RxuCalMem); + pCfgRxCal = &ee->cfg.v1.dcs1800RxuCal; + size = sizeof(ee->cfg.v1.dcs1800RxuCal) + sizeof(ee->cfg.v1.__dcs1800RxuCalMem); } else { sId = EEPROM_SID_DCS1800_RXDCAL; - pCfgRxCal = &ee.cfg.v1.dcs1800RxdCal; - size = sizeof(ee.cfg.v1.dcs1800RxdCal) + sizeof(ee.cfg.v1.__dcs1800RxdCalMem); + pCfgRxCal = &ee->cfg.v1.dcs1800RxdCal; + size = sizeof(ee->cfg.v1.dcs1800RxdCal) + sizeof(ee->cfg.v1.__dcs1800RxdCalMem); } break; case 3: @@ -998,14 +973,14 @@ eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal if ( iUplink ) { sId = EEPROM_SID_PCS1900_RXUCAL; - pCfgRxCal = &ee.cfg.v1.pcs1900RxuCal; - size = sizeof(ee.cfg.v1.pcs1900RxuCal) + sizeof(ee.cfg.v1.__pcs1900RxuCalMem); + pCfgRxCal = &ee->cfg.v1.pcs1900RxuCal; + size = sizeof(ee->cfg.v1.pcs1900RxuCal) + sizeof(ee->cfg.v1.__pcs1900RxuCalMem); } else { sId = EEPROM_SID_PCS1900_RXDCAL; - pCfgRxCal = &ee.cfg.v1.pcs1900RxdCal; - size = sizeof(ee.cfg.v1.pcs1900RxdCal) + sizeof(ee.cfg.v1.__pcs1900RxdCalMem); + pCfgRxCal = &ee->cfg.v1.pcs1900RxdCal; + size = sizeof(ee->cfg.v1.pcs1900RxdCal) + sizeof(ee->cfg.v1.__pcs1900RxdCalMem); } break; default: @@ -1013,14 +988,6 @@ eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal return EEPROM_ERR_INVALID; } - // Get a copy of the EEPROM section - err = eeprom_read( EEPROM_CFG_START_ADDR + ((uint32_t)pCfgRxCal - (uint32_t)&ee), size, (char *)pCfgRxCal ); - if ( err != size ) - { - PERROR( "Error while reading the EEPROM content (%d)\n", err ); - return EEPROM_ERR_DEVICE; - } - // Validate the ID if ( pCfgRxCal->u16SectionID != sId ) { @@ -1322,12 +1289,17 @@ int eeprom_dump( int addr, int size, int hex ) } static FILE *g_file; +static eeprom_Cfg_t *g_cached_cfg; void eeprom_free_resources(void) { if (g_file) fclose(g_file); g_file = NULL; + + /* release the header */ + free(g_cached_cfg); + g_cached_cfg = NULL; } /** @@ -1352,6 +1324,42 @@ static int eeprom_read( int addr, int size, char *pBuff ) return n; } +static void eeprom_cache_cfg(void) +{ + int err; + + free(g_cached_cfg); + g_cached_cfg = malloc(sizeof(*g_cached_cfg)); + + if (!g_cached_cfg) + return; + + err = eeprom_read( EEPROM_CFG_START_ADDR, sizeof(*g_cached_cfg), (char *) g_cached_cfg ); + if ( err != sizeof(*g_cached_cfg) ) + { + PERROR( "Error while reading the EEPROM content (%d)\n", err ); + goto error; + } + + if ( g_cached_cfg->hdr.u32MagicId != EEPROM_CFG_MAGIC_ID ) + { + PERROR( "Invalid EEPROM format\n" ); + goto error; + } + + return; + +error: + free(g_cached_cfg); + g_cached_cfg = NULL; +} + +static eeprom_Cfg_t *eeprom_cached_config(void) +{ + if (!g_cached_cfg) + eeprom_cache_cfg(); + return g_cached_cfg; +} /** * Write up to 'size' bytes of data to the EEPROM starting at offset 'addr'. -- cgit v1.2.3