Fiddling with multiboot modules (and some bug searching in ATA code)
[tpg/acess2.git] / Modules / Storage / ATA / main.c
index 3e7cb61..f4130b0 100644 (file)
@@ -2,7 +2,7 @@
  * Acess2 IDE Harddisk Driver
  * - main.c
  */
-#define DEBUG  0
+#define DEBUG  1
 #include <acess.h>
 #include <modules.h>
 #include <vfs.h>
@@ -12,9 +12,6 @@
 #include <tpl_drv_disk.h>
 #include "common.h"
 
-// --- Flags ---
-#define START_BEFORE_CMD       0
-
 // === STRUCTURES ===
 typedef struct
 {
@@ -44,7 +41,7 @@ typedef struct
 } __attribute__ ((packed))     tIdentify;
 
 // === IMPORTS ===
-extern void    ATA_ParseMBR(int Disk);
+extern void    ATA_ParseMBR(int Disk, tMBR *MBR);
 
 // === PROTOTYPES ===
  int   ATA_Install();
@@ -96,8 +93,8 @@ Uint8 *gATA_BusMasterBasePtr = 0;
  int   gATA_IRQPri = 14;
  int   gATA_IRQSec = 15;
  int   giaATA_ControllerLock[2] = {0}; //!< Spinlocks for each controller
-Uint8  gATA_Buffers[2][4096] __attribute__ ((section(".padata")));
- int   gaATA_IRQs[2] = {0};
+Uint8  gATA_Buffers[2][(MAX_DMA_SECTORS+0xFFF)&~0xFFF] __attribute__ ((section(".padata")));
+volatile int   gaATA_IRQs[2] = {0};
 tPRDT_Ent      gATA_PRDTs[2] = {
        {0, 512, IDE_PRDT_LAST},
        {0, 512, IDE_PRDT_LAST}
@@ -150,7 +147,7 @@ int ATA_SetupIO()
        if( !(gATA_BusMasterBase & 1) )
        {
                if( gATA_BusMasterBase < 0x100000 )
-                       gATA_BusMasterBasePtr = (void*)(0xC0000000|gATA_BusMasterBase);
+                       gATA_BusMasterBasePtr = (void*)(KERNEL_BASE | (tVAddr)gATA_BusMasterBase);
                else
                        gATA_BusMasterBasePtr = (void*)( MM_MapHWPages( gATA_BusMasterBase, 1 ) + (gATA_BusMasterBase&0xFFF) );
                LOG("gATA_BusMasterBasePtr = %p", gATA_BusMasterBasePtr);
@@ -164,15 +161,15 @@ int ATA_SetupIO()
        IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri );
        IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec );
 
-       gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[0] );
-       gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[1] );
+       gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[0] );
+       gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (tVAddr)&gATA_Buffers[1] );
 
        LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
 
-       addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[0] );
+       addr = MM_GetPhysAddr( (tVAddr)&gATA_PRDTs[0] );
        LOG("addr = 0x%x", addr);
        ATA_int_BusMasterWriteDWord(4, addr);
-       addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[1] );
+       addr = MM_GetPhysAddr( (tVAddr)&gATA_PRDTs[1] );
        LOG("addr = 0x%x", addr);
        ATA_int_BusMasterWriteDWord(12, addr);
 
@@ -238,9 +235,11 @@ void ATA_SetupVFS()
  */
 int ATA_ScanDisk(int Disk)
 {
-       Uint16  buf[256];
-       tIdentify       *identify = (void*)buf;
-       tMBR    *mbr = (void*)buf;
+       union {
+               Uint16  buf[256];
+               tIdentify       identify;
+               tMBR    mbr;
+       }       data;
        Uint16  base;
        Uint8   val;
         int    i;
@@ -275,26 +274,35 @@ int ATA_ScanDisk(int Disk)
        }
 
        // Read Data
-       for(i=0;i<256;i++)      buf[i] = inw(base);
+       for(i=0;i<256;i++)      data.buf[i] = inw(base);
 
        // Populate Disk Structure
-       if(identify->Sectors48 != 0)
-               gATA_Disks[ Disk ].Sectors = identify->Sectors48;
+       if(data.identify.Sectors48 != 0)
+               gATA_Disks[ Disk ].Sectors = data.identify.Sectors48;
        else
