Page 2 of 3

Re: atapi cdrom read problem

Posted: Sun Jun 12, 2016 5:55 am
by Raymond
oh,sorry,status is 0x58

Re: atapi cdrom read problem

Posted: Sun Jun 12, 2016 8:05 pm
by BenLunt
First off, 0x58 is a good thing.

0x58 = 01011000b

which means the busy bit is clear, the RDY bit is set, and the DRQ bit is set.

The "Get Identify Block" technique is just like reading a sector from the disk. You send it the ATA_IDENTIFY command (0xEC) expecting to read back 512 bytes.

1. select the drive
2. wait for the READY bit to be set (bit 6)
3. write the command to the COMMAND port (command = 0xEC)
4. wait for the DRQ bit to be set (bit 3)
5. read 256 words

Don't worry about interrupts at this point.

Also, remember, since your device is a CDROM, the above will probably fail at #4 above, i.e.: The DRQ bit will never be set.

At this point, read the ATA registers. You should get back the 0x01, 0x01, 0xEB, 0x14 combination indicating you have an ATAPI device attached.
Now do the following:

1. select the drive (you may skip this one if you already have it selected)
2. wait for the READY bit to be set (bit 6) (skipping this step for the 0xA1 command, no need to wait)
3. write the command to the COMMAND port (command = 0xA1)
4. wait for the DRQ bit to be set (bit 3)
5. read 256 words

It really is that simple. And with the ATAPI IDENTIFY command, you can skip #1 and #2 above since you already have selected the drive and this command does not require the drive to be ready.

Once you have retrieved this information, you can then start reading sectors.

atapi_data_transfers:
1. select the drive
2. if using DMA, setup the DMA (PCI or ISA)
3. wait for the READY bit to be set (bit 6)
4. write the FEATURES register (write 0x00 for PIO transfers, 0x01 for DMA transfers)
5. write the SECTOR_COUNT register (0x00, it is ignored or is the TAG)
6. write the LOW_BYTE register (0x00)
7. write the MID_BYTE register (LOW_BYTE(buflen) (buf_len = 2048 for CDROMS))
8. write the HIGH_BYTE register (HIGH_BYTE(buflen))
9. write the PACKET_COMMAND to the command register (0xA0)
10. wait for the DRQ bit to be set (optional, it usually is instantly ready, but not always)
11. using PIO, send the 12- or 16-byte command packet
12. wait for the DRQ bit to be set
13. if using PIO, read or write buflen bytes (words or dwords)
13. if using DMA, start the DMA
14. wait for the interrupt...

BTW, my book explains this in detail, along with a lot of other information, such as if you can read/write DWORDs using PIO, how to setup the PCI DMA, SATA commands, etc.
http://www.fysnet.net/media_storage_devices.htm

Hope this helps,
Ben

Re: atapi cdrom read problem

Posted: Tue Jun 14, 2016 3:49 pm
by Raymond
now i have linked up to all the irq by adding below code:

Code: Select all

for(i=0;i<1024;i++){
		io_out8 (ATA_COMMAND (bus), 0xA0);       /* ATA PACKET command */
		cd_buf[i] = io_in16(ATA_DATA (bus));
	}
cause the lower version of bochs vm 2.6.0 has not set low level cdrom,so the cdrom is always not ready,and drq is 0 after a8 command and every time i read data, so i add a0 command to set

the irq to 1.it is a bug.and it will fix up in 2.8.6 version,maybe.

I also added code like you say:

Code: Select all

io_out8 (ATA_DRIVE_SELECT (bus), drive |(1 << 4)|(1<<6));
	io_out8 (ATA_COMMAND (bus), 0xEC);       /* ATA PACKET command */
	while ((status = io_in8 (ATA_COMMAND (bus))) & 0x08){     /* BUSY */
	io_nop();
	}

Code: Select all

io_out8 (ATA_COMMAND (bus), 0xA1);       /* ATA PACKET command */
while (!((status = io_in8 (ATA_COMMAND (bus))) & 0x08)){ 
io_nop();
}
for(i=0;i<256;i++){
	id_buf[i] = io_in16(ATA_DATA (bus));
}
but now after i read data ,i found the all data is 0x85C0,0x85C0,0x85C0,0x85C0 ,it is not my correct data at 64kb of iso file(0x10000)

if i do not add the 0xa1 sending command code above ,the data is all 0x0400(1024),can you tell me what happen to my code?

and is the data of the address 0x10000 in iso file relative to lba 0x20?

Re: atapi cdrom read problem

Posted: Tue Jun 14, 2016 8:25 pm
by BenLunt
Your code

Code: Select all

for(i=0;i<1024;i++){
      io_out8 (ATA_COMMAND (bus), 0xA0);       /* ATA PACKET command */
      cd_buf[i] = io_in16(ATA_DATA (bus));
   }
is in error. You shouldn't send the packet command before each word read.

Also, you need to send it a packet after sending the packet command.
Follow my instructions from 1 to 14 as earlier posted.

Code: Select all

io_out8 (ATA_COMMAND (bus), 0xA1);       /* ATA PACKET command */
while (!((status = io_in8 (ATA_COMMAND (bus))) & 0x08)){
io_nop();
}
for(i=0;i<256;i++){
   id_buf[i] = io_in16(ATA_DATA (bus));
}
That code is just waiting for it to (not) be busy, you must wait for it to be ready to send data.
Look over my posts again and see how to wait for the drive to be ready.

Note that you are actually waiting for the drive to be busy, not waiting for it to not be busy.

Code: Select all

