📄 ide.c
字号:
if (dma) return ide_rw_dma_block(read, drive, g_ideinfo[drive].part[partition].start_sector + block, buf, nsector); else return ide_rw_block(read, 0, drive, g_ideinfo[drive].part[partition].start_sector + block, buf, nsector);}//// kernel image or filesystem in IDE device//int ide_probe_image(int drive, int *ppart, void *pinfo) { int i; int type; for (i = 0; i < g_ideinfo[drive].npart; ++i) { if (g_ideinfo[drive].part[i].valid && (type = ide_check_image(drive, i, 0, pinfo)) != IMAGE_TYPE_NONE) { *ppart = i; return type; } } 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){#define TEST_CHUNKS 64 unsigned char dataout[TEST_CHUNKS * SECTOR_SIZE]; unsigned char datain[TEST_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", TEST_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 < TEST_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 += TEST_CHUNKS) { ide_rw_block(0, 0, drive, part_startsector + startsector, dataout, TEST_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 += TEST_CHUNKS) { ide_rw_dma_block(1, drive, part_startsector + startsector, datain, TEST_CHUNKS); if ((startsector & 0x00001fff) == 0) uart_putc('.'); for (i = 0, chksumin = 0; i < TEST_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 += TEST_CHUNKS) { ide_rw_dma_block(0, drive, part_startsector + startsector, dataout, TEST_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 (PIO) : "); tick_start = timer_getticks(); for (startsector = 0; startsector < readsector; startsector += TEST_CHUNKS) { ide_rw_block(1, 0, drive, part_startsector + startsector, datain, TEST_CHUNKS); if ((startsector & 0x00001fff) == 0) uart_putc('.'); for (i = 0, chksumin = 0; i < TEST_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); }}#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 + -