Page 1 of 1

Identify command doesn't work in VirtualBox with AHCI.

Posted: Sun Aug 04, 2013 4:12 pm
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;
	}

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

Posted: Tue Aug 06, 2013 3:35 pm
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.