oxytoxin

unix-like kernel
git clone git://git.evenfri.xyz/oxytoxin.git
Log | Files | Refs | README | LICENSE

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 }