|
From: | Jakob Bohm |
Subject: | Re: [Qemu-discuss] Unable to use DMA of PCI IDE bus master |
Date: | Fri, 24 Jun 2016 04:00:03 +0200 |
User-agent: | Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.1.1 |
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.
========== 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 @B 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 @F 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
[Prev in Thread] | Current Thread | [Next in Thread] |