I bought a cheap laptop online to test my OS on it, and it works pretty good.
Im currently adjusting / coding new drivers to support the hardware.
With the help of the AHCI article in the wiki I coded a driver for the SATA controller and it works fine on VBox, VMWare and QEMU.
Unfortunately it doesnt work on the real hardware
I've got a Lenovo T400, it has a ICH9 chipset and the SATA controller PCI id is: 1.6.0 -> 0x2929 @ 0x8086
I logged some variables and read this data sheet:
http://www.intel.com/content/dam/www/pu ... v1-3-1.pdf
CAP.SAM is on all VMs 1 but on my laptop it is 0
GHC is completely 0 (therefore GHC.AE is not set either) on the laptop
The data sheet says:
Which means I should activate GHC.AE manually.The implementation of this bit is dependent upon the value of the CAP.SAM bit.
If CAP.SAM is '0', then GHC.AE shall be read-write and shall have a reset value of '0'.
If CAP.SAM is '1', then AE shall be read-only and shall have a reset value of '1'.
If I do that, all the flags in the port.ssts are 0 (and not DET_PRESENT, IPM_ACTIVE) therefore I cant rebase them.
If I dont activate AHCI mode by writing the bit, I can rebase the ports but reading from them times out.
My code:
Code: Select all
if(pci_info->class.sub_class == 6) //AHCI
{
printf("Device is AHCI ready!\n");
abar = (HBA_MEM*)(pci_info->address5 & 0xFFFFE000);
malloc_mark_used_adr((void*)abar);
//Needed to be set for a full reset
abar->ghc |= 0x80000000;
Sleep(100);
//Resetting HBA
abar->ghc |= 1;
while(abar->ghc & 1)
Sleep(10);
Sleep(100);
//Enable AHCI if not enabled yet
if (!(abar->ghc & 0x80000000))
abar->ghc |= 0x80000000;
int i;
for(i = 0; i < 32; i++)
{
//Check for drive status
if(!(abar->pi & (1 << i)))
continue;
if((abar->ports[i].ssts & 0x0F) != HBA_PORT_DET_PRESENT || ((abar->ports[i].ssts >> 8) & 0x0F) != HBA_PORT_IPM_ACTIVE)
continue;
port_rebase(&abar->ports[i], i);
malloc_mark_used_adr(*(void**)&abar->ports[i]);
ahci_devices[i].available = true;
ahci_devices[i].type = abar->ports[i].sig;
ahci_devices[i].has_data = false;
device_count++;
}
}
Thanks in advance!