2 * Acess2 IDE Harddisk Driver
5 * Disk Input/Output control
9 #include <modules.h> // Needed for error codes
14 #define IO_DELAY() do{inb(0x80); inb(0x80); inb(0x80); inb(0x80);}while(0)
17 #define IDE_PRI_BASE 0x1F0
18 #define IDE_PRI_CTRL 0x3F6
19 #define IDE_SEC_BASE 0x170
20 #define IDE_SEC_CTRL 0x376
22 #define IDE_PRDT_LAST 0x8000
25 \brief Commands to be sent to HDD_CMD
45 Uint32 PBufAddr; // Physical Buffer Address
46 Uint16 Bytes; // Size of transfer entry
47 Uint16 Flags; // Flags
48 } __attribute__ ((packed)) tPRDT_Ent;
51 * \brief Structure returned by the ATA IDENTIFY command
56 Uint16 Usused1[9]; // 10
57 char SerialNum[20]; // 20
58 Uint16 Usused2[3]; // 23
59 char FirmwareVer[8]; // 27
60 char ModelNumber[40]; // 47
61 Uint16 SectPerInt; // 48 - Low byte only
63 Uint16 Capabilities[2]; // 51
64 Uint16 Unused4[2]; // 53
65 Uint16 ValidExtData; // 54
66 Uint16 Unused5[5]; // 59
67 Uint16 SizeOfRWMultiple; // 60
68 Uint32 Sectors28; // LBA 28 Sector Count
69 Uint16 Unused6[100-62];
70 Uint64 Sectors48; // LBA 48 Sector Count
71 Uint16 Unused7[256-104];
72 } __attribute__ ((packed)) tIdentify;
75 int ATA_SetupIO(void);
76 Uint64 ATA_GetDiskSize(int Disk);
77 Uint16 ATA_GetBasePort(int Disk);
79 int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
80 int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer);
82 void ATA_IRQHandlerPri(int UNUSED(IRQ), void *UNUSED(Ptr));
83 void ATA_IRQHandlerSec(int UNUSED(IRQ), void *UNUSED(Ptr));
85 Uint8 ATA_int_BusMasterReadByte(int Ofs);
86 Uint32 ATA_int_BusMasterReadDWord(int Ofs);
87 void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value);
88 void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value);
91 // - BusMaster IO Addresses
92 Uint32 gATA_BusMasterBase; //!< True Address (IO/MMIO)
93 Uint8 *gATA_BusMasterBasePtr; //!< Paging Mapped MMIO (If needed)
97 volatile int gaATA_IRQs[2] = {0};
98 // - Locks to avoid tripping
99 tMutex glaATA_ControllerLock[2];
101 Uint8 gATA_Buffers[2][(MAX_DMA_SECTORS+0xFFF)&~0xFFF] __attribute__ ((section(".padata")));
103 tPRDT_Ent gATA_PRDTs[2] = {
104 {0, 512, IDE_PRDT_LAST},
105 {0, 512, IDE_PRDT_LAST}
107 tPAddr gaATA_PRDT_PAddrs[2];
111 * \brief Sets up the ATA controller's DMA mode
113 int ATA_SetupIO(void)
119 // Get IDE Controller's PCI Entry
120 ent = PCI_GetDeviceByClass(0x010100, 0xFFFF00, -1);
121 LOG("ent = %i", ent);
122 gATA_BusMasterBase = PCI_GetBAR(ent, 4);
123 if( gATA_BusMasterBase == 0 ) {
124 Log_Warning("ATA", "It seems that there is no Bus Master Controller on this machine. Get one");
125 // TODO: Use PIO mode instead
126 LEAVE('i', MODULE_ERR_NOTNEEDED);
127 return MODULE_ERR_NOTNEEDED;
130 LOG("BAR5 = 0x%x", PCI_GetBAR(ent, 5));
131 LOG("IRQ = %i", PCI_GetIRQ(ent));
134 if( !(gATA_BusMasterBase & 1) )
136 if( gATA_BusMasterBase < 0x100000 )
137 gATA_BusMasterBasePtr = (void*)(KERNEL_BASE | (tVAddr)gATA_BusMasterBase);
139 gATA_BusMasterBasePtr = (void*)( MM_MapHWPages( gATA_BusMasterBase, 1 ) + (gATA_BusMasterBase&0xFFF) );
140 LOG("gATA_BusMasterBasePtr = %p", gATA_BusMasterBasePtr);
143 // Bit 0 is left set as a flag to other functions
144 LOG("gATA_BusMasterBase = IO 0x%x", gATA_BusMasterBase & ~1);
147 // Register IRQs and get Buffers
148 IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri, NULL );
149 IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec, NULL );
151 gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( &gATA_Buffers[0] );
152 gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( &gATA_Buffers[1] );
154 LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
156 gaATA_PRDT_PAddrs[0] = MM_GetPhysAddr( &gATA_PRDTs[0] );
157 LOG("gaATA_PRDT_PAddrs[0] = 0x%x", gaATA_PRDT_PAddrs[0]);
158 ATA_int_BusMasterWriteDWord(4, gaATA_PRDT_PAddrs[0]);
160 gaATA_PRDT_PAddrs[1] = MM_GetPhysAddr( &gATA_PRDTs[1] );
161 LOG("gaATA_PRDT_PAddrs[1] = 0x%x", gaATA_PRDT_PAddrs[1]);
162 ATA_int_BusMasterWriteDWord(12, gaATA_PRDT_PAddrs[1]);
164 // Enable controllers
165 outb(IDE_PRI_BASE+1, 1);
166 outb(IDE_SEC_BASE+1, 1);
167 outb(IDE_PRI_CTRL, 0);
168 outb(IDE_SEC_CTRL, 0);
170 // Make sure interrupts are ACKed
171 ATA_int_BusMasterWriteByte(2, 0x4);
172 ATA_int_BusMasterWriteByte(10, 0x4);
175 LEAVE('i', MODULE_ERR_OK);
176 return MODULE_ERR_OK;
180 * \brief Get the size (in sectors) of a disk
181 * \param Disk Disk to get size of
182 * \return Number of sectors reported
184 * Does an ATA IDENTIFY
186 Uint64 ATA_GetDiskSize(int Disk)
195 ENTER("iDisk", Disk);
197 base = ATA_GetBasePort( Disk );
199 // Send Disk Selector
200 if(Disk & 1) // Slave
206 // Check for a floating bus
207 if( 0xFF == inb(base+7) ) {
213 // Check for the controller
214 // - Write to two RW ports and attempt to read back
215 outb(base+0x02, 0x66);
216 outb(base+0x03, 0xFF);
217 if(inb(base+0x02) != 0x66 || inb(base+0x03) != 0xFF) {
218 LOG("No controller");
224 outb(base+7, HDD_IDENTIFY);
226 val = inb(base+7); // Read status
227 LOG("val = 0x%02x", val);
230 return 0; // Disk does not exist
233 // Poll until BSY clears or ERR is set
235 while( (val & 0x80) && !(val & 1) )
237 LOG("BSY unset (0x%x)", val);
238 // and, wait for DRQ to set
239 while( !(val & 0x08) && !(val & 1))
241 LOG("DRQ set (0x%x)", val);
243 // Check for an error
246 return 0; // Error occured, so return false
250 for( i = 0; i < 256; i++ )
251 data.buf[i] = inw(base);
253 // Return the disk size
254 if(data.identify.Sectors48 != 0) {
255 LEAVE('X', data.identify.Sectors48);
256 return data.identify.Sectors48;
259 LEAVE('x', data.identify.Sectors28);
260 return data.identify.Sectors28;
265 * \fn Uint16 ATA_GetPortBase(int Disk)
266 * \brief Returns the base port for a given disk
268 Uint16 ATA_GetBasePort(int Disk)
272 case 0: case 1: return IDE_PRI_BASE;
273 case 2: case 3: return IDE_SEC_BASE;
279 * \fn int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
280 * \return Boolean Failure
282 int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
284 int cont = (Disk>>1)&1; // Controller ID
289 ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer);
291 // Check if the count is small enough
292 if(Count > MAX_DMA_SECTORS) {
293 Log_Warning("ATA", "Passed too many sectors for a bulk DMA read (%i > %i)",
294 Count, MAX_DMA_SECTORS);
299 // Hack to make debug hexdump noticable
301 memset(Buffer, 0xFF, Count*SECTOR_SIZE);
304 // Get exclusive access to the disk controller
305 Mutex_Acquire( &glaATA_ControllerLock[ cont ] );
308 gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
311 base = ATA_GetBasePort(Disk);
314 gaATA_IRQs[cont] = 0;
318 outb(IDE_PRI_CTRL, 4);
320 outb(IDE_PRI_CTRL, 0);
323 outb(IDE_SEC_CTRL, 4);
325 outb(IDE_SEC_CTRL, 0);
330 if( Address > 0x0FFFFFFF ) // Use LBA48
332 outb(base+0x6, 0x40 | (disk << 4));
334 outb(base+0x2, 0 >> 8); // Upper Sector Count
335 outb(base+0x3, Address >> 24); // Low 2 Addr
336 outb(base+0x4, Address >> 28); // Mid 2 Addr
337 outb(base+0x5, Address >> 32); // High 2 Addr
341 // Magic, Disk, High Address nibble
342 outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F));
343 //outb(base+0x06, 0xA0 | (disk << 4) | ((Address >> 24) & 0x0F));
347 //outb(base+0x01, 0x01); //?
348 outb(base+0x02, Count & 0xFF); // Sector Count
349 outb(base+0x03, Address & 0xFF); // Low Addr
350 outb(base+0x04, (Address >> 8) & 0xFF); // Middle Addr
351 outb(base+0x05, (Address >> 16) & 0xFF); // High Addr
353 LOG("Starting Transfer");
355 // HACK: Ensure the PRDT is reset
356 ATA_int_BusMasterWriteDWord(cont*8+4, gaATA_PRDT_PAddrs[cont]);
357 ATA_int_BusMasterWriteByte(cont*8, 4); // Reset IRQ
359 LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes);
360 if( Address > 0x0FFFFFFF )
361 outb(base+0x07, HDD_DMA_R48); // Read Command (LBA48)
363 outb(base+0x07, HDD_DMA_R28); // Read Command (LBA28)
366 ATA_int_BusMasterWriteByte( cont * 8, 9 ); // Read and start
368 // Wait for transfer to complete
369 timeoutTime = now() + ATA_TIMEOUT;
370 while( gaATA_IRQs[cont] == 0 && now() < timeoutTime)
375 if( now() >= timeoutTime ) {
376 Log_Notice("ATA", "Timeout of %i ms exceeded", ATA_TIMEOUT);
380 ATA_int_BusMasterWriteByte( cont * 8, 8 ); // Read and stop
384 Uint8 val = inb(base+0x7);
385 LOG("Status byte = 0x%02x, Controller Status = 0x%02x",
386 val, ATA_int_BusMasterReadByte(cont * 8 + 2));
392 if( gaATA_IRQs[cont] == 0 )
394 if( ATA_int_BusMasterReadByte(cont * 8 + 2) & 0x4 ) {
395 Log_Error("ATA", "BM Status reports an interrupt, but none recieved");
396 ATA_int_BusMasterWriteByte(cont*8 + 2, 4); // Clear interrupt
397 memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
398 Mutex_Release( &glaATA_ControllerLock[ cont ] );
404 Debug_HexDump("ATA", Buffer, 512);
407 // Release controller lock
408 Mutex_Release( &glaATA_ControllerLock[ cont ] );
410 "Read timeout on disk %i (Reading sector 0x%llx)",
417 LOG("Transfer Completed & Acknowledged");
418 // Copy to destination buffer
419 memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
420 // Release controller lock
421 Mutex_Release( &glaATA_ControllerLock[ cont ] );
429 * \fn int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
430 * \brief Write up to \a MAX_DMA_SECTORS to a disk
431 * \param Disk Disk ID to write to
432 * \param Address LBA of first sector
433 * \param Count Number of sectors to write (must be >= \a MAX_DMA_SECTORS)
434 * \param Buffer Source buffer for data
435 * \return Boolean Failure
437 int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer)
439 int cont = (Disk>>1)&1; // Controller ID
444 // Check if the count is small enough
445 if(Count > MAX_DMA_SECTORS) return 1;
447 // Get exclusive access to the disk controller
448 Mutex_Acquire( &glaATA_ControllerLock[ cont ] );
451 gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
454 base = ATA_GetBasePort(Disk);
457 gaATA_IRQs[cont] = 0;
460 outb(base+0x01, 0x00);
461 if( Address > 0x0FFFFFFF ) // Use LBA48
463 outb(base+0x6, 0x40 | (disk << 4));
464 outb(base+0x2, 0 >> 8); // Upper Sector Count
465 outb(base+0x3, Address >> 24); // Low 2 Addr
466 outb(base+0x3, Address >> 28); // Mid 2 Addr
467 outb(base+0x3, Address >> 32); // High 2 Addr
471 // Magic, Disk, High Address nibble
472 outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F));
475 outb(base+0x02, (Uint8) Count); // Sector Count
476 outb(base+0x03, (Uint8) Address); // Low Addr
477 outb(base+0x04, (Uint8) (Address >> 8)); // Middle Addr
478 outb(base+0x05, (Uint8) (Address >> 16)); // High Addr
479 if( Address > 0x0FFFFFFF )
480 outb(base+0x07, HDD_DMA_W48); // Write Command (LBA48)
482 outb(base+0x07, HDD_DMA_W28); // Write Command (LBA28)
484 // Copy to output buffer
485 memcpy( gATA_Buffers[cont], Buffer, Count*SECTOR_SIZE );
488 ATA_int_BusMasterWriteByte( cont << 3, 1 ); // Write and start
490 // Wait for transfer to complete
491 timeoutTime = now() + ATA_TIMEOUT;
492 while( gaATA_IRQs[cont] == 0 && now() < timeoutTime)
498 ATA_int_BusMasterWriteByte( cont << 3, 0 ); // Write and stop
500 // If the IRQ is unset, return error
501 if( gaATA_IRQs[cont] == 0 ) {
502 // Release controller lock
503 Mutex_Release( &glaATA_ControllerLock[ cont ] );
507 Mutex_Release( &glaATA_ControllerLock[ cont ] );
513 * \brief Primary ATA Channel IRQ handler
515 void ATA_IRQHandlerPri(int UNUSED(IRQ), void *UNUSED(Ptr))
519 // IRQ bit set for Primary Controller
520 val = ATA_int_BusMasterReadByte( 0x2 );
521 LOG("IRQ val = 0x%x", val);
523 LOG("IRQ hit (val = 0x%x)", val);
524 ATA_int_BusMasterWriteByte( 0x2, 4 );
531 * \brief Second ATA Channel IRQ handler
533 void ATA_IRQHandlerSec(int UNUSED(IRQ), void *UNUSED(Ptr))
536 // IRQ bit set for Secondary Controller
537 val = ATA_int_BusMasterReadByte( 0xA );
538 LOG("IRQ val = 0x%x", val);
540 LOG("IRQ hit (val = 0x%x)", val);
541 ATA_int_BusMasterWriteByte( 0xA, 4 );
548 * \brief Read an 8-bit value from a Bus Master register
549 * \param Ofs Register offset
551 Uint8 ATA_int_BusMasterReadByte(int Ofs)
553 if( gATA_BusMasterBase & 1 )
554 return inb( (gATA_BusMasterBase & ~1) + Ofs );
556 return *(Uint8*)(gATA_BusMasterBasePtr + Ofs);
560 * \brief Read an 32-bit value from a Bus Master register
561 * \param Ofs Register offset
563 Uint32 ATA_int_BusMasterReadDWord(int Ofs)
565 if( gATA_BusMasterBase & 1 )
566 return ind( (gATA_BusMasterBase & ~1) + Ofs );
568 return *(Uint32*)(gATA_BusMasterBasePtr + Ofs);
572 * \brief Writes a byte to a Bus Master Register
573 * \param Ofs Register Offset
574 * \param Value Value to write
576 void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
578 if( gATA_BusMasterBase & 1 )
579 outb( (gATA_BusMasterBase & ~1) + Ofs, Value );
581 *(Uint8*)(gATA_BusMasterBasePtr + Ofs) = Value;
585 * \brief Writes a 32-bit value to a Bus Master Register
586 * \param Ofs Register offset
587 * \param Value Value to write
589 void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
591 if( gATA_BusMasterBase & 1 )
592 outd( (gATA_BusMasterBase & ~1) + Ofs, Value );
594 *(Uint32*)(gATA_BusMasterBasePtr + Ofs) = Value;