ide_initialize is not finding any drives
Posted: Mon Dec 28, 2015 12:12 pm
I've tried to implement HDD support. I'm readed the tutorial from Quafios creator, but ide_initialize is not finding any drives. My code is:
It's not finding any drives, but displays me just Found ATA Drive 0 GB - <either nothing or some stupid unprintable text> 4 times.
This is my init function:
Code: Select all
void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2, unsigned int BAR3, unsigned int BAR4)
{
debug_print(NOTICE,"ide_initialize: started");
int j, k, count = 0;
BAR0 &= 0xFFFFFFFC;
BAR1 &= 0xFFFFFFFC;
BAR2 &= 0xFFFFFFFC;
BAR3 &= 0xFFFFFFFC;
BAR4 &= 0xFFFFFFFC;
debug_print(NOTICE,"ide_initialize: detecting I/O ports");
// 1- Detect I/O Ports which interface IDE Controller:
channels[ATA_PRIMARY ].base = (BAR0) + 0x1F0*(!BAR0);
channels[ATA_PRIMARY ].ctrl = (BAR1) + 0x3F4*(!BAR1);
channels[ATA_SECONDARY].base = (BAR2) + 0x170*(!BAR2);
channels[ATA_SECONDARY].ctrl = (BAR3) + 0x374*(!BAR3);
channels[ATA_PRIMARY ].bmide = (BAR4) + 0; // Bus Master IDE
channels[ATA_SECONDARY].bmide = (BAR4) + 8; // Bus Master IDE
debug_print(NOTICE,"ide_initialize: ide_write()");
ide_write(ATA_PRIMARY , ATA_REG_CONTROL, 2);
ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 2);
debug_print(NOTICE,"ide_initialize: detecting devices");
// 3- Detect ATA-ATAPI Devices:
int i;
for (i = 0; i < 2; i++)
{
debug_print(NOTICE,"ide_initialize: cycle 1");
for (j = 0; j < 2; j++) {
debug_print(NOTICE,"ide_initialize: cycle 2");
unsigned char err = 0, type = IDE_ATA, status;
ide_devices[count].reserved = 0; // Assuming that no drive here.
debug_print(NOTICE,"ide_initialize: vars set");
// (I) Select Drive:
ide_write(i, ATA_REG_HDDEVSEL, 0xA0 | (j<<4)); // Select Drive.
debug_print(NOTICE,"ide_initialize: drive selected");
sleep(1); // Wait 1ms for drive select to work.
debug_print(NOTICE,"ide_initialize: ATA_IDENT");
// (II) Send ATA Identify Command:
ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
sleep(1); // This function should be implemented in your OS. which waits for 1 ms. it is based on System Timer Device Driver.
debug_print(NOTICE,"ide_initialize: Polling");
// (III) Polling:
if (!(ide_read(i, ATA_REG_STATUS))){ debug_print(NOTICE,"ide_initialize: No device is attached."); continue; }// If Status = 0, No Device.
debug_print(NOTICE,"ide_initialize: is ATA?");
while(1) {
status = ide_read(i, ATA_REG_STATUS);
if ( (status & ATA_SR_ERR)) {err = 1; debug_print(ERROR,"ide_initialize: No ATA"); break;} // If Err, Device is not ATA.
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ)){ debug_print(SUCCESS,"ide_initialize: All is right.");break;} // Everything is right.
else{debug_print(ERROR,"IDE Unknown Error");break;}
}
// (IV) Probe for ATAPI Devices:
if (err) {
unsigned char cl = ide_read(i,ATA_REG_LBA1);
unsigned char ch = ide_read(i,ATA_REG_LBA2);
if (cl == 0x14 && ch ==0xEB) type = IDE_ATAPI;
else if (cl == 0x69 && ch ==0x96) type = IDE_ATAPI;
else continue; // Unknown Type (And always not be a device).
ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY_PACKET);
sleep(1);
}
// (V) Read Identification Space of the Device:
ide_read_buffer(i, ATA_REG_DATA, (unsigned int) ide_buf, 128);
// (VI) Read Device Parameters:
ide_devices[count].reserved = 1;
ide_devices[count].type = type;
ide_devices[count].channel = i;
ide_devices[count].drive = j;
ide_devices[count].sign = ((unsigned short *) (ide_buf + ATA_IDENT_DEVICETYPE ))[0];
ide_devices[count].capabilities = ((unsigned short *) (ide_buf + ATA_IDENT_CAPABILITIES ))[0];
ide_devices[count].commandsets = ((unsigned int *) (ide_buf + ATA_IDENT_COMMANDSETS ))[0];
// (VII) Get Size:
if (ide_devices[count].commandsets & (1<<26)){
// Device uses 48-Bit Addressing:
ide_devices[count].size = ((unsigned int *) (ide_buf + ATA_IDENT_MAX_LBA_EXT ))[0];
// Note that Quafios is 32-Bit Operating System, So last 2 Words are ignored.
} else {
// Device uses CHS or 28-bit Addressing:
ide_devices[count].size = ((unsigned int *) (ide_buf + ATA_IDENT_MAX_LBA ))[0];
}
// (VIII) String indicates model of device (like Western Digital HDD and SONY DVD-RW...):
for(k = ATA_IDENT_MODEL; k < (ATA_IDENT_MODEL+40); k+=2) {
ide_devices[count].model[k - ATA_IDENT_MODEL] = ide_buf[k+1];
ide_devices[count].model[(k+1) - ATA_IDENT_MODEL] = ide_buf[k];}
ide_devices[count].model[40] = 0; // Terminate String.
count++;
}
}
// 4- Print Summary:
for (int i = 0; i < 4; i++)
if (ide_devices[i].reserved == 1) {
printf(" Found %s Drive %dGB - %s\n",
(const char *[]){"ATA", "ATAPI"}[ide_devices[i].type], /* Type */
ide_devices[i].size/1024/1024/2, /* Size */
ide_devices[i].model);
}
}
This is my init function:
Code: Select all
void os_lowlevel_init()
{
debug_print(NOTICE,"init: Initializing architecture-specific features...\n");
arch_init(); //Initialize architecture-specific features.
tty_putchar('\n');
debug_print(NOTICE,"init: Initializing memory management...");
init_memory();
debug_print(NOTICE,"init: Initializing PIT...");
setupPIT();
debug_print(NOTICE,"init: Initializing mouse (debug mode)...");
mouse_install();
debug_print(NOTICE,"init: Initializing STDIO...");
init_stdio();
debug_print(NOTICE,"init: Initializing VFS...");
init_rootfs();
debug_print(NOTICE,"init: Initializing ATA...");
ide_initialize(0x1F0, 0x3F4, 0x170, 0x374, 0x000);
debug_print(SUCCESS,"init: All work is done, exiting.");
}