X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FStorage%2FATA%2Fio.c;h=de6bf96b48dee67a1600b9528e46310526f3fb4f;hb=98d45a155c3ce437d0eddb67b9eb2b203f87ec3b;hp=89fcdb9f8cb28879105474e9695669023b85da41;hpb=e6b37dbe81b4492796fd262f95fc94e06cb67966;p=tpg%2Facess2.git diff --git a/Modules/Storage/ATA/io.c b/Modules/Storage/ATA/io.c index 89fcdb9f..de6bf96b 100644 --- a/Modules/Storage/ATA/io.c +++ b/Modules/Storage/ATA/io.c @@ -15,7 +15,9 @@ // === Constants === #define IDE_PRI_BASE 0x1F0 +#define IDE_PRI_CTRL 0x3F6 #define IDE_SEC_BASE 0x170 +#define IDE_SEC_CTRL 0x376 #define IDE_PRDT_LAST 0x8000 /** @@ -94,7 +96,7 @@ Uint8 *gATA_BusMasterBasePtr; //!< Paging Mapped MMIO (If needed) int gATA_IRQSec = 15; volatile int gaATA_IRQs[2] = {0}; // - Locks to avoid tripping -tSpinlock giaATA_ControllerLock[2]; +tMutex glaATA_ControllerLock[2]; // - Buffers! Uint8 gATA_Buffers[2][(MAX_DMA_SECTORS+0xFFF)&~0xFFF] __attribute__ ((section(".padata"))); // - PRDTs @@ -117,7 +119,7 @@ int ATA_SetupIO(void) // Get IDE Controller's PCI Entry ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1); LOG("ent = %i", ent); - gATA_BusMasterBase = PCI_GetBAR4( ent ); + gATA_BusMasterBase = PCI_GetBAR(ent, 4); if( gATA_BusMasterBase == 0 ) { Log_Warning("ATA", "It seems that there is no Bus Master Controller on this machine. Get one"); // TODO: Use PIO mode instead @@ -125,6 +127,9 @@ int ATA_SetupIO(void) return MODULE_ERR_NOTNEEDED; } + LOG("BAR5 = 0x%x", PCI_GetBAR(ent, 5)); + LOG("IRQ = %i", PCI_GetIRQ(ent)); + // Map memory if( !(gATA_BusMasterBase & 1) ) { @@ -159,6 +164,10 @@ int ATA_SetupIO(void) // Enable controllers outb(IDE_PRI_BASE+1, 1); outb(IDE_SEC_BASE+1, 1); + + // Make sure interrupts are ACKed + ATA_int_BusMasterWriteByte(2, 0x4); + ATA_int_BusMasterWriteByte(10, 0x4); // return LEAVE('i', MODULE_ERR_OK); @@ -240,10 +249,14 @@ Uint64 ATA_GetDiskSize(int Disk) data.buf[i] = inw(base); // Return the disk size - if(data.identify.Sectors48 != 0) + if(data.identify.Sectors48 != 0) { + LEAVE('X', data.identify.Sectors48); return data.identify.Sectors48; - else + } + else { + LEAVE('x', data.identify.Sectors28); return data.identify.Sectors28; + } } /** @@ -281,9 +294,14 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) LEAVE('i'); return 1; } + + // Hack to make debug hexdump noticable + #if 1 + memset(Buffer, 0xFF, Count*SECTOR_SIZE); + #endif // Get exclusive access to the disk controller - LOCK( &giaATA_ControllerLock[ cont ] ); + Mutex_Acquire( &glaATA_ControllerLock[ cont ] ); // Set Size gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE; @@ -294,10 +312,24 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) // Reset IRQ Flag gaATA_IRQs[cont] = 0; + #if 1 + if( cont == 0 ) { + outb(base+IDE_PRI_CTRL, 4); + IO_DELAY(); + outb(base+IDE_PRI_CTRL, 0); + } + else { + outb(base+IDE_SEC_CTRL, 4); + IO_DELAY(); + outb(base+IDE_SEC_CTRL, 0); + } + #endif + // Set up transfer if( Address > 0x0FFFFFFF ) // Use LBA48 { outb(base+0x6, 0x40 | (disk << 4)); + IO_DELAY(); outb(base+0x2, 0 >> 8); // Upper Sector Count outb(base+0x3, Address >> 24); // Low 2 Addr outb(base+0x4, Address >> 28); // Mid 2 Addr @@ -307,19 +339,22 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) { // Magic, Disk, High Address nibble outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); + //outb(base+0x06, 0xA0 | (disk << 4) | ((Address >> 24) & 0x0F)); + IO_DELAY(); } - outb(base+0x01, 0x01); //? - outb(base+0x02, (Uint8) Count); // Sector Count - outb(base+0x03, (Uint8) Address); // Low Addr - outb(base+0x04, (Uint8) (Address >> 8)); // Middle Addr - outb(base+0x05, (Uint8) (Address >> 16)); // High Addr + //outb(base+0x01, 0x01); //? + outb(base+0x02, Count & 0xFF); // Sector Count + outb(base+0x03, Address & 0xFF); // Low Addr + outb(base+0x04, (Address >> 8) & 0xFF); // Middle Addr + outb(base+0x05, (Address >> 16) & 0xFF); // High Addr LOG("Starting Transfer"); // HACK: Ensure the PRDT is reset ATA_int_BusMasterWriteDWord(cont*8+4, gaATA_PRDT_PAddrs[cont]); - + ATA_int_BusMasterWriteByte(cont*8, 4); // Reset IRQ + LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes); if( Address > 0x0FFFFFFF ) outb(base+0x07, HDD_DMA_R48); // Read Command (LBA48) @@ -327,37 +362,43 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) outb(base+0x07, HDD_DMA_R28); // Read Command (LBA28) // Start transfer - ATA_int_BusMasterWriteByte( cont << 3, 9 ); // Read and start + ATA_int_BusMasterWriteByte( cont * 8, 9 ); // Read and start // Wait for transfer to complete timeoutTime = now() + ATA_TIMEOUT; while( gaATA_IRQs[cont] == 0 && now() < timeoutTime) - Threads_Yield(); + { + HALT(); + } // Complete Transfer - ATA_int_BusMasterWriteByte( cont << 3, 8 ); // Read and stop + ATA_int_BusMasterWriteByte( cont * 8, 8 ); // Read and stop val = inb(base+0x7); - LOG("Status byte = 0x%02x", val); - - LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes); - LOG("Transfer Completed & Acknowledged"); + LOG("Status byte = 0x%02x, Controller Status = 0x%02x", + val, ATA_int_BusMasterReadByte(cont * 8 + 2)); if( gaATA_IRQs[cont] == 0 ) { + + #if 1 + Debug_HexDump("ATA", Buffer, 512); + #endif + // Release controller lock - RELEASE( &giaATA_ControllerLock[ cont ] ); + Mutex_Release( &glaATA_ControllerLock[ cont ] ); Log_Warning("ATA", - "Read timeout on disk %i (Reading sector 0x%llx)\n", + "Read timeout on disk %i (Reading sector 0x%llx)", Disk, Address); // Return error LEAVE('i', 1); return 1; } else { + LOG("Transfer Completed & Acknowledged"); // Copy to destination buffer memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE ); // Release controller lock - RELEASE( &giaATA_ControllerLock[ cont ] ); + Mutex_Release( &glaATA_ControllerLock[ cont ] ); LEAVE('i', 0); return 0; @@ -384,7 +425,7 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer) if(Count > MAX_DMA_SECTORS) return 1; // Get exclusive access to the disk controller - LOCK( &giaATA_ControllerLock[ cont ] ); + Mutex_Acquire( &glaATA_ControllerLock[ cont ] ); // Set Size gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE; @@ -429,7 +470,9 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer) // Wait for transfer to complete timeoutTime = now() + ATA_TIMEOUT; while( gaATA_IRQs[cont] == 0 && now() < timeoutTime) - Threads_Yield(); + { + HALT(); + } // Complete Transfer ATA_int_BusMasterWriteByte( cont << 3, 0 ); // Write and stop @@ -437,11 +480,11 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer) // If the IRQ is unset, return error if( gaATA_IRQs[cont] == 0 ) { // Release controller lock - RELEASE( &giaATA_ControllerLock[ cont ] ); + Mutex_Release( &glaATA_ControllerLock[ cont ] ); return 1; // Error } else { - RELEASE( &giaATA_ControllerLock[ cont ] ); + Mutex_Release( &glaATA_ControllerLock[ cont ] ); return 0; } }