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)
22 Uint32 PBufAddr; // Physical Buffer Address
23 Uint16 Bytes; // Size of transfer entry
24 Uint16 Flags; // Flags
25 } __attribute__ ((packed)) tPRDT_Ent;
28 * \brief Structure returned by the ATA IDENTIFY command
33 Uint16 Usused1[9]; // 10
34 char SerialNum[20]; // 20
35 Uint16 Usused2[3]; // 23
36 char FirmwareVer[8]; // 27
37 char ModelNumber[40]; // 47
38 Uint16 SectPerInt; // 48 - Low byte only
40 Uint16 Capabilities[2]; // 51
41 Uint16 Unused4[2]; // 53
42 Uint16 ValidExtData; // 54
43 Uint16 Unused5[5]; // 59
44 Uint16 SizeOfRWMultiple; // 60
45 Uint32 Sectors28; // 62
46 Uint16 Unused6[100-62];
48 Uint16 Unused7[256-104];
49 } __attribute__ ((packed)) tIdentify;
52 int ATA_SetupIO(void);
53 Uint64 ATA_GetDiskSize(int Disk);
54 Uint16 ATA_GetBasePort(int Disk);
56 int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer);
57 int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer);
59 void ATA_IRQHandlerPri(int UNUSED(IRQ));
60 void ATA_IRQHandlerSec(int UNUSED(IRQ));
62 Uint8 ATA_int_BusMasterReadByte(int Ofs);
63 void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value);
64 void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value);
67 Uint32 gATA_BusMasterBase = 0;
68 Uint8 *gATA_BusMasterBasePtr = 0;
71 int giaATA_ControllerLock[2] = {0}; //!< Spinlocks for each controller
72 Uint8 gATA_Buffers[2][(MAX_DMA_SECTORS+0xFFF)&~0xFFF] __attribute__ ((section(".padata")));
73 volatile int gaATA_IRQs[2] = {0};
74 tPRDT_Ent gATA_PRDTs[2] = {
75 {0, 512, IDE_PRDT_LAST},
76 {0, 512, IDE_PRDT_LAST}
81 * \brief Sets up the ATA controller's DMA mode
90 // Get IDE Controller's PCI Entry
91 ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1);
93 gATA_BusMasterBase = PCI_GetBAR4( ent );
94 if( gATA_BusMasterBase == 0 ) {
95 Log_Warning("ATA", "It seems that there is no Bus Master Controller on this machine. Get one");
96 // TODO: Use PIO mode instead
97 LEAVE('i', MODULE_ERR_NOTNEEDED);
98 return MODULE_ERR_NOTNEEDED;
102 if( !(gATA_BusMasterBase & 1) )
104 if( gATA_BusMasterBase < 0x100000 )
105 gATA_BusMasterBasePtr = (void*)(KERNEL_BASE | (tVAddr)gATA_BusMasterBase);
107 gATA_BusMasterBasePtr = (void*)( MM_MapHWPages( gATA_BusMasterBase, 1 ) + (gATA_BusMasterBase&0xFFF) );
108 LOG("gATA_BusMasterBasePtr = %p", gATA_BusMasterBasePtr);
111 // Bit 0 is left set as a flag to other functions
112 LOG("gATA_BusMasterBase = 0x%x", gATA_BusMasterBase & ~1);
115 // Register IRQs and get Buffers
116 IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri );
117 IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec );
119 gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[0] );
120 gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[1] );
122 LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
124 addr = MM_GetPhysAddr( (tVAddr)&gATA_PRDTs[0] );
125 LOG("addr = 0x%x", addr);
126 ATA_int_BusMasterWriteDWord(4, addr);
127 addr = MM_GetPhysAddr( (tVAddr)&gATA_PRDTs[1] );
128 LOG("addr = 0x%x", addr);
129 ATA_int_BusMasterWriteDWord(12, addr);
131 // Enable controllers
132 outb(IDE_PRI_BASE+1, 1);
133 outb(IDE_SEC_BASE+1, 1);
136 LEAVE('i', MODULE_ERR_OK);
137 return MODULE_ERR_OK;
140 Uint64 ATA_GetDiskSize(int Disk)
149 ENTER("iDisk", Disk);
151 base = ATA_GetBasePort( Disk );
153 // Send Disk Selector
154 if(Disk == 1 || Disk == 3)
160 // Check for a floating bus
161 if( 0xFF == inb(base+7) ) {
167 // Check for the controller
168 outb(base+0x02, 0x66);
169 outb(base+0x03, 0xFF);
170 if(inb(base+0x02) != 0x66 || inb(base+0x03) != 0xFF) {
171 LOG("No controller");
179 val = inb(base+7); // Read status
180 LOG("val = 0x%02x", val);
183 return 0; // Disk does not exist
186 // Poll until BSY clears and DRQ sets or ERR is set
187 while( ((val & 0x80) || !(val & 0x08)) && !(val & 1))
190 // Check for an error
193 return 0; // Error occured, so return false
197 for( i = 0; i < 256; i++ )
198 data.buf[i] = inw(base);
200 // Return the disk size
201 if(data.identify.Sectors48 != 0)
202 return data.identify.Sectors48;
204 return data.identify.Sectors28;
208 * \fn Uint16 ATA_GetPortBase(int Disk)
209 * \brief Returns the base port for a given disk
211 Uint16 ATA_GetBasePort(int Disk)
215 case 0: case 1: return IDE_PRI_BASE;
216 case 2: case 3: return IDE_SEC_BASE;
222 * \fn int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
224 int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
226 int cont = (Disk>>1)&1; // Controller ID
231 ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer);
233 // Check if the count is small enough
234 if(Count > MAX_DMA_SECTORS) {
235 Warning("Passed too many sectors for a bulk DMA read (%i > %i)",
236 Count, MAX_DMA_SECTORS);
241 // Get exclusive access to the disk controller
242 LOCK( &giaATA_ControllerLock[ cont ] );
245 gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
248 base = ATA_GetBasePort(Disk);
251 gaATA_IRQs[cont] = 0;
254 if( Address > 0x0FFFFFFF ) // Use LBA48
256 outb(base+0x6, 0x40 | (disk << 4));
257 outb(base+0x2, 0 >> 8); // Upper Sector Count
258 outb(base+0x3, Address >> 24); // Low 2 Addr
259 outb(base+0x4, Address >> 28); // Mid 2 Addr
260 outb(base+0x5, Address >> 32); // High 2 Addr
264 outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); // Magic, Disk, High addr
267 outb(base+0x01, 0x01); //?
268 outb(base+0x02, (Uint8) Count); // Sector Count
269 outb(base+0x03, (Uint8) Address); // Low Addr
270 outb(base+0x04, (Uint8) (Address >> 8)); // Middle Addr
271 outb(base+0x05, (Uint8) (Address >> 16)); // High Addr
273 LOG("Starting Transfer");
274 LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes);
275 if( Address > 0x0FFFFFFF )
276 outb(base+0x07, HDD_DMA_R48); // Read Command (LBA48)
278 outb(base+0x07, HDD_DMA_R28); // Read Command (LBA28)
281 ATA_int_BusMasterWriteByte( cont << 3, 9 ); // Read and start
283 // Wait for transfer to complete
284 while( gaATA_IRQs[cont] == 0 ) Threads_Yield();
287 ATA_int_BusMasterWriteByte( cont << 3, 8 ); // Read and stop
290 LOG("Status byte = 0x%02x", val);
292 LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes);
293 LOG("Transfer Completed & Acknowledged");
295 // Copy to destination buffer
296 memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
298 // Release controller lock
299 RELEASE( &giaATA_ControllerLock[ cont ] );
306 * \fn int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
307 * \brief Write up to \a MAX_DMA_SECTORS to a disk
308 * \param Disk Disk ID to write to
309 * \param Address LBA of first sector
310 * \param Count Number of sectors to write (must be >= \a MAX_DMA_SECTORS)
311 * \param Buffer Source buffer for data
313 int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer)
315 int cont = (Disk>>1)&1; // Controller ID
319 // Check if the count is small enough
320 if(Count > MAX_DMA_SECTORS) return 0;
322 // Get exclusive access to the disk controller
323 LOCK( &giaATA_ControllerLock[ cont ] );
326 gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
329 base = ATA_GetBasePort(Disk);
332 outb(base+0x01, 0x00);
333 if( Address > 0x0FFFFFFF ) // Use LBA48
335 outb(base+0x6, 0x40 | (disk << 4));
336 outb(base+0x2, 0 >> 8); // Upper Sector Count
337 outb(base+0x3, Address >> 24); // Low 2 Addr
338 outb(base+0x3, Address >> 28); // Mid 2 Addr
339 outb(base+0x3, Address >> 32); // High 2 Addr
343 outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr
346 outb(base+0x02, (Uint8) Count); // Sector Count
347 outb(base+0x03, (Uint8) Address); // Low Addr
348 outb(base+0x04, (Uint8) (Address >> 8)); // Middle Addr
349 outb(base+0x05, (Uint8) (Address >> 16)); // High Addr
350 if( Address > 0x0FFFFFFF )
351 outb(base+0x07, HDD_DMA_W48); // Write Command (LBA48)
353 outb(base+0x07, HDD_DMA_W28); // Write Command (LBA28)
356 gaATA_IRQs[cont] = 0;
358 // Copy to output buffer
359 memcpy( gATA_Buffers[cont], Buffer, Count*SECTOR_SIZE );
362 ATA_int_BusMasterWriteByte( cont << 3, 1 ); // Write and start
364 // Wait for transfer to complete
365 while( gaATA_IRQs[cont] == 0 ) Threads_Yield();
368 ATA_int_BusMasterWriteByte( cont << 3, 0 ); // Write and stop
370 // Release controller lock
371 RELEASE( &giaATA_ControllerLock[ cont ] );
377 * \brief Primary ATA Channel IRQ handler
379 void ATA_IRQHandlerPri(int UNUSED(IRQ))
383 // IRQ bit set for Primary Controller
384 val = ATA_int_BusMasterReadByte( 0x2 );
385 LOG("IRQ val = 0x%x", val);
387 LOG("IRQ hit (val = 0x%x)", val);
388 ATA_int_BusMasterWriteByte( 0x2, 4 );
395 * \brief Second ATA Channel IRQ handler
397 void ATA_IRQHandlerSec(int UNUSED(IRQ))
400 // IRQ bit set for Secondary Controller
401 val = ATA_int_BusMasterReadByte( 0xA );
402 LOG("IRQ val = 0x%x", val);
404 LOG("IRQ hit (val = 0x%x)", val);
405 ATA_int_BusMasterWriteByte( 0xA, 4 );
412 * \brief Read an 8-bit value from a Bus Master register
413 * \param Ofs Register offset
415 Uint8 ATA_int_BusMasterReadByte(int Ofs)
417 if( gATA_BusMasterBase & 1 )
418 return inb( (gATA_BusMasterBase & ~1) + Ofs );
420 return *(Uint8*)(gATA_BusMasterBasePtr + Ofs);
424 * \brief Writes a byte to a Bus Master Register
425 * \param Ofs Register Offset
426 * \param Value Value to write
428 void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
430 if( gATA_BusMasterBase & 1 )
431 outb( (gATA_BusMasterBase & ~1) + Ofs, Value );
433 *(Uint8*)(gATA_BusMasterBasePtr + Ofs) = Value;
437 * \brief Writes a 32-bit value to a Bus Master Register
438 * \param Ofs Register offset
439 * \param Value Value to write
441 void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
443 if( gATA_BusMasterBase & 1 )
444 outd( (gATA_BusMasterBase & ~1) + Ofs, Value );
446 *(Uint32*)(gATA_BusMasterBasePtr + Ofs) = Value;