From: acevest Date: Sun, 14 Nov 2021 12:53:04 +0000 (+0800) Subject: 将ATA操作pci command的bus master的代码移动到ata_dma_read_ext和硬盘中断函数里 X-Git-Url: http://zhaoyanbai.com/repos/Bv9ARM.ch05.html?a=commitdiff_plain;h=687f4faf87c2c55474e44e93887ee389edbdf0ae;p=kernel.git 将ATA操作pci command的bus master的代码移动到ata_dma_read_ext和硬盘中断函数里 --- diff --git a/drivers/ata.c b/drivers/ata.c index eac1bdd..5ccdbbf 100644 --- a/drivers/ata.c +++ b/drivers/ata.c @@ -17,6 +17,10 @@ extern ide_pci_controller_t ide_pci_controller; void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *); void *mbr_buf; +void ata_test(uint64_t nr) { + memset(mbr_buf, 0xAA, SECT_SIZE); + ata_dma_read_ext(0, nr, 1, mbr_buf); +} // 本程序参考文档《AT Attachment with Packet Interface - 6》 @@ -45,8 +49,7 @@ void ata_read_identify(int dev) { // 这里所用的dev是逻辑编号 ATA0、A } } - // u16 *identify = (u16 *)kmalloc(ATA_NSECTOR, 0); - insw(REG_DATA(dev), identify, 512 / sizeof(u16)); + insw(REG_DATA(dev), identify, SECT_SIZE / sizeof(u16)); // 第49个word的第8个bit位表示是否支持DMA // 第83个word的第10个bit位表示是否支持LBA48,为1表示支持。 @@ -66,9 +69,9 @@ void ata_read_identify(int dev) { // 这里所用的dev是逻辑编号 ATA0、A 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); - mbr_buf = kmalloc(512, 0); - memset(mbr_buf, 0xAA, 512); - ata_dma_read_ext(0, 0, 1, mbr_buf); + // TODO REMOVE + mbr_buf = kmalloc(SECT_SIZE, 0); + // ata_test(0); } // ATA_CMD_READ_DMA_EXT @@ -79,7 +82,7 @@ void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *addr) { // 配置描述符表 unsigned long paddr = va2pa(addr); ide_pci_controller.prdt[0].phys_addr = paddr; - ide_pci_controller.prdt[0].byte_count = 512; + ide_pci_controller.prdt[0].byte_count = SECT_SIZE; ide_pci_controller.prdt[0].reserved = 0; ide_pci_controller.prdt[0].eot = 1; outl(va2pa(ide_pci_controller.prdt), ide_pci_controller.bus_prdt); @@ -115,6 +118,14 @@ void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *addr) { outb(ATA_CMD_READ_DMA_EXT, REG_CMD(dev)); + // 这一句非常重要,如果不加这一句 + // 在qemu中用DMA的方式读数据就会读不到数据,而只触是发中断,然后寄存器(Bus Master IDE Status + // Register)的值会一直是5 也就是INTERRUPT和和ACTIVE位是1,正常应该是4,也就是只有INTERRUPT位为1 + // 在bochs中则加不加这一句不会有影响,都能正常读到数据 + unsigned int v = pci_read_config_word(pci_cmd(ide_pci_controller.pci, PCI_COMMAND)); + printk(" ide pci command %04x\n", v); + pci_write_config_word(v | PCI_COMMAND_MASTER, pci_cmd(ide_pci_controller.pci, PCI_COMMAND)); + // 指定DMA操作为读取硬盘操作,内核用DMA读取,对硬盘而言是写出 // 并设置DMA的开始位,开始DMA outb(PCI_IDE_CMD_WRITE | PCI_IDE_CMD_START, ide_pci_controller.bus_cmd); diff --git a/drivers/ata.h b/drivers/ata.h index 45c05c0..904f3af 100644 --- a/drivers/ata.h +++ b/drivers/ata.h @@ -125,3 +125,5 @@ extern unsigned int ATA_CHL1_CTL_BASE; #define ATA_IDENT_MAX_LBA 120 #define ATA_IDENT_COMMANDSETS 164 #define ATA_IDENT_MAX_LBA_EXT 200 + +#define SECT_SIZE 512 diff --git a/drivers/ide.c b/drivers/ide.c index fed4c4b..b970f70 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -141,15 +141,6 @@ void ide_pci_init(pci_device_t *pci) { v = pci_read_config_word(pci_cmd(pci, PCI_COMMAND)); printk(" ide pci command %04x\n", v); - // 这一句非常重要,如果不加这一句 - // 在qemu中用DMA的方式读数据就会读不到数据,而只触是发中断,然后寄存器(Bus Master IDE Status - // Register)的值会一直是5 也就是INTERRUPT和和ACTIVE位是1,正常应该是4,也就是只有INTERRUPT位为1 - // 在bochs中则加不加这一句不会有影响,都能正常读到数据 - pci_write_config_word(v | PCI_COMMAND_MASTER, pci_cmd(pci, PCI_COMMAND)); - - v = pci_read_config_word(pci_cmd(pci, PCI_COMMAND)); - printk(" ide pci command %04x\n", v); - v = pci_read_config_byte(pci_cmd(pci, PCI_PROGIF)); printk(" ide pci program interface %02x\n", v); @@ -160,7 +151,6 @@ void ide_pci_init(pci_device_t *pci) { ide_pci_controller.bus_cmd = iobase + PCI_IDE_CMD; ide_pci_controller.bus_status = iobase + PCI_IDE_STATUS; ide_pci_controller.bus_prdt = iobase + PCI_IDE_PRDT; - ide_pci_controller.prdt = (prdte_t *)alloc_one_page(0); int i; @@ -177,6 +167,8 @@ void ide_pci_init(pci_device_t *pci) { ATA_CHL1_CMD_BASE = pci->bars[2] ? pci->bars[2] : ATA_CHL1_CMD_BASE; ATA_CHL1_CTL_BASE = pci->bars[3] ? pci->bars[3] : ATA_CHL1_CTL_BASE; + ide_pci_controller.pci = pci; + printk("channel0: cmd %04x ctl %04x channel1: cmd %04x ctl %04x\n", ATA_CHL0_CMD_BASE, ATA_CHL0_CTL_BASE, ATA_CHL1_CMD_BASE, ATA_CHL1_CTL_BASE); // printl(18, "channel0: cmd %04x ctl %04x channel1: cmd %04x ctl %04x", HD_CHL0_CMD_BASE, HD_CHL0_CTL_BASE, @@ -211,7 +203,6 @@ void init_pci_controller(unsigned int classcode) { // pci->classcode, // pci->intr_line); ide_pci_init(pci); - ide_pci_controller.pci = pci; } } void ide_default_intr() {} diff --git a/drivers/ide.h b/drivers/ide.h index 7c98511..cf09767 100644 --- a/drivers/ide.h +++ b/drivers/ide.h @@ -112,8 +112,6 @@ // #define REG_CMD(dev) REG_CMD_BASE(dev, HD_CMD) // #define REG_CTL(dev) REG_CTL_BASE(dev, HD_CTL) -// #define SECT_SIZE 512 - // #define hd_rd_data(dev, buf, count) hd_rd_port(REG_DATA(dev), buf, count) // #define hd_bsy(dev) ((inb(REG_STATUS(dev)) & HD_STATUS_BSY)) diff --git a/drivers/keyboard.c b/drivers/keyboard.c index 56b368c..a7c4325 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -101,8 +101,11 @@ void kbd_debug(unsigned char scan_code) { // if (scan_code == 0x43) // F9 // ide_dma_pci_lba48(); - // if (scan_code == 0x44) // F10 - // ide_debug(); + if (scan_code == 0x44) { // F10 + void ata_test(uint64_t nr); + ata_test(0); + } + if (scan_code == 0x57) // F11 { asm("cli;"); diff --git a/kernel/system.c b/kernel/system.c index 72bfa16..d42e98f 100644 --- a/kernel/system.c +++ b/kernel/system.c @@ -92,12 +92,15 @@ void setup_gate() { void ide_irq(); extern void *mbr_buf; uint8_t ata_pci_bus_status(); - +extern ide_pci_controller_t ide_pci_controller; void default_ide_irq_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) { printk("default irq handler %d \n", irq); printk("ide pci status after interrupt: %x", ata_pci_bus_status()); + unsigned int v = pci_read_config_word(pci_cmd(ide_pci_controller.pci, PCI_COMMAND)); + pci_write_config_word(v & (~PCI_COMMAND_MASTER), pci_cmd(ide_pci_controller.pci, PCI_COMMAND)); + uint16_t *p = (uint16_t *)mbr_buf; for (int i = 0; i < 256; i++) { if (i % 12 == 0) {