⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 biosial.c

📁 此为marvell 6081在bios芯片中运行的代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            if((lowLBAAddress + ax.parts.lval) > 
               sataAdapter.channelsInfo[channelIndex].diskSize[PMPort])
            {
#ifdef DEBUG_IAL
                printHexSingle ("LBA OOR Lo",(lowLBAAddress) & 0xffff);
                printHexSingle ("LBA OOR Hi",((lowLBAAddress)>>16) & 0xffff);
#endif
                flags |= 0x1;
                ax.parts.lval = 0x4;
                break;
            }


#ifdef DEBUG_IAL
            if(printAll == MV_TRUE)
            {
                printHexSingle ("LBA Low",lowLBAAddress);
                printHexSingle ("LBA Hi",lowLBAAddress >> 16);
                printHexSingle ("Sec Count", ax.parts.lval);
                printHexSingle ("Buff Seg",es);
                printHexSingle ("Buff off",bx.val);
            }
#endif
            /* 
             * If SP < 0x200, then probably when calling requestIO it's going
             * to overflow. Add 0x200 to stack pointer and bp and substitute
             * 0x20 from the stack segment. This is the same from the int13
             * handler point of view, but when going back with iret the 
             * stack pointer, bp and stack segment must be returned to it's
             * previous value.
             */

            if(sp.val < 0x200)
            {
                incrementSP = MV_TRUE;
                _asm {
                    push si
                    add sp, 0x200
                    add bp, 0x200
                    mov si, ss
                    sub si, 0x20
                    mov ss, si
                    pop si

                }
#ifdef DEBUG_IAL
                printHexSingle ("Stack WO",sp.val);
#endif
            }
            ax.parts.hval = requestIO (channelIndex, PMPort,
                                       lowLBAAddress, 0, 
                                       ax.parts.lval,
                                       (ax.parts.hval == 0x2) ? MV_UDMA_TYPE_READ : MV_UDMA_TYPE_WRITE,
                                       es, bx.val);
            /* Revert sp, bp and ss to it's previous value */
            if(incrementSP == MV_TRUE)
            {
                _asm {
                    push si
                    sub sp, 0x200
                    sub bp, 0x200
                    mov si, ss
                    add si, 0x20
                    mov ss, si
                    pop si

                }
#ifdef DEBUG_IAL
                printHexSingle ("StackB",sp.val);
#endif			
            }
            if(ax.parts.hval != 0x0)
            {
#ifdef DEBUG_IAL
                printAll = MV_TRUE;
                printHexSingle ("UDMA comp Err",ax.parts.hval);
#endif
                if(mvStorageDevATASoftResetDevice(&sataAdapter.mvSataAdapter,
                                                  channelIndex, PMPort, 0) ==
                   MV_FALSE)
                {
#ifdef DEBUG_IAL
                    printHexSingle ("Softrst Err",ax.parts.hval);
#endif
                }
                flags |= 0x1;
            }
            /* 
             * Revert the Request Queue hi base address to it's value that is
             * set in initializeDriver 
             */
            if((channelIndex == 0) && (useIoBar == MV_FALSE))
            {
                mvSataWriteReg(&sataAdapter.mvSataAdapter, 0x22010, mvSataBarOffset);
            }

            break;
        }
    case 0x00:          /* Reset disk system */
    case 0x0d:          /* Alternate Fixed Disk Reset */
        if(mvStorageDevATASoftResetDevice(&sataAdapter.mvSataAdapter,
                                          channelIndex, PMPort, 0) == MV_FALSE)
        {
            flags |= 0x1;
            ax.parts.hval = 0x5; /* fixed disk reset failed */
#ifdef DEBUG_IAL
            printHexSingle ("Softrst Err",ax.parts.hval);
#endif
        } else
        {
            ax.parts.hval = 0x0; /* All went good */
        }
        break;
    case 0x04:          /* Verify Sectors */
        {
            MV_U32 lowLBAAddress;
            unsigned long track, head;
            unsigned char sector;
            MV_BOOLEAN returnStatus;
            MV_U8 ATAStatus, ATAError;
            MV_U16 timerBase, timerChanges;

            sector = (unsigned short) (cx.parts.lval & 0x3f);
            track = (((unsigned short)(cx.parts.lval & 0xc0) << 2) | cx.parts.hval);
            head = (unsigned short) dx.parts.hval;
            lowLBAAddress = 
            (unsigned long) track * HEADS * SECTORS +
            (unsigned long) head * SECTORS +
            (unsigned long) (sector - 1) ;

	     cx.val = 0xf9;  0000 0000 1111 1001
            dx.val = 0xc97e; 1100 1001 0111 1110
			
            /* Check if sector count is more than 128 or equals 0 */
            if((ax.parts.lval > 128) || (ax.parts.lval == 0))
            {
#ifdef DEBUG_IAL
                printHexSingle ("Sect Cnt Err",readSegmentOffset16bit(ds,si.val+2));
#endif
                flags |= 0x1;
                ax.parts.lval = 0xa;
                break;
            }
            if((lowLBAAddress + ax.parts.lval) > 
               sataAdapter.channelsInfo[channelIndex].diskSize[PMPort])
            {
#ifdef DEBUG_IAL
                printHexSingle ("LBA OOR Lo",(lowLBAAddress) & 0xffff);
                printHexSingle ("LBA OOR Hi",((lowLBAAddress)>>16) & 0xffff);
#endif
                flags |= 0x1;
                ax.parts.lval = 0x4;
                break;
            }


#ifdef DEBUG_IAL
            if(printAll == MV_TRUE)
            {
                printHexSingle ("V LBA Low",lowLBAAddress);
                printHexSingle ("V LBA Hi",lowLBAAddress >> 16);
                printHexSingle ("V Sec Count", ax.parts.lval);
            }
#endif
            returnStatus = MV_TRUE;
            /*
             * Since in this function the LBA address translation from CHS
             * can't be LBA48, then send only LBA 28 command.
             */
            mvSataWriteReg (&sataAdapter.mvSataAdapter,
                            getEdmaRegOffset (channelIndex) + MV_ATA_DEVICE_FEATURES_REG_OFFSET,
                            0);

            mvSataWriteReg (&sataAdapter.mvSataAdapter,
                            getEdmaRegOffset (channelIndex) + MV_ATA_DEVICE_SECTOR_COUNT_REG_OFFSET,
                            ax.parts.lval);

            mvSataWriteReg (&sataAdapter.mvSataAdapter,
                            getEdmaRegOffset (channelIndex) + MV_ATA_DEVICE_LBA_LOW_REG_OFFSET,
                            (MV_U32)(lowLBAAddress & 0xffUL));

            mvSataWriteReg (&sataAdapter.mvSataAdapter,
                            getEdmaRegOffset (channelIndex) + MV_ATA_DEVICE_LBA_MID_REG_OFFSET,
                            (MV_U32)((lowLBAAddress & 0xff00UL) >> 8));

            mvSataWriteReg (&sataAdapter.mvSataAdapter,
                            getEdmaRegOffset (channelIndex) + MV_ATA_DEVICE_LBA_HIGH_REG_OFFSET,
                            (MV_U32)((lowLBAAddress & 0xff0000UL) >> 16));

            mvSataWriteReg (&sataAdapter.mvSataAdapter,
                            getEdmaRegOffset (channelIndex) + MV_ATA_DEVICE_LBA_HIGH_REG_OFFSET,
                            (MV_U32)((MV_BIT6) |
                                     ((lowLBAAddress & 0x0f000000UL) >> 24)));
            mvSataWriteReg (&sataAdapter.mvSataAdapter,
                            getEdmaRegOffset (channelIndex) + MV_ATA_DEVICE_COMMAND_REG_OFFSET,
                            MV_ATA_COMMAND_READ_VERIFY_SECTORS);
            /* Command is out - wait for 10 seconds for completion */
            timerChanges = 0;
            timerBase = readSystemClockTimer();
            while(1)
            {
                MV_U16 timerCurrent;
                timerCurrent = readSystemClockTimer();
                ATAStatus = mvSataReadReg (&sataAdapter.mvSataAdapter,
                                           getEdmaRegOffset (channelIndex) +
                                           MV_ATA_DEVICE_STATUS_REG_OFFSET);
                /* Is BSY bit '0' ? */
                if(!(ATAStatus & MV_BIT7))
                {
                    break;
                }
                /* 
                 * For measuring the time, the driver is waiting for changes on the 
                 * system timer and count these changes.
                 */
                if(timerCurrent != timerBase)
                {
                    timerChanges ++;
                    timerBase = timerCurrent;
                }

                /* 
                 * Check if reached 10 seconds timeout. The 18*10 is because the system
                 * timer is ~18Hz, and the required timeout is 10seconds
                 */

                if(timerChanges == (18*10))
                {
#ifdef DEBUG_IAL
                    printHexSingle ("Timeout !!!",0);
#endif
                    returnStatus = MV_FALSE;
                    break;
                }
            }


            /* If function returned MV_TRUE, check ATA Status */
            if(returnStatus == MV_TRUE)
            {
                /* Is err bit set ? */
                if(ATAStatus & MV_BIT0)
                {
                    ATAError = mvSataReadReg (&sataAdapter.mvSataAdapter,
                                              getEdmaRegOffset (channelIndex) +
                                              MV_ATA_DEVICE_ERROR_REG_OFFSET);

#ifdef DEBUG_IAL
                    printHexSingle ("VER ERR",ATAStatus);
                    printHexSingle ("VER ERR",ATAError);
#endif

                    /* Check UNC */
                    if(ATAStatus & MV_BIT6)
                    {
                        /* Medium error */
                        ax.parts.hval = 0x2;
                        flags |= 0x1;
                    } else
                    {
                        /* HDD Error */
                        ax.parts.hval = 0xbb;
                        flags |= 0x1;
                    }
                }
            } else
            {
#ifdef DEBUG_IAL
                printHexSingle ("TimeOut",ATAStatus);
#endif

                /* Return not ready / timeout */
                ax.parts.hval = 0x80;
                flags |= 0x1;
            }
            break;
        }
    case 0x05:          /* Format Cylinder */
    case 0x09:          /* Initialize Drive Parameters */
    case 0x0c:          /* Seek to Cylinder */
    case 0x11:          /* Recalibrate Drive */
    case 0x12:          /* Controller Ram Diagnostic */
    case 0x13:          /* Controller Driver Diagnositc */
    case 0x14:          /* Controller Internal Diagnostic */
    case 0x44:          /* Extended verify sectors */
    case 0x18:          /* Set Media Type For Format */
        {
            ax.parts.hval = 0x0;    /* Fake the command as if it has passed */
            break;
        }
    case 0x47:          /* Extended seek */
        {
            ax.parts.hval = 0;  /* lie and say it all worked */
            break;
        }
    case 0x08:          /* Read Drive Parameters */
        {
            ax.val = 0;
            cx.val = 0xfeff;
            cx.parts.lval = ((CYLINDER & 0x300) >> 2) | SECTORS;
            cx.parts.hval = (CYLINDER & 0xff);
            dx.parts.hval = HEADS - 1;
            dx.parts.lval = getCurrentInstalledDrives();

            break;
        }
    case 0x10:          /* Test for Drive Ready */
        {
            ax.parts.hval = 0;
            break;
        }
    case 0x15:          /* Read Fixed Disk Type */
        {
            cx.val = 0xf9;
            dx.val = 0xc97e;
            ax.val = 0x0300;
            break;
        }
        /* Extended commands */
    case 0x41:
        {
            ax.parts.hval = 0x21; /* Major revision number */
            bx.val = 0xaa55;
            cx.val = 0x5 ; /* Device access using the packet structure */
            break;
        }
    case 0x42:  /* Extended READ */
    case 0x43:  /* Extended WRITE */
        {
            unsigned short blknumLo, blknumHi;
            MV_U32 lowLBAAddress;
            unsigned short sectorCount;
            unsigned short segment, offset;
            /* Check that packet is at least 16 bytes */
            if(((unsigned char)readSegmentOffset16bit(ds,si.val)) < 0x10)
            {
#ifdef DEBUG_IAL
                printHexSingle ("Length err",readSegmentOffset16bit(ds,si.val));
                printAll = MV_TRUE;
#endif
                flags |= 0x1;
                ax.parts.lval = 0x1;
                break;
            }
            /* Meantime, support only 32 bits of address */
            blknumLo = readSegmentOffset16bit(ds,si.val+8);
            blknumHi = readSegmentOffset16bit(ds,si.val+10);
            lowLBAAddress = (MV_U32) ((((MV_U32)blknumHi) << 16) |
                                      (((MV_U32)blknumLo) & 0x0000ffff));

            sectorCount = (unsigned char) (readSegmentOffset16bit(ds,si.val+2) & 0xff);

            /* Check if sector count is more than 128 or equals 0 */
            if((sectorCount > 128) || (sectorCount == 0))
            {
#ifdef DEBUG_IAL
                printHexSingle ("Sect Cnt Err",readSegmentOffset16bit(ds,si.val+2));
#endif
                flags |= 0x1;
                ax.parts.lval = 0xa;
                break;
            }
            if((lowLBAAddress + sectorCount) > 
               sataAdapter.channelsInfo[channelIndex].diskSize[PMPort])
            {
#ifdef DEBUG_IAL
                printHexSingle ("LBA OOR Lo",(lowLBAAddress) & 0xffff);
                printHexSingle ("LBA OOR Hi",((lowLBAAddress)>>16) & 0xffff);
#endif
                flags |= 0x1;
                ax.parts.lval = 0x4;
                break;
            }
            segment = readSegmentOffset16bit(ds,si.val + 6);
            offset = readSegmentOffset16bit(ds,si.val + 4);
#ifdef DEBUG_IAL
            if(printAll == MV_TRUE)
            {
                printHexSingle ("LBA Low",blknumLo);
                printHexSingle ("LBA Hi",blknumHi);
                printHexSingle ("LBA Low",lowLBAAddress);
                printHexSingle ("LBA Hi",lowLBAAddress>>16);
                printHexSingle ("Sec Count",sectorCount);
                printHexSingle ("Buff seg",segment);
                printHexSingle ("Buff off",offset);
                printHexSingle ("Buff Lo",generate32Addr (segment, offset));
                printHexSingle ("Buff Hi",generate32Addr (segment, offset)>>16);
                printHexSingle ("R/W",ax.parts.hval);
            }
#endif
            /* 
             * If SP < 0x200, then probably when calling requestIO it's going
             * to overflow. Add 0x200 to stack pointer and bp and substitute
             * 0x20 from the stack segment. This is the same from the int13
             * handler point of view, but when going back with iret the 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -