Triple fault while reading disk data in x64 OS
Posted: Wed Nov 20, 2013 11:50 am
HI All,
I ma trying to read hard disk data with AHCI interface as explained in the OSDEV tutorial. For x64, i am setting both dba and dbau. It is working fine for N-1 times. but for last entry it gives triple fault.
#############
##########
Triple Fault
cmdtbl->prdt_entry.dba = (DWORD)buf;
cmdtbl->prdt_entry.dbc = count<<9; // 512 bytes per sector
Please help me by telling my mistake.
I ma trying to read hard disk data with AHCI interface as explained in the OSDEV tutorial. For x64, i am setting both dba and dbau. It is working fine for N-1 times. but for last entry it gives triple fault.
#############
Code: Select all
int read(HBA_PORT *port, DWORD startl, DWORD starth, DWORD count, QWORD buf)
{
printk("\nInside read");
int i;
port->is = (DWORD)-1; // Clear pending interrupt bits
int spin = 0; // Spin lock timeout counter
int slot = find_cmdslot(port);
printk("\nCommand Slot %d\n",slot);
if (slot == -1){
printk("\n slot==-1..i.e. no command slot");
return 0;
}
uint64_t addres=0;
addres=(((addres | port->clbu)<<32)|port->clb);
addres = addres+ kernmem1;
HBA_CMD_HEADER *cmdheader = (HBA_CMD_HEADER *)addres;
cmdheader += slot;
cmdheader->cfl = sizeof(FIS_REG_H2D)/sizeof(DWORD); // Command FIS size
cmdheader->w = 0; // Read from device
cmdheader->prdtl = (WORD)((count-1)>>4) + 1; // PRDT entries count
printk("\nPRDT ENTRIES COUNT[%d]",cmdheader->prdtl);
addres=(((addres | cmdheader->ctbau)<<32)|cmdheader->ctba);
addres = addres+ kernmem1;
HBA_CMD_TBL *cmdtbl = (HBA_CMD_TBL*)(addres);
//memset(cmdtbl, 0, sizeof(HBA_CMD_TBL) + (cmdheader->prdtl-1)*sizeof(HBA_PRDT_ENTRY));
// 8K bytes (16 sectors) per PRDT
for (i=0; i<cmdheader->prdtl-1; i++)
{
cmdtbl->prdt_entry[i].dba = (DWORD)(buf & 0xffffffff);
cmdtbl->prdt_entry[i].dbau = (DWORD)((buf>>32) & 0xffffffff);
cmdtbl->prdt_entry[i].dbc = 8*1024; // 8K bytes
cmdtbl->prdt_entry[i].i = 1;
buf += (4*1024)/4; // 4K words
count -= 16; // 16 sectors
}
// Last entry
printk("\nshashank cmtbkl [%d]",i);
printf("%x", cmdtbl->prdt_entry[i]);
while(1);
cmdtbl->prdt_entry[i].dba = (DWORD)(buf & 0xffffffff);
cmdtbl->prdt_entry[i].dbau = (DWORD)((buf>>32) & 0xffffffff);
while(1);
Triple Fault
cmdtbl->prdt_entry.dba = (DWORD)buf;
cmdtbl->prdt_entry.dbc = count<<9; // 512 bytes per sector
Please help me by telling my mistake.