-               gATA_Disks[ Disk ].Sectors = identify->Sectors28;
+               gATA_Disks[ Disk ].Sectors = data.identify.Sectors28;
 
 
        LOG("gATA_Disks[ Disk ].Sectors = 0x%x", gATA_Disks[ Disk ].Sectors);
 
-       if( gATA_Disks[ Disk ].Sectors / (2048*1024) )
-               Log("Disk %i: 0x%llx Sectors (%i GiB)", Disk,
-                       gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / (2048*1024));
-       else if( gATA_Disks[ Disk ].Sectors / 2048 )
-               Log("Disk %i: 0x%llx Sectors (%i MiB)", Disk,
-                       gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / 2048);
-       else
-               Log("Disk %i: 0x%llx Sectors (%i KiB)", Disk,
-                       gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / 2);
+       {
+               Uint64  val = gATA_Disks[ Disk ].Sectors / 2;
+               char    *units = "KiB";
+               if( val > 4*1024 ) {
+                       val /= 1024;
+                       units = "MiB";
+               }
+               else if( val > 4*1024 ) {
+                       val /= 1024;
+                       units = "GiB";
+               }
+               else if( val > 4*1024 ) {
+                       val /= 1024;
+                       units = "TiB";
+               }
+               Log_Log("ATA", "Disk %i: 0x%llx Sectors (%i %s)", Disk,
+                       gATA_Disks[ Disk ].Sectors, val, units);
+       }
 
        // Create Name
        gATA_Disks[ Disk ].Name[0] = 'A'+Disk;
@@ -314,17 +322,19 @@ int ATA_ScanDisk(int Disk)
        node->Write = ATA_WriteFS;
        node->IOCtl = ATA_IOCtl;
 
-
        // --- Scan Partitions ---
        LOG("Reading MBR");
        // Read Boot Sector
-       ATA_ReadDMA( Disk, 0, 1, mbr );
+       ATA_ReadDMA( Disk, 0, 1, &data.mbr );
 
        // Check for a GPT table
-       if(mbr->Parts[0].SystemID == 0xEE)
+       if(data.mbr.Parts[0].SystemID == 0xEE)
                ATA_ParseGPT(Disk);
        else    // No? Just parse the MBR
-               ATA_ParseMBR(Disk);
+               ATA_ParseMBR(Disk, &data.mbr);
+       
+       ATA_ReadDMA( Disk, 1, 1, &data );
+       Debug_HexDump("ATA_ScanDisk", &data, 512);
 
        LEAVE('i', 0);
        return 1;
@@ -355,6 +365,7 @@ void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start
        Part->Node.Read = ATA_ReadFS;
        Part->Node.Write = ATA_WriteFS;
        Part->Node.IOCtl = ATA_IOCtl;
+       Log_Notice("ATA", "Note '%s' at 0x%llx, 0x%llx long", Part->Name, Part->Start, Part->Length);
        LOG("Made '%s' (&Node=%p)", Part->Name, &Part->Node);
        LEAVE('-');
 }
@@ -398,14 +409,17 @@ char *ATA_ReadDir(tVFS_Node *Node, int Pos)
 tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name)
 {
         int    part;
+       tATA_Disk       *disk;
+       
        // Check first character
        if(Name[0] < 'A' || Name[0] > 'A'+MAX_ATA_DISKS)
                return NULL;
+       disk = &gATA_Disks[Name[0]-'A'];
        // Raw Disk
        if(Name[1] == '\0') {
-               if( gATA_Disks[Name[0]-'A'].Sectors == 0 )
+               if( disk->Sectors == 0 && disk->Name[0] == '\0')
                        return NULL;
-               return &gATA_Disks[Name[0]-'A'].Node;
+               return &disk->Node;
        }
 
        // Partitions
@@ -413,7 +427,7 @@ tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name)
        if(Name[2] == '\0') {   // <= 9
                part = Name[1] - '0';
                part --;
-               return &gATA_Disks[Name[0]-'A'].Partitions[part].Node;
+               return &disk->Partitions[part].Node;
        }
        // > 9
        if('0' > Name[2] || '9' < Name[2])      return NULL;
@@ -422,7 +436,7 @@ tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name)
        part = (Name[1] - '0') * 10;
        part += Name[2] - '0';
        part --;
-       return &gATA_Disks[Name[0]-'A'].Partitions[part].Node;
+       return &disk->Partitions[part].Node;
 
 }
 
