📄 ide.c
字号:
return IMAGE_TYPE_NONE;}int ide_check_image(int drive, int part, int subpart, void *pinfo) { image_infoblock_t info; if (ide_rw_block_partition(1, 0, drive, part, subpart * IMAGE_SUBPART_SECTORS, (unsigned char *) &info, 1)) return IMAGE_TYPE_NONE; if (pinfo) memcpy(pinfo, &info, sizeof info); if (strcmp(info.u.signature, IMAGE_SIGNATURE) != 0) return IMAGE_TYPE_NONE; if (strcmp(info.u.id, IMAGE_ID_KERNEL) == 0) return IMAGE_TYPE_KERNEL; else if (strcmp(info.u.id, IMAGE_ID_ROMFS) == 0) return IMAGE_TYPE_ROMFS; else return IMAGE_TYPE_NONE;}int ide_read_image(int type, int drive, int part, int subpart, unsigned char *buf){ image_infoblock_t info; int foundtype;#ifdef CONFIG_ENABLE_NETWORK extern int net_dev_down(void); net_dev_down();#endif foundtype = ide_check_image(drive, part, subpart, &info); if (type != IMAGE_TYPE_NONE && type != foundtype) return 1; return (ide_rw_block_partition(1, 0, drive, part, subpart * IMAGE_SUBPART_SECTORS + 1, buf, (info.u.len + SECTOR_SIZE - 1) / SECTOR_SIZE)) ? 1 : 0;}int ide_write_image(int type, int drive, int part, int subpart, unsigned char *buf, int len){ image_infoblock_t info; memset(&info, 0, sizeof info); strcpy(info.u.signature, IMAGE_SIGNATURE); if (type == IMAGE_TYPE_KERNEL) strcpy(info.u.id, IMAGE_ID_KERNEL); else if (type == IMAGE_TYPE_ROMFS) strcpy(info.u.id, IMAGE_ID_ROMFS); else return 1; info.u.major = 1; info.u.minor = 0; info.u.len = len; if (ide_rw_block_partition(0, 0, drive, part, subpart * IMAGE_SUBPART_SECTORS, (unsigned char *) &info, 1)) return 1; return (ide_rw_block_partition(0, 0, drive, part, subpart * IMAGE_SUBPART_SECTORS + 1, buf, (info.u.len + SECTOR_SIZE - 1) / SECTOR_SIZE)) ? 1 : 0;}//// Test functions//#ifdef CONFIG_ENABLE_FULLFUNCTIONstatic void ide_test_irq(void){ int i; uart_puts("\nIDE Interrupt Test\n"); for (i = 0; i < 10; ++i) {#ifdef CONFIG_ENABLE_IDE_BM __raw_writel(0x04, REG_BASE_HOST + IDECTRL_bmis); uart_printf(" Read %d : (%d/%d)", i, em86xx_irq_status(IRQ_IDECTRL_IDE) ? 1 : 0, em86xx_irq_status(IRQ_IDECTRL_IDEDMA) ? 1 : 0);#else uart_printf(" Read %d : (%d)", i, em86xx_gpio_read(6));#endif ide_rw_block(1, 0, 0, i, NULL, 1);#ifdef CONFIG_ENABLE_IDE_BM em86xx_irq_wait(IRQ_IDECTRL_IDE); uart_printf(" => (%d/%d)", em86xx_irq_status(IRQ_IDECTRL_IDE) ? 1 : 0, em86xx_irq_status(IRQ_IDECTRL_IDEDMA) ? 1 : 0);#else em86xx_irq_wait(IRQ_IDE); uart_printf(" => (%d)", em86xx_gpio_read(6));#endif ide_inb(IDE_STATUS_REG); em86xx_usleep(1);#ifdef CONFIG_ENABLE_IDE_BM uart_printf(" => (%d/%d)", em86xx_irq_status(IRQ_IDECTRL_IDE) ? 1 : 0, em86xx_irq_status(IRQ_IDECTRL_IDEDMA) ? 1 : 0);#else uart_printf(" => (%d)", em86xx_gpio_read(6));#endif uart_puts(" OK\n"); }}static void ide_test_pio(int drive, int partition){ int i, j, data, block; unsigned char dataout[SECTOR_CHUNKS * SECTOR_SIZE]; unsigned char datain[SECTOR_CHUNKS * SECTOR_SIZE]; unsigned char *cp; uart_puts("\nIDE PIO mode I/O test\n"); uart_printf(" Read/Write Chunks = %d sectors\n", SECTOR_CHUNKS); for (i = 0, data = 0; i < 10; ++i, ++data) { uart_printf(" Loop %d : ", i); // fill the buffer for (j = 0, cp = dataout; j < SECTOR_CHUNKS * SECTOR_SIZE; cp += 0x10, j += 0x10) memset(cp, data++, 0x10); // test loop for (j = 0, block = 0; j < 50; ++j, block += SECTOR_CHUNKS) { // write by PIO ide_rw_block_partition(0, 0, drive, partition, block, dataout, SECTOR_CHUNKS); // read by PIO memset(datain, 0, sizeof datain); ide_rw_block_partition(1, 0, drive, partition, block, datain, SECTOR_CHUNKS); // compare if (memcmp(dataout, datain, sizeof dataout) == 0) uart_putc('.'); else uart_putc('x'); } uart_puts("\n"); }}static void ide_test_readdma(int drive, int partition){ int i, j, block; unsigned char datain_dma[SECTOR_CHUNKS * SECTOR_SIZE]; unsigned char datain_pio[SECTOR_CHUNKS * SECTOR_SIZE]; uart_printf("\nIDE DMA mode read test\n"); for (i = 0; i < 10; ++i) { uart_printf(" Loop %d : ", i); for (j = 0, block = 0; j < 50; ++j, block += SECTOR_CHUNKS) { // read by DMA memset(datain_dma, 0, sizeof datain_dma); ide_rw_block_partition(1, 1, drive, partition, block, datain_dma, SECTOR_CHUNKS); // read by PIO memset(datain_pio, 0, sizeof datain_pio); ide_rw_block_partition(1, 0, drive, partition, block, datain_pio, SECTOR_CHUNKS); // compare if (memcmp(datain_dma, datain_pio, sizeof datain_dma) == 0) uart_putc('.'); else uart_putc('x'); } uart_puts("\n"); }}static void ide_test_writedma(int drive, int partition){ int i, j, data, block; unsigned char dataout[SECTOR_CHUNKS * SECTOR_SIZE]; unsigned char datain[SECTOR_CHUNKS * SECTOR_SIZE]; unsigned char *cp; uart_printf("\nIDE DMA mode write test\n"); // clear blocks by PIO memset(dataout, 0, sizeof dataout); for (i = 0, block = 0; i < 10; ++i, block += SECTOR_CHUNKS) ide_rw_block_partition(0, 0, drive, partition, block, dataout, SECTOR_CHUNKS); for (i = 0, data = 0x80, block = 0; i < 10; ++i, block += SECTOR_CHUNKS, ++data) { uart_printf(" Loop %d : ", i); // fill the buffer for (j = 0, cp = dataout; j < SECTOR_CHUNKS * SECTOR_SIZE; cp += 0x10, j += 0x10) memset(cp, data++, 0x10); // write by DMA ide_rw_block_partition(0, 1, drive, partition, block, dataout, SECTOR_CHUNKS); // read by PIO memset(datain, 0, sizeof datain); ide_rw_block_partition(1, 0, drive, partition, block, datain, SECTOR_CHUNKS); // compare uart_printf("%s\n", memcmp(datain, dataout, SECTOR_CHUNKS * SECTOR_SIZE) == 0 ? "OK" : "Fail"); }}static void ide_test_perf(int drive, int partition){ unsigned char dataout[SECTOR_CHUNKS * SECTOR_SIZE]; unsigned char datain[SECTOR_CHUNKS * SECTOR_SIZE]; int i, chksumout, chksumin; int readsector = 100 * 1024 * 2; // 100MB int part_startsector, startsector; unsigned int tick_start, tick_end; uart_puts("\nIDE performance test\n"); uart_printf(" Sectors per each transfer = %d\n", SECTOR_CHUNKS); uart_printf(" Transfer %dMB\n", readsector >> 11); if (partition < 0 || partition >= g_ideinfo[drive].npart || !g_ideinfo[drive].part[partition].valid) return; part_startsector = g_ideinfo[drive].part[partition].start_sector; for (i = 0, chksumout = 0; i < SECTOR_CHUNKS * SECTOR_SIZE / sizeof(int); ++i) { ((int *) dataout)[i] = i; chksumout += i; } // writing uart_printf("Writing (PIO) : "); tick_start = timer_getticks(); for (startsector = 0; startsector < readsector; startsector += SECTOR_CHUNKS) { ide_rw_block(0, 0, drive, part_startsector + startsector, dataout, SECTOR_CHUNKS); if ((startsector & 0x00001fff) == 0) uart_putc('.'); } tick_end = timer_getticks(); uart_printf(" done (%d ticks)\n", tick_end - tick_start); // reading uart_printf("Reading (DMA) : "); tick_start = timer_getticks(); for (startsector = 0; startsector < readsector; startsector += SECTOR_CHUNKS) { ide_rw_dma_block(1, drive, part_startsector + startsector, datain, SECTOR_CHUNKS,NULL); if ((startsector & 0x00001fff) == 0) uart_putc('.'); for (i = 0, chksumin = 0; i < SECTOR_CHUNKS * SECTOR_SIZE / sizeof(int); ++i) chksumin += ((int *) datain)[i]; if (chksumin != chksumout) uart_putc('x'); } tick_end = timer_getticks(); uart_printf(" done (%d ticks)\n", tick_end - tick_start); // writing uart_printf("Writing (DMA) : "); tick_start = timer_getticks(); for (startsector = 0; startsector < readsector; startsector += SECTOR_CHUNKS) { ide_rw_dma_block(0, drive, part_startsector + startsector, dataout, SECTOR_CHUNKS,NULL); if ((startsector & 0x00001fff) == 0) uart_putc('.'); } tick_end = timer_getticks(); uart_printf(" done (%d ticks)\n", tick_end - tick_start); // reading uart_printf("Reading (PIO) : "); tick_start = timer_getticks(); for (startsector = 0; startsector < readsector; startsector += SECTOR_CHUNKS) { ide_rw_block(1, 0, drive, part_startsector + startsector, datain, SECTOR_CHUNKS); if ((startsector & 0x00001fff) == 0) uart_putc('.'); for (i = 0, chksumin = 0; i < SECTOR_CHUNKS * SECTOR_SIZE / sizeof(int); ++i) chksumin += ((int *) datain)[i]; if (chksumin != chksumout) uart_putc('x'); } tick_end = timer_getticks(); uart_printf(" done (%d ticks)\n", tick_end - tick_start);}void ide_test(int argc, char *argv[], int drive, int partition){ int doall = (argv[0] && strcmp(argv[0], "all") == 0) ? 1 : 0; if (argv[0] == NULL) { uart_puts("IDE Test :\n"); uart_puts(" Available commands : " "irq " "pio " "readdma " "writedma " "perf " "\n"); } else { if (doall || strcmp(argv[0], "irq") == 0) ide_test_irq(); if (doall) PAUSE if (doall || strcmp(argv[0], "pio") == 0) ide_test_pio(drive, partition); if (doall) PAUSE if (doall || strcmp(argv[0], "readdma") == 0) ide_test_readdma(drive, partition); if (doall) PAUSE if (doall || strcmp(argv[0], "writedma") == 0) ide_test_writedma(drive, partition); if (doall) PAUSE if (doall || strcmp(argv[0], "perf") == 0) ide_test_perf(drive, partition); }}void ide_perf(unsigned int tblk, unsigned int sblk){#define TEST_CHUNKS 32//16#define AVERNUM 3 unsigned char dataout[TEST_CHUNKS * SECTOR_SIZE]; unsigned char datain[TEST_CHUNKS * SECTOR_SIZE]; int i, chksumout, chksumin; int readsector = 64*2; //100 * 1024 * 2; // 100MB int subsector = TEST_CHUNKS; int part_startsector, startsector; unsigned int timerw, timems[10], timer_start, timer_end; unsigned int timerw_sect, timems_sect[10]; int drive=0; unsigned int raterw,raterwd; if(tblk) { readsector = tblk; if(sblk) subsector = sblk; } if(subsector > TEST_CHUNKS || subsector > readsector) { subsector = (TEST_CHUNKS >= readsector)? readsector:TEST_CHUNKS; uart_printf("Max sectors per each transfer is %d\n",subsector); } uart_puts("\nIDE performance test\n"); uart_printf(" Total transfer %d sectors(%dKB).", readsector, readsector >> 1); uart_printf(" Sectors per each transfer %d\n", subsector); part_startsector = g_ideinfo[drive].part[0].start_sector; memset(datain,0,subsector * SECTOR_SIZE); for (i = 0, chksumout = 0; i < subsector * SECTOR_SIZE / sizeof(int); ++i) { ((int *) dataout)[i] = i; chksumout += ((int *) dataout)[i]; } // writing uart_printf("Writing (DMA) : \n"); timerw = timerw_sect = 0; for(i=0;i<AVERNUM;i++) { timer_start = __raw_readl(REG_BASE_system_block + SYS_xtal_in_cnt); for (startsector = 0; startsector < readsector; startsector += subsector) ide_rw_dma_block(0, drive, part_startsector + startsector, dataout, subsector, &timems_sect[i]); timer_end = __raw_readl(REG_BASE_system_block + SYS_xtal_in_cnt); timems[i] = (timer_end > timer_start ? (timer_end-timer_start) : ((0xffffffff-timer_start)+timer_end+1)) / 27; uart_printf(" total read time %d us, %d sectors %d us\n", timems[i],subsector, timems_sect[i]); //uart_printf("start=0x%x, end=0x%x, sta-end=0x%x, end-sta=0x%x,\n",timer_start,timer_end,timer_start-timer_end,timer_end-timer_start); timerw += timems[i]; timerw_sect += timems_sect[i]; } timerw /= AVERNUM; timerw_sect /= AVERNUM; uart_printf("Total average write time %d.%d ms, ", timerw/1000, timerw%1000); uart_printf("%d sectors %d.%d ms\n", subsector, timerw_sect/1000, timerw_sect%1000); raterw = idivide(readsector*SECTOR_SIZE*8, timerw); raterwd = idivide(readsector*SECTOR_SIZE*8 *100, timerw); uart_printf("Write Data Transfer Rate : %d.%d Mb/sec\n\n",raterw, raterwd%100); // reading uart_printf("Reading (DMA) : \n"); timerw = timerw_sect = 0; for(i=0;i<AVERNUM;i++) { timer_start = __raw_readl(REG_BASE_system_block + SYS_xtal_in_cnt); for (startsector = 0; startsector < readsector; startsector += subsector) ide_rw_dma_block(1, drive, part_startsector + startsector, datain, subsector, &timems_sect[i]); timer_end = __raw_readl(REG_BASE_system_block + SYS_xtal_in_cnt); timems[i] = (timer_end > timer_start ? (timer_end-timer_start) : ((0xffffffff-timer_start)+timer_end+1)) / 27; uart_printf(" total read time %d us, %d sectors %d us\n", timems[i],subsector, timems_sect[i]); timerw += timems[i]; timerw_sect += timems_sect[i]; } timerw /= AVERNUM; timerw_sect /= AVERNUM; uart_printf("Total average read time %d.%d ms, ", timerw/1000, timerw%1000); uart_printf("%d sectors %d.%d ms\n", subsector, timerw_sect/1000, timerw_sect%1000); raterw = idivide(readsector*SECTOR_SIZE*8, timerw); raterwd = idivide(readsector*SECTOR_SIZE*8 *100, timerw); uart_printf("Read Data Transfer Rate : %d.%d Mb/sec\n\n",raterw, raterwd%100); for (i = 0, chksumin = 0; i < subsector * SECTOR_SIZE / sizeof(int); ++i) chksumin += ((int *) datain)[i]; if (chksumin != chksumout) { uart_printf(" Last %d block check sum FAIL!\n",subsector); uart_printf(" chksumin=0x%x, chksumout=0x%x\n",chksumin,chksumout); }}#endifint ide_cdrom_eject(int drive, unsigned long oldkey){ int d;#ifdef CONFIG_ENABLE_FIP unsigned long key;#endif if ((d = ide_found(IDE_ATAPI)) == 0) { ide_probe(1 << drive, 0); d = ide_found(IDE_ATAPI); } if (d != 0) {#ifdef CONFIG_ENABLE_FIP fip_write_text(0, (cdrom0_tray_state == 0) ? "OPENING" : "CLOSING", FIP_CENTER);#endif atapi_eject(drive, cdrom0_tray_state); cdrom0_tray_state = !cdrom0_tray_state;#ifdef CONFIG_ENABLE_FIP /* Make sure the key has been released */ while ((key = fip_readkey()) == oldkey) em86xx_msleep(100); /* Sleep 100msec */#else em86xx_msleep(5000); /* Sleep 5sec */#endif#ifdef CONFIG_ENABLE_FIP if (fiptext == NULL) fip_clear(); else fip_write_text(0, fiptext, FIP_CENTER);#endif } return((d != 0) ? 1 : 0);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -