📄 ide.c
字号:
/***************************************************************************** Copyright Storlink Corp 2005. All rights reserved. *--------------------------------------------------------------------------* Name : ide.c* Description : * Handle IDE functions** History** Date Writer Description* ----------- ----------- -------------------------------------------------* 09/07/2005 Gary Chen Create*****************************************************************************/#include <define.h>#include <board_config.h>#include <sl2312.h>#ifdef BOARD_SUPPORT_IDE#include "ide.h"#ifdef BOARD_SUPPORT_IDE // backward compatiable#if !defined(BOARD_SUPPORT_IDE0) && !defined(BOARD_SUPPORT_IDE1) #define BOARD_SUPPORT_IDE0 0 #define BOARD_SUPPORT_IDE1 1#elif !(defined(BOARD_SUPPORT_IDE0) && defined(BOARD_SUPPORT_IDE1)) #error "Must define BOARD_SUPPORT_IDE0 and BOARD_SUPPORT_IDE1 in board_config.h"#endif#endif // BOARD_SUPPORT_IDE#define IDE_DETECT_TIME (80)//(180) // 180 secondsIDE_INFO_T ide_info[IDE_CONTROLLERS];IDE_PART_T ide_partitions[IDE_MAX_PARTITIONS];int ide_part_num;static int ide_detect(IDE_INFO_T *ide);static int ide_reset(IDE_INFO_T *ide);static int ide_init_disks(IDE_INFO_T *ide);static int ide_ident(IDE_INFO_T *ide, int dev, UINT16 *buf);static int ide_find_partitions(IDE_DISK_T *disk);static int ide_disk_read_sectors(IDE_DISK_T *disk, UINT64 start, UINT8 count, UINT16 *buf);static int ide_disk_write_sectors(IDE_DISK_T *disk, UINT64 start, UINT32 bytes, UINT8 *buf);static int ide_wait_busy(IDE_INFO_T *ide, UINT32 us);extern void hal_delay_us(UINT32 us);extern int uart_scanc(unsigned char *c);int ide_initialized = 0;/*----------------------------------------------------------------------* ide_init*----------------------------------------------------------------------*/int ide_init(void){ IDE_INFO_T *ide; int i, total, wait_cnt, rc; UINT64 ticks; unsigned char c; if (ide_initialized) return; //REG32(SL2312_SATA_BASE + 0x18) = 0x3; //mode 2 REG32(SL2312_SATA_BASE + 0x1c) = 0x3; //mode 3 printf("Waiting for disk ready & detect ...\n"); ticks = sys_get_ticks(); sys_sleep(BOARD_TPS * 5); ide_part_num = 0; total = wait_cnt = 0; while (total == 0 && wait_cnt++ < IDE_DETECT_TIME) // 20 seconds { if ((sys_get_ticks() - ticks) > (IDE_DETECT_TIME * BOARD_TPS)) { printf("Timeout!\n"); return 0; } hal_delay_us(1000000); if (uart_scanc(&c) && c == BOOT_BREAK_KEY) { printf("Aborted by user!\n"); return 0; } for (i=0; i<IDE_CONTROLLERS; i++, ide++) { ide = (IDE_INFO_T *)&ide_info[i]; memset((void *)ide, 0, sizeof(IDE_INFO_T)); ide->ide_id = i; if (i==0) {#if (BOARD_SUPPORT_IDE0==0) continue;#endif ide->cmd_base = (unsigned int)SL2312_IDE0_BASE + 0x20; ide->ctrl_base = (unsigned int)SL2312_IDE0_BASE + 0x36; } else {#if (BOARD_SUPPORT_IDE1==0) continue;#endif ide->cmd_base = (unsigned int)SL2312_IDE1_BASE + 0x20; ide->ctrl_base = (unsigned int)SL2312_IDE1_BASE + 0x36; } /* // detect attached IDE drive rc = ide_detect(ide); if ( rc == 0) { //printf("No IDE drive is found!"); continue; } else if (rc == -1) { printf("Aborted by user!\n"); return 0; } */ // Reset IDE controller rc = ide_reset(ide); if (rc == -1) { printf("Aborted by user!\n"); return 0; } //else if (!rc) //{ // // printf("Failed to reset IDE controller!\n"); // continue; //} if (ide_init_disks(ide) == 0) { // printf("Failed to init IDE disks!\n"); continue; } ide->present = 1; total++; break; } } if (!total) printf("No IDE drive is found!"); ide_initialized = total; return total;}/*----------------------------------------------------------------------* ide_detect* return total active drive*----------------------------------------------------------------------*/static int ide_detect(IDE_INFO_T *ide){ UINT8 sel, val ,status , signlow, signhigh; int i, total, x; static int retry=0; unsigned char c; total = 0; for (x=0; x<(IDE_DETECT_TIME * 1); x++) { for (i = 0; i <IDE_MAX_DISKS; i++) { if (ide->disk[i].present) continue; sel = (i << 4) | 0xA0; hal_delay_us(100000); IDE_CMD_REG8(ide->cmd_base, IDE_REG_DEVICE) = 0; IDE_CMD_REG8(ide->cmd_base, IDE_REG_DEVICE) = sel; hal_delay_us(100000); val =0; val = IDE_CMD_REG8(ide->cmd_base, IDE_REG_DEVICE); ide->disk[i].present = 0; //printf("val: %x sel: %x\n",val,sel); status = IDE_CMD_REG8(ide->cmd_base, 0x16); if ((status == 0xff)) continue; //return DEVICE_TYPE_NONE; IDE_CMD_REG8(ide->cmd_base, IDE_REG_COUNT) = 0xa5; val = IDE_CMD_REG8(ide->cmd_base, IDE_REG_COUNT); if (val != 0xa5) continue; //return DEVICE_TYPE_NONE; signlow = IDE_CMD_REG8(ide->cmd_base, IDE_REG_LBAMID); signhigh = IDE_CMD_REG8(ide->cmd_base, IDE_REG_LBAHI); if ((signlow == 0x14) && (signhigh == 0xeb)) continue; //return DEVICE_TYPE_CDROM; else { //return DEVICE_TYPE_HDD; ide->disk[i].present = 1; printf("IDE %d Detect disk %d\n", ide->ide_id, i); total++; } /* //if ((val&0xa0) == 0xA0)//sel) //{ if (i) { IDE_CMD_REG8(ide->cmd_base, IDE_REG_DEVICE) = 0; } } */ if (uart_scanc(&c) && c == BOOT_BREAK_KEY) { return -1; } } if (ide->disk[1].present) break; } retry = 1; return total;}/*----------------------------------------------------------------------* ide_reset*----------------------------------------------------------------------*/static int ide_reset(IDE_INFO_T *ide){ UINT8 status; int i; IDE_CTRL_REG8(ide->ctrl_base) |= 0x4; // reset asserted hal_delay_us(5000); IDE_CTRL_REG8(ide->ctrl_base) &= ~0x4; // reset cleared hal_delay_us(50000); // wait 10 seconds for (i = 0; i < 100; ++i) { unsigned char c; hal_delay_us(100000); status = IDE_CMD_REG8(ide->cmd_base, IDE_REG_STATUS); //if (!(status & IDE_STAT_BSY) && (status & IDE_STAT_DRDY)) if (!(status & IDE_STAT_BSY) ) return 1; if (uart_scanc(&c) && c == BOOT_BREAK_KEY) { // printf("Aborted by user!\n"); return -1; } } //if (!(status & IDE_STAT_BSY)) // return 0; return 0;}/*----------------------------------------------------------------------* ide_init_disks*----------------------------------------------------------------------*/static int ide_init_disks(IDE_INFO_T *ide){ int i, total; IDE_DISK_T *disk; UINT32 buf[IDE_SECTOR_SIZE/sizeof(UINT32)]; UINT32 total_bytes; UINT16 data16; int rc; int found; rc = ide_detect(ide); total = 0; disk = (IDE_DISK_T *)&ide->disk[0]; for (i = 0; i < IDE_MAX_DISKS; i++, disk++) { found = 0; disk->drive_id = i; disk->flags = 0; disk->ide = ide; disk->read = (void *)ide_disk_read_sectors; disk->write = (void *)ide_disk_write_sectors; if (!disk->present) continue; if (ide_ident(ide, i, (UINT16 *)buf) <= 0) { disk->flags = 0; disk->present = 0; continue; // can't identify device } total ++; disk->kind = DISK_IDE_HD; // until proven otherwise disk->flags |= IDE_DEV_PRESENT; data16 = REG16((char *)buf + IDE_CMD_SET); disk->lba_48 = (data16 >> 10) & 1; if (disk->lba_48) disk->sector_num = (UINT64)(REG16((char *)buf + IDE_LBA_48)) + ((UINT64)(REG16((char *)buf + IDE_LBA_48 + 2)) << 16) + ((UINT64)(REG16((char *)buf + IDE_LBA_48 + 4)) << 32) + ((UINT64)(REG16((char *)buf + IDE_LBA_48 + 6)) << 48); else disk->sector_num = (UINT64)(REG32((char *)buf + IDE_DEVID_LBA_CAPACITY)); // total_bytes = disk->sector_num * IDE_SECTOR_SIZE / 1024 / 1024; total_bytes = disk->sector_num / (1000000 / IDE_SECTOR_SIZE);#if 0 printf("Disk Drive: IDE-%d, Device-%d, %lld Sectors IDE_CMD_SET = 0x%04X ", ide->ide_id, disk->drive_id, disk->sector_num, data16);#else printf("Disk Drive: IDE-%d, Device-%d, %lld Sectors ", ide->ide_id, disk->drive_id, disk->sector_num);#endif if (total_bytes > 1000) { UINT32 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); } found = ide_find_partitions(disk); if(found) break; } ide->disk_num = total; return total;}/*----------------------------------------------------------------------* ide_wait_drq*----------------------------------------------------------------------*/static int ide_wait_drq(IDE_INFO_T *ide, UINT32 us){ UINT8 status; UINT32 tries;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -