Advertisement
Guest User

ATA/DMA test

a guest
Aug 6th, 2014
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.46 KB | None | 0 0
  1. /*
  2.  *   Buggy ATA/DMA test, that works in QEMU and not in Bochs.
  3.  */
  4.  
  5. #define ATATIMEOUT 5
  6.  
  7. /* the two following variables were
  8.  * initialized while reading the PCI
  9.  */
  10. unsigned int ata_bar[6];
  11. unsigned short ata_int_inf;
  12.  
  13. unsigned short ata_base;
  14. unsigned short ata_alts;        /* R: alternate status / W: device ctrl reg */
  15.  
  16. char *buffer = (char*)0x6000;
  17.  
  18.  
  19. struct prdt {
  20.         unsigned int addr;
  21.         unsigned short siz;
  22.         unsigned short end;
  23. };
  24.  
  25.  
  26. struct prdt *prdt;
  27.  
  28. int ataint;
  29.  
  30.  
  31. atatest()
  32. {
  33.         unsigned addr = 0;   /* LBA address */
  34.         unsigned disk = 0;
  35.         extern ksleep(int);
  36.  
  37.         printf("ATA BAR %x %x %x %x %x %x -- INT INFO %x\n",
  38.                 ata_bar[0], ata_bar[1], ata_bar[2],
  39.                 ata_bar[3], ata_bar[4], ata_bar[5],
  40.                 ata_int_inf);
  41.  
  42.         if (ata_bar[0] < 2) {
  43.                 ata_base = 0x1F0;
  44.         } else {
  45.                 ata_base = ata_bar[0];
  46.         }
  47.         if (ata_bar[1] > 2) {
  48.                 ata_alts = ata_bar[1]+2;
  49.         } else {
  50.                 ata_alts = 0x3F6;
  51.         }
  52.         printf("base = %x, alt status = %x\n", ata_base, ata_alts);
  53.  
  54.         prdt->addr = (unsigned)buffer;
  55.         prdt->siz = 512;     /* count in bytes. 512 bytes = 0x200 = 1 sect */
  56.         prdt->end = 0x8000; /* End Of Table bit set */
  57.  
  58.  
  59.         atawait();
  60.  
  61.         atabsw(4, prdt, 4);     /* set prdt pointer */
  62.  
  63.         /* enable ata controller */
  64.         outb(ata_base+1, 1);
  65.         outb(ata_alts, 0);
  66.  
  67.  
  68.         /* reset ata */
  69.         outb(ata_alts, 4);
  70.         ksleep(1);
  71.         outb(ata_alts, 0);
  72.  
  73.         atawait();
  74.  
  75.         atabsw(2, 4, 1);        /* reset interrupt bit */
  76.  
  77.         /* Read */
  78.  
  79.         outb(ata_base+6, 0xE0 | (disk << 4) | ((addr<<24) & 0x0f) );
  80.         outb(ata_base+2, 1);    /* sector count */
  81.         outb(ata_base+3, (unsigned char)addr);   /* low addr */
  82.         outb(ata_base+4, (unsigned char)(addr>>8)); /* mid addr */
  83.         outb(ata_base+5, (unsigned char)(addr>>16)); /* high addr */
  84.  
  85.  
  86.         ataint = 0;
  87.         printf("waiting for int\n");
  88.  
  89.         outb(ata_base+7, 0xC8);     /* cmd read 28 dma */
  90.        
  91.     atabsw(2, 4, 1);    /* reset interrupt bit */
  92.         atabsw(0, 8|1 ,1);  /* set start bit and read bit */
  93.  
  94.         while(!ataint)
  95.         ;
  96.  
  97.         printf("=%s\n",buffer);
  98.  
  99. }
  100.  
  101. atint1()
  102. {
  103.         ataint = 1;
  104.         printf("ATA INT 1 \n");
  105. }
  106.  
  107. atint2()
  108. {
  109.         printf("ATA INT 2 \n");
  110. }
  111.  
  112. /* bus master write - len in bytes */
  113. atabsw(int offset, unsigned val, int len)
  114. {
  115.         if (ata_bar[4] == 0)
  116.         {
  117. error:
  118.                 printf("atabsw cannot comply\n");
  119.                 return -1;
  120.         }
  121.         switch (len) {
  122.                 case 1:
  123.                         outb(offset+(ata_bar[4] & (~1)),val);
  124.                         break;
  125.                 case 2:
  126.                         outw(offset+(ata_bar[4] & (~1)),val);
  127.                         break;
  128.                 case 4:
  129.                         outl(offset+(ata_bar[4] & (~1)),val);
  130.                         break;
  131.                 default:
  132.                         goto error;
  133.         }
  134. }
  135.  
  136. /* wait until not busy */
  137. atawait()
  138. {
  139.         int i;
  140.         extern ksleep(int);
  141.         for (i = ATATIMEOUT; i > 0; i--) {
  142.                 if ( !(inb(ata_base+7) & (1<<7))  )  /* read busy flag */
  143.                         return;
  144.                 ksleep(1);
  145.         }
  146.         printf(" ata timeout\n");
  147.         return -1;
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement