flashDrvLib.c
上传用户:dqzhongke1
上传日期:2022-06-26
资源大小:667k
文件大小:15k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.  * $Id: flashDrvLib.c,v 1.4.2.1 Broadcom SDK $
  3.  * $Copyright: Copyright 2008 Broadcom Corporation.
  4.  * This program is the proprietary software of Broadcom Corporation
  5.  * and/or its licensors, and may only be used, duplicated, modified
  6.  * or distributed pursuant to the terms and conditions of a separate,
  7.  * written license agreement executed between you and Broadcom
  8.  * (an "Authorized License").  Except as set forth in an Authorized
  9.  * License, Broadcom grants no license (express or implied), right
  10.  * to use, or waiver of any kind with respect to the Software, and
  11.  * Broadcom expressly reserves all rights in and to the Software
  12.  * and all intellectual property rights therein.  IF YOU HAVE
  13.  * NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
  14.  * IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
  15.  * ALL USE OF THE SOFTWARE.  
  16.  *  
  17.  * Except as expressly set forth in the Authorized License,
  18.  *  
  19.  * 1.     This program, including its structure, sequence and organization,
  20.  * constitutes the valuable trade secrets of Broadcom, and you shall use
  21.  * all reasonable efforts to protect the confidentiality thereof,
  22.  * and to use this information only in connection with your use of
  23.  * Broadcom integrated circuit products.
  24.  *  
  25.  * 2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
  26.  * PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
  27.  * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
  28.  * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE.  BROADCOM SPECIFICALLY
  29.  * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
  30.  * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
  31.  * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
  32.  * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
  33.  * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
  34.  * 
  35.  * 3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
  36.  * BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
  37.  * INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
  38.  * ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
  39.  * TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
  40.  * POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
  41.  * THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1,
  42.  * WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
  43.  * ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
  44.  *
  45.  * File:    flashDrvLib.c
  46.  */
  47. #include "vxWorks.h"
  48. #include "taskLib.h"
  49. #include "stdlib.h"
  50. #include "stdio.h"
  51. #include "string.h"
  52. #include "ctype.h"
  53. #include "config.h"
  54. #include "flashDrvLib.h"
  55. #define TOTAL_LOADED_SECS  8
  56. int             flashVerbose = 0; /* DEBUG */
  57. unsigned int    flashBaseAddress = 0xf8000000;
  58. int             flashSize = 0x8000000;
  59. int             flashDevSectorSize = 0x20000;
  60. int             flashSectorCount = 0;
  61. #define         FLUSH_HISTORY_BUF_LEN   16
  62. static int      flashSectorFlushHistory[FLUSH_HISTORY_BUF_LEN];
  63. LOCAL struct flash_drv_funcs_s *flashDrvFuncs = &flash29GL1G;
  64. LOCAL struct flashLoadedSectorInfo {
  65.     SEM_ID fsSemID;
  66.     int   sector;
  67.     int   dirty;
  68.     char *buffer;
  69. } flashLoadedSectors[TOTAL_LOADED_SECS];
  70. #define FS_CACHE_LOCK(_x_) 
  71.     semTake(flashLoadedSectors[(_x_)].fsSemID, WAIT_FOREVER)
  72. #define FS_CACHE_UNLOCK(_x_) 
  73.     semGive(flashLoadedSectors[(_x_)].fsSemID)
  74. LOCAL int
  75. flashFlushLoadedSector(int number, int reason)
  76. {
  77.     if (flashLoadedSectors[number].sector < 0 ||
  78.         !flashLoadedSectors[number].dirty) {
  79.         if (flashVerbose)
  80.             printf("flashFlushLoadedSector(%d): not dirtyn", number);
  81.         return (OK);
  82.     }
  83.     if (flashVerbose) {
  84.         printf("flashFlushLoadedSector(%d): Flushing sector %d %sn", number,
  85.                 flashLoadedSectors[number].sector,
  86.                 (reason == 0 ? "<- flashSync" : "<- flashBlkWrite"));
  87.     }
  88.     if (flashDrvFuncs->flashEraseSector(flashLoadedSectors[number].sector)==ERROR) {
  89.         return (ERROR);
  90.     }
  91.     if (flashDrvFuncs->flashWrite(flashLoadedSectors[number].sector,
  92.             flashLoadedSectors[number].buffer, 0, FLASH_SECTOR_SIZE) == ERROR) {
  93.         return (ERROR);
  94.     }
  95.     if (flashVerbose) {
  96.         printf("                           Flushing %d donen",
  97.                 flashLoadedSectors[number].sector);
  98.     }
  99.     flashLoadedSectors[number].sector = -1;
  100.     flashLoadedSectors[number].dirty = 0;
  101.     return (OK);
  102. }
  103. LOCAL int
  104. getSectorFetchHistory(int sectorNum)
  105. {
  106.     int idx = 0, cnt = 0;
  107.     while(idx < FLUSH_HISTORY_BUF_LEN) {
  108.         cnt += (flashSectorFlushHistory[idx] == sectorNum) ? 1 : 0;
  109.         idx ++;
  110.     }
  111.     return cnt;
  112. }
  113. LOCAL int
  114. allocEmptyLoadedSector(int sectorNum)
  115. {
  116.     int number = 0, ii, min_read = FLUSH_HISTORY_BUF_LEN, tmp;
  117.     static  int ring_index = 0;
  118.     for (ii = 0; ii < TOTAL_LOADED_SECS; ii++) {
  119.         if (flashLoadedSectors[ii].sector < 0) {
  120.             flashLoadedSectors[ii].sector = sectorNum;
  121.             flashLoadedSectors[ii].dirty = 0;
  122.             flashSectorFlushHistory[ring_index] = sectorNum;
  123.             ring_index = (ring_index + 1) % FLUSH_HISTORY_BUF_LEN;
  124.             return ii;
  125.         }
  126.     }
  127.     for (ii = 0; ii < TOTAL_LOADED_SECS; ii++) {
  128.         if ((tmp = getSectorFetchHistory(flashLoadedSectors[ii].sector)) < 
  129.                                                                     min_read) {
  130.             number = ii;
  131.         }
  132.     }
  133.     if (flashVerbose)
  134.         printf("allocEmptyLoadedSector(%d): erasing %d, new sector %dn", 
  135.                number, flashLoadedSectors[number].sector, sectorNum);
  136.     FS_CACHE_LOCK(number);
  137.     if (flashFlushLoadedSector(number, 1) == ERROR) {
  138.         FS_CACHE_UNLOCK(number);
  139.         return (-1);
  140.     }
  141.     flashLoadedSectors[number].sector = sectorNum;
  142.     flashLoadedSectors[number].dirty = 0;
  143.     flashSectorFlushHistory[ring_index] = sectorNum;
  144.     ring_index = (ring_index + 1) % FLUSH_HISTORY_BUF_LEN;
  145.     FS_CACHE_UNLOCK(number);
  146.     return (number);
  147. }
  148. int
  149. flashDrvLibInit(void)
  150. {
  151.     FLASH_TYPES     dev;
  152.     FLASH_VENDORS   vendor;
  153.     int i;
  154.     flashDrvFuncs = &flash29GL1G;
  155.     flashDrvFuncs->flashAutoSelect(&dev, &vendor);
  156.     if ((vendor == 0xFF) && (dev == 0xFF)) {
  157.         printf("flashInit(): No flash Foundn");
  158.         return (ERROR);
  159.     }
  160.     switch (vendor) {
  161.         case AMD:
  162.         switch (dev & 0x0000ffff) {
  163.             case FLASH_29GL1G:
  164.                 flashSectorCount = 1024;
  165.                 flashDevSectorSize = 0x20000;
  166.                 if (flashVerbose)
  167.                     printf("flashInit(): 29GL1G Foundn");
  168.                 break;
  169.             default:
  170.                 printf("flashInit(): Unrecognized AMD Device (0x%02X)n", dev);
  171.                 return (ERROR);
  172.         }
  173.         break;
  174.         default:
  175.             printf("flashInit(): Unrecognized Vendor (0x%02X)n", vendor);
  176.             return (ERROR);
  177.     }
  178.     flashSize = flashDevSectorSize * flashSectorCount;
  179.     for (i = 0; i < TOTAL_LOADED_SECS; i++) {
  180.         flashLoadedSectors[i].buffer = malloc(FLASH_SECTOR_SIZE);
  181.         if (flashLoadedSectors[i].buffer == NULL) {
  182.             printf("flashInit(): malloc() failedn");
  183.             for (; i > 0; i--) {
  184.                 free(flashLoadedSectors[i-1].buffer);
  185.             }
  186.             return (ERROR);
  187.         }
  188.         flashLoadedSectors[i].sector = -1;
  189.         flashLoadedSectors[i].dirty = 0;
  190.         flashLoadedSectors[i].fsSemID =
  191.             semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE);
  192.     }
  193.     memset(flashSectorFlushHistory, 0, sizeof(int) * FLUSH_HISTORY_BUF_LEN);
  194.     return (OK);
  195. }
  196. int
  197. flashGetSectorSize(void)
  198. {
  199.     return (flashDevSectorSize);
  200. }
  201. int
  202. flashGetSectorCount(void)
  203. {
  204.     return (flashSectorCount);
  205. }
  206. int
  207. flashEraseBank(int firstSector, int nSectors)
  208. {
  209.     int             sectorNum, errCnt = 0;
  210.     if (firstSector < 0 || firstSector + nSectors > flashSectorCount) {
  211.         printf("flashEraseBank(): Illegal parms %d, %dn",
  212.            firstSector, nSectors);
  213.         return ERROR;
  214.     }
  215.     for (sectorNum = firstSector;
  216.          sectorNum < firstSector + nSectors; sectorNum++) {
  217.          printf(".");
  218.         if (flashDrvFuncs->flashEraseSector(sectorNum))
  219.             errCnt++;
  220.     }
  221.     printf("n");
  222.     if (errCnt)
  223.         return (ERROR);
  224.     else
  225.         return (OK);
  226. }
  227. int
  228. flashBlkRead(int sectorNum, char *buff,
  229.          unsigned int offset, unsigned int count)
  230. {
  231.     int i;
  232.     if (sectorNum < 0 || sectorNum >= flashSectorCount) {
  233.         printf("flashBlkRead(): Sector %d invalidn", sectorNum);
  234.         return (ERROR);
  235.     }
  236.     if (offset < 0 || offset >= FLASH_SECTOR_SIZE) {
  237.         printf("flashBlkRead(): Offset 0x%x invalidn", offset);
  238.         return (ERROR);
  239.     }
  240.     if (count < 0 || count > FLASH_SECTOR_SIZE - offset) {
  241.         printf("flashBlkRead(): Count 0x%x invalidn", count);
  242.         return (ERROR);
  243.     }
  244.     /*
  245.      * If the sector is loaded, read from it.  Else, read from the
  246.      * flash itself (slower).
  247.      */
  248.     for (i = 0; i < TOTAL_LOADED_SECS; i++) {
  249.         if (flashLoadedSectors[i].sector == sectorNum) {
  250.             if (flashVerbose)
  251.                 printf("flashBlkRead(): from loaded sector %dn", sectorNum);
  252.             bcopy(&flashLoadedSectors[i].buffer[offset], buff, count);
  253.             return (OK);
  254.         }
  255.     }
  256.     flashDrvFuncs->flashRead(sectorNum, buff, offset, count);
  257.     return (OK);
  258. }
  259. /*
  260.  * Check if we can program this part of the flash.  All
  261.  * the data has to be all "1" to be programmed.  Because
  262.  * the flash has to be init to all 1's and change from 1 to 0
  263.  */
  264. LOCAL int
  265. flashCheckCanProgram(int sectorNum, unsigned int offset, unsigned int count)
  266. {
  267.     unsigned char   *flashBuffPtr;
  268.     int             i;
  269.     flashBuffPtr = (unsigned char *)(FLASH_SECTOR_ADDRESS(sectorNum) + offset);
  270.     for (i = 0; i < count; i++) {
  271.         if (flashBuffPtr[i] != 0xff)
  272.             return (ERROR);
  273.     }
  274.     return (OK);
  275. }
  276. int
  277. flashBlkWrite(int sectorNum, char *buff,
  278.           unsigned int offset, unsigned int count)
  279. {
  280.     int i;
  281.     if (sectorNum < 0 || sectorNum >= flashSectorCount) {
  282.         printf("flashBlkWrite(): Sector %d invalidn", sectorNum);
  283.         return (ERROR);
  284.     }
  285.     if (offset < 0 || offset >= FLASH_SECTOR_SIZE) {
  286.         printf("flashBlkWrite(): Offset 0x%x invalidn", offset);
  287.         return (ERROR);
  288.     }
  289.     /* 
  290.      * Count must be within range and must be a long word multiple, as
  291.      * we always program long words.
  292.      */
  293.     if ((count < 0) || 
  294.         (count > ((flashSectorCount - sectorNum) * FLASH_SECTOR_SIZE - offset))) {
  295.         printf("flashBlkWrite(): Count 0x%x invalidn", count);
  296.         return (ERROR);
  297.     }
  298.     /*
  299.      * If the Sector is loaded, write it to buffer.  Else check to see
  300.      * if we can program the sector; if so, program it.  Else, flush the
  301.      * first loaded sector (if loaded and dirty), push loaded sectors
  302.      * up by one, load the new one and copy the data into the last one.
  303.      */
  304.     for (i = 0; i < TOTAL_LOADED_SECS; i++) {
  305.         FS_CACHE_LOCK(i);
  306.         if (flashLoadedSectors[i].sector == sectorNum) {
  307.             if (flashVerbose)
  308.                 printf("%d ", sectorNum);
  309.             bcopy(buff, &flashLoadedSectors[i].buffer[offset], count);
  310.             flashLoadedSectors[i].dirty = 1;
  311.             FS_CACHE_UNLOCK(i);
  312.             return (OK);
  313.         }
  314.         FS_CACHE_UNLOCK(i);
  315.     }
  316.     if (flashCheckCanProgram(sectorNum, offset, count) != ERROR) {
  317.         return (flashDrvFuncs->flashWrite(sectorNum, buff, offset, count));
  318.     }
  319.     /* Find empty sector */
  320.     if ((i = allocEmptyLoadedSector(sectorNum)) < 0) {
  321.         return (ERROR);
  322.     }
  323.     FS_CACHE_LOCK(i);
  324.     if (flashDrvFuncs->flashRead(sectorNum, flashLoadedSectors[i].buffer,
  325.                                  0, FLASH_SECTOR_SIZE) == ERROR) {
  326.         flashLoadedSectors[i].sector = -1;
  327.         FS_CACHE_UNLOCK(i);
  328.         return (ERROR);
  329.     }
  330.     bcopy(buff, &flashLoadedSectors[i].buffer[offset], count);
  331.     flashLoadedSectors[i].dirty = 1;
  332.     FS_CACHE_UNLOCK(i);
  333.     if (flashVerbose) {
  334.         printf("flashBlkWrite(): load %d sect %d (and write to cache only)n", 
  335.                i, sectorNum);
  336.     }
  337.     return (OK);
  338. }
  339. int
  340. flashDiagnostic(void)
  341. {
  342.     unsigned int   *flashSectorBuff;
  343.     int             sectorNum, i;
  344.     /*
  345.      * Probe flash; allocate flashLoadedSector Buffer
  346.      */
  347.     flashDrvLibInit();        /* Probe; clear loaded sector */
  348.     flashSectorBuff = (unsigned int *) flashLoadedSectors[0].buffer;
  349.     if (flashVerbose) {
  350.         printf("flashDiagnostic(): Executing. Erasing %d Sectorsn",
  351.                 flashSectorCount);
  352.     }
  353.     if (flashEraseBank(0, flashSectorCount) == ERROR) {
  354.         if (flashVerbose) {
  355.             printf("flashDiagnostic(): flashEraseBank() #1 failedn");
  356.         }
  357.         return (ERROR);
  358.     }
  359.     /* Write unique counting pattern to each sector. */
  360.     for (sectorNum = 0; sectorNum < flashSectorCount; sectorNum++) {
  361.         if (flashVerbose) {
  362.             printf("flashDiagnostic(): writing sector %dn", sectorNum);
  363.         }
  364.         for (i = 0; i < FLASH_SECTOR_SIZE / sizeof (unsigned int); i++) {
  365.             flashSectorBuff[i] = (i + sectorNum);
  366.         }
  367.         if (flashDrvFuncs->flashWrite(sectorNum, (char *)flashSectorBuff,
  368.                0, FLASH_SECTOR_SIZE) == ERROR) {
  369.             if (flashVerbose) {
  370.                 printf("flashDiagnostic(): flashWrite() failed on %dn",
  371.                    sectorNum);
  372.             }
  373.             return (ERROR);
  374.         }
  375.     }
  376.     /* Verify each sector. */
  377.     for (sectorNum = 0; sectorNum < flashSectorCount; sectorNum++) {
  378.         if (flashVerbose) {
  379.             printf("flashDiagnostic(): verifying sector %dn", sectorNum);
  380.         }
  381.         if (flashDrvFuncs->flashRead(sectorNum, (char *)flashSectorBuff,
  382.               0, FLASH_SECTOR_SIZE) == ERROR) {
  383.             if (flashVerbose) {
  384.                 printf("flashDiagnostic(): flashRead() failed on %dn",
  385.                 sectorNum);
  386.             }
  387.             return (ERROR);
  388.         }
  389.         for (i = 0; i < FLASH_SECTOR_SIZE / sizeof (unsigned int); i++) {
  390.             if (flashSectorBuff[i] != (i + sectorNum)) {
  391.                 if (flashVerbose) {
  392.                     printf("flashDiagnostic(): verification failedn");
  393.                     printf("flashDiagnostic(): sector %d, offset 0x%xn",
  394.                           sectorNum, (i * sizeof(unsigned int)));
  395.                     printf("flashDiagnostic(): expected 0x%x, got 0x%xn",
  396.                          (i + sectorNum), (int)flashSectorBuff[i]);
  397.                 }
  398.                 return (ERROR);
  399.            } 
  400.         }
  401.     }
  402.     if (flashEraseBank(0, flashSectorCount) == ERROR) {
  403.         if (flashVerbose) {
  404.             printf("flashDiagnostic(): flashEraseBank() #2 failedn");
  405.             return (ERROR);
  406.         }
  407.     }
  408.     if (flashVerbose) {
  409.         printf("flashDiagnostic(): Completed without errorn");
  410.     }
  411.     return (OK);
  412. }
  413. int
  414. flashSyncFilesystem(void)
  415. {
  416.     int i;
  417.     for (i = 0; i < TOTAL_LOADED_SECS; i++) {
  418.         FS_CACHE_LOCK(i);
  419.         if (flashFlushLoadedSector(i, 0) != OK) {
  420.             FS_CACHE_UNLOCK(i);
  421.             return (ERROR);
  422.         }
  423.         FS_CACHE_UNLOCK(i);
  424.     }
  425.     return (OK);
  426. }