byte flash_sector_erase_int(WORD sector) { int i; // printk("Flash erase sector number:%d\n",sector); for( i = 0; i < 3; i++ ) { flash_command(FLASH_SERASE, sector, 0, 0); if(flashFamily==FLASH_MXIC) { if (flash_wait_erase(sector, 0, 0xffff) == STATUS_READY) break; } else if (flash_wait(sector, 0, 0xffff) == STATUS_READY) break; } return(1); }
//MXIC flash only //for polling erase operation static int flash_wait_erase(WORD sector, int offset, UINT16 data) { volatile UINT16 *flashptr; /* flash window */ UINT16 d1; flashptr = (UINT16 *) flash_get_memptr(sector); do { while (!(*flashptr & 0x80)); // read DQ7 to see if it is one d1=*flashptr; d1 ^= *flashptr; if(d1==0) return STATUS_READY; }while(!(d1 & 0x20)); //time out DQ5 d1 = *flashptr; /* read data */ d1 ^= *flashptr; /* read it again and see what toggled */ if (d1 != 0) flash_command(FLASH_RESET, 0, 0, 0); return STATUS_TIMEOUT; }
inline void exit_se_flash(int base) { flash_command(base, 0x555, 0x90); *(unsigned short*)base=0; }
void setup_arch(char **cmdline_p) { int bootmap_size; extern int _stext, _etext; extern int _edata, _end; #ifdef DEBUG extern int _sdata, _sbss, _ebss; #ifdef CONFIG_BLK_DEV_BLKMEM extern int *romarray; #endif #endif unsigned char *psrc=(unsigned char *)((NIOS_FLASH_START + NIOS_FLASH_END)>>1); int i=0; memory_start = (unsigned long)&_end; memory_end = (int) nasys_program_mem_end; /* copy the command line from booting paramter region */ flash_command((int)psrc, 0x555, 0x88); while ((*psrc!=0xFF) && (i<sizeof(command_line))) { command_line[i++]=*psrc++; } command_line[i]=0; exit_se_flash(((NIOS_FLASH_START + NIOS_FLASH_END)>>1) ); if (command_line[0]==0) memcpy(command_line, default_command_line, sizeof(default_command_line)); printk("\x0F\r\n\nuClinux/NIOS\n"); printk("Altera NIOS Excalibur support (C) 2001 Microtronix Datacom Ltd.\n"); #ifdef DEBUG printk("KERNEL -> TEXT=0x%08x-0x%08x DATA=0x%08x-0x%08x " "BSS=0x%08x-0x%08x\n", (int) &_stext, (int) &_etext, (int) &_sdata, (int) &_edata, (int) &_sbss, (int) &_ebss); printk("KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x " "STACK=0x%06x-0x%06x\n", #ifdef CONFIG_BLK_DEV_BLKMEM (int) romarray, ((int) romarray) + ntohl(romarray[2]), #else (int) &_ebss, (int) memory_start, #endif (int) memory_start, (int) memory_end, (int) memory_end, (int) nasys_program_mem_end); #endif init_mm.start_code = (unsigned long) &_stext; init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) 0; //vic FIXME - this necessary ? init_task.thread.kregs = &fake_regs; #if 0 ROOT_DEV = MKDEV(BLKMEM_MAJOR,0); #endif /* Keep a copy of command line */ *cmdline_p = &command_line[0]; memcpy(saved_command_line, command_line, sizeof(saved_command_line)); saved_command_line[sizeof(saved_command_line)-1] = 0; #ifdef DEBUG if (strlen(*cmdline_p)) printk("Command line: '%s'\n", *cmdline_p); else printk("No Command line passed\n"); #endif #if defined (CONFIG_CS89x0) || (CONFIG_SMC91111) /* now read the hwaddr of the ethernet --wentao*/ flash_command(NIOS_FLASH_START, 0x555, 0x88); memcpy(cs8900a_hwaddr_array,(void*)NIOS_FLASH_START,6); exit_se_flash(NIOS_FLASH_START); /* now do the checking, make sure we got a valid addr */ if (cs8900a_hwaddr_array[0] & (unsigned char)1) { printk("Invalid ethernet hardware addr, fixed\n"); cs8900a_hwaddr_array[0] ^= (unsigned char)1; } cs8900a_hwaddr=cs8900a_hwaddr_array; #ifdef DEBUG printk("Setup the hardware addr for ethernet\n\t %02x %02x %02x %02x %02x %02x\n", cs8900a_hwaddr[0],cs8900a_hwaddr[1], cs8900a_hwaddr[2],cs8900a_hwaddr[3], cs8900a_hwaddr[4],cs8900a_hwaddr[5]); #endif #endif /* * give all the memory to the bootmap allocator, tell it to put the * boot mem_map at the start of memory */ bootmap_size = init_bootmem_node( NODE_DATA(0), memory_start >> PAGE_SHIFT, /* map goes here */ PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */ memory_end >> PAGE_SHIFT); /* * free the usable memory, we have to make sure we do not free * the bootmem bitmap so we then reserve it after freeing it :-) */ free_bootmem(memory_start, memory_end - memory_start); reserve_bootmem(memory_start, bootmap_size); /* * get kmalloc into gear */ paging_init(); #ifdef CONFIG_VT #if defined(CONFIG_DUMMY_CONSOLE) conswitchp = &dummy_con; #endif #endif #ifdef DEBUG printk("Done setup_arch\n"); #endif }
void __init setup_arch(char **cmdline_p) { int bootmap_size; extern int _stext, _etext; extern int _edata, _end; #ifdef DEBUG extern int _sdata, _sbss, _ebss; #ifdef CONFIG_BLK_DEV_BLKMEM extern int *romarray; #endif #endif #if 0 // krh unsigned char *psrc=(unsigned char *)((NIOS_FLASH_START + NIOS_FLASH_END)>>1); int i=0; #endif // krh memory_start = PAGE_ALIGN((unsigned long)&_end); memory_end = (unsigned long) nasys_program_mem_end; #if 0 //;kenw; /* copy the command line from booting paramter region */ #if defined (nasys_am29lv065d_flash_0) //;dgt; { //;dgt; // ...TBA... //;dgt; } //;dgt; #else //;dgt; flash_command((int)psrc, 0x555, 0x88); while ((*psrc!=0xFF) && (i<sizeof(command_line))) { command_line[i++]=*psrc++; } command_line[i]=0; exit_se_flash(((NIOS_FLASH_START + NIOS_FLASH_END)>>1) ); if (command_line[0]==0) #endif //;dgt; #endif //;kenw; #ifndef CONFIG_PASS_CMDLINE memcpy(command_line, default_command_line, sizeof(default_command_line)); #endif printk("\x0F\r\n\nuClinux/Nios II\n"); printk("Altera Nios II support (C) 2004 Microtronix Datacom Ltd.\n"); #ifdef DEBUG printk("KERNEL -> TEXT=0x%08x-0x%08x DATA=0x%08x-0x%08x " "BSS=0x%08x-0x%08x\n", (int) &_stext, (int) &_etext, (int) &_sdata, (int) &_edata, (int) &_sbss, (int) &_ebss); printk("KERNEL -> MEM=0x%06x-0x%06x STACK=0x%06x-0x%06x\n", (int) memory_start, (int) memory_end, (int) memory_end, (int) nasys_program_mem_end); #endif init_mm.start_code = (unsigned long) &_stext; init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) 0; init_task.thread.kregs = &fake_regs; #if 0 ROOT_DEV = MKDEV(BLKMEM_MAJOR,0); #endif /* Keep a copy of command line */ *cmdline_p = &command_line[0]; memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); boot_command_line[COMMAND_LINE_SIZE-1] = 0; #ifdef DEBUG if (strlen(*cmdline_p)) printk("Command line: '%s'\n", *cmdline_p); else printk("No Command line passed\n"); #endif #if defined (CONFIG_CS89x0) || defined (CONFIG_SMC91111) || defined (CONFIG_OPEN_ETH) || defined (CONFIG_MTIP1000_ETH) || defined (CONFIG_DM9000_ETH) || defined (CONFIG_SMC91X) || defined (CONFIG_DM9000) || defined (CONFIG_DM9KS) #if defined (CONFIG_MTIP1000_ETH) //;dgt3; (*((np_mtip_mac *) //;dgt3; (na_mtip_mac_control_port))). //;dgt3; COMMAND_CONFIG = 0; //;dgt3; #endif //;dgt3; /* now read the hwaddr of the ethernet --wentao*/ #if defined (na_flash_kernel) #if 1 //;dgt2; // #if defined (nasys_am29lv065d_flash_0) //;dgt; { //;dgt; unsigned char *flashptr = //;dgt; ((unsigned char *) //;dgt; (( //;dgt; #if defined (na_flash_kernel_end) //;dgt2; na_flash_kernel_end //;dgt2; #else //;dgt2; #if defined (na_flash_kernel_base) //;dgt2; na_flash_kernel_base + //;dgt; #else //;dgt2; na_flash_kernel + //;dgt2; #endif //;dgt2; na_flash_kernel_size //;dgt2; #endif //;dgt2; - 0x00010000))); //;dgt; // last 64K of Altera stratix/cyclone flash //;dgt; //;dgt; if((*((unsigned long *) flashptr)) == 0x00005AFE) //;dgt; { //;dgt; memcpy(excalibur_enet_hwaddr_array, //;dgt; ((void*) (flashptr+4)),6); //;dgt; } //;dgt; else //;dgt; { //;dgt; printk("\nsetup_arch: No persistant network" //;dgt; " settings signature at %08lX\n", //;dgt; ((unsigned long) flashptr)); //;dgt; *((unsigned long *) //;dgt; (&(excalibur_enet_hwaddr_array[0]))) = //;dgt; 0x00ED0700; //;dgt2; /* 0x00-07-ED: Altera Corporation. //;dgt; */ *((unsigned short *) //;dgt; (&(excalibur_enet_hwaddr_array[4]))) = //;dgt; 0x0000; //;dgt; /* Should be: 0x-00-07-ED-0A-03-(Random# 0-256) //;dgt2; */ /* 0x-00-07-ED-0A-xx-yy Vermont boards //;dgt2; */ /* 0x-00-07-ED-0B-xx-yy Rhode Island boards //;dgt2; */ /* 0x-00-07-ED-0C-xx-yy Delaware boards //;dgt2; */ /* 00 Internal Altera //;dgt2; */ /* 01 Beta, pre-production//;dgt2; */ /* 02 Beta, pre-production//;dgt2; */ /* 03 Customer use //;dgt2; */ } //;dgt; } //;dgt; #else //;dgt; flash_command(NIOS_FLASH_START, 0x555, 0x88); memcpy(excalibur_enet_hwaddr_array,(void*)NIOS_FLASH_START,6); exit_se_flash(NIOS_FLASH_START);; #endif //;dgt; /* now do the checking, make sure we got a valid addr */ if (excalibur_enet_hwaddr_array[0] & (unsigned char)1) { printk("Ethernet hardware address:Clearing invalid bit #0\n"); excalibur_enet_hwaddr_array[0] ^= (unsigned char)1; } #else excalibur_enet_hwaddr[0] = 0x00; excalibur_enet_hwaddr[1] = 0x07; excalibur_enet_hwaddr[2] = 0xed; excalibur_enet_hwaddr[3] = 0x0a; excalibur_enet_hwaddr[4] = 0x03; excalibur_enet_hwaddr[5] = 0x00; #endif /* defined na_flash_kernel */ excalibur_enet_hwaddr=excalibur_enet_hwaddr_array; #ifdef DEBUG printk("Setup the hardware addr for ethernet\n\t %02x %02x %02x %02x %02x %02x\n", excalibur_enet_hwaddr[0],excalibur_enet_hwaddr[1], excalibur_enet_hwaddr[2],excalibur_enet_hwaddr[3], excalibur_enet_hwaddr[4],excalibur_enet_hwaddr[5]); #endif #endif /* * give all the memory to the bootmap allocator, tell it to put the * boot mem_map at the start of memory */ bootmap_size = init_bootmem_node( NODE_DATA(0), memory_start >> PAGE_SHIFT, /* map goes here */ PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */ memory_end >> PAGE_SHIFT); /* * free the usable memory, we have to make sure we do not free * the bootmem bitmap so we then reserve it after freeing it :-) */ free_bootmem(memory_start, memory_end - memory_start); reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) reserve_bootmem(virt_to_phys((void *)initrd_start), initrd_end - initrd_start, BOOTMEM_DEFAULT); #endif /* CONFIG_BLK_DEV_INITRD */ /* * get kmalloc into gear */ paging_init(); #ifdef CONFIG_VT #if defined(CONFIG_DUMMY_CONSOLE) conswitchp = &dummy_con; #endif #endif #ifdef DEBUG printk("Done setup_arch\n"); #endif }
static int flash_wait(WORD sector, int offset, UINT16 data) { volatile UINT16 *flashptr; /* flash window */ UINT16 d1,d2; UINT16 var=0x20; flashptr = (UINT16 *) flash_get_memptr(sector); if ( flashFamily == FLASH_SST) var=0x40; if (flashFamily == FLASH_AMD || flashFamily == FLASH_SST || flashFamily==FLASH_MXIC) { #if defined(_BCM96338_) || defined(CONFIG_BCM96338) /* If the word written does not yet compare, try for another 100ms. * This check is done for SST39VF800A. */ if(flashFamily == FLASH_SST){ /* If the word written does not yet compare, try for another 100ms. * This check is done for SST39VF800A. */ int i; for( i = 0; i < 10000; i++ ) { d1 = flashptr[offset/2]; if (d1 == data) return STATUS_READY; udelay(10);//CFI_USLEEP(10); } d1 = flashptr[offset/2]; if (d1 != data) { flash_command(FLASH_RESET, 0, 0, 0); return STATUS_TIMEOUT; } } else { do { d1 = flashptr[offset/2]; if (d1 == data) return STATUS_READY; } while (!(d1 & 0x20)); d1 = flashptr[offset/2]; } #else if(flashFamily == FLASH_SST) { // timeout error /* If the word written does not yet compare, try for another 100ms. * This check is done for SST39VF800A. */ DWORD i,cycles; if(flashPrg==0) cycles=357143; else cycles=143; for( i = 0; i < cycles; i++ ) { d1 = flashptr[offset/2]; if (d1 == data) { Delay_1_Micro_Seconds(); return STATUS_READY; } } d1 = flashptr[offset/2]; if (d1 != data) { flash_command(FLASH_RESET, 0, 0, 0); return STATUS_TIMEOUT; } } else if(flashFamily==FLASH_AMD) { do { d1 = *flashptr; /* read data */ d1 ^= *flashptr; /* read it again and see what toggled */ if (d1 == 0) /* no toggles, nothing's happening */ return STATUS_READY; } while (!(d1 & 0x20)); d1 = *flashptr; /* read data */ d1 ^= *flashptr; /* read it again and see what toggled */ if (d1 != 0) { flash_command(FLASH_RESET, 0, 0, 0); return STATUS_TIMEOUT; } } else if(flashFamily == FLASH_MXIC) { do { d2 = *flashptr; d2 ^= *flashptr; if(d2==0) // see what toggle { d1 = flashptr[offset/2]; //compare with input data if the same then output status ready signal if(d1==data) return STATUS_READY; } } while (!(*flashptr & 0x20)); d1 = flashptr[offset/2]; if (d1 != data) { flash_command(FLASH_RESET, 0, 0, 0); return STATUS_TIMEOUT; } } #endif } else if (flashFamily == FLASH_INTEL) { flashptr[0] = 0x70; /* Wait for completion */ while(!(*flashptr & 0x80)); if (*flashptr & 0x30) { flashptr[0] = 0x50; flash_command(FLASH_RESET, 0, 0, 0); return STATUS_TIMEOUT; } flashptr[0] = 0x50; flash_command(FLASH_RESET, 0, 0, 0); } return STATUS_READY; }
byte flash_init(void) { int i=0, j=0, count=0; int basecount=0L; UINT16 device_id; int flipCFIGeometry = FALSE; /* First, assume * a single 8k sector for sector 0. This is to allow * the system to perform memory mapping to the device, * even though the actual physical layout is unknown. * Once mapped in, the CFI query will produce all * relevant information. */ meminfo.addr = 0L; meminfo.areg = 0; meminfo.nsect = 1; meminfo.bank1start = 0; meminfo.bank2start = 0; meminfo.sec[0].size = 8192; meminfo.sec[0].base = 0x00000; meminfo.sec[0].bank = 1; flash_command(FLASH_RESET, 0, 0, 0); device_id = flash_get_device_id(); #ifdef DEBUGMSG //Pan.liu printk("Flash device ID:%x\n",device_id); #endif switch (device_id) { case ID_I28F160C3B: case ID_I28F320C3B: case ID_I28F160C3T: case ID_I28F320C3T: flashFamily = FLASH_INTEL; break; case ID_AM29DL800B: case ID_AM29LV800B: case ID_AM29LV400B: case ID_AM29LV160B: case ID_AM29LV320B: case ID_AM29LV320MB: case ID_AM29DL800T: case ID_AM29LV800T: case ID_AM29LV160T: case ID_AM29LV320T: case ID_AM29LV320MT: case ID_AM29LV200BT: flashFamily = FLASH_AMD; break; case ID_MX29LV320AB: case ID_MX29LV640BT: case ID_MX29LV320AT: flashFamily = FLASH_MXIC; //Pan.Liu seperate AMD and MXIC break; case ID_SST39VF200A: case ID_SST39VF400A: case ID_SST39VF800A: case ID_SST39VF1601: case ID_SST39VF3201: case ID_SST39VF3202: flashFamily = FLASH_SST; break; default: printk("Flash memory not supported! Device id = %x\n", device_id); return -1; } #ifdef DEBUGMSG //Pan.liu if(flashFamily==FLASH_INTEL) printk("INTEL FLASH FAMILY\n"); else if(flashFamily==FLASH_AMD) printk("AMD FLASH FAMILY\n"); else if(flashFamily==FLASH_SST) printk("SST FLASH FAMILY\n"); else printk("MXIC FLASH FAMILY\n"); #endif if (flash_get_cfi(&query, 0, flashFamily) == -1) { switch(device_id) { case ID_AM29LV160T: case ID_AM29LV160B: flash_get_cfi(&query, cfi_data_struct_29W160, flashFamily); break; case ID_AM29LV200BT: flash_get_cfi(&query, cfi_data_struct_29W200, flashFamily); break; case ID_AM29LV800B: flash_get_cfi(&query, cfi_data_struct_26LV800B, flashFamily); break; default: printk("CFI data structure not found. Device id = %x\n", device_id); return -1; } } // need to determine if it top or bottom boot here switch (device_id) { case ID_AM29DL800B: case ID_AM29LV800B: // case ID_AM29LV400B: case ID_AM29LV160B: case ID_AM29LV320B: case ID_MX29LV320AB: case ID_AM29LV320MB: case ID_I28F160C3B: case ID_I28F320C3B: case ID_I28F160C3T: case ID_I28F320C3T: case ID_SST39VF3201: case ID_SST39VF3202: case ID_SST39VF200A: case ID_SST39VF400A: case ID_SST39VF800A: flipCFIGeometry = FALSE; break; case ID_AM29DL800T: case ID_AM29LV800T: case ID_AM29LV160T: case ID_AM29LV320T: case ID_MX29LV320AT: case ID_AM29LV320MT: case ID_SST39VF1601: case ID_MX29LV640BT: flipCFIGeometry = TRUE; break; default: printk("Flash memory not supported! Device id = %x\n", device_id); return -1; } count=0;basecount=0L; if (!flipCFIGeometry) { for (i=0; i<query.num_erase_blocks && basecount < query.device_size; i++) { for(j=0; j<query.erase_block[i].num_sectors; j++) { meminfo.sec[count].size = (int) query.erase_block[i].sector_size; meminfo.sec[count].base = (int) basecount; basecount += (int) query.erase_block[i].sector_size; count++; } } } else { for (i = (query.num_erase_blocks - 1); i >= 0 && basecount < query.device_size; i--) { for(j=0; j<query.erase_block[i].num_sectors; j++) { meminfo.sec[count].size = (int) query.erase_block[i].sector_size; meminfo.sec[count].base = (int) basecount; basecount += (int) query.erase_block[i].sector_size; count++; } } } meminfo.nsect = count; totalSize = meminfo.sec[count-1].base + meminfo.sec[count-1].size; return (0); }