Need help with the data returned by AHCI on IDENTIFY

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ashishkumar4
Member
Member
Posts: 73
Joined: Wed Dec 23, 2015 10:42 pm

Need help with the data returned by AHCI on IDENTIFY

Post by ashishkumar4 »

Was reading this thing : http://kurtqiao.github.io/uefi/2014/12/ ... -mode.html and made a 'driver' on its basis. it identifies sata drives and ahci controller on qemu. Then I send an Identify command to the drive and get the information from the device. But I don't know the structure of this 'info' I got from the device. The info or better dump is shown in the screenshot attached. Please help me know exactly what did the device returned and in what order (structure) like there is a structure for PATA Drives which we get while initializing them via IDENTIFY Command. I want a similar struct.
EDIT: After a few tests, I concluded that the first QWORD has something to do with the size of the SATA disk as I made several virtual disks and tried it with them. The qword I got were related to the size of the hard disks but there are a few more things in that qword along with the size. Please help me.
The code I made to do this is:

Code: Select all


int IDENTIFYdrive(HBA_PORT *port)
{

  /***Make the Command Header***/
  HBA_CMD_HEADER *cmdhead=(HBA_CMD_HEADER*)port->clb;//kmalloc(sizeof(HBA_CMD_HEADER));
  //port->clb = (DWORD)cmdhead;
  cmdhead->cfl = 5;
  //cmdhead->a=0;
  cmdhead->w = 0;
  cmdhead->prdtl = 1;
  cmdhead->p = 1;
  cmdhead->c = 1;

  /***Make the Command Table***/
  HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL*)kmalloc(sizeof(HBA_CMD_TBL));
  cmdhead->ctba = (DWORD)cmdtbl;
  memset((void*)cmdtbl, 0, sizeof(HBA_CMD_TBL));
  cmdtbl->prdt_entry[0].dba = kmalloc(4096);
  cmdtbl->prdt_entry[0].dbc = 0x1FF;
  cmdtbl->prdt_entry[0].i = 1;   // interrupt when identify complete
  data_base=cmdtbl->prdt_entry[0].dba;
  memset((void*)data_base,0,4096);

  /***Make the IDENTIFY DEVICE h2d FIS***/
  FIS_REG_H2D *cmdfis = (FIS_REG_H2D*)cmdtbl->cfis;
  //printf("cmdfis %x ",cmdfis);
  memset((void*)cmdfis,0,sizeof(FIS_REG_H2D));
  cmdfis->fis_type = FIS_TYPE_REG_H2D;
  cmdfis->c = 1;
  cmdfis->command = ATA_CMD_IDENTIFY;

  /***Send the Command***/
  port->ci=1;

  /***Wait for a reply***/
  while(1)
  {
    if(port->ci == 0)
    {
      break;
    }
    printf(" %x",port->ci);
  }
  uint32_t *baddr=data_base;
  printf("\n\t The Data we Recieved from identify command:\n\t");
  for(;*baddr;)
  {
    printf("%x ",*baddr);
    ++baddr;
  }
  return 1;
Please help me understand the thing device gave me, those numbers marked in red given to the iobuff after issuing the command.
Attachments
Capture.PNG
The best method for accelerating a computer is the one that boosts it by 9.8 m/s2.
My OS : https://github.com/AshishKumar4/Aqeous
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Need help with the data returned by AHCI on IDENTIFY

Post by Brendan »

Hi,
ashishkumar4 wrote:

Code: Select all

  uint32_t *baddr=data_base;
  printf("\n\t The Data we Recieved from identify command:\n\t");
  for(;*baddr;)
  {
    printf("%x ",*baddr);
    ++baddr;
  }
This doesn't make sense. The IDENTIFY command typically returns a block of 512 bytes, where any of the fields in the middle can be zeros and where most fields are 16-bit (and not 32-bit).

To find the format of the data return by the IDENTIFY command, you need to find the relevant documentation (e.g. google search for "serial ATA specification filetype:pdf"). Sadly, this specification only gives you part of the information and says "Set as indicated in ATA/ATAPI-5" for the rest, so you also need to find the ATA/ATAPI-5 specification.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
ashishkumar4
Member
Member
Posts: 73
Joined: Wed Dec 23, 2015 10:42 pm

Re: Need help with the data returned by AHCI on IDENTIFY

Post by ashishkumar4 »

what? ._. that's sad. yeah I got to know various fields are 0 when I replaced that part with a byte sized array. but if there is no proper documentation, how can I make correctly that which particular information refers to what ._. Sir, how did you do it for your OS or someone you know did it? because I searched Linux kernel. its way to complex. then I searched some microkernels. that also didn't helped.
The best method for accelerating a computer is the one that boosts it by 9.8 m/s2.
My OS : https://github.com/AshishKumar4/Aqeous
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Need help with the data returned by AHCI on IDENTIFY

