ata.c (1170B)
1 #include "oxytoxin.h" 2 3 extern void ata_entry(void); 4 5 static void ata_io_wait(void) { 6 inb(0x1f7); 7 inb(0x1f7); 8 inb(0x1f7); 9 inb(0x1f7); 10 } 11 12 static int ata_wait_drq(void) { 13 while (1) { 14 uint8_t status = inb(0x1f7); 15 if (status & ata_drive_err) return -1; 16 if (!(status & ata_drive_busy) && (status & ata_drive_req_ready)) return 0; 17 } 18 } 19 20 void ata_read_sectors(void *trg, unsigned int lba, unsigned char size) { 21 outb(0x1f6, 0xe0 | ((lba >> 24) & 0x0f)); 22 outb(0x1f2, size); 23 outb(0x1f3, (unsigned char) lba); 24 outb(0x1f4, (unsigned char) (lba >> 8)); 25 outb(0x1f5, (unsigned char) (lba >> 16)); 26 outb(0x3f6, 0x02); 27 outb(0x1f7, ata_cmd_read); 28 29 ata_io_wait(); 30 31 uint16_t *target = (uint16_t *) trg; 32 int count = (size == 0) ? 256 : size; 33 34 for (int i = 0; i < count; i++) { 35 if (ata_wait_drq() != 0) return; /* read error */ 36 37 for (int j = 0; j < 256; j++) { 38 target[j] = inw(0x1f0); 39 } 40 target += 256; 41 } 42 } 43 44 void ata_handler(void) { 45 inb(0x1f7); /* reset IRQ */ 46 outb(0x20, 0x20); /* EOI для master pic1 */ 47 outb(0xa0, 0x20); /* EOI для slave pic2 */ 48 } 49 50 void ata_init(void) { 51 idt_register(0x2e, ata_entry); 52 }