#include <bsp.h>

//------------------------------------------------------------------------------
//
//  Function:  OALArgsInit
//
//  This function is called by other OAL modules to intialize value of argument
//  structure.
//
BSP_ARGS *g_pBSPArgs = NULL;

VOID OALArgsInit(BSP_ARGS* pArgs)
{
    OALMSG(OAL_ARGS&&OAL_INFO, (TEXT("+OALArgsInit()\r\n")));

	g_pBSPArgs = pArgs;
    
    // Check the BSP Args area
    //
    if ((g_pBSPArgs->header.signature  == OAL_ARGS_SIGNATURE)
        && (g_pBSPArgs->header.oalVersion == OAL_ARGS_VERSION)
        && (g_pBSPArgs->header.bspVersion == BSP_ARGS_VERSION))
    {
        OALMSG(OAL_ARGS&&OAL_INFO, (L"Arguments Area has some values\r\n"));
    }
    else
    {
        volatile CHIPID_REG *pCHIPIDReg = NULL;
        DWORD count = 0, code = 0;
        int j = 0;
        UCHAR d = 0;

        OALMSG(OAL_WARN, (L"ARGS: Initializing BSP_ARGS back to initial state.\r\n"));
        
        pCHIPIDReg = (CHIPID_REG *)OALPAtoUA(BASE_REG_PA_CHIPID);

        memset(g_pBSPArgs, 0x0, sizeof(BSP_ARGS));

        // Setup header
        g_pBSPArgs->header.signature = OAL_ARGS_SIGNATURE;
        g_pBSPArgs->header.oalVersion = OAL_ARGS_VERSION;
        g_pBSPArgs->header.bspVersion = BSP_ARGS_VERSION;

        // Initialize DRVMSG
		for (j = 0; j < DRVLOG_PART_NUM; j++)
			g_pBSPArgs->dwDrvMsgMask[j] = INITIAL_LOGMASK_VAL;       

        //Set-up device ID for SMDKV210
        count = sizeof(BSP_DEVICE_PREFIX) - 1;

        //if (count > sizeof(g_pBSPArgs->deviceID)/2) count = sizeof(g_pBSPArgs->deviceID)/2;

        memcpy(g_pBSPArgs->deviceID, BSP_DEVICE_PREFIX, count);

        //Acauire CPU ID
        code = pCHIPIDReg->PRO_ID;

        // Convert it to hex number
        for (j = 28; j >= 0 && count < sizeof(g_pBSPArgs->deviceID); j -= 4)
        {
            d = (UCHAR)((code >> j) & 0xF);
            g_pBSPArgs->deviceID[count++] = d < 10 ? '0' + d : 'A' + d - 10;
        }

        // End string
        while (count < sizeof(g_pBSPArgs->deviceID)) g_pBSPArgs->deviceID[count++] = '\0';

        // Set-up uuid for SMDKV210 with OneNand UUID.
        // Actually, S5PV210 does not provide UUID for each chip
        // So read it from OneNand
        // This UUID is set by EBOOT

        OALMSG(OAL_ARGS&&OAL_INFO, (TEXT("Arguments area is initialized\r\n")));
    }

    OALMSG(OAL_ARGS&&OAL_INFO, (TEXT("-OALArgsInit()\r\n")));

    return;
}

//------------------------------------------------------------------------------
//
//  Function:  OALArgsQuery
//
//  This function is called from other OAL modules to return boot arguments.
//  Boot arguments are typically placed in fixed memory location and they are
//  filled by boot loader. In case that boot arguments can't be located
//  the function should return NULL. The OAL module then must use default
//  values.
//
VOID* OALArgsQuery(UINT32 type)
{
    VOID *pData = NULL;
    BSP_ARGS *pArgs = g_pBSPArgs;
    
    OALMSG(OAL_ARGS&&OAL_FUNC, (L"+OALArgsQuery(%d)\r\n", type));

    // Get pointer to expected boot args location
    pArgs = (BSP_ARGS*)IMAGE_SHARE_ARGS_UA_START;

	// Check if there is expected signature
	if (
		pArgs->header.signature  != OAL_ARGS_SIGNATURE ||
		pArgs->header.oalVersion != OAL_ARGS_VERSION   ||
		pArgs->header.bspVersion != BSP_ARGS_VERSION
	)
	{
		RETAILMSG(1, (L"Goto Clean up.\r\n"));
		goto cleanUp;
	}

	// Depending on required args
	switch (type) {
		case OAL_ARGS_QUERY_UPDATEMODE:
			pData = &pArgs->fUpdateMode;
			break;

		case OAL_ARGS_QUERY_KITL:
			pData = &pArgs->kitl;
			OALMSG(OAL_DEBUG, (TEXT("OAL_ARGS_QUERY_KITL\r\n")));
			break;

		case OAL_ARGS_QUERY_DEVID:
            pData = &pArgs->deviceID;
			break;

		case OAL_ARGS_QUERY_UUID:
			pData = &pArgs->uuid;
            break;
		case OAL_ARGS_QUERY_LOGMASK:
			pData = &pArgs->dwOALLogMask;
			break;

		case OAL_ARGS_QUERY_LOGMASKENABLE:
			pData = &pArgs->bUseOALLOG;
			break;			
			
		case OAL_ARGS_QUERY_DRVMASK:
			pData = &pArgs->dwDrvMsgMask;
			break;

		case OAL_ARGS_QUERY_DRVMASKENABLE:
			pData = &pArgs->bUseDRVMSG;
			break;	
		case OAL_ARGS_QUERY_USER_HIVE_CLEAN:
			pData = &pArgs->bClearUserHiveReg;
			break;

		case OAL_ARGS_QUERY_SYS_HIVE_CLEAN:
			pData = &pArgs->bClearSystemHiveReg;
			break;

		case OAL_ARGS_QUERY_CLEANBOOT:
			pData = &pArgs->bCleanBoot;
			break;
			
		case OAL_ARGS_QUERY_FORMATPART:
			pData = &pArgs->bFormatStorage;
			break;            
        case OAL_ARGS_QUERY_SYSTEMCLOCKS:
            pData = &pArgs->SystemClocks;
            OALMSG(OAL_DEBUG, (TEXT("OAL_ARGS_QUERY_SYSTEMCLOCKS\r\n")));
		    break;
		default:
		    OALMSG(OAL_ERROR,(TEXT("UnKnown OAL_ARGS_QUERY\r\n")));
    	}

cleanUp:
    OALMSG(OAL_ARGS&&OAL_FUNC, (L"-OALArgsQuery(pData = 0x%08x)\r\n", pData));

    return pData;
}

VOID OALArgsChange(void* pData, UINT32 size)
{
	BSP_ARGS *pArgs = g_pBSPArgs;
	
	OALMSG(OAL_ARGS&&OAL_OEM_FUNC, (L"ARGS: +OALArgsChange()\r\n"));

	memcpy((DWORD*)pArgs->dwDrvMsgMask, (UINT32*)pData, size);
}

//------------------------------------------------------------------------------

