I'm struggling with writing an IDE driver. Tried everything but this thing just doesn't work. I'm using bochs, Please see what the hell i'm doing wrong... this is very frustrating i'm stuck on this.
#defines
Code: Select all
#define PRIMARY_DATA_PORT 0x1F0
#define PRIMARY_ERROR_PORT PRIMARY_DATA_PORT+1
#define PRIMARY_SECTOR_COUNT_PORT PRIMARY_DATA_PORT+2 /*Number of sectors to read/write*/
#define PRIMARY_SECTOR_LBA_LOW_PORT PRIMARY_DATA_PORT+3 /*LBA28/CHS/LBA48 specific.*/
#define PRIMARY_CYLLOW_LBA_MID_PORT PRIMARY_DATA_PORT+4 /*Either Cylinder low for CHS or LBA mid bits*/
#define PRIMARY_CYLHIGH_LBA_HIGH_PORT PRIMARY_DATA_PORT+5 /*High bits for cylinder/lba address*/
#define PRIMARY_DRIVE_SELECT_PORT PRIMARY_DATA_PORT+6 /*drive/head select*/
#define PRIMARY_COMMAND_PORT PRIMARY_DATA_PORT+7 /*May also be used to read in status*/
#define PRIMARY_STATUS_PORT 0x3F6 /*Will read Alternate status register instead.Good for us.*/
#define PRIMARY_STATUS_ERROR (1<<0)
#define PRIMARY_STATUS_DATA_READY (1<<3)
#define PRIMARY_STATUS_MODE_SRV 1<<4 /*Don't really know what this is*/
#define PRIMARY_STATUS_DRIVE_FAULT 1<<5
#define PRIMARY_STATUS_DRIVE_READY 1<<6
#define PRIMARY_STATUS_DRIVE_BUSY (1<<7)
#define PRIMARY_COMMAND_INTR_ENABLE 1<<1/*Disable interrupts when set*/
#define PRIMARY_COMMAND_SOFT_RST 1<<2/*Software reset, helpful if device hangs*/
#define PRIMARY_COMMAND_HOB 1<<7/*Read the last High order byte sent to device in LBA48*/
Code: Select all
int read_sectors (struct dev_geo* dev,unsigned int first_block,unsigned char howmany,void *buffer)
{
cmd.lba_address=first_block;
cmd.count=howmany;
cmd.buffer=buffer;
unsigned short* buff=(unsigned short*)cmd.buffer;
unsigned char drive_select=0xa0;
if(IS_BIT_SET(dev->drive_mode,5))
{
drive_select=0xf0;
}
volatile unsigned char status;
drive_select|=(unsigned char)(first_block>>24 & 0x0f);
printk("drive is %x\n",drive_select);
/*while( !(inb(PRIMARY_COMMAND_PORT) & PRIMARY_STATUS_DRIVE_READY))
;
outb(PRIMARY_DRIVE_SELECT_PORT,COMMAND_IDENTIFY_MASTER_DRIVE); Primary, for slave use F0*/
read_again:
while( !(inb(PRIMARY_STATUS_PORT) & PRIMARY_STATUS_DRIVE_READY))
;
outb(PRIMARY_DRIVE_SELECT_PORT,drive_select);
outb(PRIMARY_SECTOR_COUNT_PORT,howmany);
outb(PRIMARY_SECTOR_LBA_LOW_PORT,(unsigned char)first_block);
outb(PRIMARY_CYLLOW_LBA_MID_PORT,(unsigned char)(first_block>>8 & 0xff));
outb(PRIMARY_CYLHIGH_LBA_HIGH_PORT,(unsigned char)(first_block>>16 &0xff));
// printk("%s, %x\n",__FUNCTION__,inb(PRIMARY_STATUS_PORT));
outb(PRIMARY_COMMAND_PORT,COMMAND_READ_SECTORS);
int buff_index=0;
while( cmd.count>0);
return howmany;
Code: Select all
void disk_handler(PushRegisters *reg)
{
if(!(inb(PRIMARY_STATUS_PORT) & PRIMARY_STATUS_DATA_READY)){
printk("[1]%s ,%x\n",__FUNCTION__,inb(PRIMARY_COMMAND_PORT));
return;}
printk("[2]%s %x\n",__FUNCTION__,inb(PRIMARY_COMMAND_PORT));
unsigned short* buff=(unsigned short*)cmd.buffer;
//printk("reading sectors[PKS]\n");
int j=0;
for(;j<256;j++)
{
buff[256*cmd.sectors_served+j]=ins(PRIMARY_DATA_PORT);
}
cmd.count--;
cmd.sectors_served++;
//printk("done\n");
inb(PRIMARY_COMMAND_PORT);
printk("%s %x\n",__FUNCTION__,inb(PRIMARY_COMMAND_PORT));
}
This is driving me into desperation, would do anything for correct code!