From: acevest Date: Mon, 22 Nov 2021 03:47:05 +0000 (+0800) Subject: ata pio 判断4个驱动器是否存在 X-Git-Url: http://zhaoyanbai.com/repos/man.dnssec-verify.html?a=commitdiff_plain;h=d41c89135d67b74a056ece160a81ae9ef69876b1;p=kernel.git ata pio 判断4个驱动器是否存在 --- diff --git a/drivers/ata.c b/drivers/ata.c index 6296939..d07dfc2 100644 --- a/drivers/ata.c +++ b/drivers/ata.c @@ -17,6 +17,12 @@ extern ide_pci_controller_t ide_pci_controller; +typedef struct _ide_drive { +} ide_drive_t; + +#define MAX_IDE_DRIVE_CNT 4 +ide_drive_t ide_drives[MAX_IDE_DRIVE_CNT]; + #define ATA_TIMEOUT 10 // 10次时钟中断 void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest); @@ -47,14 +53,36 @@ 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)); } -void ata_read_identify(int dev) { - outb(0x00, REG_CTL(dev)); +void ata_read_identify(int dev, int enable_intr) { + uint8_t ctl = enable_intr ? 0x00 : ATA_CTL_NIEN; + printk("%x %x %x\n", REG_CTL(dev), REG_CTL(dev), 0x00 | ((dev & 0x01) << 4)); + outb(ctl, REG_CTL(dev)); outb(0x00 | ((dev & 0x01) << 4), REG_DEVICE(dev)); // 根据文档P113,这里不用指定bit5, bit7,直接指示DRIVE就行 outb(ATA_CMD_IDENTIFY, REG_CMD(dev)); } +void ide_ata_init() { + for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) { + int dev = i; + + ata_read_identify(dev, 0); + + uint8_t status = inb(REG_STATUS(dev)); + if (status == 0 || (status & ATA_STATUS_ERR) || (status & ATA_STATUS_RDY == 0)) { + printk("ata[%d] not exists: %x\n", i, status); + continue; + } else { + printk("ata[%d] exists: %x\n", i, status); + insl(REG_DATA(dev), identify, SECT_SIZE / sizeof(uint32_t)); + } + } + asm("cli;hlt;"); +} + void ata_init() { disk_request_t r; + + r.dev = 0; r.buf = (void *)identify; r.count = 1; r.pos = 0; @@ -80,18 +108,18 @@ void ata_init() { // TODO REMOVE mbr_buf = kmalloc(SECT_SIZE, 0); r.command = DISK_REQ_READ; - r.pos = 1; + r.pos = 0; r.count = 1; r.buf = mbr_buf; send_disk_request(&r); - uint16_t *p = (uint16_t *)mbr_buf; - for (int i = 0; i < 256; i++) { - if (i % 12 == 0) { - printk("\n[%03d] ", i * 2); - } - printk("%04x ", p[i]); - } + // uint16_t *p = (uint16_t *)mbr_buf; + // for (int i = 0; i < 256; i++) { + // if (i % 12 == 0) { + // printk("\n[%03d] ", i * 2); + // } + // printk("%04x ", p[i]); + // } } void ata_read_identify_old(int dev) { // 这里所用的dev是逻辑编号 ATA0、ATA1下的Master、Salve的dev分别为0,1,2,3 diff --git a/drivers/ata.h b/drivers/ata.h index 904f3af..e0f71d1 100644 --- a/drivers/ata.h +++ b/drivers/ata.h @@ -18,7 +18,7 @@ extern unsigned int ATA_CHL1_CMD_BASE; // bit7: HOB High Order Byte (defined by 48-bit Address feature set). // bit[3-6]: - // bit2: SRST Software Reset -// bit1: IEN Interrupt Enable +// bit1: IEN disable Interrupt // bit0: 0 extern unsigned int ATA_CHL0_CTL_BASE; extern unsigned int ATA_CHL1_CTL_BASE; @@ -95,8 +95,8 @@ extern unsigned int ATA_CHL1_CTL_BASE; #define ATA_CTL_SRST 0x04 /* soft reset controller */ #define ATA_CTL_NIEN 0x02 /* disable interrupts */ -#define ATA_GET_CHL(dev) (0) /* only support channel 0 */ -#define ATA_GET_DEV(dev) (0) /* only support one hard disk */ +#define ATA_GET_CHL(dev) (((dev) >> 1) & 0x01) +#define ATA_GET_DEV(dev) (((dev) >> 1) & 0x01) #define REG_CMD_BASE(dev, offset) (ATA_GET_CHL(dev) ? (ATA_CHL1_CMD_BASE + offset) : (ATA_CHL0_CMD_BASE + offset)) #define REG_CTL_BASE(dev, offset) (ATA_GET_CHL(dev) ? (ATA_CHL1_CTL_BASE + offset) : (ATA_CHL0_CTL_BASE + offset)) diff --git a/drivers/ide.c b/drivers/ide.c index 64fcd09..cc9f0f4 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -197,14 +197,16 @@ void ide_pci_init(pci_device_t *pci) { void init_pci_controller(unsigned int classcode) { pci_device_t *pci = pci_find_device_by_classcode(classcode); if (pci != 0 && pci->intr_line < 16) { - printk("found pci vendor %04x device %04x class %04x intr %d\n", pci->vendor, pci->device, pci->classcode, - pci->intr_line); + printk("found pci vendor %04x device %04x class %04x intr %d progif: %x\n", pci->vendor, pci->device, + pci->classcode, pci->intr_line, pci->progif); // printl(17, "found pci vendor %04x device %04x class %04x intr %d", pci->vendor, pci->device, // pci->classcode, // pci->intr_line); ide_pci_init(pci); + // while (1) asm("cli;hlt;"); } } + void ide_default_intr() {} // void ide_default_intr() { // // printd("%s\n", __func__); @@ -532,7 +534,7 @@ void ide_irq() { ide_intr_func(); } // printk("%02x %02x\n", cl, ch); // } -void ata_read_identify(int dev); +// void ata_read_identify(int dev); DECLARE_WAIT_QUEUE_HEAD(ide_wait_queue_head); @@ -546,9 +548,9 @@ uint8_t ata_pci_bus_status(); extern ide_pci_controller_t ide_pci_controller; void ide_irq_handler(unsigned int irq, pt_regs_t *regs, void *devid) { - printk("ide irq handler %d \n", irq); + // printk("ide irq handler %d \n", irq); - printk("ide pci status after interrupt: %x\n", ata_pci_bus_status()); + printk("ide irq %d handler pci status after interrupt: %x\n", irq, ata_pci_bus_status()); ide_pci_controller.done = 1; @@ -559,6 +561,9 @@ void ide_init() { // memset((void *)&drv, 0, sizeof(drv)); memset(&ide_pci_controller, 0, sizeof(ide_pci_controller)); + void ide_ata_init(); + ide_ata_init(); + request_irq(0x0E, ide_irq_handler, "hard", "IDE"); // init_pci_controller(0x0106); diff --git a/include/disk.h b/include/disk.h index 0321bb5..96ef573 100644 --- a/include/disk.h +++ b/include/disk.h @@ -20,6 +20,7 @@ typedef enum { } disk_request_cmd_t; typedef struct disk_request { + int dev; uint64_t pos; // 扇区号 uint16_t count; // 扇区数 void *buf; // 到的缓冲区 diff --git a/kernel/setup.c b/kernel/setup.c index 87d984c..2c29d1b 100644 --- a/kernel/setup.c +++ b/kernel/setup.c @@ -88,7 +88,7 @@ void setup_kernel() { printk(version); extern tty_t monitor_tty; - tty_switch(&monitor_tty); + // tty_switch(&monitor_tty); void ide_init(); ide_init(); diff --git a/kernel/task_disk.c b/kernel/task_disk.c index f6d8f4c..b89631a 100644 --- a/kernel/task_disk.c +++ b/kernel/task_disk.c @@ -21,7 +21,6 @@ void disk_init() { INIT_LIST_HEAD(&disk_request_queue.list); } -#if 1 void send_disk_request(disk_request_t *r) { if (NULL == r) { panic("null disk request"); @@ -56,25 +55,25 @@ void send_disk_request(disk_request_t *r) { irq_restore(flags); // 唤醒task_disk - printk("up sem\n"); + // printk("up sem\n"); up(&disk_request_queue.sem); // 等待task_dist结束 - printk("wait event\n"); + // printk("wait event\n"); wait_event(&r->wait, r->done != 0); - printk("wait finished\n"); + // printk("wait finished\n"); } -#endif void disk_task_entry() { + int r_cnt = 0; while (1) { void prepare_to_wait_on_ide(); prepare_to_wait_on_ide(); - printk("wait for new hard disk request\n"); + // printk("wait for new hard disk request\n"); down(&disk_request_queue.sem); - printk("hard disk request: %d\n", disk_request_queue.count++); + // printk("hard disk request: %d\n", disk_request_queue.count++); unsigned long flags; irq_save(flags); @@ -87,7 +86,7 @@ void disk_task_entry() { panic("no disk request"); } - printk("disk request: pos %ld count %d cmd %d\n", r->pos, r->count, r->command); + printk("disk request[%d]: dev %d pos %ld count %d cmd %d\n", r_cnt++, r->dev, r->pos, r->count, r->command); } irq_restore(flags); @@ -96,18 +95,17 @@ void disk_task_entry() { continue; } - int dev = 0; switch (r->command) { case DISK_REQ_IDENTIFY: assert(r->count == 1); - void ata_read_identify(int dev); - ata_read_identify(dev); + void ata_read_identify(int dev, int enable_intr); + ata_read_identify(r->dev, 1); break; case DISK_REQ_READ: assert(r->count > 0); assert(r->buf != NULL); void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest); - ata_dma_read_ext(dev, r->pos, r->count, r->buf); + ata_dma_read_ext(r->dev, r->pos, r->count, r->buf); break; default: break; @@ -120,7 +118,7 @@ void disk_task_entry() { // 读数据 if (DISK_REQ_IDENTIFY == r->command) { void ata_read_data(int dev, int sect_cnt, void *dst); - ata_read_data(dev, 1, r->buf); + ata_read_data(r->dev, 1, r->buf); } // 唤醒等待该请求的进程 diff --git a/kernel/wait.c b/kernel/wait.c index f671a39..e6bdb4e 100644 --- a/kernel/wait.c +++ b/kernel/wait.c @@ -67,7 +67,7 @@ void __wake_up(wait_queue_head_t *head, int nr) { irq_save(flags); list_for_each_entry_safe(p, tmp, &head->task_list, task_list) { list_del(&p->task_list); - printk("wakeup: %s\n", p->task->name); + // printk("wakeup: %s\n", p->task->name); p->task->state = TASK_READY; --nr;