main.c

来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C语言 代码 · 共 1,412 行 · 第 1/4 页

C
1,412
字号
    //
TEST_TRAP();
    if ( (g_pBootCfg->ConfigFlags & (BOOT_TYPE_DIRECT|TARGET_TYPE_NAND)) &&
         !ReadKernelRegionFromBootMedia() )
    {
        RETAILMSG(1, (TEXT("ERROR: OEMPlatformInit: Failed to load kernel region into RAM.\r\n")));
        SPIN_FOREVER;
    }
#endif 0

    EdbgOutputDebugString("\r\nJumping to image at virtual address 0x%Xh\r\n", dwLaunchAddr);

    //  Our Launch function takes Physical address, so we need to convert it
    //  to physical address

    dwLaunchAddr = (DWORD)OALVAtoPA((void *)dwLaunchAddr);
    EdbgOutputDebugString("\r\n::: Physical Launch Address: 0x%Xh\r\n",dwLaunchAddr);

//	OEMStopDebugSerial();
	
    Launch(dwLaunchAddr);

    // never returned
    SPIN_FOREVER;
}


/*
    @func   BOOL | OEMReadData | Generically read download data (abstracts actual transport read call).
    @rdesc  TRUE = Success, FALSE = Failure.
    @comm
    @xref
*/
BOOL OEMReadData (DWORD cbData, LPBYTE pbData)
{
//	EdbgOutputDebugString("\r\n::: OEMReadData  Downlad thru:  %s\r\n",g_bUSBDownload?"USB":"Ethernet");
	if ( g_bUSBDownload == FALSE )
	{
		return EbootEtherReadData(cbData, pbData);
	}
	else
	{
		return UbootReadData(cbData, pbData);
	}
}


/*
    @func   void | OEMShowProgress | Displays download progress for the user.
    @rdesc  N/A.
    @comm
    @xref
*/
void OEMShowProgress (DWORD dwPacketNum)
{
}


#define BACKSPACE   8
#define IPADDR_MAX  15
// Read IP from command line
static BOOL ReadIPLine (char *pbuf, DWORD dwTimeout)
{
    DWORD dwCurrSec = OEMEthGetSecs ();
    char ch;
    int nLen = 0;
    while (OEMEthGetSecs () - dwCurrSec < dwTimeout) {
        ch = (CHAR)OEMReadDebugByte();
        switch (ch) {
        case OEM_DEBUG_COM_ERROR:
        case OEM_DEBUG_READ_NODATA:
            // no data or error, keep reading
            break;

        case BACKSPACE:
            nLen --;
            OEMWriteDebugByte (ch);
            break;

        case '\r':
        case '\n':
            OEMWriteDebugByte ('\n');
            pbuf[nLen] = 0;
            return TRUE;

        default:
            if ((ch == '.' || (ch >= '0' && ch <= '9')) && (nLen < IPADDR_MAX)) {
                pbuf[nLen ++] = ch;
                OEMWriteDebugByte (ch);
            }
        }
    }

    return FALSE;   // timeout
}


// get users IP / SubnetMask
// return TRUE is changes made to either, else FALSE.
static BOOL GetUserIPAddr (EDBG_ADDR *pMyAddr, DWORD *pdwSubnetMask)
{
    char  szbuf[IPADDR_MAX+1];
    uchar changes = 0;

    memset(szbuf, 0, sizeof(szbuf));

    EdbgOutputDebugString ("\r\nEnter IP address, or CR for default (%s): ", inet_ntoa(pMyAddr->dwIP));
    ReadIPLine (szbuf, INFINITE);
    if (szbuf[0]) {
        pMyAddr->dwIP = inet_addr(szbuf);
        changes++;
        memset(szbuf, 0, sizeof(szbuf));
    }

    EdbgOutputDebugString ("\r\nEnter Subnet Masks, or CR for default (%s): ", inet_ntoa(*pdwSubnetMask));
    ReadIPLine (szbuf, INFINITE);
    if (szbuf[0]) {
        *pdwSubnetMask = inet_addr (szbuf);
        changes++;
    }

    EdbgOutputDebugString ( "\r\nUsing IP Address %s, subnet mask %s\r\n",
                inet_ntoa (pMyAddr->dwIP), inet_ntoa (*pdwSubnetMask));

    return (changes ? TRUE : FALSE);
}

static ULONG mystrtoul(PUCHAR pStr, UCHAR nBase)
{
    UCHAR nPos=0;
    BYTE c;
    ULONG nVal = 0;
    UCHAR nCnt=0;
    ULONG n=0;

    // fulllibc doesn't implement isctype or iswctype, which are needed by
    // strtoul, rather than including coredll code, here's our own simple strtoul.

    if (pStr == NULL)
        return(0);

    for (nPos=0 ; nPos < strlen(pStr) ; nPos++)
    {
//        c = tolower(*(pStr + strlen(pStr) - 1 - nPos));
        c = (*(pStr + strlen(pStr) - 1 - nPos));
        if (c >= '0' && c <= '9')
            c -= '0';
        else if (c >= 'a' && c <= 'f')
        {
            c -= 'a';
            c  = (0xa + c);
        }

        for (nCnt = 0, n = 1 ; nCnt < nPos ; nCnt++)
        {
            n *= nBase;
        }
        nVal += (n * c);
    }

    return(nVal);
}

// since the startup code is in OAL and it branch to main, we'll just
// implement a pseudo 'main' instead of changing the startup code
void main (void)
{
    BootloaderMain ();

    SPIN_FOREVER;
}

VOID SC_WriteDebugLED(WORD wIndex, DWORD dwPattern)
{
    OEMWriteDebugLED(wIndex,dwPattern);
}