@@ -434,26 +448,36 @@ Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
         int    disk = Node->Inode >> 8;
         int    part = Node->Inode & 0xFF;
 
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+
        // Raw Disk Access
        if(part == 0xFF)
        {
-               if( Offset >= gATA_Disks[disk].Sectors * SECTOR_SIZE )
+               if( Offset >= gATA_Disks[disk].Sectors * SECTOR_SIZE ) {
+                       LEAVE('i', 0);
                        return 0;
+               }
                if( Offset + Length > gATA_Disks[disk].Sectors*SECTOR_SIZE )
                        Length = gATA_Disks[disk].Sectors*SECTOR_SIZE - Offset;
        }
        // Partition
        else
        {
-               if( Offset >= gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE )
+               if( Offset >= gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE ) {
+                       LEAVE('i', 0);
                        return 0;
+               }
                if( Offset + Length > gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE )
                        Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset;
                Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE;
        }
 
-       //Log("ATA_ReadFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer);
-       return DrvUtil_ReadBlock(Offset, Length, Buffer, ATA_ReadRaw, SECTOR_SIZE, disk);
+       {
+               int ret = DrvUtil_ReadBlock(Offset, Length, Buffer, ATA_ReadRaw, SECTOR_SIZE, disk);
+               Debug_HexDump("ATA_ReadFS", Buffer, Length);
+               LEAVE('i', ret);
+               return ret;
+       }
 }
 
 /**
@@ -545,7 +569,7 @@ Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
        Uint    offset;
        Uint    done = 0;
 
-       // Pass straight on to ATA_WriteDMA if we can
+       // Pass straight on to ATA_WriteDMA, if we can
        if(Count <= MAX_DMA_SECTORS)
        {
                ret = ATA_WriteDMA(Disk, Address, Count, Buffer);
@@ -579,6 +603,7 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
         int    cont = (Disk>>1)&1;     // Controller ID
         int    disk = Disk & 1;
        Uint16  base;
+       Uint8   val;
 
        ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer);
 
@@ -609,12 +634,12 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
                outb(base+0x6, 0x40 | (disk << 4));
                outb(base+0x2, 0 >> 8); // Upper Sector Count
                outb(base+0x3, Address >> 24);  // Low 2 Addr
-               outb(base+0x3, Address >> 28);  // Mid 2 Addr
-               outb(base+0x3, Address >> 32);  // High 2 Addr
+               outb(base+0x4, Address >> 28);  // Mid 2 Addr
+               outb(base+0x5, Address >> 32);  // High 2 Addr
        }
        else
        {
-               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr
+               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); // Magic, Disk, High addr
        }
 
        outb(base+0x02, (Uint8) Count);         // Sector Count
@@ -623,32 +648,26 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
        outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
 
        LOG("Starting Transfer");
-       #if START_BEFORE_CMD
-       // Start transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 9 );     // Read and start
-       if( Address > 0x0FFFFFFF )
-               outb(base+0x07, HDD_DMA_R48);   // Read Command (LBA48)
-       else
-               outb(base+0x07, HDD_DMA_R28);   // Read Command (LBA28)
-       #else
        if( Address > 0x0FFFFFFF )
                outb(base+0x07, HDD_DMA_R48);   // Read Command (LBA48)
        else
                outb(base+0x07, HDD_DMA_R28);   // Read Command (LBA28)
        // Start transfer
        ATA_int_BusMasterWriteByte( cont << 3, 9 );     // Read and start
-       #endif
 
        // Wait for transfer to complete
-       //ATA_int_BusMasterWriteByte( (cont << 3) + 2, 0x4 );
-       while( gaATA_IRQs[cont] == 0 ) {
-               //Uint8 val = ATA_int_BusMasterReadByte( (cont << 3) + 2, 0x4 );
+       val = 0;
+       while( gaATA_IRQs[cont] == 0 && !(val & 0x4) ) {
+               val = ATA_int_BusMasterReadByte( (cont << 3) + 2 );
                //LOG("val = 0x%02x", val);
                Threads_Yield();
        }
 
        // Complete Transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 0 );     // Write and stop
+       ATA_int_BusMasterWriteByte( cont << 3, 8 );     // Read and stop
+
+       val = inb(base+0x7);
+       LOG("Status byte = 0x%02x", val);
 
        LOG("Transfer Completed & Acknowledged");
 

UCC git Repository :: git.ucc.asn.au