⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ide.c

📁 某个ARM9板子的实际bootloader 对裁剪
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** 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 + -