Show drive model & serial number in SATARep.

Fix mounting bugs.
Change AHCI buffer allocation location from Fs to zenith_task code heap.
Implement DiscEject, DiscLoad.
Change installer to eject disc after installation.
This commit is contained in:
TomAwezome 2021-06-25 23:06:56 -04:00
parent 907b136cc1
commit 9461667bb0
7 changed files with 124 additions and 19 deletions

View file

@ -135,7 +135,7 @@ I64 AHCIAtapiCapacityGet(CBlkDev *bd)
throw('AHCI');
}
buf = CAlloc(8, Fs->code_heap);
buf = CAlloc(8, zenith_task->code_heap);
Bts(&cmd_header->desc, AHCI_CH_DESCf_A);
@ -253,6 +253,28 @@ Bool AHCIAtapiStartStop(CBlkDev *bd, Bool start)
return TRUE;
}
Bool DiscEject(U8 drv_let)
{ // returns whether disc tray was successfully ejected.
try
return AHCIAtapiStartStop(Letter2BlkDev(drv_let), 2);
catch
{
Fs->catch_except = TRUE;
return FALSE;
}
}
Bool DiscLoad(U8 drv_let)
{ // returns whether disc tray was successfully closed & disc loaded.
try
return AHCIAtapiStartStop(Letter2BlkDev(drv_let), 3);
catch
{
Fs->catch_except = TRUE;
return FALSE;
}
}
U0 AHCIPortIdentify(CBlkDev *bd)
{//Perform ATA_IDENTIFY command on ATA/ATAPI drive and store capacity and id record.
CPortCmdTable *cmd_table;
@ -265,7 +287,7 @@ U0 AHCIPortIdentify(CBlkDev *bd)
port->interrupt_status = port->interrupt_status; //TODO: Why?
//Using the code heap for this alloc to stay under 32-bit address space.
dev_id_record = CAlloc(512, Fs->code_heap);
dev_id_record = CAlloc(512, zenith_task->code_heap);
cmd_table = cmd_header->cmd_table_base;
MemSet(cmd_table, 0, sizeof(CPortCmdTable));
@ -606,11 +628,11 @@ U0 AHCIPortInit(CBlkDev *bd, CAHCIPort *port, I64 port_num)
AHCIPortCmdStop(port_num);
//'1K-byte' align as per SATA spec.
port->cmd_list_base = CAllocAligned(sizeof(CPortCmdHeader) * blkdev.cmd_slot_count, 1024, Fs->code_heap);
port->cmd_list_base = CAllocAligned(sizeof(CPortCmdHeader) * blkdev.cmd_slot_count, 1024, zenith_task->code_heap);
port->cmd_list_base_upper = 0;
//Alloc where received FISes will be copied to. '256-byte' align as per spec.
port->fis_base = CAllocAligned(sizeof(CFisReceived), 256, Fs->code_heap);
port->fis_base = CAllocAligned(sizeof(CFisReceived), 256, zenith_task->code_heap);
port->fis_base_upper = 0;
for (i = 0; i < blkdev.cmd_slot_count; i++)
@ -620,13 +642,56 @@ U0 AHCIPortInit(CBlkDev *bd, CAHCIPort *port, I64 port_num)
cmd_header->desc = sizeof(CFisH2D) / sizeof(U32);
//'128-byte' align as per SATA spec, minus 1 since length is 1-based.
cmd_header->cmd_table_base = CAllocAligned(sizeof(CPortCmdTable) + sizeof(CPrdtEntry) * (AHCI_PRDT_MAX_LEN - 1), 128, Fs->code_heap);
cmd_header->cmd_table_base = CAllocAligned(sizeof(CPortCmdTable) + sizeof(CPrdtEntry) * (AHCI_PRDT_MAX_LEN - 1), 128, zenith_task->code_heap);
cmd_header->cmd_table_base_upper = 0;
}
AHCIPortCmdStart(port_num);
AHCIPortIdentify(bd);
}
Bool AHCIAtaInit(CBlkDev *bd)
{
Bool unlock, okay = FALSE;
CPortCmdHeader *cmd_header;
I64 i;
if (!bd->ahci_port)
return FALSE;
unlock = BlkDevLock(bd);
// if we re-init a port, keep memory from leaking.
for (i = 0; i < blkdev.cmd_slot_count; i++)
{
cmd_header = &bd->ahci_port->cmd_list_base(CPortCmdHeader *)[i];
Free(cmd_header->cmd_table_base);
}
Free(bd->ahci_port->cmd_list_base);
Free(bd->ahci_port->fis_base);
// try to init the port, catch if fails.
try
{
AHCIPortInit(bd, bd->ahci_port, bd->port_num);
if (bd->type == BDT_ATAPI)
okay = AHCIAtapiStartStop(bd, TRUE);
else
okay = TRUE;
}
catch
{
Fs->catch_except = TRUE;
okay = FALSE;
ST_WARN_ST "AHCIAtaInit";
}
if (unlock)
BlkDevUnlock(bd);
return okay;
}
U0 AHCIHbaReset()
{
Bts(&blkdev.ahci_hba->ghc, AHCI_GHCf_HBA_RESET);

View file

@ -111,7 +111,7 @@ Bool BlkDevInit(CBlkDev *bd)
bd->max_reads = 128;
bd->max_writes = 1;
// res = IDEATAInit(bd);
res = TRUE; // ahci
res = AHCIAtaInit(bd); // ahci
break;
case BDT_ATAPI:
@ -124,7 +124,7 @@ Bool BlkDevInit(CBlkDev *bd)
bd->max_reads = 128;
bd->max_writes = 0xFFFF * 4;
// if (res = IDEATAInit(bd))
if (res = TRUE) // ahci
if (res = AHCIAtaInit(bd)) // ahci
drive->size = bd->max_blk + 1;
break;
}