Post by Brendan »

Hi,
ashishkumar4 wrote:what? ._. that's sad. yeah I got to know various fields are 0 when I replaced that part with a byte sized array. but if there is no proper documentation, how can I make correctly that which particular information refers to what ._. Sir, how did you do it for your OS or someone you know did it? because I searched Linux kernel. its way to complex. then I searched some microkernels. that also didn't helped.
Brendan wrote:To find the format of the data return by the IDENTIFY command, you need to find the relevant documentation (e.g. google search for "serial ATA specification filetype:pdf"). Sadly, this specification only gives you part of the information and says "Set as indicated in ATA/ATAPI-5" for the rest, so you also need to find the ATA/ATAPI-5 specification.

Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
ashishkumar4
Member
Member
Posts: 73
Joined: Wed Dec 23, 2015 10:42 pm

Re: Need help with the data returned by AHCI on IDENTIFY

Post by ashishkumar4 »

:/ ok
The best method for accelerating a computer is the one that boosts it by 9.8 m/s2.
My OS : https://github.com/AshishKumar4/Aqeous
ashishkumar4
Member
Member
Posts: 73
Joined: Wed Dec 23, 2015 10:42 pm

Re: Need help with the data returned by AHCI on IDENTIFY

Post by ashishkumar4 »

Thank you sir, atlast I did it too. After reading the ATA-CS and SATA specs, I have made the information structure. It looks like this:
(got some help from other sources as well) For those who are also seeking this:

Code: Select all


