some AHCI functions

This commit is contained in:
VoidNV 2020-04-27 13:38:22 -05:00
parent 5465fba708
commit c387ee9b0a
4 changed files with 121 additions and 15 deletions

93
src/Home/ac.CC Executable file
View file

@ -0,0 +1,93 @@
//TODO: Test
I64 AHCILBA48CapacityGet(U16 *id_record)
{//Get capacity of drive.
return *&id_record[ATA_IDENT_LBA48_CAPACITY](U64 *) - 1;
//return (id_record)(U64 *)[ATA_IDENT_LBA48_CAPACITY / 4] - 1;
}
I64 AHCIPortCmdSlotGet(CAHCIPort *port)
{//Get next free command slot in port; if none, return -1.
I64 i;
U32 slots = port->sata_active | port->cmd_issue;
for (i = 0; i < blkdev.cmd_slot_count; i++)
{
if (!(slots & 1))
return i;
slots >>= 1;
}
return -1;
}
Bool AHCIPortIsIdle(CAHCIPort *port)
{//Check if command engine is running on port.
return !(port->cmd & (AHCI_PxCMDF_ST | AHCI_PxCMDF_CR | AHCI_PxCMDF_FR | AHCI_PxCMDF_FRE));
}
U0 AHCIPortCmdStop(CAHCIPort *port)
{//Stop command engine on port.
//Btr(&port->cmd, AHCI_PxCMDf_ST);
//Btr(&port->cmd, AHCI_PxCMDf_FRE);
port->cmd &= ~(AHCI_PxCMDF_ST | AHCI_PxCMDF_FRE);
//while (port->cmd & (AHCI_PxCMDF_CR | AHCI_PxCMDF_FR));
while (Bt(&port->cmd, AHCI_PxCMDf_CR) || Bt(&port->cmd, AHCI_PxCMDf_FR));
}
U0 AHCIPortCmdStart(CAHCIPort *port)
{//Start command engine on port.
while (Bt(&port->cmd, AHCI_PxCMDf_CR))
Bts(&port->cmd, AHCI_PxCMDf_FRE);
Bts(&port->cmd, AHCI_PxCMDf_ST);
//port->command |= AHCI_PxCMDF_FRE | AHCI_PxCMDF_ST;
}
Bool AHCIPortWait(CAHCIPort *port, F64 timeout)
{//Wait until DRQ and BSY are clear in the port task file.
do
if (!(port->task_file_data & (ATAS_DRQ | ATAS_BSY)))
return TRUE;
while (timeout > tS);
return FALSE;
}
//TODO: explain&comment statements in this function
U0 AHCIPortReset(CAHCIPort *port)
{//Software reset of port. Port cmd engine must be started after this.
//If port is not responsive, then perform a full port reset.
AHCIPortCmdStop(port);
port->interrupt_status = port->interrupt_status; //Acknowledge all interrupt statuses.
if (!AHCIPortWait(port, tS + 1))
{//Perform a 'more intrusive' HBA<->Port comm reset (sec. 10.4.2 of spec).
port->sata_ctrl = AHCI_PxSCTLF_DET_INIT;
Sleep(1);
port->sata_ctrl = 0;
}
while (port->sata_status & 0xF != AHCI_PxSSTSF_DET_PRESENT);
port->sata_error = 0;
}
U0 AHCIPortIdentify(CBlkDev *bd)
{//Perform the ATA_IDENTIFY command and set bd.dev_id_record to result.
}
U0 AHCIInit()
{
CAHCIHba *hba;
CAHCIPort *port;
I64 i, bdf = PCIClassFind(PCIC_STORAGE << 16 | PCISC_AHCI << 8 + 1, 0); //0x010601, last byte = prog_if, AHCI 1.0 support.
if (bdf == -1)
{
"No AHCI controller found.\n";
return;
}
hba = dev.uncached_alias + PCIReadU32(bdf.u8[2], bdf.u8[1], bdf.u8[0], PCIR_BASE5) & ~0x1F; //Last 5 bits not part of addr.
Bts(&hba->ghc, AHCI_GHCf_HBA_RESET);
while (Bt(&hba->ghc, AHCI_GHCf_HBA_RESET));
Bts(&hba->ghc, AHCI_GHCf_AHCI_ENABLE);
}

View file

@ -3310,17 +3310,30 @@ class CCacheBlk
public class CBlkDevGlobals public class CBlkDevGlobals
{ {
CBlkDev *blkdevs; CBlkDev *blkdevs;
U8 *default_iso_filename; //$TX,"\"::/Tmp/CDDVD.ISO\"",D="DEFAULT_ISO_FILENAME"$ CDrive *drvs,
U8 *default_iso_c_filename; //$TX,"\"::/Tmp/CDDVD.ISO.C\"",D="DEFAULT_ISO_C_FILENAME"$ *let_to_drive[32];
U8 *tmp_filename; U8 *default_iso_filename, //$TX,"\"::/Tmp/CDDVD.ISO\"",D="DEFAULT_ISO_FILENAME"$
U8 *home_dir; *default_iso_c_filename, //$TX,"\"::/Tmp/CDDVD.ISO.C\"",D="DEFAULT_ISO_C_FILENAME"$
CCacheBlk *cache_base,*cache_ctrl,**cache_hash_table; *tmp_filename,
I64 cache_size,read_count,write_count; *home_dir,
CDrive *drvs,*let_to_drive[32]; boot_drive_let,
I64 mount_ide_auto_count, first_hd_drive_let,
ins_base0,ins_base1; //Install cd/dvd controller. first_dvd_drive_let;
U8 boot_drive_let,first_hd_drive_let,first_dvd_drive_let; CAHCIHba *ahci_hba;
Bool dvd_boot_is_good,ins_unit,pad[3]; CCacheBlk *cache_base,
*cache_ctrl,
**cache_hash_table;
I64 cache_size,
read_count,
write_count,
cmd_slot_count,
mount_ide_auto_count,
ins_base0,
ins_base1; //Install cd/dvd controller.
Bool dvd_boot_is_good,
ins_unit,
ahci64,
pad[2];
}; };
#help_index "File/Internal" #help_index "File/Internal"

View file

@ -222,9 +222,9 @@ public I64 SysRep(I64 type=0xFF, I64 handle=0, Bool show_all_flags=FALSE, I64 me
"Image Size\t\t:$$BLACK$$%d bytes$$FG$$\n", (0x10000 - bios_info->start_address_segment) * 16; "Image Size\t\t:$$BLACK$$%d bytes$$FG$$\n", (0x10000 - bios_info->start_address_segment) * 16;
"ROM Size\t\t\t:$$BLACK$$"; "ROM Size\t\t\t:$$BLACK$$";
if (bios_info->rom_size == 0xFF) if (bios_info->rom_size == 0xFF)
"%d %zB$$FG$$\n", bios_info->extended_rom_size & ~0xC000, Bt(&bios_info->extended_rom_size, 14), "M\0G"; "%d %ziB$$FG$$\n", bios_info->extended_rom_size & ~0xC000, Bt(&bios_info->extended_rom_size, 14), "M\0G";
else else
"%d KB$$FG$$\n", (bios_info->rom_size + 1) * 64; "%d KiB$$FG$$\n", (bios_info->rom_size + 1) * 64;
if (Bt(&bios_info->flags, 3)) if (Bt(&bios_info->flags, 3))
"Flags Not Supported$$FG$$\n"; "Flags Not Supported$$FG$$\n";
else else