bool Flash_Close(FLASH_HANDLE Handle){ FLASH_INFO *pFlash = (FLASH_INFO *)Handle; if (pFlash->fd_flash){ alt_flash_close_dev(pFlash->fd_flash); } free(Handle); return TRUE; }
/****************************************************************** * Function: TestFlash * * Purpose: Opens the specified flash device. If the mode * parameter is TEST, the function finds an erased * block, then tests it. If the mode parameter is * SHOWMAP, the function lists all blocks in the flash and * indicates which ones are erased. The flash is closed * at the end of the function. * ******************************************************************/ static void TestFlash(int mode) { alt_flash_fd* fd; int number_of_regions; int block; flash_region* regions; int ret_code = 0x0; alt_u8 entry[3]; char ch = 23; alt_u8 flashname[30]; ret_code = GetFlashName(flashname); fd = alt_flash_open_dev(flashname); if (fd) { printf(" -Successfully opened %s\n", flashname); /* Get some useful info about the flash */ ret_code = alt_get_flash_info(fd, ®ions, &number_of_regions); if (!ret_code) { printf(" -Region 0 contains %d blocks.\n", regions->number_of_blocks); block = FlashFindErasedBlocks(fd, regions, number_of_regions, mode); /* If we're in TEST mode, ask if this block is okay to test. */ if(mode == TEST) { printf(" -Block %d, at address 0x%X is erased.\n", block, (regions->offset + (block * regions->block_size))); printf(" -Would you like to test this block? (y/n)"); fgets(entry, sizeof(entry), stdin); if(sscanf(entry, "%c\n", &ch)) { if (ch == 'y') { /* Test that Flash! */ FlashRunTests(fd, block, regions); printf(" -Closing flash device \"%s\".\n", flashname); alt_flash_close_dev(fd); } } } } } else { printf(" -ERROR: Could not open %s\n", flashname); } }
static Cyg_ErrNo epcs_set_config( cyg_io_handle_t handle, cyg_uint32 key, const void* buf, cyg_uint32* len) { struct alt_flash_dev *flash_info = (alt_flash_dev *)p_epcs_fd; switch (key) { case CYG_IO_SET_CONFIG_CLOSE: { alt_flash_close_dev(p_epcs_fd); return -ENOERR; } default: return -EINVAL; } } // epcs_set_config()
alt_u32 Flash_Size(char *pFlashName){ alt_u32 FlashSize = 0; flash_region *regions, *nextreg; alt_flash_fd* fd; int number_of_regions; int ret_code, i; /* Set write_data to all 0xa */ fd = alt_flash_open_dev(pFlashName); if (fd){ ret_code = alt_get_flash_info(fd,®ions,&number_of_regions); if (ret_code == 0 && number_of_regions >= 1){ nextreg = regions; for(i=0;i<number_of_regions;i++){ FlashSize += nextreg->region_size; nextreg++; } } alt_flash_close_dev(fd); } return FlashSize; }
bool Flash_InfoDump(char *pFlashName){ bool bSuccess = FALSE; flash_region *regions, *nextreg; alt_flash_fd* fd; int number_of_regions; int ret_code; /* Set write_data to all 0xa */ FLASH_DEBUG(("Flash_InfoDump\r\n")); fd = alt_flash_open_dev(pFlashName); if (fd){ ret_code = alt_get_flash_info(fd,®ions,&number_of_regions); if (ret_code == 0){ int i; bSuccess = TRUE; nextreg = regions; FLASH_DEBUG(("number_of_regsion:%d\r\n", number_of_regions)); for(i=0;i<number_of_regions;i++){ FLASH_DEBUG(("regsion[%d]\r\n", i)); FLASH_DEBUG((" offset:%d\r\n", nextreg->offset)); FLASH_DEBUG((" region_size:%d\r\n", nextreg->region_size)); FLASH_DEBUG((" number_of_blocks:%d\r\n", nextreg->number_of_blocks)); FLASH_DEBUG((" block_size;:%d\r\n", nextreg->block_size)); nextreg++; } }else{ FLASH_DEBUG(("alt_get_flash_info error, ret_code:%d fail\r\n", ret_code)); } alt_flash_close_dev(fd); }else{ FLASH_DEBUG(("alt_flash_open_dev fail\r\n")); } if (!bSuccess) FLASH_DEBUG(("Flash_InfoDump fail\r\n")); return bSuccess; }
/* * generate_and_store_mac_addr() * * This routine is called when, upon program initialization, we discover * that there is no valid network settings (including MAC address) programmed * into flash memory at the last flash sector. If it is not safe to use the * contents of this last sector of flash, the user is prompted to * enter the serial number at the console. A MAC address is then * generated using 0xFF followed by the last 2 bytes of the serial number * appended to Altera's Vendor ID, an assigned MAC address range with the first * 3 bytes of 00:07:ED. For example, if the Nios Development Board serial * number is 040800017, the corresponding ethernet number generated will be * 00:07:ED:FF:8F:11. * * It should be noted that this number, while unique, will likely differ from * the also unique (but now lost forever) MAC address programmed into the * development board on the production line. * * As we are erasing the entire flash sector, we'll re-program it with not * only the MAC address, but static IP, subnet, gateway, and "Use DHCP" * sections. These fail-safe static settings are compatible with previous * Nios Ethernet designs, and allow the "factory-safe" design to behave * as expected if the last flash sector is erased. */ error_t generate_and_store_mac_addr() { error_t error = -1; alt_u32 ser_num = 0; char serial_number[9], flash_content[32]; alt_flash_fd* flash_handle; int i = 0; printf("Can't read the MAC address from your board (this probably means\n"); printf("that your flash was erased). We will assign you a MAC address and\n"); printf("static network settings\n\n"); while(!ser_num) { printf("Please enter your 9-digit serial number. This is printed on a \n"); printf("label under your Nios dev. board. The first 3 digits of the \n"); printf("label are ASJ and the serial number follows this.\n -->"); for(i=0; i<9; i++) { serial_number[i] = getchar(); putchar(serial_number[i]); /* Handle backspaces. How civilized. */ if ((serial_number[i] == 0x08) && (i >= 0)) { i--; } } printf("\n"); for(i=0; i<9; i++) { if (isdigit(serial_number[i])) { ser_num *= 10; ser_num += serial_number[i] - '0'; } else { ser_num = 0; printf("Serial number only contains decimal digits and is non-zero\n"); break; } } if (ser_num) { /* This says the image is safe */ flash_content[0] = 0xfe; flash_content[1] = 0x5a; flash_content[2] = 0x0; flash_content[3] = 0x0; /* This is the Altera Vendor ID */ flash_content[4] = 0x0; flash_content[5] = 0x7; flash_content[6] = 0xed; /* Reserverd Board identifier for erase boards */ flash_content[7] = 0xFF; flash_content[8] = (ser_num & 0xff00) >> 8; flash_content[9] = ser_num & 0xff; /* Then comes a 16-bit "flags" field */ flash_content[10] = 0xFF; flash_content[11] = 0xFF; /* Then comes the static IP address */ flash_content[12] = IPADDR0; flash_content[13] = IPADDR1; flash_content[14] = IPADDR2; flash_content[15] = IPADDR3; /* Then comes the static nameserver address */ flash_content[16] = 0xFF; flash_content[17] = 0xFF; flash_content[18] = 0xFF; flash_content[19] = 0xFF; /* Then comes the static subnet mask */ flash_content[20] = MSKADDR0; flash_content[21] = MSKADDR1; flash_content[22] = MSKADDR2; flash_content[23] = MSKADDR3; /* Then comes the static gateway address */ flash_content[24] = GWADDR0; flash_content[25] = GWADDR1; flash_content[26] = GWADDR2; flash_content[27] = GWADDR3; /* And finally whether to use DHCP - set all bits to be safe */ flash_content[28] = 0xFF; flash_content[29] = 0xFF; flash_content[30] = 0xFF; flash_content[31] = 0xFF; /* Write the MAC address to flash */ flash_handle = alt_flash_open_dev(EXT_FLASH_NAME); if (flash_handle) { alt_write_flash(flash_handle, ETHERNET_OPTION_BITS, flash_content, 32); alt_flash_close_dev(flash_handle); error = 0; } } } return error; }
/****************************************************************** * Function: ProgFlash * * Purpose: This function asks for the name of a flash device, * a pointer to a data buffer, and the size of the data buffer. * ******************************************************************/ int ProgFlash(struct flash_inf_struct *flash_info, int target_addr, char* data, int data_len) { // Flash device variables alt_flash_fd* fd; int number_of_regions; flash_region* regions; alt_u8 flashname[40]; /* Be conservative on the size of the string. */ alt_u8* flashname_ptr = (alt_u8*) &flashname; int new_flash_block = -1; // General purpose variables unsigned int sw_offset = 0; int ret_code = 0x0; /* * flash_info->device contains the flash device name * from the multipart form. * - If you want your flash name to be an option, you must change the * upload_image form in index.html to include your flash device's name * in the pick list. */ flashname_ptr += sprintf( flashname_ptr, "/dev/%s", flash_info->device ); *(flashname_ptr+1) = '\0'; fd = alt_flash_open_dev(flashname); if (fd) { /* Get some useful info about the flash */ ret_code = alt_get_flash_info(fd, ®ions, &number_of_regions); /* To which flash block is the SREC data destined? */ /* new_flash_block = target_addr / regions->block_size; */ /* Ahhh, but what happens if a line spans the end of one block and the * beginning of another? * - Better to handle this case well...as well! */ new_flash_block = (target_addr + data_len) / regions->block_size; if( current_flash_block == -1 ) { /* Output various flash information when programming the first line. */ printf( "\nFlash Name is %s.\nBlock size is %d bytes.\n\nProgramming Flash...\n", flashname, regions->block_size ); } /* if it's a new block, we need to erase it first. */ if(new_flash_block != current_flash_block) { printf("\nFlash Block %d", new_flash_block); /* Blindly erase the new flash block */ alt_erase_flash_block(fd, (new_flash_block * regions->block_size), regions->block_size); current_flash_block = new_flash_block; } alt_write_flash_block(fd, (current_flash_block * regions->block_size), target_addr, data, data_len); /* This just gives us some zippy dots so we know hard work is being done */ if ((target_addr - sw_offset) % (regions->block_size / 8) < data_len) { printf("\n 0x%8.8X: ", (target_addr & 0xFFFFFF00)); } /*if ((target_addr - sw_offset) % (regions->block_size / 256) < data_len) { printf("."); }*/ } else { printf("Error Opening flash device. Exiting."); } alt_flash_close_dev(fd); return (ret_code); }
/****************************************************************** * Function: FlashErase * * Purpose: Erases 1 or all blocks in the specified flash device. * ******************************************************************/ static void FlashErase(void) { alt_flash_fd* fd; int test_offset; int ret_code; flash_region* regions; int number_of_regions; alt_u8 entry[3]; alt_u8 flashname[30]; unsigned int block; /* Get the name of the flash we are erasing */ ret_code = GetFlashName(flashname); fd = alt_flash_open_dev(flashname); if (fd) { /* Find out some useful stuff about the flash */ ret_code = alt_get_flash_info(fd, ®ions, &number_of_regions); if (!ret_code) { printf(" -Region has %d blocks.\n", regions->number_of_blocks); printf(" -Which block would you like to erase?\n"); printf(" -> "); fgets(entry, sizeof(entry), stdin); if(entry[0] == 'a') { printf(" -Erase ALL blocks? (y/n) "); fgets(entry, sizeof(entry), stdin); if(entry[0] == 'y') { /* Erase all blocks */ printf(" -Erasing %d blocks. Please Wait.\n", (regions->number_of_blocks)); for(block = 0; block < regions->number_of_blocks; block++) { /* Dont erase it if it's already erased silly. */ if ((FlashCheckIfBlockErased(fd->base_addr, block, regions)) == 0) { test_offset = (regions->offset + (block * regions->block_size)); alt_erase_flash_block(fd, test_offset, regions->block_size); } /* Just a simple progress meter so we dont get bored waiting for the flash to erase. */ printf("."); if(((block + 1) % 80) == 0) { printf("\n"); } } printf("\n -All Blocks Erased.\n"); } else { printf("Erased zero blocks.\n"); } } /* Just erase one block */ if(sscanf(entry, "%d\n", &block)) { if ((block >= 0) && (block <= (regions->number_of_blocks - 1))) { test_offset = (regions->offset + (block * regions->block_size)); alt_erase_flash_block(fd, test_offset, regions->block_size); printf(" -Block %d erased.\n", block); } else { printf(" -Block number entered is %d\n", block); printf(" -Block number must be between 0 and %d.\n", (regions->number_of_blocks - 1)); } } } printf(" -Closing flash \"%s\".\n", flashname); alt_flash_close_dev(fd); } }
static void ExecuteCmd(const char const *input, const u32 base) { SendStr("\r\n", base); // Tokenize the command #define MAX_CMD_WORDS 4 char *token[MAX_CMD_WORDS]; char *cmd = (char *)input; u8 numTokens = 0; while (1) { // Skip leading whitespace. while ((*cmd) && isspace(*cmd)) cmd++; // If we get here and we are at the end of the string, then the last // token must have had trailing white spaces. Let's ignore them if (!(*cmd)) break; // If we have exceeded the maximum number of allowable tokens, then // return as error if (numTokens >= MAX_CMD_WORDS) { SendStr(NO_ANSWER, base); return; } // Store the token. token[numTokens] = cmd; numTokens++; // Everything that isn't a whitespace is part of the token. Let's make // sure it is in UPPER CASE while ((*cmd) && (!isspace(*cmd))) { *cmd = toupper(*cmd); cmd++; } // When we get here, we are just past the current token, either because // it ended on a whitespace or because it is the end of the user input. // If the former, then let's force a null termination for that token. If // the latter, then we are done tokenizing. if (!(*cmd)) break; *cmd = '\0'; cmd++; } if (0 == numTokens) { SendStr(NO_ANSWER, base); return; } // Process the command switch (token[0][0]) { case 'R': { if (2 != numTokens) SendStr(NO_ANSWER, base); else { u32 regAddr; u32 regValue; if (StrToU32(token[1], ®Addr) && RegRead(regAddr, ®Value)) { SendStr("Y ", base); char regValStr[9]; U32ToStr(regValue, regValStr); SendStr(regValStr, base); SendStr("\r\n", base); } else SendStr(NO_ANSWER, base); } break; } case 'W': { if (3 != numTokens) SendStr(NO_ANSWER, base); else { u32 regAddr; u32 regValue; if (StrToU32(token[1], ®Addr) && StrToU32(token[2], ®Value) && RegWrite(regAddr, regValue)) SendStr(YES_ANSWER, base); else SendStr(NO_ANSWER, base); } break; } case 'V': { SendStr("FPGA=0x", base); char versionStr[9]; FpgaRegisters * FPGARegs = (FpgaRegisters *)(REGISTER_BASE | BYPASS_DCACHE_MASK); U32ToStr(FPGARegs->fpgaVersion, versionStr); SendStr(versionStr, base); SendStr(" NIOS=0x", base); U32ToStr(NIOS_VERSION, versionStr); SendStr(versionStr, base); SendStr("\r\n", base); break; } case 'F': { if (4 != numTokens) SendStr(NO_ANSWER, base); else { u32 startAddr; u32 length; u32 checksum; StrToU32(token[1], &startAddr); StrToU32(token[2], &length); StrToU32(token[3], &checksum); // Transfer two chunks to get a full sector worth #define FLASH_SECTOR_SIZE (64*1024) #define TRANSFER_SIZE (4*1024) u8 buffer[FLASH_SECTOR_SIZE]; // Validate the requested transfer size if (length != TRANSFER_SIZE) SendStr(NO_ANSWER, base); else { u32 bufferIndex = startAddr % FLASH_SECTOR_SIZE; u32 runningSum = 0; u32 numBytesReceived = 0; // Clear the input buffer FlushRx(base); // Acknowledge that the command is good. This will tell the // sender to actually send the specified number of bytes SendStr(YES_ANSWER, base); // We must receive the correct number of bytes while (true) { while (IORD_FIFOED_AVALON_UART_STATUS(base) & FIFOED_AVALON_UART_CONTROL_RRDY_MSK) { // Read the Uart u8 rx = IORD_FIFOED_AVALON_UART_RXDATA(base); runningSum += rx; buffer[bufferIndex++] = rx; numBytesReceived++; if (numBytesReceived >= length) break; } if (numBytesReceived >= length) break; } // check the checksum if (runningSum != checksum) SendStr(NO_ANSWER, base); else { // If we don't have a full sector worth of data, then ACK and wait for more if (bufferIndex != FLASH_SECTOR_SIZE) SendStr(YES_ANSWER, base); else { u32 totalWriteBufferChecksum = 0; int i; for (i=0; i<sizeof(buffer); i++) { totalWriteBufferChecksum += buffer[i]; } alt_flash_fd* fd = alt_flash_open_dev(SERIAL_FLASH_NAME); if (NULL == fd) SendStr(NO_ANSWER, base); else { u32 sectorStartAddr = (startAddr / FLASH_SECTOR_SIZE) * FLASH_SECTOR_SIZE; if (0 == alt_write_flash(fd, sectorStartAddr, buffer, length)) { memset(buffer, 0x99, sizeof(buffer)); if (0 == alt_read_flash(fd, sectorStartAddr, buffer, sizeof(buffer))) { u32 totalReadBufferChecksum = 0; for (i=0; i<sizeof(buffer); i++) { totalReadBufferChecksum += buffer[i]; } if (totalReadBufferChecksum == totalWriteBufferChecksum) SendStr(YES_ANSWER, base); else SendStr(NO_ANSWER, base); } else SendStr(NO_ANSWER, base); } else SendStr(NO_ANSWER, base); alt_flash_close_dev(fd); } } } } } break; } default: SendStr(NO_ANSWER, base); break; } return; }
/* * generate_and_store_mac_addr() * * This routine is called when, upon program initialization, we discover * that there is no valid network settings (including MAC address) programmed * into flash memory at the last flash sector. If it is not safe to use the * contents of this last sector of flash, the user is prompted to * enter the serial number at the console. A MAC address is then * generated using 0xFF followed by the last 2 bytes of the serial number * appended to Altera's Vendor ID, an assigned MAC address range with the first * 3 bytes of 00:07:ED. For example, if the Nios Development Board serial * number is 040800017, the corresponding ethernet number generated will be * 00:07:ED:FF:8F:11. * * It should be noted that this number, while unique, will likely differ from * the also unique (but now lost forever) MAC address programmed into the * development board on the production line. * * As we are erasing the entire flash sector, we'll re-program it with not * only the MAC address, but static IP, subnet, gateway, and "Use DHCP" * sections. These fail-safe static settings are compatible with previous * Nios Ethernet designs, and allow the "factory-safe" design to behave * as expected if the last flash sector is erased. */ error_t generate_and_store_mac_addr() { error_t error = -1; alt_u32 ser_num = 0; char flash_content[32]; alt_flash_fd* flash_handle; printf("Can't read the MAC address from your board (this probably means\n"); printf("that your flash was erased). We will assign you a MAC address and\n"); printf("static network settings\n\n"); ser_num = get_serial_number(); if (ser_num) { /* This says the image is safe */ flash_content[0] = 0xfe; flash_content[1] = 0x5a; flash_content[2] = 0x0; flash_content[3] = 0x0; /* This is the Altera Vendor ID */ flash_content[4] = 0x0; flash_content[5] = 0x7; flash_content[6] = 0xed; /* Reserverd Board identifier for erase boards */ flash_content[7] = 0xFF; flash_content[8] = (ser_num & 0xff00) >> 8; flash_content[9] = ser_num & 0xff; /* Then comes a 16-bit "flags" field */ flash_content[10] = 0xFF; flash_content[11] = 0xFF; /* Then comes the static IP address */ flash_content[12] = IPADDR0; flash_content[13] = IPADDR1; flash_content[14] = IPADDR2; flash_content[15] = IPADDR3; /* Then comes the static nameserver address */ flash_content[16] = 0xFF; flash_content[17] = 0xFF; flash_content[18] = 0xFF; flash_content[19] = 0xFF; /* Then comes the static subnet mask */ flash_content[20] = MSKADDR0; flash_content[21] = MSKADDR1; flash_content[22] = MSKADDR2; flash_content[23] = MSKADDR3; /* Then comes the static gateway address */ flash_content[24] = GWADDR0; flash_content[25] = GWADDR1; flash_content[26] = GWADDR2; flash_content[27] = GWADDR3; /* And finally whether to use DHCP - set all bits to be safe */ flash_content[28] = 0xFF; flash_content[29] = 0xFF; flash_content[30] = 0xFF; flash_content[31] = 0xFF; #if 0 /* Write the MAC address to flash */ flash_handle = alt_flash_open_dev(EXT_FLASH_NAME); if (flash_handle) { alt_write_flash(flash_handle, last_flash_sector_offset, flash_content, 32); alt_flash_close_dev(flash_handle); error = 0; } #endif } return error; }