typedef struct SATA_ident
{
		unsigned short	config;		/* lots of obsolete bit flags */
		unsigned short	cyls;		/* obsolete */
		unsigned short	reserved2;	/* special config */
		unsigned short	heads;		/* "physical" heads */
		unsigned short	track_bytes;	/* unformatted bytes per track */
		unsigned short	sector_bytes;	/* unformatted bytes per sector */
		unsigned short	sectors;	/* "physical" sectors per track */
		unsigned short	vendor0;	/* vendor unique */
		unsigned short	vendor1;	/* vendor unique */
		unsigned short	vendor2;	/* vendor unique */
		unsigned char	serial_no[20];	/* 0 = not_specified */
		unsigned short	buf_type;
		unsigned short	buf_size;	/* 512 byte increments; 0 = not_specified */
		unsigned short	ecc_bytes;	/* for r/w long cmds; 0 = not_specified */
		unsigned char	fw_rev[8];	/* 0 = not_specified */
		unsigned char	model[40];	/* 0 = not_specified */
		unsigned short  multi_count; /* Multiple Count */
		unsigned short	dword_io;	/* 0=not_implemented; 1=implemented */
		unsigned short	capability1;	/* vendor unique */
		unsigned short	capability2;	/* bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup word: 50 */
		unsigned char	vendor5;	/* vendor unique */
		unsigned char	tPIO;		/* 0=slow, 1=medium, 2=fast */
		unsigned char	vendor6;	/* vendor unique */
		unsigned char	tDMA;		/* 0=slow, 1=medium, 2=fast */
		unsigned short	field_valid;	/* bits 0:cur_ok 1:eide_ok */
		unsigned short	cur_cyls;	/* logical cylinders */
		unsigned short	cur_heads;	/* logical heads word 55*/
		unsigned short	cur_sectors;	/* logical sectors per track */
		unsigned short	cur_capacity0;	/* logical total sectors on drive */
		unsigned short	cur_capacity1;	/*  (2 words, misaligned int)     */
		unsigned char	multsect;	/* current multiple sector count */
		unsigned char	multsect_valid;	/* when (bit0==1) multsect is ok */
		unsigned int	lba_capacity;	/* total number of sectors */
		unsigned short	dma_1word;	/* single-word dma info */
		unsigned short	dma_mword;	/* multiple-word dma info */
		unsigned short  eide_pio_modes; /* bits 0:mode3 1:mode4 */
		unsigned short  eide_dma_min;	/* min mword dma cycle time (ns) */
		unsigned short  eide_dma_time;	/* recommended mword dma cycle time (ns) */
		unsigned short  eide_pio;       /* min cycle time (ns), no IORDY  */
		unsigned short  eide_pio_iordy; /* min cycle time (ns), with IORDY */
		unsigned short	words69_70[2];	/* reserved words 69-70 */
		unsigned short	words71_74[4];	/* reserved words 71-74 */
		unsigned short  queue_depth;	/*  */
		unsigned short  sata_capability;	/*  SATA Capabilities word 76*/
		unsigned short  sata_additional;	/*  Additional Capabilities */
		unsigned short  sata_supported;	/* SATA Features supported  */
		unsigned short  features_enabled;	/* SATA features enabled */
		unsigned short  major_rev_num;	/*  Major rev number word 80 */
		unsigned short  minor_rev_num;	/*  */
		unsigned short  command_set_1;	/* bits 0:Smart 1:Security 2:Removable 3:PM */
		unsigned short  command_set_2;	/* bits 14:Smart Enabled 13:0 zero */
		unsigned short  cfsse;		/* command set-feature supported extensions */
		unsigned short  cfs_enable_1;	/* command set-feature enabled */
		unsigned short  cfs_enable_2;	/* command set-feature enabled */
		unsigned short  csf_default;	/* command set-feature default */
		unsigned short  dma_ultra;	/*  */
		unsigned short	word89;		/* reserved (word 89) */
		unsigned short	word90;		/* reserved (word 90) */
		unsigned short	CurAPMvalues;	/* current APM values */
		unsigned short	word92;			/* reserved (word 92) */
		unsigned short	comreset;		/* should be cleared to 0 */
		unsigned short  accoustic;		/*  accoustic management */
		unsigned short  min_req_sz;		/* Stream minimum required size */
		unsigned short  transfer_time_dma;	/* Streaming Transfer Time-DMA */
		unsigned short  access_latency;		/* Streaming access latency-DMA & PIO WORD 97*/
		unsigned int    perf_granularity;	/* Streaming performance granularity */
		unsigned int	total_usr_sectors[2]; /* Total number of user addressable sectors */
		unsigned short	transfer_time_pio; 	/* Streaming Transfer time PIO */
		unsigned short	reserved105; 		/* Word 105 */
		unsigned short	sector_sz; 			/* Puysical Sector size / Logical sector size */
		unsigned short	inter_seek_delay;	/* In microseconds */
		unsigned short	words108_116[9]; 	/*  */
		unsigned int	words_per_sector; 	/* words per logical sectors */
		unsigned short	supported_settings; /* continued from words 82-84 */
		unsigned short	command_set_3; 		/* continued from words 85-87 */
		unsigned short  words121_126[6];	/* reserved words 121-126 */
		unsigned short	word127;			/* reserved (word 127) */
		unsigned short	security_status;	/* device lock function
						 * 15:9	reserved
						 * 8	security level 1:max 0:high
						 * 7:6	reserved
						 * 5	enhanced erase
						 * 4	expire
						 * 3	frozen
						 * 2	locked
						 * 1	en/disabled
						 * 0	capability
						 */
		unsigned short  csfo;		/* current set features options
						 * 15:4	reserved
						 * 3	auto reassign
						 * 2	reverting
						 * 1	read-look-ahead
						 * 0	write cache
						 */
		unsigned short	words130_155[26];/* reserved vendor words 130-155 */
		unsigned short	word156;
		unsigned short	words157_159[3];/* reserved vendor words 157-159 */
		unsigned short	cfa; /* CFA Power mode 1 */
		unsigned short	words161_175[15]; /* Reserved */
		unsigned char	media_serial[60]; /* words 176-205 Current Media serial number */
		unsigned short	sct_cmd_transport; /* SCT Command Transport */
		unsigned short	words207_208[2]; /* reserved */
		unsigned short	block_align; /* Alignement of logical blocks in larger physical blocks */
		unsigned int	WRV_sec_count; /* Write-Read-Verify sector count mode 3 only */
		unsigned int   	verf_sec_count; /* Verify Sector count mode 2 only */
		unsigned short	nv_cache_capability; /* NV Cache capabilities */
		unsigned short	nv_cache_sz; /* NV Cache size in logical blocks */
		unsigned short	nv_cache_sz2; /* NV Cache size in logical blocks */
		unsigned short	rotation_rate; /* Nominal media rotation rate */
		unsigned short	reserved218; /*  */
		unsigned short	nv_cache_options; /* NV Cache options */
		unsigned short	words220_221[2]; /* reserved */
		unsigned short	transport_major_rev; /*  */
		unsigned short	transport_minor_rev; /*  */
		unsigned short	words224_233[10]; /* Reserved */
		unsigned short	min_dwnload_blocks; /* Minimum number of 512byte units per DOWNLOAD MICROCODE
		 									command for mode 03h */
		unsigned short	max_dwnload_blocks; /* Maximum number of 512byte units per DOWNLOAD MICROCODE
		 									command for mode 03h */
		unsigned short	words236_254[19];	/* Reserved */
		unsigned short	integrity; 			/* Cheksum, Signature */
} SATA_ident_t;

The best method for accelerating a computer is the one that boosts it by 9.8 m/s2.
My OS : https://github.com/AshishKumar4/Aqeous
Post Reply