IDE IDENTIFY

This commit is contained in:
notsomeidiot123 2025-09-20 10:27:15 -04:00
parent c880843b6c
commit 9c1f32a49c
2 changed files with 118 additions and 24 deletions

View File

@ -100,9 +100,9 @@ uint32_t module_api(uint32_t func, ...){
return_value = pm_alloc_64kaligned();
break;
case MODULE_API_KMALLOC_PADDR:
paddr = va_arg(vars, uint32_t);
paddr = (void *)va_arg(vars, uint32_t);
uint32_t size = va_arg(vars, uint32_t);
return_value = kmalloc_page_paddr((uint32_t)paddr, size);
return_value = (uint32_t)kmalloc_page_paddr((uint32_t)paddr, size);
break;
}

View File

@ -74,7 +74,8 @@ make fini function to destroy global object, and free any remaining resources.
#define ATA_TK0NF(a) a & 0x2
//data address mark not found
#define ATA_AMNF(a) a & 0x1;
#define ATA_MASTER 0xa0
#define ATA_SLAVE 0xb0
//commands
#define ATA_CMD_READ_PIO 0x20
#define ATA_CMD_READ_PIO_EXT 0x24
@ -102,13 +103,14 @@ make fini function to destroy global object, and free any remaining resources.
#define PCI_IDE_SUPPORT_DMA(a) (a & 0x80)
#define PCI_CLASS_IS_IDE(a) a == 0x0101;
typedef struct PRD{
uint32_t address;
uint16_t byte_count;
uint16_t reserved;//set msb when last;
}__attribute__((packed)) PRD_T;
uint8_t native_ide_present = 0;
void fini();
@ -143,15 +145,25 @@ uint16_t get_bus_from_drive(uint32_t drive){
//return 1 if ready, 0 if not
int ata_ready(uint32_t BAR, uint32_t BAR2, uint8_t drive){
if(drive){
outb(BAR ATA_DRIVE_HEAD, drive ? 0xB0 : 0xA0);
static uint16_t last_disk = 0;
static uint16_t last_bar = 0;
if(last_disk != drive && last_bar != BAR){
last_disk = drive;
last_bar == BAR;
outb(BAR ATA_DRIVE_HEAD, drive);
}
for(uint32_t i = 0; i < 15; i++){
uint8_t _ = inb(BAR2 ATA_ALT_STATUS);
uint8_t _ = inb(BAR2 ATA_STATUS);
}
uint8_t status = inb(BAR2 ATA_ALT_STATUS);
if(!ATA_BSY(status) || ATA_DRQ(status)) return 1;
return 0;
return ~(status >> 7);
}
void ata_reset(uint16_t bar1){
outw(bar1 ATA_DEVICE_CONTROL, 0x4);
for(uint32_t i = 0; i < 4096; i++){
asm volatile("" ::: "memory");
}
outw(bar1 ATA_DEVICE_CONTROL, 0x0);
}
//return index of first free drive descriptor
uint32_t find_free_drive(){
@ -162,15 +174,96 @@ uint32_t find_free_drive(){
}
}
void ide_init(uint32_t BARS[5]){
uint32_t index = find_free_drive();
drives[index].type = TYPE_IDE;
for(int i = 0; i < 5; i++){
drives[index].BARs[i] = BARS[i];
//return 255 if err/ does not exist
//return 0 if is ATA drive
//return 1 if is ATAPI
//return 2 if is SATA
//return 3 if is SATAPI
uint8_t ata_identify(uint32_t index, uint16_t disk){
uint16_t bar0 = drives[index].BARs[0] >> 2;
uint16_t bar1 = drives[index].BARs[1] >> 2;
while(!ata_ready(bar0, bar1, disk)){
asm volatile ("" ::: "memory");
}
outb(bar0 ATA_DRIVE_HEAD, disk);
outw(bar0 ATA_SECTOR_COUNT, 0);
outw(bar0 ATA_LBA_HIH, 0);
outw(bar0 ATA_LBA_MID, 0);
outw(bar0 ATA_LBA_LOW, 0);
outw(bar0 ATA_COMMAND, ATA_CMD_IDENTIFY);
uint16_t identify[256] = {0};
uint8_t status = inb(bar0 ATA_STATUS);
if(!status){
return -1;
}
while(ATA_BSY(status)){
asm volatile ("":::"memory"); //prevent gcc from optimizing out this loop
if(inw(bar0 ATA_LBA_MID)){
return -1;//we don't support ATAPI and SATAPI yet
}
status = inw(bar0 ATA_STATUS);
if(ATA_ERR(status)){
return -1;
}
}
for(uint16_t i = 0; i < 256; i++){
identify[i] = inw(bar0 ATA_DATA);
}
// drives[index].size_sectors
uint32_t lba48 = (identify[83] & (1 << 10));
drives[index].flags.huge = lba48 ? 1 : 0;
drives[index].size_sectors = lba48 ? (identify[60] | (identify[61] << 16)) : ((uint64_t)(identify[100]) | (uint64_t)(identify[101] << 16) | ((uint64_t)identify[102] << 32));
api(MODULE_API_PRINT, MODULE_NAME, "Sector Count: %x\n", drives[index].size_sectors);
return 1;
}
void ide_init(uint32_t BARS[5]){
uint32_t primary_index = find_free_drive();
drives[primary_index].type = TYPE_IDE;
uint32_t secondary_index = find_free_drive();
drives[secondary_index].type = TYPE_IDE;
for(int i = 0; i < 2; i++){
drives[primary_index].BARs[i] = BARS[i];
drives[secondary_index].BARs[i] = BARS[i+2];
}
drives[primary_index].BARs[4] = BARS[4];
drives[secondary_index].BARs[4] = BARS[4];
uint32_t prdt_primary_paddr = api(MODULE_API_PMALLOC64K);
uint32_t prdt_secondary_paddr = api(MODULE_API_PMALLOC64K);
drives[primary_index].PRDT = (void *)api(MODULE_API_KMALLOC_PADDR, prdt_primary_paddr, 16);
drives[secondary_index].PRDT = (void *)api(MODULE_API_KMALLOC_PADDR, prdt_secondary_paddr, 16);
//now call ATA IDENTIFY
uint8_t master_status = ata_identify(primary_index, ATA_MASTER);
drive_t master_copy = drives[primary_index];
if(ata_identify(primary_index, ATA_SLAVE) == 0){
if(master_status == -1){
drives[primary_index].flags.slave = 1;
}
else{
uint32_t slave_index = find_free_drive();
drives[slave_index] = drives[primary_index];
drives[slave_index].flags.slave = 1;
drives[primary_index] = master_copy;
drives[slave_index].type = TYPE_IDE;
}
}
master_status = ata_identify(secondary_index, ATA_MASTER);
master_copy = drives[secondary_index];
if(ata_identify(secondary_index, ATA_SLAVE) == 0){
if(master_status == -1){
drives[secondary_index].flags.slave = 1;
}
else{
uint32_t slave_index = find_free_drive();
drives[slave_index] = drives[secondary_index];
drives[slave_index].flags.slave = 1;
drives[secondary_index] = master_copy;
drives[slave_index].type = TYPE_IDE;
}
}
uint32_t paddr = api(MODULE_API_PMALLOC64K);
drives[index].PRDT = api(MODULE_API_KMALLOC_PADDR, paddr, 16);
api(MODULE_API_PRINT, MODULE_NAME, "Vaddr: %x, Paddr: %x", drives[index].PRDT, paddr);
}
void init(KOS_MAPI_FP module_api, uint32_t api_version){
@ -197,16 +290,17 @@ void init(KOS_MAPI_FP module_api, uint32_t api_version){
uint32_t progif = class >> 8 & 0xff;
class >>= 16;
api(MODULE_API_PRINT, MODULE_NAME, "Class: %x, %x\n", class, progif);
if(class == 0x101 && PCI_IDE_SUPPORT_DMA(progif)){ //in this house, we only support DMA.
if(class == 0x101 && PCI_IDE_SUPPORT_DMA(progif) && !native_ide_present){ //in this house, we only support DMA.
uint32_t BARs[5] = {0};
fread(api, current_file, BARs, 0x10, 5);
if(PCI_IDE_NATIVE(progif)){
BARs[0] = ATA_PRIMARY_BUS;
BARs[1] = ATA_PRIMARY_BUS + 0x206;
if(PCI_IDE_NATIVE(~progif)){
native_ide_present = 1;
BARs[0] = (ATA_PRIMARY_BUS) << 2 | 1;
BARs[1] = (ATA_PRIMARY_BUS + 0x206) << 2 | 1;
}
if(PCI_IDE_SECONDARY_NATIVE(progif)){
BARs[2] = ATA_SECONDARY_BUS;
BARs[3] = ATA_SECONDARY_BUS + 0x206;
if(PCI_IDE_SECONDARY_NATIVE(~progif)){
BARs[2] = (ATA_SECONDARY_BUS << 2) | 1;
BARs[3] = (ATA_SECONDARY_BUS + 0x206) << 2 | 1;
}
ide_init(BARs);
}