Changeset 1010

Show
Ignore:
Timestamp:
04/23/08 07:14:45 (13 years ago)
Author:
ppalmers
Message:

first set of ECHO firmware manipulation code

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/fireworks/efc/efc_cmds_flash.cpp

    r864 r1010  
    113113    for (unsigned int i=0; i < m_nb_quadlets; i++) { 
    114114        // FIXME: do we have to swap? 
    115         //EFC_DESERIALIZE_AND_SWAP(de, &m_data[i], result); 
     115        EFC_DESERIALIZE_AND_SWAP(de, &m_data[i], result); 
    116116        // or not? 
    117         result &= de.read(&m_data[i]); 
     117        //result &= de.read(&m_data[i]); 
    118118    } 
    119119    return result; 
  • trunk/libffado/src/fireworks/fireworks_device.cpp

    r969 r1010  
    2727#include "efc/efc_cmds_hardware.h" 
    2828#include "efc/efc_cmds_hardware_ctrl.h" 
     29#include "efc/efc_cmds_flash.h" 
    2930 
    3031#include "audiofire/audiofire_device.h" 
     
    499500} 
    500501 
     502bool 
     503Device::readFlash(uint32_t start, uint32_t len, uint32_t* buffer) { 
     504 
     505    if(len <= 0 || 0xFFFFFFFF - len*4 < start) { 
     506        debugError("bogus start/len: 0x%08X / %u\n", start, len); 
     507        return false; 
     508    } 
     509    if(start & 0x03) { 
     510        debugError("start address not quadlet aligned: 0x%08X\n", start); 
     511        return false; 
     512    } 
     513 
     514    uint32_t start_addr = start; 
     515    uint32_t stop_addr = start + len*4; 
     516    uint32_t *target_buffer = buffer; 
     517 
     518    EfcFlashReadCmd cmd; 
     519    // read EFC_FLASH_SIZE_BYTES at a time 
     520    for(start_addr = start; start_addr < stop_addr; start_addr += EFC_FLASH_SIZE_BYTES) { 
     521        cmd.m_address = start_addr; 
     522        unsigned int quads_to_read = (stop_addr - start_addr)/4; 
     523        if (quads_to_read > EFC_FLASH_SIZE_QUADS) { 
     524            quads_to_read = EFC_FLASH_SIZE_QUADS; 
     525        } 
     526        cmd.m_nb_quadlets = quads_to_read; 
     527        if(!doEfcOverAVC(cmd)) { 
     528            debugError("Flash read failed for block 0x%08X (%d quadlets)\n", start_addr, quads_to_read); 
     529            return false; 
     530        } 
     531        if(cmd.m_nb_quadlets != quads_to_read) { 
     532            debugError("Flash read didn't return enough data (%u/%u) \n", cmd.m_nb_quadlets, quads_to_read); 
     533            return false; 
     534        } 
     535        if(cmd.m_data == NULL) { 
     536            debugError("No data block in EFC cmd\n"); 
     537            return false; 
     538        } 
     539        for(unsigned int i=0; i<quads_to_read; i++) { 
     540            *target_buffer = cmd.m_data[i]; 
     541            target_buffer++; 
     542        } 
     543    } 
     544    return true; 
     545} 
     546 
    501547} // FireWorks 
  • trunk/libffado/src/fireworks/fireworks_device.h

    r864 r1010  
    6060    const EfcHardwareInfoCmd getHwInfo() 
    6161        {return m_HwInfo;}; 
     62 
     63// protected: //? 
     64    bool doEfcOverAVC(EfcCmd& c); 
    6265     
    63     bool doEfcOverAVC(EfcCmd& c); 
     66    /** 
     67     * @brief Read flash 
     68     * @param start start address 
     69     * @param len length in quadlets (4 bytes) 
     70     * @param buffer target buffer (should be 'len*4' bytes long) 
     71     * @return true if successful 
     72     */ 
     73    bool readFlash(uint32_t start, uint32_t len, uint32_t* buffer); 
    6474 
    6575// Echo specific stuff 
  • trunk/libffado/src/fireworks/fireworks_firmware.cpp

    r937 r1010  
    3333#include <fstream> 
    3434 
     35#define ECHO_FLASH_TIMEOUT_MILLISECS 2000 
     36 
    3537using namespace std; 
    3638 
     
    8486 
    8587Firmware::Firmware() 
    86 : m_Type ( eDT_Invalid ) 
     88: m_source( "none" ) 
     89, m_Type ( eDT_Invalid ) 
    8790, m_flash_offset_address ( 0 ) 
    8891, m_length_quads ( 0 ) 
     
    9396, m_footprint_quads ( 0 ) 
    9497, m_data( NULL ) 
    95 
     98, m_valid( false ) 
     99
     100
     101 
     102Firmware::Firmware(const Firmware& f) { 
     103    debugOutput(DEBUG_LEVEL_VERBOSE, "copy constructor\n"); 
     104    m_source = f.m_source; 
     105    m_Type = f.m_Type; 
     106    m_flash_offset_address = f.m_flash_offset_address; 
     107    m_length_quads = f.m_length_quads; 
     108    m_CRC32 = f.m_CRC32; 
     109    m_checksum = f.m_checksum; 
     110    m_version = f.m_version; 
     111    m_append_crc = f.m_append_crc; 
     112    m_footprint_quads = f.m_footprint_quads; 
     113    m_valid = f.m_valid; 
     114    m_data = new uint32_t[m_length_quads]; 
     115 
     116    memcpy(m_data, f.m_data, m_length_quads*sizeof(uint32_t)); 
     117
     118 
     119Firmware& Firmware::operator=(const Firmware& f) { 
     120    debugOutput(DEBUG_LEVEL_VERBOSE, "assignment\n"); 
     121    if (this != &f) {  // make sure not same object 
     122        // assign new vars 
     123        m_source = f.m_source; 
     124        m_Type = f.m_Type; 
     125        m_flash_offset_address = f.m_flash_offset_address; 
     126        m_length_quads = f.m_length_quads; 
     127        m_CRC32 = f.m_CRC32; 
     128        m_checksum = f.m_checksum; 
     129        m_version = f.m_version; 
     130        m_append_crc = f.m_append_crc; 
     131        m_footprint_quads = f.m_footprint_quads; 
     132        m_valid = f.m_valid; 
     133 
     134        // replace dynamic data 
     135        delete [] m_data; 
     136        m_data = new uint32_t[m_length_quads]; 
     137        memcpy(m_data, f.m_data, m_length_quads*sizeof(uint32_t)); 
     138    } 
     139    return *this;    // Return ref for multiple assignment 
    96140} 
    97141 
     
    105149{ 
    106150    #ifdef DEBUG 
    107     debugOutput(DEBUG_LEVEL_NORMAL, "Firmware from %s\n", m_filename.c_str()); 
     151    debugOutput(DEBUG_LEVEL_NORMAL, "Firmware from %s\n", m_source.c_str()); 
     152    debugOutput(DEBUG_LEVEL_NORMAL, " Valid?               : %s\n", (m_valid?"Yes":"No")); 
    108153    debugOutput(DEBUG_LEVEL_NORMAL, " Type                 : %s\n", eDatTypeToString(m_Type)); 
    109154    if (m_Type == eDT_Invalid) return; 
     
    113158    unsigned int version_build = (m_version & 0x0000FFFF); 
    114159    debugOutput(DEBUG_LEVEL_NORMAL, " Address Offset       : 0x%08lX\n", m_flash_offset_address); 
    115     debugOutput(DEBUG_LEVEL_NORMAL, " Lenght (Quadlets)    : 0x%08lX\n", m_length_quads); 
     160    debugOutput(DEBUG_LEVEL_NORMAL, " Length (Quadlets)    : 0x%08lX\n", m_length_quads); 
    116161    debugOutput(DEBUG_LEVEL_NORMAL, " CRC 32               : 0x%08lX\n", m_CRC32); 
    117162    debugOutput(DEBUG_LEVEL_NORMAL, " Checksum             : 0x%08lX\n", m_checksum); 
     
    121166    debugOutput(DEBUG_LEVEL_NORMAL, " Footprint (Quadlets) : 0x%08lX\n", m_footprint_quads); 
    122167    #endif 
     168} 
     169 
     170bool 
     171Firmware::operator==(const Firmware& f) 
     172{ 
     173    debugOutput(DEBUG_LEVEL_VERBOSE, "Comparing header...\n"); 
     174    if(m_flash_offset_address != f.m_flash_offset_address) { 
     175        debugOutput(DEBUG_LEVEL_VERBOSE, 
     176                    "Flash address differs: %08X != %08X\n", 
     177                    m_flash_offset_address, f.m_flash_offset_address); 
     178        return false; 
     179    } 
     180    if(m_length_quads != f.m_length_quads) { 
     181        debugOutput(DEBUG_LEVEL_VERBOSE, 
     182                    "Flash length differs: %08X != %08X\n", 
     183                    m_length_quads, f.m_length_quads); 
     184        return false; 
     185    } 
     186    if(m_data == NULL && f.m_data == NULL) { 
     187        debugOutput(DEBUG_LEVEL_VERBOSE, 
     188                    "both firmwares have no data\n"); 
     189        return true; 
     190    } 
     191    if(m_data == NULL || f.m_data == NULL) { 
     192        debugOutput(DEBUG_LEVEL_VERBOSE, 
     193                    "one of the firmwares has no data: %p != %p\n", 
     194                    m_data, f.m_data); 
     195        return false; 
     196    } 
     197     
     198    debugOutput(DEBUG_LEVEL_VERBOSE, "Comparing data...\n"); 
     199    bool retval = true; 
     200    for(unsigned int i=0; i<m_length_quads; i++) { 
     201        if(m_data[i] != f.m_data[i]) { 
     202            debugOutput(DEBUG_LEVEL_VERBOSE, 
     203                        " POS 0x%08X: %08X != %08X\n", 
     204                        i, m_data[i], f.m_data[i]); 
     205            retval = false; 
     206        } 
     207    } 
     208    return retval; 
    123209} 
    124210 
     
    212298 
    213299    debugOutput(DEBUG_LEVEL_VERBOSE, " Reading data...\n"); 
    214     delete m_data; 
     300    delete[] m_data; 
    215301    m_data = new uint32_t[m_length_quads]; 
     302    if(m_data == NULL) { 
     303        debugError("could not allocate memory for firmware\n"); 
     304        return false; 
     305    } 
    216306    for (uint32_t i=0; i < m_length_quads; i++) { 
    217307        std::string buffer; 
     
    238328    fwfile.close(); 
    239329 
    240     m_filename =  filename; 
    241     return false; 
     330    m_source = filename; 
     331    m_valid = true; 
     332    return true; 
     333
     334 
     335bool 
     336Firmware::loadFromMemory(uint32_t *data, uint32_t addr, uint32_t len) { 
     337    m_valid = false; 
     338 
     339    // mark it as invalid for now 
     340    m_Type                  = eDT_Invalid; 
     341 
     342    // set some values (FIXME) 
     343    m_flash_offset_address  = addr; 
     344    m_length_quads          = len; 
     345    m_CRC32                 = 0; 
     346    m_checksum              = 0; 
     347    m_version               = 0; 
     348    m_append_crc            = false; 
     349    m_footprint_quads       = 0; 
     350 
     351    // delete any old data 
     352    delete[] m_data; 
     353    m_data = new uint32_t[len]; 
     354    if(m_data == NULL) { 
     355        debugError("could not allocate memory for firmware\n"); 
     356        return false; 
     357    } 
     358    // copy data 
     359    memcpy(m_data, data, len*sizeof(uint32_t)); 
     360 
     361    return true; 
     362
     363 
     364void 
     365Firmware::dumpData() 
     366
     367    debugWarning("-- char dump --"); 
     368    hexDump((unsigned char*)m_data, m_length_quads*4); 
     369     
     370    debugWarning("-- quadlet dump --"); 
     371    hexDumpQuadlets(m_data, m_length_quads); 
     372 
    242373} 
    243374 
     
    252383} 
    253384 
     385Firmware 
     386FirmwareUtil::getFirmwareFromDevice(uint32_t start, uint32_t len) 
     387{ 
     388    if(len == 0) { 
     389        debugError("Invalid length: %u\n", len); 
     390        return Firmware(); 
     391    } 
     392 
     393    uint32_t data[len]; 
     394    Firmware f = Firmware(); 
     395 
     396    if(!m_Parent.readFlash(start, len, data)) { 
     397        debugError("Flash read failed\n"); 
     398        return f; 
     399    } 
     400 
     401    if(!f.loadFromMemory(data, start, len)) { 
     402        debugError("Could not load firmware from memory dump\n"); 
     403    } 
     404 
     405    return f; 
     406} 
     407 
     408bool 
     409FirmwareUtil::waitForFlash() 
     410{ 
     411    bool ready; 
     412 
     413    EfcFlashGetStatusCmd statusCmd; 
     414    const unsigned int time_to_sleep_usecs = 10000; 
     415    int wait_cycles = ECHO_FLASH_TIMEOUT_MILLISECS * 1000 / time_to_sleep_usecs; 
     416 
     417    do { 
     418        if (!m_Parent.doEfcOverAVC(statusCmd)) { 
     419            debugError("Could not read flash status\n"); 
     420            return false; 
     421        } 
     422        if (statusCmd.m_header.retval == EfcCmd::eERV_FlashBusy) { 
     423            ready = false; 
     424        } else { 
     425            ready = statusCmd.m_ready; 
     426        } 
     427        usleep(time_to_sleep_usecs); 
     428    } while (!ready && wait_cycles--); 
     429 
     430    if(wait_cycles == 0) { 
     431        debugError("Timeout while waiting for flash\n"); 
     432        return false; 
     433    } 
     434 
     435    return ready; 
     436} 
     437 
     438bool 
     439FirmwareUtil::eraseBlocks(uint32_t start_address, unsigned int nb_quads) 
     440{ 
     441    EfcFlashEraseCmd eraseCmd; 
     442    uint32_t blocksize_bytes; 
     443    uint32_t blocksize_quads; 
     444    unsigned int quads_left = nb_quads; 
     445    bool success = true; 
     446 
     447    const unsigned int max_nb_tries = 10; 
     448    unsigned int nb_tries = 0; 
     449 
     450    do { 
     451        // the erase block size is fixed by the HW, and depends 
     452        // on the flash section we're in 
     453        if (start_address < MAINBLOCKS_BASE_OFFSET_BYTES) 
     454                blocksize_bytes = PROGRAMBLOCK_SIZE_BYTES; 
     455        else 
     456                blocksize_bytes = MAINBLOCK_SIZE_BYTES; 
     457        start_address &= ~(blocksize_bytes - 1); 
     458        blocksize_quads = blocksize_bytes / 4; 
     459 
     460        // corner case: requested to erase less than one block 
     461        if (blocksize_quads > quads_left) { 
     462            blocksize_quads = quads_left; 
     463        } 
     464 
     465        // do the actual erase 
     466        eraseCmd.m_address = start_address; 
     467        if (!m_Parent.doEfcOverAVC(eraseCmd)) { 
     468            debugWarning("Could not erase flash block at 0x%08X\n", start_address); 
     469            success = false; 
     470        } else { 
     471            // verify that the block is empty as an extra precaution 
     472            EfcFlashReadCmd readCmd; 
     473            readCmd.m_address = start_address; 
     474            readCmd.m_nb_quadlets = blocksize_quads; 
     475            uint32_t verify_quadlets_read = 0; 
     476            do { 
     477                if (!m_Parent.doEfcOverAVC(readCmd)) { 
     478                    debugError("Could not read flash block at 0x%08X\n", start_address); 
     479                    return false; 
     480                } 
     481 
     482                // everything should be 0xFFFFFFFF if the erase was successful 
     483                for (unsigned int i = 0; i < readCmd.m_nb_quadlets; i++) { 
     484                    if (0xFFFFFFFF != readCmd.m_data[i]) { 
     485                        debugWarning("Flash erase verification failed.\n"); 
     486                        success = false; 
     487                        break; 
     488                    } 
     489                } 
     490  
     491                // maybe not everything was read at once 
     492                verify_quadlets_read += readCmd.m_nb_quadlets; 
     493                readCmd.m_address += start_address + verify_quadlets_read * 4; 
     494                readCmd.m_nb_quadlets = blocksize_quads - verify_quadlets_read; 
     495            } while(verify_quadlets_read < blocksize_quads); 
     496        } 
     497 
     498        if (success) { 
     499            start_address += blocksize_bytes; 
     500            quads_left -= blocksize_quads; 
     501            nb_tries = 0; 
     502        } else { 
     503            nb_tries++; 
     504        } 
     505        if (nb_tries > max_nb_tries) { 
     506            debugError("Needed too many tries to erase flash at 0x%08X", start_address); 
     507            return false; 
     508        } 
     509    } while (quads_left > 0); 
     510     
     511    return true; 
     512} 
     513 
     514 
    254515void 
    255516FirmwareUtil::show() 
  • trunk/libffado/src/fireworks/fireworks_firmware.h

    r864 r1010  
    3030#include "efc/efc_cmds_hardware.h" 
    3131#include "efc/efc_cmds_flash.h" 
     32 
     33#include "IntelFlashMap.h" 
    3234 
    3335#include <string> 
     
    6567public: 
    6668    Firmware(); 
     69    Firmware(const Firmware& f); 
    6770    virtual ~Firmware(); 
     71    Firmware& operator=(const Firmware& f); 
    6872 
    6973    virtual bool loadFile(std::string filename); 
     74    virtual bool loadFromMemory(uint32_t *data, uint32_t addr, uint32_t len); 
     75 
     76    virtual bool isValid() {return m_valid;}; 
     77 
     78    /** 
     79     * @brief compare two firmwares 
     80     * compares only the address, length and data content, not the other fields 
     81     * @param x firmware to be compared to 'this' 
     82     * @return true if equal 
     83     */ 
     84    bool operator==(const Firmware& x); 
     85 
     86    /** 
     87     * @brief get base address of the firmware image 
     88     * @return base address of the firmware image 
     89     */ 
     90    virtual uint32_t getAddress() {return m_flash_offset_address;}; 
     91    /** 
     92     * @brief get length of the firmware image (in quadlets) 
     93     * @return length of the firmware image (in quadlets) 
     94     */ 
     95    virtual uint32_t getLength() {return m_length_quads;}; 
    7096 
    7197    virtual void show(); 
    7298    virtual void setVerboseLevel(int l) 
    7399        {setDebugLevel(l);}; 
     100    void dumpData(); 
    74101 
    75102protected: 
    76103    // filename 
    77     std::string         m_filename; 
     104    std::string         m_source; 
    78105 
    79106    // header data 
     
    91118    uint32_t            *m_data; 
    92119 
     120    bool m_valid; 
     121 
    93122private: 
    94123    DECLARE_DEBUG_MODULE; 
     
    105134    virtual void setVerboseLevel(int l) 
    106135        {setDebugLevel(l);}; 
     136     
     137    /** 
     138     * @brief reads firmware block from device 
     139     * @param start start address 
     140     * @param length number of quadlets to read 
     141     * @return Firmware structure containing the read data 
     142     */ 
     143    Firmware getFirmwareFromDevice(uint32_t start, uint32_t length); 
     144 
     145    /** 
     146     * @brief wait until the device indicates the flash memory is ready 
     147     * @return true if the flash is ready, false if not (or timeout) 
     148     */ 
     149    bool waitForFlash(); 
     150 
     151    /** 
     152     * @brief erases the flash memory starting at addr 
     153     * @param address  
     154     * @param nb_quads  
     155     * @return true if successful, false otherwise 
     156     */ 
     157    bool eraseBlocks(unsigned int address, unsigned int nb_quads); 
    107158 
    108159protected: 
  • trunk/libffado/support/firmware/fireworks-downloader.cpp

    r962 r1010  
    5050const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>"; 
    5151const char *doc = "fireworks-downloader -- firmware downloader application for ECHO Fireworks devices\n\n" 
    52                     "OPERATION: display\n" 
    53                     "           firmware FILE\n"; 
     52                    "OPERATIONS:\n"  
     53                    "           list\n" 
     54                    "              Lists devices on the bus\n" 
     55                    "           display\n" 
     56                    "              Display information about a device and it's firmware\n" 
     57                    "           info FILE\n" 
     58                    "              Display information about the firmware contained in FILE\n" 
     59                    "           upload FILE\n" 
     60                    "              Upload the firmware contained in FILE to the device\n" 
     61                    "           download FILE START_ADDR LEN\n" 
     62                    "              Download the flash contents from the device to FILE\n" 
     63                    "              Starts at address START_ADDR and reads LEN quadlets\n" 
     64                    "           verify FILE\n" 
     65                    "              Verify that the firmware contained in the device corresponds\n" 
     66                    "              to the one contained in FILE\n" 
     67                    ; 
    5468 
    5569static struct argp_option _options[] = { 
    56     {"verbose",   'v', "level",     0,  "Produce verbose output" }, 
    57     {"port",      'p', "PORT",      0,  "Set port" }, 
     70    {"verbose",   'v', "LEVEL",     0,  "Produce verbose output (set level 0-10)" }, 
     71    {"guid",      'g', "GUID",      0,  "GUID of the target device" }, 
     72    {"port",      'p', "PORT",      0,  "Port to use" }, 
    5873    { 0 } 
    5974}; 
     
    6580    using namespace std; 
    6681 
     82    memset(args, 0, sizeof(args)); 
     83 
     84    args->guid = 0xFFFFFFFFFFFFFFFFLL; 
    6785    argp_parse (argp, argc, argv, 0, 0, args); 
    6886 
     87    setDebugLevel(args->verbose); 
     88 
    6989    errno = 0; 
    70     char* tail; 
    7190    int node_id = -1; 
    7291 
    73     fb_octlet_t guid = strtoll(args->args[0], &tail, 0); 
    74     if (errno) { 
    75         debugError("argument parsing failed: %s\n", 
    76                     strerror(errno)); 
    77         return -1; 
     92    fb_octlet_t guid = args->guid; 
     93 
     94    if(args->nargs < 1) { 
     95        argp_help(argp, stderr, ARGP_HELP_USAGE | ARGP_HELP_LONG | ARGP_HELP_DOC, argv[0]); 
     96        exit(-1); 
     97    } 
     98 
     99    // first do the operations for which we don't need a device 
     100    if ( strcmp( args->args[0], "info" ) == 0 ) { 
     101        if (!args->args[1] ) { 
     102            printMessage("FILE argument is missing\n"); 
     103            return -1; 
     104        } 
     105        std::string str( args->args[1] ); 
     106 
     107        // load the file 
     108        Firmware f = Firmware(); 
     109        f.setVerboseLevel( args->verbose ); 
     110         
     111        if (!f.loadFile(str)) { 
     112            printMessage("Could not load firmware\n"); 
     113            return -1; 
     114        } 
     115        f.show(); 
     116        return 0; 
     117    } else if ( strcmp( args->args[0], "dumpinfo" ) == 0 ) { 
     118        if (!args->args[1] ) { 
     119            printMessage("FILE argument is missing\n"); 
     120            return -1; 
     121        } 
     122        std::string str( args->args[1] ); 
     123 
     124        // load the file 
     125        Firmware f = Firmware(); 
     126        f.setVerboseLevel( args->verbose ); 
     127         
     128        if (!f.loadFile(str)) { 
     129            printMessage("Could not load firmware\n"); 
     130            return -1; 
     131        } 
     132        f.show(); 
     133        f.dumpData(); 
     134        return 0; 
     135    } else if ( strcmp( args->args[0], "list" ) == 0 ) { 
     136        printDeviceList(); 
     137        exit(0); 
     138    } 
     139 
     140    // we need a device, so find the specified device 
     141    if (guid == 0xFFFFFFFFFFFFFFFFLL) { 
     142        printMessage("No GUID specified\n"); 
     143        exit(-1); 
    78144    } 
    79145 
    80146    Ieee1394Service service; 
    81147    if ( !service.initialize( args->port ) ) { 
    82         debugError("Could not initialize IEEE 1394 service\n"); 
     148        printMessage("Could not initialize IEEE 1394 service\n"); 
    83149        return -1; 
    84150    } 
     
    89155        configRom.initialize(); 
    90156         
    91         if (configRom.getGuid() == guid) 
     157        if (configRom.getGuid() == guid) { 
    92158            node_id = configRom.getNodeId(); 
     159            break; 
     160        } 
    93161    } 
    94162 
    95163    if (node_id < 0) { 
    96         cerr << "Could not find device with matching GUID" << endl
     164        printMessage("Could not find device with GUID 0x%016X\n", guid)
    97165        return -1; 
    98166    } 
     
    100168    ConfigRom *configRom = new ConfigRom(service, node_id ); 
    101169    if (configRom == NULL) { 
    102         debugError("Could not create ConfigRom\n"); 
     170        printMessage("Could not create ConfigRom\n"); 
    103171        return -1; 
    104172    } 
     
    106174 
    107175    if ( !configRom->initialize() ) { 
    108         debugError( "Could not read config rom from device (node id %d).\n", 
     176        printMessage( "Could not read config rom from device (node id %d).\n", 
    109177                    node_id ); 
    110178        delete configRom; 
     
    112180    } 
    113181 
    114     if ( !Device::probe(*configRom) ) { 
    115         debugError( "Device with node id %d is not an ECHO FireWorks device.\n", 
     182    if ( !FireWorks::Device::probe(*configRom) ) { 
     183        printMessage( "Device with node id %d is not an ECHO FireWorks device.\n", 
    116184                    node_id ); 
    117185        delete configRom; 
     
    122190    Device *dev = new Device(d, std::auto_ptr<ConfigRom>(configRom) ); 
    123191    if (dev == NULL) { 
    124         debugError("Could not create FireWorks::Device\n"); 
     192        printMessage("Could not create FireWorks::Device\n"); 
    125193        delete configRom; 
    126194        return -1; 
    127195    } 
    128196 
    129     // create the firmware util class 
    130     FirmwareUtil util = FirmwareUtil(*dev); 
    131     util.setVerboseLevel( args->verbose ); 
    132      
    133     if ( strcmp( args->args[1], "firmware" ) == 0 ) { 
    134         if (!args->args[2] ) { 
    135             cerr << "FILE argument is missing" << endl; 
    136             delete dev; 
    137             return -1; 
    138         } 
    139         std::string str( args->args[2] ); 
    140  
    141         // load the file 
    142         Firmware f = Firmware(); 
    143         f.setVerboseLevel( args->verbose ); 
    144          
    145         f.loadFile(str); 
    146         f.show(); 
    147  
    148     } else if ( strcmp( args->args[1], "display" ) == 0 ) { 
     197    if ( strcmp( args->args[0], "display" ) == 0 ) { 
    149198        // nothing to do 
    150199        dev->showDevice(); 
    151     } else { 
    152         cout << "Unknown operation" << endl; 
     200    } else if (strcmp( args->args[0], "download" ) == 0) { 
     201        if (args->nargs < 3) { 
     202            printMessage("Address range not specified\n"); 
     203            delete dev; 
     204            return -1; 
     205        } 
     206        errno = 0; 
     207        uint32_t start_addr = strtol(args->args[2], NULL, 0);         
     208        if (errno) { 
     209            printMessage("start address parsing failed: %s\n", 
     210                       strerror(errno)); 
     211            delete dev; 
     212            return errno; 
     213        } 
     214        uint32_t len = strtol(args->args[3], NULL, 0); 
     215        if (errno) { 
     216            printMessage("length parsing failed: %s\n", 
     217                       strerror(errno)); 
     218            delete dev; 
     219            return errno; 
     220        } 
     221         
     222        // create the firmware util class 
     223        FirmwareUtil util = FirmwareUtil(*dev); 
     224        util.setVerboseLevel( args->verbose ); 
     225         
     226        Firmware f = util.getFirmwareFromDevice(start_addr, len); 
     227        f.setVerboseLevel( args->verbose ); 
     228        f.show(); 
     229        printMessage("Saving to file not yet supported.\n"); 
     230    } else if (strcmp( args->args[0], "verify" ) == 0) { 
     231        if (!args->args[1] ) { 
     232            printMessage("FILE argument is missing\n"); 
     233            delete dev; 
     234            return -1; 
     235        } 
     236        std::string str( args->args[1] ); 
     237 
     238        printMessage("Verifying device versus file: %s\n", str.c_str()); 
     239 
     240        printMessage(" loading file...\n"); 
     241        // load the file 
     242        Firmware ref = Firmware(); 
     243        ref.setVerboseLevel( args->verbose ); 
     244         
     245        if (!ref.loadFile(str)) { 
     246            printMessage("Could not load firmware from file\n"); 
     247            delete dev; 
     248            return -1; 
     249        } 
     250 
     251        // get the flash position from the loaded file 
     252        uint32_t start_addr = ref.getAddress(); 
     253        uint32_t len = ref.getLength(); 
     254 
     255        // create the firmware util class 
     256        FirmwareUtil util = FirmwareUtil(*dev); 
     257        util.setVerboseLevel( args->verbose ); 
     258         
     259        printMessage(" reading device...\n"); 
     260        // read the corresponding part of the device 
     261        Firmware f = util.getFirmwareFromDevice(start_addr, len); 
     262        f.setVerboseLevel( args->verbose ); 
     263        f.show(); 
     264         
     265        printMessage(" comparing...\n"); 
     266        // compare the two images 
     267        if(!(f == ref)) { 
     268            printMessage(" => Verify failed. Device content not the same as file content.\n"); 
     269            delete dev; 
     270            return -1; 
     271        } else { 
     272            printMessage(" => Verify successful. Device content identical to file content.\n"); 
     273        } 
     274 
     275    } else if (false) { 
     276        // create the firmware util class 
     277        FirmwareUtil util = FirmwareUtil(*dev); 
     278        util.setVerboseLevel( args->verbose ); 
     279 
     280    }  else { 
     281        printMessage("Unknown operation\n"); 
    153282    } 
    154283