From c37714a8a544b7115ff35f58fa958f7c98f82e2c Mon Sep 17 00:00:00 2001 From: acevest Date: Sat, 3 Jun 2023 14:32:59 +0800 Subject: [PATCH] =?utf8?q?=E5=88=A0=E9=99=A4=E7=A1=AC=E7=9B=98=E7=9B=B8?= =?utf8?q?=E5=85=B3=E8=BF=87=E6=97=B6=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- drivers/ata.c | 146 ++++++++++------ drivers/ide.c | 454 +------------------------------------------------- 2 files changed, 93 insertions(+), 507 deletions(-) diff --git a/drivers/ata.c b/drivers/ata.c index 78b37e8..f2db975 100644 --- a/drivers/ata.c +++ b/drivers/ata.c @@ -57,6 +57,7 @@ void ata_send_read_identify_cmd(int dev) {} void ata_read_data(int dev, int sect_cnt, void *dst) { insl(REG_DATA(dev), dst, (512 * sect_cnt) / sizeof(uint32_t)); } +// 这里所用的dev是逻辑编号 ATA0、ATA1下的Master、Salve的dev分别为0,1,2,3 void ata_read_identify(int dev, int disable_intr) { uint8_t ctlv = 0x00; if (disable_intr != 0) { @@ -67,9 +68,54 @@ void ata_read_identify(int dev, int disable_intr) { outb(ATA_CMD_IDENTIFY, REG_CMD(dev)); } +void ata_read_identity_string(const uint16_t *identify, int bgn, int end, char *buf) { + const char *p = (const char *)(identify + bgn); + int i = 0; + for (; i <= (end - bgn); i++) { + buf[2 * i + 1] = p[0]; + buf[2 * i + 0] = p[1]; + p += 2; + } + buf[i] = 0; +} + +// 《AT Attachment 8 - ATA/ATAPI Command Set》 void ide_ata_init() { for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) { int dev = i; + memset(ide_drives + i, 0, sizeof(ide_drive_t)); + + // https://wiki.osdev.org/ATA_PIO_Mode + // To use the IDENTIFY command, select a target drive by sending 0xA0 for the master drive, or 0xB0 for the + // slave, to the "drive select" IO port. On the Primary bus, this would be port 0x1F6. Then set the Sectorcount, + // LBAlo, LBAmid, and LBAhi IO ports to 0 (port 0x1F2 to 0x1F5). Then send the IDENTIFY command (0xEC) to the + // Command IO port (0x1F7). Then read the Status port (0x1F7) again. If the value read is 0, the drive does not + // exist. For any other value: poll the Status port (0x1F7) until bit 7 (BSY, value = 0x80) clears. Because of + // some ATAPI drives that do not follow spec, at this point you need to check the LBAmid and LBAhi ports (0x1F4 + // and 0x1F5) to see if they are non-zero. If so, the drive is not ATA, and you should stop polling. Otherwise, + // continue polling one of the Status ports until bit 3 (DRQ, value = 8) sets, or until bit 0 (ERR, value = 1) + // sets. At that point, if ERR is clear, the data is ready to read from the Data port (0x1F0). Read 256 16-bit + // values, and store them. + // + // ATAPI的情况暂时不用考虑,因为不是硬盘相关的 + // https://wiki.osdev.org/ATAPI + // ATAPI refers to devices that use the Packet Interface of the ATA6 (or higher) standard command set. It is + // basically a way to issue SCSI commands to a CD-ROM, CD-RW, DVD, or tape drive, attached to the ATA bus. + // + // 总结来说,仅考虑ATA硬盘的情况 + // 一个IDE接口能接Master、Slave两个DRIVE。 + // 一个PC机上通常有两个IDE接口(IDE0, IDE1或ATA0, ATA1),通常称通道0、1 + // + // 对于同一个IDE通道的两个DRIVE,共享同一组寄存器,它们之间的区分是通过Device寄存器的第4个bit位来实现的。0为Master,1为Slave + // + // 使用IDENTIFY命令步骤: + // 1. 选择DRIVE,发送0xA0选择master,发送0xB0选择slave。(发送 0xE0 | (drive << 4)到Device寄存器) + // 2. 发送0到该DRIVE所在通道的寄存器NSECTOR, LBAL, LBAM, LBAH + // 3. 发送IDENTIFY(0xEC)命令到该通道的命令寄存器 + // 检查status寄存器: + // 1. 若为0,就认为没有IDE + // 2. 等到status的BSY位清除 + // 3. 等到status的DRQ位或ERR位设置 ata_read_identify(dev, 1); @@ -98,9 +144,55 @@ void ide_ata_init() { ide_drives[i].lba48 = 1; ide_drives[i].max_lba = max_lba; } +#if 0 + uint16_t i80 = identify[80]; + if (i80 & (1 << 8)) { + printk("ATA8-ACS "); + } + if (i80 & (1 << 7)) { + printk("ATA/ATAPI-7 "); + } + if (i80 & (1 << 6)) { + printk("ATA/ATAPI-6 "); + } + if (i80 & (1 << 5)) { + printk("ATA/ATAPI-5 "); + } + if (i80 & (1 << 4)) { + printk("ATA/ATAPI-4 "); + } + + printk(" %02x\n", identify[81]); +#endif + printk("Ultra DMA modes: %04x\n", identify[88]); +#if 0 + uint16_t x = identify[222]; + uint16_t tt = x >> 12; + switch (tt) { + case 0: + printk("parallel"); + break; + case 1: + printk("serial"); + break; + default: + printk("reserved"); + break; + } +#endif printk("hard disk %s %s size: %u MB\n", ide_drives[i].dma == 1 ? "DMA" : "", ide_drives[i].lba48 == 1 ? "LBA48" : "LBA28", (max_lba * 512) >> 20); + + char s[64]; + ata_read_identity_string(identify, 10, 19, s); + printk("SN: %s\n", s); + + ata_read_identity_string(identify, 23, 26, s); + printk("Firmware Revision: %s\n", s); + + ata_read_identity_string(identify, 27, 46, s); + printk("HD Model: %s\n", s); } } @@ -147,60 +239,6 @@ void ata_init() { } } -#if 0 -void ata_read_identify_old(int dev) { // 这里所用的dev是逻辑编号 ATA0、ATA1下的Master、Salve的dev分别为0,1,2,3 - // void send_disk_request(); - // send_disk_request(); - // DECLARE_WAIT_QUEUE_HEAD(wq_head); - // DECLARE_WAIT_QUEUE(wait, current); - // add_wait_queue(&wq_head, &wait); - // ide_pci_controller.task = current; - - outb(0x00, REG_CTL(dev)); - outb(0x00 | ((dev & 0x01) << 4), REG_DEVICE(dev)); // 根据文档P113,这里不用指定bit5, bit7,直接指示DRIVE就行 - - unsigned long flags; - irq_save(flags); - - outb(ATA_CMD_IDENTIFY, REG_CMD(dev)); - wait_on_ide(); - - irq_restore(flags); - - insw(REG_DATA(dev), identify, SECT_SIZE / sizeof(u16)); - - // 第49个word的第8个bit位表示是否支持DMA - // 第83个word的第10个bit位表示是否支持LBA48,为1表示支持。 - // 第100~103个word的八个字节表示user的LBA最大值 - printk("%04x %04x %d %d\n", identify[49], 1 << 8, identify[49] & (1 << 8), (identify[49] & (1 << 8)) != 0); - if ((identify[49] & (1 << 8)) != 0) { - printk("support DMA\n"); - } - - if ((identify[83] & (1 << 10)) != 0) { - printk("support LBA48\n"); - - u64 lba = *(u64 *)(identify + 100); - printk("hard disk size: %u MB\n", (lba * 512) >> 20); - } - - printk("bus iobase %x cmd %x status %x prdt %x \n", ide_pci_controller.bus_iobase, ide_pci_controller.bus_cmd, - ide_pci_controller.bus_status, ide_pci_controller.bus_prdt); - - // TODO REMOVE - mbr_buf = kmalloc(SECT_SIZE, 0); - // ata_test(0); - sleep_on_ide(); - // ata_pio_read_ext(0, 0, 1, ATA_TIMEOUT, mbr_buf); - uint16_t *p = (uint16_t *)mbr_buf; - for (int i = 0; i < 256; i++) { - if (i % 12 == 0) { - printk("\n[%03d] ", i); - } - printk("%04x ", p[i]); - } -} -#endif // ATA_CMD_READ_DMA_EXT void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest) { // Intel® diff --git a/drivers/ide.c b/drivers/ide.c index b314272..6b97d0d 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -7,126 +7,12 @@ * ------------------------------------------------------------------------ */ -// #include #include -// #include #include - -// #include #include #include -// #include -// #include #include -// typedef struct prd { -// unsigned int addr; -// unsigned int cnt : 16; -// unsigned int reserved : 15; -// unsigned int eot : 1; -// } prd_t; - -// typedef struct { -// u64_t lba; -// u32_t scnt; -// u32_t read_scnt; -// char *buf; -// bool finish; -// wait_queue_head_t wait; -// } ide_request_t; - -typedef void (*ide_intr_func_t)(); - -void ide_default_intr(); - -// ide_drive_t drv; -// DECLARE_MUTEX(mutex); -// ide_request_t ide_request; - -ide_intr_func_t ide_intr_func = ide_default_intr; - -// unsigned char *dma_data = 0; - -// unsigned int HD_CHL0_CMD_BASE = 0x1F0; -// unsigned int HD_CHL1_CMD_BASE = 0x170; - -// unsigned int HD_CHL0_CTL_BASE = 0x3F6; -// unsigned int HD_CHL1_CTL_BASE = 0x376; - -// void ide_printl() { printl(MPL_IDE, "ide pio cnt %d dma cnt %d irq cnt %d", drv.pio_cnt, drv.dma_cnt, drv.irq_cnt); } - -// void ide_cmd_out(dev_t dev, u32 sect_cnt, u64 sect_nr, u32 cmd) { -// drv.pio_cnt++; -// drv.read_mode = cmd; - -// ide_printl(); - -// outb(0x00, REG_CTL(dev)); -// outb(0x40 | 0x00, REG_DEVICE(dev)); - -// outb((u8)((sect_cnt >> 8) & 0xFF), REG_NSECTOR(dev)); // High -// outb((u8)((sect_nr >> 24) & 0xFF), REG_LBAL(dev)); -// outb((u8)((sect_nr >> 32) & 0xFF), REG_LBAM(dev)); -// outb((u8)((sect_nr >> 40) & 0xFF), REG_LBAH(dev)); - -// outb((u8)((sect_cnt >> 0) & 0xFF), REG_NSECTOR(dev)); // Low -// outb((u8)((sect_nr >> 0) & 0xFF), REG_LBAL(dev)); -// outb((u8)((sect_nr >> 8) & 0xFF), REG_LBAM(dev)); -// outb((u8)((sect_nr >> 16) & 0xFF), REG_LBAH(dev)); - -// outb(cmd, REG_CMD(dev)); -// } - -// part_t *ide_get_part(dev_t dev) { -// assert(DEV_MAJOR(dev) == DEV_MAJOR_HDA); -// assert(DEV_MINOR(dev) < MAX_SUPPORT_PARTITION_CNT); - -// return drv.part + DEV_MINOR(dev); -// } - -// void ide_do_read(u64_t lba, u32_t scnt, char *buf) { -// bool finish = false; -// unsigned long flags; - -// ide_request_t *r = &ide_request; - -// down(&mutex); - -// r->lba = lba; -// r->scnt = scnt; -// r->read_scnt = 0; -// r->buf = buf; -// r->finish = false; -// init_wait_queue(&r->wait); - -// task_union *task = current; -// DECLARE_WAIT_QUEUE(wait, task); -// add_wait_queue(&r->wait, &wait); - -// ide_cmd_out(0, scnt, lba, HD_CMD_READ_PIO_EXT); - -// while (true) { -// // printd("%s pid %d is going to wait\n", __func__, sysc_getpid()); -// task->state = TASK_WAIT; -// irq_save(flags); -// finish = r->finish; -// // printd("%s pid %d finish %u read_scnt %u scnt %u\n", __func__, sysc_getpid(), r->finish, r->read_scnt, -// // r->scnt); -// irq_restore(flags); - -// if (finish) break; - -// schedule(); -// // printd("%s pid %d is running\n", __func__, sysc_getpid()); -// } - -// // printd("%s pid %d is really running\n", __func__, sysc_getpid()); -// task->state = TASK_READY; -// del_wait_queue(&r->wait, &wait); -// } - -// unsigned int sys_clock(); - ide_pci_controller_t ide_pci_controller; extern unsigned int ATA_CHL0_CMD_BASE; @@ -209,345 +95,7 @@ void init_pci_controller(unsigned int classcode) { } } -void ide_default_intr() {} -// void ide_default_intr() { -// // printd("%s\n", __func__); -// u8_t status = inb(REG_STATUS(0)); - -// drv.irq_cnt++; - -// status = inb(drv.bus_status); -// if (0 == (status & PCI_IDE_STATUS_INTR)) { -// return; -// } - -// status |= PCI_IDE_STATUS_INTR; -// outb(status, drv.bus_status); -// outb(0x00, drv.bus_cmd); - -// u16_t sig = 0; -// if (drv.read_mode == HD_CMD_READ_PIO_EXT) { -// insl(REG_DATA(0), ide_request.buf + ide_request.read_scnt * (SECT_SIZE), (SECT_SIZE) >> 2); -// ide_request.read_scnt++; -// sig = *((u16_t *)(ide_request.buf + 510)); -// } - -// if (drv.read_mode == HD_CMD_READ_DMA_EXT) { -// sig = *((u16_t *)(dma_data + 510)); -// } - -// ide_printl(); - -// // printd(" hard disk sig %04x read mode %x cnt %d\n", sig, drv.read_mode, drv.irq_cnt); -// printl(MPL_IDE_INTR, "hard disk sig %x read mode %x cnt %d", sig, drv.read_mode, drv.irq_cnt); - -// outb(PCI_IDE_CMD_STOP, drv.bus_cmd); - -// wake_up(&ide_request.wait); -// if (drv.read_mode == HD_CMD_READ_PIO_EXT) { -// if (ide_request.read_scnt == ide_request.scnt) ide_request.finish = true; -// } - -// up(&mutex); -// } - -void ide_irq() { ide_intr_func(); } - -// prd_t prd __attribute__((aligned(64 * 1024))); -// unsigned long gprdt = 0; - -// #define DELAY400NS \ -// { \ -// inb(HD_CHL0_CTL_BASE); \ -// inb(HD_CHL0_CTL_BASE); \ -// inb(HD_CHL0_CTL_BASE); \ -// inb(HD_CHL0_CTL_BASE); \ -// } - -// void ide_dma_pci_lba48() { -// drv.dma_cnt++; -// drv.read_mode = HD_CMD_READ_DMA_EXT; -// #if 1 -// memset((void *)&prd, 0, sizeof(prd)); -// unsigned long addr = alloc_one_page(0); -// dma_data = (char *)addr; -// memset(dma_data, 0xBB, 512); -// prd.addr = va2pa(addr); -// prd.cnt = 512; -// prd.eot = 1; -// gprdt = va2pa(&prd); - -// printl(16, "gprdt %08x &prdt %08x prd.addr %08x addr %08x", gprdt, &prd, prd.addr, addr); - -// outb(PCI_IDE_CMD_STOP, drv.bus_cmd); -// unsigned short status = inb(drv.bus_status); -// outb(status | PCI_IDE_STATUS_INTR | PCI_IDE_STATUS_ERR, drv.bus_status); -// outl(gprdt, drv.bus_prdt); -// outb(PCI_IDE_CMD_WRITE, drv.bus_cmd); -// #endif - -// #if 0 -// while ( 1 ) -// { -// status = inb(HD_CHL0_CMD_BASE+HD_STATUS); -// printk(" <%02x> ", status); -// if((status & (HD_STATUS_BSY | HD_STATUS_DRQ)) == 0) -// { -// break; -// } -// } - -// outb(0x00, HD_CHL0_CMD_BASE+HD_DEVICE); -// DELAY400NS; - -// while ( 1 ) -// { -// status = inb(HD_CHL0_CMD_BASE+HD_STATUS); -// printk(" <%02x> ", status); -// if((status & (HD_STATUS_BSY | HD_STATUS_DRQ)) == 0) -// { -// break; -// } -// } -// #endif - -// outb(0x00, HD_CHL0_CTL_BASE); // Device Control - -// outb(0x00, HD_CHL0_CMD_BASE + HD_FEATURES); -// outb(0x00, HD_CHL0_CMD_BASE + HD_NSECTOR); -// outb(0x00, HD_CHL0_CMD_BASE + HD_LBAL); -// outb(0x00, HD_CHL0_CMD_BASE + HD_LBAM); -// outb(0x00, HD_CHL0_CMD_BASE + HD_LBAH); - -// outb(0x00, HD_CHL0_CMD_BASE + HD_FEATURES); -// outb(0x01, HD_CHL0_CMD_BASE + HD_NSECTOR); -// outb(0x00, HD_CHL0_CMD_BASE + HD_LBAL); -// outb(0x00, HD_CHL0_CMD_BASE + HD_LBAM); -// outb(0x00, HD_CHL0_CMD_BASE + HD_LBAH); - -// outb(0x40, HD_CHL0_CMD_BASE + HD_DEVICE); - -// outb(HD_CMD_READ_DMA_EXT, HD_CHL0_CMD_BASE + HD_CMD); - -// inb(drv.bus_cmd); -// inb(drv.bus_status); -// unsigned short w = inb(drv.bus_cmd); -// outb(w | PCI_IDE_CMD_WRITE | PCI_IDE_CMD_START, drv.bus_cmd); -// inb(drv.bus_cmd); -// inb(drv.bus_status); -// } - -// typedef struct { -// u8_t a; -// u8_t b; -// u16_t lbah; // lba high -// u8_t type; -// u8_t f; -// u16_t scnth; // sector count high -// u32_t lba; // lba low -// u32_t scnt; // sector count -// } hd_part_t; - -// void ide_read_extended_partition(u64_t lba, unsigned int inx) { -// if (inx >= MAX_SUPPORT_PARTITION_CNT) return; - -// unsigned int i; -// char *buf = kmalloc(512, 0); -// if (buf == 0) panic("no memory"); - -// ide_do_read(lba, 1, buf); - -// u16_t sig = *((u16_t *)(buf + 510)); -// if (sig != 0xAA55) panic("bad partition sect"); - -// hd_part_t *p = (hd_part_t *)(buf + PARTITION_TABLE_OFFSET); -// printd("%s:%d lba %d \n", __func__, __LINE__, lba); - -// for (i = 0; i < PARTITION_CNT; ++i, ++p) { -// if (p->type == 0) continue; - -// // u64_t part_lba = lba + (p->lba|((p->lbah*1ULL)<<32)); -// // u64_t part_scnt= p->scnt | ((p->scnth*1ULL)<<32); -// u64_t part_lba = lba + p->lba; -// u64_t part_scnt = p->scnt; - -// if (p->type != 0x05) { -// drv.part[inx].lba_start = part_lba; -// drv.part[inx].lba_end = part_lba + part_scnt; -// printk(" logic partition[%02d] [%02x] LBA base %10d end %10d\n", inx, p->type, -// (unsigned int)(drv.part[inx].lba_start), (unsigned int)(drv.part[inx].lba_end - 1)); -// } else { -// part_lba = drv.ext_lba_base + p->lba; -// printk(" extended [%02x] LBA base %10d end %10d\n", p->type, (unsigned int)(part_lba), -// (unsigned int)(part_lba + part_scnt - 1)); -// ide_read_extended_partition(part_lba, inx + 1); -// } -// } - -// kfree(buf); -// } - -// void ide_read_partition() { -// printk("reading partitions....\n"); -// unsigned int i; -// char *buf = kmalloc(512, 0); -// if (buf == 0) panic("no memory"); - -// ide_do_read(0, 1, buf); - -// u16_t sig = *((u16_t *)(buf + 510)); -// if (sig != 0xAA55) panic("bad partition sect"); - -// hd_part_t *p = (hd_part_t *)(buf + PARTITION_TABLE_OFFSET); - -// unsigned int ext_inx = ~0U; - -// for (i = 0; i < PARTITION_CNT; ++i, ++p) { -// if (p->type == 0) continue; - -// // u64_t part_lba = p->lba|((p->lbah*1ULL)<<32); -// // u64_t part_scnt= p->scnt | ((p->scnth*1ULL)<<32); -// u64_t part_lba = p->lba; -// u64_t part_scnt = p->scnt; - -// drv.part[i].lba_start = part_lba; -// drv.part[i].lba_end = part_lba + part_scnt; - -// if (p->type == 0x05) { -// if (drv.ext_lba_base == 0) { -// drv.ext_lba_base = drv.part[i].lba_start; -// ext_inx = i; -// } -// } - -// printk("primary partition[%02d] [%02x] LBA base %10d end %10d\n", i, p->type, (unsigned int)(part_lba), -// (unsigned int)(part_lba + part_scnt - 1)); -// } - -// kfree(buf); - -// if (ext_inx != ~0U) ide_read_extended_partition(drv.part[ext_inx].lba_start, 4); -// } - -// u16 ide_identify_buf[256]; - -// static void ata_io_wait() { -// for (int i = 0; i < 128; i++) { -// inb(REG_CTL(0)); -// } -// } - -// // https://wiki.osdev.org/ATA_PIO_Mode -// // To use the IDENTIFY command, select a target drive by sending 0xA0 for the master drive, or 0xB0 for the -// slave, -// // to the "drive select" IO port. On the Primary bus, this would be port 0x1F6. Then set the Sectorcount, LBAlo, -// // LBAmid, and LBAhi IO ports to 0 (port 0x1F2 to 0x1F5). Then send the IDENTIFY command (0xEC) to the Command IO -// // port (0x1F7). -// // Then read the Status port (0x1F7) again. If the value read is 0, the drive does not exist. For any -// // other value: poll the Status port (0x1F7) until bit 7 (BSY, value = 0x80) clears. Because of some ATAPI drives -// // that do not follow spec, at this point you need to check the LBAmid and LBAhi ports (0x1F4 and 0x1F5) to see -// if -// // they are non-zero. If so, the drive is not ATA, and you should stop polling. Otherwise, continue polling one -// of -// // the Status ports until bit 3 (DRQ, value = 8) sets, or until bit 0 (ERR, value = 1) sets. At that point, if -// ERR -// // is clear, the data is ready to read from the Data port (0x1F0). Read 256 16-bit values, and store them. -// // -// // ATAPI的情况暂时不用考虑,因为不是硬盘相关的 -// // https://wiki.osdev.org/ATAPI -// // ATAPI refers to devices that use the Packet Interface of the ATA6 (or higher) standard command set. It is -// // basically a way to issue SCSI commands to a CD-ROM, CD-RW, DVD, or tape drive, attached to the ATA bus. -// // -// // 总结来说,仅考虑ATA硬盘的情况 -// // 一个IDE接口能接Master、Slave两个DRIVE。 -// // 一个PC机上通常有两个IDE接口(IDE0, IDE1或ATA0, ATA1),通常称通道0、1 -// // -// 对于同一个IDE通道的两个DRIVE,共享同一组寄存器,它们之间的区分是通过Device寄存器的第4个bit位来实现的。0为Master,1为Slave -// // -// // 使用IDENTIFY命令步骤: -// // 1. 选择DRIVE,发送0xA0选择master,发送0xB0选择slave。(发送 0xE0 | (drive << 4)到Device寄存器) -// // 2. 发送0到该DRIVE所在通道的寄存器NSECTOR, LBAL, LBAM, LBAH -// // 3. 发送IDENTIFY(0xEC)命令到该通道的命令寄存器 -// // 检查status寄存器: -// // 1. 若为0,就认为没有IDE -// // 2. 等到status的BSY位清除 -// // 3. 等到status的DRQ位或ERR位设置 -// void ide_read_identify() { -// int dev = 0; // 这里所用的dev是逻辑编号 ATA0、ATA1下的Master、Salve的dev分别为0,1,2,3 -// // outb(0xE0 | ((dev & 0x01) << 4), REG_DEVICE(dev)); // 这里可也可以发送(0xA0 | ((dev & 0x0ls1) << 4)) -// outb(0x00 | ((dev & 0x01) << 4), REG_DEVICE(dev)); // 这里可也可以发送(0xA0 | ((dev & 0x01) << 4)) -// outb(0x00, REG_NSECTOR(0)); -// outb(0x00, REG_LBAL(0)); -// outb(0x00, REG_LBAM(0)); -// outb(0x00, REG_LBAH(0)); -// outb(HD_CMD_IDENTIFY, REG_CMD(dev)); -// while (true) { -// u8_t status = inb(REG_STATUS(0)); -// if (status == 0) { -// panic("no hard drive"); -// } -// u8_t error = inb(REG_ERR(0)); -// printk("hd0 status: %x %x %x\n", status, error, REG_STATUS(0)); -// if ((status & HD_STATUS_BSY) == 0 && (status & HD_STATUS_DRQ) != 0) { -// break; -// } -// } - -// insw(REG_DATA(0), ide_identify_buf, 256); - -// // 第83个word(2bytes)的第10个bit位表示是否支持LBA48,为1表示支持。 - -// for (int i = 0; i < 256; i++) { -// if (i % 12 == 0) { -// printk("\n%d ", i); -// } -// printk("%04x ", ide_identify_buf[i]); -// } - -// struct iden_info { -// int idx; -// int len; -// char *desc; -// } infos[] = {{10, 20, "HD SN"}, {17, 8, "Firmware Revision"}, {27, 40, "HD Model"}}; - -// u16 *hdinfo = (u16 *)ide_identify_buf; -// char s[64]; -// for (int i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) { -// char *p = (char *)&hdinfo[infos[i].idx]; -// int j = 0; -// for (j = 0; j < infos[i].len / 2; j++) { -// s[j * 2 + 1] = *p++; -// s[j * 2] = *p++; -// } -// s[j] = 0; -// printk("%s: %s\n", infos[i].desc, s); -// } -// } - -// void ide_detect() { -// // outb(HD_CTL_SRST, REG_CTL(0)); -// outb(0xA0 | 0x00, REG_DEVICE(dev)); -// ata_io_wait(); - -// unsigned cl = inb(REG_LBAM(0)); -// ata_io_wait(); -// unsigned ch = inb(REG_LBAH(0)); -// ata_io_wait(); -// printk("%02x %02x\n", cl, ch); -// } - -// void ata_read_identify(int dev); - -#if 1 extern semaphore_t disk_intr_sem; -#else -DECLARE_WAIT_QUEUE_HEAD(ide_wait_queue_head); - -void sleep_on_ide() { sleep_on(&ide_wait_queue_head); } - -void prepare_to_wait_on_ide() { ide_pci_controller.done = 0; } -void wait_on_ide() { wait_event(&ide_wait_queue_head, ide_pci_controller.done); } -#endif extern void *mbr_buf; extern ide_pci_controller_t ide_pci_controller; @@ -563,7 +111,7 @@ void ide_irq_bh_handler() { // printl(MPL_IDE, "disk req %u consumed %u irq %u", disk_request_cnt, disk_handled_cnt, disk_inter_cnt); printlxy(MPL_IDE, MPO_IDE, "disk irq %u req %u consumed %u ", disk_inter_cnt, disk_request_cnt, disk_handled_cnt); - + ata_dma_stop(); // up里不会立即重新调度进程 up(&disk_intr_sem); } -- 2.44.0