//---------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------- // 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; } }
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,©right,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,©right,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"); }
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; }