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

📄 ide.c

📁 Hermit-at-1.1.3,一款bootloader
💻 C
字号:
/* * Copyright (c) 2006 Atmark Techno, Inc.  All Rights Reserved. */#include <target/io.h>#define MULTIPLE                 3#define TIMEOUT                  50000#define IDE_DATA                 0x62000000#define IDE_ERROR                0x62000002#define IDE_FEAUTURES            0x62000002#define IDE_SECTOR_COUNT         0x62000004#define IDE_SECTOR_NUMBER        0x62000006#define IDE_SECTOR_CYLINDER_LOW  0x62000008#define IDE_SECTOR_CYLINDER_HIGH 0x6200000a#define IDE_DEVICE_HEAD          0x6200000c#define IDE_STATUS               0x6200000e#define IDE_COMMAND              0x6200000e#define IDE_ALTERNATE_STATUS     0x6200002c#define IDE_DEVICE_CONTROL       0x6200002c#define IDE_STATUS_BUSY          0x80#define IDE_STATUS_DRDY          0x40#define IDE_STATUS_DRQ           0x08#define IDE_STATUS_ERR           0x01#define IDE_COMMAND_READ_SECTORS 0x20#define IDE_COMMAND_IDLE         0xe3#define IDE_COMMAND_IDENTIFY     0xec#define IDE_DEVICE_CONTROL_SRST  0x04#define IDE_DEVICE_CONTROL_NIEN  0x02#define IDE_LBA                  0x40#define ide_inb(port)    (*(volatile unsigned char *)(port))#define ide_inw(port)    (*(volatile unsigned short *)(port))#define ide_outb(b,port) (*(volatile unsigned char *)(port)=(b))#define ide_outw(w,port) (*(volatile unsigned short *)(port)=(w))#define delay(count) {int d;for(d=0;d<(count*MULTIPLE);d++);}static int wait_nbusy_ndrq (void){  int i;    for (i = 0; i < TIMEOUT && (ide_inb (IDE_ALTERNATE_STATUS) &			      (IDE_STATUS_BUSY | IDE_STATUS_DRQ)); i++) {    delay (100);  }  if (i >= TIMEOUT) {    return -1;  }    return 0;}static int wait_nbusy (void){  int i;    for (i = 0; i < TIMEOUT && (ide_inb (IDE_ALTERNATE_STATUS) &			      IDE_STATUS_BUSY); i++) {    delay (100);  }  if (i >= TIMEOUT) {    return -1;  }    return 0;}static int wait_ready (void){  int i;    for (i = 0; i < TIMEOUT && !(ide_inb (IDE_ALTERNATE_STATUS) &			      IDE_STATUS_DRDY); i++) {    delay (100);  }  if (i >= TIMEOUT) {    return -1;  }    return 0;}static int ide_reset (void){  int ret;  unsigned char error;    ide_outb (IDE_DEVICE_CONTROL_SRST | IDE_DEVICE_CONTROL_NIEN,	    IDE_DEVICE_CONTROL);  delay (40000);    ide_outb (IDE_DEVICE_CONTROL_NIEN, IDE_DEVICE_CONTROL);  delay (40000);    ret = wait_nbusy ();  if (ret) {    return ret;  }  error = ide_inb (IDE_ERROR);  if (error != 0 && error != 1) {    return -1;  }    return 0;}static int ide_device_selection (int dev){  int ret;    ret = wait_nbusy_ndrq ();  if (ret) {    return ret;  }    ide_outb (IDE_DEVICE_CONTROL_NIEN, IDE_DEVICE_CONTROL);  ide_outb (dev << 4, IDE_DEVICE_HEAD);  delay (100);    return wait_nbusy_ndrq ();}static int ide_register_check (void){  ide_outb (0x55, IDE_SECTOR_CYLINDER_LOW);  ide_outb (0xaa, IDE_SECTOR_CYLINDER_HIGH);  if (ide_inb (IDE_SECTOR_CYLINDER_LOW) != 0x55) {    return -1;  }  if (ide_inb (IDE_SECTOR_CYLINDER_HIGH) != 0xaa) {    return -1;  }    return 0;}static int ide_get_data (unsigned char *buf, int count){  int            ret, i;  unsigned short data;    while (count--) {    ret = wait_nbusy ();    if (ret) {      return ret;    }        if (ide_inb (IDE_ALTERNATE_STATUS) & IDE_STATUS_ERR) {      return -1;    }    for (i = 0; i < 256; i++) {      data = ide_inw (IDE_DATA);      *buf++ = data & 0xff;      *buf++ = data >> 8;    }  }    return 0;}static void ide_fix_string (unsigned char *dest, unsigned char *src, int num){  int i;    for (i = 0; i < num; i+= 2) {    *dest++ = *(src + 1);    *dest++ = *src;    src += 2;  }  while (*--dest == (' '))    ;  ++dest;  *dest++ = ' ';  *dest++ = '\0';}static int ide_identify_device (int dev){  int            ret;  unsigned short buf[256];  unsigned char  name[42];    ret = ide_device_selection (dev);  if (ret) {    return ret;  }    ret = wait_ready ();  if (ret) {    return ret;  }    ide_outb (IDE_COMMAND_IDENTIFY, IDE_COMMAND);  delay (100);    ret = ide_get_data ((unsigned char *)buf, 1);  if (ret) {    return ret;  }    if (*buf & 0x04) {    return -1;  }    hprintf ("Disk drive detected: ");  ide_fix_string (name, (unsigned char *)&buf[27], 40);  hprintf ("%s", name);  ide_fix_string (name, (unsigned char *)&buf[23], 8);  hprintf ("%s", name);  ide_fix_string (name, (unsigned char *)&buf[10], 20);  hprintf ("%s", name);  hprintf ("\n");    return 0;}static int ide_idle (int dev){  int ret;    ret = ide_device_selection (0);  if (ret) {    return ret;  }    ret = wait_ready ();  if (ret) {    return ret;  }    ide_outb (0x00, IDE_SECTOR_COUNT);  ide_outb (IDE_COMMAND_IDLE, IDE_COMMAND);  delay (100);    return wait_nbusy_ndrq ();}int ide_detect_devices (){  int ret;  ret = ide_reset ();  if (ret) {    return ret;  }    ret = ide_device_selection (0);  if (ret) {    return ret;  }    ret = ide_register_check ();  if (ret) {    return ret;  }    return ide_identify_device (0);}int ide_startup_devices (void){  return ide_idle (0);}int ide_read_sectors (int dev, unsigned long lba,		      unsigned char *buf, int count){  int ret;    ret = ide_device_selection (dev);  if (ret) {    return ret;  }    ret = wait_ready ();  if (ret) {    return ret;  }    ide_outb (count, IDE_SECTOR_COUNT);  ide_outb (lba & 0xff, IDE_SECTOR_NUMBER);  ide_outb ((lba & 0xff00) >> 8, IDE_SECTOR_CYLINDER_LOW);  ide_outb ((lba & 0xff0000) >> 16, IDE_SECTOR_CYLINDER_HIGH);  ide_outb (IDE_LBA | (dev << 4) | ((lba & 0xf000000) >> 24), IDE_DEVICE_HEAD);    ide_outb (IDE_COMMAND_READ_SECTORS, IDE_COMMAND);  delay (100);    return ide_get_data (buf, count);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -