//----------------------------------------------------------------------------
// Initialize driver details
int
flash_hwr_init(void)
{
    flash_data_t id[4];
    int i;

	NF8_Init();
	
    flash_dev_query(id);

    // Check that flash_id data is matching the one the driver was
    // configured for.

    // Check manufacturer
    if (id[0] != 0xec) {		//0xec, samsung maker code
        flash_printf("Can't identify FLASH - manufacturer is: %x, should be %x\n", 
                    id[0], 0xec);
        return FLASH_ERR_DRV_WRONG_PART;
    }

    // Did we find the device? If not, return error.
    if (id[1]!=0xda) {
        diag_printf("Can't identify FLASH - device is: %x ", id[1]);
        diag_printf("\n");
        return FLASH_ERR_DRV_WRONG_PART;
    }

    // Fill in device details
    flash_info.block_size = BYTES_PERBLOCK;
    flash_info.blocks = BLOCKS_INNAND-KEPT_BLOCKS;
    flash_info.start = 0;	
    flash_info.end = (void *)((BLOCKS_INNAND-KEPT_BLOCKS)*BYTES_PERBLOCK);
    return FLASH_ERR_OK;
}
Exemple #2
0
//--------------------------------------------------------------------------
// Magic to determine location of flash
// This works by querying at the location where we expect the EPROM to
// be. Then the returned data is compared with the data at that location.
// If there's a match, assume that to be the location of the EPROM.
// Otherwise it's at the other location.
//
// This is done to avoid having separate configurations for the two board
// configurations. This is simple, has negligible overhead, and Just Works.
void
plf_flash_init(void)
{
    flash_data_t id[2];
    flash_data_t* p;

    plf_flash_base = 0xa0400000;
    flash_dev_query(id);

    p = (flash_data_t*)0xa0400000;
    if (id[0] == *p++ && id[1] == *p)
        plf_flash_base = 0xa0000000;
        
    // Make that the cached region.
    plf_flash_base &= ~0x20000000;
}
int
flash_hwr_init(void)
{
    unsigned char data[96];
    int num_regions, region_size;

    flash_dev_query(&data);

    if ((data[0] == FLASH_Intel_code) && ((data[4] == FLASH_28F008SA) ||
					  (data[4] == FLASH_28F008SC))) {
        num_regions = 16;
        region_size = 0x40000;
        flash_info.block_size = region_size;
        flash_info.blocks = num_regions;
        flash_info.start = (void *)0x41000000;
        flash_info.end = (void *)(0x41000000+(num_regions*region_size));
        return FLASH_ERR_OK;
    } else {
        (*flash_info.pf)("Can't identify FLASH, sorry\n");
        diag_dump_buf(data, sizeof(data));
        return FLASH_ERR_HWR;
    }
}
Exemple #4
0
void cyg_user_start(void)
{
    int ret;
    char data[1024];
    void *flash_start, *flash_end;
    int block_size, blocks;
    char *prog_start;
    unsigned char * ptr;

    CYG_TEST_INIT();
  
    ret=flash_init(NULL,0,(_printf *)diag_printf);
  
    CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_init");

    flash_dev_query(data);
    CYG_TEST_PASS_FAIL(!strncmp(data,"Linux Synthetic Flash",sizeof(data)),
                       "flash_query"); 

    ret = flash_get_limits(NULL,&flash_start,&flash_end);
    CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_get_limits");

    ret = flash_get_block_info(&block_size, &blocks);
    CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_get_block_info");

    /* Erase the whole flash. Not recommended on real hardware since this
     will probably erase the bootloader etc!!! */
    ret=flash_erase(flash_start,block_size * blocks,NULL);
    CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_erase1");

    /* check that its actually been erased, and test the mmap area */
    for (ptr=flash_start,ret=0; ptr < (unsigned char *)flash_end; ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }
  
    CYG_TEST_PASS_FAIL((ret == 0),"flash empty check");

    ret = flash_program(flash_start,&copyright,sizeof(copyright),NULL);
    CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_program1");
  
    /* Check the contents made it into the flash */
    CYG_TEST_PASS_FAIL(!strncmp(flash_start,copyright,sizeof(copyright)),
                       "flash program contents");

    /* .. and check nothing else changed */
    for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0; 
         ptr < (unsigned char *)flash_end; ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }
  
    CYG_TEST_PASS_FAIL((ret == 0),"flash program overrun check");

    /* Program over a block boundary */
    prog_start = (unsigned char *)flash_start + block_size - sizeof(copyright)/2;
    ret = flash_program(prog_start,&copyright,sizeof(copyright),NULL);
    CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_program2");
  
    /* Check the first version is still OK */
    CYG_TEST_PASS_FAIL(!strncmp(flash_start,copyright,sizeof(copyright)),
                       "Original contents");
  
    CYG_TEST_PASS_FAIL(!strncmp(prog_start,copyright,sizeof(copyright)),
                       "New program contents");

    /* Check the bit in between is still erased */
    for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0; 
         ptr < (unsigned char *)prog_start; ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }
    CYG_TEST_PASS_FAIL((ret == 0),"flash erase check1");
  
    /* Erase the second block and make sure the first is not erased */
    ret=flash_erase((void *)((unsigned)flash_start+block_size),
                    block_size,NULL);
    CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_erase2");

    /* Check the erase worked */
    for (ptr=(unsigned char *)flash_start+block_size,ret=0; 
         ptr < (unsigned char *)flash_start+block_size*2; ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }

    CYG_TEST_PASS_FAIL((ret == 0), "flash erase check2");
  
    /* Lastly check the first half of the copyright message is still there */
    CYG_TEST_PASS_FAIL(!strncmp(prog_start,copyright,sizeof(copyright)/2),
                       "Block 1 OK");

