qemu-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-discuss] Unable to use DMA of PCI IDE bus master


From: Yanjun Yang
Subject: Re: [Qemu-discuss] Unable to use DMA of PCI IDE bus master
Date: Sat, 25 Jun 2016 20:49:44 +0800

After a few test on older release of QEMU, I can conform my code works fine
with version 1.2.2, but not with version 1.3.0.  The ide code seems no big differences.
However, the "pci_dma_read" in "bmdma_prepare_buf" function was unable
to get the right PRD content,  and always put zeroes into the prd buffer.

I think there must be some codes behind pci_dma_read cause my trouble, may
someone familiar with dma/pci/memory could give me a clue. Thanks in advance.

Cheers,
Pluto

On Fri, Jun 24, 2016 at 11:16 AM, Yanjun Yang <address@hidden> wrote:


On Fri, Jun 24, 2016 at 10:00 AM, Jakob Bohm <address@hidden> wrote:
On 24/06/2016 02:13, Yanjun Yang wrote:



On Thu, Jun 23, 2016 at 10:22 PM, Jakob Bohm <address@hidden <mailto:address@hidden>> wrote:

    On 23/06/2016 09:02, Yanjun Yang wrote:
    Hi,

    I was trying to use DMA to transfer a sector of data from hardisk
    to memory.  The attached
     code works under VirtualBox (change bmcr address to D000) but
    not under newer version
    of qemu.  An old version of qemu (1.1.2 from Debian wheezy)
    behave as I expected. Other
    version I tested are 2.5.1.1 from stable branch, 2.6.50 from Arch
    Linux, they both give all
    zero result.

    The following code was compiled by Jwasm(MASM compatible) under
    dos. It'll display the
    first sector of data from disk on screen.  I don't know whether
    there is bugs in my code or
    I miss a configuration of qemu.

    To test my code, I just used a clean install of FreeDos, and run
    the executable compiled by
    Jwasm. I didn't use any special qemu command line switch, just
    "qemu-system-x86_64 dos.cow"
    and run the executable inside the emulated dos environment.

    Any comment will be appreciated. Thanks in advance.

    Which (virtual) hardware disk controller and (if applicable)
    mainboard
    chipset does this assume?

    Is this the hardware emulated by default by the qemu command you ran?

    Are you trying to access the ISA-bus compatible DMA controller at I/O
    port 0x0040 using the obscure fact that older ISA machines only
    decoded the low 10 bits of the I/O port address?


All my test were based on default pc configuration. I also tried "-M pc-1.0" with no luck.
The disk controller always be piix3-ide, and at the end of transfer (interrupt asserted), the
active bit of BM_STATUS register is set, which is not right according to the datasheet.
I wasn't asking what the command line to qemu was.

I was asking how the hardware assumed by your code compares to what
different versions of qemu is trying to emulate.

Because the real issue is: Does qemu correctly emulate the hardware it
is trying to emulate or have you uncovered a bug in some of that
emulation code.

I am also not sure piix3 is still the chipset being emulated.
I know it is piix3 because I used a linux disk-image to boot the machine and got the
info from 'lspci' command.  I think the programming interface I used is ok for most
PATA controller according to what I read from http://wiki.osdev.org

