cfw.c
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:46k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. /*++
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright (c) 2001. Samsung Electronics, co. ltd  All rights reserved.
  7. --*/
  8. #include "windows.h"
  9. #include "nkintr.h"
  10. #include "oalintr.h"
  11. #include "shx.h"
  12. #include "p2.h"
  13. #include "p2debug.h"
  14. #include "tchaud.h"
  15. #include "drv_glob.h"
  16. #include <memory.h>
  17. #ifdef MODULE_CERTIFY
  18. #include "key1024.c"    // OEMLoadInit/OEMLoadModule implementation and the public key used for module signature verification.
  19. #endif
  20. //#include "timer.h"
  21. #include <S2440.h>
  22. #include <pehdr.h>
  23. #include <romldr.h>
  24. extern const unsigned short ScreenBitmap[];
  25. /*
  26.     @doc    EXTERNAL KERNEL HAL
  27.     @module cfwp2.c - P2 HW Support | 
  28.         OEM support Functions for the Windows CE P2 Platform.
  29.     
  30.     @xref <f OEMInit> <f OEMInterruptEnable> <f OEMInterruptDisable> 
  31.           <f OEMInterruptDone> <l HAL Overview.Windows CE Kernel OEM Interface>
  32.           
  33.     @topic Windows CE Kernel OEM Interface |
  34.           This defines the HAL layer - OEM and platform dependent pieces of
  35.           code which we expect the OEM to deliver to us. There are three pieces
  36.           of OEM deliverable code  - the bootstrap loader & monitor (for 
  37.           debugging), the HAL portions which are interfaces between the kernel
  38.           and the firmware, and the driver interface. This topic covers just 
  39.           the HAL portion.
  40.           The philosophy is to keep the HAL layer as simple as possible.  The 
  41.           HAL should not be confused with the machine or CPU independence. HAL 
  42.           is specific for a particular CPU and platform. It includes interfaces 
  43.           for the following devices:<nl>
  44.           Real Time Clock<nl>
  45.           Interval Timer (used for the scheduler operation) <nl>
  46.           Interrupt handlers and support <nl>
  47.           Note that it does not include abstractions for devices like the DMA 
  48.           controller etc. since the kernel does not use one. Also note that the
  49.           list could change for different CPU's and platforms - for instance, 
  50.           some chips might include a lot of peripheral devices (like the 
  51.           interval timer) on the CPU chip itself, removing the need for a 
  52.           separate interface for them.
  53.           The interfaces for the real time clock and interval timer are still 
  54.           being developed. But they should in general be extremely simple and
  55.           straightforward. For details on the interrupt support model in the 
  56.           kernel look at <l Interrupt Support Overview.Kernel Interrupt Support>
  57.     @xref <l Interrupt Support Overview.Kernel Interrupt Support>
  58.           <f OEMInit> <f OEMInterruptEnable> <f OEMInterruptDisable> 
  59.           <f OEMInterruptDone> <f HookInterrupt>
  60.              
  61.  */
  62. unsigned long OEMClockFreq; // OEM clock frequency is used only in OAL
  63. //
  64. // Kernel global variables used by GetIdleTime( ) to determine CPU utilization
  65. //
  66. extern DWORD idleconv;  // translation constant in 1 ms units
  67. extern DWORD curridlehigh, curridlelow; // 64-bit idle time in ms
  68. extern int P2ISR();
  69. extern void InitClock();
  70. extern void HalCpuInit();
  71. extern void HalTimerInit();
  72. extern void HalSleep(DWORD);
  73. extern void TIMERINIT();
  74. extern void InitDebugEther(void);
  75. static void InitDisplay(void);
  76. static void OEMInitInterrupts(void);
  77. static void InitSDMMC(void);
  78. typedef volatile WORD *PVWORD;    /* pointer to a volatile word */
  79. typedef volatile DWORD *PVDWORD;    /* pointer to a volatile dword */
  80. #define REG(base, id)   (*(PVWORD)((base)+(id)))
  81. #define REG32(base, id)   (*(PVDWORD)((base)+(id)))
  82. #define SDIO_FOR_100BD 0
  83. /*
  84. #if (CE_MAJOR_VER == 0x0003)
  85. //Cedar
  86. // The kernel exports...
  87. #ifdef AddrCurMSec
  88. // Some kernels export a pointer to the CurMSec variable.
  89. static volatile DWORD * pCurMSec  = (volatile DWORD *) AddrCurMSec;
  90. static volatile DWORD * pDiffMSec = (volatile DWORD *) AddrDiffMSec;
  91. #else
  92. extern volatile DWORD CurMSec;
  93. extern volatile DWORD DiffMSec;
  94. static volatile DWORD * pCurMSec = &CurMSec;
  95. static volatile DWORD * pDiffMSec = &DiffMSec;
  96. #endif
  97. extern DWORD dwSleepMin;
  98. extern DWORD dwPartialDiffMSec;
  99. extern DWORD ticksleft;
  100. #else
  101. // dougfir or later
  102. //
  103. #ifdef AddrCurMSec
  104. // Some kernels export a pointer to the CurMSec variable.
  105. static volatile DWORD * pCurMSec  = (volatile DWORD *) AddrCurMSec;
  106. #else
  107. extern volatile DWORD CurMSec;
  108. static volatile DWORD * pCurMSec = &CurMSec;
  109. #endif
  110. extern DWORD dwReschedTime;
  111. #endif
  112. */
  113. // dougfir or later
  114. //
  115. #ifdef AddrCurMSec
  116. // Some kernels export a pointer to the CurMSec variable.
  117. static volatile DWORD * pCurMSec  = (volatile DWORD *) AddrCurMSec;
  118. #else
  119. extern volatile DWORD CurMSec;
  120. static volatile DWORD * pCurMSec = &CurMSec;
  121. #endif
  122. extern DWORD dwReschedTime;
  123. extern BOOL fIntrTime;
  124. extern BOOL bProfileTimerRunning;
  125. volatile ULARGE_INTEGER CurTicks = { 0, 0 };
  126. volatile ULARGE_INTEGER * pCurTicks = &CurTicks;
  127. extern DWORD dwReschedIncrement;
  128. extern DWORD OEMCount1ms;
  129. //extern void Camera_Initialize(void);
  130. #define NOT_FIXEDUP    (DWORD*)-1
  131. DWORD *pdwXIPLoc = NOT_FIXEDUP;
  132. extern  ROMChain_t         *OEMRomChain;
  133. /*
  134.     @func   void | InitRomChain | Collects chain information for all image regions for the kernel.
  135.     @rdesc  N/A.
  136.     @comm    
  137.     @xref   
  138. */
  139. /*
  140. void InitRomChain(void)
  141. {
  142. static ROMChain_t s_pNextRom[MAX_ROM] = {0};
  143. DWORD dwRomCount = 0;
  144.     DWORD       dwChainCount = 0;
  145.     DWORD *pdwCurXIP;
  146.     DWORD       dwNumXIPs;
  147.     PXIPCHAIN_ENTRY pChainEntry = NULL;
  148.     if(pdwXIPLoc == NOT_FIXEDUP)
  149. {
  150.         return;  // no chain or not fixed up properly
  151.     }
  152.     // set the top bit to mark it as a virtual address
  153.     pdwCurXIP = (DWORD*)(((DWORD)pdwXIPLoc) | 0x80000000);
  154.     // first DWORD is number of XIPs
  155.     dwNumXIPs = (*pdwCurXIP);
  156.     if(dwNumXIPs > MAX_ROM)
  157. {
  158.       lpWriteDebugStringFunc(TEXT("ERROR: Number of XIPs exceeds MAXn"));
  159.       return;
  160.     }
  161.     pChainEntry = (PXIPCHAIN_ENTRY)(pdwCurXIP + 1);
  162.     while(dwChainCount < dwNumXIPs)
  163.     {
  164.         if ((pChainEntry->usFlags & ROMXIP_OK_TO_LOAD) &&  // flags indicates valid XIP
  165.             *(LPDWORD)(((DWORD)(pChainEntry->pvAddr)) + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)
  166.         {
  167.             s_pNextRom[dwRomCount].pTOC = *(ROMHDR **)(((DWORD)(pChainEntry->pvAddr)) + ROM_SIGNATURE_OFFSET + 4);
  168.             s_pNextRom[dwRomCount].pNext = NULL;
  169.             if (dwRomCount != 0)
  170.             {
  171.                 s_pNextRom[dwRomCount-1].pNext = &s_pNextRom[dwRomCount];
  172.             }
  173.             else
  174.             {
  175.                 OEMRomChain = s_pNextRom;
  176.             }
  177.             dwRomCount++;
  178.         }
  179.         else
  180.         {
  181.             lpWriteDebugStringFunc( _T("Invalid XIP foundn") );
  182.         }
  183.         ++pChainEntry;
  184. dwChainCount++;
  185. }
  186. }
  187. */
  188. #define FROM_BCD(n) ((((n) >> 4) * 10) + ((n) & 0xf))
  189. //------------------------------------------------------------------------------
  190. //
  191. //  @func   void | OEMInit | Initialize Hardware Interfaces
  192. //  @rdesc  none
  193. //  @comm   OEMInit is called by the kernel after it has performed minimal
  194. //          initialization. Interrupts are disabled and the kernel is not
  195. //          ready to handle exceptions. The only kernel service available
  196. //          to this function is <f HookInterrupt>. This should be used to 
  197. //          install ISR's for all the hardware interrupts to be handled by
  198. //          the firmware. Note that ISR's must be installed for any interrupt
  199. //          that is to be routed to a device driver - otherwise the 
  200. //          <f InterruptInitialize> call from the driver will fail.
  201. //  @xref   <l Overview.Windows CE Kernel OEM Interface> <f HookInterrupt>
  202. //          <f InterruptInitialize>
  203. //            
  204. //------------------------------------------------------------------------------
  205. void OEMInit()  
  206. {
  207. volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
  208. // Instead of calling OEMWriteDebugString directly, call through exported
  209. // function pointer.  This will allow these messages to be seen if debug
  210. // message output is redirected to Ethernet or the parallel port.  Otherwise,
  211. // lpWriteDebugStringFunc == OEMWriteDebugString.
  212. lpWriteDebugStringFunc(TEXT("nWindows CE Firmware Initrn"));
  213. #ifdef MODULE_CERTIFY
  214. //
  215. // Set the module signature verification hooks
  216. //
  217. pOEMLoadInit   = OEMLoadInit;
  218. pOEMLoadModule = OEMLoadModule;
  219. //
  220. // Init the signature verification public key
  221. //
  222. InitPubKey(g_bSignPublicKeyBlob,sizeof(g_bSignPublicKeyBlob));
  223. #endif
  224.     //
  225.     // Set up translation constant for GetIdleTime() (1 ms units).
  226.     // Note: Since curridlehigh, curridlelow is counting in ms, and GetIdleTime()
  227.     // reports in ms, the conversion ratio is one.  If curridlehigh, curridlelow
  228.     // were using other units (like ticks), then the conversion would be calculated
  229.     // from the clock frequency.
  230.     //
  231.     idleconv = 1;
  232. // Initialize interrupts.
  233. //
  234.     lpWriteDebugStringFunc(TEXT("INFO: Initializing system interrupts...rn"));
  235. OEMInitInterrupts();
  236. // Initialize the system clock(s).
  237. //
  238.     lpWriteDebugStringFunc(TEXT("INFO: Initializing system clock(s)...rn"));
  239.     InitClock();
  240.     // Initialize driver globals area.
  241. //
  242.     lpWriteDebugStringFunc(TEXT("INFO: Initializing driver globals area...rn"));
  243.     memset((PVOID)DRIVER_GLOBALS_ZEROINIT_START, 0, DRIVER_GLOBALS_ZEROINIT_SIZE);
  244.     
  245.     // Initialize S2440X01 LCD controller
  246. InitDisplay();
  247.     // Initialize debug Ethernet (KITL) connection.
  248.     //
  249. // InitDebugEther();
  250.  
  251. // Initialize GPIO /// ;;; SHL
  252. s2440IOP->rPAD9 = (1<<12) | (0<<11);
  253. //s2440IOP->rGPJCON = 0x016aaaa;
  254. //s2440IOP->rGPJUP  = ~((0<<12) | (1<<11));
  255. s2440IOP->rGPHCON = (s2440IOP->rGPHCON & ~(0xf<<18)) | (1<<20) | (1<<18); // CLKOUT1, CLKOUT0
  256. s2440IOP->rDSC0 = 0x3ff;
  257. s2440IOP->rDSC1 = 0x3fffffff;
  258. // camera
  259. //Camera_Initialize();
  260. //s2440IOP->rGPJCON = 0x2aaaaaa;
  261. //s2440IOP->rGPJUP  = 0x1fff;
  262. InitSDMMC();
  263. // Initialize the ROM chain (multi-region).
  264. //
  265. // InitRomChain();
  266. lpWriteDebugStringFunc(TEXT("OEMInit Done...rn"));
  267. }
  268. //------------------------------------------------------------------------------
  269. //  
  270. //  @func   BOOL | OEMInterruptEnable | Enable a hardware interrupt
  271. //  @rdesc  Returns TRUE if valid interrupt ID or FALSE if invalid ID.
  272. //  @comm   This function is called by the Kernel when a device driver
  273. //          calls <f InterruptInitialize>. The system is not preemptible when this
  274. //          function is called.
  275. //  @xref   <l Overview.Windows CE Kernel OEM Interface> <f InterruptInitialize>
  276. //  
  277. //------------------------------------------------------------------------------
  278. BOOL 
  279. OEMInterruptEnable(DWORD  idInt, // @parm Interrupt ID to be enabled. See <l Interrupt ID's.Interrupt ID's>  for a list of possble values.
  280.    LPVOID pvData, // @parm ptr to data passed in in the <f InterruptInitialize> call
  281.            DWORD  cbData) // @parm Size of data pointed to be <p pvData>
  282. {
  283. volatile INTreg *s2440INT = (INTreg *)INT_BASE;
  284. volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
  285. volatile MMCreg *s2440SDIO = (MMCreg *)MMC_BACE;
  286. BOOL bRet = TRUE;
  287. INTERRUPTS_OFF();
  288. switch (idInt) 
  289. {
  290. case SYSINTR_VMINI: // Vmini.
  291. //return (TRUE);
  292. break;
  293. case SYSINTR_BREAK: // There is no halt button on P2.
  294. //return(FALSE);
  295.         break;
  296.     case SYSINTR_DMA0:
  297.         s2440INT->rINTMSK &= ~BIT_DMA0; // SDIO DMA interrupt
  298. //RETAILMSG(1,(TEXT("::: SYSINTR_DMA0    OEMInterruptDisablern")));
  299.         break;
  300. case SYSINTR_SDMMC:
  301. s2440INT->rINTMSK &= ~BIT_MMC;
  302. //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC    OEMInterruptDisablern")));
  303. break;        
  304. case SYSINTR_SDMMC_SDIO_INTERRUPT:
  305. s2440INT->rINTMSK &= ~BIT_MMC;
  306. //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_SDIO_INTERRUPT    OEMInterruptEnablern")));
  307. break;
  308. case SYSINTR_SDMMC_CARD_DETECT:
  309. #if SDIO_FOR_100BD // for b'd revision 1.00
  310. s2440IOP->rEINTPEND  = (1 << 18);
  311. s2440IOP->rEINTMASK &= ~(1 << 18);
  312. //s2440INT->rSRCPND = BIT_EINT8_23;
  313. // if (s2440INT->rINTPND & BIT_EINT8_23) 
  314. // s2440INT->rINTMSK  &= ~BIT_EINT8_23;
  315. //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_CARD_DETECT    OEMInterruptEnablern")));
  316. #else // for b'd revision 0.17
  317. s2440IOP->rEINTPEND  = (1 << 16);
  318. s2440IOP->rEINTMASK &= ~(1 << 16);  
  319. #endif
  320. s2440INT->rSRCPND = BIT_EINT8_23;
  321. s2440INT->rINTPND = BIT_EINT8_23;
  322. s2440INT->rINTMSK &= ~BIT_EINT8_23;
  323. break;     
  324.     case SYSINTR_TOUCH:
  325. //RETAILMSG(0,(TEXT("OEMInterruptEnable:TOUCHnrn")));
  326.         break;
  327.     case SYSINTR_TOUCH_CHANGED:
  328. //RETAILMSG(0,(TEXT("OEMInterruptEnable:TOUCH CHANGEDrnrn")));
  329. s2440INT->rINTMSK &= ~BIT_ADC;
  330. s2440INT->rINTSUBMSK &= ~INTSUB_TC;
  331.         break;
  332. case SYSINTR_KEYBOARD: // Keyboard on EINT1.
  333. /*
  334. s2440INT->rSRCPND  = BIT_EINT1;
  335. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  336. if (s2440INT->rINTPND & BIT_EINT1) s2440INT->rINTPND = BIT_EINT1;
  337. */
  338. s2440INT->rINTMSK &= ~BIT_EINT1;
  339. break;
  340. case SYSINTR_SERIAL: // Serial port.
  341. s2440INT->rSUBSRCPND  = (INTSUB_RXD0 | INTSUB_TXD0 | INTSUB_ERR0);
  342. s2440INT->rINTSUBMSK &= ~INTSUB_RXD0;
  343. s2440INT->rINTSUBMSK &= ~INTSUB_TXD0;
  344. s2440INT->rINTSUBMSK &= ~INTSUB_ERR0;
  345. s2440INT->rSRCPND     = BIT_UART0;
  346. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  347. if (s2440INT->rINTPND & BIT_UART0) s2440INT->rINTPND = BIT_UART0;
  348. s2440INT->rINTMSK    &= ~BIT_UART0;
  349. break;
  350. case SYSINTR_IR: // IrDA.
  351. s2440INT->rSUBSRCPND  = (INTSUB_RXD2 | INTSUB_TXD2 | INTSUB_ERR2);
  352. s2440INT->rINTSUBMSK &= ~INTSUB_RXD2;
  353. s2440INT->rINTSUBMSK &= ~INTSUB_TXD2;
  354. s2440INT->rINTSUBMSK &= ~INTSUB_ERR2;
  355. s2440INT->rSRCPND     = BIT_UART2;
  356. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  357. if (s2440INT->rINTPND & BIT_UART2) s2440INT->rINTPND = BIT_UART2;
  358. s2440INT->rINTMSK    &= ~BIT_UART2;
  359. break;
  360. // update audio old ;;; SHL
  361. // case SYSINTR_AUDIO: // Audio controller (the controller uses both DMA1 and DMA2 interrupts).
  362. // // DMA1 (input).
  363. // //
  364. // s2440INT->rSRCPND  = BIT_DMA1;
  365. // // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  366. // if (s2440INT->rINTPND & BIT_DMA1) s2440INT->rINTPND = BIT_DMA1;
  367. // s2440INT->rINTMSK &= ~BIT_DMA1;
  368. // // DMA2 (output).
  369. // //
  370. // s2440INT->rSRCPND  = BIT_DMA2;
  371. // // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  372. // if (s2440INT->rINTPND & BIT_DMA2) s2440INT->rINTPND = BIT_DMA2;
  373. // s2440INT->rINTMSK &= ~BIT_DMA2;
  374. // break;
  375. // update audio bug.
  376. case SYSINTR_AUDIO: // Audio controller (the controller uses both DMA1 and DMA2 interrupts).
  377. // DMA1 (input).
  378. //
  379. s2440INT->rINTMSK &= ~BIT_DMA1;
  380. // DMA2 (output).
  381. s2440INT->rINTMSK &= ~BIT_DMA2;
  382. break;
  383. case SYSINTR_ADC:
  384. //return(FALSE);
  385. break;
  386. case SYSINTR_PCMCIA_LEVEL: // PCMCIA data on EINT8.
  387. s2440INT->rINTMSK  &= ~BIT_EINT8_23;
  388. //s2440INT->rSRCPND  = BIT_EINT8_23;
  389. //s2440INT->rINTPND  = BIT_EINT8_23;
  390. s2440IOP->rEINTMASK &= ~0x100;
  391. //s2440IOP->rEINTPEND  = 0x100;
  392. //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_LEVEL    OEMInterruptEnablern")));
  393. break;
  394. case SYSINTR_PCMCIA_EDGE:
  395. //return(FALSE);
  396. break;
  397. case SYSINTR_PCMCIA_STATE: // PCMCIA insertion interrupt.
  398. s2440INT->rSRCPND  = BIT_EINT3;  // to clear the previous pending states
  399. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  400. if (s2440INT->rINTPND & BIT_EINT3) s2440INT->rINTPND = BIT_EINT3;
  401. s2440INT->rINTMSK &= ~BIT_EINT3;
  402. //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_STATE    OEMInterruptEnablern")));
  403. break;
  404. case SYSINTR_TIMING:
  405. //return(FALSE);
  406. break;
  407.     case SYSINTR_ETHER: // Ethernet on EINT9.
  408. s2440IOP->rEINTPEND   = 0x200;
  409. s2440IOP->rEINTMASK  &= ~0x200;
  410. //s2440INT->rSRCPND     = BIT_EINT8_23; // by shim
  411. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  412. if (s2440INT->rINTPND & BIT_EINT8_23) s2440INT->rINTPND = BIT_EINT8_23;
  413. s2440INT->rINTMSK    &= ~BIT_EINT8_23;
  414. //RETAILMSG(1,(TEXT("::: SYSINTR_ETHER    OEMInterruptEnablern")));
  415.         break;
  416. #if 0
  417. case SYSINTR_USB:
  418.     // USB host interrupt enable bit. by hjcho
  419.     s2440INT->rINTMSK &= ~BIT_USBH;
  420.     break;
  421. case SYSINTR_USBD:
  422.     s2440INT->rINTMSK &= ~BIT_USBD;
  423. //RETAILMSG(1,(TEXT("::: SYSINTR_USBD     OEMInterruptEnablern")));
  424.     break;
  425. #else
  426. case SYSINTR_USB: // USB host.
  427. s2440INT->rSRCPND  = BIT_USBH;
  428. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  429. if (s2440INT->rINTPND & BIT_USBH) s2440INT->rINTPND = BIT_USBH;
  430. s2440INT->rINTMSK &= ~BIT_USBH;
  431. break;
  432. case SYSINTR_USBD:
  433. s2440INT->rSRCPND  = BIT_USBD;
  434. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  435. if (s2440INT->rINTPND & BIT_USBD) s2440INT->rINTPND = BIT_USBD;
  436. s2440INT->rINTMSK &= ~BIT_USBD;
  437. RETAILMSG(1, (TEXT("USB enable interrutprn")));
  438. break;
  439. #endif
  440. case SYSINTR_POWER:
  441. s2440INT->rSRCPND  = BIT_EINT0;
  442. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  443. if (s2440INT->rINTPND & BIT_EINT0) s2440INT->rINTPND = BIT_EINT0;
  444. s2440INT->rINTMSK &= ~BIT_EINT0;
  445. s2440INT->rSRCPND  = BIT_EINT2;
  446. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  447. if (s2440INT->rINTPND & BIT_EINT2) s2440INT->rINTPND = BIT_EINT2;
  448. s2440INT->rINTMSK &= ~BIT_EINT2;
  449. break;     
  450. case SYSINTR_CAM:
  451. s2440INT->rINTSUBMSK &= ~(BIT_SUB_CAM_P | BIT_SUB_CAM_C);
  452. s2440INT->rINTMSK &= ~BIT_CAM;
  453. break;
  454.     case SYSINTR_IIC:
  455.         s2440INT->rINTMSK &= ~BIT_IIC;
  456.        break;
  457. default:
  458. bRet = FALSE; /* unsupported interrupt value */
  459. //return(FALSE);
  460.         break;
  461. }
  462.     
  463. INTERRUPTS_ON();
  464.     
  465.     return bRet;
  466.     
  467. //return(TRUE);
  468. }
  469. //------------------------------------------------------------------------------
  470. //  
  471. //  @func   BOOL | OEMInterruptDisable | Disable a hardware interrupt
  472. //  @rdesc  none
  473. //  @comm   OEMInterruptDisable is called by the Kernel when a device driver
  474. //          calls <f InterruptDisable>. The system is not preemtible when this
  475. //          function is called.
  476. //  @xref   <l Overview.Windows CE Kernel OEM Interface> <f InterruptDisable>
  477. //  
  478. //------------------------------------------------------------------------------
  479. void 
  480. OEMInterruptDisable(DWORD idInt) // @parm Interrupt ID to be disabled. See <t Interrupt ID's>
  481. // for the list of possible values.
  482. {
  483. volatile INTreg *s2440INT = (INTreg *)INT_BASE;
  484. volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
  485. volatile MMCreg *s2440SDIO = (MMCreg *)MMC_BACE;
  486.     INTERRUPTS_OFF();
  487. switch (idInt) 
  488. {
  489. case SYSINTR_BREAK: // There is no halt button on P2.
  490. break;
  491.     case SYSINTR_DMA0:
  492.         s2440INT->rINTMSK |= BIT_DMA0; // SDIO DMA interrupt
  493. //RETAILMSG(1,(TEXT("::: SYSINTR_DMA0    OEMInterruptDisablern")));
  494. break;
  495. case SYSINTR_SDMMC:
  496. s2440INT->rINTMSK |= BIT_MMC;
  497. //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC    OEMInterruptDisablern")));
  498. break;
  499. case SYSINTR_SDMMC_SDIO_INTERRUPT:
  500. s2440INT->rINTMSK |= BIT_MMC;
  501. s2440SDIO->rSDIINTMSK &= ~(0x1<<12); // interrupt from SDIO card
  502. //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_SDIO_INTERRUPT    OEMInterruptDisablern")));
  503. break;
  504. case SYSINTR_SDMMC_CARD_DETECT:
  505. #if SDIO_FOR_100BD // for b'd revision 1.00
  506. s2440IOP->rEINTMASK |= (1 << 18);
  507. #else // for b'd revision 0.17
  508. s2440IOP->rEINTMASK |= (1 << 16);
  509. #endif
  510. s2440INT->rINTMSK    |= BIT_EINT8_23;
  511. //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_CARD_DETECT    OEMInterruptDisablern")));
  512. break;        
  513. case SYSINTR_TOUCH:
  514.     break;
  515. case SYSINTR_TOUCH_CHANGED:
  516. s2440INT->rINTMSK |= BIT_ADC;
  517. s2440INT->rINTSUBMSK |= INTSUB_TC;
  518.     break;
  519. case SYSINTR_KEYBOARD:
  520. s2440INT->rINTMSK |= BIT_EINT1;
  521. break;
  522. case SYSINTR_SERIAL:
  523. s2440INT->rINTMSK    |= BIT_UART0;
  524. s2440INT->rINTSUBMSK |= INTSUB_RXD0;
  525. s2440INT->rINTSUBMSK |= INTSUB_TXD0;
  526. s2440INT->rINTSUBMSK |= INTSUB_ERR0;
  527. break;
  528. case SYSINTR_IR:
  529. s2440INT->rINTMSK    |= BIT_UART2;
  530. s2440INT->rINTSUBMSK |= INTSUB_RXD2;
  531. s2440INT->rINTSUBMSK |= INTSUB_TXD2;
  532. s2440INT->rINTSUBMSK |= INTSUB_ERR2;
  533. break;
  534. case SYSINTR_AUDIO:
  535.         s2440INT->rINTMSK |= BIT_DMA1; // Audio input DMA.
  536. s2440INT->rINTMSK |= BIT_DMA2; // Audio output DMA.
  537. break;
  538. case SYSINTR_ADC:
  539. break;
  540.     case SYSINTR_PCMCIA_LEVEL:
  541. s2440IOP->rEINTMASK |= 0x100;
  542. s2440INT->rINTMSK   |= BIT_EINT8_23;
  543. //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_LEVEL    OEMInterruptDisablern")));
  544.         break;
  545. case SYSINTR_PCMCIA_EDGE:
  546. break;
  547. case SYSINTR_PCMCIA_STATE:
  548. s2440INT->rINTMSK |= BIT_EINT3;
  549. //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_STATE    OEMInterruptDisablern")));
  550. break;
  551.     case SYSINTR_ETHER:
  552. s2440INT->rINTMSK   |= BIT_EINT8_23;
  553. s2440IOP->rEINTMASK |= 0x200;
  554. //RETAILMSG(1,(TEXT("::: SYSINTR_ETHER    OEMInterruptDisablern")));
  555.         break;        
  556. case SYSINTR_USB:
  557. s2440INT->rINTMSK |= BIT_USBH;
  558. break;
  559.         
  560. case SYSINTR_USBD:
  561. s2440INT->rINTMSK |= BIT_USBD;
  562. //RETAILMSG(1,(TEXT("::: SYSINTR_USBD    OEMInterruptDisablern")));
  563. break;
  564.         
  565. case SYSINTR_POWER:
  566. s2440INT->rINTMSK |= BIT_EINT0;
  567. s2440INT->rINTMSK |= BIT_EINT2;
  568. break;        
  569. case SYSINTR_CAM:
  570. s2440INT->rINTMSK |= BIT_CAM;
  571. s2440INT->rINTSUBMSK |= (INTSUB_CAM_P | INTSUB_CAM_C);
  572. break;
  573.     case SYSINTR_IIC:
  574.         s2440INT->rINTMSK |= BIT_IIC;
  575.        break;
  576. default:
  577. break;
  578. }
  579. INTERRUPTS_ON();
  580. }
  581. //------------------------------------------------------------------------------
  582. //  
  583. //  @func   BOOL | OEMInterruptDone | Signal completion of interrupt processing
  584. //  @rdesc  none
  585. //  @comm   OEMInterruptDone is called by the Kernel when a device driver
  586. //          calls <f InterruptDone>. The system is not preemtible when this
  587. //          function is called.
  588. //  @xref   <l Overview.Kernel Interrupt Support> <f InterruptDone>
  589. //  
  590. //------------------------------------------------------------------------------
  591. void 
  592. OEMInterruptDone(DWORD idInt) // @parm Interrupt ID. See <t Interrupt ID's>
  593.                      // for the list of possible values.
  594. {
  595. volatile INTreg *s2440INT = (INTreg *)INT_BASE;
  596. volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;    
  597. INTERRUPTS_OFF();
  598. switch (idInt) 
  599. {
  600.     case SYSINTR_DMA0:
  601.         s2440INT->rINTMSK &= ~BIT_DMA0; // SDIO DMA interrupt
  602. //RETAILMSG(1,(TEXT("::: SYSINTR_DMA0    OEMInterruptDonern")));
  603. break;
  604. case SYSINTR_SDMMC:
  605. s2440INT->rINTMSK &= ~BIT_MMC;
  606. //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC    OEMInterruptDonern")));
  607. break;
  608. case SYSINTR_SDMMC_SDIO_INTERRUPT:
  609. s2440INT->rINTMSK &= ~BIT_MMC;
  610. //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_SDIO_INTERRUPT    OEMInterruptDonern")));
  611. break;
  612. case SYSINTR_SDMMC_CARD_DETECT:
  613. #if SDIO_FOR_100BD // for b'd revision 1.00
  614. s2440IOP->rEINTPEND  = (1<<18);
  615. s2440IOP->rEINTMASK &= ~(1 << 18);
  616. //RETAILMSG(1,(TEXT("::: SYSINTR_SDMMC_CARD_DETECT    OEMInterruptDonern")));
  617. #else // for b'd revision 0.17
  618. s2440IOP->rEINTPEND  = (1<<16);
  619. s2440IOP->rEINTMASK &= ~(1 << 16);
  620. #endif
  621. s2440INT->rINTMSK   &= ~BIT_EINT8_23;
  622. break;        
  623.     case SYSINTR_TOUCH:
  624.         /*
  625.          * Nothing has to be done here as interrupts are masked and unmasked by the touch
  626.          * handler in the HAL.
  627.          */
  628. s2440INT->rINTMSK &= ~BIT_TIMER1;
  629.         break;
  630.     case SYSINTR_TOUCH_CHANGED:
  631.         /*
  632.          * Nothing has to be done here as interrupts are masked and unmasked by the touch
  633.          * handler in the HAL.
  634.          */
  635. s2440INT->rINTMSK &= ~BIT_ADC;
  636. s2440INT->rINTSUBMSK &= ~INTSUB_TC;
  637. //RETAILMSG(0,(TEXT("OEMInterruptDone:TOUCH CHANGEDnrn")));
  638.         break;
  639. case SYSINTR_KEYBOARD:
  640. s2440INT->rINTMSK &= ~BIT_EINT1;
  641. break;
  642. case SYSINTR_SERIAL:
  643. s2440INT->rINTMSK    &= ~BIT_UART0;
  644. s2440INT->rINTSUBMSK &= ~INTSUB_RXD0;
  645. break;
  646. case SYSINTR_IR:
  647. s2440INT->rINTMSK    &= ~BIT_UART2;
  648. s2440INT->rINTSUBMSK &= ~INTSUB_RXD2;
  649. break;
  650. case SYSINTR_AUDIO:
  651. // DMA1 is for audio input.
  652. // DMA2 is for audio output.
  653. s2440INT->rSRCPND = (BIT_DMA1 | BIT_DMA2); 
  654. if (s2440INT->rINTPND & BIT_DMA1) s2440INT->rINTPND = BIT_DMA1;
  655. if (s2440INT->rINTPND & BIT_DMA2) s2440INT->rINTPND = BIT_DMA2;
  656.         s2440INT->rINTMSK &= ~BIT_DMA1;
  657.         s2440INT->rINTMSK &= ~BIT_DMA2;
  658. break;
  659. case SYSINTR_ADC:
  660. break;
  661. case SYSINTR_PCMCIA_LEVEL:
  662. s2440INT->rSRCPND = BIT_EINT8_23;
  663. if (s2440INT->rINTPND & BIT_EINT8_23) s2440INT->rINTPND = BIT_EINT8_23; 
  664. s2440INT->rINTMSK   &= ~BIT_EINT8_23;
  665. s2440IOP->rEINTMASK &= ~(1<<8);
  666. //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_LEVEL    OEMInterruptDonern")));
  667. break;
  668. case SYSINTR_PCMCIA_EDGE:
  669. //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_EDGE    OEMInterruptDonern")));
  670. break;
  671. case SYSINTR_PCMCIA_STATE:
  672. s2440INT->rINTMSK &= ~BIT_EINT3;
  673. //RETAILMSG(1,(TEXT("::: SYSINTR_PCMCIA_STATE    OEMInterruptDonern")));
  674. break;
  675. case SYSINTR_ETHER:
  676. s2440INT->rINTMSK   &= ~BIT_EINT8_23;
  677. s2440IOP->rEINTMASK &= ~0x200;
  678. //RETAILMSG(1, (TEXT("::: SYSINTR_USBD OEMInterruptDonern")));
  679. break;
  680.         
  681. case SYSINTR_USB:
  682. s2440INT->rINTMSK &= ~BIT_USBH;
  683. break;
  684. case SYSINTR_USBD:
  685. s2440INT->rINTMSK &= ~BIT_USBD;
  686. //RETAILMSG(1,(TEXT("::: SYSINTR_USBD    OEMInterruptDonern")));
  687. break;
  688.         
  689. case SYSINTR_POWER:
  690. s2440INT->rSRCPND = BIT_EINT0;
  691. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  692. if (s2440INT->rINTPND & BIT_EINT0) s2440INT->rINTPND = BIT_EINT0;
  693. s2440INT->rINTMSK &= ~BIT_EINT0;
  694. s2440INT->rSRCPND = BIT_EINT2;
  695. // S3C2440X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register.
  696. if (s2440INT->rINTPND & BIT_EINT2) s2440INT->rINTPND = BIT_EINT2;
  697. s2440INT->rINTMSK &= ~BIT_EINT2;
  698. break;
  699. case SYSINTR_CAM:
  700. s2440INT->rSUBSRCPND = INTSUB_CAM_P;
  701. s2440INT->rSUBSRCPND = INTSUB_CAM_C;
  702. s2440INT->rSRCPND = BIT_CAM;
  703. if (s2440INT->rINTPND & BIT_CAM)
  704. {
  705. s2440INT->rINTPND = BIT_CAM;
  706. }
  707. s2440INT->rINTSUBMSK &= ~(INTSUB_CAM_P | INTSUB_CAM_C);
  708. s2440INT->rINTMSK &= ~BIT_CAM;
  709. break;
  710.     case SYSINTR_IIC:
  711.         s2440INT->rINTMSK &= ~BIT_IIC;
  712.        break;
  713. }
  714.     INTERRUPTS_ON();
  715. }
  716. //------------------------------------------------------------------------------
  717. //------------------------------------------------------------------------------
  718. BOOL 
  719. OEMGetExtensionDRAM(
  720.     LPDWORD lpMemStart, 
  721.     LPDWORD lpMemLen
  722.     ) 
  723. {
  724.     return FALSE; // no extension DRAM
  725. }
  726. //------------------------------------------------------------------------------
  727. //
  728. //  OEMQueryPerformanceCounter
  729. //  
  730. //      The OEMQueryPerformanceCounter function retrieves the current value of 
  731. //      the high-resolution performance counter, if one exists. 
  732. //  
  733. //  BOOL QueryPerformanceCounter(
  734. //  
  735. //      LARGE_INTEGER  *lpliPerformanceCount    // address of current counter value
  736. //     );   
  737. //  
  738. //  Parameters
  739. //  
  740. //  lpliPerformanceCount
  741. //  
  742. //      Points to a variable that the function sets, in counts, to the current 
  743. //      performance-counter value. If the installed hardware does not support 
  744. //      a high-resolution performance counter, this parameter can be to zero. 
  745. //  
  746. //  Return Value
  747. //  
  748. //      If the installed hardware supports a high-resolution performance 
  749. //      counter, the return value is TRUE.
  750. //      If the installed hardware does not support a high-resolution 
  751. //      performance counter, the return value is FALSE.   
  752. //  
  753. //  If this function is implemented by the OEM, the pointer pQueryPerformanceCounter
  754. //  should be initialized as follows:
  755. //  
  756. //  BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount)=OEMQueryPerformanceCounter;
  757. //
  758. //------------------------------------------------------------------------------
  759. BOOL 
  760. OEMQueryPerformanceCounter(
  761.     LARGE_INTEGER *lpliPerformanceCount
  762.     )
  763. {
  764.     extern DWORD PerfCountSinceTick();
  765.     
  766.     ULARGE_INTEGER liBase;
  767.     DWORD dwCurCount;
  768. // Make sure CurTicks is the same before and after read of counter to account for
  769. // possible rollover
  770.     do {
  771.         liBase = CurTicks;
  772.         dwCurCount = PerfCountSinceTick();
  773.     } while  (liBase.LowPart != CurTicks.LowPart) ;  
  774.     lpliPerformanceCount->QuadPart = liBase.QuadPart + dwCurCount;
  775.     
  776.     return TRUE;
  777. }
  778. //------------------------------------------------------------------------------
  779. //
  780. //  OEMQueryPerformanceFrequency
  781. //  
  782. //      The OEMQueryPerformanceFrequency function retrieves the frequency of 
  783. //      the high-resolution performance counter, if one exists. 
  784. //  
  785. //  BOOL OEMQueryPerformanceFrequency(
  786. //  
  787. //      LARGE_INTEGER  *lpliPerformanceFreq     // address of current frequency
  788. //     );   
  789. //  
  790. //  Parameters
  791. //  
  792. //  lpliPerformanceFreq
  793. //  
  794. //      Points to a variable that the function sets, in counts per second, to 
  795. //      the current performance-counter frequency. If the installed hardware 
  796. //      does not support a high-resolution performance counter, this parameter
  797. //      can be to zero. 
  798. //  
  799. //  Return Value
  800. //  
  801. //      If the installed hardware supports a high-resolution performance 
  802. //      counter, the return value is TRUE.
  803. //      If the installed hardware does not support a high-resolution 
  804. //      performance counter, the return value is FALSE.
  805. //  
  806. //  If this function is implemented by the OEM, the pointer pQueryPerformanceFrequency
  807. //  should be initialized as follows:
  808. //  
  809. //  BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpPerformanceFrequency)=OEMQueryPerformanceFrequency;
  810. //
  811. //------------------------------------------------------------------------------
  812. BOOL 
  813. OEMQueryPerformanceFrequency(
  814.     LARGE_INTEGER *lpliPerformanceFreq
  815.     ) 
  816. {
  817.     extern DWORD PerfCountFreq();
  818.     
  819.     lpliPerformanceFreq->HighPart = 0;
  820.     lpliPerformanceFreq->LowPart  = PerfCountFreq();
  821.     return TRUE;
  822. }
  823. // set pointers to OEM functions
  824. BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount)=OEMQueryPerformanceCounter;
  825. BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpliPerformanceFreq)=OEMQueryPerformanceFrequency;
  826. //
  827. // CPU-specific functions for OEMIdle
  828. //
  829. extern void  CPUEnterIdle(DWORD dwIdleParam);
  830. extern DWORD CPUGetSysTimerCountMax(DWORD dwIdleMSecRequested);
  831. extern void  CPUSetSysTimerCount(DWORD dwIdleMSec);
  832. extern BOOL CPUClearSysTimerIRQ(void);
  833. //
  834. // dougfir or later
  835. //
  836. extern DWORD
  837. CPUGetSysTimerCountElapsed(
  838.     DWORD dwTimerCountdownMSec,
  839.     volatile DWORD *pCurMSec,
  840.     DWORD *pPartialCurMSec,
  841.     volatile ULARGE_INTEGER *pCurTicks
  842.     );
  843. //------------------------------------------------------------------------------
  844. //
  845. //  This routine is called by the kernel when there are no threads ready to
  846. //  run. The CPU should be put into a reduced power mode and halted. It is 
  847. //  important to be able to resume execution quickly upon receiving an interrupt.
  848. //  Note: It is assumed that interrupts are off when OEMIdle is called.  Interrrupts
  849. //  are turned off when OEMIdle returns.
  850. //
  851. //------------------------------------------------------------------------------
  852. static DWORD dwPartialCurMSec = 0; // Keep CPU-specific sub-millisecond leftover.
  853. void
  854. OEMIdle( DWORD dwIdleParam )
  855. {
  856. DWORD dwIdleMSec;
  857. DWORD dwPrevMSec = *pCurMSec;
  858. // Use for 64-bit math
  859. ULARGE_INTEGER currIdle = { curridlelow, curridlehigh };
  860. if ((int) (dwIdleMSec = dwReschedTime - dwPrevMSec) <= 0) 
  861. {
  862. return; // already time to wakeup
  863. }
  864. // just idle till tick if profiling or running iltiming
  865. if (bProfileTimerRunning || fIntrTime) // fIntrTime : Interrupt Latency timeing.
  866. {
  867. // idle till end of 'tick'
  868. CPUEnterIdle(dwIdleParam);
  869. // Update global idle time and return
  870. currIdle.QuadPart += RESCHED_PERIOD;
  871. curridlelow = currIdle.LowPart;
  872. curridlehigh = currIdle.HighPart;
  873.         
  874. return;
  875. }
  876. //
  877. // Since OEMIdle( ) is being called in the middle of a normal reschedule
  878. // period, CurMSec, dwPartialCurMSec, and CurTicks need to be updated accordingly.
  879. // Once we reach this point, we must re-program the timer (if we ever did) 
  880. // because dwPartialCurMSec will be modified in the next function call.
  881. //
  882. CPUGetSysTimerCountElapsed(RESCHED_PERIOD, pCurMSec, &dwPartialCurMSec, pCurTicks);
  883. if ((int) (dwIdleMSec -= *pCurMSec - dwPrevMSec) > 0)
  884. {
  885. dwPrevMSec = *pCurMSec;
  886. //
  887. // The system timer may not be capable of arbitrary timeouts. Get the
  888. // CPU-specific highest possible timeout available.
  889. //
  890. dwIdleMSec = CPUGetSysTimerCountMax(dwIdleMSec);
  891. //
  892. // Set the timer to wake up much later than usual, if needed.
  893. //
  894. CPUSetSysTimerCount(dwIdleMSec);
  895. CPUClearSysTimerIRQ( );
  896. //
  897. // Enable wakeup on any interrupt, then go to sleep.
  898. //
  899. // DEBUGMSG(1, (TEXT("OEMIDle  rn")));
  900. CPUEnterIdle(dwIdleParam);
  901. INTERRUPTS_OFF( );
  902.         
  903. //
  904. // We're awake! The wake-up ISR (or any other ISR) has already run.
  905. //
  906. if (dwPrevMSec != *pCurMSec)
  907. {
  908. //
  909. // We completed the full period we asked to sleep.  Update the counters.
  910. //
  911. *pCurMSec  += (dwIdleMSec - RESCHED_PERIOD); // Subtract resched period, because ISR also incremented.
  912. CurTicks.QuadPart += (dwIdleMSec - RESCHED_PERIOD) * dwReschedIncrement;
  913. currIdle.QuadPart += dwIdleMSec;
  914. } else {
  915. //
  916. // Some other interrupt woke us up before the full idle period was
  917. // complete.  Determine how much time has elapsed.
  918. //
  919. currIdle.QuadPart += CPUGetSysTimerCountElapsed(dwIdleMSec, pCurMSec, &dwPartialCurMSec, pCurTicks);
  920. }
  921. }
  922. // Re-arm counters
  923. CPUSetSysTimerCount(RESCHED_PERIOD);
  924. CPUClearSysTimerIRQ( );
  925. // Update global idle time
  926. curridlelow = currIdle.LowPart;
  927. curridlehigh = currIdle.HighPart;
  928. return;
  929. }
  930. //------------------------------------------------------------------------------
  931. //
  932. //  DWORD GetTickCount(VOID)    Return count of time since boot in milliseconds
  933. //
  934. //------------------------------------------------------------------------------
  935. DWORD 
  936. SC_GetTickCount(void) 
  937. {
  938. DWORD dwInc = 0, dwPartial = dwPartialCurMSec;
  939. DWORD curReturnMSec;
  940. ULARGE_INTEGER cdummy = {0, 0};
  941. curReturnMSec=*pCurMSec;
  942. CPUGetSysTimerCountElapsed(RESCHED_PERIOD, &dwInc, &dwPartial, &cdummy);
  943. return (curReturnMSec==*pCurMSec)?curReturnMSec+dwInc:*pCurMSec;
  944. }
  945. volatile BOOL fResumeFlag;
  946. extern void CPUEnterIdleMode(void);
  947. //------------------------------------------------------------------------------
  948. // Initialize SDMMC block.. 
  949. //------------------------------------------------------------------------------
  950. static void InitSDMMC(void) 
  951. {
  952. volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
  953. // Initialize SDMMC and Configure SDMMC Card Detect
  954. // GPIO Configure 
  955. // RETAILMSG(1,(TEXT("SDMMC config current rGPGCON: %xrn"), s2440IOP->rGPGCON));  
  956. // We must need this PULL-UP routines to inialize.
  957. // s2440IOP->rGPGUP = 0xF800;   
  958. #if SDIO_FOR_100BD // for b'd revision 1.00
  959. // s2440IOP->rGPGUP &= ~(1<<10);
  960. s2440IOP->rGPGUP = 0xF800;
  961. s2440IOP->rGPGCON &= ~((0x3 << 20));   
  962. s2440IOP->rGPGCON |=  ((0x2 << 20)); // External Interrupt #18 Enable
  963. //RETAILMSG(1,(TEXT("SDMMC config set rGPGCON: %xrn"), s2440IOP->rGPGCON));   
  964. // s2440IOP->rEXTINT2 &= ~(0x7 << 8); // Configure EINT18 as Both Edge Mode
  965. // s2440IOP->rEXTINT2 |=  (0x7 << 8);
  966. #else // for b'd revision 0.17
  967. s2440IOP->rGPGUP = 0xF800;   
  968. s2440IOP->rGPGCON &= ~((0x3 << 16));   
  969. s2440IOP->rGPGCON |=  ((0x0 << 16)); //input /* External Interrupt #16 Enable */
  970. RETAILMSG(1,(TEXT("SDMMC config set rGPGCON: %xrn"), s2440IOP->rGPGCON));   
  971. s2440IOP->rEINTPEND  = (1 << 16); //clear
  972. s2440IOP->rEINTMASK |= (1 << 16); //disable
  973. // s2440IOP->rEXTINT2 &= ~(0x7 << 0); /* Configure EINT16 as Both Edge Mode */
  974. // s2440IOP->rEXTINT2 |=  (0x0 << 0); // low level trig
  975. #endif
  976. /* Configure SDMMC Write Protect */
  977. s2440IOP->rGPHUP = 0x0;   
  978. s2440IOP->rGPHCON &= ~((0x3 << 16));   
  979. s2440IOP->rGPHCON |=  ((0x0 << 16)); /* GPH8/UCLK Write Protect Pin */
  980. //RETAILMSG(1,(TEXT("SDMMC config Init Done.rn")));   
  981. }
  982. //------------------------------------------------------------------------------
  983. // Initialize and test the LCD block.. 
  984. //------------------------------------------------------------------------------
  985. /*
  986. // Define some values for TFT 16bpp
  987. #if(LCDTYPE == TFT16BPP)    // TFT 640*480 / 16bpp
  988. #define FR_WIDTH            240
  989. #define FR_HEIGHT           320
  990. #define PhysicalVmemSize    FR_HEIGHT*FR_WIDTH*LCDTYPE
  991. struct FrameBuffer {
  992.    unsigned short pixel[FR_HEIGHT][FR_WIDTH];
  993. };
  994. #else if(LCDTYPE == STN8BPP)// STN 320*240 / 8bpp
  995. #define FR_WIDTH            320
  996. #define FR_HEIGHT           240
  997. #define PhysicalVmemSize    FR_HEIGHT*FR_WIDTH
  998. struct FrameBuffer {
  999.    unsigned char pixel[FR_HEIGHT][FR_WIDTH];
  1000. };
  1001. #endif
  1002. */
  1003. #if (LCD_TYPE == TFT640_480)
  1004. struct FrameBuffer {
  1005. unsigned short pixel[LCD_YSIZE_TFT][LCD_XSIZE_TFT];
  1006. };
  1007. struct FrameBuffer *FBuf;
  1008. #elif (LCD_TYPE == TFT240_320)
  1009. struct FrameBuffer *FBuf;
  1010. #endif
  1011. static void InitDisplay()
  1012. {
  1013. int i, j;
  1014. volatile IOPreg *s2440IOP;
  1015. volatile LCDreg *s2440LCD;    
  1016. s2440IOP = (IOPreg *)IOP_BASE;
  1017. s2440LCD = (LCDreg *)LCD_BASE; 
  1018. // LCD port initialize.
  1019. s2440IOP->rGPCUP  = 0xFFFFFFFF;
  1020. s2440IOP->rGPCCON = 0xAAAAAAAA;
  1021. s2440IOP->rGPDUP  = 0xFFFFFFFF;
  1022. s2440IOP->rGPDCON = 0xAAAAAAAA;
  1023. s2440IOP->rGPGCON &= ~(3 << 8); // Set LCD_PWREN as output
  1024. s2440IOP->rGPGCON |=  (1 << 8);
  1025. s2440IOP->rGPGDAT |=  (1 << 4); // Backlight ON
  1026. #if (LCD_TYPE == TFT640_480)
  1027. s2440LCD->rLCDCON1   =  (1 << 8) | // VCLK = HCLK / ((CLKVAL + 1) * 2) -> About 7 Mhz  // ;;; SHL
  1028. (0 << 7) | // 0 : Each Frame
  1029. (3 << 5) | // TFT LCD Pannel
  1030. (12<< 1) | // 16bpp Mode
  1031. (0 << 0) ; // Disable LCD Output
  1032. s2440LCD->rLCDCON2   =  (VBPD        << 24) | // VBPD          :   1
  1033. (LINEVAL_TFT << 14) | // Virtical Size : 320 - 1
  1034. (VFPD        <<  6) | // VFPD          :   2
  1035. (VSPW        <<  0) ; // VSPW          :   1
  1036. s2440LCD->rLCDCON3   =  (HBPD        << 19) | // HBPD          :   6
  1037. (HOZVAL_TFT  <<  8) | // HOZVAL_TFT    : 240 - 1
  1038. (HFPD        <<  0) ; // HFPD          :   2
  1039. s2440LCD->rLCDCON4   =  (MVAL        <<  8) | // MVAL          :  13                              */
  1040. (HSPW        <<  0) ; // HSPW          :   4                              */
  1041. s2440LCD->rLCDCON5   =  (0 << 12) | // BPP24BL       : LSB valid
  1042. (1 << 11) | // FRM565 MODE   : 5:6:5 Format
  1043. (0 << 10) | // INVVCLK       : VCLK Falling Edge
  1044. (1 <<  9) | // INVVLINE      : Inverted Polarity
  1045. (1 <<  8) | // INVVFRAME     : Inverted Polarity
  1046. (0 <<  7) | // INVVD         : Normal
  1047. (0 <<  6) | // INVVDEN       : Normal
  1048. (0 <<  5) | // INVPWREN      : Normal
  1049. (0 <<  4) | // INVENDLINE    : Normal
  1050. (0 <<  3) | // PWREN         : Disable PWREN
  1051. (0 <<  2) | // ENLEND        : Disable LEND signal
  1052. (0 <<  1) | // BSWP          : Swap Disable
  1053. (1 <<  0) ; // HWSWP         : Swap Enable
  1054. s2440LCD->rLCDSADDR1 = ((FRAMEBUF_DMA_BASE >> 22) << 21) |
  1055. ((M5D(FRAMEBUF_DMA_BASE >> 1)) <<  0);
  1056. s2440LCD->rLCDSADDR2 = M5D((FRAMEBUF_DMA_BASE + (LCD_XSIZE_TFT * LCD_YSIZE_TFT * 2)) >> 1);
  1057. s2440LCD->rLCDSADDR3 = (((LCD_XSIZE_TFT - LCD_XSIZE_TFT) / 1) << 11) | (LCD_XSIZE_TFT / 1);
  1058. // s2440LCD->rLPCSEL    |= 0x3; // for aiji
  1059. s2440LCD->rLCDINTMSK |= (3);
  1060. s2440LCD->rTCONSEL   &= ~(0x7); // ;;; SHL
  1061. s2440LCD->rTCONSEL   |= 0x2; //240*320
  1062. s2440LCD->rTPAL       = 0x0;
  1063. s2440LCD->rTCONSEL   &= ~((1<<4) | 1); // Disable LCC3600, LCP3600
  1064. s2440IOP->rGPGUP   = s2440IOP->rGPGUP  & (~(1<<4)) | (1<<4); // Pull-up disbale
  1065. s2440IOP->rGPGCON   = s2440IOP->rGPGCON & (~(3<<8)) | (3<<8);
  1066. s2440LCD->rLCDCON5    = s2440LCD->rLCDCON5 & (~(1<<3)) | (1<<3); // PWREN
  1067. s2440LCD->rLCDCON5    = s2440LCD->rLCDCON5 & (~(1<<5)) | (0<<5); // INVPWREN
  1068. s2440LCD->rLCDCON1  |= 1; // Enable LCD output
  1069. #elif (LCD_TYPE == TFT240_320)
  1070. // s2440LCD->rLCDCON1   =  (6           <<  8) |   /* VCLK = HCLK / ((CLKVAL + 1) * 2) -> About 7 Mhz  */
  1071. s2440LCD->rLCDCON1   =  (12           <<  8) |   /* VCLK = HCLK / ((CLKVAL + 1) * 2) -> About 7 Mhz */  // ;;; SHL
  1072. (MVAL_USED   <<  7) |   /* 0 : Each Frame                                   */
  1073. (3           <<  5) |   /* TFT LCD Pannel                                   */
  1074. (12          <<  1) |   /* 16bpp Mode                                       */
  1075. (0           <<  0) ;   /* Disable LCD Output                               */
  1076. s2440LCD->rLCDCON2   =  (VBPD        << 24) |   /* VBPD          :   1                              */
  1077. (LINEVAL_TFT << 14) |   /* Virtical Size : 320 - 1                          */
  1078. (VFPD        <<  6) |   /* VFPD          :   2                              */
  1079. (VSPW        <<  0) ;   /* VSPW          :   1                              */
  1080. s2440LCD->rLCDCON3   =  (HBPD        << 19) |   /* HBPD          :   6                              */
  1081. (HOZVAL_TFT  <<  8) |   /* HOZVAL_TFT    : 240 - 1                          */
  1082. (HFPD        <<  0) ;   /* HFPD          :   2                              */
  1083. s2440LCD->rLCDCON4   =  (MVAL        <<  8) |   /* MVAL          :  13                              */
  1084. (HSPW        <<  0) ;   /* HSPW          :   4                              */
  1085. s2440LCD->rLCDCON5   =  (0           << 12) |   /* BPP24BL       : LSB valid                        */
  1086. (1           << 11) |   /* FRM565 MODE   : 5:6:5 Format                     */
  1087. (0           << 10) |   /* INVVCLK       : VCLK Falling Edge                */
  1088. (1           <<  9) |   /* INVVLINE      : Inverted Polarity                */
  1089. (1           <<  8) |   /* INVVFRAME     : Inverted Polarity                */
  1090. (0           <<  7) |   /* INVVD         : Normal                           */
  1091. (0           <<  6) |   /* INVVDEN       : Normal                           */
  1092. (0           <<  5) |   /* INVPWREN      : Normal                           */
  1093. (0           <<  4) |   /* INVENDLINE    : Normal                           */
  1094. (0           <<  3) |   /* PWREN         : Disable PWREN                    */
  1095. (0           <<  2) |   /* ENLEND        : Disable LEND signal              */
  1096. (0           <<  1) |   /* BSWP          : Swap Disable                     */
  1097. (1           <<  0) ;   /* HWSWP         : Swap Enable                      */
  1098. s2440LCD->rLCDSADDR1 = ((FRAMEBUF_DMA_BASE >> 22)     << 21) |
  1099. ((M5D(FRAMEBUF_DMA_BASE >> 1)) <<  0);
  1100. s2440LCD->rLCDSADDR2 = M5D((FRAMEBUF_DMA_BASE + (LCD_XSIZE_TFT * LCD_YSIZE_TFT * 2)) >> 1);
  1101. s2440LCD->rLCDSADDR3 = (((LCD_XSIZE_TFT - LCD_XSIZE_TFT) / 1) << 11) | (LCD_XSIZE_TFT / 1);
  1102. // s2440LCD->rLPCSEL   |= 0x3; // for aiji
  1103. s2440LCD->rTCONSEL &= ~(0x7); // ;;; SHL
  1104. s2440LCD->rTCONSEL   |= 0x2; //240*320
  1105. s2440LCD->rTCONSEL   &= ~((1<<4) | 1); // Disable LCC3600, LCP3600
  1106. // s2440LCD->rTCONSEL |= (1<<4); // ;;; SHL
  1107. s2440LCD->rTPAL     = 0x0;
  1108. s2440LCD->rLCDCON1 |= 1;
  1109. #endif
  1110. #if (LCD_TYPE == TFT640_480)
  1111. FBuf = (struct FrameBuffer *) (FRAMEBUF_BASE);
  1112. // Test LCD display status with R.G.B and White color.
  1113. for (i=0; i<LCD_YSIZE_TFT/2; i++)
  1114. {
  1115. for (j=0; j<LCD_XSIZE_TFT; j++)
  1116. {
  1117. if (j<LCD_XSIZE_TFT/2)
  1118. #if (LCDTYPE == TFT16BPP)
  1119. FBuf->pixel[i][j]=0xffff;
  1120. #else
  1121. FBuf->pixel[i][j]=0xff;
  1122. #endif
  1123. else
  1124. #if (LCDTYPE == TFT16BPP)
  1125. FBuf->pixel[i][j]=0xf800;
  1126. #else
  1127. FBuf->pixel[i][j]=0xe0;
  1128. #endif
  1129. }
  1130. }
  1131. for (i=LCD_YSIZE_TFT/2; i<LCD_YSIZE_TFT; i++)
  1132. {
  1133. for (j=0; j<LCD_XSIZE_TFT; j++)
  1134. {
  1135. if (j<LCD_XSIZE_TFT/2)
  1136. #if (LCDTYPE == TFT16BPP)
  1137. FBuf->pixel[i][j]=0x07e0;
  1138. #else
  1139. FBuf->pixel[i][j]=0x1c;
  1140. #endif
  1141. else
  1142. #if (LCDTYPE == TFT16BPP)
  1143. FBuf->pixel[i][j]=0x001f;
  1144. #else
  1145. FBuf->pixel[i][j]=0x03;
  1146. #endif
  1147. }
  1148. }
  1149. #elif (LCD_TYPE == TFT240_320)
  1150. memcpy((void *)FRAMEBUF_BASE, ScreenBitmap, ARRAY_SIZE_TFT_16BIT);
  1151. //    rle_express(ScreenBitmap, (unsigned short *)FRAMEBUF_BASE, 0x8a8c / 2);
  1152. #endif
  1153. }
  1154. static void OEMInitInterrupts(void) // for KITL 030828
  1155. {
  1156. volatile INTreg *s2440INT = (INTreg *)INT_BASE;
  1157. volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
  1158. // Configure EINT9 for CS8900 interrupt.
  1159. //
  1160. s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 0x2)) | (0x2 << 0x2); // GPG1 == EINT9.
  1161. s2440IOP->rGPGUP   = (s2440IOP->rGPGUP   |  (0x1 << 0x1)); // Disable pull-up.
  1162. s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0xf << 0x4)) | (0x1 << 0x4); // Level-high triggered.
  1163. // Configure EINT8 for PD6710 interrupt.
  1164. //
  1165. s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 0x0)) | (0x2 << 0x0); // GPG0 == EINT8.
  1166. s2440IOP->rGPGUP   = (s2440IOP->rGPGUP   |  (0x1 << 0x0)); // Disable pull-up.
  1167. s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0xf << 0x0)) | (0x1 << 0x0); // Level-high triggered.
  1168. // Mask and clear all peripheral interrupts (these come through a second-level "GPIO" interrupt register).
  1169. //
  1170. s2440IOP->rEINTMASK = BIT_ALLMSK; // Mask all EINT interrupts.
  1171. s2440IOP->rEINTPEND = BIT_ALLMSK; // Clear pending EINT interrupts.
  1172. // Mask and clear all interrupts.
  1173. //
  1174. s2440INT->rINTMSK = BIT_ALLMSK; // Mask all interrupts (reset value).
  1175. s2440INT->rINTMSK &= ~BIT_BAT_FLT;
  1176. s2440INT->rSRCPND = BIT_ALLMSK; // Clear pending interrupts.
  1177. s2440INT->rINTPND = s2440INT->rINTPND; // S3C2440X developer notice (page 4) warns against writing a 1 to any
  1178. // 0 bit field in the INTPND register.  Instead we'll write the INTPND value itself.
  1179. }