X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FStorage%2FATA%2Fio.c;h=128fdca08e4b7564a640cdd04cf743a40bef7f4b;hb=6b71b6d8b62bc72fa91f6bc87b39185705f66f6c;hp=44f774a21787ed31f865908772bead97dd190b86;hpb=9d85201216cb35e1b1e051b1d7cdc38eaa5befa4;p=tpg%2Facess2.git diff --git a/Modules/Storage/ATA/io.c b/Modules/Storage/ATA/io.c index 44f774a2..128fdca0 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 /** @@ -77,8 +79,8 @@ Uint16 ATA_GetBasePort(int Disk); int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer); int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer); // IRQs -void ATA_IRQHandlerPri(int UNUSED(IRQ)); -void ATA_IRQHandlerSec(int UNUSED(IRQ)); +void ATA_IRQHandlerPri(int UNUSED(IRQ), void *UNUSED(Ptr)); +void ATA_IRQHandlerSec(int UNUSED(IRQ), void *UNUSED(Ptr)); // Controller IO Uint8 ATA_int_BusMasterReadByte(int Ofs); Uint32 ATA_int_BusMasterReadDWord(int Ofs); @@ -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) ) { @@ -136,12 +141,12 @@ int ATA_SetupIO(void) } else { // Bit 0 is left set as a flag to other functions - LOG("gATA_BusMasterBase = 0x%x", gATA_BusMasterBase & ~1); + LOG("gATA_BusMasterBase = IO 0x%x", gATA_BusMasterBase & ~1); } // Register IRQs and get Buffers - IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri ); - IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec ); + IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri, NULL ); + IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec, NULL ); gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[0] ); gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[1] ); @@ -159,6 +164,12 @@ int ATA_SetupIO(void) // Enable controllers outb(IDE_PRI_BASE+1, 1); outb(IDE_SEC_BASE+1, 1); + outb(IDE_PRI_CTRL, 0); + outb(IDE_SEC_CTRL, 0); + + // Make sure interrupts are ACKed + ATA_int_BusMasterWriteByte(2, 0x4); + ATA_int_BusMasterWriteByte(10, 0x4); // return LEAVE('i', MODULE_ERR_OK); @@ -240,10 +251,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,6 +296,11 @@ 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 Mutex_Acquire( &glaATA_ControllerLock[ cont ] ); @@ -294,10 +314,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(IDE_PRI_CTRL, 4); + IO_DELAY(); + outb(IDE_PRI_CTRL, 0); + } + else { + outb(IDE_SEC_CTRL, 4); + IO_DELAY(); + outb(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 +341,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,36 +364,48 @@ 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) { HALT(); -// Threads_Yield(); } // 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("Status byte = 0x%02x, Controller Status = 0x%02x", + val, ATA_int_BusMasterReadByte(cont * 8 + 2)); - LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes); - LOG("Transfer Completed & Acknowledged"); - - if( gaATA_IRQs[cont] == 0 ) { + if( gaATA_IRQs[cont] == 0 ) + { + if( ATA_int_BusMasterReadByte(cont * 8 + 2) & 0x4 ) { + Log_Error("ATA", "BM Status reports an interrupt, but none recieved"); + ATA_int_BusMasterWriteByte(cont*8 + 2, 4); // Clear interrupt + memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE ); + Mutex_Release( &glaATA_ControllerLock[ cont ] ); + LEAVE('i', 0); + return 0; + } + + #if 1 + Debug_HexDump("ATA", Buffer, 512); + #endif + // Release controller lock 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 @@ -433,7 +482,6 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer) timeoutTime = now() + ATA_TIMEOUT; while( gaATA_IRQs[cont] == 0 && now() < timeoutTime) { -// Threads_Yield(); HALT(); } @@ -455,7 +503,7 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer) /** * \brief Primary ATA Channel IRQ handler */ -void ATA_IRQHandlerPri(int UNUSED(IRQ)) +void ATA_IRQHandlerPri(int UNUSED(IRQ), void *UNUSED(Ptr)) { Uint8 val; @@ -473,7 +521,7 @@ void ATA_IRQHandlerPri(int UNUSED(IRQ)) /** * \brief Second ATA Channel IRQ handler */ -void ATA_IRQHandlerSec(int UNUSED(IRQ)) +void ATA_IRQHandlerSec(int UNUSED(IRQ), void *UNUSED(Ptr)) { Uint8 val; // IRQ bit set for Secondary Controller