qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] Read DMA command (0xC8)


From: spam collector
Subject: [Qemu-devel] Read DMA command (0xC8)
Date: Thu, 28 Jul 2016 01:33:02 -0400 (EDT)

Hello everyone, 

A little background if I may. 

I have been doing OS development for some time and even started with QEMU 
way back when. Shortly after I started, though, I found Bochs and found it 
to be more to my liking. I went on to submit many improvements to Bochs 
including the initial USB code. 

Recently, I have had a few questions about QEMU and decided to take a look 
at it again. I run WinXP and so went to https://qemu.weilnetz.de/ and 
installed the latest package there. 

BTW, I am the reason for the recent patch request from Stefan for the 
truncation of the para file :-) 

I then started to run a few images and found that I could not get QEMU to 
emulate the IDE READ_DMA command (0xC8). Therefore, I went testing my 
code, after all, it probably is my code, though it works fine in Bochs 
and Oracle VirtualBox. 

After some testing, I still couldn't get it to work, so I went 
investigating and found 
http://comments.gmane.org/gmane.comp.emulators.qemu/15307 
though currently the page is down, it suggests a patch to make 
FreeBSD work with the Bus Master. 

This suggested to me that maybe, as far as QEMU was concerned, I am not 
setting up the BusMaster in the correct sequence...No improvement. 

After many different sequences, including exactly following page 99 of 
the Piix3 specs, I still don't have the command working. 

Debug messages... 

Here is a list of message to show what I am doing and exactly what the 
values are: (Please ignore the initial xx-xxxxxxxxx number, and I will 
try to help with word-wrap) 

00-543274621: ATA: Detect ATA drive: cntlr base = 0x01F0 drive = 0 
00-543274621: ATA: Drive reset: 0x01F0 (0) 
00-543274619: ATA: Setting SRST bit 
00-543274619: ATA: Clearing SRST bit 
00-543274617: ATA: Error Register returned: 0x01 
00-543274617: ATA: Detect controller bytes: (0) 0x00 0x00 
00-543274617: ATA: Type_id returned 0x0000 atapi = 0 atapi_type = 0 
00-543274616: ATA: Sending Identify Command 
00-543274616: ATA: ata_tx_rx_data: cmn = EC, lba = 0, len = 512 bytes, 
buf address = 0x0039C2B0 
00-543274610: ATA: 32-bit PIO is allowed...(0x0001) 
00-543274610: ATA: atapi = 0, removable = 0 
00-543274609: ATA: Highest ATA version = 7 
00-543274609: ATA: Is 48-bit capable = 1 
00-543274609: ATA: Returned capacity: 201600 sectors 
00-543274306: ATA: Words per sector: 256 

At this point I have detected an ATA compatible device. So, skipping a 
lot of other things, I want to just read a sector from the disk, say 
sector 35... 
(Note, it is not an ATAPI device. If it was, 0xC8 wouldn't work anyway) 

00-543272416: ATA: ata_read_sectors: lba = 35, count = 1, 
buf address = 0x03F10000 
00-543272415: ATA: ata_tx_rx_data: cmn = C8, lba = 35, len = 512 bytes, 
buf address = 0x03F10000 
00-543272415: ATA: ata_create_dma_table: table at 0x03C10000, 
first entry: 0x03F10000, total transfer size = 512 
00-543272414: ATA: BusMaster Base Address: 0xC041 
(Obviously I am masking off the lower bits and using PIO) 
00-543272413: ATA: Command Reg: 0x0107 
(IO, Mem, and BusMaster is enabled, though I don't know why QEMU 
has bit 8 set...) 
00-543272413: ATA: Status Reg: 0x0280 
(Status register says fast back-to-back and medium device select timing) 
00-543272413: ATA: Channel = 0 
(we are using the first channel (0x1F0), and we set up the PRD Table) 
00-543272413: ATA: Channel 0: 
00-543272413: ATA: BusMaster Command: 0x00 
00-543272412: ATA: Status: 0x00 
00-543272412: ATA: Address: 0x03C10000 
00-543272411: ATA: PRD Entry 0: [03C10000]: 0x03F10000 0x80000200 
(The address of the PRDT is 0x3C10000, doesn't cross a 64k boundary) 
(The address of the first transfer doesn't either, nor does the table 
use more than 4k) 
(I'm transfering 0x200 bytes, and have the EOT set) 
(Note that I have not set the direction bit yet...) 
00-543272410: ATA: ATA Data: 0xFF 
00-543272410: ATA: Error: 0x01 (ATA_FEATURE should be 0x00) 
00-543272410: ATA: Count: 0x01 
00-543272410: ATA: Low: 0x23 (35 dec) 
00-543272409: ATA: Mid: 0x00 
00-543272409: ATA: High: 0x00 
00-543272409: ATA: Dev/Head: 0x60 
(Side Note: even though bits 7 and 5 are obsolete, I set them in code 
before this, yet QEMU cleared bit 7. Any reason for this?) 
00-543272409: ATA: altStatus: 0x50 
(Status says Drive is Ready) 

Here is were I send the 0xC8 command by writing to the COMMAND Register. 

00-543271956: ATA: ata_wait returned FALSE (D8) (00) 

Then, in the above debug line, I wait for the busy bit to clear so that I 
can check the Data Request (DRQ) bit. However, the busy bit never clears, 
even though the DRQ bit is set. 

The (alt)status register shows 0xD8 (ALT_Error = 0x00): 
BSY = 1 
DRDY = 1 
Command Spec (bit 4) 
DRQ = 1 

Even after waiting quite some time, the BSY bit never clears. 

I decided to ignore the BSY bit and just wait for the DRQ bit to become 
set (even though any other bit in the status register is invalid while 
the BSY bit is set). It still never sent any data. 

*If* the BSY bit becomes clear and the DRQ bit becomes set, this is when 
I would set the direction bit and the start bit in the BusMaster's 
Command register. 

One thing I tried was setting the direction bit as I was initializing the 
BusMaster above. This had no effect. 

I am using the Windows port at 
https://qemu.weilnetz.de/ (Thanks Stefan for your work) 
and have not tried any Linux port. 

At this point, I really have to say that it is something wrong with 
QEMU, since I cannot see anything wrong with my code, *and* it works 
with Bochs, VirtualBox, and on real hardware. However, I have been 
wrong before, once or twice... 

I know that WinXP uses this command (0xC8) and ran a version of that 
in QEMU. It worked, though I am not sure if 0xC8 actually worked or if 
WinXP switched to PIO reading after 0xC8 failed. 

If anyone has any comments, I would greatly appreciate them. 

Thanks, 
Ben 




reply via email to

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