/*
    @func   void | SetDelay | Accepts an autoboot delay value from user input.
    @rdesc  N/A.
    @comm    
    @xref   
*/
static void SetDelay()
{
    CHAR szCount[16];
    USHORT cwNumChars = 0;
    USHORT InChar = 0;

    EdbgOutputDebugString("\r\nEnter maximum number of seconds to delay [1-255]: ");

    while(!((InChar == 0x0d) || (InChar == 0x0a)))
    {
        InChar = OEMReadDebugByte();
        if (InChar != OEM_DEBUG_COM_ERROR && InChar != OEM_DEBUG_READ_NODATA) 
        {
            // If it's a number or a period, add it to the string.
            //
            if ((InChar >= '0' && InChar <= '9')) 
            {
                if (cwNumChars < 16) 
                {
                    szCount[cwNumChars++] = (char)InChar;
                    OEMWriteDebugByte((BYTE)InChar);
                }
            }
            // If it's a backspace, back up.
            //
            else if (InChar == 8) 
            {
                if (cwNumChars > 0) 
                {
                    cwNumChars--;
                    OEMWriteDebugByte((BYTE)InChar);
                }
            }
        }
    }

    // If it's a carriage return with an empty string, don't change anything.
    //
    if (cwNumChars) 
    {
        szCount[cwNumChars] = '\0';
        g_pBootCfg->BootDelay = atoi(szCount);
        if (g_pBootCfg->BootDelay > 255)
        {
            g_pBootCfg->BootDelay = 255;
        } 
        else if (g_pBootCfg->BootDelay < 1)
        {
            g_pBootCfg->BootDelay = 1;
        }
    }
}



static void CvtMAC(USHORT MacAddr[3], char *pszDottedD ) 
{
    DWORD cBytes;
    char *pszLastNum;
    int atoi (const char *s);
    int i=0;    
    BYTE *p = (BYTE *)MacAddr;

    // Replace the dots with NULL terminators
    pszLastNum = pszDottedD;
    for(cBytes = 0 ; cBytes < 6 ; cBytes++)
    {
        while(*pszDottedD != '.' && *pszDottedD != '\0')
        {
            pszDottedD++;
        }
        if (pszDottedD == '\0' && cBytes != 5)
        {
            // zero out the rest of MAC address
            while(i++ < 6)
            {
                *p++ = 0;
            }
            break;
        }
        *pszDottedD = '\0';
        *p++ = (BYTE)(mystrtoul(pszLastNum, 16) & 0xFF);
        i++;
        pszLastNum = ++pszDottedD;
    }
}



static void SetCS8900MACAddress()
{
    CHAR szDottedD[24];
    USHORT cwNumChars = 0;
    USHORT InChar = 0;

    memset(szDottedD, '0', 24);

    EdbgOutputDebugString ( "\r\nEnter new MAC address in hexadecimal (hh.hh.hh.hh.hh.hh): ");

    while(!((InChar == 0x0d) || (InChar == 0x0a)))
    {
        InChar = OEMReadDebugByte();
//        InChar = tolower(InChar);
        if (InChar != OEM_DEBUG_COM_ERROR && InChar != OEM_DEBUG_READ_NODATA) 
        {
            // If it's a hex number or a period, add it to the string.
            //
            if (InChar == '.' || (InChar >= '0' && InChar <= '9') || (InChar >= 'a' && InChar <= 'f')) 
            {
                if (cwNumChars < 17) 
                {
                    szDottedD[cwNumChars++] = (char)InChar;
                    OEMWriteDebugByte((BYTE)InChar);
                }
            }
            else if (InChar == 8)       // If it's a backspace, back up.
            {
                if (cwNumChars > 0) 
                {
                    cwNumChars--;
                    OEMWriteDebugByte((BYTE)InChar);
                }
            }
        }
    }

    EdbgOutputDebugString ( "\r\n");

    // If it's a carriage return with an empty string, don't change anything.
    //
    if (cwNumChars) 
    {
        szDottedD[cwNumChars] = '\0';
        CvtMAC(g_pBootCfg->EdbgAddr.wMAC, szDottedD);

        EdbgOutputDebugString("INFO: MAC address set to: %x:%x:%x:%x:%x:%x\r\n",
                  g_pBootCfg->EdbgAddr.wMAC[0] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[0] >> 8,
                  g_pBootCfg->EdbgAddr.wMAC[1] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[1] >> 8,
                  g_pBootCfg->EdbgAddr.wMAC[2] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[2] >> 8);
    }
    else
    {
        EdbgOutputDebugString("WARNING: SetCS8900MACAddress: Invalid MAC address.\r\n");
    }
}


void InitEthMemBank(void)
{
	volatile S3C24A0_SROM_REG *sromReg = (S3C24A0_SROM_REG *)OALPAtoVA(S3C24A0_BASE_REG_PA_SROM,FALSE);
	

	RETAILMSG(1, (TEXT("Ethernet memory bank configuration\r\n")));

	sromReg->SROM_BW &= ~(7<<3);
	sromReg->SROM_BW |= 7<<3;

#define B1_Tacs		0x0	//0  clk
#define B1_Tcos		0x2	//0  clk
#define B1_Tacc		0x6	//20 clks
#define B1_Tcoh		0x2	//0  clk
#define B1_Tcah		0x2	//0  clk
#define B1_Tacp		0x0	
#define B1_PMC		0x0	//normal

	sromReg->SROM_BC1 = 	((B1_Tacs<<14)+(B1_Tcos<<12)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tcah<<4)+(B1_Tacp<<2)+(B1_PMC));   //;GCS1 

//	sromReg->rSROM_BC1 = 2<<14|2<<12|6<<8|2<<6|2<<4; 
}

⌨️ 快捷键说明

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