Identify command doesn't work in VirtualBox with AHCI.

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
ateno3
Member
Member
Posts: 25
Joined: Sun Oct 02, 2011 3:36 am
Location: Spain

Identify command doesn't work in VirtualBox with AHCI.

Post by ateno3 »

Hello everyone.
I continue having problems with the AHCI controller: the Identify Device command (0xEC in ATA Command Set) doesn't work in VirtualBox. I know that there are one device in the port 0 (I've configured it in VirtualBox and I have read it from the PI register in HBA MEM), but when I issue the command which has the Identify Device command, the HBA enables the bit ERR(bit 0) in the TFD register in the port 0.
The code which issue the Identify command is the following:

Code: Select all

s32 AHCI_IdentifyDev(u8 p, u8* mem){
		if(p > 31) return 0x01;
		
		u32 pi = AHCI_MMIO_READ(_hba_mem->pi);
		if(!(pi & (1 << p))) return 0x02;
		if(mem == NULL) return 0x03;
		if(((u32)mem) & 1) return 0x04; // !Alineamiento PAR
		
		HBA_Port* port = &(_hba_mem->ports[p]);
		
		u32 ssts = AHCI_MMIO_READ(port->ssts);
		if(SSTS_DET(ssts) == 0x00) return 0x05;
		if(SSTS_IPM(ssts) == 0x00) return 0x06;
		
		AHCI_StopCMD(p);
		
		u8 cmd_slot = AHCI_PORT_FindFreeCmdSlot(p);
		if(cmd_slot > 31) return 0x07;
		
		HBA_CmdHeader* hdr = (HBA_CmdHeader*) AHCI_MMIO_READ(port->clb);
		hdr += cmd_slot;
		
		hdr->cfl = 5;
		if(port->cmd & CMD_ATAPI) hdr->a = 1;
		else hdr->a = 0;
		hdr->prdtl = 0x01;
		
		HBA_CmdTable* table = (HBA_CmdTable*) hdr->ctba;
		
		memset(table, 0x00, sizeof (HBA_CmdTable) + (hdr->prdtl) * sizeof(HBACMD_PRDT));
		
		table->prdt[0].dba = (u32)mem;
		table->prdt[0].dbau = 0x00;
		table->prdt[0].dbc = 512;
		table->prdt[0].i = 1;
		
		FIS_RegH2D* reg = (FIS_RegH2D*)table->cfis;
		
		reg->type = FIS_REGISTER_H2D;
		reg->c = 1;
		if(port->cmd & CMD_ATAPI) reg->cmd = 0xA1;
		else reg->cmd = 0xEC;
		
		AHCI_PORT_Wait4Free(p);
		
		u32 sact = AHCI_MMIO_READ(port->sact);
		sact |= (1 << cmd_slot);
		AHCI_MMIO_WRITE(sact, port->sact);
		
		u32 ci = AHCI_MMIO_READ(port->ci);
		ci |= (1 << cmd_slot);
		AHCI_MMIO_WRITE(ci, port->ci);
		
		AHCI_StartCMD(p);

		u32 is, err;
		while(1){
			ci = AHCI_MMIO_READ(port->ci);
			sact = AHCI_MMIO_READ(port->sact);
			if(!((ci | sact) & (1 << cmd_slot))) break;
			
			is = AHCI_MMIO_READ(port->is);
			if(is & IS_TFES) return 0x08;

			err = AHCI_MMIO_READ(port->tfd);
			if(err & TFD_STS_ERR) return 0x09;
	
		}
	
		
		is = AHCI_MMIO_READ(port->is);
		if(is & IS_TFES) return 0x08;
	
		return 0x00;
	}
Nable
Member
Member
Posts: 453
Joined: Tue Nov 08, 2011 11:35 am

Re: Identify command doesn't work in VirtualBox with AHCI.

Post by Nable »

This question seems TOO familiar to me. Ok, just check some answers:

Code: Select all

:g identify ahci site:forum.osdev.org
-> http://www.google.ru/search?q=identify+ ... 8&oe=utf-8
First 2 answers:
1) http://forum.osdev.org/viewtopic.php?f=1&t=25826
2) http://forum.osdev.org/viewtopic.php?f=1&t=24349
I also remember some really recent thread about doing working with AHCI under Parallels VM (and possibly other ones like virtualbox) but i cannot find it.

Upd: http://forum.osdev.org/viewtopic.php?f=1&p=224386 - here it is, although it's not about identify. But it may also be useful.
Post Reply