Porting Windows CE 5.0 on PXA255 Based Platform by Vinoth.R
Introduction
The PXA255 processor is one of the popular xscale processor other then PXA270. Even though Intel is not promoting this product for the future use, there are many development boards as well as devices developed over this 200MHz chip. Microsoft has released the WindowsCE 4.20 BSP during the initial boom of this processor into the market. After the introduction of the PXA270 processor by Intel Microsoft did not put any effort to release WindowsCE BSP for the next release of its pioneer Mobile operating system like Windows CE 5.0.
This article introduces some easy as well interesting method to develop PXA255 BSP for Windows CE 5.0. Instead of having the conventional approach of porting PXA255 Windows CE 4.20 BSP to Windows CE 5.0 we are following a different approach, take the PXA270 Windows CE 5.0 BSP and modify it for PXA255 processor.
Scope
The scope of this document is limited to audience who are interested in developing PXA255 BSP for Windows CE 5.0 or even 6.0. We use Windows CE 5.0 BSP for Intel's PXA270 Developers board as the reference BSP for our development. This BSP is commonly known as the Mainstone-III Windows CE 5.0 BSP. The user is expected to have the understanding of PXA255 processor register set and Mainstone III BSP architecture.
Porting the Cross Platform Low Level definitions (XLLP)
The Cross Platform Low Level functions are the processor initialization functions, and are closely bind to the processor. PXA270 has few features those are not available for the PXA255 processor. Most of the registers for the devices those are common for PXA255 and PXA270 have same register set and bit definition. So those features and its corresponding register set have to be removed from the BSP. For example PXA27x contains 120 GPIO where as PXA255 contains 85 GPIO pins, PXA255 doesn't have the power I2C interface and it contains only 15 DMA channels etc. The register set is defined in a file located at wince500/(platform)/src/common/xllp/inc/xlli_bulverde_defs.inc
Step 1:
Remove the following register definitions from the xlli_bulverde_defs.inc file. Gpio Registers: xlli_GPLR3_offset EQU (0x100) xlli_GPDR3_offset EQU (0x10C) xlli_GPSR3_offset EQU (0x118) xlli_GPCR3_offset EQU (0x124) xlli_GAFR3_L_offset EQU (0x06C) xlli_GAFR3_U_offset EQU (0x070)
Power Manager: xlli_PGSR3_offset EQU (0x2C) xlli_PSLR_offset EQU (0x34); Power Manager Sleep Mode Config Register xlli_PSTR_offset EQU (0x38); Power Manager Standby Mode Config Register xlli_PSNR_offset EQU (0x3C); Power Manager Sense Mode Config Register xlli_PVCR_offset EQU (0x40); Power Manager Voltage Change Control Register xlli_PKWR_offset EQU (0x50); Power Manager Keyboard Wake-up Enable Register xlli_PKSR_offset EQU (0x54); Power Manager Keyboard Edge-Detect Status Register xlli_PI2DBR_offset EQU (0x188); Power I2C Data Buffer Register xlli_PI2CR_offset EQU (0x190); Power I2C Control Register xlli_PI2SR_offset EQU (0x198); Power I2C Status Register xlli_PI2SAR_offset EQU (0x1A0); Power I2C Slave Address Register
Power Manager Register definition bit masks: xlli_PCFR_SYSEN_EN EQU (0x20); SYS_EN pin xlli_PCFR_DC_EN EQU (0x80); Deep-Sleep Mode
Clock Registers: xlli_CCSR_offset EQU (0x0C); Core Clock Status Register xlli_CCCR_A_Bit_Mask EQU (0x1 ? 25); "A" bit is bit 25 in CCCR
OS Timer Registers: xlli_OSCR4_offset EQU (0x40); OS Timer Count Register 4 xlli_OSCR5_offset EQU (0x44); OS Timer Count Register 5 xlli_OSCR6_offset EQU (0x48); OS Timer Count Register 6 xlli_OSCR7_offset EQU (0x4C); OS Timer Count Register 7 xlli_OSCR8_offset EQU (0x50); OS Timer Count Register 8 xlli_OSCR9_offset EQU (0x54); OS Timer Count Register 9 xlli_OSCR10_offset EQU (0x58); OS Timer Count Register 10 xlli_OSCR11_offset EQU (0x5C); OS Timer Count Register 11
xlli_OSMR4_offset EQU (0x80); OS Timer Match Register 4 xlli_OSMR5_offset EQU (0x84); OS Timer Match Register 5 xlli_OSMR6_offset EQU (0x88); OS Timer Match Register 6 xlli_OSMR7_offset EQU (0x8C); OS Timer Match Register 7 xlli_OSMR8_offset EQU (0x90); OS Timer Match Register 8 xlli_OSMR9_offset EQU (0x94); OS Timer Match Register 9 xlli_OSMR10_offset EQU (0x98); OS Timer Match Register 10 xlli_OSMR11_offset EQU (0x9C); OS Timer Match Register 11
xlli_OMCR4_offset EQU (0xC0); OS Timer Match Control Register 4 xlli_OMCR5_offset EQU (0xC4); OS Timer Match Control Register 5 xlli_OMCR6_offset EQU (0xC8); OS Timer Match Control Register 6 xlli_OMCR7_offset EQU (0xCC); OS Timer Match Control Register 7 xlli_OMCR8_offset EQU (0xD0); OS Timer Match Control Register 8 xlli_OMCR9_offset EQU (0xD4); OS Timer Match Control Register 9 xlli_OMCR10_offset EQU (0xD8); OS Timer Match Control Register 10 xlli_OMCR11_offset EQU (0xDC); OS Timer Match Control Register 11
Change the GPIO registers value and SDRAM register values based on new Platform (All values are defined in the
wince500/(platform)/src/common/xllp/inc/xlli_ (Platform) _defs.inc).
Also if you have any board specific registers you can represent the values in this file and remove the GPIO registers values which are irrelevant to PXA255 processor. The above two files are used by the Startup code of both the EBOOT and KERNEL.
Step 3:
Remove all the register definitions which are not part of the PXA255 processors device specific register set. These registers are defined in the header files in the directory, wince500/platform/src/common/xllp/inc. Each header file name is of the format xlli_(device).h. The register set is represented as structure that contains all the registers related to devices. Also the bit definitions for of each of those registers are defined in the same header file. Remove the registers and also the bit definitions which are not relevant to PXA255.
For example, to remove the GPIO registers which are not available in the PXA255, comment out the lines in the file wince500/(platform)/src/common/xllp/inc/xllp_gpio.h as shown below. typedef struct {
…….. ……..
// Commented by econ for PXA255 Gpio configuration (pxa255 is having 85 GPIO)
Follow the same instructions for the remaining device files in the same directory.
1) Since PXA255 CCLKCFG register contains only F and T bit definitions and there is no B and H bits, related operations has to be removed from the file. wince500/(platform)/src/common/xllp/src /xlli_lowlev_init.s file.
2) The CCCR register for PXA255 and PXA27x is different. There is no 'A' bit on PXA255, so remove the xlli_mem_Topt, xlli_mem_restart subroutines from the xlli_lowlev_init.s file. In the xlli_setClocks routine, the CCLKCFG Turbo mode bit and Fast bus Mode bit can be assigned directly to the CCCR register.
3) Change the MDREFR K1DB2 bit value according to the memory clock frequency.
4) I2C interface is a dedicated interface in PXA255 instead of GPIO alternating functions PXA270 and also there is no power I2C interface in PXA255. So remove the header file declarations in the corresponding device header file.
Porting the Kernel
There is no much difference in the processor dependent kernel source of the BSP. But there are two important units which are highly depended to processor, the Interrupt Unit and RTC. The interrupt architecture bit different in PXA255 and PXA270.
1) For PXA27x processor ICHP (Interrupt Higher priority register) is used for detecting the interrupt and for PXA255 processor ICIP (Interrupt Pending Register) is used. So the OEMInterruptHandler() has to be changed. Do the following changes in the OEMIntyerrupthandler().
In PXA270 the IRQ values are defined as IDs that can be understandable by the ICHP section of the processor. But in PXA255 interrupt are detected with ICIP register bits. So the OEMInterruptHandler() has to be rewritten in a from as given below. Since the Interrupt priority array g_intPriorities used by OEMIntyerrupthandler() ICHP remove it from the int.c file.
if (!g_pICReg || !g_pOSTRegs || !g_pGPIORegs ) { return(SYSINTR_NOP); } irq = (g_pICReg->icip); if (irq & 0) { return(SYSINTR_NOP); } // System timer interrupt? if (irq & PXA_IRQ_OSMR0) { // The rest is up to the timer interrupt handler. // sysIntr = OALTimerIntrHandler(); } else if (irq & PXA_IRQ_STUART) { CLRREG32(&g_pICReg->icmr, PXA_IRQ_STUART); return(SYSINTR_IR); } else if (irq & PXA_IRQ_FFUART) { CLRREG32(&g_pICReg->icmr, PXA_IRQ_FFUART); return(SYSINTR_FFUART); } . . . . } Here PXA_IRQ_OSMR0, PXA_IRQ_STUART etc are ICIP bits.
2. PXA255 RTC contains only the RTTR, RTAR, RCNR, RTSR register so day, month, year calculation are done by software or External RTC. The following are the RTC functions are used by the kernel which needs to be rewritten for PXA255. OEMGetRealTime() OEMSetRealTime() OEMSetCurrentTime() OEMSetAlarmTime() BOOL OALIoCtlHalInitRTC( UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer, UINT32 outSize, UINT32 *pOutSize)
These functions has to be implemented in the /WINCE500/PLATFORM/(Platform name)/SRC/COMMON/RTC/rtc.c file
3.PXA255 OS Timer is running at the frequency of 3.86 MHz where as PXA27x OS Timer is Timer running at the frequency of 3.25 MHz. So the Ticks per Microseconds definitions need to be changed. These OS timer definitions are used by the kernel and are defined in the /WINCE500/PLATFORM/(Platform name)/SRC/Bsp_cfg.h file.
Also calculate the divisor value according to the OEMMintickdistance in the OEMInit () function of init.c file. Make the followings changes in the for OS Timer definitions in bsp_cfg.h.
#define OEM_CLOCK_FREQ 3686400 // 3.25M ticks/sec #define OEM_TICKS_1MS 3686 // 1ms in ticks #define RESCHED_PERIOD 1 // Reschedule period in ms #define RESCHED_INCREMENT (RESCHED_PERIOD * OEM_TICKS_1MS) #define OEM_TICK_COUNT_MARGIN 0
4) Libraries for the sources KERN, KERNKITL, KERNKITLPROF are the same which is already in the sources file used for PXA27x processor except oal_cache_pxa27x.lib. Instead of the oal_cache_pxa27x.lib use oal_cache_pxa250.lib for PXA255. The above three kernel related directories are under the following tree. /WINCE500/PLATFORM/(platform name) /SRC/KERNEL/ The sample KERN sources file changed for PXA255 is given below.
All PXA255 drivers can be copied from /WINCE500/PUBLIC/COMMON/OAK/CSP/ARM/INTEL/PXA25X/ folder to local platform.
Conclusion
KITL is one the important block in the BSP for doing any sort of debugging. Most of the handheld device may not have Ethernet port on the board; in that case KITL can be implemented over either USB or Serial Port.
But there is no PDD level serial KITL driver for the Mainstone BSP. But this can be easily ported from X86 CSP.
Porting 6.0 to any cards and any questions on this article, please write to with the subject Porting Windows CE 5.0.