#if 0
    /* This test it fatal! Its not run by default!
     Check the flash is read only, by trying to write to it. We expect
     to get an exception */

    *(char *)flash_start = 'a';
#endif

    CYG_TEST_PASS_FINISH("flash1");
}
Exemple #5
0
int
flash_hwr_init(void)
{
    struct FLASH_query data, *qp;
    int num_regions, region_size, buffer_size;

    flash_dev_query(&data);
    qp = &data;
    if ( ((qp->manuf_code == FLASH_Intel_code) || 
          (qp->manuf_code == FLASH_STMicro_code))
#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
         // device types go as follows: 0x90 for 16-bits, 0xD0 for 8-bits,
         // plus 0 or 1 for -T (Top Boot) or -B (Bottom Boot)
         //     [FIXME: whatever that means :FIXME]
         // [I think it means the boot blocks are top/bottom of addr space]
         // plus the following size codes:
         //    0: 16Mbit    2:  8Mbit    4:  4Mbit
         //    6: 32Mbit    8: 64Mbit
#if 16 == CYGNUM_FLASH_WIDTH         
         && (0x90 == (0xF0 & qp->device_code)) // 16-bit devices
#elif 8 == CYGNUM_FLASH_WIDTH
         && (0xD0 == (0xF0 & qp->device_code)) // 8-bit devices
#else
         && 0
#error Only understand 16 and 8-bit bootblock flash types
#endif
        ) {
        int lookup[] = { 16, 8, 4, 32, 64 };
#define BLOCKSIZE (0x10000)
        region_size = BLOCKSIZE;
        num_regions = qp->device_code & 0x0F;
        num_regions >>= 1;
        if ( num_regions > 4 )
            goto flash_type_unknown;
        num_regions = lookup[num_regions];
        num_regions *= 1024 * 1024;     // to bits
        num_regions /= 8;               // to bytes
        num_regions /= BLOCKSIZE;       // to blocks
        buffer_size = 0;
#else // CYGOPT_FLASH_IS_BOOTBLOCK
         && (strncmp(qp->id, "QRY", 3) == 0)) {
        num_regions = _si(qp->num_regions)+1;
        region_size = _si(qp->region_size)*256;       
        if (_si(qp->buffer_size)) {
            buffer_size = CYGNUM_FLASH_DEVICES << _si(qp->buffer_size);
        } else {
            buffer_size = 0;
        }
#endif // Not CYGOPT_FLASH_IS_BOOTBLOCK

        flash_info.block_size = region_size*CYGNUM_FLASH_DEVICES;
        flash_info.buffer_size = buffer_size;
        flash_info.blocks = num_regions;
        flash_info.start = (void *)CYGNUM_FLASH_BASE;
        flash_info.end = (void *)(CYGNUM_FLASH_BASE +
                        (num_regions*region_size*CYGNUM_FLASH_DEVICES));
#ifdef CYGNUM_FLASH_BASE_MASK
        // Then this gives us a maximum size for the (visible) device.
        // This is to cope with oversize devices fitted, with some high
        // address lines ignored.
        if ( ((unsigned int)flash_info.start & CYGNUM_FLASH_BASE_MASK) !=
             (((unsigned int)flash_info.end - 1) & CYGNUM_FLASH_BASE_MASK ) ) {
            // then the size of the device appears to span >1 device-worth!
            unsigned int x;
            x = (~(CYGNUM_FLASH_BASE_MASK)) + 1; // expected device size
            x += (unsigned int)flash_info.start;
            if ( x < (unsigned int)flash_info.end ) { // 2nd sanity check
                (*flash_info.pf)("\nFLASH: Oversized device!  End addr %p changed to %p\n",
                       flash_info.end, (void *)x );
                flash_info.end = (void *)x;
                // Also adjust the block count else unlock crashes!
                x = ((cyg_uint8 *)flash_info.end - (cyg_uint8 *)flash_info.start)
                    / flash_info.block_size;
                flash_info.blocks = x;
            }
        }
#endif // CYGNUM_FLASH_BASE_MASK

        return FLASH_ERR_OK;
    }
#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
 flash_type_unknown:
#endif
    (*flash_info.pf)("Can't identify FLASH, sorry, man %x, dev %x, id [%4s] \n",
           qp->manuf_code, qp->device_code, qp->id );
    diag_dump_buf(qp, sizeof(data));
    return FLASH_ERR_HWR;
}