Page 1 of 1

How to detect SATA Drives [SOLVED]

Posted: Tue Jan 05, 2016 9:50 pm
by ashishkumar4
I know how to detect PATA Drives, its too easy to do so. But I am having trouble how to detect SATA drives. I know this that if a SATA drive is in the system and if we send 0xEC command to the drive, we should get an ERR bit and two values from 0x1F4 & 0x1F5 (primary). According to the SATA wiki on this osdev site, these should be 0x3C and 0xC3. But the values I get from these ports are completely different when I test it on different systems or on VMWARE and Virtualbox. I get 0x7F from both ports in VMware while I get 0x7D from both in virtualbox. they aint realted to 0x3C or 0xC3 at all.
Please help me on how to detect them and also How to INITIALIZE THEM, Please :'( I am noob in this osdev, so please explain in such a way that I can understand :3 Sorry for that :p

Edit: I got to know how to detect them, That's fairly Simple, Just enumerate the pci buses and find the device with class=0x01, sub class=0x06
I was so stupid :3

Re: How to detect SATA Drives

Posted: Wed Jan 06, 2016 1:13 am
by FusT
SATA drives usually use AHCI mode, unless defined otherwise in the BIOS.
This uses the (on-board) AHCI controller, you should probably start by looking into that: http://wiki.osdev.org/AHCI

Re: How to detect SATA Drives

Posted: Wed Jan 06, 2016 4:23 am
by ashishkumar4
I already went through that wiki >5 times. I have made all the structures etc but I don't know HOW TO SEND AND RECIEVE FIS to the device
Because I said, I am new to osdev, I really don't know how to do that. I mean, with PATA it was easy, just send and receive to and from ports, whatever needed. But I don't understand how to send and receive FIS packets :/ Please help me

Re: How to detect SATA Drives

Posted: Wed Jan 06, 2016 4:48 am
by MollenOS
It says in the Wiki how to do that, read it again, specifically this part AHCI Registers and Memory Structures.
You need to iterate the PCI Bus and locate the AHCI controller, and get the base-port from bar 5 i think it says on the wiki.

Re: How to detect SATA Drives

Posted: Wed Jan 06, 2016 8:50 am
by ashishkumar4
yeah, I want to know what to do after that :3 I am stuck at that point. I have enumerated the pci devices and found the ahci controller, saved its bus and slot values and all other info, but what next? I have configured fis but how to send it to device? I don't know that. thanks :)

Re: How to detect SATA Drives

Posted: Wed Jan 06, 2016 8:56 am
by MollenOS
Again, you are not reading the Wiki, I'm just copying things now:

Each port can attach a single SATA device. Host sends commands to the device using Command List and device delivers information to the host using Received FIS structure. They are located at HBA_PORT.clb/clbu, and HBA_PORT.fb/fbu. The most important part of AHCI initialization is to set correctly these two pointers and the data structures they point to.

So obviously you have to send the FIS to the device using the command list base address which is located in the port-structure:

Code: Select all

typedef volatile struct tagHBA_PORT
{
	DWORD	clb;		// 0x00, command list base address, 1K-byte aligned
	DWORD	clbu;		// 0x04, command list base address upper 32 bits
	DWORD	fb;		// 0x08, FIS base address, 256-byte aligned
	DWORD	fbu;		// 0x0C, FIS base address upper 32 bits
	DWORD	is;		// 0x10, interrupt status
	DWORD	ie;		// 0x14, interrupt enable
	DWORD	cmd;		// 0x18, command and status
	DWORD	rsv0;		// 0x1C, Reserved
	DWORD	tfd;		// 0x20, task file data
	DWORD	sig;		// 0x24, signature
	DWORD	ssts;		// 0x28, SATA status (SCR0:SStatus)
	DWORD	sctl;		// 0x2C, SATA control (SCR2:SControl)
	DWORD	serr;		// 0x30, SATA error (SCR1:SError)
	DWORD	sact;		// 0x34, SATA active (SCR3:SActive)
	DWORD	ci;		// 0x38, command issue
	DWORD	sntf;		// 0x3C, SATA notification (SCR4:SNotification)
	DWORD	fbs;		// 0x40, FIS-based switch control
	DWORD	rsv1[11];	// 0x44 ~ 0x6F, Reserved
	DWORD	vendor[4];	// 0x70 ~ 0x7F, vendor specific
} HBA_PORT;
I got this information by spending 2 minutes on reading the wiki.

Re: How to detect SATA Drives

Posted: Wed Jan 06, 2016 9:30 am
by ashishkumar4
ok I got it, but what to do next :/ yeah I know I am stupid :3 but ...
Means I want to know How to exactly communicate with the devices on PCI. like its easy to communicate with those like PATA, just use inb, outb. What to do, how to send FISs packets to device or receive device to host packets from them? :/ don't get angry on this :3 please explain me :p

Re: How to detect SATA Drives

Posted: Wed Jan 06, 2016 9:51 am
by MollenOS
I can see from the wiki that it uses memory mapped i/o, which means you probably need to setup some list or list of structures in memory, I have no knowledge about how AHCI functions since I'm not at the point of writing an AHCI driver.

What I would do, is read the AHCI specification to see HOW it works and how it handles the requests. Here's a link.

http://www.intel.com/content/www/us/en/ ... 1-3-1.html

I promise you the information you need will be in that document, otherwise go inspect how Linux does it in it's source code. I can't give you a step by step nor do I want to do that.

Re: How to detect SATA Drives

Posted: Wed Jan 06, 2016 10:10 am
by ashishkumar4
Thanks for ur help :D I thought reading specs should be the last option because its my exam time :p but anyways, its the best way. will read it and understand it.

Re: How to detect SATA Drives

Posted: Wed Jan 06, 2016 11:05 am
by cmpxchg64
If you go along with the AHCI code from the wiki there's a slight error in the code (as far as I understand AHCI): The PRDT structure has a 22-bit dbc field, where the lowest bit has to be set to 1. The specs say:
Data Byte Count (DBC): A ‘0’ based value that Indicates the length, in bytes, of the data block.
A maximum of length of 4MB may exist for any entry. Bit ‘0’ of this field must always be ‘1’ to
indicate an even byte count. A value of ‘1’ indicates 2 bytes, ‘3’ indicates 4 bytes, etc.

which means one has to set prdt->dbp = count - 1. Maybe someone who is registered with the wiki could change this.