while (!((status = io_in8 (ATA_COMMAND (bus))) & 0x08)){
That code will most likely execute once, since the drive will be busy and you check for it to be not busy.

Since you will be checking for drive ready numerous times throughout your code, it is best to call a function that returns TRUE or FALSE. This way you only write it once and don't have typo's or other errors in some of them as you do in the code block above. And a timeout mechanism is suggested.

Re: atapi cdrom read problem

Posted: Wed Jun 15, 2016 4:25 pm
by Raymond
finaly,i found the problem and fix it ,now i hava the correct value,error is:

Code: Select all

for(i=0;i<12;i++){
		io_out16(ATA_DATA (bus),read_cmd[i]|(read_cmd[i+1]<<8));
	}
it should be like this ,because it is a mistake.I should loop for 6 times

Code: Select all

for(i=0;i<6;i++){
		j=i*2;
		io_out16(ATA_DATA (bus),read_cmd[j]|(read_cmd[j+1]<<8));
	}
and also i need the version 2.8.6 of bochs,because it is not supported cdrom reading before 2.6.8 as that I read the source code of bochs.

Re: atapi cdrom read problem

Posted: Wed Jun 15, 2016 5:46 pm
by BenLunt
Yes, send six (6) 16-bit words to the drive, not twelve (12). (smile) We all make those mistakes at one time or another.

So, does this mean you have successfully read the IDENTIFY block and can now read sectors from the CDROM?

Ben

Re: atapi cdrom read problem

Posted: Fri Jun 17, 2016 6:16 pm
by Raymond
yes,i am successful to read the data from cdrom,and how can i write sectors to the cdrom,does it use the 0xAA as same steps as reading sectors?

And i buy you books of 'media storage device' and 'usb' but what is the book of 'vitual file system' want to tell us,is there any knowledge about the ntfs format?

Re: atapi cdrom read problem

Posted: Fri Jun 17, 2016 6:43 pm
by Raymond
Could you tell me reading ata hard disk with address in 0x20 of pci,is that device pci ide?

Re: atapi cdrom read problem

Posted: Fri Jun 17, 2016 6:49 pm
by Raymond
if the 0x20 should be set a memory address or it is a fixed one?

Re: atapi cdrom read problem

Posted: Sat Jun 18, 2016 1:18 am
by BenLunt
Raymond wrote:yes, i am successful to read the data from cdrom,and how can i write sectors to the cdrom,does it use the 0xAA as same steps as reading sectors?
And i buy you books of 'media storage device' and 'usb' but what is the book of 'vitual file system' want to tell us,is there any knowledge about the ntfs format?
I have never tried to write to a CDROM, though the name states that you shouldn't be able to :-)

Anyway, writing to a writable disc is probably a lot more work since you will need to open a new session, write all data desired, then close the session. Also, this is different depending on the type of media and the filesystem used. Sorry, I don't have much more information about writing to optical discs. This might be something I can add to a later issue.

As for the Virtual File System volume, it explains what type of file system core you will need to allow any file system to be read. For example, your OS should be file system independent, meaning that it should not rely on any specific part of a file system. This book explains how to do that. It describes how to create Device Parameter Blocks (DPBs) for each volume found, a volume being a complete disk/disc or a partition found on the media. It then shows how to call the DPB and then the File System Core to read and write from/to a file system without being file system dependent.

It then describes a few file systems, FAT12, 16, and 32, LeanFS, FYSFS, and ISO 9660 (more commonly known and readable CR-ROMS). It also explains how to create your own file system with the example of the FYSFS. It explains how to create bootable CD-ROM's and other information of this type. It does not explain the NTFS file system due to the fact that NTFS is copyrighted.
Raymond wrote:Could you tell me reading ata hard disk with address in 0x20 of pci,is that device pci ide?
if the 0x20 should be set a memory address or it is a fixed one?
I am sorry, I don't understand your question. Please describe a little more.

Thanks,
Ben

Re: atapi cdrom read problem

Posted: Sat Jun 18, 2016 7:06 pm
by Raymond
you know the address of DMA bus master register is stored in the 0x20 offset of pci config space for ide .Is it a fixed address or i need to set it as a value.The address must be a physical address of memory i think.

Re: atapi cdrom read problem

Posted: Sat Jun 18, 2016 9:44 pm
by BenLunt
Okay, yes offset 0x20, or BAR 4 is the address to the Bus Master DMA. However, you must be sure that bit 7 in the Programming Interface field is set or you do not have a Bus Master DMA and you must use ISA DMA or PIO transfers.

If bit 7 is set, then you may use the physical address stored in BAR 4 for the Bus Master DMA, which has two channels, each having a Command, Status, and Address register. This is explained starting with page 9-6 of the Media Storage Devices volume.

Note that the address stored in BAR 4 follows the PCI BAR rules of the lower bits indicating Port I/O or memmapped I/O, etc.

Re: atapi cdrom read problem

Posted: Mon Jun 20, 2016 4:10 pm
by Raymond
Does it mean the physical address stored in the pci config space is a real physical address in the memory?And when i use the registers,

i just access their in the memory that be an offset of the physical address?

Code: Select all

0x4000-->physcial address ,command register
0x4001-->resv
0x4002-->status register
0x4003-->resv
0x4004-->BM0 address
Is it like that?

Re: atapi cdrom read problem

Posted: Mon Jun 20, 2016 4:55 pm
by BenLunt
You are correct, however, with a value of 0x4000, this looks to me like it will be port I/O, not mem-mapped I/O.

What are the lower significant bits of the dword read from BAR 4 (0x20)?

If bit 0 is set, you need to use Port I/O to write to the controller.

Re: atapi cdrom read problem

Posted: Tue Jun 21, 2016 6:33 am
by Raymond
thank you,ben.

And in the pci-e specific,there are 4096 bytes in pci config space,at offset 0x60-0x63,what are they supposed to mean?I saw the bochs code ,maybe they are relative to irq no.

what is your suggestion?