View file

@ -277,6 +277,7 @@ U0 DiskChange(U8 drv_let=0)
{
if (bd->type == BDT_ATAPI)
//IDEATAInit(bd); //TODO: This is a kludge for QEMU?
AHCIAtaInit(bd); //TODO: This is a kludge for QEMU? // ahci
DiskCacheInvalidate(drive);
}
Drive(drv_let);

View file

@ -368,7 +368,8 @@ extern I64 AHCIAtaBlksWrite( CBlkDev *bd, U8 *buf, I64 blk, I64 count);
extern I64 AHCIAtapiBlksRead( CBlkDev *bd, U8 *buf, I64 blk, I64 count);
extern Bool AHCIAtapiSeek( CBlkDev *bd, I64 blk);
extern Bool AHCIAtapiStartStop(CBlkDev *bd, Bool start);
extern Bool DiscEject(U8 drv_let);
extern Bool DiscLoad( U8 drv_let);
public extern CBlkDevGlobals blkdev;

View file

@ -236,7 +236,10 @@ Bool DoInstall(Bool prompt_reboot)
{
"Reboot Now ";
if (YorN)
{
DiscEject(':');
Reboot;
};
}
return res;
}

View file

@ -1,8 +1,10 @@
I64 SATARep()
{
I64 /*bdf, */i, num = 0;
I64 /*bdf, */i, j, num = 0;
CAHCIPort *port;
// CPCIDev *pci;
CBlkDev *temp_blkdev;
U16 *st, *model, *serial;
"\nAHCI version %X.%1X%1X\n",
blkdev.ahci_hba->version >> 16, (blkdev.ahci_hba->version & 0xFF00) >> 8, blkdev.ahci_hba->version & 0xFF;
@ -22,6 +24,8 @@ I64 SATARep()
"HBA Base Address: 0x%X", PCIReadU32(bdf.u8[2], bdf.u8[1], bdf.u8[0], PCIR_BASE5) & ~0x1F;
}
*/
if (blkdev.ahci_hba)
{
"\nImplemented Ports:\n\n";
@ -30,23 +34,54 @@ I64 SATARep()
if (Bt(&blkdev.ahci_hba->ports_implemented, i))
{
port = &blkdev.ahci_hba->ports[i];
"$$PURPLE$$ $$BT,\"%d\",LM=\"%d\n\"$$$$FG$$", i, i;
if (port->signature == AHCI_PxSIG_ATA)
"$$LM,4$$$$RED$$Hard Drive $$LTBLUE$$ATA$$FG$$\n";
else if (port->signature == AHCI_PxSIG_ATAPI)
"$$LM,4$$$$RED$$CD/DVD Drive $$LTBLUE$$ATAPI$$FG$$\n";
else
"$$LM,4$$$$RED$$Unknown $$LTBLUE$$0x%0X$$FG$$\n", port->signature;
if (port->signature == AHCI_PxSIG_ATAPI || port->signature == AHCI_PxSIG_ATA)
{
"$$PURPLE$$ $$BT,\"%d\",LM=\"%d\n\"$$$$FG$$", i, i;
"$$LM,0$$\n\n";
if (port->signature == AHCI_PxSIG_ATA)
"$$LM,4$$$$RED$$Hard Drive $$LTBLUE$$ATA$$FG$$\n";
else if (port->signature == AHCI_PxSIG_ATAPI)
"$$LM,4$$$$RED$$CD/DVD Drive $$LTBLUE$$ATAPI$$FG$$\n";
// else
// "$$LM,4$$$$RED$$Unknown $$LTBLUE$$0x%0X$$FG$$\n", port->signature;
"$$LM,0$$\n\t";
temp_blkdev = CAlloc(sizeof(CBlkDev));
AHCIPortInit(temp_blkdev, port, i);
"\n\t";
if (temp_blkdev->dev_id_record)
{
st = CAlloc(40 + 1);
for (j = 0; j < 20; j++)
st[j] = EndianU16(temp_blkdev->dev_id_record[27 + j]);
model = MStrUtil(st, SUF_REM_LEADING | SUF_REM_TRAILING);
"Model: %s\n\t", model;
Free(st);
Free(model);
st = CAlloc(20 + 1);
for (j = 0; j < 10; j++)
st[j] = EndianU16(temp_blkdev->dev_id_record[10 + j]);
serial = MStrUtil(st, SUF_REM_LEADING | SUF_REM_TRAILING);
"Serial: %s\n", serial;
Free(st);
Free(serial);
}
"\n";
BlkDevDel(temp_blkdev);
Free(temp_blkdev);
}
num++;
}
}
}
else
"$$HL,1$$blkdev.ahci_hba$$HL,0$$ is NULL !\n";
"\n";
"$$HL,1$$blkdev.ahci_hba$$HL,0$$ is NULL !\n\n";
return num;
}