#include <windows.h>
#include <image_cfg.h>
#define DRVMSG_LIBRARY
//#define DRVMSG_STATIC_LIBRARY
#include <drvmsg.h>
//#undef DRVMSG_STATIC_LIBRARY
#undef DRVMSG_LIBRARY

#define DRVWAIT_LIBRARY
#include <drvlib_wait.h>
#undef DRVWAIT_LIBRARY

#define DRVLIB_STATIC_LIBRARY
#include <drvlib_mem.h>
#undef DRVMSG_STATIC_LIBRARY

typedef struct _TEST_DATA{
    BYTE a;
    BYTE b;
    BYTE c;
    BYTE d;
    BYTE e;
    BYTE f;
    BYTE g;
    BYTE h;
    DWORD i;
    DWORD j;
}TEST_DATA;

//#define TEST_UNALIGNED

BOOL WINAPI DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
    LPDWORD   dwRet = NULL;
    DWORD   dwUnalignedEnable = TRUE;    // FALSE: can't use unaligned (generate DataA), TRUE: can use unaligned

    UINT8  *pVirAddr;
    UINT32  i;
    UINT32  uSize=0x1000;

    TEST_DATA *pSrc;
    UINT32 *pDest;
    
    switch(dwReason)
    {
        DBGMSG(DRVLIB_INFO, (L"DLIB: =============== Driver Library loading DllMain============\r\n"));
		
    	case DLL_PROCESS_ATTACH:
			DrvMSGInitialize();
            DrvWAITInitialize();
			//DrvGlobInit();
			
			// WinCE6 supports unaligned access on ARM V6.
			// But KernelStart disable unaligned access, it checks unaligned access fault. 
			// So, we need to enable unaligned access through IOCTL.
			
            if(!KernelLibIoControl((HANDLE)KMOD_CORE, IOCTL_KLIB_UNALIGNENABLE, &dwUnalignedEnable, sizeof(dwUnalignedEnable),NULL,NULL,dwRet))
            {
                DBGMSG(1,(L"KernelLibIoControl-IOCTL_KLIB_UNALIGNENABLE Fail\r\n"));
            }

#ifdef TEST_UNALIGNED
            pVirAddr = DrvLib_MapIoSpace(IMAGE_CAMERA_PREVIEWBUFFER_PA_START, uSize, TRUE);
           
            if (pVirAddr == NULL)
            {
        		DBGMSG(1,(L"[Unaligned TEST] Failed to allocate buffer\r\n"));
            }
            DBGMSG(1,(_T("[Unaligned TEST] pVirAddr: 0x%x, 0x%x\r\n"), pVirAddr, *pVirAddr));
#if 0
            pSrc = (UINT8 *)(pVirAddr+2);
            
            if(pSrc->a != 'B')
            {
                DBGMSG(1,(_T("+ 1 \r\n")));
                DBGMSG(1,(_T("[Unaligned TEST] (pSrc) = 0x%x, 0x%x\r\n"),(pSrc), pSrc->a));
            }

            if(pSrc->b != 'C')
            {
                DBGMSG(1,(_T("+ 2 \r\n")));
                DBGMSG(1,(_T("[Unaligned TEST] (pSrc) = 0x%x, 0x%x\r\n"),(pSrc), pSrc->b));
            }

            if(pSrc->i != 0x1234)
            {
                DBGMSG(1,(_T("+ 3 \r\n")));
                DBGMSG(1,(_T("[Unaligned TEST] (pSrc) = 0x%x, 0x%x\r\n"),(pSrc), pSrc->i));
            }
#else
            for(i=0; i<(uSize/4); i++){
                pDest = (UINT8 *)(pVirAddr+i);
                *pDest = i;
            }
#endif     
#endif
		    DBGMSG(DRVLIB_INFO, (ANSI_BLUE L"DLIB: =============== Driver Library loading ============\r\n" ANSI_CLEAR));
	        break;

    	case DLL_PROCESS_DETACH:
			DBGMSG(DRVLIB_INFO, (ANSI_BLUE L"DLIB: =============== Driver Library unloading ==========\r\n" ANSI_CLEAR));
			//DrvMSGDeinitialize();
	        break;
    }

    return TRUE;
}
