📄 ide.c
字号:
for (tries=0; tries<(us/10); tries++) { status = IDE_CMD_REG8(ide->cmd_base, IDE_REG_STATUS); if (!(status & IDE_STAT_BSY)) { if (status & IDE_STAT_DRQ) return 1; } hal_delay_us(10); } printf("disk(%x) : DRQ timeout!\n",ide->ide_id); return 0;}/*----------------------------------------------------------------------* ide_wait_busy*----------------------------------------------------------------------*/static int ide_wait_busy(IDE_INFO_T *ide, UINT32 us){ UINT8 status; UINT32 tries; for (tries=0; tries < (us/10); tries++) { hal_delay_us(10); status = IDE_CMD_REG8(ide->cmd_base, IDE_REG_STATUS); if ((status & IDE_STAT_BSY) == 0) return 1; } return 0; }/*----------------------------------------------------------------------* ide_ident*----------------------------------------------------------------------*/static int ide_ident(IDE_INFO_T *ide, int dev, UINT16 *buf){ int i; UINT32 *data; IDE_CMD_REG8(ide->cmd_base, IDE_REG_DEVICE) = dev << 4; IDE_CMD_REG8(ide->cmd_base, IDE_REG_COMMAND) = 0xEC; hal_delay_us(50000); if (!ide_wait_drq(ide, 5000000)) { //printf("%s: NO DRQ for IDE-%d\n", // __FUNCTION__, ide->ide_id); return 0; } data = (UINT32 *)buf; for (i = 0; i < (IDE_SECTOR_SIZE / sizeof(*data)); i++, data++) *data = IDE_CMD_REG32(ide->cmd_base, IDE_REG_DATA); return 1;}/*----------------------------------------------------------------------* ide_find_partitions*----------------------------------------------------------------------*/static int ide_find_partitions(IDE_DISK_T *disk){ UINT16 buf[IDE_SECTOR_SIZE / sizeof(UINT16)]; UINT16 magic; IDE_PART_T *part; int i, found = 0; UINT32 total_bytes; IDE_MBR_T *mbr; UINT32 s, n; // read Master Boot Record if ((*disk->read)(disk, 0, 1, buf) <= 0) return 0; // Read MBR magic = ide_get_uint16((char *)buf + MBR_MAGIC_OFFSET); if (magic != MBR_MAGIC) { printf("Unknown partition type!\n"); return 0; } mbr = (IDE_MBR_T *)((char *)buf + MBR_PTABLE_OFFSET); for (i = 0; i < IDE_MAX_PARTS_PER_DISK && ide_part_num<IDE_MAX_PARTITIONS; i++, mbr++) { if (mbr->sys_ind == 0) continue; printf("Partition %d: ", i+1); switch (mbr->sys_ind) { case IDE_PART_LINUX_MINIX: printf("Linux/MINIX"); break; case IDE_PART_LINUX_SWAP: printf("Linux Swap"); break; case IDE_PART_LINUX: printf("Linux"); break; case IDE_PART_LINUX_EXTENDED: printf("Linux Extended"); break; case 0x01: printf("FAT12"); break; case 0x04: printf("FAT16 <32M"); break; case 0x05: printf("Extended"); break; case 0x06: printf("FAT16"); break; case 0x07: printf("HPFS/NTFS"); break; case 0x0b: printf("FAT32"); break; case 0x0c: printf("FAT32"); break; case 0x0e: printf("FAT16"); break; case 0x0f: printf("Win95 Ext'd"); break; default: printf("(0x%02X)", mbr->sys_ind); break; } if (mbr->sys_ind != IDE_PART_LINUX) { printf("\n"); continue; } s = ide_get_uint32((char *)(&mbr->start_sect)); n = ide_get_uint32((char *)(&mbr->sector_num)); if (s==0 || n ==0) continue; part = (IDE_PART_T *)&ide_partitions[ide_part_num]; part->present = 1; part->part_id = i; part->disk = disk; part->start_sector = s; part->sector_num = n; part->os = mbr->sys_ind; part->bootflag = mbr->boot_ind; part->read = (void *)ide_disk_read_sectors; part->write = (void *)ide_disk_write_sectors; ide_part_num++; disk->part_num++; found++; printf(" %lld Sectors ", part->sector_num); // total_bytes = part->sector_num * IDE_SECTOR_SIZE / 1024 / 1024; total_bytes = (UINT64)part->sector_num / (1000000 / IDE_SECTOR_SIZE); if (total_bytes > 1000) { int Gb, Mb; Gb = total_bytes / 1000; Mb = total_bytes % 1000; printf("%d GB %d MB\n", Gb, Mb); } else { printf("%d MB\n", total_bytes); } } return found;}/*----------------------------------------------------------------------* ide_disk_read_sectors*----------------------------------------------------------------------*/static int ide_disk_read_sectors(IDE_DISK_T *disk, UINT64 start, UINT8 count, UINT16 *buf){ int i, j; UINT32 *p; unsigned int cmd_base; if(!ide_wait_busy(disk->ide, 2000000)) { printf("IDE %d is BUSY!\n", disk->ide->ide_id); return 0; } cmd_base = disk->ide->cmd_base; if (!disk->lba_48) { IDE_CMD_REG8(cmd_base, IDE_REG_COUNT) = count; IDE_CMD_REG8(cmd_base, IDE_REG_LBALOW) = start & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAMID) = (start >> 8) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAHI) = (start >> 16) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_DEVICE) = ((start >> 24) & 0xf) | (disk->drive_id << 4) | 0x40; IDE_CMD_REG8(cmd_base, IDE_REG_COMMAND) = 0x20; } else { IDE_CMD_REG8(cmd_base, IDE_REG_COUNT) = (count >> 8) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_COUNT) = count & 0xff; // high 24 bits of LBA IDE_CMD_REG8(cmd_base, IDE_REG_LBALOW) = (start >> 24) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAMID) = (start >> 32) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAHI) = (start >> 40) & 0xff; // low 24 bits of LBA IDE_CMD_REG8(cmd_base, IDE_REG_LBALOW) = start & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAMID) = (start >> 8) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAHI) = (start >> 16) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_DEVICE) = (disk->drive_id << 4) | 0x40; IDE_CMD_REG8(cmd_base, IDE_REG_COMMAND) = 0x24; } p = (UINT32 *)buf; for(i = 0; i < count; i++) { if (!ide_wait_drq(disk->ide, 5000000)) { printf("%s: NO DRQ for ide%d, device %d LBA %u\n", __FUNCTION__, disk->ide->ide_id, disk->drive_id, start); return 0; } for (j = 0; j < (IDE_SECTOR_SIZE / sizeof(*p)); j++, p++) *p = IDE_CMD_REG32(cmd_base, IDE_REG_DATA); } return 1;}/*----------------------------------------------------------------------* ide_disk_read_sectors*----------------------------------------------------------------------*/static int ide_disk_write_sectors(IDE_DISK_T *disk, UINT64 start, UINT32 bytes, UINT8 *buf){ int i, len; UINT32 data; UINT32 *cp; unsigned int cmd_base; if(!ide_wait_busy(disk->ide, 2000000)) { printf("IDE %d is BUSY!\n", disk->ide->ide_id); return 0; } cmd_base = disk->ide->cmd_base; if (!disk->lba_48) { IDE_CMD_REG8(cmd_base, IDE_REG_COUNT) = 1; IDE_CMD_REG8(cmd_base, IDE_REG_LBALOW) = start & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAMID) = (start >> 8) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAHI) = (start >> 16) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_DEVICE) = ((start >> 24) & 0xf) | (disk->drive_id << 4) | 0x40; IDE_CMD_REG8(cmd_base, IDE_REG_COMMAND) = 0x30; } else { IDE_CMD_REG8(cmd_base, IDE_REG_COUNT) = 0; // high 8 bits IDE_CMD_REG8(cmd_base, IDE_REG_COUNT) = 1; // low 8 bits // high 24 bits of LBA IDE_CMD_REG8(cmd_base, IDE_REG_LBALOW) = (start >> 24) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAMID) = (start >> 32) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAHI) = (start >> 40) & 0xff; // low 24 bits of LBA IDE_CMD_REG8(cmd_base, IDE_REG_LBALOW) = start & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAMID) = (start >> 8) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_LBAHI) = (start >> 16) & 0xff; IDE_CMD_REG8(cmd_base, IDE_REG_DEVICE) = (disk->drive_id << 4) | 0x40; IDE_CMD_REG8(cmd_base, IDE_REG_COMMAND) = 0x34; } if (!ide_wait_drq(disk->ide, 5000000)) { printf("%s: NO DRQ for ide%d, device %d.\n", __FUNCTION__, disk->ide->ide_id, disk->drive_id); return 0; } cp = (UINT32 *)buf; for (i = 0, len=0 ; i < (IDE_SECTOR_SIZE / sizeof(*cp)); i++) { if (len < bytes) { IDE_CMD_REG32(cmd_base, IDE_REG_DATA) = *cp; cp++; } else IDE_CMD_REG32(cmd_base, IDE_REG_DATA) = 0; len += sizeof(UINT32); } return 1;}#define IDE_TEST_RW_SIZE 512#define IDE_TEST_RW_SECTOR 0x1000000/*----------------------------------------------------------------------* ide_ui_test_cmd* CLI command for IDE* Write 512-byte data (1-sector) to sector 0x1000000, then* Read back and verify*----------------------------------------------------------------------*/void ide_ui_test_cmd(char argc, char *argv[]){ char *buf1, *buf2, *cp; int i; if (ide_partitions[0].present == 0) { printf("No active partition!\n"); return; } buf1 = (char *)malloc(IDE_TEST_RW_SIZE); if (!buf1) { printf("No free memeory!\n"); return; } buf2 = (char *)malloc(IDE_TEST_RW_SIZE); if (!buf2) { free(buf1); printf("No free memeory!\n"); return; } cp = buf1; for (i=0; i<IDE_TEST_RW_SIZE; i++) *cp++ = i; ide_disk_write_sectors(ide_partitions[0].disk, (UINT64)IDE_TEST_RW_SECTOR, (UINT32)IDE_TEST_RW_SIZE, buf1); ide_disk_read_sectors(ide_partitions[0].disk, (UINT64)IDE_TEST_RW_SECTOR, (UINT8)(IDE_TEST_RW_SIZE/IDE_SECTOR_SIZE), (UINT16 *)buf2); for (i=0; i<IDE_TEST_RW_SIZE; i++) { if (buf1[i] != buf2[i]) { printf("Content error!\n"); free(buf1); free(buf2); return; } } printf("Content correct!\n"); free(buf1); free(buf2); return;}#endif // BOARD_SUPPORT_IDE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -