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》
}
}
- // 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表示支持。
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
// 配置描述符表
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);
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);
#define ATA_IDENT_MAX_LBA 120
#define ATA_IDENT_COMMANDSETS 164
#define ATA_IDENT_MAX_LBA_EXT 200
+
+#define SECT_SIZE 512
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);
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;
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,
// pci->classcode,
// pci->intr_line);
ide_pci_init(pci);
- ide_pci_controller.pci = pci;
}
}
void ide_default_intr() {}
// #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))
// 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;");
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) {