However, I'm not an expert in either field of qemu or IDE controller, I don't know where
to go from this point.  The only thing I know is newer version of qemu breaks code
used to work, maybe I should check this code on real hardware to give me a direction
to look into.
 



    ========== code attached below ===========

        .386
    STACK segment para stack 'STACK'
        db 512 dup(0)
    STACK ends

    BMCR_BASE       equ    0c040h       ; Bus Master Control Register
    base address
    BM_COMMAND_REG  equ    BMCR_BASE    ; Command
    BM_STATUS_REG   equ    BMCR_BASE + 2  ; Status
    BM_PRD_ADDR_REG equ    BMCR_BASE + 4  ; Physical Region
    Descriptor address
    PIO_BASE_ADDR1  equ    01f0h
    PIO_BASE_ADDR2  equ    03f6h
    SEC_NUM         equ    1
    LBASECTOR       equ    0

    DATA segment use16 para 'DATA'
        align 2
    Buf         db      512 * SEC_NUM DUP (0)   ; DMA Buffer
    BufLen      equ     $ - Buf
        align 4
    PRD_Buf     dd      0           ; Physical Region Descriptor Buffer
                dd      0
    DATA ends

    EchoCH   macro   ascii
        mov     ah, 2
        mov     dl, ascii
        int     21h
    endm

    outx macro reg, val
        mov     dx, reg
        mov     al, val
        out     dx, al
    endm

    inx  macro reg
        mov     dx, reg
        in      al, dx
    endm

    CODE segment use16
        assume cs:CODE,ds:DATA,ss:STACK

    start:
        mov     ax, DATA
        mov     ds, ax
        cli
        outx    BM_COMMAND_REG, 00h     ; start/STOP = 0, reset BM status
        outx    BM_STATUS_REG, 00000110B; clear interrupt and error flag
        ; create PRD
        mov     ax, ds
        movzx   eax, ax
        shl     eax, 4                  ; eax=base for data segment
        add     eax, offset Buf         ; eax=base for PRD_Bufj
        mov     PRD_Buf, eax               ; Physical address
        mov     word ptr [PRD_Buf+4], BufLen ; Byte count [15:1]
        mov     word ptr [PRD_Buf+6], 8000h  ; EOT=1
        mov     ax, ds
        movzx   eax, ax
        shl     eax, 4
        add     eax, offset PRD_Buf
        mov     dx, BM_PRD_ADDR_REG
        out     dx, eax                 ; PRD address
        outx    BM_COMMAND_REG, 08h     ; R/W=1, read from disk
        call    WaitDevice
        outx    PIO_BASE_ADDR1+6, 00h   ; Dev=0
        call    WaitDevice
        ;outx    PIO_BASE_ADDR2, 00      ; enable interrupt
        outx    PIO_BASE_ADDR1 + 1, 00h              ; =00
        outx    PIO_BASE_ADDR1 + 2, SEC_NUM          ; sector num
        outx    PIO_BASE_ADDR1 + 3, LBASECTOR
        outx    PIO_BASE_ADDR1 + 4, LBASECTOR/256
        outx    PIO_BASE_ADDR1 + 5, LBASECTOR/65536
        outx    PIO_BASE_ADDR1 + 6, 01000000B OR (LBASECTOR/256/256/256)
        outx    PIO_BASE_ADDR1 + 7, 0C8h             ; 0C8h=READ DMA
        outx    BM_COMMAND_REG, 09h     ; R/W=1, START/STOP=1, start DMA
    @@:
        inx     BM_STATUS_REG
        and     al, 00000100B
        JZ      @B
        outx    BM_STATUS_REG, 00000100B
        outx    BM_COMMAND_REG, 00h     ; START/STOP = 0, stop DMA
        sti
        call    ShowBuf
        mov     ax,4C00h
        int     21h


        ; Wait until BSY=0,DRQ=0
    WaitDevice  proc
    @@:
        inx     PIO_BASE_ADDR1 + 7
        and     al, 10001000b
        jnz    address@hidden
        ret
    WaitDevice  endp

    ;Show what's in the buffer
    ShowBuf     proc
        lea     si, Buf
        cld
        mov     bp, BufLen / 16
    NextLine:
        mov     cx,16
    NextCh:
        lodsb
        push    ax
        shr     al, 4
        call    ToAscii
        EchoCH  al
        pop     ax
        call    ToAscii
        EchoCH  al
        EchoCH  ' '
        loop    NextCh
        EchoCH  0dh
        EchoCH  0ah
        dec     bp
        jnz     NextLine
        ret
    ShowBuf     endp

    ToAscii     proc
        and     al, 0fh
        cmp     al, 10
        jae    address@hidden
        add     al,'0'
        ret
    @@: add     al,'A' - 10
        ret
    ToAscii     endp

    CODE ends
    end start


Enjoy

Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S.  https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark.  Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded





reply via email to

[Prev in Thread] Current Thread [Next in Thread]