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);
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;
// 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
// 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;
#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))
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__);
// 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);
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;
// 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);
} disk_request_cmd_t;
typedef struct disk_request {
+ int dev;
uint64_t pos; // 扇区号
uint16_t count; // 扇区数
void *buf; // 到的缓冲区
printk(version);
extern tty_t monitor_tty;
- tty_switch(&monitor_tty);
+ // tty_switch(&monitor_tty);
void ide_init();
ide_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");
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);
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);
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;
// 读数据
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);
}
// 唤醒等待该请求的进程
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;