ATA DMA чтение

Тема в разделе "WASM.OS.DEVEL", создана пользователем rei3er, 6 май 2007.

  1. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    есть небольшая проблема
    пытаюсь разобраться c DMA, вот есть код, вроде все работает правильно и чтение завершается успешно, но винчестер после завершения чтения по-прежнему сигнализирует о своей активности (не гаснет диод), в чем может быть причина, может чего в коде не учел, кому не лень, посмотрите код, что в нем может быть ошибочного
    Код (Text):
    1. ...
    2.         mov eax, 24
    3. @@:
    4.  ;mask all IRQ lines
    5.     lea ecx, [eax * 2 + 0xE]
    6.     mov dword [0xFEC00000], ecx
    7.     or  dword [0xFEC00010], 0x10000
    8.     dec eax
    9.     jnz @B
    10.  
    11. ; unmask IRQ14 (IDE channel 0)
    12.     mov dword [0xFEC00000], 0x10 + 14 SHL 1
    13.     mov dword [0xFEC00010], 0x8020
    14.     sti
    15.  
    16. IDE_DEVICE_ID   = 0x24DB
    17. IDE_VENDOR_ID   = 0x8086
    18.  
    19.     mov eax, 0x80000100
    20. ; find 82801EB
    21. start:
    22.     mov ebx, eax
    23.     mov edx, 0xCF8
    24.     out dx, eax
    25.     mov edx, 0xCFC
    26.     in  eax, dx
    27.     mov edx, eax
    28.     and edx, 0x0000FFFF
    29.     cmp edx, IDE_VENDOR_ID
    30.     jnz continue
    31.     shr eax, 16
    32.     cmp eax, IDE_DEVICE_ID
    33.     jnz continue
    34. ; read bus mastering BAR
    35.     mov eax, ebx
    36.     or  eax, 0x20
    37.     mov edx, 0xCF8
    38.     out dx, eax
    39.     mov edx, 0xCFC
    40.     in  eax, dx
    41.     and eax, 0x0000FFF0
    42.  ; get address of bus mastering registers
    43.     mov ecx, eax
    44. ; enable interrupts
    45.  from device
    46.     xor eax, eax
    47.     mov edx, 0x3F6
    48.     out dx, al
    49. ; wait BSY = 0
    50.     mov edx, 0x1F7
    51. @@:
    52.     in  al, dx
    53.     test al, 0x80
    54.     jnz @B
    55. ; set device, address mode
    56.     mov al, 0xE0
    57.     mov edx, 0x1F6
    58.     out dx, al
    59. ; wait BSY = 0, DRDY = 1
    60.     mov edx, 0x1F7
    61. @@:
    62.     in  al, dx
    63.     test al, 0x80
    64.     jnz @B
    65.     test al, 0x40
    66.     jz @B
    67. ; set LBA address
    68.     mov edx, 0x1F3
    69.     xor al, al
    70.     out dx, al
    71.     inc edx
    72.     out dx, al
    73.     inc edx
    74.     out dx, al
    75. ; set count of sectors
    76.     mov edx, 0x1F2
    77.     xor eax, eax
    78.     inc eax
    79.     out dx, al
    80. ; set PRD
    81.  address
    82.     mov edx, ecx
    83.     add edx, 4
    84.     mov eax, prd
    85.     out dx, eax
    86. ; set R/W bit
    87.     mov edx, ecx
    88.     mov eax, 8
    89.     out dx, al
    90. ; send command
    91.     mov edx, 0x1F7
    92.     mov eax, 0xC8
    93.     out dx, al  ; read DMA
    94. ; enable bus mastering
    95.     mov edx, ecx
    96.     mov eax, 9
    97.     out dx, al
    98.     jmp @F
    99. continue:
    100.     mov eax, ebx
    101.     add eax, 0x800
    102.     test eax, 0x7F000000
    103.     jz start
    104. @@:
    105.     hlt
    106.     mov dword [0xB8000], 0x0F31 ; true
    107.     jmp @B
    108. ...
    109. ide0_interrupt:
    110.         mov edx, ecx
    111.         xor eax, eax
    112.         out dx, al ; stop bus mastering
    113.         and dword [0xFEE000B0], 0 ; send EOI
    114.         iretd
    115.  
    116. ...
    117. align 8
    118. prd:
    119.     dd 0x7C00
    120.     dw 512
    121.     dw 0x8000